xref: /aosp_15_r20/external/vulkan-validation-layers/tests/vkpositivelayertests.cpp (revision b7893ccf7851cd6a48cc5a1e965257d8a5cdcc70)
1*b7893ccfSSadaf Ebrahimi /*
2*b7893ccfSSadaf Ebrahimi  * Copyright (c) 2015-2019 The Khronos Group Inc.
3*b7893ccfSSadaf Ebrahimi  * Copyright (c) 2015-2019 Valve Corporation
4*b7893ccfSSadaf Ebrahimi  * Copyright (c) 2015-2019 LunarG, Inc.
5*b7893ccfSSadaf Ebrahimi  * Copyright (c) 2015-2019 Google, Inc.
6*b7893ccfSSadaf Ebrahimi  *
7*b7893ccfSSadaf Ebrahimi  * Licensed under the Apache License, Version 2.0 (the "License");
8*b7893ccfSSadaf Ebrahimi  * you may not use this file except in compliance with the License.
9*b7893ccfSSadaf Ebrahimi  * You may obtain a copy of the License at
10*b7893ccfSSadaf Ebrahimi  *
11*b7893ccfSSadaf Ebrahimi  *     http://www.apache.org/licenses/LICENSE-2.0
12*b7893ccfSSadaf Ebrahimi  *
13*b7893ccfSSadaf Ebrahimi  * Author: Chia-I Wu <[email protected]>
14*b7893ccfSSadaf Ebrahimi  * Author: Chris Forbes <[email protected]>
15*b7893ccfSSadaf Ebrahimi  * Author: Courtney Goeltzenleuchter <[email protected]>
16*b7893ccfSSadaf Ebrahimi  * Author: Mark Lobodzinski <[email protected]>
17*b7893ccfSSadaf Ebrahimi  * Author: Mike Stroyan <[email protected]>
18*b7893ccfSSadaf Ebrahimi  * Author: Tobin Ehlis <[email protected]>
19*b7893ccfSSadaf Ebrahimi  * Author: Tony Barbour <[email protected]>
20*b7893ccfSSadaf Ebrahimi  * Author: Cody Northrop <[email protected]>
21*b7893ccfSSadaf Ebrahimi  * Author: Dave Houlton <[email protected]>
22*b7893ccfSSadaf Ebrahimi  * Author: Jeremy Kniager <[email protected]>
23*b7893ccfSSadaf Ebrahimi  * Author: Shannon McPherson <[email protected]>
24*b7893ccfSSadaf Ebrahimi  * Author: John Zulauf <[email protected]>
25*b7893ccfSSadaf Ebrahimi  */
26*b7893ccfSSadaf Ebrahimi 
27*b7893ccfSSadaf Ebrahimi #include "cast_utils.h"
28*b7893ccfSSadaf Ebrahimi #include "layer_validation_tests.h"
29*b7893ccfSSadaf Ebrahimi //
30*b7893ccfSSadaf Ebrahimi // POSITIVE VALIDATION TESTS
31*b7893ccfSSadaf Ebrahimi //
32*b7893ccfSSadaf Ebrahimi // These tests do not expect to encounter ANY validation errors pass only if this is true
33*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,NullFunctionPointer)34*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, NullFunctionPointer) {
35*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("On 1_0 instance , call GetDeviceProcAddr on promoted 1_1 device-level entrypoint");
36*b7893ccfSSadaf Ebrahimi     SetTargetApiVersion(VK_API_VERSION_1_0);
37*b7893ccfSSadaf Ebrahimi 
38*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
39*b7893ccfSSadaf Ebrahimi 
40*b7893ccfSSadaf Ebrahimi     if (DeviceExtensionSupported(gpu(), nullptr, "VK_KHR_get_memory_requirements2")) {
41*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back("VK_KHR_get_memory_requirements2");
42*b7893ccfSSadaf Ebrahimi     } else {
43*b7893ccfSSadaf Ebrahimi         printf("%s VK_KHR_get_memory_reqirements2 extension not supported, skipping NullFunctionPointer test\n", kSkipPrefix);
44*b7893ccfSSadaf Ebrahimi         return;
45*b7893ccfSSadaf Ebrahimi     }
46*b7893ccfSSadaf Ebrahimi 
47*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
48*b7893ccfSSadaf Ebrahimi 
49*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
50*b7893ccfSSadaf Ebrahimi     auto fpGetBufferMemoryRequirements =
51*b7893ccfSSadaf Ebrahimi         (PFN_vkGetBufferMemoryRequirements2)vkGetDeviceProcAddr(m_device->device(), "vkGetBufferMemoryRequirements2");
52*b7893ccfSSadaf Ebrahimi     if (fpGetBufferMemoryRequirements) {
53*b7893ccfSSadaf Ebrahimi         m_errorMonitor->SetError("Null was expected!");
54*b7893ccfSSadaf Ebrahimi     }
55*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
56*b7893ccfSSadaf Ebrahimi }
57*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,SecondaryCommandBufferBarrier)58*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, SecondaryCommandBufferBarrier) {
59*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Add a pipeline barrier in a secondary command buffer");
60*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
61*b7893ccfSSadaf Ebrahimi 
62*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
63*b7893ccfSSadaf Ebrahimi 
64*b7893ccfSSadaf Ebrahimi     // A renderpass with a single subpass that declared a self-dependency
65*b7893ccfSSadaf Ebrahimi     VkAttachmentDescription attach[] = {
66*b7893ccfSSadaf Ebrahimi         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
67*b7893ccfSSadaf Ebrahimi          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED,
68*b7893ccfSSadaf Ebrahimi          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
69*b7893ccfSSadaf Ebrahimi     };
70*b7893ccfSSadaf Ebrahimi     VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
71*b7893ccfSSadaf Ebrahimi     VkSubpassDescription subpasses[] = {
72*b7893ccfSSadaf Ebrahimi         {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &ref, nullptr, nullptr, 0, nullptr},
73*b7893ccfSSadaf Ebrahimi     };
74*b7893ccfSSadaf Ebrahimi     VkSubpassDependency dep = {0,
75*b7893ccfSSadaf Ebrahimi                                0,
76*b7893ccfSSadaf Ebrahimi                                VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
77*b7893ccfSSadaf Ebrahimi                                VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
78*b7893ccfSSadaf Ebrahimi                                VK_ACCESS_SHADER_WRITE_BIT,
79*b7893ccfSSadaf Ebrahimi                                VK_ACCESS_SHADER_WRITE_BIT,
80*b7893ccfSSadaf Ebrahimi                                VK_DEPENDENCY_BY_REGION_BIT};
81*b7893ccfSSadaf Ebrahimi     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 1, &dep};
82*b7893ccfSSadaf Ebrahimi     VkRenderPass rp;
83*b7893ccfSSadaf Ebrahimi 
84*b7893ccfSSadaf Ebrahimi     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
85*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
86*b7893ccfSSadaf Ebrahimi 
87*b7893ccfSSadaf Ebrahimi     VkImageObj image(m_device);
88*b7893ccfSSadaf Ebrahimi     image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
89*b7893ccfSSadaf Ebrahimi     VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
90*b7893ccfSSadaf Ebrahimi 
91*b7893ccfSSadaf Ebrahimi     VkFramebufferCreateInfo fbci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &imageView, 32, 32, 1};
92*b7893ccfSSadaf Ebrahimi     VkFramebuffer fb;
93*b7893ccfSSadaf Ebrahimi     err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
94*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
95*b7893ccfSSadaf Ebrahimi 
96*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
97*b7893ccfSSadaf Ebrahimi 
98*b7893ccfSSadaf Ebrahimi     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
99*b7893ccfSSadaf Ebrahimi                                   nullptr,
100*b7893ccfSSadaf Ebrahimi                                   rp,
101*b7893ccfSSadaf Ebrahimi                                   fb,
102*b7893ccfSSadaf Ebrahimi                                   {{
103*b7893ccfSSadaf Ebrahimi                                        0,
104*b7893ccfSSadaf Ebrahimi                                        0,
105*b7893ccfSSadaf Ebrahimi                                    },
106*b7893ccfSSadaf Ebrahimi                                    {32, 32}},
107*b7893ccfSSadaf Ebrahimi                                   0,
108*b7893ccfSSadaf Ebrahimi                                   nullptr};
109*b7893ccfSSadaf Ebrahimi 
110*b7893ccfSSadaf Ebrahimi     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
111*b7893ccfSSadaf Ebrahimi 
112*b7893ccfSSadaf Ebrahimi     VkCommandPoolObj pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
113*b7893ccfSSadaf Ebrahimi     VkCommandBufferObj secondary(m_device, &pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
114*b7893ccfSSadaf Ebrahimi 
115*b7893ccfSSadaf Ebrahimi     VkCommandBufferInheritanceInfo cbii = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
116*b7893ccfSSadaf Ebrahimi                                            nullptr,
117*b7893ccfSSadaf Ebrahimi                                            rp,
118*b7893ccfSSadaf Ebrahimi                                            0,
119*b7893ccfSSadaf Ebrahimi                                            VK_NULL_HANDLE,  // Set to NULL FB handle intentionally to flesh out any errors
120*b7893ccfSSadaf Ebrahimi                                            VK_FALSE,
121*b7893ccfSSadaf Ebrahimi                                            0,
122*b7893ccfSSadaf Ebrahimi                                            0};
123*b7893ccfSSadaf Ebrahimi     VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
124*b7893ccfSSadaf Ebrahimi                                      VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT,
125*b7893ccfSSadaf Ebrahimi                                      &cbii};
126*b7893ccfSSadaf Ebrahimi     vkBeginCommandBuffer(secondary.handle(), &cbbi);
127*b7893ccfSSadaf Ebrahimi     VkMemoryBarrier mem_barrier = {};
128*b7893ccfSSadaf Ebrahimi     mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
129*b7893ccfSSadaf Ebrahimi     mem_barrier.pNext = NULL;
130*b7893ccfSSadaf Ebrahimi     mem_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
131*b7893ccfSSadaf Ebrahimi     mem_barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
132*b7893ccfSSadaf Ebrahimi     vkCmdPipelineBarrier(secondary.handle(), VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
133*b7893ccfSSadaf Ebrahimi                          VK_DEPENDENCY_BY_REGION_BIT, 1, &mem_barrier, 0, nullptr, 0, nullptr);
134*b7893ccfSSadaf Ebrahimi 
135*b7893ccfSSadaf Ebrahimi     image.ImageMemoryBarrier(&secondary, VK_IMAGE_ASPECT_COLOR_BIT, VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT,
136*b7893ccfSSadaf Ebrahimi                              VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
137*b7893ccfSSadaf Ebrahimi                              VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
138*b7893ccfSSadaf Ebrahimi     secondary.end();
139*b7893ccfSSadaf Ebrahimi 
140*b7893ccfSSadaf Ebrahimi     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
141*b7893ccfSSadaf Ebrahimi     vkCmdEndRenderPass(m_commandBuffer->handle());
142*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
143*b7893ccfSSadaf Ebrahimi 
144*b7893ccfSSadaf Ebrahimi     VkSubmitInfo submit_info = {};
145*b7893ccfSSadaf Ebrahimi     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
146*b7893ccfSSadaf Ebrahimi     submit_info.commandBufferCount = 1;
147*b7893ccfSSadaf Ebrahimi     submit_info.pCommandBuffers = &m_commandBuffer->handle();
148*b7893ccfSSadaf Ebrahimi     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
149*b7893ccfSSadaf Ebrahimi     vkQueueWaitIdle(m_device->m_queue);
150*b7893ccfSSadaf Ebrahimi 
151*b7893ccfSSadaf Ebrahimi     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
152*b7893ccfSSadaf Ebrahimi     vkDestroyRenderPass(m_device->device(), rp, nullptr);
153*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
154*b7893ccfSSadaf Ebrahimi }
155*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,RenderPassCreateAttachmentUsedTwiceOK)156*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, RenderPassCreateAttachmentUsedTwiceOK) {
157*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Attachment is used simultaneously as color and input, with the same layout. This is OK.");
158*b7893ccfSSadaf Ebrahimi 
159*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
160*b7893ccfSSadaf Ebrahimi 
161*b7893ccfSSadaf Ebrahimi     VkAttachmentDescription attach[] = {
162*b7893ccfSSadaf Ebrahimi         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_DONT_CARE,
163*b7893ccfSSadaf Ebrahimi          VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
164*b7893ccfSSadaf Ebrahimi     };
165*b7893ccfSSadaf Ebrahimi     VkAttachmentReference ref = {0, VK_IMAGE_LAYOUT_GENERAL};
166*b7893ccfSSadaf Ebrahimi     VkSubpassDescription subpasses[] = {
167*b7893ccfSSadaf Ebrahimi         {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &ref, 1, &ref, nullptr, nullptr, 0, nullptr},
168*b7893ccfSSadaf Ebrahimi     };
169*b7893ccfSSadaf Ebrahimi 
170*b7893ccfSSadaf Ebrahimi     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, attach, 1, subpasses, 0, nullptr};
171*b7893ccfSSadaf Ebrahimi     VkRenderPass rp;
172*b7893ccfSSadaf Ebrahimi 
173*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
174*b7893ccfSSadaf Ebrahimi     vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
175*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
176*b7893ccfSSadaf Ebrahimi     vkDestroyRenderPass(m_device->device(), rp, nullptr);
177*b7893ccfSSadaf Ebrahimi }
178*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,RenderPassCreateInitialLayoutUndefined)179*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, RenderPassCreateInitialLayoutUndefined) {
180*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
181*b7893ccfSSadaf Ebrahimi         "Ensure that CmdBeginRenderPass with an attachment's initialLayout of VK_IMAGE_LAYOUT_UNDEFINED works when the command "
182*b7893ccfSSadaf Ebrahimi         "buffer has prior knowledge of that attachment's layout.");
183*b7893ccfSSadaf Ebrahimi 
184*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
185*b7893ccfSSadaf Ebrahimi 
186*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
187*b7893ccfSSadaf Ebrahimi 
188*b7893ccfSSadaf Ebrahimi     // A renderpass with one color attachment.
189*b7893ccfSSadaf Ebrahimi     VkAttachmentDescription attachment = {0,
190*b7893ccfSSadaf Ebrahimi                                           VK_FORMAT_R8G8B8A8_UNORM,
191*b7893ccfSSadaf Ebrahimi                                           VK_SAMPLE_COUNT_1_BIT,
192*b7893ccfSSadaf Ebrahimi                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
193*b7893ccfSSadaf Ebrahimi                                           VK_ATTACHMENT_STORE_OP_STORE,
194*b7893ccfSSadaf Ebrahimi                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
195*b7893ccfSSadaf Ebrahimi                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
196*b7893ccfSSadaf Ebrahimi                                           VK_IMAGE_LAYOUT_UNDEFINED,
197*b7893ccfSSadaf Ebrahimi                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
198*b7893ccfSSadaf Ebrahimi 
199*b7893ccfSSadaf Ebrahimi     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
200*b7893ccfSSadaf Ebrahimi 
201*b7893ccfSSadaf Ebrahimi     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
202*b7893ccfSSadaf Ebrahimi 
203*b7893ccfSSadaf Ebrahimi     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
204*b7893ccfSSadaf Ebrahimi 
205*b7893ccfSSadaf Ebrahimi     VkRenderPass rp;
206*b7893ccfSSadaf Ebrahimi     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
207*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
208*b7893ccfSSadaf Ebrahimi 
209*b7893ccfSSadaf Ebrahimi     // A compatible framebuffer.
210*b7893ccfSSadaf Ebrahimi     VkImageObj image(m_device);
211*b7893ccfSSadaf Ebrahimi     image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
212*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(image.initialized());
213*b7893ccfSSadaf Ebrahimi 
214*b7893ccfSSadaf Ebrahimi     VkImageViewCreateInfo ivci = {
215*b7893ccfSSadaf Ebrahimi         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
216*b7893ccfSSadaf Ebrahimi         nullptr,
217*b7893ccfSSadaf Ebrahimi         0,
218*b7893ccfSSadaf Ebrahimi         image.handle(),
219*b7893ccfSSadaf Ebrahimi         VK_IMAGE_VIEW_TYPE_2D,
220*b7893ccfSSadaf Ebrahimi         VK_FORMAT_R8G8B8A8_UNORM,
221*b7893ccfSSadaf Ebrahimi         {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
222*b7893ccfSSadaf Ebrahimi          VK_COMPONENT_SWIZZLE_IDENTITY},
223*b7893ccfSSadaf Ebrahimi         {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
224*b7893ccfSSadaf Ebrahimi     };
225*b7893ccfSSadaf Ebrahimi     VkImageView view;
226*b7893ccfSSadaf Ebrahimi     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
227*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
228*b7893ccfSSadaf Ebrahimi 
229*b7893ccfSSadaf Ebrahimi     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
230*b7893ccfSSadaf Ebrahimi     VkFramebuffer fb;
231*b7893ccfSSadaf Ebrahimi     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
232*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
233*b7893ccfSSadaf Ebrahimi 
234*b7893ccfSSadaf Ebrahimi     // Record a single command buffer which uses this renderpass twice. The
235*b7893ccfSSadaf Ebrahimi     // bug is triggered at the beginning of the second renderpass, when the
236*b7893ccfSSadaf Ebrahimi     // command buffer already has a layout recorded for the attachment.
237*b7893ccfSSadaf Ebrahimi     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
238*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
239*b7893ccfSSadaf Ebrahimi     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
240*b7893ccfSSadaf Ebrahimi     vkCmdEndRenderPass(m_commandBuffer->handle());
241*b7893ccfSSadaf Ebrahimi     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
242*b7893ccfSSadaf Ebrahimi 
243*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
244*b7893ccfSSadaf Ebrahimi 
245*b7893ccfSSadaf Ebrahimi     vkCmdEndRenderPass(m_commandBuffer->handle());
246*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
247*b7893ccfSSadaf Ebrahimi 
248*b7893ccfSSadaf Ebrahimi     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
249*b7893ccfSSadaf Ebrahimi     vkDestroyRenderPass(m_device->device(), rp, nullptr);
250*b7893ccfSSadaf Ebrahimi     vkDestroyImageView(m_device->device(), view, nullptr);
251*b7893ccfSSadaf Ebrahimi }
252*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,RenderPassCreateAttachmentLayoutWithLoadOpThenReadOnly)253*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, RenderPassCreateAttachmentLayoutWithLoadOpThenReadOnly) {
254*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
255*b7893ccfSSadaf Ebrahimi         "Positive test where we create a renderpass with an attachment that uses LOAD_OP_CLEAR, the first subpass has a valid "
256*b7893ccfSSadaf Ebrahimi         "layout, and a second subpass then uses a valid *READ_ONLY* layout.");
257*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
258*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
259*b7893ccfSSadaf Ebrahimi     auto depth_format = FindSupportedDepthStencilFormat(gpu());
260*b7893ccfSSadaf Ebrahimi     if (!depth_format) {
261*b7893ccfSSadaf Ebrahimi         printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
262*b7893ccfSSadaf Ebrahimi         return;
263*b7893ccfSSadaf Ebrahimi     }
264*b7893ccfSSadaf Ebrahimi 
265*b7893ccfSSadaf Ebrahimi     VkAttachmentReference attach[2] = {};
266*b7893ccfSSadaf Ebrahimi     attach[0].attachment = 0;
267*b7893ccfSSadaf Ebrahimi     attach[0].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
268*b7893ccfSSadaf Ebrahimi     attach[1].attachment = 0;
269*b7893ccfSSadaf Ebrahimi     attach[1].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
270*b7893ccfSSadaf Ebrahimi     VkSubpassDescription subpasses[2] = {};
271*b7893ccfSSadaf Ebrahimi     // First subpass clears DS attach on load
272*b7893ccfSSadaf Ebrahimi     subpasses[0].pDepthStencilAttachment = &attach[0];
273*b7893ccfSSadaf Ebrahimi     // 2nd subpass reads in DS as input attachment
274*b7893ccfSSadaf Ebrahimi     subpasses[1].inputAttachmentCount = 1;
275*b7893ccfSSadaf Ebrahimi     subpasses[1].pInputAttachments = &attach[1];
276*b7893ccfSSadaf Ebrahimi     VkAttachmentDescription attach_desc = {};
277*b7893ccfSSadaf Ebrahimi     attach_desc.format = depth_format;
278*b7893ccfSSadaf Ebrahimi     attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
279*b7893ccfSSadaf Ebrahimi     attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
280*b7893ccfSSadaf Ebrahimi     attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
281*b7893ccfSSadaf Ebrahimi     attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
282*b7893ccfSSadaf Ebrahimi     attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
283*b7893ccfSSadaf Ebrahimi     attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
284*b7893ccfSSadaf Ebrahimi     attach_desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
285*b7893ccfSSadaf Ebrahimi     VkRenderPassCreateInfo rpci = {};
286*b7893ccfSSadaf Ebrahimi     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
287*b7893ccfSSadaf Ebrahimi     rpci.attachmentCount = 1;
288*b7893ccfSSadaf Ebrahimi     rpci.pAttachments = &attach_desc;
289*b7893ccfSSadaf Ebrahimi     rpci.subpassCount = 2;
290*b7893ccfSSadaf Ebrahimi     rpci.pSubpasses = subpasses;
291*b7893ccfSSadaf Ebrahimi 
292*b7893ccfSSadaf Ebrahimi     // Now create RenderPass and verify no errors
293*b7893ccfSSadaf Ebrahimi     VkRenderPass rp;
294*b7893ccfSSadaf Ebrahimi     vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
295*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
296*b7893ccfSSadaf Ebrahimi 
297*b7893ccfSSadaf Ebrahimi     vkDestroyRenderPass(m_device->device(), rp, NULL);
298*b7893ccfSSadaf Ebrahimi }
299*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,RenderPassBeginSubpassZeroTransitionsApplied)300*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, RenderPassBeginSubpassZeroTransitionsApplied) {
301*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Ensure that CmdBeginRenderPass applies the layout transitions for the first subpass");
302*b7893ccfSSadaf Ebrahimi 
303*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
304*b7893ccfSSadaf Ebrahimi 
305*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
306*b7893ccfSSadaf Ebrahimi 
307*b7893ccfSSadaf Ebrahimi     // A renderpass with one color attachment.
308*b7893ccfSSadaf Ebrahimi     VkAttachmentDescription attachment = {0,
309*b7893ccfSSadaf Ebrahimi                                           VK_FORMAT_R8G8B8A8_UNORM,
310*b7893ccfSSadaf Ebrahimi                                           VK_SAMPLE_COUNT_1_BIT,
311*b7893ccfSSadaf Ebrahimi                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
312*b7893ccfSSadaf Ebrahimi                                           VK_ATTACHMENT_STORE_OP_STORE,
313*b7893ccfSSadaf Ebrahimi                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
314*b7893ccfSSadaf Ebrahimi                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
315*b7893ccfSSadaf Ebrahimi                                           VK_IMAGE_LAYOUT_UNDEFINED,
316*b7893ccfSSadaf Ebrahimi                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
317*b7893ccfSSadaf Ebrahimi 
318*b7893ccfSSadaf Ebrahimi     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
319*b7893ccfSSadaf Ebrahimi 
320*b7893ccfSSadaf Ebrahimi     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
321*b7893ccfSSadaf Ebrahimi 
322*b7893ccfSSadaf Ebrahimi     VkSubpassDependency dep = {0,
323*b7893ccfSSadaf Ebrahimi                                0,
324*b7893ccfSSadaf Ebrahimi                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
325*b7893ccfSSadaf Ebrahimi                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
326*b7893ccfSSadaf Ebrahimi                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
327*b7893ccfSSadaf Ebrahimi                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
328*b7893ccfSSadaf Ebrahimi                                VK_DEPENDENCY_BY_REGION_BIT};
329*b7893ccfSSadaf Ebrahimi 
330*b7893ccfSSadaf Ebrahimi     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep};
331*b7893ccfSSadaf Ebrahimi 
332*b7893ccfSSadaf Ebrahimi     VkResult err;
333*b7893ccfSSadaf Ebrahimi     VkRenderPass rp;
334*b7893ccfSSadaf Ebrahimi     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
335*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
336*b7893ccfSSadaf Ebrahimi 
337*b7893ccfSSadaf Ebrahimi     // A compatible framebuffer.
338*b7893ccfSSadaf Ebrahimi     VkImageObj image(m_device);
339*b7893ccfSSadaf Ebrahimi     image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
340*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(image.initialized());
341*b7893ccfSSadaf Ebrahimi 
342*b7893ccfSSadaf Ebrahimi     VkImageView view = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
343*b7893ccfSSadaf Ebrahimi 
344*b7893ccfSSadaf Ebrahimi     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
345*b7893ccfSSadaf Ebrahimi     VkFramebuffer fb;
346*b7893ccfSSadaf Ebrahimi     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
347*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
348*b7893ccfSSadaf Ebrahimi 
349*b7893ccfSSadaf Ebrahimi     // Record a single command buffer which issues a pipeline barrier w/
350*b7893ccfSSadaf Ebrahimi     // image memory barrier for the attachment. This detects the previously
351*b7893ccfSSadaf Ebrahimi     // missing tracking of the subpass layout by throwing a validation error
352*b7893ccfSSadaf Ebrahimi     // if it doesn't occur.
353*b7893ccfSSadaf Ebrahimi     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
354*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
355*b7893ccfSSadaf Ebrahimi     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
356*b7893ccfSSadaf Ebrahimi 
357*b7893ccfSSadaf Ebrahimi     image.ImageMemoryBarrier(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
358*b7893ccfSSadaf Ebrahimi                              VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
359*b7893ccfSSadaf Ebrahimi                              VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
360*b7893ccfSSadaf Ebrahimi 
361*b7893ccfSSadaf Ebrahimi     vkCmdEndRenderPass(m_commandBuffer->handle());
362*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
363*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
364*b7893ccfSSadaf Ebrahimi 
365*b7893ccfSSadaf Ebrahimi     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
366*b7893ccfSSadaf Ebrahimi     vkDestroyRenderPass(m_device->device(), rp, nullptr);
367*b7893ccfSSadaf Ebrahimi }
368*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,RenderPassBeginTransitionsAttachmentUnused)369*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, RenderPassBeginTransitionsAttachmentUnused) {
370*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
371*b7893ccfSSadaf Ebrahimi         "Ensure that layout transitions work correctly without errors, when an attachment reference is VK_ATTACHMENT_UNUSED");
372*b7893ccfSSadaf Ebrahimi 
373*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
374*b7893ccfSSadaf Ebrahimi 
375*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
376*b7893ccfSSadaf Ebrahimi 
377*b7893ccfSSadaf Ebrahimi     // A renderpass with no attachments
378*b7893ccfSSadaf Ebrahimi     VkAttachmentReference att_ref = {VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
379*b7893ccfSSadaf Ebrahimi 
380*b7893ccfSSadaf Ebrahimi     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
381*b7893ccfSSadaf Ebrahimi 
382*b7893ccfSSadaf Ebrahimi     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 1, &subpass, 0, nullptr};
383*b7893ccfSSadaf Ebrahimi 
384*b7893ccfSSadaf Ebrahimi     VkRenderPass rp;
385*b7893ccfSSadaf Ebrahimi     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
386*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
387*b7893ccfSSadaf Ebrahimi 
388*b7893ccfSSadaf Ebrahimi     // A compatible framebuffer.
389*b7893ccfSSadaf Ebrahimi     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 32, 32, 1};
390*b7893ccfSSadaf Ebrahimi     VkFramebuffer fb;
391*b7893ccfSSadaf Ebrahimi     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
392*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
393*b7893ccfSSadaf Ebrahimi 
394*b7893ccfSSadaf Ebrahimi     // Record a command buffer which just begins and ends the renderpass. The
395*b7893ccfSSadaf Ebrahimi     // bug manifests in BeginRenderPass.
396*b7893ccfSSadaf Ebrahimi     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
397*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
398*b7893ccfSSadaf Ebrahimi     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
399*b7893ccfSSadaf Ebrahimi     vkCmdEndRenderPass(m_commandBuffer->handle());
400*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
401*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
402*b7893ccfSSadaf Ebrahimi 
403*b7893ccfSSadaf Ebrahimi     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
404*b7893ccfSSadaf Ebrahimi     vkDestroyRenderPass(m_device->device(), rp, nullptr);
405*b7893ccfSSadaf Ebrahimi }
406*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,RenderPassBeginStencilLoadOp)407*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, RenderPassBeginStencilLoadOp) {
408*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Create a stencil-only attachment with a LOAD_OP set to CLEAR. stencil[Load|Store]Op used to be ignored.");
409*b7893ccfSSadaf Ebrahimi     VkResult result = VK_SUCCESS;
410*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
411*b7893ccfSSadaf Ebrahimi     auto depth_format = FindSupportedDepthStencilFormat(gpu());
412*b7893ccfSSadaf Ebrahimi     if (!depth_format) {
413*b7893ccfSSadaf Ebrahimi         printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
414*b7893ccfSSadaf Ebrahimi         return;
415*b7893ccfSSadaf Ebrahimi     }
416*b7893ccfSSadaf Ebrahimi     VkImageFormatProperties formatProps;
417*b7893ccfSSadaf Ebrahimi     vkGetPhysicalDeviceImageFormatProperties(gpu(), depth_format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
418*b7893ccfSSadaf Ebrahimi                                              VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
419*b7893ccfSSadaf Ebrahimi                                              &formatProps);
420*b7893ccfSSadaf Ebrahimi     if (formatProps.maxExtent.width < 100 || formatProps.maxExtent.height < 100) {
421*b7893ccfSSadaf Ebrahimi         printf("%s Image format max extent is too small.\n", kSkipPrefix);
422*b7893ccfSSadaf Ebrahimi         return;
423*b7893ccfSSadaf Ebrahimi     }
424*b7893ccfSSadaf Ebrahimi 
425*b7893ccfSSadaf Ebrahimi     VkFormat depth_stencil_fmt = depth_format;
426*b7893ccfSSadaf Ebrahimi     m_depthStencil->Init(m_device, 100, 100, depth_stencil_fmt,
427*b7893ccfSSadaf Ebrahimi                          VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
428*b7893ccfSSadaf Ebrahimi     VkAttachmentDescription att = {};
429*b7893ccfSSadaf Ebrahimi     VkAttachmentReference ref = {};
430*b7893ccfSSadaf Ebrahimi     att.format = depth_stencil_fmt;
431*b7893ccfSSadaf Ebrahimi     att.samples = VK_SAMPLE_COUNT_1_BIT;
432*b7893ccfSSadaf Ebrahimi     att.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
433*b7893ccfSSadaf Ebrahimi     att.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
434*b7893ccfSSadaf Ebrahimi     att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
435*b7893ccfSSadaf Ebrahimi     att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
436*b7893ccfSSadaf Ebrahimi     att.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
437*b7893ccfSSadaf Ebrahimi     att.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
438*b7893ccfSSadaf Ebrahimi 
439*b7893ccfSSadaf Ebrahimi     VkClearValue clear;
440*b7893ccfSSadaf Ebrahimi     clear.depthStencil.depth = 1.0;
441*b7893ccfSSadaf Ebrahimi     clear.depthStencil.stencil = 0;
442*b7893ccfSSadaf Ebrahimi     ref.attachment = 0;
443*b7893ccfSSadaf Ebrahimi     ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
444*b7893ccfSSadaf Ebrahimi 
445*b7893ccfSSadaf Ebrahimi     VkSubpassDescription subpass = {};
446*b7893ccfSSadaf Ebrahimi     subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
447*b7893ccfSSadaf Ebrahimi     subpass.flags = 0;
448*b7893ccfSSadaf Ebrahimi     subpass.inputAttachmentCount = 0;
449*b7893ccfSSadaf Ebrahimi     subpass.pInputAttachments = NULL;
450*b7893ccfSSadaf Ebrahimi     subpass.colorAttachmentCount = 0;
451*b7893ccfSSadaf Ebrahimi     subpass.pColorAttachments = NULL;
452*b7893ccfSSadaf Ebrahimi     subpass.pResolveAttachments = NULL;
453*b7893ccfSSadaf Ebrahimi     subpass.pDepthStencilAttachment = &ref;
454*b7893ccfSSadaf Ebrahimi     subpass.preserveAttachmentCount = 0;
455*b7893ccfSSadaf Ebrahimi     subpass.pPreserveAttachments = NULL;
456*b7893ccfSSadaf Ebrahimi 
457*b7893ccfSSadaf Ebrahimi     VkRenderPass rp;
458*b7893ccfSSadaf Ebrahimi     VkRenderPassCreateInfo rp_info = {};
459*b7893ccfSSadaf Ebrahimi     rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
460*b7893ccfSSadaf Ebrahimi     rp_info.attachmentCount = 1;
461*b7893ccfSSadaf Ebrahimi     rp_info.pAttachments = &att;
462*b7893ccfSSadaf Ebrahimi     rp_info.subpassCount = 1;
463*b7893ccfSSadaf Ebrahimi     rp_info.pSubpasses = &subpass;
464*b7893ccfSSadaf Ebrahimi     result = vkCreateRenderPass(device(), &rp_info, NULL, &rp);
465*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(result);
466*b7893ccfSSadaf Ebrahimi 
467*b7893ccfSSadaf Ebrahimi     VkImageView *depthView = m_depthStencil->BindInfo();
468*b7893ccfSSadaf Ebrahimi     VkFramebufferCreateInfo fb_info = {};
469*b7893ccfSSadaf Ebrahimi     fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
470*b7893ccfSSadaf Ebrahimi     fb_info.pNext = NULL;
471*b7893ccfSSadaf Ebrahimi     fb_info.renderPass = rp;
472*b7893ccfSSadaf Ebrahimi     fb_info.attachmentCount = 1;
473*b7893ccfSSadaf Ebrahimi     fb_info.pAttachments = depthView;
474*b7893ccfSSadaf Ebrahimi     fb_info.width = 100;
475*b7893ccfSSadaf Ebrahimi     fb_info.height = 100;
476*b7893ccfSSadaf Ebrahimi     fb_info.layers = 1;
477*b7893ccfSSadaf Ebrahimi     VkFramebuffer fb;
478*b7893ccfSSadaf Ebrahimi     result = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
479*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(result);
480*b7893ccfSSadaf Ebrahimi 
481*b7893ccfSSadaf Ebrahimi     VkRenderPassBeginInfo rpbinfo = {};
482*b7893ccfSSadaf Ebrahimi     rpbinfo.clearValueCount = 1;
483*b7893ccfSSadaf Ebrahimi     rpbinfo.pClearValues = &clear;
484*b7893ccfSSadaf Ebrahimi     rpbinfo.pNext = NULL;
485*b7893ccfSSadaf Ebrahimi     rpbinfo.renderPass = rp;
486*b7893ccfSSadaf Ebrahimi     rpbinfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
487*b7893ccfSSadaf Ebrahimi     rpbinfo.renderArea.extent.width = 100;
488*b7893ccfSSadaf Ebrahimi     rpbinfo.renderArea.extent.height = 100;
489*b7893ccfSSadaf Ebrahimi     rpbinfo.renderArea.offset.x = 0;
490*b7893ccfSSadaf Ebrahimi     rpbinfo.renderArea.offset.y = 0;
491*b7893ccfSSadaf Ebrahimi     rpbinfo.framebuffer = fb;
492*b7893ccfSSadaf Ebrahimi 
493*b7893ccfSSadaf Ebrahimi     VkFenceObj fence;
494*b7893ccfSSadaf Ebrahimi     fence.init(*m_device, VkFenceObj::create_info());
495*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(fence.initialized());
496*b7893ccfSSadaf Ebrahimi 
497*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
498*b7893ccfSSadaf Ebrahimi     m_commandBuffer->BeginRenderPass(rpbinfo);
499*b7893ccfSSadaf Ebrahimi     m_commandBuffer->EndRenderPass();
500*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
501*b7893ccfSSadaf Ebrahimi     m_commandBuffer->QueueCommandBuffer(fence);
502*b7893ccfSSadaf Ebrahimi 
503*b7893ccfSSadaf Ebrahimi     VkImageObj destImage(m_device);
504*b7893ccfSSadaf Ebrahimi     destImage.Init(100, 100, 1, depth_stencil_fmt, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
505*b7893ccfSSadaf Ebrahimi                    VK_IMAGE_TILING_OPTIMAL, 0);
506*b7893ccfSSadaf Ebrahimi     fence.wait(VK_TRUE, UINT64_MAX);
507*b7893ccfSSadaf Ebrahimi     VkCommandBufferObj cmdbuf(m_device, m_commandPool);
508*b7893ccfSSadaf Ebrahimi     cmdbuf.begin();
509*b7893ccfSSadaf Ebrahimi 
510*b7893ccfSSadaf Ebrahimi     m_depthStencil->ImageMemoryBarrier(&cmdbuf, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
511*b7893ccfSSadaf Ebrahimi                                        VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
512*b7893ccfSSadaf Ebrahimi                                        VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
513*b7893ccfSSadaf Ebrahimi                                        VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
514*b7893ccfSSadaf Ebrahimi 
515*b7893ccfSSadaf Ebrahimi     destImage.ImageMemoryBarrier(&cmdbuf, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
516*b7893ccfSSadaf Ebrahimi                                  VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 0,
517*b7893ccfSSadaf Ebrahimi                                  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
518*b7893ccfSSadaf Ebrahimi     VkImageCopy cregion;
519*b7893ccfSSadaf Ebrahimi     cregion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
520*b7893ccfSSadaf Ebrahimi     cregion.srcSubresource.mipLevel = 0;
521*b7893ccfSSadaf Ebrahimi     cregion.srcSubresource.baseArrayLayer = 0;
522*b7893ccfSSadaf Ebrahimi     cregion.srcSubresource.layerCount = 1;
523*b7893ccfSSadaf Ebrahimi     cregion.srcOffset.x = 0;
524*b7893ccfSSadaf Ebrahimi     cregion.srcOffset.y = 0;
525*b7893ccfSSadaf Ebrahimi     cregion.srcOffset.z = 0;
526*b7893ccfSSadaf Ebrahimi     cregion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
527*b7893ccfSSadaf Ebrahimi     cregion.dstSubresource.mipLevel = 0;
528*b7893ccfSSadaf Ebrahimi     cregion.dstSubresource.baseArrayLayer = 0;
529*b7893ccfSSadaf Ebrahimi     cregion.dstSubresource.layerCount = 1;
530*b7893ccfSSadaf Ebrahimi     cregion.dstOffset.x = 0;
531*b7893ccfSSadaf Ebrahimi     cregion.dstOffset.y = 0;
532*b7893ccfSSadaf Ebrahimi     cregion.dstOffset.z = 0;
533*b7893ccfSSadaf Ebrahimi     cregion.extent.width = 100;
534*b7893ccfSSadaf Ebrahimi     cregion.extent.height = 100;
535*b7893ccfSSadaf Ebrahimi     cregion.extent.depth = 1;
536*b7893ccfSSadaf Ebrahimi     cmdbuf.CopyImage(m_depthStencil->handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, destImage.handle(),
537*b7893ccfSSadaf Ebrahimi                      VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cregion);
538*b7893ccfSSadaf Ebrahimi     cmdbuf.end();
539*b7893ccfSSadaf Ebrahimi 
540*b7893ccfSSadaf Ebrahimi     VkSubmitInfo submit_info;
541*b7893ccfSSadaf Ebrahimi     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
542*b7893ccfSSadaf Ebrahimi     submit_info.pNext = NULL;
543*b7893ccfSSadaf Ebrahimi     submit_info.waitSemaphoreCount = 0;
544*b7893ccfSSadaf Ebrahimi     submit_info.pWaitSemaphores = NULL;
545*b7893ccfSSadaf Ebrahimi     submit_info.pWaitDstStageMask = NULL;
546*b7893ccfSSadaf Ebrahimi     submit_info.commandBufferCount = 1;
547*b7893ccfSSadaf Ebrahimi     submit_info.pCommandBuffers = &cmdbuf.handle();
548*b7893ccfSSadaf Ebrahimi     submit_info.signalSemaphoreCount = 0;
549*b7893ccfSSadaf Ebrahimi     submit_info.pSignalSemaphores = NULL;
550*b7893ccfSSadaf Ebrahimi 
551*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
552*b7893ccfSSadaf Ebrahimi     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
553*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
554*b7893ccfSSadaf Ebrahimi 
555*b7893ccfSSadaf Ebrahimi     vkQueueWaitIdle(m_device->m_queue);
556*b7893ccfSSadaf Ebrahimi     vkDestroyRenderPass(m_device->device(), rp, nullptr);
557*b7893ccfSSadaf Ebrahimi     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
558*b7893ccfSSadaf Ebrahimi }
559*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,RenderPassBeginInlineAndSecondaryCommandBuffers)560*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, RenderPassBeginInlineAndSecondaryCommandBuffers) {
561*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
562*b7893ccfSSadaf Ebrahimi 
563*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
564*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
565*b7893ccfSSadaf Ebrahimi 
566*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
567*b7893ccfSSadaf Ebrahimi 
568*b7893ccfSSadaf Ebrahimi     vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
569*b7893ccfSSadaf Ebrahimi     vkCmdEndRenderPass(m_commandBuffer->handle());
570*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
571*b7893ccfSSadaf Ebrahimi     vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
572*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
573*b7893ccfSSadaf Ebrahimi     vkCmdEndRenderPass(m_commandBuffer->handle());
574*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
575*b7893ccfSSadaf Ebrahimi 
576*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
577*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
578*b7893ccfSSadaf Ebrahimi }
579*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,RenderPassBeginDepthStencilLayoutTransitionFromUndefined)580*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, RenderPassBeginDepthStencilLayoutTransitionFromUndefined) {
581*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
582*b7893ccfSSadaf Ebrahimi         "Create a render pass with depth-stencil attachment where layout transition from UNDEFINED TO DS_READ_ONLY_OPTIMAL is set "
583*b7893ccfSSadaf Ebrahimi         "by render pass and verify that transition has correctly occurred at queue submit time with no validation errors.");
584*b7893ccfSSadaf Ebrahimi 
585*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
586*b7893ccfSSadaf Ebrahimi     auto depth_format = FindSupportedDepthStencilFormat(gpu());
587*b7893ccfSSadaf Ebrahimi     if (!depth_format) {
588*b7893ccfSSadaf Ebrahimi         printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
589*b7893ccfSSadaf Ebrahimi         return;
590*b7893ccfSSadaf Ebrahimi     }
591*b7893ccfSSadaf Ebrahimi     VkImageFormatProperties format_props;
592*b7893ccfSSadaf Ebrahimi     vkGetPhysicalDeviceImageFormatProperties(gpu(), depth_format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
593*b7893ccfSSadaf Ebrahimi                                              VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 0, &format_props);
594*b7893ccfSSadaf Ebrahimi     if (format_props.maxExtent.width < 32 || format_props.maxExtent.height < 32) {
595*b7893ccfSSadaf Ebrahimi         printf("%s Depth extent too small, RenderPassDepthStencilLayoutTransition skipped.\n", kSkipPrefix);
596*b7893ccfSSadaf Ebrahimi         return;
597*b7893ccfSSadaf Ebrahimi     }
598*b7893ccfSSadaf Ebrahimi 
599*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
600*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
601*b7893ccfSSadaf Ebrahimi 
602*b7893ccfSSadaf Ebrahimi     // A renderpass with one depth/stencil attachment.
603*b7893ccfSSadaf Ebrahimi     VkAttachmentDescription attachment = {0,
604*b7893ccfSSadaf Ebrahimi                                           depth_format,
605*b7893ccfSSadaf Ebrahimi                                           VK_SAMPLE_COUNT_1_BIT,
606*b7893ccfSSadaf Ebrahimi                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
607*b7893ccfSSadaf Ebrahimi                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
608*b7893ccfSSadaf Ebrahimi                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
609*b7893ccfSSadaf Ebrahimi                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
610*b7893ccfSSadaf Ebrahimi                                           VK_IMAGE_LAYOUT_UNDEFINED,
611*b7893ccfSSadaf Ebrahimi                                           VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
612*b7893ccfSSadaf Ebrahimi 
613*b7893ccfSSadaf Ebrahimi     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
614*b7893ccfSSadaf Ebrahimi 
615*b7893ccfSSadaf Ebrahimi     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &att_ref, 0, nullptr};
616*b7893ccfSSadaf Ebrahimi 
617*b7893ccfSSadaf Ebrahimi     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
618*b7893ccfSSadaf Ebrahimi 
619*b7893ccfSSadaf Ebrahimi     VkRenderPass rp;
620*b7893ccfSSadaf Ebrahimi     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
621*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
622*b7893ccfSSadaf Ebrahimi     // A compatible ds image.
623*b7893ccfSSadaf Ebrahimi     VkImageObj image(m_device);
624*b7893ccfSSadaf Ebrahimi     image.Init(32, 32, 1, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
625*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(image.initialized());
626*b7893ccfSSadaf Ebrahimi 
627*b7893ccfSSadaf Ebrahimi     VkImageViewCreateInfo ivci = {
628*b7893ccfSSadaf Ebrahimi         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
629*b7893ccfSSadaf Ebrahimi         nullptr,
630*b7893ccfSSadaf Ebrahimi         0,
631*b7893ccfSSadaf Ebrahimi         image.handle(),
632*b7893ccfSSadaf Ebrahimi         VK_IMAGE_VIEW_TYPE_2D,
633*b7893ccfSSadaf Ebrahimi         depth_format,
634*b7893ccfSSadaf Ebrahimi         {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
635*b7893ccfSSadaf Ebrahimi          VK_COMPONENT_SWIZZLE_IDENTITY},
636*b7893ccfSSadaf Ebrahimi         {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 1, 0, 1},
637*b7893ccfSSadaf Ebrahimi     };
638*b7893ccfSSadaf Ebrahimi     VkImageView view;
639*b7893ccfSSadaf Ebrahimi     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
640*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
641*b7893ccfSSadaf Ebrahimi 
642*b7893ccfSSadaf Ebrahimi     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
643*b7893ccfSSadaf Ebrahimi     VkFramebuffer fb;
644*b7893ccfSSadaf Ebrahimi     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
645*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
646*b7893ccfSSadaf Ebrahimi 
647*b7893ccfSSadaf Ebrahimi     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
648*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
649*b7893ccfSSadaf Ebrahimi     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
650*b7893ccfSSadaf Ebrahimi     vkCmdEndRenderPass(m_commandBuffer->handle());
651*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
652*b7893ccfSSadaf Ebrahimi     m_commandBuffer->QueueCommandBuffer(false);
653*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
654*b7893ccfSSadaf Ebrahimi 
655*b7893ccfSSadaf Ebrahimi     // Cleanup
656*b7893ccfSSadaf Ebrahimi     vkDestroyImageView(m_device->device(), view, NULL);
657*b7893ccfSSadaf Ebrahimi     vkDestroyRenderPass(m_device->device(), rp, NULL);
658*b7893ccfSSadaf Ebrahimi     vkDestroyFramebuffer(m_device->device(), fb, NULL);
659*b7893ccfSSadaf Ebrahimi }
660*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,DestroyPipelineRenderPass)661*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, DestroyPipelineRenderPass) {
662*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Draw using a pipeline whose create renderPass has been destroyed.");
663*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
664*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
665*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
666*b7893ccfSSadaf Ebrahimi 
667*b7893ccfSSadaf Ebrahimi     VkResult err;
668*b7893ccfSSadaf Ebrahimi 
669*b7893ccfSSadaf Ebrahimi     // Create a renderPass that's compatible with Draw-time renderPass
670*b7893ccfSSadaf Ebrahimi     VkAttachmentDescription att = {};
671*b7893ccfSSadaf Ebrahimi     att.format = m_render_target_fmt;
672*b7893ccfSSadaf Ebrahimi     att.samples = VK_SAMPLE_COUNT_1_BIT;
673*b7893ccfSSadaf Ebrahimi     att.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
674*b7893ccfSSadaf Ebrahimi     att.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
675*b7893ccfSSadaf Ebrahimi     att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
676*b7893ccfSSadaf Ebrahimi     att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
677*b7893ccfSSadaf Ebrahimi     att.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
678*b7893ccfSSadaf Ebrahimi     att.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
679*b7893ccfSSadaf Ebrahimi 
680*b7893ccfSSadaf Ebrahimi     VkAttachmentReference ref = {};
681*b7893ccfSSadaf Ebrahimi     ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
682*b7893ccfSSadaf Ebrahimi     ref.attachment = 0;
683*b7893ccfSSadaf Ebrahimi 
684*b7893ccfSSadaf Ebrahimi     m_renderPassClearValues.clear();
685*b7893ccfSSadaf Ebrahimi     VkClearValue clear = {};
686*b7893ccfSSadaf Ebrahimi     clear.color = m_clear_color;
687*b7893ccfSSadaf Ebrahimi 
688*b7893ccfSSadaf Ebrahimi     VkSubpassDescription subpass = {};
689*b7893ccfSSadaf Ebrahimi     subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
690*b7893ccfSSadaf Ebrahimi     subpass.flags = 0;
691*b7893ccfSSadaf Ebrahimi     subpass.inputAttachmentCount = 0;
692*b7893ccfSSadaf Ebrahimi     subpass.pInputAttachments = NULL;
693*b7893ccfSSadaf Ebrahimi     subpass.colorAttachmentCount = 1;
694*b7893ccfSSadaf Ebrahimi     subpass.pColorAttachments = &ref;
695*b7893ccfSSadaf Ebrahimi     subpass.pResolveAttachments = NULL;
696*b7893ccfSSadaf Ebrahimi 
697*b7893ccfSSadaf Ebrahimi     subpass.pDepthStencilAttachment = NULL;
698*b7893ccfSSadaf Ebrahimi     subpass.preserveAttachmentCount = 0;
699*b7893ccfSSadaf Ebrahimi     subpass.pPreserveAttachments = NULL;
700*b7893ccfSSadaf Ebrahimi 
701*b7893ccfSSadaf Ebrahimi     VkRenderPassCreateInfo rp_info = {};
702*b7893ccfSSadaf Ebrahimi     rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
703*b7893ccfSSadaf Ebrahimi     rp_info.attachmentCount = 1;
704*b7893ccfSSadaf Ebrahimi     rp_info.pAttachments = &att;
705*b7893ccfSSadaf Ebrahimi     rp_info.subpassCount = 1;
706*b7893ccfSSadaf Ebrahimi     rp_info.pSubpasses = &subpass;
707*b7893ccfSSadaf Ebrahimi 
708*b7893ccfSSadaf Ebrahimi     VkRenderPass rp;
709*b7893ccfSSadaf Ebrahimi     err = vkCreateRenderPass(device(), &rp_info, NULL, &rp);
710*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
711*b7893ccfSSadaf Ebrahimi 
712*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
713*b7893ccfSSadaf Ebrahimi     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
714*b7893ccfSSadaf Ebrahimi 
715*b7893ccfSSadaf Ebrahimi     VkPipelineObj pipe(m_device);
716*b7893ccfSSadaf Ebrahimi     pipe.AddDefaultColorAttachment();
717*b7893ccfSSadaf Ebrahimi     pipe.AddShader(&vs);
718*b7893ccfSSadaf Ebrahimi     pipe.AddShader(&fs);
719*b7893ccfSSadaf Ebrahimi     VkViewport viewport = {0.0f, 0.0f, 64.0f, 64.0f, 0.0f, 1.0f};
720*b7893ccfSSadaf Ebrahimi     m_viewports.push_back(viewport);
721*b7893ccfSSadaf Ebrahimi     pipe.SetViewport(m_viewports);
722*b7893ccfSSadaf Ebrahimi     VkRect2D rect = {{0, 0}, {64, 64}};
723*b7893ccfSSadaf Ebrahimi     m_scissors.push_back(rect);
724*b7893ccfSSadaf Ebrahimi     pipe.SetScissor(m_scissors);
725*b7893ccfSSadaf Ebrahimi 
726*b7893ccfSSadaf Ebrahimi     const VkPipelineLayoutObj pl(m_device);
727*b7893ccfSSadaf Ebrahimi     pipe.CreateVKPipeline(pl.handle(), rp);
728*b7893ccfSSadaf Ebrahimi 
729*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
730*b7893ccfSSadaf Ebrahimi     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
731*b7893ccfSSadaf Ebrahimi     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
732*b7893ccfSSadaf Ebrahimi     // Destroy renderPass before pipeline is used in Draw
733*b7893ccfSSadaf Ebrahimi     //  We delay until after CmdBindPipeline to verify that invalid binding isn't
734*b7893ccfSSadaf Ebrahimi     //  created between CB & renderPass, which we used to do.
735*b7893ccfSSadaf Ebrahimi     vkDestroyRenderPass(m_device->device(), rp, nullptr);
736*b7893ccfSSadaf Ebrahimi     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
737*b7893ccfSSadaf Ebrahimi     vkCmdEndRenderPass(m_commandBuffer->handle());
738*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
739*b7893ccfSSadaf Ebrahimi 
740*b7893ccfSSadaf Ebrahimi     VkSubmitInfo submit_info = {};
741*b7893ccfSSadaf Ebrahimi     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
742*b7893ccfSSadaf Ebrahimi     submit_info.commandBufferCount = 1;
743*b7893ccfSSadaf Ebrahimi     submit_info.pCommandBuffers = &m_commandBuffer->handle();
744*b7893ccfSSadaf Ebrahimi     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
745*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
746*b7893ccfSSadaf Ebrahimi     vkQueueWaitIdle(m_device->m_queue);
747*b7893ccfSSadaf Ebrahimi }
748*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,BasicQuery)749*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, BasicQuery) {
750*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Use a couple occlusion queries");
751*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
752*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
753*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
754*b7893ccfSSadaf Ebrahimi 
755*b7893ccfSSadaf Ebrahimi     uint32_t qfi = 0;
756*b7893ccfSSadaf Ebrahimi     VkBufferCreateInfo bci = {};
757*b7893ccfSSadaf Ebrahimi     bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
758*b7893ccfSSadaf Ebrahimi     bci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
759*b7893ccfSSadaf Ebrahimi     bci.size = 4 * sizeof(uint64_t);
760*b7893ccfSSadaf Ebrahimi     bci.queueFamilyIndexCount = 1;
761*b7893ccfSSadaf Ebrahimi     bci.pQueueFamilyIndices = &qfi;
762*b7893ccfSSadaf Ebrahimi     VkBufferObj buffer;
763*b7893ccfSSadaf Ebrahimi     VkMemoryPropertyFlags mem_props = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
764*b7893ccfSSadaf Ebrahimi     buffer.init(*m_device, bci, mem_props);
765*b7893ccfSSadaf Ebrahimi 
766*b7893ccfSSadaf Ebrahimi     VkQueryPool query_pool;
767*b7893ccfSSadaf Ebrahimi     VkQueryPoolCreateInfo query_pool_info;
768*b7893ccfSSadaf Ebrahimi     query_pool_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
769*b7893ccfSSadaf Ebrahimi     query_pool_info.pNext = NULL;
770*b7893ccfSSadaf Ebrahimi     query_pool_info.queryType = VK_QUERY_TYPE_OCCLUSION;
771*b7893ccfSSadaf Ebrahimi     query_pool_info.flags = 0;
772*b7893ccfSSadaf Ebrahimi     query_pool_info.queryCount = 2;
773*b7893ccfSSadaf Ebrahimi     query_pool_info.pipelineStatistics = 0;
774*b7893ccfSSadaf Ebrahimi 
775*b7893ccfSSadaf Ebrahimi     VkResult res = vkCreateQueryPool(m_device->handle(), &query_pool_info, NULL, &query_pool);
776*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(res);
777*b7893ccfSSadaf Ebrahimi 
778*b7893ccfSSadaf Ebrahimi     CreatePipelineHelper pipe(*this);
779*b7893ccfSSadaf Ebrahimi     pipe.InitInfo();
780*b7893ccfSSadaf Ebrahimi     pipe.InitState();
781*b7893ccfSSadaf Ebrahimi     pipe.CreateGraphicsPipeline();
782*b7893ccfSSadaf Ebrahimi 
783*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
784*b7893ccfSSadaf Ebrahimi     vkCmdResetQueryPool(m_commandBuffer->handle(), query_pool, 0, 2);
785*b7893ccfSSadaf Ebrahimi     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
786*b7893ccfSSadaf Ebrahimi     vkCmdBeginQuery(m_commandBuffer->handle(), query_pool, 0, 0);
787*b7893ccfSSadaf Ebrahimi     vkCmdEndQuery(m_commandBuffer->handle(), query_pool, 0);
788*b7893ccfSSadaf Ebrahimi     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
789*b7893ccfSSadaf Ebrahimi     vkCmdBeginQuery(m_commandBuffer->handle(), query_pool, 1, 0);
790*b7893ccfSSadaf Ebrahimi     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
791*b7893ccfSSadaf Ebrahimi     vkCmdEndRenderPass(m_commandBuffer->handle());
792*b7893ccfSSadaf Ebrahimi     vkCmdEndQuery(m_commandBuffer->handle(), query_pool, 1);
793*b7893ccfSSadaf Ebrahimi     vkCmdCopyQueryPoolResults(m_commandBuffer->handle(), query_pool, 0, 2, buffer.handle(), 0, sizeof(uint64_t),
794*b7893ccfSSadaf Ebrahimi                               VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
795*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
796*b7893ccfSSadaf Ebrahimi 
797*b7893ccfSSadaf Ebrahimi     VkSubmitInfo submit_info = {};
798*b7893ccfSSadaf Ebrahimi     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
799*b7893ccfSSadaf Ebrahimi     submit_info.commandBufferCount = 1;
800*b7893ccfSSadaf Ebrahimi     submit_info.pCommandBuffers = &m_commandBuffer->handle();
801*b7893ccfSSadaf Ebrahimi     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
802*b7893ccfSSadaf Ebrahimi 
803*b7893ccfSSadaf Ebrahimi     vkQueueWaitIdle(m_device->m_queue);
804*b7893ccfSSadaf Ebrahimi     uint64_t samples_passed[4];
805*b7893ccfSSadaf Ebrahimi     res = vkGetQueryPoolResults(m_device->handle(), query_pool, 0, 2, sizeof(samples_passed), samples_passed, sizeof(uint64_t),
806*b7893ccfSSadaf Ebrahimi                                 VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
807*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(res);
808*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
809*b7893ccfSSadaf Ebrahimi     vkDestroyQueryPool(m_device->handle(), query_pool, NULL);
810*b7893ccfSSadaf Ebrahimi }
811*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,MultiplaneGetImageSubresourceLayout)812*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, MultiplaneGetImageSubresourceLayout) {
813*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Positive test, query layout of a single plane of a multiplane image. (repro Github #2530)");
814*b7893ccfSSadaf Ebrahimi 
815*b7893ccfSSadaf Ebrahimi     // Enable KHR multiplane req'd extensions
816*b7893ccfSSadaf Ebrahimi     bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
817*b7893ccfSSadaf Ebrahimi                                                     VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION);
818*b7893ccfSSadaf Ebrahimi     if (mp_extensions) {
819*b7893ccfSSadaf Ebrahimi         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
820*b7893ccfSSadaf Ebrahimi     }
821*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
822*b7893ccfSSadaf Ebrahimi     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
823*b7893ccfSSadaf Ebrahimi     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
824*b7893ccfSSadaf Ebrahimi     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
825*b7893ccfSSadaf Ebrahimi     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
826*b7893ccfSSadaf Ebrahimi     if (mp_extensions) {
827*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
828*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
829*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
830*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
831*b7893ccfSSadaf Ebrahimi     } else {
832*b7893ccfSSadaf Ebrahimi         printf("%s test requires KHR multiplane extensions, not available.  Skipping.\n", kSkipPrefix);
833*b7893ccfSSadaf Ebrahimi         return;
834*b7893ccfSSadaf Ebrahimi     }
835*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
836*b7893ccfSSadaf Ebrahimi 
837*b7893ccfSSadaf Ebrahimi     VkImageCreateInfo ci = {};
838*b7893ccfSSadaf Ebrahimi     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
839*b7893ccfSSadaf Ebrahimi     ci.pNext = NULL;
840*b7893ccfSSadaf Ebrahimi     ci.flags = 0;
841*b7893ccfSSadaf Ebrahimi     ci.imageType = VK_IMAGE_TYPE_2D;
842*b7893ccfSSadaf Ebrahimi     ci.format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR;
843*b7893ccfSSadaf Ebrahimi     ci.extent = {128, 128, 1};
844*b7893ccfSSadaf Ebrahimi     ci.mipLevels = 1;
845*b7893ccfSSadaf Ebrahimi     ci.arrayLayers = 1;
846*b7893ccfSSadaf Ebrahimi     ci.samples = VK_SAMPLE_COUNT_1_BIT;
847*b7893ccfSSadaf Ebrahimi     ci.tiling = VK_IMAGE_TILING_LINEAR;
848*b7893ccfSSadaf Ebrahimi     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
849*b7893ccfSSadaf Ebrahimi     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
850*b7893ccfSSadaf Ebrahimi     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
851*b7893ccfSSadaf Ebrahimi 
852*b7893ccfSSadaf Ebrahimi     // Verify format
853*b7893ccfSSadaf Ebrahimi     bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), ci, VK_FORMAT_FEATURE_TRANSFER_SRC_BIT);
854*b7893ccfSSadaf Ebrahimi     if (!supported) {
855*b7893ccfSSadaf Ebrahimi         printf("%s Multiplane image format not supported.  Skipping test.\n", kSkipPrefix);
856*b7893ccfSSadaf Ebrahimi         return;  // Assume there's low ROI on searching for different mp formats
857*b7893ccfSSadaf Ebrahimi     }
858*b7893ccfSSadaf Ebrahimi 
859*b7893ccfSSadaf Ebrahimi     VkImage image;
860*b7893ccfSSadaf Ebrahimi     VkResult err = vkCreateImage(device(), &ci, NULL, &image);
861*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
862*b7893ccfSSadaf Ebrahimi 
863*b7893ccfSSadaf Ebrahimi     // Query layout of 3rd plane
864*b7893ccfSSadaf Ebrahimi     VkImageSubresource subres = {};
865*b7893ccfSSadaf Ebrahimi     subres.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
866*b7893ccfSSadaf Ebrahimi     subres.mipLevel = 0;
867*b7893ccfSSadaf Ebrahimi     subres.arrayLayer = 0;
868*b7893ccfSSadaf Ebrahimi     VkSubresourceLayout layout = {};
869*b7893ccfSSadaf Ebrahimi 
870*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
871*b7893ccfSSadaf Ebrahimi     vkGetImageSubresourceLayout(device(), image, &subres, &layout);
872*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
873*b7893ccfSSadaf Ebrahimi 
874*b7893ccfSSadaf Ebrahimi     vkDestroyImage(device(), image, NULL);
875*b7893ccfSSadaf Ebrahimi }
876*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,OwnershipTranfersImage)877*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, OwnershipTranfersImage) {
878*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Valid image ownership transfers that shouldn't create errors");
879*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
880*b7893ccfSSadaf Ebrahimi 
881*b7893ccfSSadaf Ebrahimi     uint32_t no_gfx = m_device->QueueFamilyWithoutCapabilities(VK_QUEUE_GRAPHICS_BIT);
882*b7893ccfSSadaf Ebrahimi     if (no_gfx == UINT32_MAX) {
883*b7893ccfSSadaf Ebrahimi         printf("%s Required queue families not present (non-graphics capable required).\n", kSkipPrefix);
884*b7893ccfSSadaf Ebrahimi         return;
885*b7893ccfSSadaf Ebrahimi     }
886*b7893ccfSSadaf Ebrahimi     VkQueueObj *no_gfx_queue = m_device->queue_family_queues(no_gfx)[0].get();
887*b7893ccfSSadaf Ebrahimi 
888*b7893ccfSSadaf Ebrahimi     VkCommandPoolObj no_gfx_pool(m_device, no_gfx, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
889*b7893ccfSSadaf Ebrahimi     VkCommandBufferObj no_gfx_cb(m_device, &no_gfx_pool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, no_gfx_queue);
890*b7893ccfSSadaf Ebrahimi 
891*b7893ccfSSadaf Ebrahimi     // Create an "exclusive" image owned by the graphics queue.
892*b7893ccfSSadaf Ebrahimi     VkImageObj image(m_device);
893*b7893ccfSSadaf Ebrahimi     VkFlags image_use = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
894*b7893ccfSSadaf Ebrahimi     image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, image_use, VK_IMAGE_TILING_OPTIMAL, 0);
895*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(image.initialized());
896*b7893ccfSSadaf Ebrahimi     auto image_subres = image.subresource_range(VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1);
897*b7893ccfSSadaf Ebrahimi     auto image_barrier = image.image_memory_barrier(0, 0, image.Layout(), image.Layout(), image_subres);
898*b7893ccfSSadaf Ebrahimi     image_barrier.srcQueueFamilyIndex = m_device->graphics_queue_node_index_;
899*b7893ccfSSadaf Ebrahimi     image_barrier.dstQueueFamilyIndex = no_gfx;
900*b7893ccfSSadaf Ebrahimi 
901*b7893ccfSSadaf Ebrahimi     ValidOwnershipTransfer(m_errorMonitor, m_commandBuffer, &no_gfx_cb, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
902*b7893ccfSSadaf Ebrahimi                            VK_PIPELINE_STAGE_TRANSFER_BIT, nullptr, &image_barrier);
903*b7893ccfSSadaf Ebrahimi 
904*b7893ccfSSadaf Ebrahimi     // Change layouts while changing ownership
905*b7893ccfSSadaf Ebrahimi     image_barrier.srcQueueFamilyIndex = no_gfx;
906*b7893ccfSSadaf Ebrahimi     image_barrier.dstQueueFamilyIndex = m_device->graphics_queue_node_index_;
907*b7893ccfSSadaf Ebrahimi     image_barrier.oldLayout = image.Layout();
908*b7893ccfSSadaf Ebrahimi     // Make sure the new layout is different from the old
909*b7893ccfSSadaf Ebrahimi     if (image_barrier.oldLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
910*b7893ccfSSadaf Ebrahimi         image_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
911*b7893ccfSSadaf Ebrahimi     } else {
912*b7893ccfSSadaf Ebrahimi         image_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
913*b7893ccfSSadaf Ebrahimi     }
914*b7893ccfSSadaf Ebrahimi 
915*b7893ccfSSadaf Ebrahimi     ValidOwnershipTransfer(m_errorMonitor, &no_gfx_cb, m_commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
916*b7893ccfSSadaf Ebrahimi                            VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, nullptr, &image_barrier);
917*b7893ccfSSadaf Ebrahimi }
918*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,OwnershipTranfersBuffer)919*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, OwnershipTranfersBuffer) {
920*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Valid buffer ownership transfers that shouldn't create errors");
921*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
922*b7893ccfSSadaf Ebrahimi 
923*b7893ccfSSadaf Ebrahimi     uint32_t no_gfx = m_device->QueueFamilyWithoutCapabilities(VK_QUEUE_GRAPHICS_BIT);
924*b7893ccfSSadaf Ebrahimi     if (no_gfx == UINT32_MAX) {
925*b7893ccfSSadaf Ebrahimi         printf("%s Required queue families not present (non-graphics capable required).\n", kSkipPrefix);
926*b7893ccfSSadaf Ebrahimi         return;
927*b7893ccfSSadaf Ebrahimi     }
928*b7893ccfSSadaf Ebrahimi     VkQueueObj *no_gfx_queue = m_device->queue_family_queues(no_gfx)[0].get();
929*b7893ccfSSadaf Ebrahimi 
930*b7893ccfSSadaf Ebrahimi     VkCommandPoolObj no_gfx_pool(m_device, no_gfx, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
931*b7893ccfSSadaf Ebrahimi     VkCommandBufferObj no_gfx_cb(m_device, &no_gfx_pool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, no_gfx_queue);
932*b7893ccfSSadaf Ebrahimi 
933*b7893ccfSSadaf Ebrahimi     // Create a buffer
934*b7893ccfSSadaf Ebrahimi     const VkDeviceSize buffer_size = 256;
935*b7893ccfSSadaf Ebrahimi     uint8_t data[buffer_size] = {0xFF};
936*b7893ccfSSadaf Ebrahimi     VkConstantBufferObj buffer(m_device, buffer_size, data, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT);
937*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(buffer.initialized());
938*b7893ccfSSadaf Ebrahimi     auto buffer_barrier = buffer.buffer_memory_barrier(0, 0, 0, VK_WHOLE_SIZE);
939*b7893ccfSSadaf Ebrahimi 
940*b7893ccfSSadaf Ebrahimi     // Let gfx own it.
941*b7893ccfSSadaf Ebrahimi     buffer_barrier.srcQueueFamilyIndex = m_device->graphics_queue_node_index_;
942*b7893ccfSSadaf Ebrahimi     buffer_barrier.dstQueueFamilyIndex = m_device->graphics_queue_node_index_;
943*b7893ccfSSadaf Ebrahimi     ValidOwnershipTransferOp(m_errorMonitor, m_commandBuffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
944*b7893ccfSSadaf Ebrahimi                              &buffer_barrier, nullptr);
945*b7893ccfSSadaf Ebrahimi 
946*b7893ccfSSadaf Ebrahimi     // Transfer it to non-gfx
947*b7893ccfSSadaf Ebrahimi     buffer_barrier.dstQueueFamilyIndex = no_gfx;
948*b7893ccfSSadaf Ebrahimi     ValidOwnershipTransfer(m_errorMonitor, m_commandBuffer, &no_gfx_cb, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
949*b7893ccfSSadaf Ebrahimi                            VK_PIPELINE_STAGE_TRANSFER_BIT, &buffer_barrier, nullptr);
950*b7893ccfSSadaf Ebrahimi 
951*b7893ccfSSadaf Ebrahimi     // Transfer it to gfx
952*b7893ccfSSadaf Ebrahimi     buffer_barrier.srcQueueFamilyIndex = no_gfx;
953*b7893ccfSSadaf Ebrahimi     buffer_barrier.dstQueueFamilyIndex = m_device->graphics_queue_node_index_;
954*b7893ccfSSadaf Ebrahimi     ValidOwnershipTransfer(m_errorMonitor, &no_gfx_cb, m_commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
955*b7893ccfSSadaf Ebrahimi                            VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, &buffer_barrier, nullptr);
956*b7893ccfSSadaf Ebrahimi }
957*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,LayoutFromPresentWithoutAccessMemoryRead)958*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, LayoutFromPresentWithoutAccessMemoryRead) {
959*b7893ccfSSadaf Ebrahimi     // Transition an image away from PRESENT_SRC_KHR without ACCESS_MEMORY_READ
960*b7893ccfSSadaf Ebrahimi     // in srcAccessMask.
961*b7893ccfSSadaf Ebrahimi 
962*b7893ccfSSadaf Ebrahimi     // The required behavior here was a bit unclear in earlier versions of the
963*b7893ccfSSadaf Ebrahimi     // spec, but there is no memory dependency required here, so this should
964*b7893ccfSSadaf Ebrahimi     // work without warnings.
965*b7893ccfSSadaf Ebrahimi 
966*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
967*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
968*b7893ccfSSadaf Ebrahimi     VkImageObj image(m_device);
969*b7893ccfSSadaf Ebrahimi     image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT),
970*b7893ccfSSadaf Ebrahimi                VK_IMAGE_TILING_OPTIMAL, 0);
971*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(image.initialized());
972*b7893ccfSSadaf Ebrahimi 
973*b7893ccfSSadaf Ebrahimi     VkImageMemoryBarrier barrier = {};
974*b7893ccfSSadaf Ebrahimi     VkImageSubresourceRange range;
975*b7893ccfSSadaf Ebrahimi     barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
976*b7893ccfSSadaf Ebrahimi     barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
977*b7893ccfSSadaf Ebrahimi     barrier.dstAccessMask = 0;
978*b7893ccfSSadaf Ebrahimi     barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
979*b7893ccfSSadaf Ebrahimi     barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
980*b7893ccfSSadaf Ebrahimi     barrier.image = image.handle();
981*b7893ccfSSadaf Ebrahimi     range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
982*b7893ccfSSadaf Ebrahimi     range.baseMipLevel = 0;
983*b7893ccfSSadaf Ebrahimi     range.levelCount = 1;
984*b7893ccfSSadaf Ebrahimi     range.baseArrayLayer = 0;
985*b7893ccfSSadaf Ebrahimi     range.layerCount = 1;
986*b7893ccfSSadaf Ebrahimi     barrier.subresourceRange = range;
987*b7893ccfSSadaf Ebrahimi     VkCommandBufferObj cmdbuf(m_device, m_commandPool);
988*b7893ccfSSadaf Ebrahimi     cmdbuf.begin();
989*b7893ccfSSadaf Ebrahimi     cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
990*b7893ccfSSadaf Ebrahimi                            &barrier);
991*b7893ccfSSadaf Ebrahimi     barrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
992*b7893ccfSSadaf Ebrahimi     barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
993*b7893ccfSSadaf Ebrahimi     barrier.srcAccessMask = 0;
994*b7893ccfSSadaf Ebrahimi     barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
995*b7893ccfSSadaf Ebrahimi     cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
996*b7893ccfSSadaf Ebrahimi                            &barrier);
997*b7893ccfSSadaf Ebrahimi 
998*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
999*b7893ccfSSadaf Ebrahimi }
1000*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CopyNonupdatedDescriptors)1001*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CopyNonupdatedDescriptors) {
1002*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Copy non-updated descriptors");
1003*b7893ccfSSadaf Ebrahimi     unsigned int i;
1004*b7893ccfSSadaf Ebrahimi 
1005*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
1006*b7893ccfSSadaf Ebrahimi     OneOffDescriptorSet src_descriptor_set(m_device, {
1007*b7893ccfSSadaf Ebrahimi                                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
1008*b7893ccfSSadaf Ebrahimi                                                          {1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_ALL, nullptr},
1009*b7893ccfSSadaf Ebrahimi                                                          {2, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
1010*b7893ccfSSadaf Ebrahimi                                                      });
1011*b7893ccfSSadaf Ebrahimi     OneOffDescriptorSet dst_descriptor_set(m_device, {
1012*b7893ccfSSadaf Ebrahimi                                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
1013*b7893ccfSSadaf Ebrahimi                                                          {1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_ALL, nullptr},
1014*b7893ccfSSadaf Ebrahimi                                                      });
1015*b7893ccfSSadaf Ebrahimi 
1016*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
1017*b7893ccfSSadaf Ebrahimi 
1018*b7893ccfSSadaf Ebrahimi     const unsigned int copy_size = 2;
1019*b7893ccfSSadaf Ebrahimi     VkCopyDescriptorSet copy_ds_update[copy_size];
1020*b7893ccfSSadaf Ebrahimi     memset(copy_ds_update, 0, sizeof(copy_ds_update));
1021*b7893ccfSSadaf Ebrahimi     for (i = 0; i < copy_size; i++) {
1022*b7893ccfSSadaf Ebrahimi         copy_ds_update[i].sType = VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET;
1023*b7893ccfSSadaf Ebrahimi         copy_ds_update[i].srcSet = src_descriptor_set.set_;
1024*b7893ccfSSadaf Ebrahimi         copy_ds_update[i].srcBinding = i;
1025*b7893ccfSSadaf Ebrahimi         copy_ds_update[i].dstSet = dst_descriptor_set.set_;
1026*b7893ccfSSadaf Ebrahimi         copy_ds_update[i].dstBinding = i;
1027*b7893ccfSSadaf Ebrahimi         copy_ds_update[i].descriptorCount = 1;
1028*b7893ccfSSadaf Ebrahimi     }
1029*b7893ccfSSadaf Ebrahimi     vkUpdateDescriptorSets(m_device->device(), 0, NULL, copy_size, copy_ds_update);
1030*b7893ccfSSadaf Ebrahimi 
1031*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
1032*b7893ccfSSadaf Ebrahimi }
1033*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,ConfirmNoVLErrorWhenVkCmdClearAttachmentsCalledInSecondaryCB)1034*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, ConfirmNoVLErrorWhenVkCmdClearAttachmentsCalledInSecondaryCB) {
1035*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
1036*b7893ccfSSadaf Ebrahimi         "This test is to verify that when vkCmdClearAttachments is called by a secondary commandbuffer, the validation layers do "
1037*b7893ccfSSadaf Ebrahimi         "not throw an error if the primary commandbuffer begins a renderpass before executing the secondary commandbuffer.");
1038*b7893ccfSSadaf Ebrahimi 
1039*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
1040*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1041*b7893ccfSSadaf Ebrahimi 
1042*b7893ccfSSadaf Ebrahimi     VkCommandBufferObj secondary(m_device, m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
1043*b7893ccfSSadaf Ebrahimi 
1044*b7893ccfSSadaf Ebrahimi     VkCommandBufferBeginInfo info = {};
1045*b7893ccfSSadaf Ebrahimi     VkCommandBufferInheritanceInfo hinfo = {};
1046*b7893ccfSSadaf Ebrahimi     info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
1047*b7893ccfSSadaf Ebrahimi     info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
1048*b7893ccfSSadaf Ebrahimi     info.pInheritanceInfo = &hinfo;
1049*b7893ccfSSadaf Ebrahimi     hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
1050*b7893ccfSSadaf Ebrahimi     hinfo.pNext = NULL;
1051*b7893ccfSSadaf Ebrahimi     hinfo.renderPass = renderPass();
1052*b7893ccfSSadaf Ebrahimi     hinfo.subpass = 0;
1053*b7893ccfSSadaf Ebrahimi     hinfo.framebuffer = m_framebuffer;
1054*b7893ccfSSadaf Ebrahimi     hinfo.occlusionQueryEnable = VK_FALSE;
1055*b7893ccfSSadaf Ebrahimi     hinfo.queryFlags = 0;
1056*b7893ccfSSadaf Ebrahimi     hinfo.pipelineStatistics = 0;
1057*b7893ccfSSadaf Ebrahimi 
1058*b7893ccfSSadaf Ebrahimi     secondary.begin(&info);
1059*b7893ccfSSadaf Ebrahimi     VkClearAttachment color_attachment;
1060*b7893ccfSSadaf Ebrahimi     color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1061*b7893ccfSSadaf Ebrahimi     color_attachment.clearValue.color.float32[0] = 0.0;
1062*b7893ccfSSadaf Ebrahimi     color_attachment.clearValue.color.float32[1] = 0.0;
1063*b7893ccfSSadaf Ebrahimi     color_attachment.clearValue.color.float32[2] = 0.0;
1064*b7893ccfSSadaf Ebrahimi     color_attachment.clearValue.color.float32[3] = 0.0;
1065*b7893ccfSSadaf Ebrahimi     color_attachment.colorAttachment = 0;
1066*b7893ccfSSadaf Ebrahimi     VkClearRect clear_rect = {{{0, 0}, {(uint32_t)m_width, (uint32_t)m_height}}, 0, 1};
1067*b7893ccfSSadaf Ebrahimi     vkCmdClearAttachments(secondary.handle(), 1, &color_attachment, 1, &clear_rect);
1068*b7893ccfSSadaf Ebrahimi     secondary.end();
1069*b7893ccfSSadaf Ebrahimi     // Modify clear rect here to verify that it doesn't cause validation error
1070*b7893ccfSSadaf Ebrahimi     clear_rect = {{{0, 0}, {99999999, 99999999}}, 0, 0};
1071*b7893ccfSSadaf Ebrahimi 
1072*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
1073*b7893ccfSSadaf Ebrahimi     vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
1074*b7893ccfSSadaf Ebrahimi     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary.handle());
1075*b7893ccfSSadaf Ebrahimi     vkCmdEndRenderPass(m_commandBuffer->handle());
1076*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
1077*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
1078*b7893ccfSSadaf Ebrahimi }
1079*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CreatePipelineComplexTypes)1080*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CreatePipelineComplexTypes) {
1081*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Smoke test for complex types across VS/FS boundary");
1082*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
1083*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1084*b7893ccfSSadaf Ebrahimi 
1085*b7893ccfSSadaf Ebrahimi     if (!m_device->phy().features().tessellationShader) {
1086*b7893ccfSSadaf Ebrahimi         printf("%s Device does not support tessellation shaders; skipped.\n", kSkipPrefix);
1087*b7893ccfSSadaf Ebrahimi         return;
1088*b7893ccfSSadaf Ebrahimi     }
1089*b7893ccfSSadaf Ebrahimi 
1090*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
1091*b7893ccfSSadaf Ebrahimi 
1092*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
1093*b7893ccfSSadaf Ebrahimi     VkShaderObj tcs(m_device, bindStateTscShaderText, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
1094*b7893ccfSSadaf Ebrahimi     VkShaderObj tes(m_device, bindStateTeshaderText, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
1095*b7893ccfSSadaf Ebrahimi     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
1096*b7893ccfSSadaf Ebrahimi 
1097*b7893ccfSSadaf Ebrahimi     VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
1098*b7893ccfSSadaf Ebrahimi                                                  VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
1099*b7893ccfSSadaf Ebrahimi     VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3};
1100*b7893ccfSSadaf Ebrahimi 
1101*b7893ccfSSadaf Ebrahimi     CreatePipelineHelper pipe(*this);
1102*b7893ccfSSadaf Ebrahimi     pipe.InitInfo();
1103*b7893ccfSSadaf Ebrahimi     pipe.gp_ci_.pTessellationState = &tsci;
1104*b7893ccfSSadaf Ebrahimi     pipe.gp_ci_.pInputAssemblyState = &iasci;
1105*b7893ccfSSadaf Ebrahimi     pipe.shader_stages_ = {vs.GetStageCreateInfo(), tcs.GetStageCreateInfo(), tes.GetStageCreateInfo(), fs.GetStageCreateInfo()};
1106*b7893ccfSSadaf Ebrahimi     pipe.InitState();
1107*b7893ccfSSadaf Ebrahimi     pipe.CreateGraphicsPipeline();
1108*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
1109*b7893ccfSSadaf Ebrahimi }
1110*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,ShaderRelaxedBlockLayout)1111*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, ShaderRelaxedBlockLayout) {
1112*b7893ccfSSadaf Ebrahimi     // This is a positive test, no errors expected
1113*b7893ccfSSadaf Ebrahimi     // Verifies the ability to relax block layout rules with a shader that requires them to be relaxed
1114*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Create a shader that requires relaxed block layout.");
1115*b7893ccfSSadaf Ebrahimi 
1116*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
1117*b7893ccfSSadaf Ebrahimi 
1118*b7893ccfSSadaf Ebrahimi     // The Relaxed Block Layout extension was promoted to core in 1.1.
1119*b7893ccfSSadaf Ebrahimi     // Go ahead and check for it and turn it on in case a 1.0 device has it.
1120*b7893ccfSSadaf Ebrahimi     if (!DeviceExtensionSupported(gpu(), nullptr, VK_KHR_RELAXED_BLOCK_LAYOUT_EXTENSION_NAME)) {
1121*b7893ccfSSadaf Ebrahimi         printf("%s Extension %s not supported, skipping this pass. \n", kSkipPrefix, VK_KHR_RELAXED_BLOCK_LAYOUT_EXTENSION_NAME);
1122*b7893ccfSSadaf Ebrahimi         return;
1123*b7893ccfSSadaf Ebrahimi     }
1124*b7893ccfSSadaf Ebrahimi     m_device_extension_names.push_back(VK_KHR_RELAXED_BLOCK_LAYOUT_EXTENSION_NAME);
1125*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
1126*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1127*b7893ccfSSadaf Ebrahimi 
1128*b7893ccfSSadaf Ebrahimi     // Vertex shader requiring relaxed layout.
1129*b7893ccfSSadaf Ebrahimi     // Without relaxed layout, we would expect a message like:
1130*b7893ccfSSadaf Ebrahimi     // "Structure id 2 decorated as Block for variable in Uniform storage class
1131*b7893ccfSSadaf Ebrahimi     // must follow standard uniform buffer layout rules: member 1 at offset 4 is not aligned to 16"
1132*b7893ccfSSadaf Ebrahimi 
1133*b7893ccfSSadaf Ebrahimi     const std::string spv_source = R"(
1134*b7893ccfSSadaf Ebrahimi                   OpCapability Shader
1135*b7893ccfSSadaf Ebrahimi                   OpMemoryModel Logical GLSL450
1136*b7893ccfSSadaf Ebrahimi                   OpEntryPoint Vertex %main "main"
1137*b7893ccfSSadaf Ebrahimi                   OpSource GLSL 450
1138*b7893ccfSSadaf Ebrahimi                   OpMemberDecorate %S 0 Offset 0
1139*b7893ccfSSadaf Ebrahimi                   OpMemberDecorate %S 1 Offset 4
1140*b7893ccfSSadaf Ebrahimi                   OpDecorate %S Block
1141*b7893ccfSSadaf Ebrahimi                   OpDecorate %B DescriptorSet 0
1142*b7893ccfSSadaf Ebrahimi                   OpDecorate %B Binding 0
1143*b7893ccfSSadaf Ebrahimi           %void = OpTypeVoid
1144*b7893ccfSSadaf Ebrahimi              %3 = OpTypeFunction %void
1145*b7893ccfSSadaf Ebrahimi          %float = OpTypeFloat 32
1146*b7893ccfSSadaf Ebrahimi        %v3float = OpTypeVector %float 3
1147*b7893ccfSSadaf Ebrahimi              %S = OpTypeStruct %float %v3float
1148*b7893ccfSSadaf Ebrahimi %_ptr_Uniform_S = OpTypePointer Uniform %S
1149*b7893ccfSSadaf Ebrahimi              %B = OpVariable %_ptr_Uniform_S Uniform
1150*b7893ccfSSadaf Ebrahimi           %main = OpFunction %void None %3
1151*b7893ccfSSadaf Ebrahimi              %5 = OpLabel
1152*b7893ccfSSadaf Ebrahimi                   OpReturn
1153*b7893ccfSSadaf Ebrahimi                   OpFunctionEnd
1154*b7893ccfSSadaf Ebrahimi         )";
1155*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
1156*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, spv_source, VK_SHADER_STAGE_VERTEX_BIT, this);
1157*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
1158*b7893ccfSSadaf Ebrahimi }
1159*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,ShaderUboStd430Layout)1160*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, ShaderUboStd430Layout) {
1161*b7893ccfSSadaf Ebrahimi     // This is a positive test, no errors expected
1162*b7893ccfSSadaf Ebrahimi     // Verifies the ability to scalar block layout rules with a shader that requires them to be relaxed
1163*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Create a shader that requires UBO std430 layout.");
1164*b7893ccfSSadaf Ebrahimi     // Enable req'd extensions
1165*b7893ccfSSadaf Ebrahimi     if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
1166*b7893ccfSSadaf Ebrahimi         printf("%s Extension %s not supported, skipping this pass. \n", kSkipPrefix,
1167*b7893ccfSSadaf Ebrahimi                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1168*b7893ccfSSadaf Ebrahimi         return;
1169*b7893ccfSSadaf Ebrahimi     }
1170*b7893ccfSSadaf Ebrahimi     m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1171*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
1172*b7893ccfSSadaf Ebrahimi 
1173*b7893ccfSSadaf Ebrahimi     // Check for the UBO standard block layout extension and turn it on if it's available
1174*b7893ccfSSadaf Ebrahimi     if (!DeviceExtensionSupported(gpu(), nullptr, VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME)) {
1175*b7893ccfSSadaf Ebrahimi         printf("%s Extension %s not supported, skipping this pass. \n", kSkipPrefix,
1176*b7893ccfSSadaf Ebrahimi                VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME);
1177*b7893ccfSSadaf Ebrahimi         return;
1178*b7893ccfSSadaf Ebrahimi     }
1179*b7893ccfSSadaf Ebrahimi     m_device_extension_names.push_back(VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME);
1180*b7893ccfSSadaf Ebrahimi 
1181*b7893ccfSSadaf Ebrahimi     PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2 =
1182*b7893ccfSSadaf Ebrahimi         (PFN_vkGetPhysicalDeviceFeatures2)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
1183*b7893ccfSSadaf Ebrahimi 
1184*b7893ccfSSadaf Ebrahimi     auto uniform_buffer_standard_layout_features = lvl_init_struct<VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR>(NULL);
1185*b7893ccfSSadaf Ebrahimi     uniform_buffer_standard_layout_features.uniformBufferStandardLayout = VK_TRUE;
1186*b7893ccfSSadaf Ebrahimi     auto query_features2 = lvl_init_struct<VkPhysicalDeviceFeatures2>(&uniform_buffer_standard_layout_features);
1187*b7893ccfSSadaf Ebrahimi     vkGetPhysicalDeviceFeatures2(gpu(), &query_features2);
1188*b7893ccfSSadaf Ebrahimi 
1189*b7893ccfSSadaf Ebrahimi     auto set_features2 = lvl_init_struct<VkPhysicalDeviceFeatures2>(&uniform_buffer_standard_layout_features);
1190*b7893ccfSSadaf Ebrahimi 
1191*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &set_features2));
1192*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1193*b7893ccfSSadaf Ebrahimi 
1194*b7893ccfSSadaf Ebrahimi     // Vertex shader requiring std430 in a uniform buffer.
1195*b7893ccfSSadaf Ebrahimi     // Without uniform buffer standard layout, we would expect a message like:
1196*b7893ccfSSadaf Ebrahimi     // "Structure id 3 decorated as Block for variable in Uniform storage class
1197*b7893ccfSSadaf Ebrahimi     // must follow standard uniform buffer layout rules: member 0 is an array
1198*b7893ccfSSadaf Ebrahimi     // with stride 4 not satisfying alignment to 16"
1199*b7893ccfSSadaf Ebrahimi 
1200*b7893ccfSSadaf Ebrahimi     const std::string spv_source = R"(
1201*b7893ccfSSadaf Ebrahimi                OpCapability Shader
1202*b7893ccfSSadaf Ebrahimi                OpMemoryModel Logical GLSL450
1203*b7893ccfSSadaf Ebrahimi                OpEntryPoint Vertex %main "main"
1204*b7893ccfSSadaf Ebrahimi                OpSource GLSL 460
1205*b7893ccfSSadaf Ebrahimi                OpDecorate %_arr_float_uint_8 ArrayStride 4
1206*b7893ccfSSadaf Ebrahimi                OpMemberDecorate %foo 0 Offset 0
1207*b7893ccfSSadaf Ebrahimi                OpDecorate %foo Block
1208*b7893ccfSSadaf Ebrahimi                OpDecorate %b DescriptorSet 0
1209*b7893ccfSSadaf Ebrahimi                OpDecorate %b Binding 0
1210*b7893ccfSSadaf Ebrahimi        %void = OpTypeVoid
1211*b7893ccfSSadaf Ebrahimi           %3 = OpTypeFunction %void
1212*b7893ccfSSadaf Ebrahimi       %float = OpTypeFloat 32
1213*b7893ccfSSadaf Ebrahimi        %uint = OpTypeInt 32 0
1214*b7893ccfSSadaf Ebrahimi      %uint_8 = OpConstant %uint 8
1215*b7893ccfSSadaf Ebrahimi %_arr_float_uint_8 = OpTypeArray %float %uint_8
1216*b7893ccfSSadaf Ebrahimi         %foo = OpTypeStruct %_arr_float_uint_8
1217*b7893ccfSSadaf Ebrahimi %_ptr_Uniform_foo = OpTypePointer Uniform %foo
1218*b7893ccfSSadaf Ebrahimi           %b = OpVariable %_ptr_Uniform_foo Uniform
1219*b7893ccfSSadaf Ebrahimi        %main = OpFunction %void None %3
1220*b7893ccfSSadaf Ebrahimi           %5 = OpLabel
1221*b7893ccfSSadaf Ebrahimi                OpReturn
1222*b7893ccfSSadaf Ebrahimi                OpFunctionEnd
1223*b7893ccfSSadaf Ebrahimi         )";
1224*b7893ccfSSadaf Ebrahimi 
1225*b7893ccfSSadaf Ebrahimi     std::vector<unsigned int> spv;
1226*b7893ccfSSadaf Ebrahimi     VkShaderModuleCreateInfo module_create_info;
1227*b7893ccfSSadaf Ebrahimi     VkShaderModule shader_module;
1228*b7893ccfSSadaf Ebrahimi     module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
1229*b7893ccfSSadaf Ebrahimi     module_create_info.pNext = NULL;
1230*b7893ccfSSadaf Ebrahimi     ASMtoSPV(SPV_ENV_VULKAN_1_0, 0, spv_source.data(), spv);
1231*b7893ccfSSadaf Ebrahimi     module_create_info.pCode = spv.data();
1232*b7893ccfSSadaf Ebrahimi     module_create_info.codeSize = spv.size() * sizeof(unsigned int);
1233*b7893ccfSSadaf Ebrahimi     module_create_info.flags = 0;
1234*b7893ccfSSadaf Ebrahimi 
1235*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
1236*b7893ccfSSadaf Ebrahimi     VkResult err = vkCreateShaderModule(m_device->handle(), &module_create_info, NULL, &shader_module);
1237*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
1238*b7893ccfSSadaf Ebrahimi     if (err == VK_SUCCESS) {
1239*b7893ccfSSadaf Ebrahimi         vkDestroyShaderModule(m_device->handle(), shader_module, NULL);
1240*b7893ccfSSadaf Ebrahimi     }
1241*b7893ccfSSadaf Ebrahimi }
1242*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,ShaderScalarBlockLayout)1243*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, ShaderScalarBlockLayout) {
1244*b7893ccfSSadaf Ebrahimi     // This is a positive test, no errors expected
1245*b7893ccfSSadaf Ebrahimi     // Verifies the ability to scalar block layout rules with a shader that requires them to be relaxed
1246*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Create a shader that requires scalar block layout.");
1247*b7893ccfSSadaf Ebrahimi     // Enable req'd extensions
1248*b7893ccfSSadaf Ebrahimi     if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
1249*b7893ccfSSadaf Ebrahimi         printf("%s Extension %s not supported, skipping this pass. \n", kSkipPrefix,
1250*b7893ccfSSadaf Ebrahimi                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1251*b7893ccfSSadaf Ebrahimi         return;
1252*b7893ccfSSadaf Ebrahimi     }
1253*b7893ccfSSadaf Ebrahimi     m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
1254*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
1255*b7893ccfSSadaf Ebrahimi 
1256*b7893ccfSSadaf Ebrahimi     // Check for the Scalar Block Layout extension and turn it on if it's available
1257*b7893ccfSSadaf Ebrahimi     if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME)) {
1258*b7893ccfSSadaf Ebrahimi         printf("%s Extension %s not supported, skipping this pass. \n", kSkipPrefix, VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME);
1259*b7893ccfSSadaf Ebrahimi         return;
1260*b7893ccfSSadaf Ebrahimi     }
1261*b7893ccfSSadaf Ebrahimi     m_device_extension_names.push_back(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME);
1262*b7893ccfSSadaf Ebrahimi 
1263*b7893ccfSSadaf Ebrahimi     PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2 =
1264*b7893ccfSSadaf Ebrahimi         (PFN_vkGetPhysicalDeviceFeatures2)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
1265*b7893ccfSSadaf Ebrahimi 
1266*b7893ccfSSadaf Ebrahimi     auto scalar_block_features = lvl_init_struct<VkPhysicalDeviceScalarBlockLayoutFeaturesEXT>(NULL);
1267*b7893ccfSSadaf Ebrahimi     scalar_block_features.scalarBlockLayout = VK_TRUE;
1268*b7893ccfSSadaf Ebrahimi     auto query_features2 = lvl_init_struct<VkPhysicalDeviceFeatures2>(&scalar_block_features);
1269*b7893ccfSSadaf Ebrahimi     vkGetPhysicalDeviceFeatures2(gpu(), &query_features2);
1270*b7893ccfSSadaf Ebrahimi 
1271*b7893ccfSSadaf Ebrahimi     auto set_features2 = lvl_init_struct<VkPhysicalDeviceFeatures2>(&scalar_block_features);
1272*b7893ccfSSadaf Ebrahimi 
1273*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &set_features2));
1274*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1275*b7893ccfSSadaf Ebrahimi 
1276*b7893ccfSSadaf Ebrahimi     // Vertex shader requiring scalar layout.
1277*b7893ccfSSadaf Ebrahimi     // Without scalar layout, we would expect a message like:
1278*b7893ccfSSadaf Ebrahimi     // "Structure id 2 decorated as Block for variable in Uniform storage class
1279*b7893ccfSSadaf Ebrahimi     // must follow standard uniform buffer layout rules: member 1 at offset 4 is not aligned to 16"
1280*b7893ccfSSadaf Ebrahimi 
1281*b7893ccfSSadaf Ebrahimi     const std::string spv_source = R"(
1282*b7893ccfSSadaf Ebrahimi                   OpCapability Shader
1283*b7893ccfSSadaf Ebrahimi                   OpMemoryModel Logical GLSL450
1284*b7893ccfSSadaf Ebrahimi                   OpEntryPoint Vertex %main "main"
1285*b7893ccfSSadaf Ebrahimi                   OpSource GLSL 450
1286*b7893ccfSSadaf Ebrahimi                   OpMemberDecorate %S 0 Offset 0
1287*b7893ccfSSadaf Ebrahimi                   OpMemberDecorate %S 1 Offset 4
1288*b7893ccfSSadaf Ebrahimi                   OpMemberDecorate %S 2 Offset 8
1289*b7893ccfSSadaf Ebrahimi                   OpDecorate %S Block
1290*b7893ccfSSadaf Ebrahimi                   OpDecorate %B DescriptorSet 0
1291*b7893ccfSSadaf Ebrahimi                   OpDecorate %B Binding 0
1292*b7893ccfSSadaf Ebrahimi           %void = OpTypeVoid
1293*b7893ccfSSadaf Ebrahimi              %3 = OpTypeFunction %void
1294*b7893ccfSSadaf Ebrahimi          %float = OpTypeFloat 32
1295*b7893ccfSSadaf Ebrahimi        %v3float = OpTypeVector %float 3
1296*b7893ccfSSadaf Ebrahimi              %S = OpTypeStruct %float %float %v3float
1297*b7893ccfSSadaf Ebrahimi %_ptr_Uniform_S = OpTypePointer Uniform %S
1298*b7893ccfSSadaf Ebrahimi              %B = OpVariable %_ptr_Uniform_S Uniform
1299*b7893ccfSSadaf Ebrahimi           %main = OpFunction %void None %3
1300*b7893ccfSSadaf Ebrahimi              %5 = OpLabel
1301*b7893ccfSSadaf Ebrahimi                   OpReturn
1302*b7893ccfSSadaf Ebrahimi                   OpFunctionEnd
1303*b7893ccfSSadaf Ebrahimi         )";
1304*b7893ccfSSadaf Ebrahimi 
1305*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
1306*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, spv_source, VK_SHADER_STAGE_VERTEX_BIT, this);
1307*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
1308*b7893ccfSSadaf Ebrahimi }
1309*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,SpirvGroupDecorations)1310*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, SpirvGroupDecorations) {
1311*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Test shader validation support for group decorations.");
1312*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
1313*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
1314*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1315*b7893ccfSSadaf Ebrahimi 
1316*b7893ccfSSadaf Ebrahimi     const std::string spv_source = R"(
1317*b7893ccfSSadaf Ebrahimi               OpCapability Shader
1318*b7893ccfSSadaf Ebrahimi                OpMemoryModel Logical GLSL450
1319*b7893ccfSSadaf Ebrahimi                OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
1320*b7893ccfSSadaf Ebrahimi                OpExecutionMode %main LocalSize 1 1 1
1321*b7893ccfSSadaf Ebrahimi                OpSource GLSL 430
1322*b7893ccfSSadaf Ebrahimi                OpName %main "main"
1323*b7893ccfSSadaf Ebrahimi                OpName %gl_GlobalInvocationID "gl_GlobalInvocationID"
1324*b7893ccfSSadaf Ebrahimi                OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
1325*b7893ccfSSadaf Ebrahimi                OpDecorate %_runtimearr_float ArrayStride 4
1326*b7893ccfSSadaf Ebrahimi                OpDecorate %4 BufferBlock
1327*b7893ccfSSadaf Ebrahimi                OpDecorate %5 Offset 0
1328*b7893ccfSSadaf Ebrahimi           %4 = OpDecorationGroup
1329*b7893ccfSSadaf Ebrahimi           %5 = OpDecorationGroup
1330*b7893ccfSSadaf Ebrahimi                OpGroupDecorate %4 %_struct_6 %_struct_7 %_struct_8 %_struct_9 %_struct_10 %_struct_11
1331*b7893ccfSSadaf Ebrahimi                OpGroupMemberDecorate %5 %_struct_6 0 %_struct_7 0 %_struct_8 0 %_struct_9 0 %_struct_10 0 %_struct_11 0
1332*b7893ccfSSadaf Ebrahimi                OpDecorate %12 DescriptorSet 0
1333*b7893ccfSSadaf Ebrahimi                OpDecorate %13 DescriptorSet 0
1334*b7893ccfSSadaf Ebrahimi                OpDecorate %13 NonWritable
1335*b7893ccfSSadaf Ebrahimi                OpDecorate %13 Restrict
1336*b7893ccfSSadaf Ebrahimi          %14 = OpDecorationGroup
1337*b7893ccfSSadaf Ebrahimi          %12 = OpDecorationGroup
1338*b7893ccfSSadaf Ebrahimi          %13 = OpDecorationGroup
1339*b7893ccfSSadaf Ebrahimi                OpGroupDecorate %12 %15
1340*b7893ccfSSadaf Ebrahimi                OpGroupDecorate %12 %15
1341*b7893ccfSSadaf Ebrahimi                OpGroupDecorate %12 %15
1342*b7893ccfSSadaf Ebrahimi                OpDecorate %15 DescriptorSet 0
1343*b7893ccfSSadaf Ebrahimi                OpDecorate %15 Binding 5
1344*b7893ccfSSadaf Ebrahimi                OpGroupDecorate %14 %16
1345*b7893ccfSSadaf Ebrahimi                OpDecorate %16 DescriptorSet 0
1346*b7893ccfSSadaf Ebrahimi                OpDecorate %16 Binding 0
1347*b7893ccfSSadaf Ebrahimi                OpGroupDecorate %12 %17
1348*b7893ccfSSadaf Ebrahimi                OpDecorate %17 Binding 1
1349*b7893ccfSSadaf Ebrahimi                OpGroupDecorate %13 %18 %19
1350*b7893ccfSSadaf Ebrahimi                OpDecorate %18 Binding 2
1351*b7893ccfSSadaf Ebrahimi                OpDecorate %19 Binding 3
1352*b7893ccfSSadaf Ebrahimi                OpGroupDecorate %14 %20
1353*b7893ccfSSadaf Ebrahimi                OpGroupDecorate %12 %20
1354*b7893ccfSSadaf Ebrahimi                OpGroupDecorate %13 %20
1355*b7893ccfSSadaf Ebrahimi                OpDecorate %20 Binding 4
1356*b7893ccfSSadaf Ebrahimi        %bool = OpTypeBool
1357*b7893ccfSSadaf Ebrahimi        %void = OpTypeVoid
1358*b7893ccfSSadaf Ebrahimi          %23 = OpTypeFunction %void
1359*b7893ccfSSadaf Ebrahimi        %uint = OpTypeInt 32 0
1360*b7893ccfSSadaf Ebrahimi         %int = OpTypeInt 32 1
1361*b7893ccfSSadaf Ebrahimi       %float = OpTypeFloat 32
1362*b7893ccfSSadaf Ebrahimi      %v3uint = OpTypeVector %uint 3
1363*b7893ccfSSadaf Ebrahimi     %v3float = OpTypeVector %float 3
1364*b7893ccfSSadaf Ebrahimi %_ptr_Input_v3uint = OpTypePointer Input %v3uint
1365*b7893ccfSSadaf Ebrahimi %_ptr_Uniform_int = OpTypePointer Uniform %int
1366*b7893ccfSSadaf Ebrahimi %_ptr_Uniform_float = OpTypePointer Uniform %float
1367*b7893ccfSSadaf Ebrahimi %_runtimearr_int = OpTypeRuntimeArray %int
1368*b7893ccfSSadaf Ebrahimi %_runtimearr_float = OpTypeRuntimeArray %float
1369*b7893ccfSSadaf Ebrahimi %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
1370*b7893ccfSSadaf Ebrahimi       %int_0 = OpConstant %int 0
1371*b7893ccfSSadaf Ebrahimi   %_struct_6 = OpTypeStruct %_runtimearr_float
1372*b7893ccfSSadaf Ebrahimi %_ptr_Uniform__struct_6 = OpTypePointer Uniform %_struct_6
1373*b7893ccfSSadaf Ebrahimi          %15 = OpVariable %_ptr_Uniform__struct_6 Uniform
1374*b7893ccfSSadaf Ebrahimi   %_struct_7 = OpTypeStruct %_runtimearr_float
1375*b7893ccfSSadaf Ebrahimi %_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7
1376*b7893ccfSSadaf Ebrahimi          %16 = OpVariable %_ptr_Uniform__struct_7 Uniform
1377*b7893ccfSSadaf Ebrahimi   %_struct_8 = OpTypeStruct %_runtimearr_float
1378*b7893ccfSSadaf Ebrahimi %_ptr_Uniform__struct_8 = OpTypePointer Uniform %_struct_8
1379*b7893ccfSSadaf Ebrahimi          %17 = OpVariable %_ptr_Uniform__struct_8 Uniform
1380*b7893ccfSSadaf Ebrahimi   %_struct_9 = OpTypeStruct %_runtimearr_float
1381*b7893ccfSSadaf Ebrahimi %_ptr_Uniform__struct_9 = OpTypePointer Uniform %_struct_9
1382*b7893ccfSSadaf Ebrahimi          %18 = OpVariable %_ptr_Uniform__struct_9 Uniform
1383*b7893ccfSSadaf Ebrahimi  %_struct_10 = OpTypeStruct %_runtimearr_float
1384*b7893ccfSSadaf Ebrahimi %_ptr_Uniform__struct_10 = OpTypePointer Uniform %_struct_10
1385*b7893ccfSSadaf Ebrahimi          %19 = OpVariable %_ptr_Uniform__struct_10 Uniform
1386*b7893ccfSSadaf Ebrahimi  %_struct_11 = OpTypeStruct %_runtimearr_float
1387*b7893ccfSSadaf Ebrahimi %_ptr_Uniform__struct_11 = OpTypePointer Uniform %_struct_11
1388*b7893ccfSSadaf Ebrahimi          %20 = OpVariable %_ptr_Uniform__struct_11 Uniform
1389*b7893ccfSSadaf Ebrahimi        %main = OpFunction %void None %23
1390*b7893ccfSSadaf Ebrahimi          %40 = OpLabel
1391*b7893ccfSSadaf Ebrahimi          %41 = OpLoad %v3uint %gl_GlobalInvocationID
1392*b7893ccfSSadaf Ebrahimi          %42 = OpCompositeExtract %uint %41 0
1393*b7893ccfSSadaf Ebrahimi          %43 = OpAccessChain %_ptr_Uniform_float %16 %int_0 %42
1394*b7893ccfSSadaf Ebrahimi          %44 = OpAccessChain %_ptr_Uniform_float %17 %int_0 %42
1395*b7893ccfSSadaf Ebrahimi          %45 = OpAccessChain %_ptr_Uniform_float %18 %int_0 %42
1396*b7893ccfSSadaf Ebrahimi          %46 = OpAccessChain %_ptr_Uniform_float %19 %int_0 %42
1397*b7893ccfSSadaf Ebrahimi          %47 = OpAccessChain %_ptr_Uniform_float %20 %int_0 %42
1398*b7893ccfSSadaf Ebrahimi          %48 = OpAccessChain %_ptr_Uniform_float %15 %int_0 %42
1399*b7893ccfSSadaf Ebrahimi          %49 = OpLoad %float %43
1400*b7893ccfSSadaf Ebrahimi          %50 = OpLoad %float %44
1401*b7893ccfSSadaf Ebrahimi          %51 = OpLoad %float %45
1402*b7893ccfSSadaf Ebrahimi          %52 = OpLoad %float %46
1403*b7893ccfSSadaf Ebrahimi          %53 = OpLoad %float %47
1404*b7893ccfSSadaf Ebrahimi          %54 = OpFAdd %float %49 %50
1405*b7893ccfSSadaf Ebrahimi          %55 = OpFAdd %float %54 %51
1406*b7893ccfSSadaf Ebrahimi          %56 = OpFAdd %float %55 %52
1407*b7893ccfSSadaf Ebrahimi          %57 = OpFAdd %float %56 %53
1408*b7893ccfSSadaf Ebrahimi                OpStore %48 %57
1409*b7893ccfSSadaf Ebrahimi                OpReturn
1410*b7893ccfSSadaf Ebrahimi                OpFunctionEnd
1411*b7893ccfSSadaf Ebrahimi )";
1412*b7893ccfSSadaf Ebrahimi 
1413*b7893ccfSSadaf Ebrahimi     // CreateDescriptorSetLayout
1414*b7893ccfSSadaf Ebrahimi     VkDescriptorSetLayoutBinding dslb[6] = {};
1415*b7893ccfSSadaf Ebrahimi     size_t dslb_size = size(dslb);
1416*b7893ccfSSadaf Ebrahimi     for (size_t i = 0; i < dslb_size; i++) {
1417*b7893ccfSSadaf Ebrahimi         dslb[i].binding = i;
1418*b7893ccfSSadaf Ebrahimi         dslb[i].descriptorCount = 1;
1419*b7893ccfSSadaf Ebrahimi         dslb[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
1420*b7893ccfSSadaf Ebrahimi         dslb[i].pImmutableSamplers = NULL;
1421*b7893ccfSSadaf Ebrahimi         dslb[i].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_ALL;
1422*b7893ccfSSadaf Ebrahimi     }
1423*b7893ccfSSadaf Ebrahimi     if (m_device->props.limits.maxPerStageDescriptorStorageBuffers < dslb_size) {
1424*b7893ccfSSadaf Ebrahimi         printf("%sNeeded storage buffer bindings exceeds this devices limit.  Skipping tests.\n", kSkipPrefix);
1425*b7893ccfSSadaf Ebrahimi         return;
1426*b7893ccfSSadaf Ebrahimi     }
1427*b7893ccfSSadaf Ebrahimi 
1428*b7893ccfSSadaf Ebrahimi     CreateComputePipelineHelper pipe(*this);
1429*b7893ccfSSadaf Ebrahimi     pipe.InitInfo();
1430*b7893ccfSSadaf Ebrahimi     pipe.dsl_bindings_.resize(dslb_size);
1431*b7893ccfSSadaf Ebrahimi     memcpy(pipe.dsl_bindings_.data(), dslb, dslb_size * sizeof(VkDescriptorSetLayoutBinding));
1432*b7893ccfSSadaf Ebrahimi     pipe.cs_.reset(new VkShaderObj(m_device, bindStateMinimalShaderText, VK_SHADER_STAGE_COMPUTE_BIT, this));
1433*b7893ccfSSadaf Ebrahimi     pipe.InitState();
1434*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
1435*b7893ccfSSadaf Ebrahimi     pipe.CreateComputePipeline();
1436*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
1437*b7893ccfSSadaf Ebrahimi }
1438*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CreatePipelineCheckShaderCapabilityExtension1of2)1439*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CreatePipelineCheckShaderCapabilityExtension1of2) {
1440*b7893ccfSSadaf Ebrahimi     // This is a positive test, no errors expected
1441*b7893ccfSSadaf Ebrahimi     // Verifies the ability to deal with a shader that declares a non-unique SPIRV capability ID
1442*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Create a shader in which uses a non-unique capability ID extension, 1 of 2");
1443*b7893ccfSSadaf Ebrahimi 
1444*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
1445*b7893ccfSSadaf Ebrahimi     if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME)) {
1446*b7893ccfSSadaf Ebrahimi         printf("%s Extension %s not supported, skipping this pass. \n", kSkipPrefix,
1447*b7893ccfSSadaf Ebrahimi                VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME);
1448*b7893ccfSSadaf Ebrahimi         return;
1449*b7893ccfSSadaf Ebrahimi     }
1450*b7893ccfSSadaf Ebrahimi     m_device_extension_names.push_back(VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME);
1451*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
1452*b7893ccfSSadaf Ebrahimi 
1453*b7893ccfSSadaf Ebrahimi     // These tests require that the device support multiViewport
1454*b7893ccfSSadaf Ebrahimi     if (!m_device->phy().features().multiViewport) {
1455*b7893ccfSSadaf Ebrahimi         printf("%s Device does not support multiViewport, test skipped.\n", kSkipPrefix);
1456*b7893ccfSSadaf Ebrahimi         return;
1457*b7893ccfSSadaf Ebrahimi     }
1458*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1459*b7893ccfSSadaf Ebrahimi 
1460*b7893ccfSSadaf Ebrahimi     // Vertex shader using viewport array capability
1461*b7893ccfSSadaf Ebrahimi     char const *vsSource =
1462*b7893ccfSSadaf Ebrahimi         "#version 450\n"
1463*b7893ccfSSadaf Ebrahimi         "#extension GL_ARB_shader_viewport_layer_array : enable\n"
1464*b7893ccfSSadaf Ebrahimi         "void main() {\n"
1465*b7893ccfSSadaf Ebrahimi         "    gl_ViewportIndex = 1;\n"
1466*b7893ccfSSadaf Ebrahimi         "}\n";
1467*b7893ccfSSadaf Ebrahimi 
1468*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
1469*b7893ccfSSadaf Ebrahimi 
1470*b7893ccfSSadaf Ebrahimi     CreatePipelineHelper pipe(*this);
1471*b7893ccfSSadaf Ebrahimi     pipe.InitInfo();
1472*b7893ccfSSadaf Ebrahimi     pipe.shader_stages_ = {vs.GetStageCreateInfo()};
1473*b7893ccfSSadaf Ebrahimi     pipe.InitState();
1474*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
1475*b7893ccfSSadaf Ebrahimi     pipe.CreateGraphicsPipeline();
1476*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
1477*b7893ccfSSadaf Ebrahimi }
1478*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CreatePipelineCheckShaderCapabilityExtension2of2)1479*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CreatePipelineCheckShaderCapabilityExtension2of2) {
1480*b7893ccfSSadaf Ebrahimi     // This is a positive test, no errors expected
1481*b7893ccfSSadaf Ebrahimi     // Verifies the ability to deal with a shader that declares a non-unique SPIRV capability ID
1482*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Create a shader in which uses a non-unique capability ID extension, 2 of 2");
1483*b7893ccfSSadaf Ebrahimi 
1484*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
1485*b7893ccfSSadaf Ebrahimi     if (!DeviceExtensionSupported(gpu(), nullptr, VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME)) {
1486*b7893ccfSSadaf Ebrahimi         printf("%s Extension %s not supported, skipping this pass. \n", kSkipPrefix, VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME);
1487*b7893ccfSSadaf Ebrahimi         return;
1488*b7893ccfSSadaf Ebrahimi     }
1489*b7893ccfSSadaf Ebrahimi     m_device_extension_names.push_back(VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME);
1490*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
1491*b7893ccfSSadaf Ebrahimi 
1492*b7893ccfSSadaf Ebrahimi     // These tests require that the device support multiViewport
1493*b7893ccfSSadaf Ebrahimi     if (!m_device->phy().features().multiViewport) {
1494*b7893ccfSSadaf Ebrahimi         printf("%s Device does not support multiViewport, test skipped.\n", kSkipPrefix);
1495*b7893ccfSSadaf Ebrahimi         return;
1496*b7893ccfSSadaf Ebrahimi     }
1497*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1498*b7893ccfSSadaf Ebrahimi 
1499*b7893ccfSSadaf Ebrahimi     // Vertex shader using viewport array capability
1500*b7893ccfSSadaf Ebrahimi     char const *vsSource =
1501*b7893ccfSSadaf Ebrahimi         "#version 450\n"
1502*b7893ccfSSadaf Ebrahimi         "#extension GL_ARB_shader_viewport_layer_array : enable\n"
1503*b7893ccfSSadaf Ebrahimi         "void main() {\n"
1504*b7893ccfSSadaf Ebrahimi         "    gl_ViewportIndex = 1;\n"
1505*b7893ccfSSadaf Ebrahimi         "}\n";
1506*b7893ccfSSadaf Ebrahimi 
1507*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
1508*b7893ccfSSadaf Ebrahimi 
1509*b7893ccfSSadaf Ebrahimi     CreatePipelineHelper pipe(*this);
1510*b7893ccfSSadaf Ebrahimi     pipe.InitInfo();
1511*b7893ccfSSadaf Ebrahimi     pipe.shader_stages_ = {vs.GetStageCreateInfo()};
1512*b7893ccfSSadaf Ebrahimi     pipe.InitState();
1513*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
1514*b7893ccfSSadaf Ebrahimi     pipe.CreateGraphicsPipeline();
1515*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
1516*b7893ccfSSadaf Ebrahimi }
1517*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CreatePipelineFragmentOutputNotWrittenButMasked)1518*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CreatePipelineFragmentOutputNotWrittenButMasked) {
1519*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
1520*b7893ccfSSadaf Ebrahimi         "Test that no error is produced when the fragment shader fails to declare an output, but the corresponding attachment's "
1521*b7893ccfSSadaf Ebrahimi         "write mask is 0.");
1522*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
1523*b7893ccfSSadaf Ebrahimi 
1524*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
1525*b7893ccfSSadaf Ebrahimi 
1526*b7893ccfSSadaf Ebrahimi     char const *fsSource =
1527*b7893ccfSSadaf Ebrahimi         "#version 450\n"
1528*b7893ccfSSadaf Ebrahimi         "\n"
1529*b7893ccfSSadaf Ebrahimi         "void main(){\n"
1530*b7893ccfSSadaf Ebrahimi         "}\n";
1531*b7893ccfSSadaf Ebrahimi 
1532*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
1533*b7893ccfSSadaf Ebrahimi     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
1534*b7893ccfSSadaf Ebrahimi 
1535*b7893ccfSSadaf Ebrahimi     VkPipelineObj pipe(m_device);
1536*b7893ccfSSadaf Ebrahimi     pipe.AddShader(&vs);
1537*b7893ccfSSadaf Ebrahimi     pipe.AddShader(&fs);
1538*b7893ccfSSadaf Ebrahimi 
1539*b7893ccfSSadaf Ebrahimi     /* set up CB 0, not written, but also masked */
1540*b7893ccfSSadaf Ebrahimi     pipe.AddDefaultColorAttachment(0);
1541*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1542*b7893ccfSSadaf Ebrahimi 
1543*b7893ccfSSadaf Ebrahimi     VkDescriptorSetObj descriptorSet(m_device);
1544*b7893ccfSSadaf Ebrahimi     descriptorSet.AppendDummy();
1545*b7893ccfSSadaf Ebrahimi     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
1546*b7893ccfSSadaf Ebrahimi 
1547*b7893ccfSSadaf Ebrahimi     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
1548*b7893ccfSSadaf Ebrahimi 
1549*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
1550*b7893ccfSSadaf Ebrahimi }
1551*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,StatelessValidationDisable)1552*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, StatelessValidationDisable) {
1553*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Specify a non-zero value for a reserved parameter with stateless validation disabled");
1554*b7893ccfSSadaf Ebrahimi 
1555*b7893ccfSSadaf Ebrahimi     VkValidationFeatureDisableEXT disables[] = {VK_VALIDATION_FEATURE_DISABLE_API_PARAMETERS_EXT};
1556*b7893ccfSSadaf Ebrahimi     VkValidationFeaturesEXT features = {};
1557*b7893ccfSSadaf Ebrahimi     features.sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT;
1558*b7893ccfSSadaf Ebrahimi     features.disabledValidationFeatureCount = 1;
1559*b7893ccfSSadaf Ebrahimi     features.pDisabledValidationFeatures = disables;
1560*b7893ccfSSadaf Ebrahimi     VkCommandPoolCreateFlags pool_flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
1561*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, pool_flags, &features));
1562*b7893ccfSSadaf Ebrahimi 
1563*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
1564*b7893ccfSSadaf Ebrahimi     // Specify 0 for a reserved VkFlags parameter. Normally this is expected to trigger an stateless validation error, but this
1565*b7893ccfSSadaf Ebrahimi     // validation was disabled via the features extension, so no errors should be forthcoming.
1566*b7893ccfSSadaf Ebrahimi     VkEvent event_handle = VK_NULL_HANDLE;
1567*b7893ccfSSadaf Ebrahimi     VkEventCreateInfo event_info = {};
1568*b7893ccfSSadaf Ebrahimi     event_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1569*b7893ccfSSadaf Ebrahimi     event_info.flags = 1;
1570*b7893ccfSSadaf Ebrahimi     vkCreateEvent(device(), &event_info, NULL, &event_handle);
1571*b7893ccfSSadaf Ebrahimi     vkDestroyEvent(device(), event_handle, NULL);
1572*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
1573*b7893ccfSSadaf Ebrahimi }
1574*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,PointSizeWriteInFunction)1575*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, PointSizeWriteInFunction) {
1576*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Create a pipeline using TOPOLOGY_POINT_LIST and write PointSize in vertex shader function.");
1577*b7893ccfSSadaf Ebrahimi 
1578*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
1579*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
1580*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1581*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitViewport());
1582*b7893ccfSSadaf Ebrahimi 
1583*b7893ccfSSadaf Ebrahimi     // Create VS declaring PointSize and write to it in a function call.
1584*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, bindStateVertPointSizeShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
1585*b7893ccfSSadaf Ebrahimi     VkShaderObj ps(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
1586*b7893ccfSSadaf Ebrahimi     {
1587*b7893ccfSSadaf Ebrahimi         CreatePipelineHelper pipe(*this);
1588*b7893ccfSSadaf Ebrahimi         pipe.InitInfo();
1589*b7893ccfSSadaf Ebrahimi         pipe.shader_stages_ = {vs.GetStageCreateInfo(), ps.GetStageCreateInfo()};
1590*b7893ccfSSadaf Ebrahimi         pipe.ia_ci_.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
1591*b7893ccfSSadaf Ebrahimi         pipe.InitState();
1592*b7893ccfSSadaf Ebrahimi         pipe.CreateGraphicsPipeline();
1593*b7893ccfSSadaf Ebrahimi     }
1594*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
1595*b7893ccfSSadaf Ebrahimi }
1596*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,PointSizeGeomShaderSuccess)1597*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, PointSizeGeomShaderSuccess) {
1598*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
1599*b7893ccfSSadaf Ebrahimi         "Create a pipeline using TOPOLOGY_POINT_LIST, set PointSize vertex shader, and write in the final geometry stage.");
1600*b7893ccfSSadaf Ebrahimi 
1601*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
1602*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
1603*b7893ccfSSadaf Ebrahimi 
1604*b7893ccfSSadaf Ebrahimi     if ((!m_device->phy().features().geometryShader) || (!m_device->phy().features().shaderTessellationAndGeometryPointSize)) {
1605*b7893ccfSSadaf Ebrahimi         printf("%s Device does not support the required geometry shader features; skipped.\n", kSkipPrefix);
1606*b7893ccfSSadaf Ebrahimi         return;
1607*b7893ccfSSadaf Ebrahimi     }
1608*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1609*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitViewport());
1610*b7893ccfSSadaf Ebrahimi 
1611*b7893ccfSSadaf Ebrahimi     // Create VS declaring PointSize and writing to it
1612*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, bindStateVertPointSizeShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
1613*b7893ccfSSadaf Ebrahimi     VkShaderObj gs(m_device, bindStateGeomPointSizeShaderText, VK_SHADER_STAGE_GEOMETRY_BIT, this);
1614*b7893ccfSSadaf Ebrahimi     VkShaderObj ps(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
1615*b7893ccfSSadaf Ebrahimi 
1616*b7893ccfSSadaf Ebrahimi     CreatePipelineHelper pipe(*this);
1617*b7893ccfSSadaf Ebrahimi     pipe.InitInfo();
1618*b7893ccfSSadaf Ebrahimi     pipe.shader_stages_ = {vs.GetStageCreateInfo(), gs.GetStageCreateInfo(), ps.GetStageCreateInfo()};
1619*b7893ccfSSadaf Ebrahimi     // Set Input Assembly to TOPOLOGY POINT LIST
1620*b7893ccfSSadaf Ebrahimi     pipe.ia_ci_.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
1621*b7893ccfSSadaf Ebrahimi     pipe.InitState();
1622*b7893ccfSSadaf Ebrahimi     pipe.CreateGraphicsPipeline();
1623*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
1624*b7893ccfSSadaf Ebrahimi }
1625*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,LoosePointSizeWrite)1626*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, LoosePointSizeWrite) {
1627*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Create a pipeline using TOPOLOGY_POINT_LIST and write PointSize outside of a structure.");
1628*b7893ccfSSadaf Ebrahimi 
1629*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
1630*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
1631*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1632*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitViewport());
1633*b7893ccfSSadaf Ebrahimi 
1634*b7893ccfSSadaf Ebrahimi     const std::string LoosePointSizeWrite = R"(
1635*b7893ccfSSadaf Ebrahimi                                        OpCapability Shader
1636*b7893ccfSSadaf Ebrahimi                                   %1 = OpExtInstImport "GLSL.std.450"
1637*b7893ccfSSadaf Ebrahimi                                        OpMemoryModel Logical GLSL450
1638*b7893ccfSSadaf Ebrahimi                                        OpEntryPoint Vertex %main "main" %glposition %glpointsize %gl_VertexIndex
1639*b7893ccfSSadaf Ebrahimi                                        OpSource GLSL 450
1640*b7893ccfSSadaf Ebrahimi                                        OpName %main "main"
1641*b7893ccfSSadaf Ebrahimi                                        OpName %vertices "vertices"
1642*b7893ccfSSadaf Ebrahimi                                        OpName %glposition "glposition"
1643*b7893ccfSSadaf Ebrahimi                                        OpName %glpointsize "glpointsize"
1644*b7893ccfSSadaf Ebrahimi                                        OpName %gl_VertexIndex "gl_VertexIndex"
1645*b7893ccfSSadaf Ebrahimi                                        OpDecorate %glposition BuiltIn Position
1646*b7893ccfSSadaf Ebrahimi                                        OpDecorate %glpointsize BuiltIn PointSize
1647*b7893ccfSSadaf Ebrahimi                                        OpDecorate %gl_VertexIndex BuiltIn VertexIndex
1648*b7893ccfSSadaf Ebrahimi                                %void = OpTypeVoid
1649*b7893ccfSSadaf Ebrahimi                                   %3 = OpTypeFunction %void
1650*b7893ccfSSadaf Ebrahimi                               %float = OpTypeFloat 32
1651*b7893ccfSSadaf Ebrahimi                             %v2float = OpTypeVector %float 2
1652*b7893ccfSSadaf Ebrahimi                                %uint = OpTypeInt 32 0
1653*b7893ccfSSadaf Ebrahimi                              %uint_3 = OpConstant %uint 3
1654*b7893ccfSSadaf Ebrahimi                 %_arr_v2float_uint_3 = OpTypeArray %v2float %uint_3
1655*b7893ccfSSadaf Ebrahimi    %_ptr_Private__arr_v2float_uint_3 = OpTypePointer Private %_arr_v2float_uint_3
1656*b7893ccfSSadaf Ebrahimi                            %vertices = OpVariable %_ptr_Private__arr_v2float_uint_3 Private
1657*b7893ccfSSadaf Ebrahimi                                 %int = OpTypeInt 32 1
1658*b7893ccfSSadaf Ebrahimi                               %int_0 = OpConstant %int 0
1659*b7893ccfSSadaf Ebrahimi                            %float_n1 = OpConstant %float -1
1660*b7893ccfSSadaf Ebrahimi                                  %16 = OpConstantComposite %v2float %float_n1 %float_n1
1661*b7893ccfSSadaf Ebrahimi                %_ptr_Private_v2float = OpTypePointer Private %v2float
1662*b7893ccfSSadaf Ebrahimi                               %int_1 = OpConstant %int 1
1663*b7893ccfSSadaf Ebrahimi                             %float_1 = OpConstant %float 1
1664*b7893ccfSSadaf Ebrahimi                                  %21 = OpConstantComposite %v2float %float_1 %float_n1
1665*b7893ccfSSadaf Ebrahimi                               %int_2 = OpConstant %int 2
1666*b7893ccfSSadaf Ebrahimi                             %float_0 = OpConstant %float 0
1667*b7893ccfSSadaf Ebrahimi                                  %25 = OpConstantComposite %v2float %float_0 %float_1
1668*b7893ccfSSadaf Ebrahimi                             %v4float = OpTypeVector %float 4
1669*b7893ccfSSadaf Ebrahimi             %_ptr_Output_gl_Position = OpTypePointer Output %v4float
1670*b7893ccfSSadaf Ebrahimi                          %glposition = OpVariable %_ptr_Output_gl_Position Output
1671*b7893ccfSSadaf Ebrahimi            %_ptr_Output_gl_PointSize = OpTypePointer Output %float
1672*b7893ccfSSadaf Ebrahimi                         %glpointsize = OpVariable %_ptr_Output_gl_PointSize Output
1673*b7893ccfSSadaf Ebrahimi                      %_ptr_Input_int = OpTypePointer Input %int
1674*b7893ccfSSadaf Ebrahimi                      %gl_VertexIndex = OpVariable %_ptr_Input_int Input
1675*b7893ccfSSadaf Ebrahimi                               %int_3 = OpConstant %int 3
1676*b7893ccfSSadaf Ebrahimi                 %_ptr_Output_v4float = OpTypePointer Output %v4float
1677*b7893ccfSSadaf Ebrahimi                   %_ptr_Output_float = OpTypePointer Output %float
1678*b7893ccfSSadaf Ebrahimi                                %main = OpFunction %void None %3
1679*b7893ccfSSadaf Ebrahimi                                   %5 = OpLabel
1680*b7893ccfSSadaf Ebrahimi                                  %18 = OpAccessChain %_ptr_Private_v2float %vertices %int_0
1681*b7893ccfSSadaf Ebrahimi                                        OpStore %18 %16
1682*b7893ccfSSadaf Ebrahimi                                  %22 = OpAccessChain %_ptr_Private_v2float %vertices %int_1
1683*b7893ccfSSadaf Ebrahimi                                        OpStore %22 %21
1684*b7893ccfSSadaf Ebrahimi                                  %26 = OpAccessChain %_ptr_Private_v2float %vertices %int_2
1685*b7893ccfSSadaf Ebrahimi                                        OpStore %26 %25
1686*b7893ccfSSadaf Ebrahimi                                  %33 = OpLoad %int %gl_VertexIndex
1687*b7893ccfSSadaf Ebrahimi                                  %35 = OpSMod %int %33 %int_3
1688*b7893ccfSSadaf Ebrahimi                                  %36 = OpAccessChain %_ptr_Private_v2float %vertices %35
1689*b7893ccfSSadaf Ebrahimi                                  %37 = OpLoad %v2float %36
1690*b7893ccfSSadaf Ebrahimi                                  %38 = OpCompositeExtract %float %37 0
1691*b7893ccfSSadaf Ebrahimi                                  %39 = OpCompositeExtract %float %37 1
1692*b7893ccfSSadaf Ebrahimi                                  %40 = OpCompositeConstruct %v4float %38 %39 %float_0 %float_1
1693*b7893ccfSSadaf Ebrahimi                                  %42 = OpAccessChain %_ptr_Output_v4float %glposition
1694*b7893ccfSSadaf Ebrahimi                                        OpStore %42 %40
1695*b7893ccfSSadaf Ebrahimi                                        OpStore %glpointsize %float_1
1696*b7893ccfSSadaf Ebrahimi                                        OpReturn
1697*b7893ccfSSadaf Ebrahimi                                        OpFunctionEnd
1698*b7893ccfSSadaf Ebrahimi         )";
1699*b7893ccfSSadaf Ebrahimi 
1700*b7893ccfSSadaf Ebrahimi     // Create VS declaring PointSize and write to it in a function call.
1701*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, LoosePointSizeWrite, VK_SHADER_STAGE_VERTEX_BIT, this);
1702*b7893ccfSSadaf Ebrahimi     VkShaderObj ps(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
1703*b7893ccfSSadaf Ebrahimi 
1704*b7893ccfSSadaf Ebrahimi     {
1705*b7893ccfSSadaf Ebrahimi         CreatePipelineHelper pipe(*this);
1706*b7893ccfSSadaf Ebrahimi         pipe.InitInfo();
1707*b7893ccfSSadaf Ebrahimi         pipe.shader_stages_ = {vs.GetStageCreateInfo(), ps.GetStageCreateInfo()};
1708*b7893ccfSSadaf Ebrahimi         // Set Input Assembly to TOPOLOGY POINT LIST
1709*b7893ccfSSadaf Ebrahimi         pipe.ia_ci_.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
1710*b7893ccfSSadaf Ebrahimi         pipe.InitState();
1711*b7893ccfSSadaf Ebrahimi         pipe.CreateGraphicsPipeline();
1712*b7893ccfSSadaf Ebrahimi     }
1713*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
1714*b7893ccfSSadaf Ebrahimi }
1715*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,UncompressedToCompressedImageCopy)1716*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, UncompressedToCompressedImageCopy) {
1717*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Image copies between compressed and uncompressed images");
1718*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
1719*b7893ccfSSadaf Ebrahimi 
1720*b7893ccfSSadaf Ebrahimi     // Verify format support
1721*b7893ccfSSadaf Ebrahimi     // Size-compatible (64-bit) formats. Uncompressed is 64 bits per texel, compressed is 64 bits per 4x4 block (or 4bpt).
1722*b7893ccfSSadaf Ebrahimi     if (!ImageFormatAndFeaturesSupported(gpu(), VK_FORMAT_R16G16B16A16_UINT, VK_IMAGE_TILING_OPTIMAL,
1723*b7893ccfSSadaf Ebrahimi                                          VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR | VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR) ||
1724*b7893ccfSSadaf Ebrahimi         !ImageFormatAndFeaturesSupported(gpu(), VK_FORMAT_BC1_RGBA_SRGB_BLOCK, VK_IMAGE_TILING_OPTIMAL,
1725*b7893ccfSSadaf Ebrahimi                                          VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR | VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR)) {
1726*b7893ccfSSadaf Ebrahimi         printf("%s Required formats/features not supported - UncompressedToCompressedImageCopy skipped.\n", kSkipPrefix);
1727*b7893ccfSSadaf Ebrahimi         return;
1728*b7893ccfSSadaf Ebrahimi     }
1729*b7893ccfSSadaf Ebrahimi 
1730*b7893ccfSSadaf Ebrahimi     VkImageObj uncomp_10x10t_image(m_device);       // Size = 10 * 10 * 64 = 6400
1731*b7893ccfSSadaf Ebrahimi     VkImageObj comp_10x10b_40x40t_image(m_device);  // Size = 40 * 40 * 4  = 6400
1732*b7893ccfSSadaf Ebrahimi 
1733*b7893ccfSSadaf Ebrahimi     uncomp_10x10t_image.Init(10, 10, 1, VK_FORMAT_R16G16B16A16_UINT,
1734*b7893ccfSSadaf Ebrahimi                              VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
1735*b7893ccfSSadaf Ebrahimi     comp_10x10b_40x40t_image.Init(40, 40, 1, VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
1736*b7893ccfSSadaf Ebrahimi                                   VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
1737*b7893ccfSSadaf Ebrahimi 
1738*b7893ccfSSadaf Ebrahimi     if (!uncomp_10x10t_image.initialized() || !comp_10x10b_40x40t_image.initialized()) {
1739*b7893ccfSSadaf Ebrahimi         printf("%s Unable to initialize surfaces - UncompressedToCompressedImageCopy skipped.\n", kSkipPrefix);
1740*b7893ccfSSadaf Ebrahimi         return;
1741*b7893ccfSSadaf Ebrahimi     }
1742*b7893ccfSSadaf Ebrahimi 
1743*b7893ccfSSadaf Ebrahimi     // Both copies represent the same number of bytes. Bytes Per Texel = 1 for bc6, 16 for uncompressed
1744*b7893ccfSSadaf Ebrahimi     // Copy compressed to uncompressed
1745*b7893ccfSSadaf Ebrahimi     VkImageCopy copy_region = {};
1746*b7893ccfSSadaf Ebrahimi     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1747*b7893ccfSSadaf Ebrahimi     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1748*b7893ccfSSadaf Ebrahimi     copy_region.srcSubresource.mipLevel = 0;
1749*b7893ccfSSadaf Ebrahimi     copy_region.dstSubresource.mipLevel = 0;
1750*b7893ccfSSadaf Ebrahimi     copy_region.srcSubresource.baseArrayLayer = 0;
1751*b7893ccfSSadaf Ebrahimi     copy_region.dstSubresource.baseArrayLayer = 0;
1752*b7893ccfSSadaf Ebrahimi     copy_region.srcSubresource.layerCount = 1;
1753*b7893ccfSSadaf Ebrahimi     copy_region.dstSubresource.layerCount = 1;
1754*b7893ccfSSadaf Ebrahimi     copy_region.srcOffset = {0, 0, 0};
1755*b7893ccfSSadaf Ebrahimi     copy_region.dstOffset = {0, 0, 0};
1756*b7893ccfSSadaf Ebrahimi 
1757*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
1758*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
1759*b7893ccfSSadaf Ebrahimi 
1760*b7893ccfSSadaf Ebrahimi     // Copy from uncompressed to compressed
1761*b7893ccfSSadaf Ebrahimi     copy_region.extent = {10, 10, 1};  // Dimensions in (uncompressed) texels
1762*b7893ccfSSadaf Ebrahimi     vkCmdCopyImage(m_commandBuffer->handle(), uncomp_10x10t_image.handle(), VK_IMAGE_LAYOUT_GENERAL,
1763*b7893ccfSSadaf Ebrahimi                    comp_10x10b_40x40t_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
1764*b7893ccfSSadaf Ebrahimi 
1765*b7893ccfSSadaf Ebrahimi     // And from compressed to uncompressed
1766*b7893ccfSSadaf Ebrahimi     copy_region.extent = {40, 40, 1};  // Dimensions in (compressed) texels
1767*b7893ccfSSadaf Ebrahimi     vkCmdCopyImage(m_commandBuffer->handle(), comp_10x10b_40x40t_image.handle(), VK_IMAGE_LAYOUT_GENERAL,
1768*b7893ccfSSadaf Ebrahimi                    uncomp_10x10t_image.handle(), VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
1769*b7893ccfSSadaf Ebrahimi 
1770*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
1771*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
1772*b7893ccfSSadaf Ebrahimi }
1773*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,DeleteDescriptorSetLayoutsBeforeDescriptorSets)1774*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, DeleteDescriptorSetLayoutsBeforeDescriptorSets) {
1775*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Create DSLayouts and DescriptorSets and then delete the DSLayouts before the DescriptorSets.");
1776*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
1777*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1778*b7893ccfSSadaf Ebrahimi     VkResult err;
1779*b7893ccfSSadaf Ebrahimi 
1780*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
1781*b7893ccfSSadaf Ebrahimi 
1782*b7893ccfSSadaf Ebrahimi     VkDescriptorPoolSize ds_type_count = {};
1783*b7893ccfSSadaf Ebrahimi     ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLER;
1784*b7893ccfSSadaf Ebrahimi     ds_type_count.descriptorCount = 1;
1785*b7893ccfSSadaf Ebrahimi 
1786*b7893ccfSSadaf Ebrahimi     VkDescriptorPoolCreateInfo ds_pool_ci = {};
1787*b7893ccfSSadaf Ebrahimi     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
1788*b7893ccfSSadaf Ebrahimi     ds_pool_ci.pNext = NULL;
1789*b7893ccfSSadaf Ebrahimi     ds_pool_ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
1790*b7893ccfSSadaf Ebrahimi     ds_pool_ci.maxSets = 1;
1791*b7893ccfSSadaf Ebrahimi     ds_pool_ci.poolSizeCount = 1;
1792*b7893ccfSSadaf Ebrahimi     ds_pool_ci.pPoolSizes = &ds_type_count;
1793*b7893ccfSSadaf Ebrahimi 
1794*b7893ccfSSadaf Ebrahimi     VkDescriptorPool ds_pool_one;
1795*b7893ccfSSadaf Ebrahimi     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool_one);
1796*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
1797*b7893ccfSSadaf Ebrahimi 
1798*b7893ccfSSadaf Ebrahimi     VkDescriptorSetLayoutBinding dsl_binding = {};
1799*b7893ccfSSadaf Ebrahimi     dsl_binding.binding = 0;
1800*b7893ccfSSadaf Ebrahimi     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
1801*b7893ccfSSadaf Ebrahimi     dsl_binding.descriptorCount = 1;
1802*b7893ccfSSadaf Ebrahimi     dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
1803*b7893ccfSSadaf Ebrahimi     dsl_binding.pImmutableSamplers = NULL;
1804*b7893ccfSSadaf Ebrahimi 
1805*b7893ccfSSadaf Ebrahimi     VkDescriptorSet descriptorSet;
1806*b7893ccfSSadaf Ebrahimi     {
1807*b7893ccfSSadaf Ebrahimi         const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
1808*b7893ccfSSadaf Ebrahimi 
1809*b7893ccfSSadaf Ebrahimi         VkDescriptorSetAllocateInfo alloc_info = {};
1810*b7893ccfSSadaf Ebrahimi         alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
1811*b7893ccfSSadaf Ebrahimi         alloc_info.descriptorSetCount = 1;
1812*b7893ccfSSadaf Ebrahimi         alloc_info.descriptorPool = ds_pool_one;
1813*b7893ccfSSadaf Ebrahimi         alloc_info.pSetLayouts = &ds_layout.handle();
1814*b7893ccfSSadaf Ebrahimi         err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
1815*b7893ccfSSadaf Ebrahimi         ASSERT_VK_SUCCESS(err);
1816*b7893ccfSSadaf Ebrahimi     }  // ds_layout destroyed
1817*b7893ccfSSadaf Ebrahimi     err = vkFreeDescriptorSets(m_device->device(), ds_pool_one, 1, &descriptorSet);
1818*b7893ccfSSadaf Ebrahimi 
1819*b7893ccfSSadaf Ebrahimi     vkDestroyDescriptorPool(m_device->device(), ds_pool_one, NULL);
1820*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
1821*b7893ccfSSadaf Ebrahimi }
1822*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CommandPoolDeleteWithReferences)1823*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CommandPoolDeleteWithReferences) {
1824*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Ensure the validation layers bookkeeping tracks the implicit command buffer frees.");
1825*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
1826*b7893ccfSSadaf Ebrahimi 
1827*b7893ccfSSadaf Ebrahimi     VkCommandPoolCreateInfo cmd_pool_info = {};
1828*b7893ccfSSadaf Ebrahimi     cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
1829*b7893ccfSSadaf Ebrahimi     cmd_pool_info.pNext = NULL;
1830*b7893ccfSSadaf Ebrahimi     cmd_pool_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
1831*b7893ccfSSadaf Ebrahimi     cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
1832*b7893ccfSSadaf Ebrahimi     cmd_pool_info.flags = 0;
1833*b7893ccfSSadaf Ebrahimi 
1834*b7893ccfSSadaf Ebrahimi     VkCommandPool secondary_cmd_pool;
1835*b7893ccfSSadaf Ebrahimi     VkResult res = vkCreateCommandPool(m_device->handle(), &cmd_pool_info, NULL, &secondary_cmd_pool);
1836*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(res);
1837*b7893ccfSSadaf Ebrahimi 
1838*b7893ccfSSadaf Ebrahimi     VkCommandBufferAllocateInfo cmdalloc = vk_testing::CommandBuffer::create_info(secondary_cmd_pool);
1839*b7893ccfSSadaf Ebrahimi     cmdalloc.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
1840*b7893ccfSSadaf Ebrahimi 
1841*b7893ccfSSadaf Ebrahimi     VkCommandBuffer secondary_cmds;
1842*b7893ccfSSadaf Ebrahimi     res = vkAllocateCommandBuffers(m_device->handle(), &cmdalloc, &secondary_cmds);
1843*b7893ccfSSadaf Ebrahimi 
1844*b7893ccfSSadaf Ebrahimi     VkCommandBufferInheritanceInfo cmd_buf_inheritance_info = {};
1845*b7893ccfSSadaf Ebrahimi     cmd_buf_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
1846*b7893ccfSSadaf Ebrahimi     cmd_buf_inheritance_info.pNext = NULL;
1847*b7893ccfSSadaf Ebrahimi     cmd_buf_inheritance_info.renderPass = VK_NULL_HANDLE;
1848*b7893ccfSSadaf Ebrahimi     cmd_buf_inheritance_info.subpass = 0;
1849*b7893ccfSSadaf Ebrahimi     cmd_buf_inheritance_info.framebuffer = VK_NULL_HANDLE;
1850*b7893ccfSSadaf Ebrahimi     cmd_buf_inheritance_info.occlusionQueryEnable = VK_FALSE;
1851*b7893ccfSSadaf Ebrahimi     cmd_buf_inheritance_info.queryFlags = 0;
1852*b7893ccfSSadaf Ebrahimi     cmd_buf_inheritance_info.pipelineStatistics = 0;
1853*b7893ccfSSadaf Ebrahimi 
1854*b7893ccfSSadaf Ebrahimi     VkCommandBufferBeginInfo secondary_begin = {};
1855*b7893ccfSSadaf Ebrahimi     secondary_begin.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
1856*b7893ccfSSadaf Ebrahimi     secondary_begin.pNext = NULL;
1857*b7893ccfSSadaf Ebrahimi     secondary_begin.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
1858*b7893ccfSSadaf Ebrahimi     secondary_begin.pInheritanceInfo = &cmd_buf_inheritance_info;
1859*b7893ccfSSadaf Ebrahimi 
1860*b7893ccfSSadaf Ebrahimi     res = vkBeginCommandBuffer(secondary_cmds, &secondary_begin);
1861*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(res);
1862*b7893ccfSSadaf Ebrahimi     vkEndCommandBuffer(secondary_cmds);
1863*b7893ccfSSadaf Ebrahimi 
1864*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
1865*b7893ccfSSadaf Ebrahimi     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_cmds);
1866*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
1867*b7893ccfSSadaf Ebrahimi 
1868*b7893ccfSSadaf Ebrahimi     // DestroyCommandPool *implicitly* frees the command buffers allocated from it
1869*b7893ccfSSadaf Ebrahimi     vkDestroyCommandPool(m_device->handle(), secondary_cmd_pool, NULL);
1870*b7893ccfSSadaf Ebrahimi     // If bookkeeping has been lax, validating the reset will attempt to touch deleted data
1871*b7893ccfSSadaf Ebrahimi     res = vkResetCommandPool(m_device->handle(), m_commandPool->handle(), 0);
1872*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(res);
1873*b7893ccfSSadaf Ebrahimi }
1874*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,SecondaryCommandBufferClearColorAttachments)1875*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, SecondaryCommandBufferClearColorAttachments) {
1876*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Create a secondary command buffer and record a CmdClearAttachments call into it");
1877*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
1878*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
1879*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1880*b7893ccfSSadaf Ebrahimi 
1881*b7893ccfSSadaf Ebrahimi     VkCommandBufferAllocateInfo command_buffer_allocate_info = {};
1882*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
1883*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandPool = m_commandPool->handle();
1884*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
1885*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandBufferCount = 1;
1886*b7893ccfSSadaf Ebrahimi 
1887*b7893ccfSSadaf Ebrahimi     VkCommandBuffer secondary_command_buffer;
1888*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer));
1889*b7893ccfSSadaf Ebrahimi     VkCommandBufferBeginInfo command_buffer_begin_info = {};
1890*b7893ccfSSadaf Ebrahimi     VkCommandBufferInheritanceInfo command_buffer_inheritance_info = {};
1891*b7893ccfSSadaf Ebrahimi     command_buffer_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
1892*b7893ccfSSadaf Ebrahimi     command_buffer_inheritance_info.renderPass = m_renderPass;
1893*b7893ccfSSadaf Ebrahimi     command_buffer_inheritance_info.framebuffer = m_framebuffer;
1894*b7893ccfSSadaf Ebrahimi 
1895*b7893ccfSSadaf Ebrahimi     command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
1896*b7893ccfSSadaf Ebrahimi     command_buffer_begin_info.flags =
1897*b7893ccfSSadaf Ebrahimi         VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
1898*b7893ccfSSadaf Ebrahimi     command_buffer_begin_info.pInheritanceInfo = &command_buffer_inheritance_info;
1899*b7893ccfSSadaf Ebrahimi 
1900*b7893ccfSSadaf Ebrahimi     vkBeginCommandBuffer(secondary_command_buffer, &command_buffer_begin_info);
1901*b7893ccfSSadaf Ebrahimi     VkClearAttachment color_attachment;
1902*b7893ccfSSadaf Ebrahimi     color_attachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1903*b7893ccfSSadaf Ebrahimi     color_attachment.clearValue.color.float32[0] = 0;
1904*b7893ccfSSadaf Ebrahimi     color_attachment.clearValue.color.float32[1] = 0;
1905*b7893ccfSSadaf Ebrahimi     color_attachment.clearValue.color.float32[2] = 0;
1906*b7893ccfSSadaf Ebrahimi     color_attachment.clearValue.color.float32[3] = 0;
1907*b7893ccfSSadaf Ebrahimi     color_attachment.colorAttachment = 0;
1908*b7893ccfSSadaf Ebrahimi     VkClearRect clear_rect = {{{0, 0}, {32, 32}}, 0, 1};
1909*b7893ccfSSadaf Ebrahimi     vkCmdClearAttachments(secondary_command_buffer, 1, &color_attachment, 1, &clear_rect);
1910*b7893ccfSSadaf Ebrahimi     vkEndCommandBuffer(secondary_command_buffer);
1911*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
1912*b7893ccfSSadaf Ebrahimi     vkCmdBeginRenderPass(m_commandBuffer->handle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
1913*b7893ccfSSadaf Ebrahimi     vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &secondary_command_buffer);
1914*b7893ccfSSadaf Ebrahimi     vkCmdEndRenderPass(m_commandBuffer->handle());
1915*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
1916*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
1917*b7893ccfSSadaf Ebrahimi }
1918*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,SecondaryCommandBufferImageLayoutTransitions)1919*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, SecondaryCommandBufferImageLayoutTransitions) {
1920*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Perform an image layout transition in a secondary command buffer followed by a transition in the primary.");
1921*b7893ccfSSadaf Ebrahimi     VkResult err;
1922*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
1923*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
1924*b7893ccfSSadaf Ebrahimi     auto depth_format = FindSupportedDepthStencilFormat(gpu());
1925*b7893ccfSSadaf Ebrahimi     if (!depth_format) {
1926*b7893ccfSSadaf Ebrahimi         printf("%s Couldn't find depth stencil format.\n", kSkipPrefix);
1927*b7893ccfSSadaf Ebrahimi         return;
1928*b7893ccfSSadaf Ebrahimi     }
1929*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
1930*b7893ccfSSadaf Ebrahimi     // Allocate a secondary and primary cmd buffer
1931*b7893ccfSSadaf Ebrahimi     VkCommandBufferAllocateInfo command_buffer_allocate_info = {};
1932*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
1933*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandPool = m_commandPool->handle();
1934*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
1935*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandBufferCount = 1;
1936*b7893ccfSSadaf Ebrahimi 
1937*b7893ccfSSadaf Ebrahimi     VkCommandBuffer secondary_command_buffer;
1938*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer));
1939*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
1940*b7893ccfSSadaf Ebrahimi     VkCommandBuffer primary_command_buffer;
1941*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &primary_command_buffer));
1942*b7893ccfSSadaf Ebrahimi     VkCommandBufferBeginInfo command_buffer_begin_info = {};
1943*b7893ccfSSadaf Ebrahimi     VkCommandBufferInheritanceInfo command_buffer_inheritance_info = {};
1944*b7893ccfSSadaf Ebrahimi     command_buffer_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
1945*b7893ccfSSadaf Ebrahimi     command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
1946*b7893ccfSSadaf Ebrahimi     command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
1947*b7893ccfSSadaf Ebrahimi     command_buffer_begin_info.pInheritanceInfo = &command_buffer_inheritance_info;
1948*b7893ccfSSadaf Ebrahimi 
1949*b7893ccfSSadaf Ebrahimi     err = vkBeginCommandBuffer(secondary_command_buffer, &command_buffer_begin_info);
1950*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
1951*b7893ccfSSadaf Ebrahimi     VkImageObj image(m_device);
1952*b7893ccfSSadaf Ebrahimi     image.Init(128, 128, 1, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
1953*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(image.initialized());
1954*b7893ccfSSadaf Ebrahimi     VkImageMemoryBarrier img_barrier = {};
1955*b7893ccfSSadaf Ebrahimi     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
1956*b7893ccfSSadaf Ebrahimi     img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
1957*b7893ccfSSadaf Ebrahimi     img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
1958*b7893ccfSSadaf Ebrahimi     img_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1959*b7893ccfSSadaf Ebrahimi     img_barrier.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
1960*b7893ccfSSadaf Ebrahimi     img_barrier.image = image.handle();
1961*b7893ccfSSadaf Ebrahimi     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1962*b7893ccfSSadaf Ebrahimi     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1963*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1964*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.baseArrayLayer = 0;
1965*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.baseMipLevel = 0;
1966*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.layerCount = 1;
1967*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.levelCount = 1;
1968*b7893ccfSSadaf Ebrahimi     vkCmdPipelineBarrier(secondary_command_buffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr,
1969*b7893ccfSSadaf Ebrahimi                          0, nullptr, 1, &img_barrier);
1970*b7893ccfSSadaf Ebrahimi     err = vkEndCommandBuffer(secondary_command_buffer);
1971*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
1972*b7893ccfSSadaf Ebrahimi 
1973*b7893ccfSSadaf Ebrahimi     // Now update primary cmd buffer to execute secondary and transitions image
1974*b7893ccfSSadaf Ebrahimi     command_buffer_begin_info.pInheritanceInfo = nullptr;
1975*b7893ccfSSadaf Ebrahimi     err = vkBeginCommandBuffer(primary_command_buffer, &command_buffer_begin_info);
1976*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
1977*b7893ccfSSadaf Ebrahimi     vkCmdExecuteCommands(primary_command_buffer, 1, &secondary_command_buffer);
1978*b7893ccfSSadaf Ebrahimi     VkImageMemoryBarrier img_barrier2 = {};
1979*b7893ccfSSadaf Ebrahimi     img_barrier2.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
1980*b7893ccfSSadaf Ebrahimi     img_barrier2.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
1981*b7893ccfSSadaf Ebrahimi     img_barrier2.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
1982*b7893ccfSSadaf Ebrahimi     img_barrier2.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
1983*b7893ccfSSadaf Ebrahimi     img_barrier2.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
1984*b7893ccfSSadaf Ebrahimi     img_barrier2.image = image.handle();
1985*b7893ccfSSadaf Ebrahimi     img_barrier2.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1986*b7893ccfSSadaf Ebrahimi     img_barrier2.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1987*b7893ccfSSadaf Ebrahimi     img_barrier2.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1988*b7893ccfSSadaf Ebrahimi     img_barrier2.subresourceRange.baseArrayLayer = 0;
1989*b7893ccfSSadaf Ebrahimi     img_barrier2.subresourceRange.baseMipLevel = 0;
1990*b7893ccfSSadaf Ebrahimi     img_barrier2.subresourceRange.layerCount = 1;
1991*b7893ccfSSadaf Ebrahimi     img_barrier2.subresourceRange.levelCount = 1;
1992*b7893ccfSSadaf Ebrahimi     vkCmdPipelineBarrier(primary_command_buffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr, 0,
1993*b7893ccfSSadaf Ebrahimi                          nullptr, 1, &img_barrier2);
1994*b7893ccfSSadaf Ebrahimi     err = vkEndCommandBuffer(primary_command_buffer);
1995*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
1996*b7893ccfSSadaf Ebrahimi     VkSubmitInfo submit_info = {};
1997*b7893ccfSSadaf Ebrahimi     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1998*b7893ccfSSadaf Ebrahimi     submit_info.commandBufferCount = 1;
1999*b7893ccfSSadaf Ebrahimi     submit_info.pCommandBuffers = &primary_command_buffer;
2000*b7893ccfSSadaf Ebrahimi     err = vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
2001*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
2002*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
2003*b7893ccfSSadaf Ebrahimi     err = vkDeviceWaitIdle(m_device->device());
2004*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
2005*b7893ccfSSadaf Ebrahimi     vkFreeCommandBuffers(m_device->device(), m_commandPool->handle(), 1, &secondary_command_buffer);
2006*b7893ccfSSadaf Ebrahimi     vkFreeCommandBuffers(m_device->device(), m_commandPool->handle(), 1, &primary_command_buffer);
2007*b7893ccfSSadaf Ebrahimi }
2008*b7893ccfSSadaf Ebrahimi 
2009*b7893ccfSSadaf Ebrahimi // This is a positive test. No failures are expected.
TEST_F(VkPositiveLayerTest,IgnoreUnrelatedDescriptor)2010*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, IgnoreUnrelatedDescriptor) {
2011*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
2012*b7893ccfSSadaf Ebrahimi         "Ensure that the vkUpdateDescriptorSets validation code is ignoring VkWriteDescriptorSet members that are not related to "
2013*b7893ccfSSadaf Ebrahimi         "the descriptor type specified by VkWriteDescriptorSet::descriptorType.  Correct validation behavior will result in the "
2014*b7893ccfSSadaf Ebrahimi         "test running to completion without validation errors.");
2015*b7893ccfSSadaf Ebrahimi 
2016*b7893ccfSSadaf Ebrahimi     const uintptr_t invalid_ptr = 0xcdcdcdcd;
2017*b7893ccfSSadaf Ebrahimi 
2018*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
2019*b7893ccfSSadaf Ebrahimi 
2020*b7893ccfSSadaf Ebrahimi     // Verify VK_FORMAT_R8_UNORM supports VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT
2021*b7893ccfSSadaf Ebrahimi     const VkFormat format_texel_case = VK_FORMAT_R8_UNORM;
2022*b7893ccfSSadaf Ebrahimi     const char *format_texel_case_string = "VK_FORMAT_R8_UNORM";
2023*b7893ccfSSadaf Ebrahimi     VkFormatProperties format_properties;
2024*b7893ccfSSadaf Ebrahimi     vkGetPhysicalDeviceFormatProperties(gpu(), format_texel_case, &format_properties);
2025*b7893ccfSSadaf Ebrahimi     if (!(format_properties.bufferFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT)) {
2026*b7893ccfSSadaf Ebrahimi         printf("%s Test requires %s to support VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT\n", kSkipPrefix, format_texel_case_string);
2027*b7893ccfSSadaf Ebrahimi         return;
2028*b7893ccfSSadaf Ebrahimi     }
2029*b7893ccfSSadaf Ebrahimi 
2030*b7893ccfSSadaf Ebrahimi     // Image Case
2031*b7893ccfSSadaf Ebrahimi     {
2032*b7893ccfSSadaf Ebrahimi         m_errorMonitor->ExpectSuccess();
2033*b7893ccfSSadaf Ebrahimi 
2034*b7893ccfSSadaf Ebrahimi         VkImageObj image(m_device);
2035*b7893ccfSSadaf Ebrahimi         image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
2036*b7893ccfSSadaf Ebrahimi 
2037*b7893ccfSSadaf Ebrahimi         VkImageView view = image.targetView(VK_FORMAT_B8G8R8A8_UNORM);
2038*b7893ccfSSadaf Ebrahimi 
2039*b7893ccfSSadaf Ebrahimi         OneOffDescriptorSet descriptor_set(m_device, {
2040*b7893ccfSSadaf Ebrahimi                                                          {0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_ALL, nullptr},
2041*b7893ccfSSadaf Ebrahimi                                                      });
2042*b7893ccfSSadaf Ebrahimi 
2043*b7893ccfSSadaf Ebrahimi         VkDescriptorImageInfo image_info = {};
2044*b7893ccfSSadaf Ebrahimi         image_info.imageView = view;
2045*b7893ccfSSadaf Ebrahimi         image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
2046*b7893ccfSSadaf Ebrahimi 
2047*b7893ccfSSadaf Ebrahimi         VkWriteDescriptorSet descriptor_write;
2048*b7893ccfSSadaf Ebrahimi         memset(&descriptor_write, 0, sizeof(descriptor_write));
2049*b7893ccfSSadaf Ebrahimi         descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
2050*b7893ccfSSadaf Ebrahimi         descriptor_write.dstSet = descriptor_set.set_;
2051*b7893ccfSSadaf Ebrahimi         descriptor_write.dstBinding = 0;
2052*b7893ccfSSadaf Ebrahimi         descriptor_write.descriptorCount = 1;
2053*b7893ccfSSadaf Ebrahimi         descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
2054*b7893ccfSSadaf Ebrahimi         descriptor_write.pImageInfo = &image_info;
2055*b7893ccfSSadaf Ebrahimi 
2056*b7893ccfSSadaf Ebrahimi         // Set pBufferInfo and pTexelBufferView to invalid values, which should
2057*b7893ccfSSadaf Ebrahimi         // be
2058*b7893ccfSSadaf Ebrahimi         //  ignored for descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE.
2059*b7893ccfSSadaf Ebrahimi         // This will most likely produce a crash if the parameter_validation
2060*b7893ccfSSadaf Ebrahimi         // layer
2061*b7893ccfSSadaf Ebrahimi         // does not correctly ignore pBufferInfo.
2062*b7893ccfSSadaf Ebrahimi         descriptor_write.pBufferInfo = reinterpret_cast<const VkDescriptorBufferInfo *>(invalid_ptr);
2063*b7893ccfSSadaf Ebrahimi         descriptor_write.pTexelBufferView = reinterpret_cast<const VkBufferView *>(invalid_ptr);
2064*b7893ccfSSadaf Ebrahimi 
2065*b7893ccfSSadaf Ebrahimi         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
2066*b7893ccfSSadaf Ebrahimi 
2067*b7893ccfSSadaf Ebrahimi         m_errorMonitor->VerifyNotFound();
2068*b7893ccfSSadaf Ebrahimi     }
2069*b7893ccfSSadaf Ebrahimi 
2070*b7893ccfSSadaf Ebrahimi     // Buffer Case
2071*b7893ccfSSadaf Ebrahimi     {
2072*b7893ccfSSadaf Ebrahimi         m_errorMonitor->ExpectSuccess();
2073*b7893ccfSSadaf Ebrahimi 
2074*b7893ccfSSadaf Ebrahimi         uint32_t queue_family_index = 0;
2075*b7893ccfSSadaf Ebrahimi         VkBufferCreateInfo buffer_create_info = {};
2076*b7893ccfSSadaf Ebrahimi         buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
2077*b7893ccfSSadaf Ebrahimi         buffer_create_info.size = 1024;
2078*b7893ccfSSadaf Ebrahimi         buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
2079*b7893ccfSSadaf Ebrahimi         buffer_create_info.queueFamilyIndexCount = 1;
2080*b7893ccfSSadaf Ebrahimi         buffer_create_info.pQueueFamilyIndices = &queue_family_index;
2081*b7893ccfSSadaf Ebrahimi 
2082*b7893ccfSSadaf Ebrahimi         VkBufferObj buffer;
2083*b7893ccfSSadaf Ebrahimi         buffer.init(*m_device, buffer_create_info);
2084*b7893ccfSSadaf Ebrahimi 
2085*b7893ccfSSadaf Ebrahimi         OneOffDescriptorSet descriptor_set(m_device, {
2086*b7893ccfSSadaf Ebrahimi                                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
2087*b7893ccfSSadaf Ebrahimi                                                      });
2088*b7893ccfSSadaf Ebrahimi 
2089*b7893ccfSSadaf Ebrahimi         VkDescriptorBufferInfo buffer_info = {};
2090*b7893ccfSSadaf Ebrahimi         buffer_info.buffer = buffer.handle();
2091*b7893ccfSSadaf Ebrahimi         buffer_info.offset = 0;
2092*b7893ccfSSadaf Ebrahimi         buffer_info.range = 1024;
2093*b7893ccfSSadaf Ebrahimi 
2094*b7893ccfSSadaf Ebrahimi         VkWriteDescriptorSet descriptor_write;
2095*b7893ccfSSadaf Ebrahimi         memset(&descriptor_write, 0, sizeof(descriptor_write));
2096*b7893ccfSSadaf Ebrahimi         descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
2097*b7893ccfSSadaf Ebrahimi         descriptor_write.dstSet = descriptor_set.set_;
2098*b7893ccfSSadaf Ebrahimi         descriptor_write.dstBinding = 0;
2099*b7893ccfSSadaf Ebrahimi         descriptor_write.descriptorCount = 1;
2100*b7893ccfSSadaf Ebrahimi         descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
2101*b7893ccfSSadaf Ebrahimi         descriptor_write.pBufferInfo = &buffer_info;
2102*b7893ccfSSadaf Ebrahimi 
2103*b7893ccfSSadaf Ebrahimi         // Set pImageInfo and pTexelBufferView to invalid values, which should
2104*b7893ccfSSadaf Ebrahimi         // be
2105*b7893ccfSSadaf Ebrahimi         //  ignored for descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER.
2106*b7893ccfSSadaf Ebrahimi         // This will most likely produce a crash if the parameter_validation
2107*b7893ccfSSadaf Ebrahimi         // layer
2108*b7893ccfSSadaf Ebrahimi         // does not correctly ignore pImageInfo.
2109*b7893ccfSSadaf Ebrahimi         descriptor_write.pImageInfo = reinterpret_cast<const VkDescriptorImageInfo *>(invalid_ptr);
2110*b7893ccfSSadaf Ebrahimi         descriptor_write.pTexelBufferView = reinterpret_cast<const VkBufferView *>(invalid_ptr);
2111*b7893ccfSSadaf Ebrahimi 
2112*b7893ccfSSadaf Ebrahimi         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
2113*b7893ccfSSadaf Ebrahimi 
2114*b7893ccfSSadaf Ebrahimi         m_errorMonitor->VerifyNotFound();
2115*b7893ccfSSadaf Ebrahimi     }
2116*b7893ccfSSadaf Ebrahimi 
2117*b7893ccfSSadaf Ebrahimi     // Texel Buffer Case
2118*b7893ccfSSadaf Ebrahimi     {
2119*b7893ccfSSadaf Ebrahimi         m_errorMonitor->ExpectSuccess();
2120*b7893ccfSSadaf Ebrahimi 
2121*b7893ccfSSadaf Ebrahimi         uint32_t queue_family_index = 0;
2122*b7893ccfSSadaf Ebrahimi         VkBufferCreateInfo buffer_create_info = {};
2123*b7893ccfSSadaf Ebrahimi         buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
2124*b7893ccfSSadaf Ebrahimi         buffer_create_info.size = 1024;
2125*b7893ccfSSadaf Ebrahimi         buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
2126*b7893ccfSSadaf Ebrahimi         buffer_create_info.queueFamilyIndexCount = 1;
2127*b7893ccfSSadaf Ebrahimi         buffer_create_info.pQueueFamilyIndices = &queue_family_index;
2128*b7893ccfSSadaf Ebrahimi 
2129*b7893ccfSSadaf Ebrahimi         VkBufferObj buffer;
2130*b7893ccfSSadaf Ebrahimi         buffer.init(*m_device, buffer_create_info);
2131*b7893ccfSSadaf Ebrahimi 
2132*b7893ccfSSadaf Ebrahimi         VkBufferViewCreateInfo buff_view_ci = {};
2133*b7893ccfSSadaf Ebrahimi         buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
2134*b7893ccfSSadaf Ebrahimi         buff_view_ci.buffer = buffer.handle();
2135*b7893ccfSSadaf Ebrahimi         buff_view_ci.format = format_texel_case;
2136*b7893ccfSSadaf Ebrahimi         buff_view_ci.range = VK_WHOLE_SIZE;
2137*b7893ccfSSadaf Ebrahimi         VkBufferView buffer_view;
2138*b7893ccfSSadaf Ebrahimi         VkResult err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buffer_view);
2139*b7893ccfSSadaf Ebrahimi         ASSERT_VK_SUCCESS(err);
2140*b7893ccfSSadaf Ebrahimi         OneOffDescriptorSet descriptor_set(m_device,
2141*b7893ccfSSadaf Ebrahimi                                            {
2142*b7893ccfSSadaf Ebrahimi                                                {0, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
2143*b7893ccfSSadaf Ebrahimi                                            });
2144*b7893ccfSSadaf Ebrahimi 
2145*b7893ccfSSadaf Ebrahimi         VkWriteDescriptorSet descriptor_write;
2146*b7893ccfSSadaf Ebrahimi         memset(&descriptor_write, 0, sizeof(descriptor_write));
2147*b7893ccfSSadaf Ebrahimi         descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
2148*b7893ccfSSadaf Ebrahimi         descriptor_write.dstSet = descriptor_set.set_;
2149*b7893ccfSSadaf Ebrahimi         descriptor_write.dstBinding = 0;
2150*b7893ccfSSadaf Ebrahimi         descriptor_write.descriptorCount = 1;
2151*b7893ccfSSadaf Ebrahimi         descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
2152*b7893ccfSSadaf Ebrahimi         descriptor_write.pTexelBufferView = &buffer_view;
2153*b7893ccfSSadaf Ebrahimi 
2154*b7893ccfSSadaf Ebrahimi         // Set pImageInfo and pBufferInfo to invalid values, which should be
2155*b7893ccfSSadaf Ebrahimi         //  ignored for descriptorType ==
2156*b7893ccfSSadaf Ebrahimi         //  VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER.
2157*b7893ccfSSadaf Ebrahimi         // This will most likely produce a crash if the parameter_validation
2158*b7893ccfSSadaf Ebrahimi         // layer
2159*b7893ccfSSadaf Ebrahimi         // does not correctly ignore pImageInfo and pBufferInfo.
2160*b7893ccfSSadaf Ebrahimi         descriptor_write.pImageInfo = reinterpret_cast<const VkDescriptorImageInfo *>(invalid_ptr);
2161*b7893ccfSSadaf Ebrahimi         descriptor_write.pBufferInfo = reinterpret_cast<const VkDescriptorBufferInfo *>(invalid_ptr);
2162*b7893ccfSSadaf Ebrahimi 
2163*b7893ccfSSadaf Ebrahimi         vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
2164*b7893ccfSSadaf Ebrahimi 
2165*b7893ccfSSadaf Ebrahimi         m_errorMonitor->VerifyNotFound();
2166*b7893ccfSSadaf Ebrahimi 
2167*b7893ccfSSadaf Ebrahimi         vkDestroyBufferView(m_device->device(), buffer_view, NULL);
2168*b7893ccfSSadaf Ebrahimi     }
2169*b7893ccfSSadaf Ebrahimi }
2170*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,ImmutableSamplerOnlyDescriptor)2171*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, ImmutableSamplerOnlyDescriptor) {
2172*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Bind a DescriptorSet with only an immutable sampler and make sure that we don't warn for no update.");
2173*b7893ccfSSadaf Ebrahimi 
2174*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
2175*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2176*b7893ccfSSadaf Ebrahimi 
2177*b7893ccfSSadaf Ebrahimi     OneOffDescriptorSet descriptor_set(m_device, {
2178*b7893ccfSSadaf Ebrahimi                                                      {0, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
2179*b7893ccfSSadaf Ebrahimi                                                  });
2180*b7893ccfSSadaf Ebrahimi 
2181*b7893ccfSSadaf Ebrahimi     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
2182*b7893ccfSSadaf Ebrahimi     VkSampler sampler;
2183*b7893ccfSSadaf Ebrahimi     VkResult err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
2184*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
2185*b7893ccfSSadaf Ebrahimi 
2186*b7893ccfSSadaf Ebrahimi     const VkPipelineLayoutObj pipeline_layout(m_device, {&descriptor_set.layout_});
2187*b7893ccfSSadaf Ebrahimi 
2188*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
2189*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
2190*b7893ccfSSadaf Ebrahimi     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2191*b7893ccfSSadaf Ebrahimi 
2192*b7893ccfSSadaf Ebrahimi     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
2193*b7893ccfSSadaf Ebrahimi                             &descriptor_set.set_, 0, nullptr);
2194*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
2195*b7893ccfSSadaf Ebrahimi 
2196*b7893ccfSSadaf Ebrahimi     vkDestroySampler(m_device->device(), sampler, NULL);
2197*b7893ccfSSadaf Ebrahimi 
2198*b7893ccfSSadaf Ebrahimi     m_commandBuffer->EndRenderPass();
2199*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
2200*b7893ccfSSadaf Ebrahimi }
2201*b7893ccfSSadaf Ebrahimi 
2202*b7893ccfSSadaf Ebrahimi // This is a positive test. No failures are expected.
TEST_F(VkPositiveLayerTest,EmptyDescriptorUpdateTest)2203*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, EmptyDescriptorUpdateTest) {
2204*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Update last descriptor in a set that includes an empty binding");
2205*b7893ccfSSadaf Ebrahimi     VkResult err;
2206*b7893ccfSSadaf Ebrahimi 
2207*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
2208*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
2209*b7893ccfSSadaf Ebrahimi 
2210*b7893ccfSSadaf Ebrahimi     // Create layout with two uniform buffer descriptors w/ empty binding between them
2211*b7893ccfSSadaf Ebrahimi     OneOffDescriptorSet ds(m_device, {
2212*b7893ccfSSadaf Ebrahimi                                          {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
2213*b7893ccfSSadaf Ebrahimi                                          {1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0 /*!*/, 0, nullptr},
2214*b7893ccfSSadaf Ebrahimi                                          {2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
2215*b7893ccfSSadaf Ebrahimi                                      });
2216*b7893ccfSSadaf Ebrahimi 
2217*b7893ccfSSadaf Ebrahimi     // Create a buffer to be used for update
2218*b7893ccfSSadaf Ebrahimi     VkBufferCreateInfo buff_ci = {};
2219*b7893ccfSSadaf Ebrahimi     buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
2220*b7893ccfSSadaf Ebrahimi     buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
2221*b7893ccfSSadaf Ebrahimi     buff_ci.size = 256;
2222*b7893ccfSSadaf Ebrahimi     buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2223*b7893ccfSSadaf Ebrahimi     VkBuffer buffer;
2224*b7893ccfSSadaf Ebrahimi     err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
2225*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
2226*b7893ccfSSadaf Ebrahimi     // Have to bind memory to buffer before descriptor update
2227*b7893ccfSSadaf Ebrahimi     VkMemoryAllocateInfo mem_alloc = {};
2228*b7893ccfSSadaf Ebrahimi     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
2229*b7893ccfSSadaf Ebrahimi     mem_alloc.pNext = NULL;
2230*b7893ccfSSadaf Ebrahimi     mem_alloc.allocationSize = 512;  // one allocation for both buffers
2231*b7893ccfSSadaf Ebrahimi     mem_alloc.memoryTypeIndex = 0;
2232*b7893ccfSSadaf Ebrahimi 
2233*b7893ccfSSadaf Ebrahimi     VkMemoryRequirements mem_reqs;
2234*b7893ccfSSadaf Ebrahimi     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
2235*b7893ccfSSadaf Ebrahimi     bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
2236*b7893ccfSSadaf Ebrahimi     if (!pass) {
2237*b7893ccfSSadaf Ebrahimi         printf("%s Failed to allocate memory.\n", kSkipPrefix);
2238*b7893ccfSSadaf Ebrahimi         vkDestroyBuffer(m_device->device(), buffer, NULL);
2239*b7893ccfSSadaf Ebrahimi         return;
2240*b7893ccfSSadaf Ebrahimi     }
2241*b7893ccfSSadaf Ebrahimi     // Make sure allocation is sufficiently large to accommodate buffer requirements
2242*b7893ccfSSadaf Ebrahimi     if (mem_reqs.size > mem_alloc.allocationSize) {
2243*b7893ccfSSadaf Ebrahimi         mem_alloc.allocationSize = mem_reqs.size;
2244*b7893ccfSSadaf Ebrahimi     }
2245*b7893ccfSSadaf Ebrahimi 
2246*b7893ccfSSadaf Ebrahimi     VkDeviceMemory mem;
2247*b7893ccfSSadaf Ebrahimi     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
2248*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
2249*b7893ccfSSadaf Ebrahimi     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
2250*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
2251*b7893ccfSSadaf Ebrahimi 
2252*b7893ccfSSadaf Ebrahimi     // Only update the descriptor at binding 2
2253*b7893ccfSSadaf Ebrahimi     VkDescriptorBufferInfo buff_info = {};
2254*b7893ccfSSadaf Ebrahimi     buff_info.buffer = buffer;
2255*b7893ccfSSadaf Ebrahimi     buff_info.offset = 0;
2256*b7893ccfSSadaf Ebrahimi     buff_info.range = VK_WHOLE_SIZE;
2257*b7893ccfSSadaf Ebrahimi     VkWriteDescriptorSet descriptor_write = {};
2258*b7893ccfSSadaf Ebrahimi     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
2259*b7893ccfSSadaf Ebrahimi     descriptor_write.dstBinding = 2;
2260*b7893ccfSSadaf Ebrahimi     descriptor_write.descriptorCount = 1;
2261*b7893ccfSSadaf Ebrahimi     descriptor_write.pTexelBufferView = nullptr;
2262*b7893ccfSSadaf Ebrahimi     descriptor_write.pBufferInfo = &buff_info;
2263*b7893ccfSSadaf Ebrahimi     descriptor_write.pImageInfo = nullptr;
2264*b7893ccfSSadaf Ebrahimi     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
2265*b7893ccfSSadaf Ebrahimi     descriptor_write.dstSet = ds.set_;
2266*b7893ccfSSadaf Ebrahimi 
2267*b7893ccfSSadaf Ebrahimi     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
2268*b7893ccfSSadaf Ebrahimi 
2269*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
2270*b7893ccfSSadaf Ebrahimi     // Cleanup
2271*b7893ccfSSadaf Ebrahimi     vkFreeMemory(m_device->device(), mem, NULL);
2272*b7893ccfSSadaf Ebrahimi     vkDestroyBuffer(m_device->device(), buffer, NULL);
2273*b7893ccfSSadaf Ebrahimi }
2274*b7893ccfSSadaf Ebrahimi 
2275*b7893ccfSSadaf Ebrahimi // This is a positive test. No failures are expected.
TEST_F(VkPositiveLayerTest,PushDescriptorNullDstSetTest)2276*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, PushDescriptorNullDstSetTest) {
2277*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Use null dstSet in CmdPushDescriptorSetKHR");
2278*b7893ccfSSadaf Ebrahimi 
2279*b7893ccfSSadaf Ebrahimi     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
2280*b7893ccfSSadaf Ebrahimi         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2281*b7893ccfSSadaf Ebrahimi     } else {
2282*b7893ccfSSadaf Ebrahimi         printf("%s Did not find VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; skipped.\n", kSkipPrefix);
2283*b7893ccfSSadaf Ebrahimi         return;
2284*b7893ccfSSadaf Ebrahimi     }
2285*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
2286*b7893ccfSSadaf Ebrahimi     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
2287*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
2288*b7893ccfSSadaf Ebrahimi     } else {
2289*b7893ccfSSadaf Ebrahimi         printf("%s Push Descriptors Extension not supported, skipping tests\n", kSkipPrefix);
2290*b7893ccfSSadaf Ebrahimi         return;
2291*b7893ccfSSadaf Ebrahimi     }
2292*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
2293*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
2294*b7893ccfSSadaf Ebrahimi 
2295*b7893ccfSSadaf Ebrahimi     auto push_descriptor_prop = GetPushDescriptorProperties(instance(), gpu());
2296*b7893ccfSSadaf Ebrahimi     if (push_descriptor_prop.maxPushDescriptors < 1) {
2297*b7893ccfSSadaf Ebrahimi         // Some implementations report an invalid maxPushDescriptors of 0
2298*b7893ccfSSadaf Ebrahimi         printf("%s maxPushDescriptors is zero, skipping tests\n", kSkipPrefix);
2299*b7893ccfSSadaf Ebrahimi         return;
2300*b7893ccfSSadaf Ebrahimi     }
2301*b7893ccfSSadaf Ebrahimi 
2302*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitViewport());
2303*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2304*b7893ccfSSadaf Ebrahimi 
2305*b7893ccfSSadaf Ebrahimi     VkDescriptorSetLayoutBinding dsl_binding = {};
2306*b7893ccfSSadaf Ebrahimi     dsl_binding.binding = 2;
2307*b7893ccfSSadaf Ebrahimi     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
2308*b7893ccfSSadaf Ebrahimi     dsl_binding.descriptorCount = 1;
2309*b7893ccfSSadaf Ebrahimi     dsl_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
2310*b7893ccfSSadaf Ebrahimi     dsl_binding.pImmutableSamplers = NULL;
2311*b7893ccfSSadaf Ebrahimi 
2312*b7893ccfSSadaf Ebrahimi     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
2313*b7893ccfSSadaf Ebrahimi     // Create push descriptor set layout
2314*b7893ccfSSadaf Ebrahimi     const VkDescriptorSetLayoutObj push_ds_layout(m_device, {dsl_binding}, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
2315*b7893ccfSSadaf Ebrahimi 
2316*b7893ccfSSadaf Ebrahimi     // Use helper to create graphics pipeline
2317*b7893ccfSSadaf Ebrahimi     CreatePipelineHelper helper(*this);
2318*b7893ccfSSadaf Ebrahimi     helper.InitInfo();
2319*b7893ccfSSadaf Ebrahimi     helper.InitState();
2320*b7893ccfSSadaf Ebrahimi     helper.pipeline_layout_ = VkPipelineLayoutObj(m_device, {&push_ds_layout, &ds_layout});
2321*b7893ccfSSadaf Ebrahimi     helper.CreateGraphicsPipeline();
2322*b7893ccfSSadaf Ebrahimi 
2323*b7893ccfSSadaf Ebrahimi     const float vbo_data[3] = {1.f, 0.f, 1.f};
2324*b7893ccfSSadaf Ebrahimi     VkConstantBufferObj vbo(m_device, sizeof(vbo_data), (const void *)&vbo_data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
2325*b7893ccfSSadaf Ebrahimi 
2326*b7893ccfSSadaf Ebrahimi     VkDescriptorBufferInfo buff_info;
2327*b7893ccfSSadaf Ebrahimi     buff_info.buffer = vbo.handle();
2328*b7893ccfSSadaf Ebrahimi     buff_info.offset = 0;
2329*b7893ccfSSadaf Ebrahimi     buff_info.range = sizeof(vbo_data);
2330*b7893ccfSSadaf Ebrahimi     VkWriteDescriptorSet descriptor_write = {};
2331*b7893ccfSSadaf Ebrahimi     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
2332*b7893ccfSSadaf Ebrahimi     descriptor_write.dstBinding = 2;
2333*b7893ccfSSadaf Ebrahimi     descriptor_write.descriptorCount = 1;
2334*b7893ccfSSadaf Ebrahimi     descriptor_write.pTexelBufferView = nullptr;
2335*b7893ccfSSadaf Ebrahimi     descriptor_write.pBufferInfo = &buff_info;
2336*b7893ccfSSadaf Ebrahimi     descriptor_write.pImageInfo = nullptr;
2337*b7893ccfSSadaf Ebrahimi     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
2338*b7893ccfSSadaf Ebrahimi     descriptor_write.dstSet = 0;  // Should not cause a validation error
2339*b7893ccfSSadaf Ebrahimi 
2340*b7893ccfSSadaf Ebrahimi     // Find address of extension call and make the call
2341*b7893ccfSSadaf Ebrahimi     PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR =
2342*b7893ccfSSadaf Ebrahimi         (PFN_vkCmdPushDescriptorSetKHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdPushDescriptorSetKHR");
2343*b7893ccfSSadaf Ebrahimi     assert(vkCmdPushDescriptorSetKHR != nullptr);
2344*b7893ccfSSadaf Ebrahimi 
2345*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
2346*b7893ccfSSadaf Ebrahimi 
2347*b7893ccfSSadaf Ebrahimi     // In Intel GPU, it needs to bind pipeline before push descriptor set.
2348*b7893ccfSSadaf Ebrahimi     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, helper.pipeline_);
2349*b7893ccfSSadaf Ebrahimi     vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, helper.pipeline_layout_.handle(), 0, 1,
2350*b7893ccfSSadaf Ebrahimi                               &descriptor_write);
2351*b7893ccfSSadaf Ebrahimi 
2352*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
2353*b7893ccfSSadaf Ebrahimi }
2354*b7893ccfSSadaf Ebrahimi 
2355*b7893ccfSSadaf Ebrahimi // This is a positive test. No failures are expected.
TEST_F(VkPositiveLayerTest,PushDescriptorUnboundSetTest)2356*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, PushDescriptorUnboundSetTest) {
2357*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Ensure that no validation errors are produced for not bound push descriptor sets");
2358*b7893ccfSSadaf Ebrahimi     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
2359*b7893ccfSSadaf Ebrahimi         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2360*b7893ccfSSadaf Ebrahimi     } else {
2361*b7893ccfSSadaf Ebrahimi         printf("%s Did not find VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; skipped.\n", kSkipPrefix);
2362*b7893ccfSSadaf Ebrahimi         return;
2363*b7893ccfSSadaf Ebrahimi     }
2364*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
2365*b7893ccfSSadaf Ebrahimi     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
2366*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
2367*b7893ccfSSadaf Ebrahimi     } else {
2368*b7893ccfSSadaf Ebrahimi         printf("%s Push Descriptors Extension not supported, skipping tests\n", kSkipPrefix);
2369*b7893ccfSSadaf Ebrahimi         return;
2370*b7893ccfSSadaf Ebrahimi     }
2371*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
2372*b7893ccfSSadaf Ebrahimi 
2373*b7893ccfSSadaf Ebrahimi     auto push_descriptor_prop = GetPushDescriptorProperties(instance(), gpu());
2374*b7893ccfSSadaf Ebrahimi     if (push_descriptor_prop.maxPushDescriptors < 1) {
2375*b7893ccfSSadaf Ebrahimi         // Some implementations report an invalid maxPushDescriptors of 0
2376*b7893ccfSSadaf Ebrahimi         printf("%s maxPushDescriptors is zero, skipping tests\n", kSkipPrefix);
2377*b7893ccfSSadaf Ebrahimi         return;
2378*b7893ccfSSadaf Ebrahimi     }
2379*b7893ccfSSadaf Ebrahimi 
2380*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitViewport());
2381*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2382*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
2383*b7893ccfSSadaf Ebrahimi 
2384*b7893ccfSSadaf Ebrahimi     // Create descriptor set layout
2385*b7893ccfSSadaf Ebrahimi     VkDescriptorSetLayoutBinding dsl_binding = {};
2386*b7893ccfSSadaf Ebrahimi     dsl_binding.binding = 2;
2387*b7893ccfSSadaf Ebrahimi     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
2388*b7893ccfSSadaf Ebrahimi     dsl_binding.descriptorCount = 1;
2389*b7893ccfSSadaf Ebrahimi     dsl_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
2390*b7893ccfSSadaf Ebrahimi     dsl_binding.pImmutableSamplers = NULL;
2391*b7893ccfSSadaf Ebrahimi 
2392*b7893ccfSSadaf Ebrahimi     OneOffDescriptorSet descriptor_set(m_device, {dsl_binding}, 0, nullptr, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
2393*b7893ccfSSadaf Ebrahimi                                        nullptr);
2394*b7893ccfSSadaf Ebrahimi 
2395*b7893ccfSSadaf Ebrahimi     // Create push descriptor set layout
2396*b7893ccfSSadaf Ebrahimi     const VkDescriptorSetLayoutObj push_ds_layout(m_device, {dsl_binding}, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
2397*b7893ccfSSadaf Ebrahimi 
2398*b7893ccfSSadaf Ebrahimi     // Create PSO
2399*b7893ccfSSadaf Ebrahimi     char const fsSource[] =
2400*b7893ccfSSadaf Ebrahimi         "#version 450\n"
2401*b7893ccfSSadaf Ebrahimi         "\n"
2402*b7893ccfSSadaf Ebrahimi         "layout(location=0) out vec4 x;\n"
2403*b7893ccfSSadaf Ebrahimi         "layout(set=0) layout(binding=2) uniform foo1 { float x; } bar1;\n"
2404*b7893ccfSSadaf Ebrahimi         "layout(set=1) layout(binding=2) uniform foo2 { float y; } bar2;\n"
2405*b7893ccfSSadaf Ebrahimi         "void main(){\n"
2406*b7893ccfSSadaf Ebrahimi         "   x = vec4(bar1.x) + vec4(bar2.y);\n"
2407*b7893ccfSSadaf Ebrahimi         "}\n";
2408*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2409*b7893ccfSSadaf Ebrahimi     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2410*b7893ccfSSadaf Ebrahimi     CreatePipelineHelper pipe(*this);
2411*b7893ccfSSadaf Ebrahimi     pipe.InitInfo();
2412*b7893ccfSSadaf Ebrahimi     pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2413*b7893ccfSSadaf Ebrahimi     pipe.InitState();
2414*b7893ccfSSadaf Ebrahimi     // Now use the descriptor layouts to create a pipeline layout
2415*b7893ccfSSadaf Ebrahimi     pipe.pipeline_layout_ = VkPipelineLayoutObj(m_device, {&push_ds_layout, &descriptor_set.layout_});
2416*b7893ccfSSadaf Ebrahimi     pipe.CreateGraphicsPipeline();
2417*b7893ccfSSadaf Ebrahimi 
2418*b7893ccfSSadaf Ebrahimi     const float bo_data[1] = {1.f};
2419*b7893ccfSSadaf Ebrahimi     VkConstantBufferObj buffer(m_device, sizeof(bo_data), (const void *)&bo_data, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
2420*b7893ccfSSadaf Ebrahimi 
2421*b7893ccfSSadaf Ebrahimi     // Update descriptor set
2422*b7893ccfSSadaf Ebrahimi     descriptor_set.WriteDescriptorBufferInfo(2, buffer.handle(), sizeof(bo_data));
2423*b7893ccfSSadaf Ebrahimi     descriptor_set.UpdateDescriptorSets();
2424*b7893ccfSSadaf Ebrahimi 
2425*b7893ccfSSadaf Ebrahimi     PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR =
2426*b7893ccfSSadaf Ebrahimi         (PFN_vkCmdPushDescriptorSetKHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdPushDescriptorSetKHR");
2427*b7893ccfSSadaf Ebrahimi     assert(vkCmdPushDescriptorSetKHR != nullptr);
2428*b7893ccfSSadaf Ebrahimi 
2429*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
2430*b7893ccfSSadaf Ebrahimi     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2431*b7893ccfSSadaf Ebrahimi     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
2432*b7893ccfSSadaf Ebrahimi 
2433*b7893ccfSSadaf Ebrahimi     // Push descriptors and bind descriptor set
2434*b7893ccfSSadaf Ebrahimi     vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
2435*b7893ccfSSadaf Ebrahimi                               descriptor_set.descriptor_writes.data());
2436*b7893ccfSSadaf Ebrahimi     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 1, 1,
2437*b7893ccfSSadaf Ebrahimi                             &descriptor_set.set_, 0, NULL);
2438*b7893ccfSSadaf Ebrahimi 
2439*b7893ccfSSadaf Ebrahimi     // No errors should be generated.
2440*b7893ccfSSadaf Ebrahimi     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2441*b7893ccfSSadaf Ebrahimi 
2442*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
2443*b7893ccfSSadaf Ebrahimi 
2444*b7893ccfSSadaf Ebrahimi     m_commandBuffer->EndRenderPass();
2445*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
2446*b7893ccfSSadaf Ebrahimi }
2447*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,PushDescriptorSetUpdatingSetNumber)2448*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, PushDescriptorSetUpdatingSetNumber) {
2449*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
2450*b7893ccfSSadaf Ebrahimi         "Ensure that no validation errors are produced when the push descriptor set number changes "
2451*b7893ccfSSadaf Ebrahimi         "between two vkCmdPushDescriptorSetKHR calls.");
2452*b7893ccfSSadaf Ebrahimi 
2453*b7893ccfSSadaf Ebrahimi     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
2454*b7893ccfSSadaf Ebrahimi         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2455*b7893ccfSSadaf Ebrahimi     } else {
2456*b7893ccfSSadaf Ebrahimi         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix,
2457*b7893ccfSSadaf Ebrahimi                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
2458*b7893ccfSSadaf Ebrahimi         return;
2459*b7893ccfSSadaf Ebrahimi     }
2460*b7893ccfSSadaf Ebrahimi 
2461*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
2462*b7893ccfSSadaf Ebrahimi     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
2463*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
2464*b7893ccfSSadaf Ebrahimi     } else {
2465*b7893ccfSSadaf Ebrahimi         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
2466*b7893ccfSSadaf Ebrahimi         return;
2467*b7893ccfSSadaf Ebrahimi     }
2468*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
2469*b7893ccfSSadaf Ebrahimi     auto push_descriptor_prop = GetPushDescriptorProperties(instance(), gpu());
2470*b7893ccfSSadaf Ebrahimi     if (push_descriptor_prop.maxPushDescriptors < 1) {
2471*b7893ccfSSadaf Ebrahimi         // Some implementations report an invalid maxPushDescriptors of 0
2472*b7893ccfSSadaf Ebrahimi         printf("%s maxPushDescriptors is zero, skipping tests\n", kSkipPrefix);
2473*b7893ccfSSadaf Ebrahimi         return;
2474*b7893ccfSSadaf Ebrahimi     }
2475*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitViewport());
2476*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2477*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
2478*b7893ccfSSadaf Ebrahimi 
2479*b7893ccfSSadaf Ebrahimi     // Create a descriptor to push
2480*b7893ccfSSadaf Ebrahimi     const uint32_t buffer_data[4] = {4, 5, 6, 7};
2481*b7893ccfSSadaf Ebrahimi     VkConstantBufferObj buffer_obj(
2482*b7893ccfSSadaf Ebrahimi         m_device, sizeof(buffer_data), &buffer_data,
2483*b7893ccfSSadaf Ebrahimi         VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
2484*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(buffer_obj.initialized());
2485*b7893ccfSSadaf Ebrahimi 
2486*b7893ccfSSadaf Ebrahimi     VkDescriptorBufferInfo buffer_info = {buffer_obj.handle(), 0, VK_WHOLE_SIZE};
2487*b7893ccfSSadaf Ebrahimi 
2488*b7893ccfSSadaf Ebrahimi     PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR =
2489*b7893ccfSSadaf Ebrahimi         (PFN_vkCmdPushDescriptorSetKHR)vkGetDeviceProcAddr(m_device->device(), "vkCmdPushDescriptorSetKHR");
2490*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(vkCmdPushDescriptorSetKHR != nullptr);
2491*b7893ccfSSadaf Ebrahimi 
2492*b7893ccfSSadaf Ebrahimi     const VkDescriptorSetLayoutBinding ds_binding_0 = {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT,
2493*b7893ccfSSadaf Ebrahimi                                                        nullptr};
2494*b7893ccfSSadaf Ebrahimi     const VkDescriptorSetLayoutBinding ds_binding_1 = {1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT,
2495*b7893ccfSSadaf Ebrahimi                                                        nullptr};
2496*b7893ccfSSadaf Ebrahimi     const VkDescriptorSetLayoutObj ds_layout(m_device, {ds_binding_0, ds_binding_1});
2497*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(ds_layout.initialized());
2498*b7893ccfSSadaf Ebrahimi 
2499*b7893ccfSSadaf Ebrahimi     const VkDescriptorSetLayoutBinding push_ds_binding_0 = {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT,
2500*b7893ccfSSadaf Ebrahimi                                                             nullptr};
2501*b7893ccfSSadaf Ebrahimi     const VkDescriptorSetLayoutObj push_ds_layout(m_device, {push_ds_binding_0},
2502*b7893ccfSSadaf Ebrahimi                                                   VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
2503*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(push_ds_layout.initialized());
2504*b7893ccfSSadaf Ebrahimi 
2505*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
2506*b7893ccfSSadaf Ebrahimi     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2507*b7893ccfSSadaf Ebrahimi 
2508*b7893ccfSSadaf Ebrahimi     VkPipelineObj pipe0(m_device);
2509*b7893ccfSSadaf Ebrahimi     VkPipelineObj pipe1(m_device);
2510*b7893ccfSSadaf Ebrahimi     {
2511*b7893ccfSSadaf Ebrahimi         // Note: the push descriptor set is set number 2.
2512*b7893ccfSSadaf Ebrahimi         const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout, &ds_layout, &push_ds_layout, &ds_layout});
2513*b7893ccfSSadaf Ebrahimi         ASSERT_TRUE(pipeline_layout.initialized());
2514*b7893ccfSSadaf Ebrahimi 
2515*b7893ccfSSadaf Ebrahimi         char const *fsSource =
2516*b7893ccfSSadaf Ebrahimi             "#version 450\n"
2517*b7893ccfSSadaf Ebrahimi             "\n"
2518*b7893ccfSSadaf Ebrahimi             "layout(location=0) out vec4 x;\n"
2519*b7893ccfSSadaf Ebrahimi             "layout(set=2) layout(binding=0) uniform foo { vec4 y; } bar;\n"
2520*b7893ccfSSadaf Ebrahimi             "void main(){\n"
2521*b7893ccfSSadaf Ebrahimi             "   x = bar.y;\n"
2522*b7893ccfSSadaf Ebrahimi             "}\n";
2523*b7893ccfSSadaf Ebrahimi 
2524*b7893ccfSSadaf Ebrahimi         VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2525*b7893ccfSSadaf Ebrahimi         VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2526*b7893ccfSSadaf Ebrahimi         VkPipelineObj &pipe = pipe0;
2527*b7893ccfSSadaf Ebrahimi         pipe.SetViewport(m_viewports);
2528*b7893ccfSSadaf Ebrahimi         pipe.SetScissor(m_scissors);
2529*b7893ccfSSadaf Ebrahimi         pipe.AddShader(&vs);
2530*b7893ccfSSadaf Ebrahimi         pipe.AddShader(&fs);
2531*b7893ccfSSadaf Ebrahimi         pipe.AddDefaultColorAttachment();
2532*b7893ccfSSadaf Ebrahimi         pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
2533*b7893ccfSSadaf Ebrahimi 
2534*b7893ccfSSadaf Ebrahimi         vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
2535*b7893ccfSSadaf Ebrahimi 
2536*b7893ccfSSadaf Ebrahimi         const VkWriteDescriptorSet descriptor_write = vk_testing::Device::write_descriptor_set(
2537*b7893ccfSSadaf Ebrahimi             vk_testing::DescriptorSet(), 0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, &buffer_info);
2538*b7893ccfSSadaf Ebrahimi 
2539*b7893ccfSSadaf Ebrahimi         // Note: pushing to desciptor set number 2.
2540*b7893ccfSSadaf Ebrahimi         vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 2, 1,
2541*b7893ccfSSadaf Ebrahimi                                   &descriptor_write);
2542*b7893ccfSSadaf Ebrahimi         vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2543*b7893ccfSSadaf Ebrahimi     }
2544*b7893ccfSSadaf Ebrahimi 
2545*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
2546*b7893ccfSSadaf Ebrahimi 
2547*b7893ccfSSadaf Ebrahimi     {
2548*b7893ccfSSadaf Ebrahimi         // Note: the push descriptor set is now set number 3.
2549*b7893ccfSSadaf Ebrahimi         const VkPipelineLayoutObj pipeline_layout(m_device, {&ds_layout, &ds_layout, &ds_layout, &push_ds_layout});
2550*b7893ccfSSadaf Ebrahimi         ASSERT_TRUE(pipeline_layout.initialized());
2551*b7893ccfSSadaf Ebrahimi 
2552*b7893ccfSSadaf Ebrahimi         const VkWriteDescriptorSet descriptor_write = vk_testing::Device::write_descriptor_set(
2553*b7893ccfSSadaf Ebrahimi             vk_testing::DescriptorSet(), 0, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, &buffer_info);
2554*b7893ccfSSadaf Ebrahimi 
2555*b7893ccfSSadaf Ebrahimi         char const *fsSource =
2556*b7893ccfSSadaf Ebrahimi             "#version 450\n"
2557*b7893ccfSSadaf Ebrahimi             "\n"
2558*b7893ccfSSadaf Ebrahimi             "layout(location=0) out vec4 x;\n"
2559*b7893ccfSSadaf Ebrahimi             "layout(set=3) layout(binding=0) uniform foo { vec4 y; } bar;\n"
2560*b7893ccfSSadaf Ebrahimi             "void main(){\n"
2561*b7893ccfSSadaf Ebrahimi             "   x = bar.y;\n"
2562*b7893ccfSSadaf Ebrahimi             "}\n";
2563*b7893ccfSSadaf Ebrahimi 
2564*b7893ccfSSadaf Ebrahimi         VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2565*b7893ccfSSadaf Ebrahimi         VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2566*b7893ccfSSadaf Ebrahimi         VkPipelineObj &pipe = pipe1;
2567*b7893ccfSSadaf Ebrahimi         pipe.SetViewport(m_viewports);
2568*b7893ccfSSadaf Ebrahimi         pipe.SetScissor(m_scissors);
2569*b7893ccfSSadaf Ebrahimi         pipe.AddShader(&vs);
2570*b7893ccfSSadaf Ebrahimi         pipe.AddShader(&fs);
2571*b7893ccfSSadaf Ebrahimi         pipe.AddDefaultColorAttachment();
2572*b7893ccfSSadaf Ebrahimi         pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
2573*b7893ccfSSadaf Ebrahimi 
2574*b7893ccfSSadaf Ebrahimi         vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
2575*b7893ccfSSadaf Ebrahimi 
2576*b7893ccfSSadaf Ebrahimi         // Note: now pushing to desciptor set number 3.
2577*b7893ccfSSadaf Ebrahimi         vkCmdPushDescriptorSetKHR(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 3, 1,
2578*b7893ccfSSadaf Ebrahimi                                   &descriptor_write);
2579*b7893ccfSSadaf Ebrahimi         vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
2580*b7893ccfSSadaf Ebrahimi     }
2581*b7893ccfSSadaf Ebrahimi 
2582*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
2583*b7893ccfSSadaf Ebrahimi 
2584*b7893ccfSSadaf Ebrahimi     m_commandBuffer->EndRenderPass();
2585*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
2586*b7893ccfSSadaf Ebrahimi }
2587*b7893ccfSSadaf Ebrahimi 
2588*b7893ccfSSadaf Ebrahimi // This is a positive test. No failures are expected.
TEST_F(VkPositiveLayerTest,TestAliasedMemoryTracking)2589*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, TestAliasedMemoryTracking) {
2590*b7893ccfSSadaf Ebrahimi     VkResult err;
2591*b7893ccfSSadaf Ebrahimi     bool pass;
2592*b7893ccfSSadaf Ebrahimi 
2593*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
2594*b7893ccfSSadaf Ebrahimi         "Create a buffer, allocate memory, bind memory, destroy the buffer, create an image, and bind the same memory to it");
2595*b7893ccfSSadaf Ebrahimi 
2596*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
2597*b7893ccfSSadaf Ebrahimi 
2598*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
2599*b7893ccfSSadaf Ebrahimi 
2600*b7893ccfSSadaf Ebrahimi     VkBuffer buffer;
2601*b7893ccfSSadaf Ebrahimi     VkImage image;
2602*b7893ccfSSadaf Ebrahimi     VkDeviceMemory mem;
2603*b7893ccfSSadaf Ebrahimi     VkMemoryRequirements mem_reqs;
2604*b7893ccfSSadaf Ebrahimi 
2605*b7893ccfSSadaf Ebrahimi     VkBufferCreateInfo buf_info = {};
2606*b7893ccfSSadaf Ebrahimi     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
2607*b7893ccfSSadaf Ebrahimi     buf_info.pNext = NULL;
2608*b7893ccfSSadaf Ebrahimi     buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
2609*b7893ccfSSadaf Ebrahimi     buf_info.size = 256;
2610*b7893ccfSSadaf Ebrahimi     buf_info.queueFamilyIndexCount = 0;
2611*b7893ccfSSadaf Ebrahimi     buf_info.pQueueFamilyIndices = NULL;
2612*b7893ccfSSadaf Ebrahimi     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2613*b7893ccfSSadaf Ebrahimi     buf_info.flags = 0;
2614*b7893ccfSSadaf Ebrahimi     err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
2615*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
2616*b7893ccfSSadaf Ebrahimi 
2617*b7893ccfSSadaf Ebrahimi     vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
2618*b7893ccfSSadaf Ebrahimi 
2619*b7893ccfSSadaf Ebrahimi     VkMemoryAllocateInfo alloc_info = {};
2620*b7893ccfSSadaf Ebrahimi     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
2621*b7893ccfSSadaf Ebrahimi     alloc_info.pNext = NULL;
2622*b7893ccfSSadaf Ebrahimi     alloc_info.memoryTypeIndex = 0;
2623*b7893ccfSSadaf Ebrahimi 
2624*b7893ccfSSadaf Ebrahimi     // Ensure memory is big enough for both bindings
2625*b7893ccfSSadaf Ebrahimi     alloc_info.allocationSize = 0x10000;
2626*b7893ccfSSadaf Ebrahimi 
2627*b7893ccfSSadaf Ebrahimi     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
2628*b7893ccfSSadaf Ebrahimi     if (!pass) {
2629*b7893ccfSSadaf Ebrahimi         printf("%s Failed to allocate memory.\n", kSkipPrefix);
2630*b7893ccfSSadaf Ebrahimi         vkDestroyBuffer(m_device->device(), buffer, NULL);
2631*b7893ccfSSadaf Ebrahimi         return;
2632*b7893ccfSSadaf Ebrahimi     }
2633*b7893ccfSSadaf Ebrahimi 
2634*b7893ccfSSadaf Ebrahimi     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
2635*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
2636*b7893ccfSSadaf Ebrahimi 
2637*b7893ccfSSadaf Ebrahimi     uint8_t *pData;
2638*b7893ccfSSadaf Ebrahimi     err = vkMapMemory(m_device->device(), mem, 0, mem_reqs.size, 0, (void **)&pData);
2639*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
2640*b7893ccfSSadaf Ebrahimi 
2641*b7893ccfSSadaf Ebrahimi     memset(pData, 0xCADECADE, static_cast<size_t>(mem_reqs.size));
2642*b7893ccfSSadaf Ebrahimi 
2643*b7893ccfSSadaf Ebrahimi     vkUnmapMemory(m_device->device(), mem);
2644*b7893ccfSSadaf Ebrahimi 
2645*b7893ccfSSadaf Ebrahimi     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
2646*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
2647*b7893ccfSSadaf Ebrahimi 
2648*b7893ccfSSadaf Ebrahimi     // NOW, destroy the buffer. Obviously, the resource no longer occupies this
2649*b7893ccfSSadaf Ebrahimi     // memory. In fact, it was never used by the GPU.
2650*b7893ccfSSadaf Ebrahimi     // Just be sure, wait for idle.
2651*b7893ccfSSadaf Ebrahimi     vkDestroyBuffer(m_device->device(), buffer, NULL);
2652*b7893ccfSSadaf Ebrahimi     vkDeviceWaitIdle(m_device->device());
2653*b7893ccfSSadaf Ebrahimi 
2654*b7893ccfSSadaf Ebrahimi     // Use optimal as some platforms report linear support but then fail image creation
2655*b7893ccfSSadaf Ebrahimi     VkImageTiling image_tiling = VK_IMAGE_TILING_OPTIMAL;
2656*b7893ccfSSadaf Ebrahimi     VkImageFormatProperties image_format_properties;
2657*b7893ccfSSadaf Ebrahimi     vkGetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TYPE_2D, image_tiling,
2658*b7893ccfSSadaf Ebrahimi                                              VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0, &image_format_properties);
2659*b7893ccfSSadaf Ebrahimi     if (image_format_properties.maxExtent.width == 0) {
2660*b7893ccfSSadaf Ebrahimi         printf("%s Image format not supported; skipped.\n", kSkipPrefix);
2661*b7893ccfSSadaf Ebrahimi         vkFreeMemory(m_device->device(), mem, NULL);
2662*b7893ccfSSadaf Ebrahimi         return;
2663*b7893ccfSSadaf Ebrahimi     }
2664*b7893ccfSSadaf Ebrahimi     VkImageCreateInfo image_create_info = {};
2665*b7893ccfSSadaf Ebrahimi     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
2666*b7893ccfSSadaf Ebrahimi     image_create_info.pNext = NULL;
2667*b7893ccfSSadaf Ebrahimi     image_create_info.imageType = VK_IMAGE_TYPE_2D;
2668*b7893ccfSSadaf Ebrahimi     image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
2669*b7893ccfSSadaf Ebrahimi     image_create_info.extent.width = 64;
2670*b7893ccfSSadaf Ebrahimi     image_create_info.extent.height = 64;
2671*b7893ccfSSadaf Ebrahimi     image_create_info.extent.depth = 1;
2672*b7893ccfSSadaf Ebrahimi     image_create_info.mipLevels = 1;
2673*b7893ccfSSadaf Ebrahimi     image_create_info.arrayLayers = 1;
2674*b7893ccfSSadaf Ebrahimi     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
2675*b7893ccfSSadaf Ebrahimi     image_create_info.tiling = image_tiling;
2676*b7893ccfSSadaf Ebrahimi     image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
2677*b7893ccfSSadaf Ebrahimi     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2678*b7893ccfSSadaf Ebrahimi     image_create_info.queueFamilyIndexCount = 0;
2679*b7893ccfSSadaf Ebrahimi     image_create_info.pQueueFamilyIndices = NULL;
2680*b7893ccfSSadaf Ebrahimi     image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
2681*b7893ccfSSadaf Ebrahimi     image_create_info.flags = 0;
2682*b7893ccfSSadaf Ebrahimi 
2683*b7893ccfSSadaf Ebrahimi     /* Create a mappable image.  It will be the texture if linear images are OK
2684*b7893ccfSSadaf Ebrahimi      * to be textures or it will be the staging image if they are not.
2685*b7893ccfSSadaf Ebrahimi      */
2686*b7893ccfSSadaf Ebrahimi     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
2687*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
2688*b7893ccfSSadaf Ebrahimi 
2689*b7893ccfSSadaf Ebrahimi     vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
2690*b7893ccfSSadaf Ebrahimi 
2691*b7893ccfSSadaf Ebrahimi     VkMemoryAllocateInfo mem_alloc = {};
2692*b7893ccfSSadaf Ebrahimi     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
2693*b7893ccfSSadaf Ebrahimi     mem_alloc.pNext = NULL;
2694*b7893ccfSSadaf Ebrahimi     mem_alloc.allocationSize = 0;
2695*b7893ccfSSadaf Ebrahimi     mem_alloc.memoryTypeIndex = 0;
2696*b7893ccfSSadaf Ebrahimi     mem_alloc.allocationSize = mem_reqs.size;
2697*b7893ccfSSadaf Ebrahimi 
2698*b7893ccfSSadaf Ebrahimi     pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
2699*b7893ccfSSadaf Ebrahimi     if (!pass) {
2700*b7893ccfSSadaf Ebrahimi         printf("%s Failed to allocate memory.\n", kSkipPrefix);
2701*b7893ccfSSadaf Ebrahimi         vkFreeMemory(m_device->device(), mem, NULL);
2702*b7893ccfSSadaf Ebrahimi         vkDestroyImage(m_device->device(), image, NULL);
2703*b7893ccfSSadaf Ebrahimi         return;
2704*b7893ccfSSadaf Ebrahimi     }
2705*b7893ccfSSadaf Ebrahimi 
2706*b7893ccfSSadaf Ebrahimi     // VALIDATION FAILURE:
2707*b7893ccfSSadaf Ebrahimi     err = vkBindImageMemory(m_device->device(), image, mem, 0);
2708*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
2709*b7893ccfSSadaf Ebrahimi 
2710*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
2711*b7893ccfSSadaf Ebrahimi 
2712*b7893ccfSSadaf Ebrahimi     vkFreeMemory(m_device->device(), mem, NULL);
2713*b7893ccfSSadaf Ebrahimi     vkDestroyImage(m_device->device(), image, NULL);
2714*b7893ccfSSadaf Ebrahimi }
2715*b7893ccfSSadaf Ebrahimi 
2716*b7893ccfSSadaf Ebrahimi // This is a positive test. No failures are expected.
TEST_F(VkPositiveLayerTest,TestDestroyFreeNullHandles)2717*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, TestDestroyFreeNullHandles) {
2718*b7893ccfSSadaf Ebrahimi     VkResult err;
2719*b7893ccfSSadaf Ebrahimi 
2720*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Call all applicable destroy and free routines with NULL handles, expecting no validation errors");
2721*b7893ccfSSadaf Ebrahimi 
2722*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
2723*b7893ccfSSadaf Ebrahimi 
2724*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
2725*b7893ccfSSadaf Ebrahimi     vkDestroyBuffer(m_device->device(), VK_NULL_HANDLE, NULL);
2726*b7893ccfSSadaf Ebrahimi     vkDestroyBufferView(m_device->device(), VK_NULL_HANDLE, NULL);
2727*b7893ccfSSadaf Ebrahimi     vkDestroyCommandPool(m_device->device(), VK_NULL_HANDLE, NULL);
2728*b7893ccfSSadaf Ebrahimi     vkDestroyDescriptorPool(m_device->device(), VK_NULL_HANDLE, NULL);
2729*b7893ccfSSadaf Ebrahimi     vkDestroyDescriptorSetLayout(m_device->device(), VK_NULL_HANDLE, NULL);
2730*b7893ccfSSadaf Ebrahimi     vkDestroyDevice(VK_NULL_HANDLE, NULL);
2731*b7893ccfSSadaf Ebrahimi     vkDestroyEvent(m_device->device(), VK_NULL_HANDLE, NULL);
2732*b7893ccfSSadaf Ebrahimi     vkDestroyFence(m_device->device(), VK_NULL_HANDLE, NULL);
2733*b7893ccfSSadaf Ebrahimi     vkDestroyFramebuffer(m_device->device(), VK_NULL_HANDLE, NULL);
2734*b7893ccfSSadaf Ebrahimi     vkDestroyImage(m_device->device(), VK_NULL_HANDLE, NULL);
2735*b7893ccfSSadaf Ebrahimi     vkDestroyImageView(m_device->device(), VK_NULL_HANDLE, NULL);
2736*b7893ccfSSadaf Ebrahimi     vkDestroyInstance(VK_NULL_HANDLE, NULL);
2737*b7893ccfSSadaf Ebrahimi     vkDestroyPipeline(m_device->device(), VK_NULL_HANDLE, NULL);
2738*b7893ccfSSadaf Ebrahimi     vkDestroyPipelineCache(m_device->device(), VK_NULL_HANDLE, NULL);
2739*b7893ccfSSadaf Ebrahimi     vkDestroyPipelineLayout(m_device->device(), VK_NULL_HANDLE, NULL);
2740*b7893ccfSSadaf Ebrahimi     vkDestroyQueryPool(m_device->device(), VK_NULL_HANDLE, NULL);
2741*b7893ccfSSadaf Ebrahimi     vkDestroyRenderPass(m_device->device(), VK_NULL_HANDLE, NULL);
2742*b7893ccfSSadaf Ebrahimi     vkDestroySampler(m_device->device(), VK_NULL_HANDLE, NULL);
2743*b7893ccfSSadaf Ebrahimi     vkDestroySemaphore(m_device->device(), VK_NULL_HANDLE, NULL);
2744*b7893ccfSSadaf Ebrahimi     vkDestroyShaderModule(m_device->device(), VK_NULL_HANDLE, NULL);
2745*b7893ccfSSadaf Ebrahimi 
2746*b7893ccfSSadaf Ebrahimi     VkCommandPool command_pool;
2747*b7893ccfSSadaf Ebrahimi     VkCommandPoolCreateInfo pool_create_info{};
2748*b7893ccfSSadaf Ebrahimi     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
2749*b7893ccfSSadaf Ebrahimi     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
2750*b7893ccfSSadaf Ebrahimi     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
2751*b7893ccfSSadaf Ebrahimi     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
2752*b7893ccfSSadaf Ebrahimi     VkCommandBuffer command_buffers[3] = {};
2753*b7893ccfSSadaf Ebrahimi     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
2754*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
2755*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandPool = command_pool;
2756*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandBufferCount = 1;
2757*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
2758*b7893ccfSSadaf Ebrahimi     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffers[1]);
2759*b7893ccfSSadaf Ebrahimi     vkFreeCommandBuffers(m_device->device(), command_pool, 3, command_buffers);
2760*b7893ccfSSadaf Ebrahimi     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
2761*b7893ccfSSadaf Ebrahimi 
2762*b7893ccfSSadaf Ebrahimi     VkDescriptorPoolSize ds_type_count = {};
2763*b7893ccfSSadaf Ebrahimi     ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
2764*b7893ccfSSadaf Ebrahimi     ds_type_count.descriptorCount = 1;
2765*b7893ccfSSadaf Ebrahimi 
2766*b7893ccfSSadaf Ebrahimi     VkDescriptorPoolCreateInfo ds_pool_ci = {};
2767*b7893ccfSSadaf Ebrahimi     ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
2768*b7893ccfSSadaf Ebrahimi     ds_pool_ci.pNext = NULL;
2769*b7893ccfSSadaf Ebrahimi     ds_pool_ci.maxSets = 1;
2770*b7893ccfSSadaf Ebrahimi     ds_pool_ci.poolSizeCount = 1;
2771*b7893ccfSSadaf Ebrahimi     ds_pool_ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
2772*b7893ccfSSadaf Ebrahimi     ds_pool_ci.pPoolSizes = &ds_type_count;
2773*b7893ccfSSadaf Ebrahimi 
2774*b7893ccfSSadaf Ebrahimi     VkDescriptorPool ds_pool;
2775*b7893ccfSSadaf Ebrahimi     err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
2776*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
2777*b7893ccfSSadaf Ebrahimi 
2778*b7893ccfSSadaf Ebrahimi     VkDescriptorSetLayoutBinding dsl_binding = {};
2779*b7893ccfSSadaf Ebrahimi     dsl_binding.binding = 2;
2780*b7893ccfSSadaf Ebrahimi     dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
2781*b7893ccfSSadaf Ebrahimi     dsl_binding.descriptorCount = 1;
2782*b7893ccfSSadaf Ebrahimi     dsl_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
2783*b7893ccfSSadaf Ebrahimi     dsl_binding.pImmutableSamplers = NULL;
2784*b7893ccfSSadaf Ebrahimi 
2785*b7893ccfSSadaf Ebrahimi     const VkDescriptorSetLayoutObj ds_layout(m_device, {dsl_binding});
2786*b7893ccfSSadaf Ebrahimi 
2787*b7893ccfSSadaf Ebrahimi     VkDescriptorSet descriptor_sets[3] = {};
2788*b7893ccfSSadaf Ebrahimi     VkDescriptorSetAllocateInfo alloc_info = {};
2789*b7893ccfSSadaf Ebrahimi     alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
2790*b7893ccfSSadaf Ebrahimi     alloc_info.descriptorSetCount = 1;
2791*b7893ccfSSadaf Ebrahimi     alloc_info.descriptorPool = ds_pool;
2792*b7893ccfSSadaf Ebrahimi     alloc_info.pSetLayouts = &ds_layout.handle();
2793*b7893ccfSSadaf Ebrahimi     err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_sets[1]);
2794*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
2795*b7893ccfSSadaf Ebrahimi     vkFreeDescriptorSets(m_device->device(), ds_pool, 3, descriptor_sets);
2796*b7893ccfSSadaf Ebrahimi     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
2797*b7893ccfSSadaf Ebrahimi 
2798*b7893ccfSSadaf Ebrahimi     vkFreeMemory(m_device->device(), VK_NULL_HANDLE, NULL);
2799*b7893ccfSSadaf Ebrahimi 
2800*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
2801*b7893ccfSSadaf Ebrahimi }
2802*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,QueueSubmitSemaphoresAndLayoutTracking)2803*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, QueueSubmitSemaphoresAndLayoutTracking) {
2804*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Submit multiple command buffers with chained semaphore signals and layout transitions");
2805*b7893ccfSSadaf Ebrahimi 
2806*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
2807*b7893ccfSSadaf Ebrahimi 
2808*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
2809*b7893ccfSSadaf Ebrahimi     VkCommandBuffer cmd_bufs[4];
2810*b7893ccfSSadaf Ebrahimi     VkCommandBufferAllocateInfo alloc_info;
2811*b7893ccfSSadaf Ebrahimi     alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
2812*b7893ccfSSadaf Ebrahimi     alloc_info.pNext = NULL;
2813*b7893ccfSSadaf Ebrahimi     alloc_info.commandBufferCount = 4;
2814*b7893ccfSSadaf Ebrahimi     alloc_info.commandPool = m_commandPool->handle();
2815*b7893ccfSSadaf Ebrahimi     alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
2816*b7893ccfSSadaf Ebrahimi     vkAllocateCommandBuffers(m_device->device(), &alloc_info, cmd_bufs);
2817*b7893ccfSSadaf Ebrahimi     VkImageObj image(m_device);
2818*b7893ccfSSadaf Ebrahimi     image.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM,
2819*b7893ccfSSadaf Ebrahimi                (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT),
2820*b7893ccfSSadaf Ebrahimi                VK_IMAGE_TILING_OPTIMAL, 0);
2821*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(image.initialized());
2822*b7893ccfSSadaf Ebrahimi     VkCommandBufferBeginInfo cb_binfo;
2823*b7893ccfSSadaf Ebrahimi     cb_binfo.pNext = NULL;
2824*b7893ccfSSadaf Ebrahimi     cb_binfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
2825*b7893ccfSSadaf Ebrahimi     cb_binfo.pInheritanceInfo = VK_NULL_HANDLE;
2826*b7893ccfSSadaf Ebrahimi     cb_binfo.flags = 0;
2827*b7893ccfSSadaf Ebrahimi     // Use 4 command buffers, each with an image layout transition, ColorAO->General->ColorAO->TransferSrc->TransferDst
2828*b7893ccfSSadaf Ebrahimi     vkBeginCommandBuffer(cmd_bufs[0], &cb_binfo);
2829*b7893ccfSSadaf Ebrahimi     VkImageMemoryBarrier img_barrier = {};
2830*b7893ccfSSadaf Ebrahimi     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
2831*b7893ccfSSadaf Ebrahimi     img_barrier.pNext = NULL;
2832*b7893ccfSSadaf Ebrahimi     img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
2833*b7893ccfSSadaf Ebrahimi     img_barrier.dstAccessMask = VK_ACCESS_HOST_WRITE_BIT;
2834*b7893ccfSSadaf Ebrahimi     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2835*b7893ccfSSadaf Ebrahimi     img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
2836*b7893ccfSSadaf Ebrahimi     img_barrier.image = image.handle();
2837*b7893ccfSSadaf Ebrahimi     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
2838*b7893ccfSSadaf Ebrahimi     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
2839*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
2840*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.baseArrayLayer = 0;
2841*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.baseMipLevel = 0;
2842*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.layerCount = 1;
2843*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.levelCount = 1;
2844*b7893ccfSSadaf Ebrahimi     vkCmdPipelineBarrier(cmd_bufs[0], VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0, nullptr, 0, nullptr, 1,
2845*b7893ccfSSadaf Ebrahimi                          &img_barrier);
2846*b7893ccfSSadaf Ebrahimi     vkEndCommandBuffer(cmd_bufs[0]);
2847*b7893ccfSSadaf Ebrahimi     vkBeginCommandBuffer(cmd_bufs[1], &cb_binfo);
2848*b7893ccfSSadaf Ebrahimi     img_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
2849*b7893ccfSSadaf Ebrahimi     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2850*b7893ccfSSadaf Ebrahimi     vkCmdPipelineBarrier(cmd_bufs[1], VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0, nullptr, 0, nullptr, 1,
2851*b7893ccfSSadaf Ebrahimi                          &img_barrier);
2852*b7893ccfSSadaf Ebrahimi     vkEndCommandBuffer(cmd_bufs[1]);
2853*b7893ccfSSadaf Ebrahimi     vkBeginCommandBuffer(cmd_bufs[2], &cb_binfo);
2854*b7893ccfSSadaf Ebrahimi     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
2855*b7893ccfSSadaf Ebrahimi     img_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
2856*b7893ccfSSadaf Ebrahimi     vkCmdPipelineBarrier(cmd_bufs[2], VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0, nullptr, 0, nullptr, 1,
2857*b7893ccfSSadaf Ebrahimi                          &img_barrier);
2858*b7893ccfSSadaf Ebrahimi     vkEndCommandBuffer(cmd_bufs[2]);
2859*b7893ccfSSadaf Ebrahimi     vkBeginCommandBuffer(cmd_bufs[3], &cb_binfo);
2860*b7893ccfSSadaf Ebrahimi     img_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
2861*b7893ccfSSadaf Ebrahimi     img_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
2862*b7893ccfSSadaf Ebrahimi     vkCmdPipelineBarrier(cmd_bufs[3], VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 0, nullptr, 0, nullptr, 1,
2863*b7893ccfSSadaf Ebrahimi                          &img_barrier);
2864*b7893ccfSSadaf Ebrahimi     vkEndCommandBuffer(cmd_bufs[3]);
2865*b7893ccfSSadaf Ebrahimi 
2866*b7893ccfSSadaf Ebrahimi     // Submit 4 command buffers in 3 submits, with submits 2 and 3 waiting for semaphores from submits 1 and 2
2867*b7893ccfSSadaf Ebrahimi     VkSemaphore semaphore1, semaphore2;
2868*b7893ccfSSadaf Ebrahimi     VkSemaphoreCreateInfo semaphore_create_info{};
2869*b7893ccfSSadaf Ebrahimi     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
2870*b7893ccfSSadaf Ebrahimi     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore1);
2871*b7893ccfSSadaf Ebrahimi     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore2);
2872*b7893ccfSSadaf Ebrahimi     VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
2873*b7893ccfSSadaf Ebrahimi     VkSubmitInfo submit_info[3];
2874*b7893ccfSSadaf Ebrahimi     submit_info[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2875*b7893ccfSSadaf Ebrahimi     submit_info[0].pNext = nullptr;
2876*b7893ccfSSadaf Ebrahimi     submit_info[0].commandBufferCount = 1;
2877*b7893ccfSSadaf Ebrahimi     submit_info[0].pCommandBuffers = &cmd_bufs[0];
2878*b7893ccfSSadaf Ebrahimi     submit_info[0].signalSemaphoreCount = 1;
2879*b7893ccfSSadaf Ebrahimi     submit_info[0].pSignalSemaphores = &semaphore1;
2880*b7893ccfSSadaf Ebrahimi     submit_info[0].waitSemaphoreCount = 0;
2881*b7893ccfSSadaf Ebrahimi     submit_info[0].pWaitDstStageMask = nullptr;
2882*b7893ccfSSadaf Ebrahimi     submit_info[0].pWaitDstStageMask = flags;
2883*b7893ccfSSadaf Ebrahimi     submit_info[1].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2884*b7893ccfSSadaf Ebrahimi     submit_info[1].pNext = nullptr;
2885*b7893ccfSSadaf Ebrahimi     submit_info[1].commandBufferCount = 1;
2886*b7893ccfSSadaf Ebrahimi     submit_info[1].pCommandBuffers = &cmd_bufs[1];
2887*b7893ccfSSadaf Ebrahimi     submit_info[1].waitSemaphoreCount = 1;
2888*b7893ccfSSadaf Ebrahimi     submit_info[1].pWaitSemaphores = &semaphore1;
2889*b7893ccfSSadaf Ebrahimi     submit_info[1].signalSemaphoreCount = 1;
2890*b7893ccfSSadaf Ebrahimi     submit_info[1].pSignalSemaphores = &semaphore2;
2891*b7893ccfSSadaf Ebrahimi     submit_info[1].pWaitDstStageMask = flags;
2892*b7893ccfSSadaf Ebrahimi     submit_info[2].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
2893*b7893ccfSSadaf Ebrahimi     submit_info[2].pNext = nullptr;
2894*b7893ccfSSadaf Ebrahimi     submit_info[2].commandBufferCount = 2;
2895*b7893ccfSSadaf Ebrahimi     submit_info[2].pCommandBuffers = &cmd_bufs[2];
2896*b7893ccfSSadaf Ebrahimi     submit_info[2].waitSemaphoreCount = 1;
2897*b7893ccfSSadaf Ebrahimi     submit_info[2].pWaitSemaphores = &semaphore2;
2898*b7893ccfSSadaf Ebrahimi     submit_info[2].signalSemaphoreCount = 0;
2899*b7893ccfSSadaf Ebrahimi     submit_info[2].pSignalSemaphores = nullptr;
2900*b7893ccfSSadaf Ebrahimi     submit_info[2].pWaitDstStageMask = flags;
2901*b7893ccfSSadaf Ebrahimi     vkQueueSubmit(m_device->m_queue, 3, submit_info, VK_NULL_HANDLE);
2902*b7893ccfSSadaf Ebrahimi     vkQueueWaitIdle(m_device->m_queue);
2903*b7893ccfSSadaf Ebrahimi 
2904*b7893ccfSSadaf Ebrahimi     vkDestroySemaphore(m_device->device(), semaphore1, NULL);
2905*b7893ccfSSadaf Ebrahimi     vkDestroySemaphore(m_device->device(), semaphore2, NULL);
2906*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
2907*b7893ccfSSadaf Ebrahimi }
2908*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,DynamicOffsetWithInactiveBinding)2909*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, DynamicOffsetWithInactiveBinding) {
2910*b7893ccfSSadaf Ebrahimi     // Create a descriptorSet w/ dynamic descriptors where 1 binding is inactive
2911*b7893ccfSSadaf Ebrahimi     // We previously had a bug where dynamic offset of inactive bindings was still being used
2912*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
2913*b7893ccfSSadaf Ebrahimi 
2914*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
2915*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitViewport());
2916*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
2917*b7893ccfSSadaf Ebrahimi 
2918*b7893ccfSSadaf Ebrahimi     OneOffDescriptorSet descriptor_set(m_device,
2919*b7893ccfSSadaf Ebrahimi                                        {
2920*b7893ccfSSadaf Ebrahimi                                            {2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
2921*b7893ccfSSadaf Ebrahimi                                            {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
2922*b7893ccfSSadaf Ebrahimi                                            {1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
2923*b7893ccfSSadaf Ebrahimi                                        });
2924*b7893ccfSSadaf Ebrahimi 
2925*b7893ccfSSadaf Ebrahimi     // Create two buffers to update the descriptors with
2926*b7893ccfSSadaf Ebrahimi     // The first will be 2k and used for bindings 0 & 1, the second is 1k for binding 2
2927*b7893ccfSSadaf Ebrahimi     uint32_t qfi = 0;
2928*b7893ccfSSadaf Ebrahimi     VkBufferCreateInfo buffCI = {};
2929*b7893ccfSSadaf Ebrahimi     buffCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
2930*b7893ccfSSadaf Ebrahimi     buffCI.size = 2048;
2931*b7893ccfSSadaf Ebrahimi     buffCI.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
2932*b7893ccfSSadaf Ebrahimi     buffCI.queueFamilyIndexCount = 1;
2933*b7893ccfSSadaf Ebrahimi     buffCI.pQueueFamilyIndices = &qfi;
2934*b7893ccfSSadaf Ebrahimi 
2935*b7893ccfSSadaf Ebrahimi     VkBufferObj dynamic_uniform_buffer_1, dynamic_uniform_buffer_2;
2936*b7893ccfSSadaf Ebrahimi     dynamic_uniform_buffer_1.init(*m_device, buffCI);
2937*b7893ccfSSadaf Ebrahimi     buffCI.size = 1024;
2938*b7893ccfSSadaf Ebrahimi     dynamic_uniform_buffer_2.init(*m_device, buffCI);
2939*b7893ccfSSadaf Ebrahimi 
2940*b7893ccfSSadaf Ebrahimi     // Update descriptors
2941*b7893ccfSSadaf Ebrahimi     const uint32_t BINDING_COUNT = 3;
2942*b7893ccfSSadaf Ebrahimi     VkDescriptorBufferInfo buff_info[BINDING_COUNT] = {};
2943*b7893ccfSSadaf Ebrahimi     buff_info[0].buffer = dynamic_uniform_buffer_1.handle();
2944*b7893ccfSSadaf Ebrahimi     buff_info[0].offset = 0;
2945*b7893ccfSSadaf Ebrahimi     buff_info[0].range = 256;
2946*b7893ccfSSadaf Ebrahimi     buff_info[1].buffer = dynamic_uniform_buffer_1.handle();
2947*b7893ccfSSadaf Ebrahimi     buff_info[1].offset = 256;
2948*b7893ccfSSadaf Ebrahimi     buff_info[1].range = 512;
2949*b7893ccfSSadaf Ebrahimi     buff_info[2].buffer = dynamic_uniform_buffer_2.handle();
2950*b7893ccfSSadaf Ebrahimi     buff_info[2].offset = 0;
2951*b7893ccfSSadaf Ebrahimi     buff_info[2].range = 512;
2952*b7893ccfSSadaf Ebrahimi 
2953*b7893ccfSSadaf Ebrahimi     VkWriteDescriptorSet descriptor_write;
2954*b7893ccfSSadaf Ebrahimi     memset(&descriptor_write, 0, sizeof(descriptor_write));
2955*b7893ccfSSadaf Ebrahimi     descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
2956*b7893ccfSSadaf Ebrahimi     descriptor_write.dstSet = descriptor_set.set_;
2957*b7893ccfSSadaf Ebrahimi     descriptor_write.dstBinding = 0;
2958*b7893ccfSSadaf Ebrahimi     descriptor_write.descriptorCount = BINDING_COUNT;
2959*b7893ccfSSadaf Ebrahimi     descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
2960*b7893ccfSSadaf Ebrahimi     descriptor_write.pBufferInfo = buff_info;
2961*b7893ccfSSadaf Ebrahimi 
2962*b7893ccfSSadaf Ebrahimi     vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
2963*b7893ccfSSadaf Ebrahimi 
2964*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
2965*b7893ccfSSadaf Ebrahimi     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
2966*b7893ccfSSadaf Ebrahimi 
2967*b7893ccfSSadaf Ebrahimi     // Create PSO to be used for draw-time errors below
2968*b7893ccfSSadaf Ebrahimi     char const *fsSource =
2969*b7893ccfSSadaf Ebrahimi         "#version 450\n"
2970*b7893ccfSSadaf Ebrahimi         "\n"
2971*b7893ccfSSadaf Ebrahimi         "layout(location=0) out vec4 x;\n"
2972*b7893ccfSSadaf Ebrahimi         "layout(set=0) layout(binding=0) uniform foo1 { int x; int y; } bar1;\n"
2973*b7893ccfSSadaf Ebrahimi         "layout(set=0) layout(binding=2) uniform foo2 { int x; int y; } bar2;\n"
2974*b7893ccfSSadaf Ebrahimi         "void main(){\n"
2975*b7893ccfSSadaf Ebrahimi         "   x = vec4(bar1.y) + vec4(bar2.y);\n"
2976*b7893ccfSSadaf Ebrahimi         "}\n";
2977*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
2978*b7893ccfSSadaf Ebrahimi     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
2979*b7893ccfSSadaf Ebrahimi 
2980*b7893ccfSSadaf Ebrahimi     CreatePipelineHelper pipe(*this);
2981*b7893ccfSSadaf Ebrahimi     pipe.InitInfo();
2982*b7893ccfSSadaf Ebrahimi     pipe.InitState();
2983*b7893ccfSSadaf Ebrahimi     pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
2984*b7893ccfSSadaf Ebrahimi     pipe.pipeline_layout_ = VkPipelineLayoutObj(m_device, {&descriptor_set.layout_});
2985*b7893ccfSSadaf Ebrahimi     pipe.CreateGraphicsPipeline();
2986*b7893ccfSSadaf Ebrahimi 
2987*b7893ccfSSadaf Ebrahimi     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
2988*b7893ccfSSadaf Ebrahimi     // This update should succeed, but offset of inactive binding 1 oversteps binding 2 buffer size
2989*b7893ccfSSadaf Ebrahimi     //   we used to have a bug in this case.
2990*b7893ccfSSadaf Ebrahimi     uint32_t dyn_off[BINDING_COUNT] = {0, 1024, 256};
2991*b7893ccfSSadaf Ebrahimi     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
2992*b7893ccfSSadaf Ebrahimi                             &descriptor_set.set_, BINDING_COUNT, dyn_off);
2993*b7893ccfSSadaf Ebrahimi     m_commandBuffer->Draw(1, 0, 0, 0);
2994*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
2995*b7893ccfSSadaf Ebrahimi 
2996*b7893ccfSSadaf Ebrahimi     m_commandBuffer->EndRenderPass();
2997*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
2998*b7893ccfSSadaf Ebrahimi }
2999*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,NonCoherentMemoryMapping)3000*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, NonCoherentMemoryMapping) {
3001*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
3002*b7893ccfSSadaf Ebrahimi         "Ensure that validations handling of non-coherent memory mapping while using VK_WHOLE_SIZE does not cause access "
3003*b7893ccfSSadaf Ebrahimi         "violations");
3004*b7893ccfSSadaf Ebrahimi     VkResult err;
3005*b7893ccfSSadaf Ebrahimi     uint8_t *pData;
3006*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
3007*b7893ccfSSadaf Ebrahimi 
3008*b7893ccfSSadaf Ebrahimi     VkDeviceMemory mem;
3009*b7893ccfSSadaf Ebrahimi     VkMemoryRequirements mem_reqs;
3010*b7893ccfSSadaf Ebrahimi     mem_reqs.memoryTypeBits = 0xFFFFFFFF;
3011*b7893ccfSSadaf Ebrahimi     const VkDeviceSize atom_size = m_device->props.limits.nonCoherentAtomSize;
3012*b7893ccfSSadaf Ebrahimi     VkMemoryAllocateInfo alloc_info = {};
3013*b7893ccfSSadaf Ebrahimi     alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3014*b7893ccfSSadaf Ebrahimi     alloc_info.pNext = NULL;
3015*b7893ccfSSadaf Ebrahimi     alloc_info.memoryTypeIndex = 0;
3016*b7893ccfSSadaf Ebrahimi 
3017*b7893ccfSSadaf Ebrahimi     static const VkDeviceSize allocation_size = 32 * atom_size;
3018*b7893ccfSSadaf Ebrahimi     alloc_info.allocationSize = allocation_size;
3019*b7893ccfSSadaf Ebrahimi 
3020*b7893ccfSSadaf Ebrahimi     // Find a memory configurations WITHOUT a COHERENT bit, otherwise exit
3021*b7893ccfSSadaf Ebrahimi     bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
3022*b7893ccfSSadaf Ebrahimi                                                 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
3023*b7893ccfSSadaf Ebrahimi     if (!pass) {
3024*b7893ccfSSadaf Ebrahimi         pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info,
3025*b7893ccfSSadaf Ebrahimi                                                VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
3026*b7893ccfSSadaf Ebrahimi                                                VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
3027*b7893ccfSSadaf Ebrahimi         if (!pass) {
3028*b7893ccfSSadaf Ebrahimi             pass = m_device->phy().set_memory_type(
3029*b7893ccfSSadaf Ebrahimi                 mem_reqs.memoryTypeBits, &alloc_info,
3030*b7893ccfSSadaf Ebrahimi                 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
3031*b7893ccfSSadaf Ebrahimi                 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
3032*b7893ccfSSadaf Ebrahimi             if (!pass) {
3033*b7893ccfSSadaf Ebrahimi                 printf("%s Couldn't find a memory type wihtout a COHERENT bit.\n", kSkipPrefix);
3034*b7893ccfSSadaf Ebrahimi                 return;
3035*b7893ccfSSadaf Ebrahimi             }
3036*b7893ccfSSadaf Ebrahimi         }
3037*b7893ccfSSadaf Ebrahimi     }
3038*b7893ccfSSadaf Ebrahimi 
3039*b7893ccfSSadaf Ebrahimi     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
3040*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3041*b7893ccfSSadaf Ebrahimi 
3042*b7893ccfSSadaf Ebrahimi     // Map/Flush/Invalidate using WHOLE_SIZE and zero offsets and entire mapped range
3043*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
3044*b7893ccfSSadaf Ebrahimi     err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, (void **)&pData);
3045*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3046*b7893ccfSSadaf Ebrahimi     VkMappedMemoryRange mmr = {};
3047*b7893ccfSSadaf Ebrahimi     mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
3048*b7893ccfSSadaf Ebrahimi     mmr.memory = mem;
3049*b7893ccfSSadaf Ebrahimi     mmr.offset = 0;
3050*b7893ccfSSadaf Ebrahimi     mmr.size = VK_WHOLE_SIZE;
3051*b7893ccfSSadaf Ebrahimi     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
3052*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3053*b7893ccfSSadaf Ebrahimi     err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr);
3054*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3055*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
3056*b7893ccfSSadaf Ebrahimi     vkUnmapMemory(m_device->device(), mem);
3057*b7893ccfSSadaf Ebrahimi 
3058*b7893ccfSSadaf Ebrahimi     // Map/Flush/Invalidate using WHOLE_SIZE and an offset and entire mapped range
3059*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
3060*b7893ccfSSadaf Ebrahimi     err = vkMapMemory(m_device->device(), mem, 5 * atom_size, VK_WHOLE_SIZE, 0, (void **)&pData);
3061*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3062*b7893ccfSSadaf Ebrahimi     mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
3063*b7893ccfSSadaf Ebrahimi     mmr.memory = mem;
3064*b7893ccfSSadaf Ebrahimi     mmr.offset = 6 * atom_size;
3065*b7893ccfSSadaf Ebrahimi     mmr.size = VK_WHOLE_SIZE;
3066*b7893ccfSSadaf Ebrahimi     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
3067*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3068*b7893ccfSSadaf Ebrahimi     err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr);
3069*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3070*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
3071*b7893ccfSSadaf Ebrahimi     vkUnmapMemory(m_device->device(), mem);
3072*b7893ccfSSadaf Ebrahimi 
3073*b7893ccfSSadaf Ebrahimi     // Map with offset and size
3074*b7893ccfSSadaf Ebrahimi     // Flush/Invalidate subrange of mapped area with offset and size
3075*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
3076*b7893ccfSSadaf Ebrahimi     err = vkMapMemory(m_device->device(), mem, 3 * atom_size, 9 * atom_size, 0, (void **)&pData);
3077*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3078*b7893ccfSSadaf Ebrahimi     mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
3079*b7893ccfSSadaf Ebrahimi     mmr.memory = mem;
3080*b7893ccfSSadaf Ebrahimi     mmr.offset = 4 * atom_size;
3081*b7893ccfSSadaf Ebrahimi     mmr.size = 2 * atom_size;
3082*b7893ccfSSadaf Ebrahimi     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
3083*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3084*b7893ccfSSadaf Ebrahimi     err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr);
3085*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3086*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
3087*b7893ccfSSadaf Ebrahimi     vkUnmapMemory(m_device->device(), mem);
3088*b7893ccfSSadaf Ebrahimi 
3089*b7893ccfSSadaf Ebrahimi     // Map without offset and flush WHOLE_SIZE with two separate offsets
3090*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
3091*b7893ccfSSadaf Ebrahimi     err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, (void **)&pData);
3092*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3093*b7893ccfSSadaf Ebrahimi     mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
3094*b7893ccfSSadaf Ebrahimi     mmr.memory = mem;
3095*b7893ccfSSadaf Ebrahimi     mmr.offset = allocation_size - (4 * atom_size);
3096*b7893ccfSSadaf Ebrahimi     mmr.size = VK_WHOLE_SIZE;
3097*b7893ccfSSadaf Ebrahimi     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
3098*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3099*b7893ccfSSadaf Ebrahimi     mmr.offset = allocation_size - (6 * atom_size);
3100*b7893ccfSSadaf Ebrahimi     mmr.size = VK_WHOLE_SIZE;
3101*b7893ccfSSadaf Ebrahimi     err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
3102*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3103*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
3104*b7893ccfSSadaf Ebrahimi     vkUnmapMemory(m_device->device(), mem);
3105*b7893ccfSSadaf Ebrahimi 
3106*b7893ccfSSadaf Ebrahimi     vkFreeMemory(m_device->device(), mem, NULL);
3107*b7893ccfSSadaf Ebrahimi }
3108*b7893ccfSSadaf Ebrahimi 
3109*b7893ccfSSadaf Ebrahimi // This is a positive test. We used to expect error in this case but spec now allows it
TEST_F(VkPositiveLayerTest,ResetUnsignaledFence)3110*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, ResetUnsignaledFence) {
3111*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
3112*b7893ccfSSadaf Ebrahimi     vk_testing::Fence testFence;
3113*b7893ccfSSadaf Ebrahimi     VkFenceCreateInfo fenceInfo = {};
3114*b7893ccfSSadaf Ebrahimi     fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
3115*b7893ccfSSadaf Ebrahimi     fenceInfo.pNext = NULL;
3116*b7893ccfSSadaf Ebrahimi 
3117*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
3118*b7893ccfSSadaf Ebrahimi     testFence.init(*m_device, fenceInfo);
3119*b7893ccfSSadaf Ebrahimi     VkFence fences[1] = {testFence.handle()};
3120*b7893ccfSSadaf Ebrahimi     VkResult result = vkResetFences(m_device->device(), 1, fences);
3121*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(result);
3122*b7893ccfSSadaf Ebrahimi 
3123*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
3124*b7893ccfSSadaf Ebrahimi }
3125*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CommandBufferSimultaneousUseSync)3126*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CommandBufferSimultaneousUseSync) {
3127*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
3128*b7893ccfSSadaf Ebrahimi 
3129*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
3130*b7893ccfSSadaf Ebrahimi     VkResult err;
3131*b7893ccfSSadaf Ebrahimi 
3132*b7893ccfSSadaf Ebrahimi     // Record (empty!) command buffer that can be submitted multiple times
3133*b7893ccfSSadaf Ebrahimi     // simultaneously.
3134*b7893ccfSSadaf Ebrahimi     VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
3135*b7893ccfSSadaf Ebrahimi                                      VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, nullptr};
3136*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin(&cbbi);
3137*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
3138*b7893ccfSSadaf Ebrahimi 
3139*b7893ccfSSadaf Ebrahimi     VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
3140*b7893ccfSSadaf Ebrahimi     VkFence fence;
3141*b7893ccfSSadaf Ebrahimi     err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
3142*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3143*b7893ccfSSadaf Ebrahimi 
3144*b7893ccfSSadaf Ebrahimi     VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
3145*b7893ccfSSadaf Ebrahimi     VkSemaphore s1, s2;
3146*b7893ccfSSadaf Ebrahimi     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s1);
3147*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3148*b7893ccfSSadaf Ebrahimi     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s2);
3149*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3150*b7893ccfSSadaf Ebrahimi 
3151*b7893ccfSSadaf Ebrahimi     // Submit CB once signaling s1, with fence so we can roll forward to its retirement.
3152*b7893ccfSSadaf Ebrahimi     VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &m_commandBuffer->handle(), 1, &s1};
3153*b7893ccfSSadaf Ebrahimi     err = vkQueueSubmit(m_device->m_queue, 1, &si, fence);
3154*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3155*b7893ccfSSadaf Ebrahimi 
3156*b7893ccfSSadaf Ebrahimi     // Submit CB again, signaling s2.
3157*b7893ccfSSadaf Ebrahimi     si.pSignalSemaphores = &s2;
3158*b7893ccfSSadaf Ebrahimi     err = vkQueueSubmit(m_device->m_queue, 1, &si, VK_NULL_HANDLE);
3159*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3160*b7893ccfSSadaf Ebrahimi 
3161*b7893ccfSSadaf Ebrahimi     // Wait for fence.
3162*b7893ccfSSadaf Ebrahimi     err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
3163*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3164*b7893ccfSSadaf Ebrahimi 
3165*b7893ccfSSadaf Ebrahimi     // CB is still in flight from second submission, but semaphore s1 is no
3166*b7893ccfSSadaf Ebrahimi     // longer in flight. delete it.
3167*b7893ccfSSadaf Ebrahimi     vkDestroySemaphore(m_device->device(), s1, nullptr);
3168*b7893ccfSSadaf Ebrahimi 
3169*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
3170*b7893ccfSSadaf Ebrahimi 
3171*b7893ccfSSadaf Ebrahimi     // Force device idle and clean up remaining objects
3172*b7893ccfSSadaf Ebrahimi     vkDeviceWaitIdle(m_device->device());
3173*b7893ccfSSadaf Ebrahimi     vkDestroySemaphore(m_device->device(), s2, nullptr);
3174*b7893ccfSSadaf Ebrahimi     vkDestroyFence(m_device->device(), fence, nullptr);
3175*b7893ccfSSadaf Ebrahimi }
3176*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,FenceCreateSignaledWaitHandling)3177*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, FenceCreateSignaledWaitHandling) {
3178*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
3179*b7893ccfSSadaf Ebrahimi 
3180*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
3181*b7893ccfSSadaf Ebrahimi     VkResult err;
3182*b7893ccfSSadaf Ebrahimi 
3183*b7893ccfSSadaf Ebrahimi     // A fence created signaled
3184*b7893ccfSSadaf Ebrahimi     VkFenceCreateInfo fci1 = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, VK_FENCE_CREATE_SIGNALED_BIT};
3185*b7893ccfSSadaf Ebrahimi     VkFence f1;
3186*b7893ccfSSadaf Ebrahimi     err = vkCreateFence(m_device->device(), &fci1, nullptr, &f1);
3187*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3188*b7893ccfSSadaf Ebrahimi 
3189*b7893ccfSSadaf Ebrahimi     // A fence created not
3190*b7893ccfSSadaf Ebrahimi     VkFenceCreateInfo fci2 = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
3191*b7893ccfSSadaf Ebrahimi     VkFence f2;
3192*b7893ccfSSadaf Ebrahimi     err = vkCreateFence(m_device->device(), &fci2, nullptr, &f2);
3193*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3194*b7893ccfSSadaf Ebrahimi 
3195*b7893ccfSSadaf Ebrahimi     // Submit the unsignaled fence
3196*b7893ccfSSadaf Ebrahimi     VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 0, nullptr, 0, nullptr};
3197*b7893ccfSSadaf Ebrahimi     err = vkQueueSubmit(m_device->m_queue, 1, &si, f2);
3198*b7893ccfSSadaf Ebrahimi 
3199*b7893ccfSSadaf Ebrahimi     // Wait on both fences, with signaled first.
3200*b7893ccfSSadaf Ebrahimi     VkFence fences[] = {f1, f2};
3201*b7893ccfSSadaf Ebrahimi     vkWaitForFences(m_device->device(), 2, fences, VK_TRUE, UINT64_MAX);
3202*b7893ccfSSadaf Ebrahimi 
3203*b7893ccfSSadaf Ebrahimi     // Should have both retired!
3204*b7893ccfSSadaf Ebrahimi     vkDestroyFence(m_device->device(), f1, nullptr);
3205*b7893ccfSSadaf Ebrahimi     vkDestroyFence(m_device->device(), f2, nullptr);
3206*b7893ccfSSadaf Ebrahimi 
3207*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
3208*b7893ccfSSadaf Ebrahimi }
3209*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CreateImageViewFollowsParameterCompatibilityRequirements)3210*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CreateImageViewFollowsParameterCompatibilityRequirements) {
3211*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Verify that creating an ImageView with valid usage does not generate validation errors.");
3212*b7893ccfSSadaf Ebrahimi 
3213*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
3214*b7893ccfSSadaf Ebrahimi 
3215*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
3216*b7893ccfSSadaf Ebrahimi 
3217*b7893ccfSSadaf Ebrahimi     VkImageCreateInfo imgInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
3218*b7893ccfSSadaf Ebrahimi                                  nullptr,
3219*b7893ccfSSadaf Ebrahimi                                  VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
3220*b7893ccfSSadaf Ebrahimi                                  VK_IMAGE_TYPE_2D,
3221*b7893ccfSSadaf Ebrahimi                                  VK_FORMAT_R8G8B8A8_UNORM,
3222*b7893ccfSSadaf Ebrahimi                                  {128, 128, 1},
3223*b7893ccfSSadaf Ebrahimi                                  1,
3224*b7893ccfSSadaf Ebrahimi                                  1,
3225*b7893ccfSSadaf Ebrahimi                                  VK_SAMPLE_COUNT_1_BIT,
3226*b7893ccfSSadaf Ebrahimi                                  VK_IMAGE_TILING_OPTIMAL,
3227*b7893ccfSSadaf Ebrahimi                                  VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
3228*b7893ccfSSadaf Ebrahimi                                  VK_SHARING_MODE_EXCLUSIVE,
3229*b7893ccfSSadaf Ebrahimi                                  0,
3230*b7893ccfSSadaf Ebrahimi                                  nullptr,
3231*b7893ccfSSadaf Ebrahimi                                  VK_IMAGE_LAYOUT_UNDEFINED};
3232*b7893ccfSSadaf Ebrahimi     VkImageObj image(m_device);
3233*b7893ccfSSadaf Ebrahimi     image.init(&imgInfo);
3234*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(image.initialized());
3235*b7893ccfSSadaf Ebrahimi     image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
3236*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
3237*b7893ccfSSadaf Ebrahimi }
3238*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,ValidUsage)3239*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, ValidUsage) {
3240*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Verify that creating an image view from an image with valid usage doesn't generate validation errors");
3241*b7893ccfSSadaf Ebrahimi 
3242*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
3243*b7893ccfSSadaf Ebrahimi 
3244*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
3245*b7893ccfSSadaf Ebrahimi     // Verify that we can create a view with usage INPUT_ATTACHMENT
3246*b7893ccfSSadaf Ebrahimi     VkImageObj image(m_device);
3247*b7893ccfSSadaf Ebrahimi     image.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
3248*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(image.initialized());
3249*b7893ccfSSadaf Ebrahimi     VkImageView imageView;
3250*b7893ccfSSadaf Ebrahimi     VkImageViewCreateInfo ivci = {};
3251*b7893ccfSSadaf Ebrahimi     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
3252*b7893ccfSSadaf Ebrahimi     ivci.image = image.handle();
3253*b7893ccfSSadaf Ebrahimi     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
3254*b7893ccfSSadaf Ebrahimi     ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
3255*b7893ccfSSadaf Ebrahimi     ivci.subresourceRange.layerCount = 1;
3256*b7893ccfSSadaf Ebrahimi     ivci.subresourceRange.baseMipLevel = 0;
3257*b7893ccfSSadaf Ebrahimi     ivci.subresourceRange.levelCount = 1;
3258*b7893ccfSSadaf Ebrahimi     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3259*b7893ccfSSadaf Ebrahimi 
3260*b7893ccfSSadaf Ebrahimi     vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
3261*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
3262*b7893ccfSSadaf Ebrahimi     vkDestroyImageView(m_device->device(), imageView, NULL);
3263*b7893ccfSSadaf Ebrahimi }
3264*b7893ccfSSadaf Ebrahimi 
3265*b7893ccfSSadaf Ebrahimi // This is a positive test. No failures are expected.
TEST_F(VkPositiveLayerTest,BindSparse)3266*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, BindSparse) {
3267*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Bind 2 memory ranges to one image using vkQueueBindSparse, destroy the image and then free the memory");
3268*b7893ccfSSadaf Ebrahimi 
3269*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
3270*b7893ccfSSadaf Ebrahimi 
3271*b7893ccfSSadaf Ebrahimi     auto index = m_device->graphics_queue_node_index_;
3272*b7893ccfSSadaf Ebrahimi     if (!(m_device->queue_props[index].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT)) {
3273*b7893ccfSSadaf Ebrahimi         printf("%s Graphics queue does not have sparse binding bit.\n", kSkipPrefix);
3274*b7893ccfSSadaf Ebrahimi         return;
3275*b7893ccfSSadaf Ebrahimi     }
3276*b7893ccfSSadaf Ebrahimi     if (!m_device->phy().features().sparseBinding) {
3277*b7893ccfSSadaf Ebrahimi         printf("%s Device does not support sparse bindings.\n", kSkipPrefix);
3278*b7893ccfSSadaf Ebrahimi         return;
3279*b7893ccfSSadaf Ebrahimi     }
3280*b7893ccfSSadaf Ebrahimi 
3281*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT);
3282*b7893ccfSSadaf Ebrahimi 
3283*b7893ccfSSadaf Ebrahimi     VkImage image;
3284*b7893ccfSSadaf Ebrahimi     VkImageCreateInfo image_create_info = {};
3285*b7893ccfSSadaf Ebrahimi     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3286*b7893ccfSSadaf Ebrahimi     image_create_info.pNext = NULL;
3287*b7893ccfSSadaf Ebrahimi     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3288*b7893ccfSSadaf Ebrahimi     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3289*b7893ccfSSadaf Ebrahimi     image_create_info.extent.width = 64;
3290*b7893ccfSSadaf Ebrahimi     image_create_info.extent.height = 64;
3291*b7893ccfSSadaf Ebrahimi     image_create_info.extent.depth = 1;
3292*b7893ccfSSadaf Ebrahimi     image_create_info.mipLevels = 1;
3293*b7893ccfSSadaf Ebrahimi     image_create_info.arrayLayers = 1;
3294*b7893ccfSSadaf Ebrahimi     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3295*b7893ccfSSadaf Ebrahimi     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3296*b7893ccfSSadaf Ebrahimi     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
3297*b7893ccfSSadaf Ebrahimi     image_create_info.flags = VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
3298*b7893ccfSSadaf Ebrahimi     VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
3299*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3300*b7893ccfSSadaf Ebrahimi 
3301*b7893ccfSSadaf Ebrahimi     VkMemoryRequirements memory_reqs;
3302*b7893ccfSSadaf Ebrahimi     VkDeviceMemory memory_one, memory_two;
3303*b7893ccfSSadaf Ebrahimi     bool pass;
3304*b7893ccfSSadaf Ebrahimi     VkMemoryAllocateInfo memory_info = {};
3305*b7893ccfSSadaf Ebrahimi     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3306*b7893ccfSSadaf Ebrahimi     memory_info.pNext = NULL;
3307*b7893ccfSSadaf Ebrahimi     memory_info.allocationSize = 0;
3308*b7893ccfSSadaf Ebrahimi     memory_info.memoryTypeIndex = 0;
3309*b7893ccfSSadaf Ebrahimi     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
3310*b7893ccfSSadaf Ebrahimi     // Find an image big enough to allow sparse mapping of 2 memory regions
3311*b7893ccfSSadaf Ebrahimi     // Increase the image size until it is at least twice the
3312*b7893ccfSSadaf Ebrahimi     // size of the required alignment, to ensure we can bind both
3313*b7893ccfSSadaf Ebrahimi     // allocated memory blocks to the image on aligned offsets.
3314*b7893ccfSSadaf Ebrahimi     while (memory_reqs.size < (memory_reqs.alignment * 2)) {
3315*b7893ccfSSadaf Ebrahimi         vkDestroyImage(m_device->device(), image, nullptr);
3316*b7893ccfSSadaf Ebrahimi         image_create_info.extent.width *= 2;
3317*b7893ccfSSadaf Ebrahimi         image_create_info.extent.height *= 2;
3318*b7893ccfSSadaf Ebrahimi         err = vkCreateImage(m_device->device(), &image_create_info, nullptr, &image);
3319*b7893ccfSSadaf Ebrahimi         ASSERT_VK_SUCCESS(err);
3320*b7893ccfSSadaf Ebrahimi         vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
3321*b7893ccfSSadaf Ebrahimi     }
3322*b7893ccfSSadaf Ebrahimi     // Allocate 2 memory regions of minimum alignment size, bind one at 0, the other
3323*b7893ccfSSadaf Ebrahimi     // at the end of the first
3324*b7893ccfSSadaf Ebrahimi     memory_info.allocationSize = memory_reqs.alignment;
3325*b7893ccfSSadaf Ebrahimi     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
3326*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(pass);
3327*b7893ccfSSadaf Ebrahimi     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &memory_one);
3328*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3329*b7893ccfSSadaf Ebrahimi     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &memory_two);
3330*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3331*b7893ccfSSadaf Ebrahimi     VkSparseMemoryBind binds[2];
3332*b7893ccfSSadaf Ebrahimi     binds[0].flags = 0;
3333*b7893ccfSSadaf Ebrahimi     binds[0].memory = memory_one;
3334*b7893ccfSSadaf Ebrahimi     binds[0].memoryOffset = 0;
3335*b7893ccfSSadaf Ebrahimi     binds[0].resourceOffset = 0;
3336*b7893ccfSSadaf Ebrahimi     binds[0].size = memory_info.allocationSize;
3337*b7893ccfSSadaf Ebrahimi     binds[1].flags = 0;
3338*b7893ccfSSadaf Ebrahimi     binds[1].memory = memory_two;
3339*b7893ccfSSadaf Ebrahimi     binds[1].memoryOffset = 0;
3340*b7893ccfSSadaf Ebrahimi     binds[1].resourceOffset = memory_info.allocationSize;
3341*b7893ccfSSadaf Ebrahimi     binds[1].size = memory_info.allocationSize;
3342*b7893ccfSSadaf Ebrahimi 
3343*b7893ccfSSadaf Ebrahimi     VkSparseImageOpaqueMemoryBindInfo opaqueBindInfo;
3344*b7893ccfSSadaf Ebrahimi     opaqueBindInfo.image = image;
3345*b7893ccfSSadaf Ebrahimi     opaqueBindInfo.bindCount = 2;
3346*b7893ccfSSadaf Ebrahimi     opaqueBindInfo.pBinds = binds;
3347*b7893ccfSSadaf Ebrahimi 
3348*b7893ccfSSadaf Ebrahimi     VkFence fence = VK_NULL_HANDLE;
3349*b7893ccfSSadaf Ebrahimi     VkBindSparseInfo bindSparseInfo = {};
3350*b7893ccfSSadaf Ebrahimi     bindSparseInfo.sType = VK_STRUCTURE_TYPE_BIND_SPARSE_INFO;
3351*b7893ccfSSadaf Ebrahimi     bindSparseInfo.imageOpaqueBindCount = 1;
3352*b7893ccfSSadaf Ebrahimi     bindSparseInfo.pImageOpaqueBinds = &opaqueBindInfo;
3353*b7893ccfSSadaf Ebrahimi 
3354*b7893ccfSSadaf Ebrahimi     vkQueueBindSparse(m_device->m_queue, 1, &bindSparseInfo, fence);
3355*b7893ccfSSadaf Ebrahimi     vkQueueWaitIdle(m_device->m_queue);
3356*b7893ccfSSadaf Ebrahimi     vkDestroyImage(m_device->device(), image, NULL);
3357*b7893ccfSSadaf Ebrahimi     vkFreeMemory(m_device->device(), memory_one, NULL);
3358*b7893ccfSSadaf Ebrahimi     vkFreeMemory(m_device->device(), memory_two, NULL);
3359*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
3360*b7893ccfSSadaf Ebrahimi }
3361*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,BindSparseMetadata)3362*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, BindSparseMetadata) {
3363*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Bind memory for the metadata aspect of a sparse image");
3364*b7893ccfSSadaf Ebrahimi 
3365*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
3366*b7893ccfSSadaf Ebrahimi 
3367*b7893ccfSSadaf Ebrahimi     auto index = m_device->graphics_queue_node_index_;
3368*b7893ccfSSadaf Ebrahimi     if (!(m_device->queue_props[index].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT)) {
3369*b7893ccfSSadaf Ebrahimi         printf("%s Graphics queue does not have sparse binding bit.\n", kSkipPrefix);
3370*b7893ccfSSadaf Ebrahimi         return;
3371*b7893ccfSSadaf Ebrahimi     }
3372*b7893ccfSSadaf Ebrahimi     if (!m_device->phy().features().sparseResidencyImage2D) {
3373*b7893ccfSSadaf Ebrahimi         printf("%s Device does not support sparse residency for images.\n", kSkipPrefix);
3374*b7893ccfSSadaf Ebrahimi         return;
3375*b7893ccfSSadaf Ebrahimi     }
3376*b7893ccfSSadaf Ebrahimi 
3377*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT);
3378*b7893ccfSSadaf Ebrahimi 
3379*b7893ccfSSadaf Ebrahimi     // Create a sparse image
3380*b7893ccfSSadaf Ebrahimi     VkImage image;
3381*b7893ccfSSadaf Ebrahimi     VkImageCreateInfo image_create_info = {};
3382*b7893ccfSSadaf Ebrahimi     image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
3383*b7893ccfSSadaf Ebrahimi     image_create_info.pNext = NULL;
3384*b7893ccfSSadaf Ebrahimi     image_create_info.imageType = VK_IMAGE_TYPE_2D;
3385*b7893ccfSSadaf Ebrahimi     image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
3386*b7893ccfSSadaf Ebrahimi     image_create_info.extent.width = 64;
3387*b7893ccfSSadaf Ebrahimi     image_create_info.extent.height = 64;
3388*b7893ccfSSadaf Ebrahimi     image_create_info.extent.depth = 1;
3389*b7893ccfSSadaf Ebrahimi     image_create_info.mipLevels = 1;
3390*b7893ccfSSadaf Ebrahimi     image_create_info.arrayLayers = 1;
3391*b7893ccfSSadaf Ebrahimi     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
3392*b7893ccfSSadaf Ebrahimi     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
3393*b7893ccfSSadaf Ebrahimi     image_create_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
3394*b7893ccfSSadaf Ebrahimi     image_create_info.flags = VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT;
3395*b7893ccfSSadaf Ebrahimi     VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
3396*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3397*b7893ccfSSadaf Ebrahimi 
3398*b7893ccfSSadaf Ebrahimi     // Query image memory requirements
3399*b7893ccfSSadaf Ebrahimi     VkMemoryRequirements memory_reqs;
3400*b7893ccfSSadaf Ebrahimi     vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
3401*b7893ccfSSadaf Ebrahimi 
3402*b7893ccfSSadaf Ebrahimi     // Query sparse memory requirements
3403*b7893ccfSSadaf Ebrahimi     uint32_t sparse_reqs_count = 0;
3404*b7893ccfSSadaf Ebrahimi     vkGetImageSparseMemoryRequirements(m_device->device(), image, &sparse_reqs_count, nullptr);
3405*b7893ccfSSadaf Ebrahimi     std::vector<VkSparseImageMemoryRequirements> sparse_reqs(sparse_reqs_count);
3406*b7893ccfSSadaf Ebrahimi     vkGetImageSparseMemoryRequirements(m_device->device(), image, &sparse_reqs_count, sparse_reqs.data());
3407*b7893ccfSSadaf Ebrahimi 
3408*b7893ccfSSadaf Ebrahimi     // Find requirements for metadata aspect
3409*b7893ccfSSadaf Ebrahimi     const VkSparseImageMemoryRequirements *metadata_reqs = nullptr;
3410*b7893ccfSSadaf Ebrahimi     for (auto const &aspect_sparse_reqs : sparse_reqs) {
3411*b7893ccfSSadaf Ebrahimi         if (aspect_sparse_reqs.formatProperties.aspectMask == VK_IMAGE_ASPECT_METADATA_BIT) {
3412*b7893ccfSSadaf Ebrahimi             metadata_reqs = &aspect_sparse_reqs;
3413*b7893ccfSSadaf Ebrahimi         }
3414*b7893ccfSSadaf Ebrahimi     }
3415*b7893ccfSSadaf Ebrahimi 
3416*b7893ccfSSadaf Ebrahimi     if (!metadata_reqs) {
3417*b7893ccfSSadaf Ebrahimi         printf("%s Sparse image does not require memory for metadata.\n", kSkipPrefix);
3418*b7893ccfSSadaf Ebrahimi     } else {
3419*b7893ccfSSadaf Ebrahimi         // Allocate memory for the metadata
3420*b7893ccfSSadaf Ebrahimi         VkDeviceMemory metadata_memory = VK_NULL_HANDLE;
3421*b7893ccfSSadaf Ebrahimi         VkMemoryAllocateInfo metadata_memory_info = {};
3422*b7893ccfSSadaf Ebrahimi         metadata_memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
3423*b7893ccfSSadaf Ebrahimi         metadata_memory_info.allocationSize = metadata_reqs->imageMipTailSize;
3424*b7893ccfSSadaf Ebrahimi         m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &metadata_memory_info, 0);
3425*b7893ccfSSadaf Ebrahimi         err = vkAllocateMemory(m_device->device(), &metadata_memory_info, NULL, &metadata_memory);
3426*b7893ccfSSadaf Ebrahimi         ASSERT_VK_SUCCESS(err);
3427*b7893ccfSSadaf Ebrahimi 
3428*b7893ccfSSadaf Ebrahimi         // Bind metadata
3429*b7893ccfSSadaf Ebrahimi         VkSparseMemoryBind sparse_bind = {};
3430*b7893ccfSSadaf Ebrahimi         sparse_bind.resourceOffset = metadata_reqs->imageMipTailOffset;
3431*b7893ccfSSadaf Ebrahimi         sparse_bind.size = metadata_reqs->imageMipTailSize;
3432*b7893ccfSSadaf Ebrahimi         sparse_bind.memory = metadata_memory;
3433*b7893ccfSSadaf Ebrahimi         sparse_bind.memoryOffset = 0;
3434*b7893ccfSSadaf Ebrahimi         sparse_bind.flags = VK_SPARSE_MEMORY_BIND_METADATA_BIT;
3435*b7893ccfSSadaf Ebrahimi 
3436*b7893ccfSSadaf Ebrahimi         VkSparseImageOpaqueMemoryBindInfo opaque_bind_info = {};
3437*b7893ccfSSadaf Ebrahimi         opaque_bind_info.image = image;
3438*b7893ccfSSadaf Ebrahimi         opaque_bind_info.bindCount = 1;
3439*b7893ccfSSadaf Ebrahimi         opaque_bind_info.pBinds = &sparse_bind;
3440*b7893ccfSSadaf Ebrahimi 
3441*b7893ccfSSadaf Ebrahimi         VkBindSparseInfo bind_info = {};
3442*b7893ccfSSadaf Ebrahimi         bind_info.sType = VK_STRUCTURE_TYPE_BIND_SPARSE_INFO;
3443*b7893ccfSSadaf Ebrahimi         bind_info.imageOpaqueBindCount = 1;
3444*b7893ccfSSadaf Ebrahimi         bind_info.pImageOpaqueBinds = &opaque_bind_info;
3445*b7893ccfSSadaf Ebrahimi 
3446*b7893ccfSSadaf Ebrahimi         vkQueueBindSparse(m_device->m_queue, 1, &bind_info, VK_NULL_HANDLE);
3447*b7893ccfSSadaf Ebrahimi         m_errorMonitor->VerifyNotFound();
3448*b7893ccfSSadaf Ebrahimi 
3449*b7893ccfSSadaf Ebrahimi         // Cleanup
3450*b7893ccfSSadaf Ebrahimi         vkQueueWaitIdle(m_device->m_queue);
3451*b7893ccfSSadaf Ebrahimi         vkFreeMemory(m_device->device(), metadata_memory, NULL);
3452*b7893ccfSSadaf Ebrahimi     }
3453*b7893ccfSSadaf Ebrahimi 
3454*b7893ccfSSadaf Ebrahimi     vkDestroyImage(m_device->device(), image, NULL);
3455*b7893ccfSSadaf Ebrahimi }
3456*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,FramebufferBindingDestroyCommandPool)3457*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, FramebufferBindingDestroyCommandPool) {
3458*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
3459*b7893ccfSSadaf Ebrahimi         "This test should pass. Create a Framebuffer and command buffer, bind them together, then destroy command pool and "
3460*b7893ccfSSadaf Ebrahimi         "framebuffer and verify there are no errors.");
3461*b7893ccfSSadaf Ebrahimi 
3462*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
3463*b7893ccfSSadaf Ebrahimi 
3464*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
3465*b7893ccfSSadaf Ebrahimi 
3466*b7893ccfSSadaf Ebrahimi     // A renderpass with one color attachment.
3467*b7893ccfSSadaf Ebrahimi     VkAttachmentDescription attachment = {0,
3468*b7893ccfSSadaf Ebrahimi                                           VK_FORMAT_R8G8B8A8_UNORM,
3469*b7893ccfSSadaf Ebrahimi                                           VK_SAMPLE_COUNT_1_BIT,
3470*b7893ccfSSadaf Ebrahimi                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3471*b7893ccfSSadaf Ebrahimi                                           VK_ATTACHMENT_STORE_OP_STORE,
3472*b7893ccfSSadaf Ebrahimi                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3473*b7893ccfSSadaf Ebrahimi                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
3474*b7893ccfSSadaf Ebrahimi                                           VK_IMAGE_LAYOUT_UNDEFINED,
3475*b7893ccfSSadaf Ebrahimi                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
3476*b7893ccfSSadaf Ebrahimi 
3477*b7893ccfSSadaf Ebrahimi     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
3478*b7893ccfSSadaf Ebrahimi 
3479*b7893ccfSSadaf Ebrahimi     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
3480*b7893ccfSSadaf Ebrahimi 
3481*b7893ccfSSadaf Ebrahimi     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
3482*b7893ccfSSadaf Ebrahimi 
3483*b7893ccfSSadaf Ebrahimi     VkRenderPass rp;
3484*b7893ccfSSadaf Ebrahimi     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
3485*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3486*b7893ccfSSadaf Ebrahimi 
3487*b7893ccfSSadaf Ebrahimi     // A compatible framebuffer.
3488*b7893ccfSSadaf Ebrahimi     VkImageObj image(m_device);
3489*b7893ccfSSadaf Ebrahimi     image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
3490*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(image.initialized());
3491*b7893ccfSSadaf Ebrahimi 
3492*b7893ccfSSadaf Ebrahimi     VkImageView view = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
3493*b7893ccfSSadaf Ebrahimi 
3494*b7893ccfSSadaf Ebrahimi     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
3495*b7893ccfSSadaf Ebrahimi     VkFramebuffer fb;
3496*b7893ccfSSadaf Ebrahimi     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
3497*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3498*b7893ccfSSadaf Ebrahimi 
3499*b7893ccfSSadaf Ebrahimi     // Explicitly create a command buffer to bind the FB to so that we can then
3500*b7893ccfSSadaf Ebrahimi     //  destroy the command pool in order to implicitly free command buffer
3501*b7893ccfSSadaf Ebrahimi     VkCommandPool command_pool;
3502*b7893ccfSSadaf Ebrahimi     VkCommandPoolCreateInfo pool_create_info{};
3503*b7893ccfSSadaf Ebrahimi     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
3504*b7893ccfSSadaf Ebrahimi     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
3505*b7893ccfSSadaf Ebrahimi     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
3506*b7893ccfSSadaf Ebrahimi     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
3507*b7893ccfSSadaf Ebrahimi 
3508*b7893ccfSSadaf Ebrahimi     VkCommandBuffer command_buffer;
3509*b7893ccfSSadaf Ebrahimi     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
3510*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
3511*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandPool = command_pool;
3512*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandBufferCount = 1;
3513*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
3514*b7893ccfSSadaf Ebrahimi     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
3515*b7893ccfSSadaf Ebrahimi 
3516*b7893ccfSSadaf Ebrahimi     // Begin our cmd buffer with renderpass using our framebuffer
3517*b7893ccfSSadaf Ebrahimi     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
3518*b7893ccfSSadaf Ebrahimi     VkCommandBufferBeginInfo begin_info{};
3519*b7893ccfSSadaf Ebrahimi     begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
3520*b7893ccfSSadaf Ebrahimi     vkBeginCommandBuffer(command_buffer, &begin_info);
3521*b7893ccfSSadaf Ebrahimi 
3522*b7893ccfSSadaf Ebrahimi     vkCmdBeginRenderPass(command_buffer, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
3523*b7893ccfSSadaf Ebrahimi     vkCmdEndRenderPass(command_buffer);
3524*b7893ccfSSadaf Ebrahimi     vkEndCommandBuffer(command_buffer);
3525*b7893ccfSSadaf Ebrahimi     // Destroy command pool to implicitly free command buffer
3526*b7893ccfSSadaf Ebrahimi     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
3527*b7893ccfSSadaf Ebrahimi     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
3528*b7893ccfSSadaf Ebrahimi     vkDestroyRenderPass(m_device->device(), rp, nullptr);
3529*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
3530*b7893ccfSSadaf Ebrahimi }
3531*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,FramebufferCreateDepthStencilLayoutTransitionForDepthOnlyImageView)3532*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, FramebufferCreateDepthStencilLayoutTransitionForDepthOnlyImageView) {
3533*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
3534*b7893ccfSSadaf Ebrahimi         "Validate that when an imageView of a depth/stencil image is used as a depth/stencil framebuffer attachment, the "
3535*b7893ccfSSadaf Ebrahimi         "aspectMask is ignored and both depth and stencil image subresources are used.");
3536*b7893ccfSSadaf Ebrahimi 
3537*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
3538*b7893ccfSSadaf Ebrahimi     VkFormatProperties format_properties;
3539*b7893ccfSSadaf Ebrahimi     vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_D32_SFLOAT_S8_UINT, &format_properties);
3540*b7893ccfSSadaf Ebrahimi     if (!(format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
3541*b7893ccfSSadaf Ebrahimi         printf("%s Image format does not support sampling.\n", kSkipPrefix);
3542*b7893ccfSSadaf Ebrahimi         return;
3543*b7893ccfSSadaf Ebrahimi     }
3544*b7893ccfSSadaf Ebrahimi 
3545*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
3546*b7893ccfSSadaf Ebrahimi 
3547*b7893ccfSSadaf Ebrahimi     VkAttachmentDescription attachment = {0,
3548*b7893ccfSSadaf Ebrahimi                                           VK_FORMAT_D32_SFLOAT_S8_UINT,
3549*b7893ccfSSadaf Ebrahimi                                           VK_SAMPLE_COUNT_1_BIT,
3550*b7893ccfSSadaf Ebrahimi                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3551*b7893ccfSSadaf Ebrahimi                                           VK_ATTACHMENT_STORE_OP_STORE,
3552*b7893ccfSSadaf Ebrahimi                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3553*b7893ccfSSadaf Ebrahimi                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
3554*b7893ccfSSadaf Ebrahimi                                           VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
3555*b7893ccfSSadaf Ebrahimi                                           VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
3556*b7893ccfSSadaf Ebrahimi 
3557*b7893ccfSSadaf Ebrahimi     VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
3558*b7893ccfSSadaf Ebrahimi 
3559*b7893ccfSSadaf Ebrahimi     VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &att_ref, 0, nullptr};
3560*b7893ccfSSadaf Ebrahimi 
3561*b7893ccfSSadaf Ebrahimi     VkSubpassDependency dep = {0,
3562*b7893ccfSSadaf Ebrahimi                                0,
3563*b7893ccfSSadaf Ebrahimi                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
3564*b7893ccfSSadaf Ebrahimi                                VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
3565*b7893ccfSSadaf Ebrahimi                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
3566*b7893ccfSSadaf Ebrahimi                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
3567*b7893ccfSSadaf Ebrahimi                                VK_DEPENDENCY_BY_REGION_BIT};
3568*b7893ccfSSadaf Ebrahimi 
3569*b7893ccfSSadaf Ebrahimi     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep};
3570*b7893ccfSSadaf Ebrahimi 
3571*b7893ccfSSadaf Ebrahimi     VkResult err;
3572*b7893ccfSSadaf Ebrahimi     VkRenderPass rp;
3573*b7893ccfSSadaf Ebrahimi     err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
3574*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3575*b7893ccfSSadaf Ebrahimi 
3576*b7893ccfSSadaf Ebrahimi     VkImageObj image(m_device);
3577*b7893ccfSSadaf Ebrahimi     image.InitNoLayout(32, 32, 1, VK_FORMAT_D32_SFLOAT_S8_UINT,
3578*b7893ccfSSadaf Ebrahimi                        0x26,  // usage
3579*b7893ccfSSadaf Ebrahimi                        VK_IMAGE_TILING_OPTIMAL, 0);
3580*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(image.initialized());
3581*b7893ccfSSadaf Ebrahimi     image.SetLayout(0x6, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
3582*b7893ccfSSadaf Ebrahimi 
3583*b7893ccfSSadaf Ebrahimi     VkImageView view = image.targetView(VK_FORMAT_D32_SFLOAT_S8_UINT, VK_IMAGE_ASPECT_DEPTH_BIT);
3584*b7893ccfSSadaf Ebrahimi 
3585*b7893ccfSSadaf Ebrahimi     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
3586*b7893ccfSSadaf Ebrahimi     VkFramebuffer fb;
3587*b7893ccfSSadaf Ebrahimi     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
3588*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3589*b7893ccfSSadaf Ebrahimi 
3590*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
3591*b7893ccfSSadaf Ebrahimi 
3592*b7893ccfSSadaf Ebrahimi     VkImageMemoryBarrier imb = {};
3593*b7893ccfSSadaf Ebrahimi     imb.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
3594*b7893ccfSSadaf Ebrahimi     imb.pNext = nullptr;
3595*b7893ccfSSadaf Ebrahimi     imb.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
3596*b7893ccfSSadaf Ebrahimi     imb.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
3597*b7893ccfSSadaf Ebrahimi     imb.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
3598*b7893ccfSSadaf Ebrahimi     imb.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
3599*b7893ccfSSadaf Ebrahimi     imb.srcQueueFamilyIndex = 0;
3600*b7893ccfSSadaf Ebrahimi     imb.dstQueueFamilyIndex = 0;
3601*b7893ccfSSadaf Ebrahimi     imb.image = image.handle();
3602*b7893ccfSSadaf Ebrahimi     imb.subresourceRange.aspectMask = 0x6;
3603*b7893ccfSSadaf Ebrahimi     imb.subresourceRange.baseMipLevel = 0;
3604*b7893ccfSSadaf Ebrahimi     imb.subresourceRange.levelCount = 0x1;
3605*b7893ccfSSadaf Ebrahimi     imb.subresourceRange.baseArrayLayer = 0;
3606*b7893ccfSSadaf Ebrahimi     imb.subresourceRange.layerCount = 0x1;
3607*b7893ccfSSadaf Ebrahimi 
3608*b7893ccfSSadaf Ebrahimi     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
3609*b7893ccfSSadaf Ebrahimi                          VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &imb);
3610*b7893ccfSSadaf Ebrahimi 
3611*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
3612*b7893ccfSSadaf Ebrahimi     m_commandBuffer->QueueCommandBuffer(false);
3613*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
3614*b7893ccfSSadaf Ebrahimi 
3615*b7893ccfSSadaf Ebrahimi     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
3616*b7893ccfSSadaf Ebrahimi     vkDestroyRenderPass(m_device->device(), rp, nullptr);
3617*b7893ccfSSadaf Ebrahimi }
3618*b7893ccfSSadaf Ebrahimi 
3619*b7893ccfSSadaf Ebrahimi // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,BarrierLayoutToImageUsage)3620*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, BarrierLayoutToImageUsage) {
3621*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Ensure barriers' new and old VkImageLayout are compatible with their images' VkImageUsageFlags");
3622*b7893ccfSSadaf Ebrahimi 
3623*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
3624*b7893ccfSSadaf Ebrahimi 
3625*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
3626*b7893ccfSSadaf Ebrahimi     auto depth_format = FindSupportedDepthStencilFormat(gpu());
3627*b7893ccfSSadaf Ebrahimi     if (!depth_format) {
3628*b7893ccfSSadaf Ebrahimi         printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
3629*b7893ccfSSadaf Ebrahimi         return;
3630*b7893ccfSSadaf Ebrahimi     }
3631*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
3632*b7893ccfSSadaf Ebrahimi 
3633*b7893ccfSSadaf Ebrahimi     VkImageMemoryBarrier img_barrier = {};
3634*b7893ccfSSadaf Ebrahimi     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
3635*b7893ccfSSadaf Ebrahimi     img_barrier.pNext = NULL;
3636*b7893ccfSSadaf Ebrahimi     img_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
3637*b7893ccfSSadaf Ebrahimi     img_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
3638*b7893ccfSSadaf Ebrahimi     img_barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
3639*b7893ccfSSadaf Ebrahimi     img_barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
3640*b7893ccfSSadaf Ebrahimi     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
3641*b7893ccfSSadaf Ebrahimi     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
3642*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3643*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.baseArrayLayer = 0;
3644*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.baseMipLevel = 0;
3645*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.layerCount = 1;
3646*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.levelCount = 1;
3647*b7893ccfSSadaf Ebrahimi 
3648*b7893ccfSSadaf Ebrahimi     {
3649*b7893ccfSSadaf Ebrahimi         VkImageObj img_color(m_device);
3650*b7893ccfSSadaf Ebrahimi         img_color.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
3651*b7893ccfSSadaf Ebrahimi         ASSERT_TRUE(img_color.initialized());
3652*b7893ccfSSadaf Ebrahimi 
3653*b7893ccfSSadaf Ebrahimi         VkImageObj img_ds1(m_device);
3654*b7893ccfSSadaf Ebrahimi         img_ds1.Init(128, 128, 1, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
3655*b7893ccfSSadaf Ebrahimi         ASSERT_TRUE(img_ds1.initialized());
3656*b7893ccfSSadaf Ebrahimi 
3657*b7893ccfSSadaf Ebrahimi         VkImageObj img_ds2(m_device);
3658*b7893ccfSSadaf Ebrahimi         img_ds2.Init(128, 128, 1, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
3659*b7893ccfSSadaf Ebrahimi         ASSERT_TRUE(img_ds2.initialized());
3660*b7893ccfSSadaf Ebrahimi 
3661*b7893ccfSSadaf Ebrahimi         VkImageObj img_xfer_src(m_device);
3662*b7893ccfSSadaf Ebrahimi         img_xfer_src.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_OPTIMAL);
3663*b7893ccfSSadaf Ebrahimi         ASSERT_TRUE(img_xfer_src.initialized());
3664*b7893ccfSSadaf Ebrahimi 
3665*b7893ccfSSadaf Ebrahimi         VkImageObj img_xfer_dst(m_device);
3666*b7893ccfSSadaf Ebrahimi         img_xfer_dst.Init(128, 128, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
3667*b7893ccfSSadaf Ebrahimi         ASSERT_TRUE(img_xfer_dst.initialized());
3668*b7893ccfSSadaf Ebrahimi 
3669*b7893ccfSSadaf Ebrahimi         VkImageObj img_sampled(m_device);
3670*b7893ccfSSadaf Ebrahimi         img_sampled.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL);
3671*b7893ccfSSadaf Ebrahimi         ASSERT_TRUE(img_sampled.initialized());
3672*b7893ccfSSadaf Ebrahimi 
3673*b7893ccfSSadaf Ebrahimi         VkImageObj img_input(m_device);
3674*b7893ccfSSadaf Ebrahimi         img_input.Init(128, 128, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL);
3675*b7893ccfSSadaf Ebrahimi         ASSERT_TRUE(img_input.initialized());
3676*b7893ccfSSadaf Ebrahimi 
3677*b7893ccfSSadaf Ebrahimi         const struct {
3678*b7893ccfSSadaf Ebrahimi             VkImageObj &image_obj;
3679*b7893ccfSSadaf Ebrahimi             VkImageLayout old_layout;
3680*b7893ccfSSadaf Ebrahimi             VkImageLayout new_layout;
3681*b7893ccfSSadaf Ebrahimi         } buffer_layouts[] = {
3682*b7893ccfSSadaf Ebrahimi             // clang-format off
3683*b7893ccfSSadaf Ebrahimi             {img_color,    VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,         VK_IMAGE_LAYOUT_GENERAL},
3684*b7893ccfSSadaf Ebrahimi             {img_ds1,      VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL},
3685*b7893ccfSSadaf Ebrahimi             {img_ds2,      VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,  VK_IMAGE_LAYOUT_GENERAL},
3686*b7893ccfSSadaf Ebrahimi             {img_sampled,  VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,         VK_IMAGE_LAYOUT_GENERAL},
3687*b7893ccfSSadaf Ebrahimi             {img_input,    VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,         VK_IMAGE_LAYOUT_GENERAL},
3688*b7893ccfSSadaf Ebrahimi             {img_xfer_src, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,             VK_IMAGE_LAYOUT_GENERAL},
3689*b7893ccfSSadaf Ebrahimi             {img_xfer_dst, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,             VK_IMAGE_LAYOUT_GENERAL},
3690*b7893ccfSSadaf Ebrahimi             // clang-format on
3691*b7893ccfSSadaf Ebrahimi         };
3692*b7893ccfSSadaf Ebrahimi         const uint32_t layout_count = sizeof(buffer_layouts) / sizeof(buffer_layouts[0]);
3693*b7893ccfSSadaf Ebrahimi 
3694*b7893ccfSSadaf Ebrahimi         m_commandBuffer->begin();
3695*b7893ccfSSadaf Ebrahimi         for (uint32_t i = 0; i < layout_count; ++i) {
3696*b7893ccfSSadaf Ebrahimi             img_barrier.image = buffer_layouts[i].image_obj.handle();
3697*b7893ccfSSadaf Ebrahimi             const VkImageUsageFlags usage = buffer_layouts[i].image_obj.usage();
3698*b7893ccfSSadaf Ebrahimi             img_barrier.subresourceRange.aspectMask = (usage == VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
3699*b7893ccfSSadaf Ebrahimi                                                           ? (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)
3700*b7893ccfSSadaf Ebrahimi                                                           : VK_IMAGE_ASPECT_COLOR_BIT;
3701*b7893ccfSSadaf Ebrahimi 
3702*b7893ccfSSadaf Ebrahimi             img_barrier.oldLayout = buffer_layouts[i].old_layout;
3703*b7893ccfSSadaf Ebrahimi             img_barrier.newLayout = buffer_layouts[i].new_layout;
3704*b7893ccfSSadaf Ebrahimi             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
3705*b7893ccfSSadaf Ebrahimi                                  nullptr, 0, nullptr, 1, &img_barrier);
3706*b7893ccfSSadaf Ebrahimi 
3707*b7893ccfSSadaf Ebrahimi             img_barrier.oldLayout = buffer_layouts[i].new_layout;
3708*b7893ccfSSadaf Ebrahimi             img_barrier.newLayout = buffer_layouts[i].old_layout;
3709*b7893ccfSSadaf Ebrahimi             vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0,
3710*b7893ccfSSadaf Ebrahimi                                  nullptr, 0, nullptr, 1, &img_barrier);
3711*b7893ccfSSadaf Ebrahimi         }
3712*b7893ccfSSadaf Ebrahimi         m_commandBuffer->end();
3713*b7893ccfSSadaf Ebrahimi 
3714*b7893ccfSSadaf Ebrahimi         img_barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
3715*b7893ccfSSadaf Ebrahimi         img_barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
3716*b7893ccfSSadaf Ebrahimi     }
3717*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
3718*b7893ccfSSadaf Ebrahimi }
3719*b7893ccfSSadaf Ebrahimi 
3720*b7893ccfSSadaf Ebrahimi // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,WaitEventThenSet)3721*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, WaitEventThenSet) {
3722*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Wait on a event then set it after the wait has been submitted.");
3723*b7893ccfSSadaf Ebrahimi 
3724*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
3725*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
3726*b7893ccfSSadaf Ebrahimi 
3727*b7893ccfSSadaf Ebrahimi     VkEvent event;
3728*b7893ccfSSadaf Ebrahimi     VkEventCreateInfo event_create_info{};
3729*b7893ccfSSadaf Ebrahimi     event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
3730*b7893ccfSSadaf Ebrahimi     vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
3731*b7893ccfSSadaf Ebrahimi 
3732*b7893ccfSSadaf Ebrahimi     VkCommandPool command_pool;
3733*b7893ccfSSadaf Ebrahimi     VkCommandPoolCreateInfo pool_create_info{};
3734*b7893ccfSSadaf Ebrahimi     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
3735*b7893ccfSSadaf Ebrahimi     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
3736*b7893ccfSSadaf Ebrahimi     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
3737*b7893ccfSSadaf Ebrahimi     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
3738*b7893ccfSSadaf Ebrahimi 
3739*b7893ccfSSadaf Ebrahimi     VkCommandBuffer command_buffer;
3740*b7893ccfSSadaf Ebrahimi     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
3741*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
3742*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandPool = command_pool;
3743*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandBufferCount = 1;
3744*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
3745*b7893ccfSSadaf Ebrahimi     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
3746*b7893ccfSSadaf Ebrahimi 
3747*b7893ccfSSadaf Ebrahimi     VkQueue queue = VK_NULL_HANDLE;
3748*b7893ccfSSadaf Ebrahimi     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
3749*b7893ccfSSadaf Ebrahimi 
3750*b7893ccfSSadaf Ebrahimi     {
3751*b7893ccfSSadaf Ebrahimi         VkCommandBufferBeginInfo begin_info{};
3752*b7893ccfSSadaf Ebrahimi         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
3753*b7893ccfSSadaf Ebrahimi         vkBeginCommandBuffer(command_buffer, &begin_info);
3754*b7893ccfSSadaf Ebrahimi 
3755*b7893ccfSSadaf Ebrahimi         vkCmdWaitEvents(command_buffer, 1, &event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0,
3756*b7893ccfSSadaf Ebrahimi                         nullptr, 0, nullptr);
3757*b7893ccfSSadaf Ebrahimi         vkCmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
3758*b7893ccfSSadaf Ebrahimi         vkEndCommandBuffer(command_buffer);
3759*b7893ccfSSadaf Ebrahimi     }
3760*b7893ccfSSadaf Ebrahimi     {
3761*b7893ccfSSadaf Ebrahimi         VkSubmitInfo submit_info{};
3762*b7893ccfSSadaf Ebrahimi         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
3763*b7893ccfSSadaf Ebrahimi         submit_info.commandBufferCount = 1;
3764*b7893ccfSSadaf Ebrahimi         submit_info.pCommandBuffers = &command_buffer;
3765*b7893ccfSSadaf Ebrahimi         submit_info.signalSemaphoreCount = 0;
3766*b7893ccfSSadaf Ebrahimi         submit_info.pSignalSemaphores = nullptr;
3767*b7893ccfSSadaf Ebrahimi         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
3768*b7893ccfSSadaf Ebrahimi     }
3769*b7893ccfSSadaf Ebrahimi     { vkSetEvent(m_device->device(), event); }
3770*b7893ccfSSadaf Ebrahimi 
3771*b7893ccfSSadaf Ebrahimi     vkQueueWaitIdle(queue);
3772*b7893ccfSSadaf Ebrahimi 
3773*b7893ccfSSadaf Ebrahimi     vkDestroyEvent(m_device->device(), event, nullptr);
3774*b7893ccfSSadaf Ebrahimi     vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
3775*b7893ccfSSadaf Ebrahimi     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
3776*b7893ccfSSadaf Ebrahimi 
3777*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
3778*b7893ccfSSadaf Ebrahimi }
3779*b7893ccfSSadaf Ebrahimi // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,QueryAndCopySecondaryCommandBuffers)3780*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, QueryAndCopySecondaryCommandBuffers) {
3781*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Issue a query on a secondary command buffer and copy it on a primary.");
3782*b7893ccfSSadaf Ebrahimi 
3783*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
3784*b7893ccfSSadaf Ebrahimi     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
3785*b7893ccfSSadaf Ebrahimi         printf("%s Queue family needs to have multiple queues to run this test.\n", kSkipPrefix);
3786*b7893ccfSSadaf Ebrahimi         return;
3787*b7893ccfSSadaf Ebrahimi     }
3788*b7893ccfSSadaf Ebrahimi 
3789*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
3790*b7893ccfSSadaf Ebrahimi 
3791*b7893ccfSSadaf Ebrahimi     VkQueryPool query_pool;
3792*b7893ccfSSadaf Ebrahimi     VkQueryPoolCreateInfo query_pool_create_info{};
3793*b7893ccfSSadaf Ebrahimi     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
3794*b7893ccfSSadaf Ebrahimi     query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
3795*b7893ccfSSadaf Ebrahimi     query_pool_create_info.queryCount = 1;
3796*b7893ccfSSadaf Ebrahimi     vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
3797*b7893ccfSSadaf Ebrahimi 
3798*b7893ccfSSadaf Ebrahimi     VkCommandPoolObj command_pool(m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
3799*b7893ccfSSadaf Ebrahimi     VkCommandBufferObj primary_buffer(m_device, &command_pool);
3800*b7893ccfSSadaf Ebrahimi     VkCommandBufferObj secondary_buffer(m_device, &command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
3801*b7893ccfSSadaf Ebrahimi 
3802*b7893ccfSSadaf Ebrahimi     VkQueue queue = VK_NULL_HANDLE;
3803*b7893ccfSSadaf Ebrahimi     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
3804*b7893ccfSSadaf Ebrahimi 
3805*b7893ccfSSadaf Ebrahimi     uint32_t qfi = 0;
3806*b7893ccfSSadaf Ebrahimi     VkBufferCreateInfo buff_create_info = {};
3807*b7893ccfSSadaf Ebrahimi     buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
3808*b7893ccfSSadaf Ebrahimi     buff_create_info.size = 1024;
3809*b7893ccfSSadaf Ebrahimi     buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3810*b7893ccfSSadaf Ebrahimi     buff_create_info.queueFamilyIndexCount = 1;
3811*b7893ccfSSadaf Ebrahimi     buff_create_info.pQueueFamilyIndices = &qfi;
3812*b7893ccfSSadaf Ebrahimi 
3813*b7893ccfSSadaf Ebrahimi     VkBufferObj buffer;
3814*b7893ccfSSadaf Ebrahimi     buffer.init(*m_device, buff_create_info);
3815*b7893ccfSSadaf Ebrahimi 
3816*b7893ccfSSadaf Ebrahimi     VkCommandBufferInheritanceInfo hinfo = {};
3817*b7893ccfSSadaf Ebrahimi     hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
3818*b7893ccfSSadaf Ebrahimi     hinfo.renderPass = VK_NULL_HANDLE;
3819*b7893ccfSSadaf Ebrahimi     hinfo.subpass = 0;
3820*b7893ccfSSadaf Ebrahimi     hinfo.framebuffer = VK_NULL_HANDLE;
3821*b7893ccfSSadaf Ebrahimi     hinfo.occlusionQueryEnable = VK_FALSE;
3822*b7893ccfSSadaf Ebrahimi     hinfo.queryFlags = 0;
3823*b7893ccfSSadaf Ebrahimi     hinfo.pipelineStatistics = 0;
3824*b7893ccfSSadaf Ebrahimi 
3825*b7893ccfSSadaf Ebrahimi     {
3826*b7893ccfSSadaf Ebrahimi         VkCommandBufferBeginInfo begin_info{};
3827*b7893ccfSSadaf Ebrahimi         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
3828*b7893ccfSSadaf Ebrahimi         begin_info.pInheritanceInfo = &hinfo;
3829*b7893ccfSSadaf Ebrahimi         secondary_buffer.begin(&begin_info);
3830*b7893ccfSSadaf Ebrahimi         vkCmdResetQueryPool(secondary_buffer.handle(), query_pool, 0, 1);
3831*b7893ccfSSadaf Ebrahimi         vkCmdWriteTimestamp(secondary_buffer.handle(), VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
3832*b7893ccfSSadaf Ebrahimi         secondary_buffer.end();
3833*b7893ccfSSadaf Ebrahimi 
3834*b7893ccfSSadaf Ebrahimi         primary_buffer.begin();
3835*b7893ccfSSadaf Ebrahimi         vkCmdExecuteCommands(primary_buffer.handle(), 1, &secondary_buffer.handle());
3836*b7893ccfSSadaf Ebrahimi         vkCmdCopyQueryPoolResults(primary_buffer.handle(), query_pool, 0, 1, buffer.handle(), 0, 0, VK_QUERY_RESULT_WAIT_BIT);
3837*b7893ccfSSadaf Ebrahimi         primary_buffer.end();
3838*b7893ccfSSadaf Ebrahimi     }
3839*b7893ccfSSadaf Ebrahimi 
3840*b7893ccfSSadaf Ebrahimi     primary_buffer.QueueCommandBuffer();
3841*b7893ccfSSadaf Ebrahimi     vkQueueWaitIdle(queue);
3842*b7893ccfSSadaf Ebrahimi 
3843*b7893ccfSSadaf Ebrahimi     vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
3844*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
3845*b7893ccfSSadaf Ebrahimi }
3846*b7893ccfSSadaf Ebrahimi 
3847*b7893ccfSSadaf Ebrahimi // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,QueryAndCopyMultipleCommandBuffers)3848*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, QueryAndCopyMultipleCommandBuffers) {
3849*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Issue a query and copy from it on a second command buffer.");
3850*b7893ccfSSadaf Ebrahimi 
3851*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
3852*b7893ccfSSadaf Ebrahimi     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
3853*b7893ccfSSadaf Ebrahimi         printf("%s Queue family needs to have multiple queues to run this test.\n", kSkipPrefix);
3854*b7893ccfSSadaf Ebrahimi         return;
3855*b7893ccfSSadaf Ebrahimi     }
3856*b7893ccfSSadaf Ebrahimi 
3857*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
3858*b7893ccfSSadaf Ebrahimi 
3859*b7893ccfSSadaf Ebrahimi     VkQueryPool query_pool;
3860*b7893ccfSSadaf Ebrahimi     VkQueryPoolCreateInfo query_pool_create_info{};
3861*b7893ccfSSadaf Ebrahimi     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
3862*b7893ccfSSadaf Ebrahimi     query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
3863*b7893ccfSSadaf Ebrahimi     query_pool_create_info.queryCount = 1;
3864*b7893ccfSSadaf Ebrahimi     vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
3865*b7893ccfSSadaf Ebrahimi 
3866*b7893ccfSSadaf Ebrahimi     VkCommandPool command_pool;
3867*b7893ccfSSadaf Ebrahimi     VkCommandPoolCreateInfo pool_create_info{};
3868*b7893ccfSSadaf Ebrahimi     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
3869*b7893ccfSSadaf Ebrahimi     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
3870*b7893ccfSSadaf Ebrahimi     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
3871*b7893ccfSSadaf Ebrahimi     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
3872*b7893ccfSSadaf Ebrahimi 
3873*b7893ccfSSadaf Ebrahimi     VkCommandBuffer command_buffer[2];
3874*b7893ccfSSadaf Ebrahimi     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
3875*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
3876*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandPool = command_pool;
3877*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandBufferCount = 2;
3878*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
3879*b7893ccfSSadaf Ebrahimi     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
3880*b7893ccfSSadaf Ebrahimi 
3881*b7893ccfSSadaf Ebrahimi     VkQueue queue = VK_NULL_HANDLE;
3882*b7893ccfSSadaf Ebrahimi     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
3883*b7893ccfSSadaf Ebrahimi 
3884*b7893ccfSSadaf Ebrahimi     uint32_t qfi = 0;
3885*b7893ccfSSadaf Ebrahimi     VkBufferCreateInfo buff_create_info = {};
3886*b7893ccfSSadaf Ebrahimi     buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
3887*b7893ccfSSadaf Ebrahimi     buff_create_info.size = 1024;
3888*b7893ccfSSadaf Ebrahimi     buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
3889*b7893ccfSSadaf Ebrahimi     buff_create_info.queueFamilyIndexCount = 1;
3890*b7893ccfSSadaf Ebrahimi     buff_create_info.pQueueFamilyIndices = &qfi;
3891*b7893ccfSSadaf Ebrahimi 
3892*b7893ccfSSadaf Ebrahimi     VkBufferObj buffer;
3893*b7893ccfSSadaf Ebrahimi     buffer.init(*m_device, buff_create_info);
3894*b7893ccfSSadaf Ebrahimi 
3895*b7893ccfSSadaf Ebrahimi     {
3896*b7893ccfSSadaf Ebrahimi         VkCommandBufferBeginInfo begin_info{};
3897*b7893ccfSSadaf Ebrahimi         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
3898*b7893ccfSSadaf Ebrahimi         vkBeginCommandBuffer(command_buffer[0], &begin_info);
3899*b7893ccfSSadaf Ebrahimi 
3900*b7893ccfSSadaf Ebrahimi         vkCmdResetQueryPool(command_buffer[0], query_pool, 0, 1);
3901*b7893ccfSSadaf Ebrahimi         vkCmdWriteTimestamp(command_buffer[0], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
3902*b7893ccfSSadaf Ebrahimi 
3903*b7893ccfSSadaf Ebrahimi         vkEndCommandBuffer(command_buffer[0]);
3904*b7893ccfSSadaf Ebrahimi 
3905*b7893ccfSSadaf Ebrahimi         vkBeginCommandBuffer(command_buffer[1], &begin_info);
3906*b7893ccfSSadaf Ebrahimi 
3907*b7893ccfSSadaf Ebrahimi         vkCmdCopyQueryPoolResults(command_buffer[1], query_pool, 0, 1, buffer.handle(), 0, 0, VK_QUERY_RESULT_WAIT_BIT);
3908*b7893ccfSSadaf Ebrahimi 
3909*b7893ccfSSadaf Ebrahimi         vkEndCommandBuffer(command_buffer[1]);
3910*b7893ccfSSadaf Ebrahimi     }
3911*b7893ccfSSadaf Ebrahimi     {
3912*b7893ccfSSadaf Ebrahimi         VkSubmitInfo submit_info{};
3913*b7893ccfSSadaf Ebrahimi         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
3914*b7893ccfSSadaf Ebrahimi         submit_info.commandBufferCount = 2;
3915*b7893ccfSSadaf Ebrahimi         submit_info.pCommandBuffers = command_buffer;
3916*b7893ccfSSadaf Ebrahimi         submit_info.signalSemaphoreCount = 0;
3917*b7893ccfSSadaf Ebrahimi         submit_info.pSignalSemaphores = nullptr;
3918*b7893ccfSSadaf Ebrahimi         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
3919*b7893ccfSSadaf Ebrahimi     }
3920*b7893ccfSSadaf Ebrahimi 
3921*b7893ccfSSadaf Ebrahimi     vkQueueWaitIdle(queue);
3922*b7893ccfSSadaf Ebrahimi 
3923*b7893ccfSSadaf Ebrahimi     vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
3924*b7893ccfSSadaf Ebrahimi     vkFreeCommandBuffers(m_device->device(), command_pool, 2, command_buffer);
3925*b7893ccfSSadaf Ebrahimi     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
3926*b7893ccfSSadaf Ebrahimi 
3927*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
3928*b7893ccfSSadaf Ebrahimi }
3929*b7893ccfSSadaf Ebrahimi 
3930*b7893ccfSSadaf Ebrahimi // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,TwoFencesThreeFrames)3931*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, TwoFencesThreeFrames) {
3932*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
3933*b7893ccfSSadaf Ebrahimi         "Two command buffers with two separate fences are each run through a Submit & WaitForFences cycle 3 times. This previously "
3934*b7893ccfSSadaf Ebrahimi         "revealed a bug so running this positive test to prevent a regression.");
3935*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
3936*b7893ccfSSadaf Ebrahimi 
3937*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
3938*b7893ccfSSadaf Ebrahimi     VkQueue queue = VK_NULL_HANDLE;
3939*b7893ccfSSadaf Ebrahimi     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
3940*b7893ccfSSadaf Ebrahimi 
3941*b7893ccfSSadaf Ebrahimi     static const uint32_t NUM_OBJECTS = 2;
3942*b7893ccfSSadaf Ebrahimi     static const uint32_t NUM_FRAMES = 3;
3943*b7893ccfSSadaf Ebrahimi     VkCommandBuffer cmd_buffers[NUM_OBJECTS] = {};
3944*b7893ccfSSadaf Ebrahimi     VkFence fences[NUM_OBJECTS] = {};
3945*b7893ccfSSadaf Ebrahimi 
3946*b7893ccfSSadaf Ebrahimi     VkCommandPool cmd_pool;
3947*b7893ccfSSadaf Ebrahimi     VkCommandPoolCreateInfo cmd_pool_ci = {};
3948*b7893ccfSSadaf Ebrahimi     cmd_pool_ci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
3949*b7893ccfSSadaf Ebrahimi     cmd_pool_ci.queueFamilyIndex = m_device->graphics_queue_node_index_;
3950*b7893ccfSSadaf Ebrahimi     cmd_pool_ci.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
3951*b7893ccfSSadaf Ebrahimi     VkResult err = vkCreateCommandPool(m_device->device(), &cmd_pool_ci, nullptr, &cmd_pool);
3952*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
3953*b7893ccfSSadaf Ebrahimi 
3954*b7893ccfSSadaf Ebrahimi     VkCommandBufferAllocateInfo cmd_buf_info = {};
3955*b7893ccfSSadaf Ebrahimi     cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
3956*b7893ccfSSadaf Ebrahimi     cmd_buf_info.commandPool = cmd_pool;
3957*b7893ccfSSadaf Ebrahimi     cmd_buf_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
3958*b7893ccfSSadaf Ebrahimi     cmd_buf_info.commandBufferCount = 1;
3959*b7893ccfSSadaf Ebrahimi 
3960*b7893ccfSSadaf Ebrahimi     VkFenceCreateInfo fence_ci = {};
3961*b7893ccfSSadaf Ebrahimi     fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
3962*b7893ccfSSadaf Ebrahimi     fence_ci.pNext = nullptr;
3963*b7893ccfSSadaf Ebrahimi     fence_ci.flags = 0;
3964*b7893ccfSSadaf Ebrahimi 
3965*b7893ccfSSadaf Ebrahimi     for (uint32_t i = 0; i < NUM_OBJECTS; ++i) {
3966*b7893ccfSSadaf Ebrahimi         err = vkAllocateCommandBuffers(m_device->device(), &cmd_buf_info, &cmd_buffers[i]);
3967*b7893ccfSSadaf Ebrahimi         ASSERT_VK_SUCCESS(err);
3968*b7893ccfSSadaf Ebrahimi         err = vkCreateFence(m_device->device(), &fence_ci, nullptr, &fences[i]);
3969*b7893ccfSSadaf Ebrahimi         ASSERT_VK_SUCCESS(err);
3970*b7893ccfSSadaf Ebrahimi     }
3971*b7893ccfSSadaf Ebrahimi 
3972*b7893ccfSSadaf Ebrahimi     for (uint32_t frame = 0; frame < NUM_FRAMES; ++frame) {
3973*b7893ccfSSadaf Ebrahimi         for (uint32_t obj = 0; obj < NUM_OBJECTS; ++obj) {
3974*b7893ccfSSadaf Ebrahimi             // Create empty cmd buffer
3975*b7893ccfSSadaf Ebrahimi             VkCommandBufferBeginInfo cmdBufBeginDesc = {};
3976*b7893ccfSSadaf Ebrahimi             cmdBufBeginDesc.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
3977*b7893ccfSSadaf Ebrahimi 
3978*b7893ccfSSadaf Ebrahimi             err = vkBeginCommandBuffer(cmd_buffers[obj], &cmdBufBeginDesc);
3979*b7893ccfSSadaf Ebrahimi             ASSERT_VK_SUCCESS(err);
3980*b7893ccfSSadaf Ebrahimi             err = vkEndCommandBuffer(cmd_buffers[obj]);
3981*b7893ccfSSadaf Ebrahimi             ASSERT_VK_SUCCESS(err);
3982*b7893ccfSSadaf Ebrahimi 
3983*b7893ccfSSadaf Ebrahimi             VkSubmitInfo submit_info = {};
3984*b7893ccfSSadaf Ebrahimi             submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
3985*b7893ccfSSadaf Ebrahimi             submit_info.commandBufferCount = 1;
3986*b7893ccfSSadaf Ebrahimi             submit_info.pCommandBuffers = &cmd_buffers[obj];
3987*b7893ccfSSadaf Ebrahimi             // Submit cmd buffer and wait for fence
3988*b7893ccfSSadaf Ebrahimi             err = vkQueueSubmit(queue, 1, &submit_info, fences[obj]);
3989*b7893ccfSSadaf Ebrahimi             ASSERT_VK_SUCCESS(err);
3990*b7893ccfSSadaf Ebrahimi             err = vkWaitForFences(m_device->device(), 1, &fences[obj], VK_TRUE, UINT64_MAX);
3991*b7893ccfSSadaf Ebrahimi             ASSERT_VK_SUCCESS(err);
3992*b7893ccfSSadaf Ebrahimi             err = vkResetFences(m_device->device(), 1, &fences[obj]);
3993*b7893ccfSSadaf Ebrahimi             ASSERT_VK_SUCCESS(err);
3994*b7893ccfSSadaf Ebrahimi         }
3995*b7893ccfSSadaf Ebrahimi     }
3996*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
3997*b7893ccfSSadaf Ebrahimi     vkDestroyCommandPool(m_device->device(), cmd_pool, NULL);
3998*b7893ccfSSadaf Ebrahimi     for (uint32_t i = 0; i < NUM_OBJECTS; ++i) {
3999*b7893ccfSSadaf Ebrahimi         vkDestroyFence(m_device->device(), fences[i], nullptr);
4000*b7893ccfSSadaf Ebrahimi     }
4001*b7893ccfSSadaf Ebrahimi }
4002*b7893ccfSSadaf Ebrahimi // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWI)4003*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWI) {
4004*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
4005*b7893ccfSSadaf Ebrahimi         "Two command buffers, each in a separate QueueSubmit call submitted on separate queues followed by a QueueWaitIdle.");
4006*b7893ccfSSadaf Ebrahimi 
4007*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
4008*b7893ccfSSadaf Ebrahimi     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
4009*b7893ccfSSadaf Ebrahimi         printf("%s Queue family needs to have multiple queues to run this test.\n", kSkipPrefix);
4010*b7893ccfSSadaf Ebrahimi         return;
4011*b7893ccfSSadaf Ebrahimi     }
4012*b7893ccfSSadaf Ebrahimi 
4013*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
4014*b7893ccfSSadaf Ebrahimi 
4015*b7893ccfSSadaf Ebrahimi     VkSemaphore semaphore;
4016*b7893ccfSSadaf Ebrahimi     VkSemaphoreCreateInfo semaphore_create_info{};
4017*b7893ccfSSadaf Ebrahimi     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
4018*b7893ccfSSadaf Ebrahimi     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
4019*b7893ccfSSadaf Ebrahimi 
4020*b7893ccfSSadaf Ebrahimi     VkCommandPool command_pool;
4021*b7893ccfSSadaf Ebrahimi     VkCommandPoolCreateInfo pool_create_info{};
4022*b7893ccfSSadaf Ebrahimi     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
4023*b7893ccfSSadaf Ebrahimi     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
4024*b7893ccfSSadaf Ebrahimi     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
4025*b7893ccfSSadaf Ebrahimi     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
4026*b7893ccfSSadaf Ebrahimi 
4027*b7893ccfSSadaf Ebrahimi     VkCommandBuffer command_buffer[2];
4028*b7893ccfSSadaf Ebrahimi     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
4029*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
4030*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandPool = command_pool;
4031*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandBufferCount = 2;
4032*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
4033*b7893ccfSSadaf Ebrahimi     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
4034*b7893ccfSSadaf Ebrahimi 
4035*b7893ccfSSadaf Ebrahimi     VkQueue queue = VK_NULL_HANDLE;
4036*b7893ccfSSadaf Ebrahimi     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
4037*b7893ccfSSadaf Ebrahimi 
4038*b7893ccfSSadaf Ebrahimi     {
4039*b7893ccfSSadaf Ebrahimi         VkCommandBufferBeginInfo begin_info{};
4040*b7893ccfSSadaf Ebrahimi         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4041*b7893ccfSSadaf Ebrahimi         vkBeginCommandBuffer(command_buffer[0], &begin_info);
4042*b7893ccfSSadaf Ebrahimi 
4043*b7893ccfSSadaf Ebrahimi         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
4044*b7893ccfSSadaf Ebrahimi                              nullptr, 0, nullptr, 0, nullptr);
4045*b7893ccfSSadaf Ebrahimi 
4046*b7893ccfSSadaf Ebrahimi         VkViewport viewport{};
4047*b7893ccfSSadaf Ebrahimi         viewport.maxDepth = 1.0f;
4048*b7893ccfSSadaf Ebrahimi         viewport.minDepth = 0.0f;
4049*b7893ccfSSadaf Ebrahimi         viewport.width = 512;
4050*b7893ccfSSadaf Ebrahimi         viewport.height = 512;
4051*b7893ccfSSadaf Ebrahimi         viewport.x = 0;
4052*b7893ccfSSadaf Ebrahimi         viewport.y = 0;
4053*b7893ccfSSadaf Ebrahimi         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
4054*b7893ccfSSadaf Ebrahimi         vkEndCommandBuffer(command_buffer[0]);
4055*b7893ccfSSadaf Ebrahimi     }
4056*b7893ccfSSadaf Ebrahimi     {
4057*b7893ccfSSadaf Ebrahimi         VkCommandBufferBeginInfo begin_info{};
4058*b7893ccfSSadaf Ebrahimi         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4059*b7893ccfSSadaf Ebrahimi         vkBeginCommandBuffer(command_buffer[1], &begin_info);
4060*b7893ccfSSadaf Ebrahimi 
4061*b7893ccfSSadaf Ebrahimi         VkViewport viewport{};
4062*b7893ccfSSadaf Ebrahimi         viewport.maxDepth = 1.0f;
4063*b7893ccfSSadaf Ebrahimi         viewport.minDepth = 0.0f;
4064*b7893ccfSSadaf Ebrahimi         viewport.width = 512;
4065*b7893ccfSSadaf Ebrahimi         viewport.height = 512;
4066*b7893ccfSSadaf Ebrahimi         viewport.x = 0;
4067*b7893ccfSSadaf Ebrahimi         viewport.y = 0;
4068*b7893ccfSSadaf Ebrahimi         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
4069*b7893ccfSSadaf Ebrahimi         vkEndCommandBuffer(command_buffer[1]);
4070*b7893ccfSSadaf Ebrahimi     }
4071*b7893ccfSSadaf Ebrahimi     {
4072*b7893ccfSSadaf Ebrahimi         VkSubmitInfo submit_info{};
4073*b7893ccfSSadaf Ebrahimi         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4074*b7893ccfSSadaf Ebrahimi         submit_info.commandBufferCount = 1;
4075*b7893ccfSSadaf Ebrahimi         submit_info.pCommandBuffers = &command_buffer[0];
4076*b7893ccfSSadaf Ebrahimi         submit_info.signalSemaphoreCount = 1;
4077*b7893ccfSSadaf Ebrahimi         submit_info.pSignalSemaphores = &semaphore;
4078*b7893ccfSSadaf Ebrahimi         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
4079*b7893ccfSSadaf Ebrahimi     }
4080*b7893ccfSSadaf Ebrahimi     {
4081*b7893ccfSSadaf Ebrahimi         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
4082*b7893ccfSSadaf Ebrahimi         VkSubmitInfo submit_info{};
4083*b7893ccfSSadaf Ebrahimi         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4084*b7893ccfSSadaf Ebrahimi         submit_info.commandBufferCount = 1;
4085*b7893ccfSSadaf Ebrahimi         submit_info.pCommandBuffers = &command_buffer[1];
4086*b7893ccfSSadaf Ebrahimi         submit_info.waitSemaphoreCount = 1;
4087*b7893ccfSSadaf Ebrahimi         submit_info.pWaitSemaphores = &semaphore;
4088*b7893ccfSSadaf Ebrahimi         submit_info.pWaitDstStageMask = flags;
4089*b7893ccfSSadaf Ebrahimi         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
4090*b7893ccfSSadaf Ebrahimi     }
4091*b7893ccfSSadaf Ebrahimi 
4092*b7893ccfSSadaf Ebrahimi     vkQueueWaitIdle(m_device->m_queue);
4093*b7893ccfSSadaf Ebrahimi 
4094*b7893ccfSSadaf Ebrahimi     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
4095*b7893ccfSSadaf Ebrahimi     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
4096*b7893ccfSSadaf Ebrahimi     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
4097*b7893ccfSSadaf Ebrahimi 
4098*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
4099*b7893ccfSSadaf Ebrahimi }
4100*b7893ccfSSadaf Ebrahimi 
4101*b7893ccfSSadaf Ebrahimi // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWIFence)4102*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWIFence) {
4103*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
4104*b7893ccfSSadaf Ebrahimi         "Two command buffers, each in a separate QueueSubmit call submitted on separate queues, the second having a fence followed "
4105*b7893ccfSSadaf Ebrahimi         "by a QueueWaitIdle.");
4106*b7893ccfSSadaf Ebrahimi 
4107*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
4108*b7893ccfSSadaf Ebrahimi     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
4109*b7893ccfSSadaf Ebrahimi         printf("%s Queue family needs to have multiple queues to run this test.\n", kSkipPrefix);
4110*b7893ccfSSadaf Ebrahimi         return;
4111*b7893ccfSSadaf Ebrahimi     }
4112*b7893ccfSSadaf Ebrahimi 
4113*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
4114*b7893ccfSSadaf Ebrahimi 
4115*b7893ccfSSadaf Ebrahimi     VkFence fence;
4116*b7893ccfSSadaf Ebrahimi     VkFenceCreateInfo fence_create_info{};
4117*b7893ccfSSadaf Ebrahimi     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
4118*b7893ccfSSadaf Ebrahimi     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
4119*b7893ccfSSadaf Ebrahimi 
4120*b7893ccfSSadaf Ebrahimi     VkSemaphore semaphore;
4121*b7893ccfSSadaf Ebrahimi     VkSemaphoreCreateInfo semaphore_create_info{};
4122*b7893ccfSSadaf Ebrahimi     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
4123*b7893ccfSSadaf Ebrahimi     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
4124*b7893ccfSSadaf Ebrahimi 
4125*b7893ccfSSadaf Ebrahimi     VkCommandPool command_pool;
4126*b7893ccfSSadaf Ebrahimi     VkCommandPoolCreateInfo pool_create_info{};
4127*b7893ccfSSadaf Ebrahimi     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
4128*b7893ccfSSadaf Ebrahimi     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
4129*b7893ccfSSadaf Ebrahimi     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
4130*b7893ccfSSadaf Ebrahimi     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
4131*b7893ccfSSadaf Ebrahimi 
4132*b7893ccfSSadaf Ebrahimi     VkCommandBuffer command_buffer[2];
4133*b7893ccfSSadaf Ebrahimi     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
4134*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
4135*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandPool = command_pool;
4136*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandBufferCount = 2;
4137*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
4138*b7893ccfSSadaf Ebrahimi     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
4139*b7893ccfSSadaf Ebrahimi 
4140*b7893ccfSSadaf Ebrahimi     VkQueue queue = VK_NULL_HANDLE;
4141*b7893ccfSSadaf Ebrahimi     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
4142*b7893ccfSSadaf Ebrahimi 
4143*b7893ccfSSadaf Ebrahimi     {
4144*b7893ccfSSadaf Ebrahimi         VkCommandBufferBeginInfo begin_info{};
4145*b7893ccfSSadaf Ebrahimi         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4146*b7893ccfSSadaf Ebrahimi         vkBeginCommandBuffer(command_buffer[0], &begin_info);
4147*b7893ccfSSadaf Ebrahimi 
4148*b7893ccfSSadaf Ebrahimi         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
4149*b7893ccfSSadaf Ebrahimi                              nullptr, 0, nullptr, 0, nullptr);
4150*b7893ccfSSadaf Ebrahimi 
4151*b7893ccfSSadaf Ebrahimi         VkViewport viewport{};
4152*b7893ccfSSadaf Ebrahimi         viewport.maxDepth = 1.0f;
4153*b7893ccfSSadaf Ebrahimi         viewport.minDepth = 0.0f;
4154*b7893ccfSSadaf Ebrahimi         viewport.width = 512;
4155*b7893ccfSSadaf Ebrahimi         viewport.height = 512;
4156*b7893ccfSSadaf Ebrahimi         viewport.x = 0;
4157*b7893ccfSSadaf Ebrahimi         viewport.y = 0;
4158*b7893ccfSSadaf Ebrahimi         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
4159*b7893ccfSSadaf Ebrahimi         vkEndCommandBuffer(command_buffer[0]);
4160*b7893ccfSSadaf Ebrahimi     }
4161*b7893ccfSSadaf Ebrahimi     {
4162*b7893ccfSSadaf Ebrahimi         VkCommandBufferBeginInfo begin_info{};
4163*b7893ccfSSadaf Ebrahimi         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4164*b7893ccfSSadaf Ebrahimi         vkBeginCommandBuffer(command_buffer[1], &begin_info);
4165*b7893ccfSSadaf Ebrahimi 
4166*b7893ccfSSadaf Ebrahimi         VkViewport viewport{};
4167*b7893ccfSSadaf Ebrahimi         viewport.maxDepth = 1.0f;
4168*b7893ccfSSadaf Ebrahimi         viewport.minDepth = 0.0f;
4169*b7893ccfSSadaf Ebrahimi         viewport.width = 512;
4170*b7893ccfSSadaf Ebrahimi         viewport.height = 512;
4171*b7893ccfSSadaf Ebrahimi         viewport.x = 0;
4172*b7893ccfSSadaf Ebrahimi         viewport.y = 0;
4173*b7893ccfSSadaf Ebrahimi         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
4174*b7893ccfSSadaf Ebrahimi         vkEndCommandBuffer(command_buffer[1]);
4175*b7893ccfSSadaf Ebrahimi     }
4176*b7893ccfSSadaf Ebrahimi     {
4177*b7893ccfSSadaf Ebrahimi         VkSubmitInfo submit_info{};
4178*b7893ccfSSadaf Ebrahimi         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4179*b7893ccfSSadaf Ebrahimi         submit_info.commandBufferCount = 1;
4180*b7893ccfSSadaf Ebrahimi         submit_info.pCommandBuffers = &command_buffer[0];
4181*b7893ccfSSadaf Ebrahimi         submit_info.signalSemaphoreCount = 1;
4182*b7893ccfSSadaf Ebrahimi         submit_info.pSignalSemaphores = &semaphore;
4183*b7893ccfSSadaf Ebrahimi         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
4184*b7893ccfSSadaf Ebrahimi     }
4185*b7893ccfSSadaf Ebrahimi     {
4186*b7893ccfSSadaf Ebrahimi         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
4187*b7893ccfSSadaf Ebrahimi         VkSubmitInfo submit_info{};
4188*b7893ccfSSadaf Ebrahimi         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4189*b7893ccfSSadaf Ebrahimi         submit_info.commandBufferCount = 1;
4190*b7893ccfSSadaf Ebrahimi         submit_info.pCommandBuffers = &command_buffer[1];
4191*b7893ccfSSadaf Ebrahimi         submit_info.waitSemaphoreCount = 1;
4192*b7893ccfSSadaf Ebrahimi         submit_info.pWaitSemaphores = &semaphore;
4193*b7893ccfSSadaf Ebrahimi         submit_info.pWaitDstStageMask = flags;
4194*b7893ccfSSadaf Ebrahimi         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
4195*b7893ccfSSadaf Ebrahimi     }
4196*b7893ccfSSadaf Ebrahimi 
4197*b7893ccfSSadaf Ebrahimi     vkQueueWaitIdle(m_device->m_queue);
4198*b7893ccfSSadaf Ebrahimi 
4199*b7893ccfSSadaf Ebrahimi     vkDestroyFence(m_device->device(), fence, nullptr);
4200*b7893ccfSSadaf Ebrahimi     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
4201*b7893ccfSSadaf Ebrahimi     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
4202*b7893ccfSSadaf Ebrahimi     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
4203*b7893ccfSSadaf Ebrahimi 
4204*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
4205*b7893ccfSSadaf Ebrahimi }
4206*b7893ccfSSadaf Ebrahimi 
4207*b7893ccfSSadaf Ebrahimi // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceTwoWFF)4208*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceTwoWFF) {
4209*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
4210*b7893ccfSSadaf Ebrahimi         "Two command buffers, each in a separate QueueSubmit call submitted on separate queues, the second having a fence followed "
4211*b7893ccfSSadaf Ebrahimi         "by two consecutive WaitForFences calls on the same fence.");
4212*b7893ccfSSadaf Ebrahimi 
4213*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
4214*b7893ccfSSadaf Ebrahimi     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
4215*b7893ccfSSadaf Ebrahimi         printf("%s Queue family needs to have multiple queues to run this test.\n", kSkipPrefix);
4216*b7893ccfSSadaf Ebrahimi         return;
4217*b7893ccfSSadaf Ebrahimi     }
4218*b7893ccfSSadaf Ebrahimi 
4219*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
4220*b7893ccfSSadaf Ebrahimi 
4221*b7893ccfSSadaf Ebrahimi     VkFence fence;
4222*b7893ccfSSadaf Ebrahimi     VkFenceCreateInfo fence_create_info{};
4223*b7893ccfSSadaf Ebrahimi     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
4224*b7893ccfSSadaf Ebrahimi     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
4225*b7893ccfSSadaf Ebrahimi 
4226*b7893ccfSSadaf Ebrahimi     VkSemaphore semaphore;
4227*b7893ccfSSadaf Ebrahimi     VkSemaphoreCreateInfo semaphore_create_info{};
4228*b7893ccfSSadaf Ebrahimi     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
4229*b7893ccfSSadaf Ebrahimi     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
4230*b7893ccfSSadaf Ebrahimi 
4231*b7893ccfSSadaf Ebrahimi     VkCommandPool command_pool;
4232*b7893ccfSSadaf Ebrahimi     VkCommandPoolCreateInfo pool_create_info{};
4233*b7893ccfSSadaf Ebrahimi     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
4234*b7893ccfSSadaf Ebrahimi     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
4235*b7893ccfSSadaf Ebrahimi     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
4236*b7893ccfSSadaf Ebrahimi     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
4237*b7893ccfSSadaf Ebrahimi 
4238*b7893ccfSSadaf Ebrahimi     VkCommandBuffer command_buffer[2];
4239*b7893ccfSSadaf Ebrahimi     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
4240*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
4241*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandPool = command_pool;
4242*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandBufferCount = 2;
4243*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
4244*b7893ccfSSadaf Ebrahimi     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
4245*b7893ccfSSadaf Ebrahimi 
4246*b7893ccfSSadaf Ebrahimi     VkQueue queue = VK_NULL_HANDLE;
4247*b7893ccfSSadaf Ebrahimi     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
4248*b7893ccfSSadaf Ebrahimi 
4249*b7893ccfSSadaf Ebrahimi     {
4250*b7893ccfSSadaf Ebrahimi         VkCommandBufferBeginInfo begin_info{};
4251*b7893ccfSSadaf Ebrahimi         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4252*b7893ccfSSadaf Ebrahimi         vkBeginCommandBuffer(command_buffer[0], &begin_info);
4253*b7893ccfSSadaf Ebrahimi 
4254*b7893ccfSSadaf Ebrahimi         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
4255*b7893ccfSSadaf Ebrahimi                              nullptr, 0, nullptr, 0, nullptr);
4256*b7893ccfSSadaf Ebrahimi 
4257*b7893ccfSSadaf Ebrahimi         VkViewport viewport{};
4258*b7893ccfSSadaf Ebrahimi         viewport.maxDepth = 1.0f;
4259*b7893ccfSSadaf Ebrahimi         viewport.minDepth = 0.0f;
4260*b7893ccfSSadaf Ebrahimi         viewport.width = 512;
4261*b7893ccfSSadaf Ebrahimi         viewport.height = 512;
4262*b7893ccfSSadaf Ebrahimi         viewport.x = 0;
4263*b7893ccfSSadaf Ebrahimi         viewport.y = 0;
4264*b7893ccfSSadaf Ebrahimi         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
4265*b7893ccfSSadaf Ebrahimi         vkEndCommandBuffer(command_buffer[0]);
4266*b7893ccfSSadaf Ebrahimi     }
4267*b7893ccfSSadaf Ebrahimi     {
4268*b7893ccfSSadaf Ebrahimi         VkCommandBufferBeginInfo begin_info{};
4269*b7893ccfSSadaf Ebrahimi         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4270*b7893ccfSSadaf Ebrahimi         vkBeginCommandBuffer(command_buffer[1], &begin_info);
4271*b7893ccfSSadaf Ebrahimi 
4272*b7893ccfSSadaf Ebrahimi         VkViewport viewport{};
4273*b7893ccfSSadaf Ebrahimi         viewport.maxDepth = 1.0f;
4274*b7893ccfSSadaf Ebrahimi         viewport.minDepth = 0.0f;
4275*b7893ccfSSadaf Ebrahimi         viewport.width = 512;
4276*b7893ccfSSadaf Ebrahimi         viewport.height = 512;
4277*b7893ccfSSadaf Ebrahimi         viewport.x = 0;
4278*b7893ccfSSadaf Ebrahimi         viewport.y = 0;
4279*b7893ccfSSadaf Ebrahimi         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
4280*b7893ccfSSadaf Ebrahimi         vkEndCommandBuffer(command_buffer[1]);
4281*b7893ccfSSadaf Ebrahimi     }
4282*b7893ccfSSadaf Ebrahimi     {
4283*b7893ccfSSadaf Ebrahimi         VkSubmitInfo submit_info{};
4284*b7893ccfSSadaf Ebrahimi         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4285*b7893ccfSSadaf Ebrahimi         submit_info.commandBufferCount = 1;
4286*b7893ccfSSadaf Ebrahimi         submit_info.pCommandBuffers = &command_buffer[0];
4287*b7893ccfSSadaf Ebrahimi         submit_info.signalSemaphoreCount = 1;
4288*b7893ccfSSadaf Ebrahimi         submit_info.pSignalSemaphores = &semaphore;
4289*b7893ccfSSadaf Ebrahimi         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
4290*b7893ccfSSadaf Ebrahimi     }
4291*b7893ccfSSadaf Ebrahimi     {
4292*b7893ccfSSadaf Ebrahimi         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
4293*b7893ccfSSadaf Ebrahimi         VkSubmitInfo submit_info{};
4294*b7893ccfSSadaf Ebrahimi         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4295*b7893ccfSSadaf Ebrahimi         submit_info.commandBufferCount = 1;
4296*b7893ccfSSadaf Ebrahimi         submit_info.pCommandBuffers = &command_buffer[1];
4297*b7893ccfSSadaf Ebrahimi         submit_info.waitSemaphoreCount = 1;
4298*b7893ccfSSadaf Ebrahimi         submit_info.pWaitSemaphores = &semaphore;
4299*b7893ccfSSadaf Ebrahimi         submit_info.pWaitDstStageMask = flags;
4300*b7893ccfSSadaf Ebrahimi         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
4301*b7893ccfSSadaf Ebrahimi     }
4302*b7893ccfSSadaf Ebrahimi 
4303*b7893ccfSSadaf Ebrahimi     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
4304*b7893ccfSSadaf Ebrahimi     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
4305*b7893ccfSSadaf Ebrahimi 
4306*b7893ccfSSadaf Ebrahimi     vkDestroyFence(m_device->device(), fence, nullptr);
4307*b7893ccfSSadaf Ebrahimi     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
4308*b7893ccfSSadaf Ebrahimi     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
4309*b7893ccfSSadaf Ebrahimi     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
4310*b7893ccfSSadaf Ebrahimi 
4311*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
4312*b7893ccfSSadaf Ebrahimi }
4313*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,TwoQueuesEnsureCorrectRetirementWithWorkStolen)4314*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, TwoQueuesEnsureCorrectRetirementWithWorkStolen) {
4315*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
4316*b7893ccfSSadaf Ebrahimi     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
4317*b7893ccfSSadaf Ebrahimi         printf("%s Test requires two queues, skipping\n", kSkipPrefix);
4318*b7893ccfSSadaf Ebrahimi         return;
4319*b7893ccfSSadaf Ebrahimi     }
4320*b7893ccfSSadaf Ebrahimi 
4321*b7893ccfSSadaf Ebrahimi     VkResult err;
4322*b7893ccfSSadaf Ebrahimi 
4323*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
4324*b7893ccfSSadaf Ebrahimi 
4325*b7893ccfSSadaf Ebrahimi     VkQueue q0 = m_device->m_queue;
4326*b7893ccfSSadaf Ebrahimi     VkQueue q1 = nullptr;
4327*b7893ccfSSadaf Ebrahimi     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &q1);
4328*b7893ccfSSadaf Ebrahimi     ASSERT_NE(q1, nullptr);
4329*b7893ccfSSadaf Ebrahimi 
4330*b7893ccfSSadaf Ebrahimi     // An (empty) command buffer. We must have work in the first submission --
4331*b7893ccfSSadaf Ebrahimi     // the layer treats unfenced work differently from fenced work.
4332*b7893ccfSSadaf Ebrahimi     VkCommandPoolCreateInfo cpci = {VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, nullptr, 0, 0};
4333*b7893ccfSSadaf Ebrahimi     VkCommandPool pool;
4334*b7893ccfSSadaf Ebrahimi     err = vkCreateCommandPool(m_device->device(), &cpci, nullptr, &pool);
4335*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
4336*b7893ccfSSadaf Ebrahimi     VkCommandBufferAllocateInfo cbai = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, nullptr, pool,
4337*b7893ccfSSadaf Ebrahimi                                         VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1};
4338*b7893ccfSSadaf Ebrahimi     VkCommandBuffer cb;
4339*b7893ccfSSadaf Ebrahimi     err = vkAllocateCommandBuffers(m_device->device(), &cbai, &cb);
4340*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
4341*b7893ccfSSadaf Ebrahimi     VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, nullptr};
4342*b7893ccfSSadaf Ebrahimi     err = vkBeginCommandBuffer(cb, &cbbi);
4343*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
4344*b7893ccfSSadaf Ebrahimi     err = vkEndCommandBuffer(cb);
4345*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
4346*b7893ccfSSadaf Ebrahimi 
4347*b7893ccfSSadaf Ebrahimi     // A semaphore
4348*b7893ccfSSadaf Ebrahimi     VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
4349*b7893ccfSSadaf Ebrahimi     VkSemaphore s;
4350*b7893ccfSSadaf Ebrahimi     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s);
4351*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
4352*b7893ccfSSadaf Ebrahimi 
4353*b7893ccfSSadaf Ebrahimi     // First submission, to q0
4354*b7893ccfSSadaf Ebrahimi     VkSubmitInfo s0 = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &cb, 1, &s};
4355*b7893ccfSSadaf Ebrahimi 
4356*b7893ccfSSadaf Ebrahimi     err = vkQueueSubmit(q0, 1, &s0, VK_NULL_HANDLE);
4357*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
4358*b7893ccfSSadaf Ebrahimi 
4359*b7893ccfSSadaf Ebrahimi     // Second submission, to q1, waiting on s
4360*b7893ccfSSadaf Ebrahimi     VkFlags waitmask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;  // doesn't really matter what this value is.
4361*b7893ccfSSadaf Ebrahimi     VkSubmitInfo s1 = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &s, &waitmask, 0, nullptr, 0, nullptr};
4362*b7893ccfSSadaf Ebrahimi 
4363*b7893ccfSSadaf Ebrahimi     err = vkQueueSubmit(q1, 1, &s1, VK_NULL_HANDLE);
4364*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
4365*b7893ccfSSadaf Ebrahimi 
4366*b7893ccfSSadaf Ebrahimi     // Wait for q0 idle
4367*b7893ccfSSadaf Ebrahimi     err = vkQueueWaitIdle(q0);
4368*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
4369*b7893ccfSSadaf Ebrahimi 
4370*b7893ccfSSadaf Ebrahimi     // Command buffer should have been completed (it was on q0); reset the pool.
4371*b7893ccfSSadaf Ebrahimi     vkFreeCommandBuffers(m_device->device(), pool, 1, &cb);
4372*b7893ccfSSadaf Ebrahimi 
4373*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
4374*b7893ccfSSadaf Ebrahimi 
4375*b7893ccfSSadaf Ebrahimi     // Force device completely idle and clean up resources
4376*b7893ccfSSadaf Ebrahimi     vkDeviceWaitIdle(m_device->device());
4377*b7893ccfSSadaf Ebrahimi     vkDestroyCommandPool(m_device->device(), pool, nullptr);
4378*b7893ccfSSadaf Ebrahimi     vkDestroySemaphore(m_device->device(), s, nullptr);
4379*b7893ccfSSadaf Ebrahimi }
4380*b7893ccfSSadaf Ebrahimi 
4381*b7893ccfSSadaf Ebrahimi // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFence)4382*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFence) {
4383*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
4384*b7893ccfSSadaf Ebrahimi         "Two command buffers, each in a separate QueueSubmit call submitted on separate queues, the second having a fence, "
4385*b7893ccfSSadaf Ebrahimi         "followed by a WaitForFences call.");
4386*b7893ccfSSadaf Ebrahimi 
4387*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
4388*b7893ccfSSadaf Ebrahimi     if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
4389*b7893ccfSSadaf Ebrahimi         printf("%s Queue family needs to have multiple queues to run this test.\n", kSkipPrefix);
4390*b7893ccfSSadaf Ebrahimi         return;
4391*b7893ccfSSadaf Ebrahimi     }
4392*b7893ccfSSadaf Ebrahimi 
4393*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
4394*b7893ccfSSadaf Ebrahimi 
4395*b7893ccfSSadaf Ebrahimi     VkFence fence;
4396*b7893ccfSSadaf Ebrahimi     VkFenceCreateInfo fence_create_info{};
4397*b7893ccfSSadaf Ebrahimi     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
4398*b7893ccfSSadaf Ebrahimi     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
4399*b7893ccfSSadaf Ebrahimi 
4400*b7893ccfSSadaf Ebrahimi     VkSemaphore semaphore;
4401*b7893ccfSSadaf Ebrahimi     VkSemaphoreCreateInfo semaphore_create_info{};
4402*b7893ccfSSadaf Ebrahimi     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
4403*b7893ccfSSadaf Ebrahimi     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
4404*b7893ccfSSadaf Ebrahimi 
4405*b7893ccfSSadaf Ebrahimi     VkCommandPool command_pool;
4406*b7893ccfSSadaf Ebrahimi     VkCommandPoolCreateInfo pool_create_info{};
4407*b7893ccfSSadaf Ebrahimi     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
4408*b7893ccfSSadaf Ebrahimi     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
4409*b7893ccfSSadaf Ebrahimi     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
4410*b7893ccfSSadaf Ebrahimi     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
4411*b7893ccfSSadaf Ebrahimi 
4412*b7893ccfSSadaf Ebrahimi     VkCommandBuffer command_buffer[2];
4413*b7893ccfSSadaf Ebrahimi     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
4414*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
4415*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandPool = command_pool;
4416*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandBufferCount = 2;
4417*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
4418*b7893ccfSSadaf Ebrahimi     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
4419*b7893ccfSSadaf Ebrahimi 
4420*b7893ccfSSadaf Ebrahimi     VkQueue queue = VK_NULL_HANDLE;
4421*b7893ccfSSadaf Ebrahimi     vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
4422*b7893ccfSSadaf Ebrahimi 
4423*b7893ccfSSadaf Ebrahimi     {
4424*b7893ccfSSadaf Ebrahimi         VkCommandBufferBeginInfo begin_info{};
4425*b7893ccfSSadaf Ebrahimi         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4426*b7893ccfSSadaf Ebrahimi         vkBeginCommandBuffer(command_buffer[0], &begin_info);
4427*b7893ccfSSadaf Ebrahimi 
4428*b7893ccfSSadaf Ebrahimi         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
4429*b7893ccfSSadaf Ebrahimi                              nullptr, 0, nullptr, 0, nullptr);
4430*b7893ccfSSadaf Ebrahimi 
4431*b7893ccfSSadaf Ebrahimi         VkViewport viewport{};
4432*b7893ccfSSadaf Ebrahimi         viewport.maxDepth = 1.0f;
4433*b7893ccfSSadaf Ebrahimi         viewport.minDepth = 0.0f;
4434*b7893ccfSSadaf Ebrahimi         viewport.width = 512;
4435*b7893ccfSSadaf Ebrahimi         viewport.height = 512;
4436*b7893ccfSSadaf Ebrahimi         viewport.x = 0;
4437*b7893ccfSSadaf Ebrahimi         viewport.y = 0;
4438*b7893ccfSSadaf Ebrahimi         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
4439*b7893ccfSSadaf Ebrahimi         vkEndCommandBuffer(command_buffer[0]);
4440*b7893ccfSSadaf Ebrahimi     }
4441*b7893ccfSSadaf Ebrahimi     {
4442*b7893ccfSSadaf Ebrahimi         VkCommandBufferBeginInfo begin_info{};
4443*b7893ccfSSadaf Ebrahimi         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4444*b7893ccfSSadaf Ebrahimi         vkBeginCommandBuffer(command_buffer[1], &begin_info);
4445*b7893ccfSSadaf Ebrahimi 
4446*b7893ccfSSadaf Ebrahimi         VkViewport viewport{};
4447*b7893ccfSSadaf Ebrahimi         viewport.maxDepth = 1.0f;
4448*b7893ccfSSadaf Ebrahimi         viewport.minDepth = 0.0f;
4449*b7893ccfSSadaf Ebrahimi         viewport.width = 512;
4450*b7893ccfSSadaf Ebrahimi         viewport.height = 512;
4451*b7893ccfSSadaf Ebrahimi         viewport.x = 0;
4452*b7893ccfSSadaf Ebrahimi         viewport.y = 0;
4453*b7893ccfSSadaf Ebrahimi         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
4454*b7893ccfSSadaf Ebrahimi         vkEndCommandBuffer(command_buffer[1]);
4455*b7893ccfSSadaf Ebrahimi     }
4456*b7893ccfSSadaf Ebrahimi     {
4457*b7893ccfSSadaf Ebrahimi         VkSubmitInfo submit_info{};
4458*b7893ccfSSadaf Ebrahimi         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4459*b7893ccfSSadaf Ebrahimi         submit_info.commandBufferCount = 1;
4460*b7893ccfSSadaf Ebrahimi         submit_info.pCommandBuffers = &command_buffer[0];
4461*b7893ccfSSadaf Ebrahimi         submit_info.signalSemaphoreCount = 1;
4462*b7893ccfSSadaf Ebrahimi         submit_info.pSignalSemaphores = &semaphore;
4463*b7893ccfSSadaf Ebrahimi         vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
4464*b7893ccfSSadaf Ebrahimi     }
4465*b7893ccfSSadaf Ebrahimi     {
4466*b7893ccfSSadaf Ebrahimi         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
4467*b7893ccfSSadaf Ebrahimi         VkSubmitInfo submit_info{};
4468*b7893ccfSSadaf Ebrahimi         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4469*b7893ccfSSadaf Ebrahimi         submit_info.commandBufferCount = 1;
4470*b7893ccfSSadaf Ebrahimi         submit_info.pCommandBuffers = &command_buffer[1];
4471*b7893ccfSSadaf Ebrahimi         submit_info.waitSemaphoreCount = 1;
4472*b7893ccfSSadaf Ebrahimi         submit_info.pWaitSemaphores = &semaphore;
4473*b7893ccfSSadaf Ebrahimi         submit_info.pWaitDstStageMask = flags;
4474*b7893ccfSSadaf Ebrahimi         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
4475*b7893ccfSSadaf Ebrahimi     }
4476*b7893ccfSSadaf Ebrahimi 
4477*b7893ccfSSadaf Ebrahimi     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
4478*b7893ccfSSadaf Ebrahimi 
4479*b7893ccfSSadaf Ebrahimi     vkDestroyFence(m_device->device(), fence, nullptr);
4480*b7893ccfSSadaf Ebrahimi     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
4481*b7893ccfSSadaf Ebrahimi     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
4482*b7893ccfSSadaf Ebrahimi     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
4483*b7893ccfSSadaf Ebrahimi 
4484*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
4485*b7893ccfSSadaf Ebrahimi }
4486*b7893ccfSSadaf Ebrahimi 
4487*b7893ccfSSadaf Ebrahimi // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,TwoQueueSubmitsOneQueueWithSemaphoreAndOneFence)4488*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, TwoQueueSubmitsOneQueueWithSemaphoreAndOneFence) {
4489*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
4490*b7893ccfSSadaf Ebrahimi         "Two command buffers, each in a separate QueueSubmit call on the same queue, sharing a signal/wait semaphore, the second "
4491*b7893ccfSSadaf Ebrahimi         "having a fence, followed by a WaitForFences call.");
4492*b7893ccfSSadaf Ebrahimi 
4493*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
4494*b7893ccfSSadaf Ebrahimi 
4495*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
4496*b7893ccfSSadaf Ebrahimi     VkFence fence;
4497*b7893ccfSSadaf Ebrahimi     VkFenceCreateInfo fence_create_info{};
4498*b7893ccfSSadaf Ebrahimi     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
4499*b7893ccfSSadaf Ebrahimi     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
4500*b7893ccfSSadaf Ebrahimi 
4501*b7893ccfSSadaf Ebrahimi     VkSemaphore semaphore;
4502*b7893ccfSSadaf Ebrahimi     VkSemaphoreCreateInfo semaphore_create_info{};
4503*b7893ccfSSadaf Ebrahimi     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
4504*b7893ccfSSadaf Ebrahimi     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
4505*b7893ccfSSadaf Ebrahimi 
4506*b7893ccfSSadaf Ebrahimi     VkCommandPool command_pool;
4507*b7893ccfSSadaf Ebrahimi     VkCommandPoolCreateInfo pool_create_info{};
4508*b7893ccfSSadaf Ebrahimi     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
4509*b7893ccfSSadaf Ebrahimi     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
4510*b7893ccfSSadaf Ebrahimi     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
4511*b7893ccfSSadaf Ebrahimi     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
4512*b7893ccfSSadaf Ebrahimi 
4513*b7893ccfSSadaf Ebrahimi     VkCommandBuffer command_buffer[2];
4514*b7893ccfSSadaf Ebrahimi     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
4515*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
4516*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandPool = command_pool;
4517*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandBufferCount = 2;
4518*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
4519*b7893ccfSSadaf Ebrahimi     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
4520*b7893ccfSSadaf Ebrahimi 
4521*b7893ccfSSadaf Ebrahimi     {
4522*b7893ccfSSadaf Ebrahimi         VkCommandBufferBeginInfo begin_info{};
4523*b7893ccfSSadaf Ebrahimi         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4524*b7893ccfSSadaf Ebrahimi         vkBeginCommandBuffer(command_buffer[0], &begin_info);
4525*b7893ccfSSadaf Ebrahimi 
4526*b7893ccfSSadaf Ebrahimi         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
4527*b7893ccfSSadaf Ebrahimi                              nullptr, 0, nullptr, 0, nullptr);
4528*b7893ccfSSadaf Ebrahimi 
4529*b7893ccfSSadaf Ebrahimi         VkViewport viewport{};
4530*b7893ccfSSadaf Ebrahimi         viewport.maxDepth = 1.0f;
4531*b7893ccfSSadaf Ebrahimi         viewport.minDepth = 0.0f;
4532*b7893ccfSSadaf Ebrahimi         viewport.width = 512;
4533*b7893ccfSSadaf Ebrahimi         viewport.height = 512;
4534*b7893ccfSSadaf Ebrahimi         viewport.x = 0;
4535*b7893ccfSSadaf Ebrahimi         viewport.y = 0;
4536*b7893ccfSSadaf Ebrahimi         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
4537*b7893ccfSSadaf Ebrahimi         vkEndCommandBuffer(command_buffer[0]);
4538*b7893ccfSSadaf Ebrahimi     }
4539*b7893ccfSSadaf Ebrahimi     {
4540*b7893ccfSSadaf Ebrahimi         VkCommandBufferBeginInfo begin_info{};
4541*b7893ccfSSadaf Ebrahimi         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4542*b7893ccfSSadaf Ebrahimi         vkBeginCommandBuffer(command_buffer[1], &begin_info);
4543*b7893ccfSSadaf Ebrahimi 
4544*b7893ccfSSadaf Ebrahimi         VkViewport viewport{};
4545*b7893ccfSSadaf Ebrahimi         viewport.maxDepth = 1.0f;
4546*b7893ccfSSadaf Ebrahimi         viewport.minDepth = 0.0f;
4547*b7893ccfSSadaf Ebrahimi         viewport.width = 512;
4548*b7893ccfSSadaf Ebrahimi         viewport.height = 512;
4549*b7893ccfSSadaf Ebrahimi         viewport.x = 0;
4550*b7893ccfSSadaf Ebrahimi         viewport.y = 0;
4551*b7893ccfSSadaf Ebrahimi         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
4552*b7893ccfSSadaf Ebrahimi         vkEndCommandBuffer(command_buffer[1]);
4553*b7893ccfSSadaf Ebrahimi     }
4554*b7893ccfSSadaf Ebrahimi     {
4555*b7893ccfSSadaf Ebrahimi         VkSubmitInfo submit_info{};
4556*b7893ccfSSadaf Ebrahimi         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4557*b7893ccfSSadaf Ebrahimi         submit_info.commandBufferCount = 1;
4558*b7893ccfSSadaf Ebrahimi         submit_info.pCommandBuffers = &command_buffer[0];
4559*b7893ccfSSadaf Ebrahimi         submit_info.signalSemaphoreCount = 1;
4560*b7893ccfSSadaf Ebrahimi         submit_info.pSignalSemaphores = &semaphore;
4561*b7893ccfSSadaf Ebrahimi         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
4562*b7893ccfSSadaf Ebrahimi     }
4563*b7893ccfSSadaf Ebrahimi     {
4564*b7893ccfSSadaf Ebrahimi         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
4565*b7893ccfSSadaf Ebrahimi         VkSubmitInfo submit_info{};
4566*b7893ccfSSadaf Ebrahimi         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4567*b7893ccfSSadaf Ebrahimi         submit_info.commandBufferCount = 1;
4568*b7893ccfSSadaf Ebrahimi         submit_info.pCommandBuffers = &command_buffer[1];
4569*b7893ccfSSadaf Ebrahimi         submit_info.waitSemaphoreCount = 1;
4570*b7893ccfSSadaf Ebrahimi         submit_info.pWaitSemaphores = &semaphore;
4571*b7893ccfSSadaf Ebrahimi         submit_info.pWaitDstStageMask = flags;
4572*b7893ccfSSadaf Ebrahimi         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
4573*b7893ccfSSadaf Ebrahimi     }
4574*b7893ccfSSadaf Ebrahimi 
4575*b7893ccfSSadaf Ebrahimi     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
4576*b7893ccfSSadaf Ebrahimi 
4577*b7893ccfSSadaf Ebrahimi     vkDestroyFence(m_device->device(), fence, nullptr);
4578*b7893ccfSSadaf Ebrahimi     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
4579*b7893ccfSSadaf Ebrahimi     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
4580*b7893ccfSSadaf Ebrahimi     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
4581*b7893ccfSSadaf Ebrahimi 
4582*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
4583*b7893ccfSSadaf Ebrahimi }
4584*b7893ccfSSadaf Ebrahimi 
4585*b7893ccfSSadaf Ebrahimi // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,TwoQueueSubmitsOneQueueNullQueueSubmitWithFence)4586*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, TwoQueueSubmitsOneQueueNullQueueSubmitWithFence) {
4587*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
4588*b7893ccfSSadaf Ebrahimi         "Two command buffers, each in a separate QueueSubmit call on the same queue, no fences, followed by a third QueueSubmit "
4589*b7893ccfSSadaf Ebrahimi         "with NO SubmitInfos but with a fence, followed by a WaitForFences call.");
4590*b7893ccfSSadaf Ebrahimi 
4591*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
4592*b7893ccfSSadaf Ebrahimi 
4593*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
4594*b7893ccfSSadaf Ebrahimi     VkFence fence;
4595*b7893ccfSSadaf Ebrahimi     VkFenceCreateInfo fence_create_info{};
4596*b7893ccfSSadaf Ebrahimi     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
4597*b7893ccfSSadaf Ebrahimi     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
4598*b7893ccfSSadaf Ebrahimi 
4599*b7893ccfSSadaf Ebrahimi     VkCommandPool command_pool;
4600*b7893ccfSSadaf Ebrahimi     VkCommandPoolCreateInfo pool_create_info{};
4601*b7893ccfSSadaf Ebrahimi     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
4602*b7893ccfSSadaf Ebrahimi     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
4603*b7893ccfSSadaf Ebrahimi     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
4604*b7893ccfSSadaf Ebrahimi     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
4605*b7893ccfSSadaf Ebrahimi 
4606*b7893ccfSSadaf Ebrahimi     VkCommandBuffer command_buffer[2];
4607*b7893ccfSSadaf Ebrahimi     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
4608*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
4609*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandPool = command_pool;
4610*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandBufferCount = 2;
4611*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
4612*b7893ccfSSadaf Ebrahimi     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
4613*b7893ccfSSadaf Ebrahimi 
4614*b7893ccfSSadaf Ebrahimi     {
4615*b7893ccfSSadaf Ebrahimi         VkCommandBufferBeginInfo begin_info{};
4616*b7893ccfSSadaf Ebrahimi         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4617*b7893ccfSSadaf Ebrahimi         vkBeginCommandBuffer(command_buffer[0], &begin_info);
4618*b7893ccfSSadaf Ebrahimi 
4619*b7893ccfSSadaf Ebrahimi         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
4620*b7893ccfSSadaf Ebrahimi                              nullptr, 0, nullptr, 0, nullptr);
4621*b7893ccfSSadaf Ebrahimi 
4622*b7893ccfSSadaf Ebrahimi         VkViewport viewport{};
4623*b7893ccfSSadaf Ebrahimi         viewport.maxDepth = 1.0f;
4624*b7893ccfSSadaf Ebrahimi         viewport.minDepth = 0.0f;
4625*b7893ccfSSadaf Ebrahimi         viewport.width = 512;
4626*b7893ccfSSadaf Ebrahimi         viewport.height = 512;
4627*b7893ccfSSadaf Ebrahimi         viewport.x = 0;
4628*b7893ccfSSadaf Ebrahimi         viewport.y = 0;
4629*b7893ccfSSadaf Ebrahimi         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
4630*b7893ccfSSadaf Ebrahimi         vkEndCommandBuffer(command_buffer[0]);
4631*b7893ccfSSadaf Ebrahimi     }
4632*b7893ccfSSadaf Ebrahimi     {
4633*b7893ccfSSadaf Ebrahimi         VkCommandBufferBeginInfo begin_info{};
4634*b7893ccfSSadaf Ebrahimi         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4635*b7893ccfSSadaf Ebrahimi         vkBeginCommandBuffer(command_buffer[1], &begin_info);
4636*b7893ccfSSadaf Ebrahimi 
4637*b7893ccfSSadaf Ebrahimi         VkViewport viewport{};
4638*b7893ccfSSadaf Ebrahimi         viewport.maxDepth = 1.0f;
4639*b7893ccfSSadaf Ebrahimi         viewport.minDepth = 0.0f;
4640*b7893ccfSSadaf Ebrahimi         viewport.width = 512;
4641*b7893ccfSSadaf Ebrahimi         viewport.height = 512;
4642*b7893ccfSSadaf Ebrahimi         viewport.x = 0;
4643*b7893ccfSSadaf Ebrahimi         viewport.y = 0;
4644*b7893ccfSSadaf Ebrahimi         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
4645*b7893ccfSSadaf Ebrahimi         vkEndCommandBuffer(command_buffer[1]);
4646*b7893ccfSSadaf Ebrahimi     }
4647*b7893ccfSSadaf Ebrahimi     {
4648*b7893ccfSSadaf Ebrahimi         VkSubmitInfo submit_info{};
4649*b7893ccfSSadaf Ebrahimi         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4650*b7893ccfSSadaf Ebrahimi         submit_info.commandBufferCount = 1;
4651*b7893ccfSSadaf Ebrahimi         submit_info.pCommandBuffers = &command_buffer[0];
4652*b7893ccfSSadaf Ebrahimi         submit_info.signalSemaphoreCount = 0;
4653*b7893ccfSSadaf Ebrahimi         submit_info.pSignalSemaphores = VK_NULL_HANDLE;
4654*b7893ccfSSadaf Ebrahimi         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
4655*b7893ccfSSadaf Ebrahimi     }
4656*b7893ccfSSadaf Ebrahimi     {
4657*b7893ccfSSadaf Ebrahimi         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
4658*b7893ccfSSadaf Ebrahimi         VkSubmitInfo submit_info{};
4659*b7893ccfSSadaf Ebrahimi         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4660*b7893ccfSSadaf Ebrahimi         submit_info.commandBufferCount = 1;
4661*b7893ccfSSadaf Ebrahimi         submit_info.pCommandBuffers = &command_buffer[1];
4662*b7893ccfSSadaf Ebrahimi         submit_info.waitSemaphoreCount = 0;
4663*b7893ccfSSadaf Ebrahimi         submit_info.pWaitSemaphores = VK_NULL_HANDLE;
4664*b7893ccfSSadaf Ebrahimi         submit_info.pWaitDstStageMask = flags;
4665*b7893ccfSSadaf Ebrahimi         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
4666*b7893ccfSSadaf Ebrahimi     }
4667*b7893ccfSSadaf Ebrahimi 
4668*b7893ccfSSadaf Ebrahimi     vkQueueSubmit(m_device->m_queue, 0, NULL, fence);
4669*b7893ccfSSadaf Ebrahimi 
4670*b7893ccfSSadaf Ebrahimi     VkResult err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
4671*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
4672*b7893ccfSSadaf Ebrahimi 
4673*b7893ccfSSadaf Ebrahimi     vkDestroyFence(m_device->device(), fence, nullptr);
4674*b7893ccfSSadaf Ebrahimi     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
4675*b7893ccfSSadaf Ebrahimi     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
4676*b7893ccfSSadaf Ebrahimi 
4677*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
4678*b7893ccfSSadaf Ebrahimi }
4679*b7893ccfSSadaf Ebrahimi 
4680*b7893ccfSSadaf Ebrahimi // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,TwoQueueSubmitsOneQueueOneFence)4681*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, TwoQueueSubmitsOneQueueOneFence) {
4682*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
4683*b7893ccfSSadaf Ebrahimi         "Two command buffers, each in a separate QueueSubmit call on the same queue, the second having a fence, followed by a "
4684*b7893ccfSSadaf Ebrahimi         "WaitForFences call.");
4685*b7893ccfSSadaf Ebrahimi 
4686*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
4687*b7893ccfSSadaf Ebrahimi 
4688*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
4689*b7893ccfSSadaf Ebrahimi     VkFence fence;
4690*b7893ccfSSadaf Ebrahimi     VkFenceCreateInfo fence_create_info{};
4691*b7893ccfSSadaf Ebrahimi     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
4692*b7893ccfSSadaf Ebrahimi     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
4693*b7893ccfSSadaf Ebrahimi 
4694*b7893ccfSSadaf Ebrahimi     VkCommandPool command_pool;
4695*b7893ccfSSadaf Ebrahimi     VkCommandPoolCreateInfo pool_create_info{};
4696*b7893ccfSSadaf Ebrahimi     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
4697*b7893ccfSSadaf Ebrahimi     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
4698*b7893ccfSSadaf Ebrahimi     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
4699*b7893ccfSSadaf Ebrahimi     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
4700*b7893ccfSSadaf Ebrahimi 
4701*b7893ccfSSadaf Ebrahimi     VkCommandBuffer command_buffer[2];
4702*b7893ccfSSadaf Ebrahimi     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
4703*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
4704*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandPool = command_pool;
4705*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandBufferCount = 2;
4706*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
4707*b7893ccfSSadaf Ebrahimi     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
4708*b7893ccfSSadaf Ebrahimi 
4709*b7893ccfSSadaf Ebrahimi     {
4710*b7893ccfSSadaf Ebrahimi         VkCommandBufferBeginInfo begin_info{};
4711*b7893ccfSSadaf Ebrahimi         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4712*b7893ccfSSadaf Ebrahimi         vkBeginCommandBuffer(command_buffer[0], &begin_info);
4713*b7893ccfSSadaf Ebrahimi 
4714*b7893ccfSSadaf Ebrahimi         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
4715*b7893ccfSSadaf Ebrahimi                              nullptr, 0, nullptr, 0, nullptr);
4716*b7893ccfSSadaf Ebrahimi 
4717*b7893ccfSSadaf Ebrahimi         VkViewport viewport{};
4718*b7893ccfSSadaf Ebrahimi         viewport.maxDepth = 1.0f;
4719*b7893ccfSSadaf Ebrahimi         viewport.minDepth = 0.0f;
4720*b7893ccfSSadaf Ebrahimi         viewport.width = 512;
4721*b7893ccfSSadaf Ebrahimi         viewport.height = 512;
4722*b7893ccfSSadaf Ebrahimi         viewport.x = 0;
4723*b7893ccfSSadaf Ebrahimi         viewport.y = 0;
4724*b7893ccfSSadaf Ebrahimi         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
4725*b7893ccfSSadaf Ebrahimi         vkEndCommandBuffer(command_buffer[0]);
4726*b7893ccfSSadaf Ebrahimi     }
4727*b7893ccfSSadaf Ebrahimi     {
4728*b7893ccfSSadaf Ebrahimi         VkCommandBufferBeginInfo begin_info{};
4729*b7893ccfSSadaf Ebrahimi         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4730*b7893ccfSSadaf Ebrahimi         vkBeginCommandBuffer(command_buffer[1], &begin_info);
4731*b7893ccfSSadaf Ebrahimi 
4732*b7893ccfSSadaf Ebrahimi         VkViewport viewport{};
4733*b7893ccfSSadaf Ebrahimi         viewport.maxDepth = 1.0f;
4734*b7893ccfSSadaf Ebrahimi         viewport.minDepth = 0.0f;
4735*b7893ccfSSadaf Ebrahimi         viewport.width = 512;
4736*b7893ccfSSadaf Ebrahimi         viewport.height = 512;
4737*b7893ccfSSadaf Ebrahimi         viewport.x = 0;
4738*b7893ccfSSadaf Ebrahimi         viewport.y = 0;
4739*b7893ccfSSadaf Ebrahimi         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
4740*b7893ccfSSadaf Ebrahimi         vkEndCommandBuffer(command_buffer[1]);
4741*b7893ccfSSadaf Ebrahimi     }
4742*b7893ccfSSadaf Ebrahimi     {
4743*b7893ccfSSadaf Ebrahimi         VkSubmitInfo submit_info{};
4744*b7893ccfSSadaf Ebrahimi         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4745*b7893ccfSSadaf Ebrahimi         submit_info.commandBufferCount = 1;
4746*b7893ccfSSadaf Ebrahimi         submit_info.pCommandBuffers = &command_buffer[0];
4747*b7893ccfSSadaf Ebrahimi         submit_info.signalSemaphoreCount = 0;
4748*b7893ccfSSadaf Ebrahimi         submit_info.pSignalSemaphores = VK_NULL_HANDLE;
4749*b7893ccfSSadaf Ebrahimi         vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
4750*b7893ccfSSadaf Ebrahimi     }
4751*b7893ccfSSadaf Ebrahimi     {
4752*b7893ccfSSadaf Ebrahimi         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
4753*b7893ccfSSadaf Ebrahimi         VkSubmitInfo submit_info{};
4754*b7893ccfSSadaf Ebrahimi         submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4755*b7893ccfSSadaf Ebrahimi         submit_info.commandBufferCount = 1;
4756*b7893ccfSSadaf Ebrahimi         submit_info.pCommandBuffers = &command_buffer[1];
4757*b7893ccfSSadaf Ebrahimi         submit_info.waitSemaphoreCount = 0;
4758*b7893ccfSSadaf Ebrahimi         submit_info.pWaitSemaphores = VK_NULL_HANDLE;
4759*b7893ccfSSadaf Ebrahimi         submit_info.pWaitDstStageMask = flags;
4760*b7893ccfSSadaf Ebrahimi         vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
4761*b7893ccfSSadaf Ebrahimi     }
4762*b7893ccfSSadaf Ebrahimi 
4763*b7893ccfSSadaf Ebrahimi     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
4764*b7893ccfSSadaf Ebrahimi 
4765*b7893ccfSSadaf Ebrahimi     vkDestroyFence(m_device->device(), fence, nullptr);
4766*b7893ccfSSadaf Ebrahimi     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
4767*b7893ccfSSadaf Ebrahimi     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
4768*b7893ccfSSadaf Ebrahimi 
4769*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
4770*b7893ccfSSadaf Ebrahimi }
4771*b7893ccfSSadaf Ebrahimi 
4772*b7893ccfSSadaf Ebrahimi // This is a positive test.  No errors should be generated.
TEST_F(VkPositiveLayerTest,TwoSubmitInfosWithSemaphoreOneQueueSubmitsOneFence)4773*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, TwoSubmitInfosWithSemaphoreOneQueueSubmitsOneFence) {
4774*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
4775*b7893ccfSSadaf Ebrahimi         "Two command buffers each in a separate SubmitInfo sent in a single QueueSubmit call followed by a WaitForFences call.");
4776*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
4777*b7893ccfSSadaf Ebrahimi 
4778*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
4779*b7893ccfSSadaf Ebrahimi 
4780*b7893ccfSSadaf Ebrahimi     VkFence fence;
4781*b7893ccfSSadaf Ebrahimi     VkFenceCreateInfo fence_create_info{};
4782*b7893ccfSSadaf Ebrahimi     fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
4783*b7893ccfSSadaf Ebrahimi     vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
4784*b7893ccfSSadaf Ebrahimi 
4785*b7893ccfSSadaf Ebrahimi     VkSemaphore semaphore;
4786*b7893ccfSSadaf Ebrahimi     VkSemaphoreCreateInfo semaphore_create_info{};
4787*b7893ccfSSadaf Ebrahimi     semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
4788*b7893ccfSSadaf Ebrahimi     vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
4789*b7893ccfSSadaf Ebrahimi 
4790*b7893ccfSSadaf Ebrahimi     VkCommandPool command_pool;
4791*b7893ccfSSadaf Ebrahimi     VkCommandPoolCreateInfo pool_create_info{};
4792*b7893ccfSSadaf Ebrahimi     pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
4793*b7893ccfSSadaf Ebrahimi     pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
4794*b7893ccfSSadaf Ebrahimi     pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
4795*b7893ccfSSadaf Ebrahimi     vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
4796*b7893ccfSSadaf Ebrahimi 
4797*b7893ccfSSadaf Ebrahimi     VkCommandBuffer command_buffer[2];
4798*b7893ccfSSadaf Ebrahimi     VkCommandBufferAllocateInfo command_buffer_allocate_info{};
4799*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
4800*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandPool = command_pool;
4801*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.commandBufferCount = 2;
4802*b7893ccfSSadaf Ebrahimi     command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
4803*b7893ccfSSadaf Ebrahimi     vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
4804*b7893ccfSSadaf Ebrahimi 
4805*b7893ccfSSadaf Ebrahimi     {
4806*b7893ccfSSadaf Ebrahimi         VkCommandBufferBeginInfo begin_info{};
4807*b7893ccfSSadaf Ebrahimi         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4808*b7893ccfSSadaf Ebrahimi         vkBeginCommandBuffer(command_buffer[0], &begin_info);
4809*b7893ccfSSadaf Ebrahimi 
4810*b7893ccfSSadaf Ebrahimi         vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
4811*b7893ccfSSadaf Ebrahimi                              nullptr, 0, nullptr, 0, nullptr);
4812*b7893ccfSSadaf Ebrahimi 
4813*b7893ccfSSadaf Ebrahimi         VkViewport viewport{};
4814*b7893ccfSSadaf Ebrahimi         viewport.maxDepth = 1.0f;
4815*b7893ccfSSadaf Ebrahimi         viewport.minDepth = 0.0f;
4816*b7893ccfSSadaf Ebrahimi         viewport.width = 512;
4817*b7893ccfSSadaf Ebrahimi         viewport.height = 512;
4818*b7893ccfSSadaf Ebrahimi         viewport.x = 0;
4819*b7893ccfSSadaf Ebrahimi         viewport.y = 0;
4820*b7893ccfSSadaf Ebrahimi         vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
4821*b7893ccfSSadaf Ebrahimi         vkEndCommandBuffer(command_buffer[0]);
4822*b7893ccfSSadaf Ebrahimi     }
4823*b7893ccfSSadaf Ebrahimi     {
4824*b7893ccfSSadaf Ebrahimi         VkCommandBufferBeginInfo begin_info{};
4825*b7893ccfSSadaf Ebrahimi         begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
4826*b7893ccfSSadaf Ebrahimi         vkBeginCommandBuffer(command_buffer[1], &begin_info);
4827*b7893ccfSSadaf Ebrahimi 
4828*b7893ccfSSadaf Ebrahimi         VkViewport viewport{};
4829*b7893ccfSSadaf Ebrahimi         viewport.maxDepth = 1.0f;
4830*b7893ccfSSadaf Ebrahimi         viewport.minDepth = 0.0f;
4831*b7893ccfSSadaf Ebrahimi         viewport.width = 512;
4832*b7893ccfSSadaf Ebrahimi         viewport.height = 512;
4833*b7893ccfSSadaf Ebrahimi         viewport.x = 0;
4834*b7893ccfSSadaf Ebrahimi         viewport.y = 0;
4835*b7893ccfSSadaf Ebrahimi         vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
4836*b7893ccfSSadaf Ebrahimi         vkEndCommandBuffer(command_buffer[1]);
4837*b7893ccfSSadaf Ebrahimi     }
4838*b7893ccfSSadaf Ebrahimi     {
4839*b7893ccfSSadaf Ebrahimi         VkSubmitInfo submit_info[2];
4840*b7893ccfSSadaf Ebrahimi         VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
4841*b7893ccfSSadaf Ebrahimi 
4842*b7893ccfSSadaf Ebrahimi         submit_info[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4843*b7893ccfSSadaf Ebrahimi         submit_info[0].pNext = NULL;
4844*b7893ccfSSadaf Ebrahimi         submit_info[0].commandBufferCount = 1;
4845*b7893ccfSSadaf Ebrahimi         submit_info[0].pCommandBuffers = &command_buffer[0];
4846*b7893ccfSSadaf Ebrahimi         submit_info[0].signalSemaphoreCount = 1;
4847*b7893ccfSSadaf Ebrahimi         submit_info[0].pSignalSemaphores = &semaphore;
4848*b7893ccfSSadaf Ebrahimi         submit_info[0].waitSemaphoreCount = 0;
4849*b7893ccfSSadaf Ebrahimi         submit_info[0].pWaitSemaphores = NULL;
4850*b7893ccfSSadaf Ebrahimi         submit_info[0].pWaitDstStageMask = 0;
4851*b7893ccfSSadaf Ebrahimi 
4852*b7893ccfSSadaf Ebrahimi         submit_info[1].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
4853*b7893ccfSSadaf Ebrahimi         submit_info[1].pNext = NULL;
4854*b7893ccfSSadaf Ebrahimi         submit_info[1].commandBufferCount = 1;
4855*b7893ccfSSadaf Ebrahimi         submit_info[1].pCommandBuffers = &command_buffer[1];
4856*b7893ccfSSadaf Ebrahimi         submit_info[1].waitSemaphoreCount = 1;
4857*b7893ccfSSadaf Ebrahimi         submit_info[1].pWaitSemaphores = &semaphore;
4858*b7893ccfSSadaf Ebrahimi         submit_info[1].pWaitDstStageMask = flags;
4859*b7893ccfSSadaf Ebrahimi         submit_info[1].signalSemaphoreCount = 0;
4860*b7893ccfSSadaf Ebrahimi         submit_info[1].pSignalSemaphores = NULL;
4861*b7893ccfSSadaf Ebrahimi         vkQueueSubmit(m_device->m_queue, 2, &submit_info[0], fence);
4862*b7893ccfSSadaf Ebrahimi     }
4863*b7893ccfSSadaf Ebrahimi 
4864*b7893ccfSSadaf Ebrahimi     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
4865*b7893ccfSSadaf Ebrahimi 
4866*b7893ccfSSadaf Ebrahimi     vkDestroyFence(m_device->device(), fence, nullptr);
4867*b7893ccfSSadaf Ebrahimi     vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
4868*b7893ccfSSadaf Ebrahimi     vkDestroyCommandPool(m_device->device(), command_pool, NULL);
4869*b7893ccfSSadaf Ebrahimi     vkDestroySemaphore(m_device->device(), semaphore, nullptr);
4870*b7893ccfSSadaf Ebrahimi 
4871*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
4872*b7893ccfSSadaf Ebrahimi }
4873*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CreatePipelineAttribMatrixType)4874*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CreatePipelineAttribMatrixType) {
4875*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Test that pipeline validation accepts matrices passed as vertex attributes");
4876*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
4877*b7893ccfSSadaf Ebrahimi 
4878*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
4879*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4880*b7893ccfSSadaf Ebrahimi 
4881*b7893ccfSSadaf Ebrahimi     VkVertexInputBindingDescription input_binding;
4882*b7893ccfSSadaf Ebrahimi     memset(&input_binding, 0, sizeof(input_binding));
4883*b7893ccfSSadaf Ebrahimi 
4884*b7893ccfSSadaf Ebrahimi     VkVertexInputAttributeDescription input_attribs[2];
4885*b7893ccfSSadaf Ebrahimi     memset(input_attribs, 0, sizeof(input_attribs));
4886*b7893ccfSSadaf Ebrahimi 
4887*b7893ccfSSadaf Ebrahimi     for (int i = 0; i < 2; i++) {
4888*b7893ccfSSadaf Ebrahimi         input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
4889*b7893ccfSSadaf Ebrahimi         input_attribs[i].location = i;
4890*b7893ccfSSadaf Ebrahimi     }
4891*b7893ccfSSadaf Ebrahimi 
4892*b7893ccfSSadaf Ebrahimi     char const *vsSource =
4893*b7893ccfSSadaf Ebrahimi         "#version 450\n"
4894*b7893ccfSSadaf Ebrahimi         "\n"
4895*b7893ccfSSadaf Ebrahimi         "layout(location=0) in mat2x4 x;\n"
4896*b7893ccfSSadaf Ebrahimi         "void main(){\n"
4897*b7893ccfSSadaf Ebrahimi         "   gl_Position = x[0] + x[1];\n"
4898*b7893ccfSSadaf Ebrahimi         "}\n";
4899*b7893ccfSSadaf Ebrahimi 
4900*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
4901*b7893ccfSSadaf Ebrahimi     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
4902*b7893ccfSSadaf Ebrahimi 
4903*b7893ccfSSadaf Ebrahimi     CreatePipelineHelper pipe(*this);
4904*b7893ccfSSadaf Ebrahimi     pipe.InitInfo();
4905*b7893ccfSSadaf Ebrahimi     pipe.vi_ci_.pVertexBindingDescriptions = &input_binding;
4906*b7893ccfSSadaf Ebrahimi     pipe.vi_ci_.vertexBindingDescriptionCount = 1;
4907*b7893ccfSSadaf Ebrahimi     pipe.vi_ci_.pVertexAttributeDescriptions = input_attribs;
4908*b7893ccfSSadaf Ebrahimi     pipe.vi_ci_.vertexAttributeDescriptionCount = 2;
4909*b7893ccfSSadaf Ebrahimi     pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
4910*b7893ccfSSadaf Ebrahimi     pipe.InitState();
4911*b7893ccfSSadaf Ebrahimi     pipe.CreateGraphicsPipeline();
4912*b7893ccfSSadaf Ebrahimi     /* expect success */
4913*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
4914*b7893ccfSSadaf Ebrahimi }
4915*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CreatePipelineAttribArrayType)4916*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CreatePipelineAttribArrayType) {
4917*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
4918*b7893ccfSSadaf Ebrahimi 
4919*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
4920*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4921*b7893ccfSSadaf Ebrahimi 
4922*b7893ccfSSadaf Ebrahimi     VkVertexInputBindingDescription input_binding;
4923*b7893ccfSSadaf Ebrahimi     memset(&input_binding, 0, sizeof(input_binding));
4924*b7893ccfSSadaf Ebrahimi 
4925*b7893ccfSSadaf Ebrahimi     VkVertexInputAttributeDescription input_attribs[2];
4926*b7893ccfSSadaf Ebrahimi     memset(input_attribs, 0, sizeof(input_attribs));
4927*b7893ccfSSadaf Ebrahimi 
4928*b7893ccfSSadaf Ebrahimi     for (int i = 0; i < 2; i++) {
4929*b7893ccfSSadaf Ebrahimi         input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
4930*b7893ccfSSadaf Ebrahimi         input_attribs[i].location = i;
4931*b7893ccfSSadaf Ebrahimi     }
4932*b7893ccfSSadaf Ebrahimi 
4933*b7893ccfSSadaf Ebrahimi     char const *vsSource =
4934*b7893ccfSSadaf Ebrahimi         "#version 450\n"
4935*b7893ccfSSadaf Ebrahimi         "\n"
4936*b7893ccfSSadaf Ebrahimi         "layout(location=0) in vec4 x[2];\n"
4937*b7893ccfSSadaf Ebrahimi         "void main(){\n"
4938*b7893ccfSSadaf Ebrahimi         "   gl_Position = x[0] + x[1];\n"
4939*b7893ccfSSadaf Ebrahimi         "}\n";
4940*b7893ccfSSadaf Ebrahimi 
4941*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
4942*b7893ccfSSadaf Ebrahimi     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
4943*b7893ccfSSadaf Ebrahimi 
4944*b7893ccfSSadaf Ebrahimi     CreatePipelineHelper pipe(*this);
4945*b7893ccfSSadaf Ebrahimi     pipe.InitInfo();
4946*b7893ccfSSadaf Ebrahimi     pipe.vi_ci_.pVertexBindingDescriptions = &input_binding;
4947*b7893ccfSSadaf Ebrahimi     pipe.vi_ci_.vertexBindingDescriptionCount = 1;
4948*b7893ccfSSadaf Ebrahimi     pipe.vi_ci_.pVertexAttributeDescriptions = input_attribs;
4949*b7893ccfSSadaf Ebrahimi     pipe.vi_ci_.vertexAttributeDescriptionCount = 2;
4950*b7893ccfSSadaf Ebrahimi     pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
4951*b7893ccfSSadaf Ebrahimi     pipe.InitState();
4952*b7893ccfSSadaf Ebrahimi     pipe.CreateGraphicsPipeline();
4953*b7893ccfSSadaf Ebrahimi 
4954*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
4955*b7893ccfSSadaf Ebrahimi }
4956*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CreatePipelineAttribComponents)4957*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CreatePipelineAttribComponents) {
4958*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
4959*b7893ccfSSadaf Ebrahimi         "Test that pipeline validation accepts consuming a vertex attribute through multiple vertex shader inputs, each consuming "
4960*b7893ccfSSadaf Ebrahimi         "a different subset of the components, and that fragment shader-attachment validation tolerates multiple duplicate "
4961*b7893ccfSSadaf Ebrahimi         "location outputs");
4962*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT);
4963*b7893ccfSSadaf Ebrahimi 
4964*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
4965*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
4966*b7893ccfSSadaf Ebrahimi 
4967*b7893ccfSSadaf Ebrahimi     VkVertexInputBindingDescription input_binding;
4968*b7893ccfSSadaf Ebrahimi     memset(&input_binding, 0, sizeof(input_binding));
4969*b7893ccfSSadaf Ebrahimi 
4970*b7893ccfSSadaf Ebrahimi     VkVertexInputAttributeDescription input_attribs[3];
4971*b7893ccfSSadaf Ebrahimi     memset(input_attribs, 0, sizeof(input_attribs));
4972*b7893ccfSSadaf Ebrahimi 
4973*b7893ccfSSadaf Ebrahimi     for (int i = 0; i < 3; i++) {
4974*b7893ccfSSadaf Ebrahimi         input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
4975*b7893ccfSSadaf Ebrahimi         input_attribs[i].location = i;
4976*b7893ccfSSadaf Ebrahimi     }
4977*b7893ccfSSadaf Ebrahimi 
4978*b7893ccfSSadaf Ebrahimi     char const *vsSource =
4979*b7893ccfSSadaf Ebrahimi         "#version 450\n"
4980*b7893ccfSSadaf Ebrahimi         "\n"
4981*b7893ccfSSadaf Ebrahimi         "layout(location=0) in vec4 x;\n"
4982*b7893ccfSSadaf Ebrahimi         "layout(location=1) in vec3 y1;\n"
4983*b7893ccfSSadaf Ebrahimi         "layout(location=1, component=3) in float y2;\n"
4984*b7893ccfSSadaf Ebrahimi         "layout(location=2) in vec4 z;\n"
4985*b7893ccfSSadaf Ebrahimi         "void main(){\n"
4986*b7893ccfSSadaf Ebrahimi         "   gl_Position = x + vec4(y1, y2) + z;\n"
4987*b7893ccfSSadaf Ebrahimi         "}\n";
4988*b7893ccfSSadaf Ebrahimi     char const *fsSource =
4989*b7893ccfSSadaf Ebrahimi         "#version 450\n"
4990*b7893ccfSSadaf Ebrahimi         "\n"
4991*b7893ccfSSadaf Ebrahimi         "layout(location=0, component=0) out float color0;\n"
4992*b7893ccfSSadaf Ebrahimi         "layout(location=0, component=1) out float color1;\n"
4993*b7893ccfSSadaf Ebrahimi         "layout(location=0, component=2) out float color2;\n"
4994*b7893ccfSSadaf Ebrahimi         "layout(location=0, component=3) out float color3;\n"
4995*b7893ccfSSadaf Ebrahimi         "layout(location=1, component=0) out vec2 second_color0;\n"
4996*b7893ccfSSadaf Ebrahimi         "layout(location=1, component=2) out vec2 second_color1;\n"
4997*b7893ccfSSadaf Ebrahimi         "void main(){\n"
4998*b7893ccfSSadaf Ebrahimi         "   color0 = float(1);\n"
4999*b7893ccfSSadaf Ebrahimi         "   second_color0 = vec2(1);\n"
5000*b7893ccfSSadaf Ebrahimi         "}\n";
5001*b7893ccfSSadaf Ebrahimi 
5002*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
5003*b7893ccfSSadaf Ebrahimi     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
5004*b7893ccfSSadaf Ebrahimi 
5005*b7893ccfSSadaf Ebrahimi     VkPipelineObj pipe(m_device);
5006*b7893ccfSSadaf Ebrahimi 
5007*b7893ccfSSadaf Ebrahimi     VkDescriptorSetObj descriptorSet(m_device);
5008*b7893ccfSSadaf Ebrahimi     descriptorSet.AppendDummy();
5009*b7893ccfSSadaf Ebrahimi     descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
5010*b7893ccfSSadaf Ebrahimi 
5011*b7893ccfSSadaf Ebrahimi     // Create a renderPass with two color attachments
5012*b7893ccfSSadaf Ebrahimi     VkAttachmentReference attachments[2] = {};
5013*b7893ccfSSadaf Ebrahimi     attachments[0].layout = VK_IMAGE_LAYOUT_GENERAL;
5014*b7893ccfSSadaf Ebrahimi     attachments[1].attachment = 1;
5015*b7893ccfSSadaf Ebrahimi     attachments[1].layout = VK_IMAGE_LAYOUT_GENERAL;
5016*b7893ccfSSadaf Ebrahimi 
5017*b7893ccfSSadaf Ebrahimi     VkSubpassDescription subpass = {};
5018*b7893ccfSSadaf Ebrahimi     subpass.pColorAttachments = attachments;
5019*b7893ccfSSadaf Ebrahimi     subpass.colorAttachmentCount = 2;
5020*b7893ccfSSadaf Ebrahimi 
5021*b7893ccfSSadaf Ebrahimi     VkRenderPassCreateInfo rpci = {};
5022*b7893ccfSSadaf Ebrahimi     rpci.subpassCount = 1;
5023*b7893ccfSSadaf Ebrahimi     rpci.pSubpasses = &subpass;
5024*b7893ccfSSadaf Ebrahimi     rpci.attachmentCount = 2;
5025*b7893ccfSSadaf Ebrahimi 
5026*b7893ccfSSadaf Ebrahimi     VkAttachmentDescription attach_desc[2] = {};
5027*b7893ccfSSadaf Ebrahimi     attach_desc[0].format = VK_FORMAT_B8G8R8A8_UNORM;
5028*b7893ccfSSadaf Ebrahimi     attach_desc[0].samples = VK_SAMPLE_COUNT_1_BIT;
5029*b7893ccfSSadaf Ebrahimi     attach_desc[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
5030*b7893ccfSSadaf Ebrahimi     attach_desc[0].finalLayout = VK_IMAGE_LAYOUT_GENERAL;
5031*b7893ccfSSadaf Ebrahimi     attach_desc[0].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
5032*b7893ccfSSadaf Ebrahimi     attach_desc[1].format = VK_FORMAT_B8G8R8A8_UNORM;
5033*b7893ccfSSadaf Ebrahimi     attach_desc[1].samples = VK_SAMPLE_COUNT_1_BIT;
5034*b7893ccfSSadaf Ebrahimi     attach_desc[1].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
5035*b7893ccfSSadaf Ebrahimi     attach_desc[1].finalLayout = VK_IMAGE_LAYOUT_GENERAL;
5036*b7893ccfSSadaf Ebrahimi     attach_desc[1].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
5037*b7893ccfSSadaf Ebrahimi 
5038*b7893ccfSSadaf Ebrahimi     rpci.pAttachments = attach_desc;
5039*b7893ccfSSadaf Ebrahimi     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
5040*b7893ccfSSadaf Ebrahimi 
5041*b7893ccfSSadaf Ebrahimi     VkRenderPass renderpass;
5042*b7893ccfSSadaf Ebrahimi     vkCreateRenderPass(m_device->device(), &rpci, NULL, &renderpass);
5043*b7893ccfSSadaf Ebrahimi     pipe.AddShader(&vs);
5044*b7893ccfSSadaf Ebrahimi     pipe.AddShader(&fs);
5045*b7893ccfSSadaf Ebrahimi 
5046*b7893ccfSSadaf Ebrahimi     VkPipelineColorBlendAttachmentState att_state1 = {};
5047*b7893ccfSSadaf Ebrahimi     att_state1.dstAlphaBlendFactor = VK_BLEND_FACTOR_CONSTANT_COLOR;
5048*b7893ccfSSadaf Ebrahimi     att_state1.blendEnable = VK_FALSE;
5049*b7893ccfSSadaf Ebrahimi 
5050*b7893ccfSSadaf Ebrahimi     pipe.AddColorAttachment(0, att_state1);
5051*b7893ccfSSadaf Ebrahimi     pipe.AddColorAttachment(1, att_state1);
5052*b7893ccfSSadaf Ebrahimi     pipe.AddVertexInputBindings(&input_binding, 1);
5053*b7893ccfSSadaf Ebrahimi     pipe.AddVertexInputAttribs(input_attribs, 3);
5054*b7893ccfSSadaf Ebrahimi     pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderpass);
5055*b7893ccfSSadaf Ebrahimi     vkDestroyRenderPass(m_device->device(), renderpass, nullptr);
5056*b7893ccfSSadaf Ebrahimi 
5057*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
5058*b7893ccfSSadaf Ebrahimi }
5059*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CreatePipelineSimplePositive)5060*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CreatePipelineSimplePositive) {
5061*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
5062*b7893ccfSSadaf Ebrahimi 
5063*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
5064*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5065*b7893ccfSSadaf Ebrahimi 
5066*b7893ccfSSadaf Ebrahimi     CreatePipelineHelper pipe(*this);
5067*b7893ccfSSadaf Ebrahimi     pipe.InitInfo();
5068*b7893ccfSSadaf Ebrahimi     pipe.InitState();
5069*b7893ccfSSadaf Ebrahimi     pipe.CreateGraphicsPipeline();
5070*b7893ccfSSadaf Ebrahimi 
5071*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
5072*b7893ccfSSadaf Ebrahimi }
5073*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CreatePipelineRelaxedTypeMatch)5074*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CreatePipelineRelaxedTypeMatch) {
5075*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
5076*b7893ccfSSadaf Ebrahimi         "Test that pipeline validation accepts the relaxed type matching rules set out in 14.1.3: fundamental type must match, and "
5077*b7893ccfSSadaf Ebrahimi         "producer side must have at least as many components");
5078*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
5079*b7893ccfSSadaf Ebrahimi 
5080*b7893ccfSSadaf Ebrahimi     // VK 1.0.8 Specification, 14.1.3 "Additionally,..." block
5081*b7893ccfSSadaf Ebrahimi 
5082*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
5083*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5084*b7893ccfSSadaf Ebrahimi 
5085*b7893ccfSSadaf Ebrahimi     char const *vsSource =
5086*b7893ccfSSadaf Ebrahimi         "#version 450\n"
5087*b7893ccfSSadaf Ebrahimi         "layout(location=0) out vec3 x;\n"
5088*b7893ccfSSadaf Ebrahimi         "layout(location=1) out ivec3 y;\n"
5089*b7893ccfSSadaf Ebrahimi         "layout(location=2) out vec3 z;\n"
5090*b7893ccfSSadaf Ebrahimi         "void main(){\n"
5091*b7893ccfSSadaf Ebrahimi         "   gl_Position = vec4(0);\n"
5092*b7893ccfSSadaf Ebrahimi         "   x = vec3(0); y = ivec3(0); z = vec3(0);\n"
5093*b7893ccfSSadaf Ebrahimi         "}\n";
5094*b7893ccfSSadaf Ebrahimi     char const *fsSource =
5095*b7893ccfSSadaf Ebrahimi         "#version 450\n"
5096*b7893ccfSSadaf Ebrahimi         "\n"
5097*b7893ccfSSadaf Ebrahimi         "layout(location=0) out vec4 color;\n"
5098*b7893ccfSSadaf Ebrahimi         "layout(location=0) in float x;\n"
5099*b7893ccfSSadaf Ebrahimi         "layout(location=1) flat in int y;\n"
5100*b7893ccfSSadaf Ebrahimi         "layout(location=2) in vec2 z;\n"
5101*b7893ccfSSadaf Ebrahimi         "void main(){\n"
5102*b7893ccfSSadaf Ebrahimi         "   color = vec4(1 + x + y + z.x);\n"
5103*b7893ccfSSadaf Ebrahimi         "}\n";
5104*b7893ccfSSadaf Ebrahimi 
5105*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
5106*b7893ccfSSadaf Ebrahimi     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
5107*b7893ccfSSadaf Ebrahimi 
5108*b7893ccfSSadaf Ebrahimi     CreatePipelineHelper pipe(*this);
5109*b7893ccfSSadaf Ebrahimi     pipe.InitInfo();
5110*b7893ccfSSadaf Ebrahimi     pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
5111*b7893ccfSSadaf Ebrahimi     pipe.InitState();
5112*b7893ccfSSadaf Ebrahimi     pipe.CreateGraphicsPipeline();
5113*b7893ccfSSadaf Ebrahimi 
5114*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
5115*b7893ccfSSadaf Ebrahimi }
5116*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CreatePipelineTessPerVertex)5117*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CreatePipelineTessPerVertex) {
5118*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Test that pipeline validation accepts per-vertex variables passed between the TCS and TES stages");
5119*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
5120*b7893ccfSSadaf Ebrahimi 
5121*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
5122*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5123*b7893ccfSSadaf Ebrahimi 
5124*b7893ccfSSadaf Ebrahimi     if (!m_device->phy().features().tessellationShader) {
5125*b7893ccfSSadaf Ebrahimi         printf("%s Device does not support tessellation shaders; skipped.\n", kSkipPrefix);
5126*b7893ccfSSadaf Ebrahimi         return;
5127*b7893ccfSSadaf Ebrahimi     }
5128*b7893ccfSSadaf Ebrahimi 
5129*b7893ccfSSadaf Ebrahimi     char const *tcsSource =
5130*b7893ccfSSadaf Ebrahimi         "#version 450\n"
5131*b7893ccfSSadaf Ebrahimi         "layout(location=0) out int x[];\n"
5132*b7893ccfSSadaf Ebrahimi         "layout(vertices=3) out;\n"
5133*b7893ccfSSadaf Ebrahimi         "void main(){\n"
5134*b7893ccfSSadaf Ebrahimi         "   gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
5135*b7893ccfSSadaf Ebrahimi         "   gl_TessLevelInner[0] = 1;\n"
5136*b7893ccfSSadaf Ebrahimi         "   x[gl_InvocationID] = gl_InvocationID;\n"
5137*b7893ccfSSadaf Ebrahimi         "}\n";
5138*b7893ccfSSadaf Ebrahimi     char const *tesSource =
5139*b7893ccfSSadaf Ebrahimi         "#version 450\n"
5140*b7893ccfSSadaf Ebrahimi         "layout(triangles, equal_spacing, cw) in;\n"
5141*b7893ccfSSadaf Ebrahimi         "layout(location=0) in int x[];\n"
5142*b7893ccfSSadaf Ebrahimi         "void main(){\n"
5143*b7893ccfSSadaf Ebrahimi         "   gl_Position.xyz = gl_TessCoord;\n"
5144*b7893ccfSSadaf Ebrahimi         "   gl_Position.w = x[0] + x[1] + x[2];\n"
5145*b7893ccfSSadaf Ebrahimi         "}\n";
5146*b7893ccfSSadaf Ebrahimi 
5147*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, bindStateMinimalShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
5148*b7893ccfSSadaf Ebrahimi     VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
5149*b7893ccfSSadaf Ebrahimi     VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
5150*b7893ccfSSadaf Ebrahimi     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
5151*b7893ccfSSadaf Ebrahimi 
5152*b7893ccfSSadaf Ebrahimi     VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
5153*b7893ccfSSadaf Ebrahimi                                                  VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
5154*b7893ccfSSadaf Ebrahimi 
5155*b7893ccfSSadaf Ebrahimi     VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3};
5156*b7893ccfSSadaf Ebrahimi 
5157*b7893ccfSSadaf Ebrahimi     CreatePipelineHelper pipe(*this);
5158*b7893ccfSSadaf Ebrahimi     pipe.InitInfo();
5159*b7893ccfSSadaf Ebrahimi     pipe.gp_ci_.pTessellationState = &tsci;
5160*b7893ccfSSadaf Ebrahimi     pipe.gp_ci_.pInputAssemblyState = &iasci;
5161*b7893ccfSSadaf Ebrahimi     pipe.shader_stages_ = {vs.GetStageCreateInfo(), tcs.GetStageCreateInfo(), tes.GetStageCreateInfo(), fs.GetStageCreateInfo()};
5162*b7893ccfSSadaf Ebrahimi     pipe.InitState();
5163*b7893ccfSSadaf Ebrahimi     pipe.CreateGraphicsPipeline();
5164*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
5165*b7893ccfSSadaf Ebrahimi }
5166*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CreatePipelineGeometryInputBlockPositive)5167*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CreatePipelineGeometryInputBlockPositive) {
5168*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
5169*b7893ccfSSadaf Ebrahimi         "Test that pipeline validation accepts a user-defined interface block passed into the geometry shader. This is interesting "
5170*b7893ccfSSadaf Ebrahimi         "because the 'extra' array level is not present on the member type, but on the block instance.");
5171*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
5172*b7893ccfSSadaf Ebrahimi 
5173*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
5174*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5175*b7893ccfSSadaf Ebrahimi 
5176*b7893ccfSSadaf Ebrahimi     if (!m_device->phy().features().geometryShader) {
5177*b7893ccfSSadaf Ebrahimi         printf("%s Device does not support geometry shaders; skipped.\n", kSkipPrefix);
5178*b7893ccfSSadaf Ebrahimi         return;
5179*b7893ccfSSadaf Ebrahimi     }
5180*b7893ccfSSadaf Ebrahimi 
5181*b7893ccfSSadaf Ebrahimi     char const *gsSource =
5182*b7893ccfSSadaf Ebrahimi         "#version 450\n"
5183*b7893ccfSSadaf Ebrahimi         "layout(triangles) in;\n"
5184*b7893ccfSSadaf Ebrahimi         "layout(triangle_strip, max_vertices=3) out;\n"
5185*b7893ccfSSadaf Ebrahimi         "layout(location=0) in VertexData { vec4 x; } gs_in[];\n"
5186*b7893ccfSSadaf Ebrahimi         "void main() {\n"
5187*b7893ccfSSadaf Ebrahimi         "   gl_Position = gs_in[0].x;\n"
5188*b7893ccfSSadaf Ebrahimi         "   EmitVertex();\n"
5189*b7893ccfSSadaf Ebrahimi         "}\n";
5190*b7893ccfSSadaf Ebrahimi 
5191*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
5192*b7893ccfSSadaf Ebrahimi     VkShaderObj gs(m_device, gsSource, VK_SHADER_STAGE_GEOMETRY_BIT, this);
5193*b7893ccfSSadaf Ebrahimi     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
5194*b7893ccfSSadaf Ebrahimi 
5195*b7893ccfSSadaf Ebrahimi     CreatePipelineHelper pipe(*this);
5196*b7893ccfSSadaf Ebrahimi     pipe.InitInfo();
5197*b7893ccfSSadaf Ebrahimi     pipe.shader_stages_ = {vs.GetStageCreateInfo(), gs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
5198*b7893ccfSSadaf Ebrahimi     pipe.InitState();
5199*b7893ccfSSadaf Ebrahimi     pipe.CreateGraphicsPipeline();
5200*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
5201*b7893ccfSSadaf Ebrahimi }
5202*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CreatePipeline64BitAttributesPositive)5203*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CreatePipeline64BitAttributesPositive) {
5204*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
5205*b7893ccfSSadaf Ebrahimi         "Test that pipeline validation accepts basic use of 64bit vertex attributes. This is interesting because they consume "
5206*b7893ccfSSadaf Ebrahimi         "multiple locations.");
5207*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
5208*b7893ccfSSadaf Ebrahimi 
5209*b7893ccfSSadaf Ebrahimi     if (!EnableDeviceProfileLayer()) {
5210*b7893ccfSSadaf Ebrahimi         printf("%s Failed to enable device profile layer.\n", kSkipPrefix);
5211*b7893ccfSSadaf Ebrahimi         return;
5212*b7893ccfSSadaf Ebrahimi     }
5213*b7893ccfSSadaf Ebrahimi 
5214*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
5215*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
5216*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5217*b7893ccfSSadaf Ebrahimi 
5218*b7893ccfSSadaf Ebrahimi     if (!m_device->phy().features().shaderFloat64) {
5219*b7893ccfSSadaf Ebrahimi         printf("%s Device does not support 64bit vertex attributes; skipped.\n", kSkipPrefix);
5220*b7893ccfSSadaf Ebrahimi         return;
5221*b7893ccfSSadaf Ebrahimi     }
5222*b7893ccfSSadaf Ebrahimi     // Set 64bit format to support VTX Buffer feature
5223*b7893ccfSSadaf Ebrahimi     PFN_vkSetPhysicalDeviceFormatPropertiesEXT fpvkSetPhysicalDeviceFormatPropertiesEXT = nullptr;
5224*b7893ccfSSadaf Ebrahimi     PFN_vkGetOriginalPhysicalDeviceFormatPropertiesEXT fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT = nullptr;
5225*b7893ccfSSadaf Ebrahimi 
5226*b7893ccfSSadaf Ebrahimi     // Load required functions
5227*b7893ccfSSadaf Ebrahimi     if (!LoadDeviceProfileLayer(fpvkSetPhysicalDeviceFormatPropertiesEXT, fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT)) {
5228*b7893ccfSSadaf Ebrahimi         return;
5229*b7893ccfSSadaf Ebrahimi     }
5230*b7893ccfSSadaf Ebrahimi     VkFormatProperties format_props;
5231*b7893ccfSSadaf Ebrahimi     fpvkGetOriginalPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R64G64B64A64_SFLOAT, &format_props);
5232*b7893ccfSSadaf Ebrahimi     format_props.bufferFeatures |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT;
5233*b7893ccfSSadaf Ebrahimi     fpvkSetPhysicalDeviceFormatPropertiesEXT(gpu(), VK_FORMAT_R64G64B64A64_SFLOAT, format_props);
5234*b7893ccfSSadaf Ebrahimi 
5235*b7893ccfSSadaf Ebrahimi     VkVertexInputBindingDescription input_bindings[1];
5236*b7893ccfSSadaf Ebrahimi     memset(input_bindings, 0, sizeof(input_bindings));
5237*b7893ccfSSadaf Ebrahimi 
5238*b7893ccfSSadaf Ebrahimi     VkVertexInputAttributeDescription input_attribs[4];
5239*b7893ccfSSadaf Ebrahimi     memset(input_attribs, 0, sizeof(input_attribs));
5240*b7893ccfSSadaf Ebrahimi     input_attribs[0].location = 0;
5241*b7893ccfSSadaf Ebrahimi     input_attribs[0].offset = 0;
5242*b7893ccfSSadaf Ebrahimi     input_attribs[0].format = VK_FORMAT_R64G64B64A64_SFLOAT;
5243*b7893ccfSSadaf Ebrahimi     input_attribs[1].location = 2;
5244*b7893ccfSSadaf Ebrahimi     input_attribs[1].offset = 32;
5245*b7893ccfSSadaf Ebrahimi     input_attribs[1].format = VK_FORMAT_R64G64B64A64_SFLOAT;
5246*b7893ccfSSadaf Ebrahimi     input_attribs[2].location = 4;
5247*b7893ccfSSadaf Ebrahimi     input_attribs[2].offset = 64;
5248*b7893ccfSSadaf Ebrahimi     input_attribs[2].format = VK_FORMAT_R64G64B64A64_SFLOAT;
5249*b7893ccfSSadaf Ebrahimi     input_attribs[3].location = 6;
5250*b7893ccfSSadaf Ebrahimi     input_attribs[3].offset = 96;
5251*b7893ccfSSadaf Ebrahimi     input_attribs[3].format = VK_FORMAT_R64G64B64A64_SFLOAT;
5252*b7893ccfSSadaf Ebrahimi 
5253*b7893ccfSSadaf Ebrahimi     char const *vsSource =
5254*b7893ccfSSadaf Ebrahimi         "#version 450\n"
5255*b7893ccfSSadaf Ebrahimi         "\n"
5256*b7893ccfSSadaf Ebrahimi         "layout(location=0) in dmat4 x;\n"
5257*b7893ccfSSadaf Ebrahimi         "void main(){\n"
5258*b7893ccfSSadaf Ebrahimi         "   gl_Position = vec4(x[0][0]);\n"
5259*b7893ccfSSadaf Ebrahimi         "}\n";
5260*b7893ccfSSadaf Ebrahimi 
5261*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
5262*b7893ccfSSadaf Ebrahimi     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
5263*b7893ccfSSadaf Ebrahimi 
5264*b7893ccfSSadaf Ebrahimi     CreatePipelineHelper pipe(*this);
5265*b7893ccfSSadaf Ebrahimi     pipe.InitInfo();
5266*b7893ccfSSadaf Ebrahimi     pipe.vi_ci_.pVertexBindingDescriptions = input_bindings;
5267*b7893ccfSSadaf Ebrahimi     pipe.vi_ci_.vertexBindingDescriptionCount = 1;
5268*b7893ccfSSadaf Ebrahimi     pipe.vi_ci_.pVertexAttributeDescriptions = input_attribs;
5269*b7893ccfSSadaf Ebrahimi     pipe.vi_ci_.vertexAttributeDescriptionCount = 4;
5270*b7893ccfSSadaf Ebrahimi     pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
5271*b7893ccfSSadaf Ebrahimi     pipe.InitState();
5272*b7893ccfSSadaf Ebrahimi     pipe.CreateGraphicsPipeline();
5273*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
5274*b7893ccfSSadaf Ebrahimi }
5275*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CreatePipelineInputAttachmentPositive)5276*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CreatePipelineInputAttachmentPositive) {
5277*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Positive test for a correctly matched input attachment");
5278*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
5279*b7893ccfSSadaf Ebrahimi 
5280*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
5281*b7893ccfSSadaf Ebrahimi 
5282*b7893ccfSSadaf Ebrahimi     char const *fsSource =
5283*b7893ccfSSadaf Ebrahimi         "#version 450\n"
5284*b7893ccfSSadaf Ebrahimi         "\n"
5285*b7893ccfSSadaf Ebrahimi         "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
5286*b7893ccfSSadaf Ebrahimi         "layout(location=0) out vec4 color;\n"
5287*b7893ccfSSadaf Ebrahimi         "void main() {\n"
5288*b7893ccfSSadaf Ebrahimi         "   color = subpassLoad(x);\n"
5289*b7893ccfSSadaf Ebrahimi         "}\n";
5290*b7893ccfSSadaf Ebrahimi 
5291*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
5292*b7893ccfSSadaf Ebrahimi     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
5293*b7893ccfSSadaf Ebrahimi 
5294*b7893ccfSSadaf Ebrahimi     VkPipelineObj pipe(m_device);
5295*b7893ccfSSadaf Ebrahimi     pipe.AddShader(&vs);
5296*b7893ccfSSadaf Ebrahimi     pipe.AddShader(&fs);
5297*b7893ccfSSadaf Ebrahimi     pipe.AddDefaultColorAttachment();
5298*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5299*b7893ccfSSadaf Ebrahimi 
5300*b7893ccfSSadaf Ebrahimi     VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
5301*b7893ccfSSadaf Ebrahimi     const VkDescriptorSetLayoutObj dsl(m_device, {dslb});
5302*b7893ccfSSadaf Ebrahimi     const VkPipelineLayoutObj pl(m_device, {&dsl});
5303*b7893ccfSSadaf Ebrahimi 
5304*b7893ccfSSadaf Ebrahimi     VkAttachmentDescription descs[2] = {
5305*b7893ccfSSadaf Ebrahimi         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
5306*b7893ccfSSadaf Ebrahimi          VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5307*b7893ccfSSadaf Ebrahimi          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
5308*b7893ccfSSadaf Ebrahimi         {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
5309*b7893ccfSSadaf Ebrahimi          VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
5310*b7893ccfSSadaf Ebrahimi     };
5311*b7893ccfSSadaf Ebrahimi     VkAttachmentReference color = {
5312*b7893ccfSSadaf Ebrahimi         0,
5313*b7893ccfSSadaf Ebrahimi         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5314*b7893ccfSSadaf Ebrahimi     };
5315*b7893ccfSSadaf Ebrahimi     VkAttachmentReference input = {
5316*b7893ccfSSadaf Ebrahimi         1,
5317*b7893ccfSSadaf Ebrahimi         VK_IMAGE_LAYOUT_GENERAL,
5318*b7893ccfSSadaf Ebrahimi     };
5319*b7893ccfSSadaf Ebrahimi 
5320*b7893ccfSSadaf Ebrahimi     VkSubpassDescription sd = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input, 1, &color, nullptr, nullptr, 0, nullptr};
5321*b7893ccfSSadaf Ebrahimi 
5322*b7893ccfSSadaf Ebrahimi     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, descs, 1, &sd, 0, nullptr};
5323*b7893ccfSSadaf Ebrahimi     VkRenderPass rp;
5324*b7893ccfSSadaf Ebrahimi     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
5325*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
5326*b7893ccfSSadaf Ebrahimi 
5327*b7893ccfSSadaf Ebrahimi     // should be OK. would go wrong here if it's going to...
5328*b7893ccfSSadaf Ebrahimi     pipe.CreateVKPipeline(pl.handle(), rp);
5329*b7893ccfSSadaf Ebrahimi 
5330*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
5331*b7893ccfSSadaf Ebrahimi 
5332*b7893ccfSSadaf Ebrahimi     vkDestroyRenderPass(m_device->device(), rp, nullptr);
5333*b7893ccfSSadaf Ebrahimi }
5334*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CreateComputePipelineMissingDescriptorUnusedPositive)5335*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CreateComputePipelineMissingDescriptorUnusedPositive) {
5336*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
5337*b7893ccfSSadaf Ebrahimi         "Test that pipeline validation accepts a compute pipeline which declares a descriptor-backed resource which is not "
5338*b7893ccfSSadaf Ebrahimi         "provided, but the shader does not statically use it. This is interesting because it requires compute pipelines to have a "
5339*b7893ccfSSadaf Ebrahimi         "proper descriptor use walk, which they didn't for some time.");
5340*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
5341*b7893ccfSSadaf Ebrahimi 
5342*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
5343*b7893ccfSSadaf Ebrahimi 
5344*b7893ccfSSadaf Ebrahimi     char const *csSource =
5345*b7893ccfSSadaf Ebrahimi         "#version 450\n"
5346*b7893ccfSSadaf Ebrahimi         "\n"
5347*b7893ccfSSadaf Ebrahimi         "layout(local_size_x=1) in;\n"
5348*b7893ccfSSadaf Ebrahimi         "layout(set=0, binding=0) buffer block { vec4 x; };\n"
5349*b7893ccfSSadaf Ebrahimi         "void main(){\n"
5350*b7893ccfSSadaf Ebrahimi         "   // x is not used.\n"
5351*b7893ccfSSadaf Ebrahimi         "}\n";
5352*b7893ccfSSadaf Ebrahimi 
5353*b7893ccfSSadaf Ebrahimi     CreateComputePipelineHelper pipe(*this);
5354*b7893ccfSSadaf Ebrahimi     pipe.InitInfo();
5355*b7893ccfSSadaf Ebrahimi     pipe.cs_.reset(new VkShaderObj(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this));
5356*b7893ccfSSadaf Ebrahimi     pipe.InitState();
5357*b7893ccfSSadaf Ebrahimi     pipe.CreateComputePipeline();
5358*b7893ccfSSadaf Ebrahimi 
5359*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
5360*b7893ccfSSadaf Ebrahimi }
5361*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CreateComputePipelineCombinedImageSamplerConsumedAsSampler)5362*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsSampler) {
5363*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
5364*b7893ccfSSadaf Ebrahimi         "Test that pipeline validation accepts a shader consuming only the sampler portion of a combined image + sampler");
5365*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
5366*b7893ccfSSadaf Ebrahimi 
5367*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
5368*b7893ccfSSadaf Ebrahimi 
5369*b7893ccfSSadaf Ebrahimi     std::vector<VkDescriptorSetLayoutBinding> bindings = {
5370*b7893ccfSSadaf Ebrahimi         {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
5371*b7893ccfSSadaf Ebrahimi         {1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
5372*b7893ccfSSadaf Ebrahimi         {2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
5373*b7893ccfSSadaf Ebrahimi     };
5374*b7893ccfSSadaf Ebrahimi 
5375*b7893ccfSSadaf Ebrahimi     char const *csSource =
5376*b7893ccfSSadaf Ebrahimi         "#version 450\n"
5377*b7893ccfSSadaf Ebrahimi         "\n"
5378*b7893ccfSSadaf Ebrahimi         "layout(local_size_x=1) in;\n"
5379*b7893ccfSSadaf Ebrahimi         "layout(set=0, binding=0) uniform sampler s;\n"
5380*b7893ccfSSadaf Ebrahimi         "layout(set=0, binding=1) uniform texture2D t;\n"
5381*b7893ccfSSadaf Ebrahimi         "layout(set=0, binding=2) buffer block { vec4 x; };\n"
5382*b7893ccfSSadaf Ebrahimi         "void main() {\n"
5383*b7893ccfSSadaf Ebrahimi         "   x = texture(sampler2D(t, s), vec2(0));\n"
5384*b7893ccfSSadaf Ebrahimi         "}\n";
5385*b7893ccfSSadaf Ebrahimi     CreateComputePipelineHelper pipe(*this);
5386*b7893ccfSSadaf Ebrahimi     pipe.InitInfo();
5387*b7893ccfSSadaf Ebrahimi     pipe.dsl_bindings_.resize(bindings.size());
5388*b7893ccfSSadaf Ebrahimi     memcpy(pipe.dsl_bindings_.data(), bindings.data(), bindings.size() * sizeof(VkDescriptorSetLayoutBinding));
5389*b7893ccfSSadaf Ebrahimi     pipe.cs_.reset(new VkShaderObj(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this));
5390*b7893ccfSSadaf Ebrahimi     pipe.InitState();
5391*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
5392*b7893ccfSSadaf Ebrahimi     pipe.CreateComputePipeline();
5393*b7893ccfSSadaf Ebrahimi 
5394*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
5395*b7893ccfSSadaf Ebrahimi }
5396*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CreateComputePipelineCombinedImageSamplerConsumedAsImage)5397*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsImage) {
5398*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
5399*b7893ccfSSadaf Ebrahimi         "Test that pipeline validation accepts a shader consuming only the image portion of a combined image + sampler");
5400*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
5401*b7893ccfSSadaf Ebrahimi 
5402*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
5403*b7893ccfSSadaf Ebrahimi 
5404*b7893ccfSSadaf Ebrahimi     std::vector<VkDescriptorSetLayoutBinding> bindings = {
5405*b7893ccfSSadaf Ebrahimi         {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
5406*b7893ccfSSadaf Ebrahimi         {1, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
5407*b7893ccfSSadaf Ebrahimi         {2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
5408*b7893ccfSSadaf Ebrahimi     };
5409*b7893ccfSSadaf Ebrahimi 
5410*b7893ccfSSadaf Ebrahimi     char const *csSource =
5411*b7893ccfSSadaf Ebrahimi         "#version 450\n"
5412*b7893ccfSSadaf Ebrahimi         "\n"
5413*b7893ccfSSadaf Ebrahimi         "layout(local_size_x=1) in;\n"
5414*b7893ccfSSadaf Ebrahimi         "layout(set=0, binding=0) uniform texture2D t;\n"
5415*b7893ccfSSadaf Ebrahimi         "layout(set=0, binding=1) uniform sampler s;\n"
5416*b7893ccfSSadaf Ebrahimi         "layout(set=0, binding=2) buffer block { vec4 x; };\n"
5417*b7893ccfSSadaf Ebrahimi         "void main() {\n"
5418*b7893ccfSSadaf Ebrahimi         "   x = texture(sampler2D(t, s), vec2(0));\n"
5419*b7893ccfSSadaf Ebrahimi         "}\n";
5420*b7893ccfSSadaf Ebrahimi     CreateComputePipelineHelper pipe(*this);
5421*b7893ccfSSadaf Ebrahimi     pipe.InitInfo();
5422*b7893ccfSSadaf Ebrahimi     pipe.dsl_bindings_.resize(bindings.size());
5423*b7893ccfSSadaf Ebrahimi     memcpy(pipe.dsl_bindings_.data(), bindings.data(), bindings.size() * sizeof(VkDescriptorSetLayoutBinding));
5424*b7893ccfSSadaf Ebrahimi     pipe.cs_.reset(new VkShaderObj(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this));
5425*b7893ccfSSadaf Ebrahimi     pipe.InitState();
5426*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
5427*b7893ccfSSadaf Ebrahimi     pipe.CreateComputePipeline();
5428*b7893ccfSSadaf Ebrahimi 
5429*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
5430*b7893ccfSSadaf Ebrahimi }
5431*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CreateComputePipelineCombinedImageSamplerConsumedAsBoth)5432*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsBoth) {
5433*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
5434*b7893ccfSSadaf Ebrahimi         "Test that pipeline validation accepts a shader consuming both the sampler and the image of a combined image+sampler but "
5435*b7893ccfSSadaf Ebrahimi         "via separate variables");
5436*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
5437*b7893ccfSSadaf Ebrahimi 
5438*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
5439*b7893ccfSSadaf Ebrahimi 
5440*b7893ccfSSadaf Ebrahimi     std::vector<VkDescriptorSetLayoutBinding> bindings = {
5441*b7893ccfSSadaf Ebrahimi         {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
5442*b7893ccfSSadaf Ebrahimi         {1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
5443*b7893ccfSSadaf Ebrahimi     };
5444*b7893ccfSSadaf Ebrahimi 
5445*b7893ccfSSadaf Ebrahimi     char const *csSource =
5446*b7893ccfSSadaf Ebrahimi         "#version 450\n"
5447*b7893ccfSSadaf Ebrahimi         "\n"
5448*b7893ccfSSadaf Ebrahimi         "layout(local_size_x=1) in;\n"
5449*b7893ccfSSadaf Ebrahimi         "layout(set=0, binding=0) uniform texture2D t;\n"
5450*b7893ccfSSadaf Ebrahimi         "layout(set=0, binding=0) uniform sampler s;  // both binding 0!\n"
5451*b7893ccfSSadaf Ebrahimi         "layout(set=0, binding=1) buffer block { vec4 x; };\n"
5452*b7893ccfSSadaf Ebrahimi         "void main() {\n"
5453*b7893ccfSSadaf Ebrahimi         "   x = texture(sampler2D(t, s), vec2(0));\n"
5454*b7893ccfSSadaf Ebrahimi         "}\n";
5455*b7893ccfSSadaf Ebrahimi     CreateComputePipelineHelper pipe(*this);
5456*b7893ccfSSadaf Ebrahimi     pipe.InitInfo();
5457*b7893ccfSSadaf Ebrahimi     pipe.dsl_bindings_.resize(bindings.size());
5458*b7893ccfSSadaf Ebrahimi     memcpy(pipe.dsl_bindings_.data(), bindings.data(), bindings.size() * sizeof(VkDescriptorSetLayoutBinding));
5459*b7893ccfSSadaf Ebrahimi     pipe.cs_.reset(new VkShaderObj(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this));
5460*b7893ccfSSadaf Ebrahimi     pipe.InitState();
5461*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
5462*b7893ccfSSadaf Ebrahimi     pipe.CreateComputePipeline();
5463*b7893ccfSSadaf Ebrahimi 
5464*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
5465*b7893ccfSSadaf Ebrahimi }
5466*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CreateDescriptorSetBindingWithIgnoredSamplers)5467*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CreateDescriptorSetBindingWithIgnoredSamplers) {
5468*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Test that layers conditionally do ignore the pImmutableSamplers on vkCreateDescriptorSetLayout");
5469*b7893ccfSSadaf Ebrahimi 
5470*b7893ccfSSadaf Ebrahimi     bool prop2_found = false;
5471*b7893ccfSSadaf Ebrahimi     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
5472*b7893ccfSSadaf Ebrahimi         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5473*b7893ccfSSadaf Ebrahimi         prop2_found = true;
5474*b7893ccfSSadaf Ebrahimi     } else {
5475*b7893ccfSSadaf Ebrahimi         printf("%s %s Extension not supported, skipping push descriptor sub-tests\n", kSkipPrefix,
5476*b7893ccfSSadaf Ebrahimi                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5477*b7893ccfSSadaf Ebrahimi     }
5478*b7893ccfSSadaf Ebrahimi 
5479*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
5480*b7893ccfSSadaf Ebrahimi     bool push_descriptor_found = false;
5481*b7893ccfSSadaf Ebrahimi     if (prop2_found && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)) {
5482*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
5483*b7893ccfSSadaf Ebrahimi 
5484*b7893ccfSSadaf Ebrahimi         // In addition to the extension being supported we need to have at least one available
5485*b7893ccfSSadaf Ebrahimi         // Some implementations report an invalid maxPushDescriptors of 0
5486*b7893ccfSSadaf Ebrahimi         push_descriptor_found = GetPushDescriptorProperties(instance(), gpu()).maxPushDescriptors > 0;
5487*b7893ccfSSadaf Ebrahimi     } else {
5488*b7893ccfSSadaf Ebrahimi         printf("%s %s Extension not supported, skipping push descriptor sub-tests\n", kSkipPrefix,
5489*b7893ccfSSadaf Ebrahimi                VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
5490*b7893ccfSSadaf Ebrahimi     }
5491*b7893ccfSSadaf Ebrahimi 
5492*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
5493*b7893ccfSSadaf Ebrahimi     const uint64_t fake_address_64 = 0xCDCDCDCDCDCDCDCD;
5494*b7893ccfSSadaf Ebrahimi     const uint64_t fake_address_32 = 0xCDCDCDCD;
5495*b7893ccfSSadaf Ebrahimi     const void *fake_pointer =
5496*b7893ccfSSadaf Ebrahimi         sizeof(void *) == 8 ? reinterpret_cast<void *>(fake_address_64) : reinterpret_cast<void *>(fake_address_32);
5497*b7893ccfSSadaf Ebrahimi     const VkSampler *hopefully_undereferencable_pointer = reinterpret_cast<const VkSampler *>(fake_pointer);
5498*b7893ccfSSadaf Ebrahimi 
5499*b7893ccfSSadaf Ebrahimi     // regular descriptors
5500*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
5501*b7893ccfSSadaf Ebrahimi     {
5502*b7893ccfSSadaf Ebrahimi         const VkDescriptorSetLayoutBinding non_sampler_bindings[] = {
5503*b7893ccfSSadaf Ebrahimi             {0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
5504*b7893ccfSSadaf Ebrahimi             {1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
5505*b7893ccfSSadaf Ebrahimi             {2, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
5506*b7893ccfSSadaf Ebrahimi             {3, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
5507*b7893ccfSSadaf Ebrahimi             {4, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
5508*b7893ccfSSadaf Ebrahimi             {5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
5509*b7893ccfSSadaf Ebrahimi             {6, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
5510*b7893ccfSSadaf Ebrahimi             {7, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
5511*b7893ccfSSadaf Ebrahimi             {8, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
5512*b7893ccfSSadaf Ebrahimi         };
5513*b7893ccfSSadaf Ebrahimi         const VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0,
5514*b7893ccfSSadaf Ebrahimi                                                        static_cast<uint32_t>(size(non_sampler_bindings)), non_sampler_bindings};
5515*b7893ccfSSadaf Ebrahimi         VkDescriptorSetLayout dsl;
5516*b7893ccfSSadaf Ebrahimi         const VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
5517*b7893ccfSSadaf Ebrahimi         ASSERT_VK_SUCCESS(err);
5518*b7893ccfSSadaf Ebrahimi         vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
5519*b7893ccfSSadaf Ebrahimi     }
5520*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
5521*b7893ccfSSadaf Ebrahimi 
5522*b7893ccfSSadaf Ebrahimi     if (push_descriptor_found) {
5523*b7893ccfSSadaf Ebrahimi         // push descriptors
5524*b7893ccfSSadaf Ebrahimi         m_errorMonitor->ExpectSuccess();
5525*b7893ccfSSadaf Ebrahimi         {
5526*b7893ccfSSadaf Ebrahimi             const VkDescriptorSetLayoutBinding non_sampler_bindings[] = {
5527*b7893ccfSSadaf Ebrahimi                 {0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
5528*b7893ccfSSadaf Ebrahimi                 {1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
5529*b7893ccfSSadaf Ebrahimi                 {2, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
5530*b7893ccfSSadaf Ebrahimi                 {3, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
5531*b7893ccfSSadaf Ebrahimi                 {4, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
5532*b7893ccfSSadaf Ebrahimi                 {5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
5533*b7893ccfSSadaf Ebrahimi                 {6, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, hopefully_undereferencable_pointer},
5534*b7893ccfSSadaf Ebrahimi             };
5535*b7893ccfSSadaf Ebrahimi             const VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr,
5536*b7893ccfSSadaf Ebrahimi                                                            VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,
5537*b7893ccfSSadaf Ebrahimi                                                            static_cast<uint32_t>(size(non_sampler_bindings)), non_sampler_bindings};
5538*b7893ccfSSadaf Ebrahimi             VkDescriptorSetLayout dsl;
5539*b7893ccfSSadaf Ebrahimi             const VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
5540*b7893ccfSSadaf Ebrahimi             ASSERT_VK_SUCCESS(err);
5541*b7893ccfSSadaf Ebrahimi             vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
5542*b7893ccfSSadaf Ebrahimi         }
5543*b7893ccfSSadaf Ebrahimi         m_errorMonitor->VerifyNotFound();
5544*b7893ccfSSadaf Ebrahimi     }
5545*b7893ccfSSadaf Ebrahimi }
TEST_F(VkPositiveLayerTest,GpuValidationInlineUniformBlock)5546*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, GpuValidationInlineUniformBlock) {
5547*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("GPU validation: Make sure inline uniform blocks don't generate false validation errors");
5548*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
5549*b7893ccfSSadaf Ebrahimi     VkValidationFeatureEnableEXT enables[] = {VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT};
5550*b7893ccfSSadaf Ebrahimi     VkValidationFeaturesEXT features = {};
5551*b7893ccfSSadaf Ebrahimi     features.sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT;
5552*b7893ccfSSadaf Ebrahimi     features.enabledValidationFeatureCount = 1;
5553*b7893ccfSSadaf Ebrahimi     features.pEnabledValidationFeatures = enables;
5554*b7893ccfSSadaf Ebrahimi     bool descriptor_indexing = CheckDescriptorIndexingSupportAndInitFramework(this, m_instance_extension_names,
5555*b7893ccfSSadaf Ebrahimi                                                                               m_device_extension_names, &features, m_errorMonitor);
5556*b7893ccfSSadaf Ebrahimi     if (DeviceIsMockICD() || DeviceSimulation()) {
5557*b7893ccfSSadaf Ebrahimi         printf("%s Test not supported by MockICD, skipping tests\n", kSkipPrefix);
5558*b7893ccfSSadaf Ebrahimi         return;
5559*b7893ccfSSadaf Ebrahimi     }
5560*b7893ccfSSadaf Ebrahimi     VkPhysicalDeviceFeatures2KHR features2 = {};
5561*b7893ccfSSadaf Ebrahimi     auto indexing_features = lvl_init_struct<VkPhysicalDeviceDescriptorIndexingFeaturesEXT>();
5562*b7893ccfSSadaf Ebrahimi     auto inline_uniform_block_features = lvl_init_struct<VkPhysicalDeviceInlineUniformBlockFeaturesEXT>(&indexing_features);
5563*b7893ccfSSadaf Ebrahimi     bool inline_uniform_block = DeviceExtensionSupported(gpu(), nullptr, VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME);
5564*b7893ccfSSadaf Ebrahimi     if (!(descriptor_indexing && inline_uniform_block)) {
5565*b7893ccfSSadaf Ebrahimi         printf("Descriptor indexing and/or inline uniform block not supported Skipping test\n");
5566*b7893ccfSSadaf Ebrahimi         return;
5567*b7893ccfSSadaf Ebrahimi     }
5568*b7893ccfSSadaf Ebrahimi     m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
5569*b7893ccfSSadaf Ebrahimi     m_device_extension_names.push_back(VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME);
5570*b7893ccfSSadaf Ebrahimi     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
5571*b7893ccfSSadaf Ebrahimi         (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
5572*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
5573*b7893ccfSSadaf Ebrahimi 
5574*b7893ccfSSadaf Ebrahimi     features2 = lvl_init_struct<VkPhysicalDeviceFeatures2KHR>(&inline_uniform_block_features);
5575*b7893ccfSSadaf Ebrahimi     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
5576*b7893ccfSSadaf Ebrahimi     if (!indexing_features.descriptorBindingPartiallyBound || !inline_uniform_block_features.inlineUniformBlock) {
5577*b7893ccfSSadaf Ebrahimi         printf("Not all features supported, skipping test\n");
5578*b7893ccfSSadaf Ebrahimi         return;
5579*b7893ccfSSadaf Ebrahimi     }
5580*b7893ccfSSadaf Ebrahimi     auto inline_uniform_props = lvl_init_struct<VkPhysicalDeviceInlineUniformBlockPropertiesEXT>();
5581*b7893ccfSSadaf Ebrahimi     auto prop2 = lvl_init_struct<VkPhysicalDeviceProperties2KHR>(&inline_uniform_props);
5582*b7893ccfSSadaf Ebrahimi     vkGetPhysicalDeviceProperties2(gpu(), &prop2);
5583*b7893ccfSSadaf Ebrahimi 
5584*b7893ccfSSadaf Ebrahimi     VkCommandPoolCreateFlags pool_flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
5585*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &features2, pool_flags));
5586*b7893ccfSSadaf Ebrahimi     if (m_device->props.apiVersion < VK_API_VERSION_1_1) {
5587*b7893ccfSSadaf Ebrahimi         printf("%s GPU-Assisted validation test requires Vulkan 1.1+.\n", kSkipPrefix);
5588*b7893ccfSSadaf Ebrahimi         return;
5589*b7893ccfSSadaf Ebrahimi     }
5590*b7893ccfSSadaf Ebrahimi     auto c_queue = m_device->GetDefaultComputeQueue();
5591*b7893ccfSSadaf Ebrahimi     if (nullptr == c_queue) {
5592*b7893ccfSSadaf Ebrahimi         printf("Compute not supported, skipping test\n");
5593*b7893ccfSSadaf Ebrahimi         return;
5594*b7893ccfSSadaf Ebrahimi     }
5595*b7893ccfSSadaf Ebrahimi 
5596*b7893ccfSSadaf Ebrahimi     uint32_t qfi = 0;
5597*b7893ccfSSadaf Ebrahimi     VkBufferCreateInfo bci = {};
5598*b7893ccfSSadaf Ebrahimi     bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
5599*b7893ccfSSadaf Ebrahimi     bci.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
5600*b7893ccfSSadaf Ebrahimi     bci.size = 4;
5601*b7893ccfSSadaf Ebrahimi     bci.queueFamilyIndexCount = 1;
5602*b7893ccfSSadaf Ebrahimi     bci.pQueueFamilyIndices = &qfi;
5603*b7893ccfSSadaf Ebrahimi     VkBufferObj buffer0;
5604*b7893ccfSSadaf Ebrahimi     VkMemoryPropertyFlags mem_props = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
5605*b7893ccfSSadaf Ebrahimi     buffer0.init(*m_device, bci, mem_props);
5606*b7893ccfSSadaf Ebrahimi 
5607*b7893ccfSSadaf Ebrahimi     VkDescriptorBindingFlagsEXT ds_binding_flags[2] = {};
5608*b7893ccfSSadaf Ebrahimi     ds_binding_flags[1] = VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT;
5609*b7893ccfSSadaf Ebrahimi     VkDescriptorSetLayoutBindingFlagsCreateInfoEXT layout_createinfo_binding_flags[1] = {};
5610*b7893ccfSSadaf Ebrahimi     layout_createinfo_binding_flags[0].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT;
5611*b7893ccfSSadaf Ebrahimi     layout_createinfo_binding_flags[0].pNext = NULL;
5612*b7893ccfSSadaf Ebrahimi     layout_createinfo_binding_flags[0].bindingCount = 2;
5613*b7893ccfSSadaf Ebrahimi     layout_createinfo_binding_flags[0].pBindingFlags = ds_binding_flags;
5614*b7893ccfSSadaf Ebrahimi 
5615*b7893ccfSSadaf Ebrahimi     OneOffDescriptorSet descriptor_set(m_device,
5616*b7893ccfSSadaf Ebrahimi                                        {
5617*b7893ccfSSadaf Ebrahimi                                            {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_ALL, nullptr},
5618*b7893ccfSSadaf Ebrahimi                                            {1, VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT, 20, VK_SHADER_STAGE_ALL,
5619*b7893ccfSSadaf Ebrahimi                                             nullptr},  // 16 bytes for ivec4, 4 more for int
5620*b7893ccfSSadaf Ebrahimi                                        },
5621*b7893ccfSSadaf Ebrahimi                                        0, layout_createinfo_binding_flags, 0);
5622*b7893ccfSSadaf Ebrahimi     const VkPipelineLayoutObj pipeline_layout(m_device, {&descriptor_set.layout_});
5623*b7893ccfSSadaf Ebrahimi 
5624*b7893ccfSSadaf Ebrahimi     VkDescriptorBufferInfo buffer_info[1] = {};
5625*b7893ccfSSadaf Ebrahimi     buffer_info[0].buffer = buffer0.handle();
5626*b7893ccfSSadaf Ebrahimi     buffer_info[0].offset = 0;
5627*b7893ccfSSadaf Ebrahimi     buffer_info[0].range = sizeof(uint32_t);
5628*b7893ccfSSadaf Ebrahimi 
5629*b7893ccfSSadaf Ebrahimi     const uint32_t test_data = 0xdeadca7;
5630*b7893ccfSSadaf Ebrahimi     VkWriteDescriptorSetInlineUniformBlockEXT write_inline_uniform = {};
5631*b7893ccfSSadaf Ebrahimi     write_inline_uniform.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT;
5632*b7893ccfSSadaf Ebrahimi     write_inline_uniform.dataSize = 4;
5633*b7893ccfSSadaf Ebrahimi     write_inline_uniform.pData = &test_data;
5634*b7893ccfSSadaf Ebrahimi 
5635*b7893ccfSSadaf Ebrahimi     VkWriteDescriptorSet descriptor_writes[2] = {};
5636*b7893ccfSSadaf Ebrahimi     descriptor_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
5637*b7893ccfSSadaf Ebrahimi     descriptor_writes[0].dstSet = descriptor_set.set_;
5638*b7893ccfSSadaf Ebrahimi     descriptor_writes[0].dstBinding = 0;
5639*b7893ccfSSadaf Ebrahimi     descriptor_writes[0].descriptorCount = 1;
5640*b7893ccfSSadaf Ebrahimi     descriptor_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
5641*b7893ccfSSadaf Ebrahimi     descriptor_writes[0].pBufferInfo = buffer_info;
5642*b7893ccfSSadaf Ebrahimi 
5643*b7893ccfSSadaf Ebrahimi     descriptor_writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
5644*b7893ccfSSadaf Ebrahimi     descriptor_writes[1].dstSet = descriptor_set.set_;
5645*b7893ccfSSadaf Ebrahimi     descriptor_writes[1].dstBinding = 1;
5646*b7893ccfSSadaf Ebrahimi     descriptor_writes[1].dstArrayElement = 16;  // Skip first 16 bytes (dummy)
5647*b7893ccfSSadaf Ebrahimi     descriptor_writes[1].descriptorCount = 4;   // Write 4 bytes to val
5648*b7893ccfSSadaf Ebrahimi     descriptor_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT;
5649*b7893ccfSSadaf Ebrahimi     descriptor_writes[1].pNext = &write_inline_uniform;
5650*b7893ccfSSadaf Ebrahimi     vkUpdateDescriptorSets(m_device->device(), 2, descriptor_writes, 0, NULL);
5651*b7893ccfSSadaf Ebrahimi 
5652*b7893ccfSSadaf Ebrahimi     char const *csSource =
5653*b7893ccfSSadaf Ebrahimi         "#version 450\n"
5654*b7893ccfSSadaf Ebrahimi         "#extension GL_EXT_nonuniform_qualifier : enable\n "
5655*b7893ccfSSadaf Ebrahimi         "layout(set = 0, binding = 0) buffer StorageBuffer { uint index; } u_index;"
5656*b7893ccfSSadaf Ebrahimi         "layout(set = 0, binding = 1) uniform inlineubodef { ivec4 dummy; int val; } inlineubo;\n"
5657*b7893ccfSSadaf Ebrahimi 
5658*b7893ccfSSadaf Ebrahimi         "void main() {\n"
5659*b7893ccfSSadaf Ebrahimi         "    u_index.index = inlineubo.val;\n"
5660*b7893ccfSSadaf Ebrahimi         "}\n";
5661*b7893ccfSSadaf Ebrahimi 
5662*b7893ccfSSadaf Ebrahimi     auto shader_module = new VkShaderObj(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
5663*b7893ccfSSadaf Ebrahimi 
5664*b7893ccfSSadaf Ebrahimi     VkPipelineShaderStageCreateInfo stage;
5665*b7893ccfSSadaf Ebrahimi     stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
5666*b7893ccfSSadaf Ebrahimi     stage.pNext = nullptr;
5667*b7893ccfSSadaf Ebrahimi     stage.flags = 0;
5668*b7893ccfSSadaf Ebrahimi     stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
5669*b7893ccfSSadaf Ebrahimi     stage.module = shader_module->handle();
5670*b7893ccfSSadaf Ebrahimi     stage.pName = "main";
5671*b7893ccfSSadaf Ebrahimi     stage.pSpecializationInfo = nullptr;
5672*b7893ccfSSadaf Ebrahimi 
5673*b7893ccfSSadaf Ebrahimi     // CreateComputePipelines
5674*b7893ccfSSadaf Ebrahimi     VkComputePipelineCreateInfo pipeline_info = {};
5675*b7893ccfSSadaf Ebrahimi     pipeline_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
5676*b7893ccfSSadaf Ebrahimi     pipeline_info.pNext = nullptr;
5677*b7893ccfSSadaf Ebrahimi     pipeline_info.flags = 0;
5678*b7893ccfSSadaf Ebrahimi     pipeline_info.layout = pipeline_layout.handle();
5679*b7893ccfSSadaf Ebrahimi     pipeline_info.basePipelineHandle = VK_NULL_HANDLE;
5680*b7893ccfSSadaf Ebrahimi     pipeline_info.basePipelineIndex = -1;
5681*b7893ccfSSadaf Ebrahimi     pipeline_info.stage = stage;
5682*b7893ccfSSadaf Ebrahimi 
5683*b7893ccfSSadaf Ebrahimi     VkPipeline c_pipeline;
5684*b7893ccfSSadaf Ebrahimi     vkCreateComputePipelines(device(), VK_NULL_HANDLE, 1, &pipeline_info, nullptr, &c_pipeline);
5685*b7893ccfSSadaf Ebrahimi 
5686*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
5687*b7893ccfSSadaf Ebrahimi     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, c_pipeline);
5688*b7893ccfSSadaf Ebrahimi     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_layout.handle(), 0, 1,
5689*b7893ccfSSadaf Ebrahimi                             &descriptor_set.set_, 0, nullptr);
5690*b7893ccfSSadaf Ebrahimi     vkCmdDispatch(m_commandBuffer->handle(), 1, 1, 1);
5691*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
5692*b7893ccfSSadaf Ebrahimi 
5693*b7893ccfSSadaf Ebrahimi     VkSubmitInfo submit_info = {};
5694*b7893ccfSSadaf Ebrahimi     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
5695*b7893ccfSSadaf Ebrahimi     submit_info.commandBufferCount = 1;
5696*b7893ccfSSadaf Ebrahimi     submit_info.pCommandBuffers = &m_commandBuffer->handle();
5697*b7893ccfSSadaf Ebrahimi     vkQueueSubmit(c_queue->handle(), 1, &submit_info, VK_NULL_HANDLE);
5698*b7893ccfSSadaf Ebrahimi     vkQueueWaitIdle(m_device->m_queue);
5699*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
5700*b7893ccfSSadaf Ebrahimi     vkDestroyPipeline(m_device->handle(), c_pipeline, NULL);
5701*b7893ccfSSadaf Ebrahimi     vkDestroyShaderModule(m_device->handle(), shader_module->handle(), NULL);
5702*b7893ccfSSadaf Ebrahimi 
5703*b7893ccfSSadaf Ebrahimi     uint32_t *data = (uint32_t *)buffer0.memory().map();
5704*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(*data = test_data);
5705*b7893ccfSSadaf Ebrahimi     buffer0.memory().unmap();
5706*b7893ccfSSadaf Ebrahimi }
5707*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,Maintenance1Tests)5708*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, Maintenance1Tests) {
5709*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Validate various special cases for the Maintenance1_KHR extension");
5710*b7893ccfSSadaf Ebrahimi 
5711*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
5712*b7893ccfSSadaf Ebrahimi     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME)) {
5713*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
5714*b7893ccfSSadaf Ebrahimi     } else {
5715*b7893ccfSSadaf Ebrahimi         printf("%s Maintenance1 Extension not supported, skipping tests\n", kSkipPrefix);
5716*b7893ccfSSadaf Ebrahimi         return;
5717*b7893ccfSSadaf Ebrahimi     }
5718*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
5719*b7893ccfSSadaf Ebrahimi 
5720*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
5721*b7893ccfSSadaf Ebrahimi 
5722*b7893ccfSSadaf Ebrahimi     VkCommandBufferObj cmd_buf(m_device, m_commandPool);
5723*b7893ccfSSadaf Ebrahimi     cmd_buf.begin();
5724*b7893ccfSSadaf Ebrahimi     // Set Negative height, should give error if Maintenance 1 is not enabled
5725*b7893ccfSSadaf Ebrahimi     VkViewport viewport = {0, 0, 16, -16, 0, 1};
5726*b7893ccfSSadaf Ebrahimi     vkCmdSetViewport(cmd_buf.handle(), 0, 1, &viewport);
5727*b7893ccfSSadaf Ebrahimi     cmd_buf.end();
5728*b7893ccfSSadaf Ebrahimi 
5729*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
5730*b7893ccfSSadaf Ebrahimi }
5731*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,ValidStructPNext)5732*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, ValidStructPNext) {
5733*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Verify that a valid pNext value is handled correctly");
5734*b7893ccfSSadaf Ebrahimi 
5735*b7893ccfSSadaf Ebrahimi     // Positive test to check parameter_validation and unique_objects support for NV_dedicated_allocation
5736*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
5737*b7893ccfSSadaf Ebrahimi     if (DeviceExtensionSupported(gpu(), nullptr, VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME)) {
5738*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME);
5739*b7893ccfSSadaf Ebrahimi     } else {
5740*b7893ccfSSadaf Ebrahimi         printf("%s VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME Extension not supported, skipping test\n", kSkipPrefix);
5741*b7893ccfSSadaf Ebrahimi         return;
5742*b7893ccfSSadaf Ebrahimi     }
5743*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
5744*b7893ccfSSadaf Ebrahimi 
5745*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
5746*b7893ccfSSadaf Ebrahimi 
5747*b7893ccfSSadaf Ebrahimi     VkDedicatedAllocationBufferCreateInfoNV dedicated_buffer_create_info = {};
5748*b7893ccfSSadaf Ebrahimi     dedicated_buffer_create_info.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV;
5749*b7893ccfSSadaf Ebrahimi     dedicated_buffer_create_info.pNext = nullptr;
5750*b7893ccfSSadaf Ebrahimi     dedicated_buffer_create_info.dedicatedAllocation = VK_TRUE;
5751*b7893ccfSSadaf Ebrahimi 
5752*b7893ccfSSadaf Ebrahimi     uint32_t queue_family_index = 0;
5753*b7893ccfSSadaf Ebrahimi     VkBufferCreateInfo buffer_create_info = {};
5754*b7893ccfSSadaf Ebrahimi     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
5755*b7893ccfSSadaf Ebrahimi     buffer_create_info.pNext = &dedicated_buffer_create_info;
5756*b7893ccfSSadaf Ebrahimi     buffer_create_info.size = 1024;
5757*b7893ccfSSadaf Ebrahimi     buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
5758*b7893ccfSSadaf Ebrahimi     buffer_create_info.queueFamilyIndexCount = 1;
5759*b7893ccfSSadaf Ebrahimi     buffer_create_info.pQueueFamilyIndices = &queue_family_index;
5760*b7893ccfSSadaf Ebrahimi 
5761*b7893ccfSSadaf Ebrahimi     VkBuffer buffer;
5762*b7893ccfSSadaf Ebrahimi     VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
5763*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
5764*b7893ccfSSadaf Ebrahimi 
5765*b7893ccfSSadaf Ebrahimi     VkMemoryRequirements memory_reqs;
5766*b7893ccfSSadaf Ebrahimi     vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
5767*b7893ccfSSadaf Ebrahimi 
5768*b7893ccfSSadaf Ebrahimi     VkDedicatedAllocationMemoryAllocateInfoNV dedicated_memory_info = {};
5769*b7893ccfSSadaf Ebrahimi     dedicated_memory_info.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV;
5770*b7893ccfSSadaf Ebrahimi     dedicated_memory_info.pNext = nullptr;
5771*b7893ccfSSadaf Ebrahimi     dedicated_memory_info.buffer = buffer;
5772*b7893ccfSSadaf Ebrahimi     dedicated_memory_info.image = VK_NULL_HANDLE;
5773*b7893ccfSSadaf Ebrahimi 
5774*b7893ccfSSadaf Ebrahimi     VkMemoryAllocateInfo memory_info = {};
5775*b7893ccfSSadaf Ebrahimi     memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
5776*b7893ccfSSadaf Ebrahimi     memory_info.pNext = &dedicated_memory_info;
5777*b7893ccfSSadaf Ebrahimi     memory_info.allocationSize = memory_reqs.size;
5778*b7893ccfSSadaf Ebrahimi 
5779*b7893ccfSSadaf Ebrahimi     bool pass;
5780*b7893ccfSSadaf Ebrahimi     pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
5781*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(pass);
5782*b7893ccfSSadaf Ebrahimi 
5783*b7893ccfSSadaf Ebrahimi     VkDeviceMemory buffer_memory;
5784*b7893ccfSSadaf Ebrahimi     err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
5785*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
5786*b7893ccfSSadaf Ebrahimi 
5787*b7893ccfSSadaf Ebrahimi     err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
5788*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
5789*b7893ccfSSadaf Ebrahimi 
5790*b7893ccfSSadaf Ebrahimi     vkDestroyBuffer(m_device->device(), buffer, NULL);
5791*b7893ccfSSadaf Ebrahimi     vkFreeMemory(m_device->device(), buffer_memory, NULL);
5792*b7893ccfSSadaf Ebrahimi 
5793*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
5794*b7893ccfSSadaf Ebrahimi }
5795*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,PSOPolygonModeValid)5796*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, PSOPolygonModeValid) {
5797*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Verify that using a solid polygon fill mode works correctly.");
5798*b7893ccfSSadaf Ebrahimi 
5799*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
5800*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
5801*b7893ccfSSadaf Ebrahimi 
5802*b7893ccfSSadaf Ebrahimi     std::vector<const char *> device_extension_names;
5803*b7893ccfSSadaf Ebrahimi     auto features = m_device->phy().features();
5804*b7893ccfSSadaf Ebrahimi     // Artificially disable support for non-solid fill modes
5805*b7893ccfSSadaf Ebrahimi     features.fillModeNonSolid = false;
5806*b7893ccfSSadaf Ebrahimi     // The sacrificial device object
5807*b7893ccfSSadaf Ebrahimi     VkDeviceObj test_device(0, gpu(), device_extension_names, &features);
5808*b7893ccfSSadaf Ebrahimi 
5809*b7893ccfSSadaf Ebrahimi     VkRenderpassObj render_pass(&test_device);
5810*b7893ccfSSadaf Ebrahimi 
5811*b7893ccfSSadaf Ebrahimi     const VkPipelineLayoutObj pipeline_layout(&test_device);
5812*b7893ccfSSadaf Ebrahimi 
5813*b7893ccfSSadaf Ebrahimi     VkPipelineRasterizationStateCreateInfo rs_ci = {};
5814*b7893ccfSSadaf Ebrahimi     rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
5815*b7893ccfSSadaf Ebrahimi     rs_ci.pNext = nullptr;
5816*b7893ccfSSadaf Ebrahimi     rs_ci.lineWidth = 1.0f;
5817*b7893ccfSSadaf Ebrahimi     rs_ci.rasterizerDiscardEnable = false;
5818*b7893ccfSSadaf Ebrahimi 
5819*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(&test_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
5820*b7893ccfSSadaf Ebrahimi     VkShaderObj fs(&test_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
5821*b7893ccfSSadaf Ebrahimi 
5822*b7893ccfSSadaf Ebrahimi     // Set polygonMode=FILL. No error is expected
5823*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
5824*b7893ccfSSadaf Ebrahimi     {
5825*b7893ccfSSadaf Ebrahimi         VkPipelineObj pipe(&test_device);
5826*b7893ccfSSadaf Ebrahimi         pipe.AddShader(&vs);
5827*b7893ccfSSadaf Ebrahimi         pipe.AddShader(&fs);
5828*b7893ccfSSadaf Ebrahimi         pipe.AddDefaultColorAttachment();
5829*b7893ccfSSadaf Ebrahimi         // Set polygonMode to a good value
5830*b7893ccfSSadaf Ebrahimi         rs_ci.polygonMode = VK_POLYGON_MODE_FILL;
5831*b7893ccfSSadaf Ebrahimi         pipe.SetRasterization(&rs_ci);
5832*b7893ccfSSadaf Ebrahimi         pipe.CreateVKPipeline(pipeline_layout.handle(), render_pass.handle());
5833*b7893ccfSSadaf Ebrahimi     }
5834*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
5835*b7893ccfSSadaf Ebrahimi }
5836*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,LongSemaphoreChain)5837*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, LongSemaphoreChain) {
5838*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
5839*b7893ccfSSadaf Ebrahimi 
5840*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
5841*b7893ccfSSadaf Ebrahimi     VkResult err;
5842*b7893ccfSSadaf Ebrahimi 
5843*b7893ccfSSadaf Ebrahimi     std::vector<VkSemaphore> semaphores;
5844*b7893ccfSSadaf Ebrahimi 
5845*b7893ccfSSadaf Ebrahimi     const int chainLength = 32768;
5846*b7893ccfSSadaf Ebrahimi     VkPipelineStageFlags flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
5847*b7893ccfSSadaf Ebrahimi 
5848*b7893ccfSSadaf Ebrahimi     for (int i = 0; i < chainLength; i++) {
5849*b7893ccfSSadaf Ebrahimi         VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
5850*b7893ccfSSadaf Ebrahimi         VkSemaphore semaphore;
5851*b7893ccfSSadaf Ebrahimi         err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &semaphore);
5852*b7893ccfSSadaf Ebrahimi         ASSERT_VK_SUCCESS(err);
5853*b7893ccfSSadaf Ebrahimi 
5854*b7893ccfSSadaf Ebrahimi         semaphores.push_back(semaphore);
5855*b7893ccfSSadaf Ebrahimi 
5856*b7893ccfSSadaf Ebrahimi         VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO,
5857*b7893ccfSSadaf Ebrahimi                            nullptr,
5858*b7893ccfSSadaf Ebrahimi                            semaphores.size() > 1 ? 1u : 0u,
5859*b7893ccfSSadaf Ebrahimi                            semaphores.size() > 1 ? &semaphores[semaphores.size() - 2] : nullptr,
5860*b7893ccfSSadaf Ebrahimi                            &flags,
5861*b7893ccfSSadaf Ebrahimi                            0,
5862*b7893ccfSSadaf Ebrahimi                            nullptr,
5863*b7893ccfSSadaf Ebrahimi                            1,
5864*b7893ccfSSadaf Ebrahimi                            &semaphores[semaphores.size() - 1]};
5865*b7893ccfSSadaf Ebrahimi         err = vkQueueSubmit(m_device->m_queue, 1, &si, VK_NULL_HANDLE);
5866*b7893ccfSSadaf Ebrahimi         ASSERT_VK_SUCCESS(err);
5867*b7893ccfSSadaf Ebrahimi     }
5868*b7893ccfSSadaf Ebrahimi 
5869*b7893ccfSSadaf Ebrahimi     VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
5870*b7893ccfSSadaf Ebrahimi     VkFence fence;
5871*b7893ccfSSadaf Ebrahimi     err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
5872*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
5873*b7893ccfSSadaf Ebrahimi     VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &semaphores.back(), &flags, 0, nullptr, 0, nullptr};
5874*b7893ccfSSadaf Ebrahimi     err = vkQueueSubmit(m_device->m_queue, 1, &si, fence);
5875*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
5876*b7893ccfSSadaf Ebrahimi 
5877*b7893ccfSSadaf Ebrahimi     vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
5878*b7893ccfSSadaf Ebrahimi 
5879*b7893ccfSSadaf Ebrahimi     for (auto semaphore : semaphores) vkDestroySemaphore(m_device->device(), semaphore, nullptr);
5880*b7893ccfSSadaf Ebrahimi 
5881*b7893ccfSSadaf Ebrahimi     vkDestroyFence(m_device->device(), fence, nullptr);
5882*b7893ccfSSadaf Ebrahimi 
5883*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
5884*b7893ccfSSadaf Ebrahimi }
5885*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,ExternalSemaphore)5886*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, ExternalSemaphore) {
5887*b7893ccfSSadaf Ebrahimi #ifdef _WIN32
5888*b7893ccfSSadaf Ebrahimi     const auto extension_name = VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME;
5889*b7893ccfSSadaf Ebrahimi     const auto handle_type = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR;
5890*b7893ccfSSadaf Ebrahimi #else
5891*b7893ccfSSadaf Ebrahimi     const auto extension_name = VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME;
5892*b7893ccfSSadaf Ebrahimi     const auto handle_type = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
5893*b7893ccfSSadaf Ebrahimi #endif
5894*b7893ccfSSadaf Ebrahimi     // Check for external semaphore instance extensions
5895*b7893ccfSSadaf Ebrahimi     if (InstanceExtensionSupported(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME)) {
5896*b7893ccfSSadaf Ebrahimi         m_instance_extension_names.push_back(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME);
5897*b7893ccfSSadaf Ebrahimi         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
5898*b7893ccfSSadaf Ebrahimi     } else {
5899*b7893ccfSSadaf Ebrahimi         printf("%s External semaphore extension not supported, skipping test\n", kSkipPrefix);
5900*b7893ccfSSadaf Ebrahimi         return;
5901*b7893ccfSSadaf Ebrahimi     }
5902*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
5903*b7893ccfSSadaf Ebrahimi 
5904*b7893ccfSSadaf Ebrahimi     // Check for external semaphore device extensions
5905*b7893ccfSSadaf Ebrahimi     if (DeviceExtensionSupported(gpu(), nullptr, extension_name)) {
5906*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(extension_name);
5907*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME);
5908*b7893ccfSSadaf Ebrahimi     } else {
5909*b7893ccfSSadaf Ebrahimi         printf("%s External semaphore extension not supported, skipping test\n", kSkipPrefix);
5910*b7893ccfSSadaf Ebrahimi         return;
5911*b7893ccfSSadaf Ebrahimi     }
5912*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
5913*b7893ccfSSadaf Ebrahimi 
5914*b7893ccfSSadaf Ebrahimi     // Check for external semaphore import and export capability
5915*b7893ccfSSadaf Ebrahimi     VkPhysicalDeviceExternalSemaphoreInfoKHR esi = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR, nullptr,
5916*b7893ccfSSadaf Ebrahimi                                                     handle_type};
5917*b7893ccfSSadaf Ebrahimi     VkExternalSemaphorePropertiesKHR esp = {VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR, nullptr};
5918*b7893ccfSSadaf Ebrahimi     auto vkGetPhysicalDeviceExternalSemaphorePropertiesKHR =
5919*b7893ccfSSadaf Ebrahimi         (PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR)vkGetInstanceProcAddr(
5920*b7893ccfSSadaf Ebrahimi             instance(), "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR");
5921*b7893ccfSSadaf Ebrahimi     vkGetPhysicalDeviceExternalSemaphorePropertiesKHR(gpu(), &esi, &esp);
5922*b7893ccfSSadaf Ebrahimi 
5923*b7893ccfSSadaf Ebrahimi     if (!(esp.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR) ||
5924*b7893ccfSSadaf Ebrahimi         !(esp.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR)) {
5925*b7893ccfSSadaf Ebrahimi         printf("%s External semaphore does not support importing and exporting, skipping test\n", kSkipPrefix);
5926*b7893ccfSSadaf Ebrahimi         return;
5927*b7893ccfSSadaf Ebrahimi     }
5928*b7893ccfSSadaf Ebrahimi 
5929*b7893ccfSSadaf Ebrahimi     VkResult err;
5930*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
5931*b7893ccfSSadaf Ebrahimi 
5932*b7893ccfSSadaf Ebrahimi     // Create a semaphore to export payload from
5933*b7893ccfSSadaf Ebrahimi     VkExportSemaphoreCreateInfoKHR esci = {VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR, nullptr, handle_type};
5934*b7893ccfSSadaf Ebrahimi     VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, &esci, 0};
5935*b7893ccfSSadaf Ebrahimi 
5936*b7893ccfSSadaf Ebrahimi     VkSemaphore export_semaphore;
5937*b7893ccfSSadaf Ebrahimi     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &export_semaphore);
5938*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
5939*b7893ccfSSadaf Ebrahimi 
5940*b7893ccfSSadaf Ebrahimi     // Create a semaphore to import payload into
5941*b7893ccfSSadaf Ebrahimi     sci.pNext = nullptr;
5942*b7893ccfSSadaf Ebrahimi     VkSemaphore import_semaphore;
5943*b7893ccfSSadaf Ebrahimi     err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &import_semaphore);
5944*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
5945*b7893ccfSSadaf Ebrahimi 
5946*b7893ccfSSadaf Ebrahimi #ifdef _WIN32
5947*b7893ccfSSadaf Ebrahimi     // Export semaphore payload to an opaque handle
5948*b7893ccfSSadaf Ebrahimi     HANDLE handle = nullptr;
5949*b7893ccfSSadaf Ebrahimi     VkSemaphoreGetWin32HandleInfoKHR ghi = {VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR, nullptr, export_semaphore,
5950*b7893ccfSSadaf Ebrahimi                                             handle_type};
5951*b7893ccfSSadaf Ebrahimi     auto vkGetSemaphoreWin32HandleKHR =
5952*b7893ccfSSadaf Ebrahimi         (PFN_vkGetSemaphoreWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetSemaphoreWin32HandleKHR");
5953*b7893ccfSSadaf Ebrahimi     err = vkGetSemaphoreWin32HandleKHR(m_device->device(), &ghi, &handle);
5954*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
5955*b7893ccfSSadaf Ebrahimi 
5956*b7893ccfSSadaf Ebrahimi     // Import opaque handle exported above
5957*b7893ccfSSadaf Ebrahimi     VkImportSemaphoreWin32HandleInfoKHR ihi = {
5958*b7893ccfSSadaf Ebrahimi         VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR, nullptr, import_semaphore, 0, handle_type, handle, nullptr};
5959*b7893ccfSSadaf Ebrahimi     auto vkImportSemaphoreWin32HandleKHR =
5960*b7893ccfSSadaf Ebrahimi         (PFN_vkImportSemaphoreWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportSemaphoreWin32HandleKHR");
5961*b7893ccfSSadaf Ebrahimi     err = vkImportSemaphoreWin32HandleKHR(m_device->device(), &ihi);
5962*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
5963*b7893ccfSSadaf Ebrahimi #else
5964*b7893ccfSSadaf Ebrahimi     // Export semaphore payload to an opaque handle
5965*b7893ccfSSadaf Ebrahimi     int fd = 0;
5966*b7893ccfSSadaf Ebrahimi     VkSemaphoreGetFdInfoKHR ghi = {VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR, nullptr, export_semaphore, handle_type};
5967*b7893ccfSSadaf Ebrahimi     auto vkGetSemaphoreFdKHR = (PFN_vkGetSemaphoreFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetSemaphoreFdKHR");
5968*b7893ccfSSadaf Ebrahimi     err = vkGetSemaphoreFdKHR(m_device->device(), &ghi, &fd);
5969*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
5970*b7893ccfSSadaf Ebrahimi 
5971*b7893ccfSSadaf Ebrahimi     // Import opaque handle exported above
5972*b7893ccfSSadaf Ebrahimi     VkImportSemaphoreFdInfoKHR ihi = {
5973*b7893ccfSSadaf Ebrahimi         VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR, nullptr, import_semaphore, 0, handle_type, fd};
5974*b7893ccfSSadaf Ebrahimi     auto vkImportSemaphoreFdKHR = (PFN_vkImportSemaphoreFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportSemaphoreFdKHR");
5975*b7893ccfSSadaf Ebrahimi     err = vkImportSemaphoreFdKHR(m_device->device(), &ihi);
5976*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
5977*b7893ccfSSadaf Ebrahimi #endif
5978*b7893ccfSSadaf Ebrahimi 
5979*b7893ccfSSadaf Ebrahimi     // Signal the exported semaphore and wait on the imported semaphore
5980*b7893ccfSSadaf Ebrahimi     VkPipelineStageFlags flags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
5981*b7893ccfSSadaf Ebrahimi     VkSubmitInfo si[] = {
5982*b7893ccfSSadaf Ebrahimi         {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, &flags, 0, nullptr, 1, &export_semaphore},
5983*b7893ccfSSadaf Ebrahimi         {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &import_semaphore, &flags, 0, nullptr, 0, nullptr},
5984*b7893ccfSSadaf Ebrahimi         {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, &flags, 0, nullptr, 1, &export_semaphore},
5985*b7893ccfSSadaf Ebrahimi         {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &import_semaphore, &flags, 0, nullptr, 0, nullptr},
5986*b7893ccfSSadaf Ebrahimi     };
5987*b7893ccfSSadaf Ebrahimi     err = vkQueueSubmit(m_device->m_queue, 4, si, VK_NULL_HANDLE);
5988*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
5989*b7893ccfSSadaf Ebrahimi 
5990*b7893ccfSSadaf Ebrahimi     if (m_device->phy().features().sparseBinding) {
5991*b7893ccfSSadaf Ebrahimi         // Signal the imported semaphore and wait on the exported semaphore
5992*b7893ccfSSadaf Ebrahimi         VkBindSparseInfo bi[] = {
5993*b7893ccfSSadaf Ebrahimi             {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 1, &import_semaphore},
5994*b7893ccfSSadaf Ebrahimi             {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 1, &export_semaphore, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr},
5995*b7893ccfSSadaf Ebrahimi             {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 1, &import_semaphore},
5996*b7893ccfSSadaf Ebrahimi             {VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, nullptr, 1, &export_semaphore, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr},
5997*b7893ccfSSadaf Ebrahimi         };
5998*b7893ccfSSadaf Ebrahimi         err = vkQueueBindSparse(m_device->m_queue, 4, bi, VK_NULL_HANDLE);
5999*b7893ccfSSadaf Ebrahimi         ASSERT_VK_SUCCESS(err);
6000*b7893ccfSSadaf Ebrahimi     }
6001*b7893ccfSSadaf Ebrahimi 
6002*b7893ccfSSadaf Ebrahimi     // Cleanup
6003*b7893ccfSSadaf Ebrahimi     err = vkQueueWaitIdle(m_device->m_queue);
6004*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
6005*b7893ccfSSadaf Ebrahimi     vkDestroySemaphore(m_device->device(), export_semaphore, nullptr);
6006*b7893ccfSSadaf Ebrahimi     vkDestroySemaphore(m_device->device(), import_semaphore, nullptr);
6007*b7893ccfSSadaf Ebrahimi 
6008*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
6009*b7893ccfSSadaf Ebrahimi }
6010*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,ExternalFence)6011*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, ExternalFence) {
6012*b7893ccfSSadaf Ebrahimi #ifdef _WIN32
6013*b7893ccfSSadaf Ebrahimi     const auto extension_name = VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME;
6014*b7893ccfSSadaf Ebrahimi     const auto handle_type = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
6015*b7893ccfSSadaf Ebrahimi #else
6016*b7893ccfSSadaf Ebrahimi     const auto extension_name = VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME;
6017*b7893ccfSSadaf Ebrahimi     const auto handle_type = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
6018*b7893ccfSSadaf Ebrahimi #endif
6019*b7893ccfSSadaf Ebrahimi     // Check for external fence instance extensions
6020*b7893ccfSSadaf Ebrahimi     if (InstanceExtensionSupported(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME)) {
6021*b7893ccfSSadaf Ebrahimi         m_instance_extension_names.push_back(VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME);
6022*b7893ccfSSadaf Ebrahimi         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6023*b7893ccfSSadaf Ebrahimi     } else {
6024*b7893ccfSSadaf Ebrahimi         printf("%s External fence extension not supported, skipping test\n", kSkipPrefix);
6025*b7893ccfSSadaf Ebrahimi         return;
6026*b7893ccfSSadaf Ebrahimi     }
6027*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
6028*b7893ccfSSadaf Ebrahimi 
6029*b7893ccfSSadaf Ebrahimi     // Check for external fence device extensions
6030*b7893ccfSSadaf Ebrahimi     if (DeviceExtensionSupported(gpu(), nullptr, extension_name)) {
6031*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(extension_name);
6032*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME);
6033*b7893ccfSSadaf Ebrahimi     } else {
6034*b7893ccfSSadaf Ebrahimi         printf("%s External fence extension not supported, skipping test\n", kSkipPrefix);
6035*b7893ccfSSadaf Ebrahimi         return;
6036*b7893ccfSSadaf Ebrahimi     }
6037*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
6038*b7893ccfSSadaf Ebrahimi 
6039*b7893ccfSSadaf Ebrahimi     // Check for external fence import and export capability
6040*b7893ccfSSadaf Ebrahimi     VkPhysicalDeviceExternalFenceInfoKHR efi = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR, nullptr, handle_type};
6041*b7893ccfSSadaf Ebrahimi     VkExternalFencePropertiesKHR efp = {VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR, nullptr};
6042*b7893ccfSSadaf Ebrahimi     auto vkGetPhysicalDeviceExternalFencePropertiesKHR = (PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR)vkGetInstanceProcAddr(
6043*b7893ccfSSadaf Ebrahimi         instance(), "vkGetPhysicalDeviceExternalFencePropertiesKHR");
6044*b7893ccfSSadaf Ebrahimi     vkGetPhysicalDeviceExternalFencePropertiesKHR(gpu(), &efi, &efp);
6045*b7893ccfSSadaf Ebrahimi 
6046*b7893ccfSSadaf Ebrahimi     if (!(efp.externalFenceFeatures & VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT_KHR) ||
6047*b7893ccfSSadaf Ebrahimi         !(efp.externalFenceFeatures & VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT_KHR)) {
6048*b7893ccfSSadaf Ebrahimi         printf("%s External fence does not support importing and exporting, skipping test\n", kSkipPrefix);
6049*b7893ccfSSadaf Ebrahimi         return;
6050*b7893ccfSSadaf Ebrahimi     }
6051*b7893ccfSSadaf Ebrahimi 
6052*b7893ccfSSadaf Ebrahimi     VkResult err;
6053*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
6054*b7893ccfSSadaf Ebrahimi 
6055*b7893ccfSSadaf Ebrahimi     // Create a fence to export payload from
6056*b7893ccfSSadaf Ebrahimi     VkFence export_fence;
6057*b7893ccfSSadaf Ebrahimi     {
6058*b7893ccfSSadaf Ebrahimi         VkExportFenceCreateInfoKHR efci = {VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR, nullptr, handle_type};
6059*b7893ccfSSadaf Ebrahimi         VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, &efci, 0};
6060*b7893ccfSSadaf Ebrahimi         err = vkCreateFence(m_device->device(), &fci, nullptr, &export_fence);
6061*b7893ccfSSadaf Ebrahimi         ASSERT_VK_SUCCESS(err);
6062*b7893ccfSSadaf Ebrahimi     }
6063*b7893ccfSSadaf Ebrahimi 
6064*b7893ccfSSadaf Ebrahimi     // Create a fence to import payload into
6065*b7893ccfSSadaf Ebrahimi     VkFence import_fence;
6066*b7893ccfSSadaf Ebrahimi     {
6067*b7893ccfSSadaf Ebrahimi         VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
6068*b7893ccfSSadaf Ebrahimi         err = vkCreateFence(m_device->device(), &fci, nullptr, &import_fence);
6069*b7893ccfSSadaf Ebrahimi         ASSERT_VK_SUCCESS(err);
6070*b7893ccfSSadaf Ebrahimi     }
6071*b7893ccfSSadaf Ebrahimi 
6072*b7893ccfSSadaf Ebrahimi #ifdef _WIN32
6073*b7893ccfSSadaf Ebrahimi     // Export fence payload to an opaque handle
6074*b7893ccfSSadaf Ebrahimi     HANDLE handle = nullptr;
6075*b7893ccfSSadaf Ebrahimi     {
6076*b7893ccfSSadaf Ebrahimi         VkFenceGetWin32HandleInfoKHR ghi = {VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR, nullptr, export_fence, handle_type};
6077*b7893ccfSSadaf Ebrahimi         auto vkGetFenceWin32HandleKHR =
6078*b7893ccfSSadaf Ebrahimi             (PFN_vkGetFenceWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetFenceWin32HandleKHR");
6079*b7893ccfSSadaf Ebrahimi         err = vkGetFenceWin32HandleKHR(m_device->device(), &ghi, &handle);
6080*b7893ccfSSadaf Ebrahimi         ASSERT_VK_SUCCESS(err);
6081*b7893ccfSSadaf Ebrahimi     }
6082*b7893ccfSSadaf Ebrahimi 
6083*b7893ccfSSadaf Ebrahimi     // Import opaque handle exported above
6084*b7893ccfSSadaf Ebrahimi     {
6085*b7893ccfSSadaf Ebrahimi         VkImportFenceWin32HandleInfoKHR ifi = {
6086*b7893ccfSSadaf Ebrahimi             VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR, nullptr, import_fence, 0, handle_type, handle, nullptr};
6087*b7893ccfSSadaf Ebrahimi         auto vkImportFenceWin32HandleKHR =
6088*b7893ccfSSadaf Ebrahimi             (PFN_vkImportFenceWin32HandleKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportFenceWin32HandleKHR");
6089*b7893ccfSSadaf Ebrahimi         err = vkImportFenceWin32HandleKHR(m_device->device(), &ifi);
6090*b7893ccfSSadaf Ebrahimi         ASSERT_VK_SUCCESS(err);
6091*b7893ccfSSadaf Ebrahimi     }
6092*b7893ccfSSadaf Ebrahimi #else
6093*b7893ccfSSadaf Ebrahimi     // Export fence payload to an opaque handle
6094*b7893ccfSSadaf Ebrahimi     int fd = 0;
6095*b7893ccfSSadaf Ebrahimi     {
6096*b7893ccfSSadaf Ebrahimi         VkFenceGetFdInfoKHR gfi = {VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR, nullptr, export_fence, handle_type};
6097*b7893ccfSSadaf Ebrahimi         auto vkGetFenceFdKHR = (PFN_vkGetFenceFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkGetFenceFdKHR");
6098*b7893ccfSSadaf Ebrahimi         err = vkGetFenceFdKHR(m_device->device(), &gfi, &fd);
6099*b7893ccfSSadaf Ebrahimi         ASSERT_VK_SUCCESS(err);
6100*b7893ccfSSadaf Ebrahimi     }
6101*b7893ccfSSadaf Ebrahimi 
6102*b7893ccfSSadaf Ebrahimi     // Import opaque handle exported above
6103*b7893ccfSSadaf Ebrahimi     {
6104*b7893ccfSSadaf Ebrahimi         VkImportFenceFdInfoKHR ifi = {VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR, nullptr, import_fence, 0, handle_type, fd};
6105*b7893ccfSSadaf Ebrahimi         auto vkImportFenceFdKHR = (PFN_vkImportFenceFdKHR)vkGetDeviceProcAddr(m_device->device(), "vkImportFenceFdKHR");
6106*b7893ccfSSadaf Ebrahimi         err = vkImportFenceFdKHR(m_device->device(), &ifi);
6107*b7893ccfSSadaf Ebrahimi         ASSERT_VK_SUCCESS(err);
6108*b7893ccfSSadaf Ebrahimi     }
6109*b7893ccfSSadaf Ebrahimi #endif
6110*b7893ccfSSadaf Ebrahimi 
6111*b7893ccfSSadaf Ebrahimi     // Signal the exported fence and wait on the imported fence
6112*b7893ccfSSadaf Ebrahimi     vkQueueSubmit(m_device->m_queue, 0, nullptr, export_fence);
6113*b7893ccfSSadaf Ebrahimi     vkWaitForFences(m_device->device(), 1, &import_fence, VK_TRUE, 1000000000);
6114*b7893ccfSSadaf Ebrahimi     vkResetFences(m_device->device(), 1, &import_fence);
6115*b7893ccfSSadaf Ebrahimi     vkQueueSubmit(m_device->m_queue, 0, nullptr, export_fence);
6116*b7893ccfSSadaf Ebrahimi     vkWaitForFences(m_device->device(), 1, &import_fence, VK_TRUE, 1000000000);
6117*b7893ccfSSadaf Ebrahimi     vkResetFences(m_device->device(), 1, &import_fence);
6118*b7893ccfSSadaf Ebrahimi 
6119*b7893ccfSSadaf Ebrahimi     // Signal the imported fence and wait on the exported fence
6120*b7893ccfSSadaf Ebrahimi     vkQueueSubmit(m_device->m_queue, 0, nullptr, import_fence);
6121*b7893ccfSSadaf Ebrahimi     vkWaitForFences(m_device->device(), 1, &export_fence, VK_TRUE, 1000000000);
6122*b7893ccfSSadaf Ebrahimi     vkResetFences(m_device->device(), 1, &export_fence);
6123*b7893ccfSSadaf Ebrahimi     vkQueueSubmit(m_device->m_queue, 0, nullptr, import_fence);
6124*b7893ccfSSadaf Ebrahimi     vkWaitForFences(m_device->device(), 1, &export_fence, VK_TRUE, 1000000000);
6125*b7893ccfSSadaf Ebrahimi     vkResetFences(m_device->device(), 1, &export_fence);
6126*b7893ccfSSadaf Ebrahimi 
6127*b7893ccfSSadaf Ebrahimi     // Cleanup
6128*b7893ccfSSadaf Ebrahimi     err = vkQueueWaitIdle(m_device->m_queue);
6129*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
6130*b7893ccfSSadaf Ebrahimi     vkDestroyFence(m_device->device(), export_fence, nullptr);
6131*b7893ccfSSadaf Ebrahimi     vkDestroyFence(m_device->device(), import_fence, nullptr);
6132*b7893ccfSSadaf Ebrahimi 
6133*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
6134*b7893ccfSSadaf Ebrahimi }
6135*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,ThreadNullFenceCollision)6136*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, ThreadNullFenceCollision) {
6137*b7893ccfSSadaf Ebrahimi     test_platform_thread thread;
6138*b7893ccfSSadaf Ebrahimi 
6139*b7893ccfSSadaf Ebrahimi     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "THREADING ERROR");
6140*b7893ccfSSadaf Ebrahimi 
6141*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
6142*b7893ccfSSadaf Ebrahimi 
6143*b7893ccfSSadaf Ebrahimi     struct thread_data_struct data;
6144*b7893ccfSSadaf Ebrahimi     data.device = m_device->device();
6145*b7893ccfSSadaf Ebrahimi     data.bailout = false;
6146*b7893ccfSSadaf Ebrahimi     m_errorMonitor->SetBailout(&data.bailout);
6147*b7893ccfSSadaf Ebrahimi 
6148*b7893ccfSSadaf Ebrahimi     // Call vkDestroyFence of VK_NULL_HANDLE repeatedly using multiple threads.
6149*b7893ccfSSadaf Ebrahimi     // There should be no validation error from collision of that non-object.
6150*b7893ccfSSadaf Ebrahimi     test_platform_thread_create(&thread, ReleaseNullFence, (void *)&data);
6151*b7893ccfSSadaf Ebrahimi     for (int i = 0; i < 40000; i++) {
6152*b7893ccfSSadaf Ebrahimi         vkDestroyFence(m_device->device(), VK_NULL_HANDLE, NULL);
6153*b7893ccfSSadaf Ebrahimi     }
6154*b7893ccfSSadaf Ebrahimi     test_platform_thread_join(thread, NULL);
6155*b7893ccfSSadaf Ebrahimi 
6156*b7893ccfSSadaf Ebrahimi     m_errorMonitor->SetBailout(NULL);
6157*b7893ccfSSadaf Ebrahimi 
6158*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
6159*b7893ccfSSadaf Ebrahimi }
6160*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,ClearColorImageWithValidRange)6161*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, ClearColorImageWithValidRange) {
6162*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Record clear color with a valid VkImageSubresourceRange");
6163*b7893ccfSSadaf Ebrahimi 
6164*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
6165*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6166*b7893ccfSSadaf Ebrahimi 
6167*b7893ccfSSadaf Ebrahimi     VkImageObj image(m_device);
6168*b7893ccfSSadaf Ebrahimi     image.Init(32, 32, 1, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
6169*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(image.create_info().arrayLayers == 1);
6170*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(image.initialized());
6171*b7893ccfSSadaf Ebrahimi     image.SetLayout(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
6172*b7893ccfSSadaf Ebrahimi 
6173*b7893ccfSSadaf Ebrahimi     const VkClearColorValue clear_color = {{0.0f, 0.0f, 0.0f, 1.0f}};
6174*b7893ccfSSadaf Ebrahimi 
6175*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
6176*b7893ccfSSadaf Ebrahimi     const auto cb_handle = m_commandBuffer->handle();
6177*b7893ccfSSadaf Ebrahimi 
6178*b7893ccfSSadaf Ebrahimi     // Try good case
6179*b7893ccfSSadaf Ebrahimi     {
6180*b7893ccfSSadaf Ebrahimi         m_errorMonitor->ExpectSuccess();
6181*b7893ccfSSadaf Ebrahimi         VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
6182*b7893ccfSSadaf Ebrahimi         vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range);
6183*b7893ccfSSadaf Ebrahimi         m_errorMonitor->VerifyNotFound();
6184*b7893ccfSSadaf Ebrahimi     }
6185*b7893ccfSSadaf Ebrahimi 
6186*b7893ccfSSadaf Ebrahimi     // Try good case with VK_REMAINING
6187*b7893ccfSSadaf Ebrahimi     {
6188*b7893ccfSSadaf Ebrahimi         m_errorMonitor->ExpectSuccess();
6189*b7893ccfSSadaf Ebrahimi         VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS};
6190*b7893ccfSSadaf Ebrahimi         vkCmdClearColorImage(cb_handle, image.handle(), image.Layout(), &clear_color, 1, &range);
6191*b7893ccfSSadaf Ebrahimi         m_errorMonitor->VerifyNotFound();
6192*b7893ccfSSadaf Ebrahimi     }
6193*b7893ccfSSadaf Ebrahimi }
6194*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,ClearDepthStencilWithValidRange)6195*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, ClearDepthStencilWithValidRange) {
6196*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Record clear depth with a valid VkImageSubresourceRange");
6197*b7893ccfSSadaf Ebrahimi 
6198*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
6199*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6200*b7893ccfSSadaf Ebrahimi 
6201*b7893ccfSSadaf Ebrahimi     auto depth_format = FindSupportedDepthStencilFormat(gpu());
6202*b7893ccfSSadaf Ebrahimi     if (!depth_format) {
6203*b7893ccfSSadaf Ebrahimi         printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
6204*b7893ccfSSadaf Ebrahimi         return;
6205*b7893ccfSSadaf Ebrahimi     }
6206*b7893ccfSSadaf Ebrahimi 
6207*b7893ccfSSadaf Ebrahimi     VkImageObj image(m_device);
6208*b7893ccfSSadaf Ebrahimi     image.Init(32, 32, 1, depth_format, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_OPTIMAL);
6209*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(image.create_info().arrayLayers == 1);
6210*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(image.initialized());
6211*b7893ccfSSadaf Ebrahimi     const VkImageAspectFlags ds_aspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
6212*b7893ccfSSadaf Ebrahimi     image.SetLayout(ds_aspect, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
6213*b7893ccfSSadaf Ebrahimi 
6214*b7893ccfSSadaf Ebrahimi     const VkClearDepthStencilValue clear_value = {};
6215*b7893ccfSSadaf Ebrahimi 
6216*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
6217*b7893ccfSSadaf Ebrahimi     const auto cb_handle = m_commandBuffer->handle();
6218*b7893ccfSSadaf Ebrahimi 
6219*b7893ccfSSadaf Ebrahimi     // Try good case
6220*b7893ccfSSadaf Ebrahimi     {
6221*b7893ccfSSadaf Ebrahimi         m_errorMonitor->ExpectSuccess();
6222*b7893ccfSSadaf Ebrahimi         VkImageSubresourceRange range = {ds_aspect, 0, 1, 0, 1};
6223*b7893ccfSSadaf Ebrahimi         vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range);
6224*b7893ccfSSadaf Ebrahimi         m_errorMonitor->VerifyNotFound();
6225*b7893ccfSSadaf Ebrahimi     }
6226*b7893ccfSSadaf Ebrahimi 
6227*b7893ccfSSadaf Ebrahimi     // Try good case with VK_REMAINING
6228*b7893ccfSSadaf Ebrahimi     {
6229*b7893ccfSSadaf Ebrahimi         m_errorMonitor->ExpectSuccess();
6230*b7893ccfSSadaf Ebrahimi         VkImageSubresourceRange range = {ds_aspect, 0, VK_REMAINING_MIP_LEVELS, 0, VK_REMAINING_ARRAY_LAYERS};
6231*b7893ccfSSadaf Ebrahimi         vkCmdClearDepthStencilImage(cb_handle, image.handle(), image.Layout(), &clear_value, 1, &range);
6232*b7893ccfSSadaf Ebrahimi         m_errorMonitor->VerifyNotFound();
6233*b7893ccfSSadaf Ebrahimi     }
6234*b7893ccfSSadaf Ebrahimi }
6235*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CreateGraphicsPipelineWithIgnoredPointers)6236*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CreateGraphicsPipelineWithIgnoredPointers) {
6237*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Create Graphics Pipeline with pointers that must be ignored by layers");
6238*b7893ccfSSadaf Ebrahimi 
6239*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
6240*b7893ccfSSadaf Ebrahimi 
6241*b7893ccfSSadaf Ebrahimi     m_depth_stencil_fmt = FindSupportedDepthStencilFormat(gpu());
6242*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(m_depth_stencil_fmt != 0);
6243*b7893ccfSSadaf Ebrahimi 
6244*b7893ccfSSadaf Ebrahimi     m_depthStencil->Init(m_device, static_cast<int32_t>(m_width), static_cast<int32_t>(m_height), m_depth_stencil_fmt);
6245*b7893ccfSSadaf Ebrahimi 
6246*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget(m_depthStencil->BindInfo()));
6247*b7893ccfSSadaf Ebrahimi 
6248*b7893ccfSSadaf Ebrahimi     const uint64_t fake_address_64 = 0xCDCDCDCDCDCDCDCD;
6249*b7893ccfSSadaf Ebrahimi     const uint64_t fake_address_32 = 0xCDCDCDCD;
6250*b7893ccfSSadaf Ebrahimi     void *hopefully_undereferencable_pointer =
6251*b7893ccfSSadaf Ebrahimi         sizeof(void *) == 8 ? reinterpret_cast<void *>(fake_address_64) : reinterpret_cast<void *>(fake_address_32);
6252*b7893ccfSSadaf Ebrahimi 
6253*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
6254*b7893ccfSSadaf Ebrahimi 
6255*b7893ccfSSadaf Ebrahimi     const VkPipelineVertexInputStateCreateInfo pipeline_vertex_input_state_create_info{
6256*b7893ccfSSadaf Ebrahimi         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
6257*b7893ccfSSadaf Ebrahimi         nullptr,  // pNext
6258*b7893ccfSSadaf Ebrahimi         0,        // flags
6259*b7893ccfSSadaf Ebrahimi         0,
6260*b7893ccfSSadaf Ebrahimi         nullptr,  // bindings
6261*b7893ccfSSadaf Ebrahimi         0,
6262*b7893ccfSSadaf Ebrahimi         nullptr  // attributes
6263*b7893ccfSSadaf Ebrahimi     };
6264*b7893ccfSSadaf Ebrahimi 
6265*b7893ccfSSadaf Ebrahimi     const VkPipelineInputAssemblyStateCreateInfo pipeline_input_assembly_state_create_info{
6266*b7893ccfSSadaf Ebrahimi         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
6267*b7893ccfSSadaf Ebrahimi         nullptr,  // pNext
6268*b7893ccfSSadaf Ebrahimi         0,        // flags
6269*b7893ccfSSadaf Ebrahimi         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
6270*b7893ccfSSadaf Ebrahimi         VK_FALSE  // primitive restart
6271*b7893ccfSSadaf Ebrahimi     };
6272*b7893ccfSSadaf Ebrahimi 
6273*b7893ccfSSadaf Ebrahimi     const VkPipelineRasterizationStateCreateInfo pipeline_rasterization_state_create_info_template{
6274*b7893ccfSSadaf Ebrahimi         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
6275*b7893ccfSSadaf Ebrahimi         nullptr,   // pNext
6276*b7893ccfSSadaf Ebrahimi         0,         // flags
6277*b7893ccfSSadaf Ebrahimi         VK_FALSE,  // depthClamp
6278*b7893ccfSSadaf Ebrahimi         VK_FALSE,  // rasterizerDiscardEnable
6279*b7893ccfSSadaf Ebrahimi         VK_POLYGON_MODE_FILL,
6280*b7893ccfSSadaf Ebrahimi         VK_CULL_MODE_NONE,
6281*b7893ccfSSadaf Ebrahimi         VK_FRONT_FACE_COUNTER_CLOCKWISE,
6282*b7893ccfSSadaf Ebrahimi         VK_FALSE,  // depthBias
6283*b7893ccfSSadaf Ebrahimi         0.0f,
6284*b7893ccfSSadaf Ebrahimi         0.0f,
6285*b7893ccfSSadaf Ebrahimi         0.0f,  // depthBias params
6286*b7893ccfSSadaf Ebrahimi         1.0f   // lineWidth
6287*b7893ccfSSadaf Ebrahimi     };
6288*b7893ccfSSadaf Ebrahimi 
6289*b7893ccfSSadaf Ebrahimi     VkPipelineLayout pipeline_layout;
6290*b7893ccfSSadaf Ebrahimi     {
6291*b7893ccfSSadaf Ebrahimi         VkPipelineLayoutCreateInfo pipeline_layout_create_info{
6292*b7893ccfSSadaf Ebrahimi             VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
6293*b7893ccfSSadaf Ebrahimi             nullptr,  // pNext
6294*b7893ccfSSadaf Ebrahimi             0,        // flags
6295*b7893ccfSSadaf Ebrahimi             0,
6296*b7893ccfSSadaf Ebrahimi             nullptr,  // layouts
6297*b7893ccfSSadaf Ebrahimi             0,
6298*b7893ccfSSadaf Ebrahimi             nullptr  // push constants
6299*b7893ccfSSadaf Ebrahimi         };
6300*b7893ccfSSadaf Ebrahimi 
6301*b7893ccfSSadaf Ebrahimi         VkResult err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_create_info, nullptr, &pipeline_layout);
6302*b7893ccfSSadaf Ebrahimi         ASSERT_VK_SUCCESS(err);
6303*b7893ccfSSadaf Ebrahimi     }
6304*b7893ccfSSadaf Ebrahimi 
6305*b7893ccfSSadaf Ebrahimi     // try disabled rasterizer and no tessellation
6306*b7893ccfSSadaf Ebrahimi     {
6307*b7893ccfSSadaf Ebrahimi         m_errorMonitor->ExpectSuccess();
6308*b7893ccfSSadaf Ebrahimi 
6309*b7893ccfSSadaf Ebrahimi         VkPipelineRasterizationStateCreateInfo pipeline_rasterization_state_create_info =
6310*b7893ccfSSadaf Ebrahimi             pipeline_rasterization_state_create_info_template;
6311*b7893ccfSSadaf Ebrahimi         pipeline_rasterization_state_create_info.rasterizerDiscardEnable = VK_TRUE;
6312*b7893ccfSSadaf Ebrahimi 
6313*b7893ccfSSadaf Ebrahimi         VkGraphicsPipelineCreateInfo graphics_pipeline_create_info{
6314*b7893ccfSSadaf Ebrahimi             VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
6315*b7893ccfSSadaf Ebrahimi             nullptr,  // pNext
6316*b7893ccfSSadaf Ebrahimi             0,        // flags
6317*b7893ccfSSadaf Ebrahimi             1,        // stageCount
6318*b7893ccfSSadaf Ebrahimi             &vs.GetStageCreateInfo(),
6319*b7893ccfSSadaf Ebrahimi             &pipeline_vertex_input_state_create_info,
6320*b7893ccfSSadaf Ebrahimi             &pipeline_input_assembly_state_create_info,
6321*b7893ccfSSadaf Ebrahimi             reinterpret_cast<const VkPipelineTessellationStateCreateInfo *>(hopefully_undereferencable_pointer),
6322*b7893ccfSSadaf Ebrahimi             reinterpret_cast<const VkPipelineViewportStateCreateInfo *>(hopefully_undereferencable_pointer),
6323*b7893ccfSSadaf Ebrahimi             &pipeline_rasterization_state_create_info,
6324*b7893ccfSSadaf Ebrahimi             reinterpret_cast<const VkPipelineMultisampleStateCreateInfo *>(hopefully_undereferencable_pointer),
6325*b7893ccfSSadaf Ebrahimi             reinterpret_cast<const VkPipelineDepthStencilStateCreateInfo *>(hopefully_undereferencable_pointer),
6326*b7893ccfSSadaf Ebrahimi             reinterpret_cast<const VkPipelineColorBlendStateCreateInfo *>(hopefully_undereferencable_pointer),
6327*b7893ccfSSadaf Ebrahimi             nullptr,  // dynamic states
6328*b7893ccfSSadaf Ebrahimi             pipeline_layout,
6329*b7893ccfSSadaf Ebrahimi             m_renderPass,
6330*b7893ccfSSadaf Ebrahimi             0,  // subpass
6331*b7893ccfSSadaf Ebrahimi             VK_NULL_HANDLE,
6332*b7893ccfSSadaf Ebrahimi             0};
6333*b7893ccfSSadaf Ebrahimi 
6334*b7893ccfSSadaf Ebrahimi         VkPipeline pipeline;
6335*b7893ccfSSadaf Ebrahimi         vkCreateGraphicsPipelines(m_device->handle(), VK_NULL_HANDLE, 1, &graphics_pipeline_create_info, nullptr, &pipeline);
6336*b7893ccfSSadaf Ebrahimi 
6337*b7893ccfSSadaf Ebrahimi         m_errorMonitor->VerifyNotFound();
6338*b7893ccfSSadaf Ebrahimi 
6339*b7893ccfSSadaf Ebrahimi         vkDestroyPipeline(m_device->handle(), pipeline, nullptr);
6340*b7893ccfSSadaf Ebrahimi     }
6341*b7893ccfSSadaf Ebrahimi 
6342*b7893ccfSSadaf Ebrahimi     const VkPipelineMultisampleStateCreateInfo pipeline_multisample_state_create_info{
6343*b7893ccfSSadaf Ebrahimi         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
6344*b7893ccfSSadaf Ebrahimi         nullptr,  // pNext
6345*b7893ccfSSadaf Ebrahimi         0,        // flags
6346*b7893ccfSSadaf Ebrahimi         VK_SAMPLE_COUNT_1_BIT,
6347*b7893ccfSSadaf Ebrahimi         VK_FALSE,  // sample shading
6348*b7893ccfSSadaf Ebrahimi         0.0f,      // minSampleShading
6349*b7893ccfSSadaf Ebrahimi         nullptr,   // pSampleMask
6350*b7893ccfSSadaf Ebrahimi         VK_FALSE,  // alphaToCoverageEnable
6351*b7893ccfSSadaf Ebrahimi         VK_FALSE   // alphaToOneEnable
6352*b7893ccfSSadaf Ebrahimi     };
6353*b7893ccfSSadaf Ebrahimi 
6354*b7893ccfSSadaf Ebrahimi     // try enabled rasterizer but no subpass attachments
6355*b7893ccfSSadaf Ebrahimi     {
6356*b7893ccfSSadaf Ebrahimi         m_errorMonitor->ExpectSuccess();
6357*b7893ccfSSadaf Ebrahimi 
6358*b7893ccfSSadaf Ebrahimi         VkPipelineRasterizationStateCreateInfo pipeline_rasterization_state_create_info =
6359*b7893ccfSSadaf Ebrahimi             pipeline_rasterization_state_create_info_template;
6360*b7893ccfSSadaf Ebrahimi         pipeline_rasterization_state_create_info.rasterizerDiscardEnable = VK_FALSE;
6361*b7893ccfSSadaf Ebrahimi 
6362*b7893ccfSSadaf Ebrahimi         VkViewport viewport = {0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f};
6363*b7893ccfSSadaf Ebrahimi         VkRect2D scissor = {{0, 0}, {static_cast<uint32_t>(m_width), static_cast<uint32_t>(m_height)}};
6364*b7893ccfSSadaf Ebrahimi 
6365*b7893ccfSSadaf Ebrahimi         const VkPipelineViewportStateCreateInfo pipeline_viewport_state_create_info{
6366*b7893ccfSSadaf Ebrahimi             VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
6367*b7893ccfSSadaf Ebrahimi             nullptr,  // pNext
6368*b7893ccfSSadaf Ebrahimi             0,        // flags
6369*b7893ccfSSadaf Ebrahimi             1,
6370*b7893ccfSSadaf Ebrahimi             &viewport,
6371*b7893ccfSSadaf Ebrahimi             1,
6372*b7893ccfSSadaf Ebrahimi             &scissor};
6373*b7893ccfSSadaf Ebrahimi 
6374*b7893ccfSSadaf Ebrahimi         VkRenderPass render_pass;
6375*b7893ccfSSadaf Ebrahimi         {
6376*b7893ccfSSadaf Ebrahimi             VkSubpassDescription subpass_desc = {};
6377*b7893ccfSSadaf Ebrahimi 
6378*b7893ccfSSadaf Ebrahimi             VkRenderPassCreateInfo render_pass_create_info{
6379*b7893ccfSSadaf Ebrahimi                 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
6380*b7893ccfSSadaf Ebrahimi                 nullptr,  // pNext
6381*b7893ccfSSadaf Ebrahimi                 0,        // flags
6382*b7893ccfSSadaf Ebrahimi                 0,
6383*b7893ccfSSadaf Ebrahimi                 nullptr,  // attachments
6384*b7893ccfSSadaf Ebrahimi                 1,
6385*b7893ccfSSadaf Ebrahimi                 &subpass_desc,
6386*b7893ccfSSadaf Ebrahimi                 0,
6387*b7893ccfSSadaf Ebrahimi                 nullptr  // subpass dependencies
6388*b7893ccfSSadaf Ebrahimi             };
6389*b7893ccfSSadaf Ebrahimi 
6390*b7893ccfSSadaf Ebrahimi             VkResult err = vkCreateRenderPass(m_device->handle(), &render_pass_create_info, nullptr, &render_pass);
6391*b7893ccfSSadaf Ebrahimi             ASSERT_VK_SUCCESS(err);
6392*b7893ccfSSadaf Ebrahimi         }
6393*b7893ccfSSadaf Ebrahimi 
6394*b7893ccfSSadaf Ebrahimi         VkGraphicsPipelineCreateInfo graphics_pipeline_create_info{
6395*b7893ccfSSadaf Ebrahimi             VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
6396*b7893ccfSSadaf Ebrahimi             nullptr,  // pNext
6397*b7893ccfSSadaf Ebrahimi             0,        // flags
6398*b7893ccfSSadaf Ebrahimi             1,        // stageCount
6399*b7893ccfSSadaf Ebrahimi             &vs.GetStageCreateInfo(),
6400*b7893ccfSSadaf Ebrahimi             &pipeline_vertex_input_state_create_info,
6401*b7893ccfSSadaf Ebrahimi             &pipeline_input_assembly_state_create_info,
6402*b7893ccfSSadaf Ebrahimi             nullptr,
6403*b7893ccfSSadaf Ebrahimi             &pipeline_viewport_state_create_info,
6404*b7893ccfSSadaf Ebrahimi             &pipeline_rasterization_state_create_info,
6405*b7893ccfSSadaf Ebrahimi             &pipeline_multisample_state_create_info,
6406*b7893ccfSSadaf Ebrahimi             reinterpret_cast<const VkPipelineDepthStencilStateCreateInfo *>(hopefully_undereferencable_pointer),
6407*b7893ccfSSadaf Ebrahimi             reinterpret_cast<const VkPipelineColorBlendStateCreateInfo *>(hopefully_undereferencable_pointer),
6408*b7893ccfSSadaf Ebrahimi             nullptr,  // dynamic states
6409*b7893ccfSSadaf Ebrahimi             pipeline_layout,
6410*b7893ccfSSadaf Ebrahimi             render_pass,
6411*b7893ccfSSadaf Ebrahimi             0,  // subpass
6412*b7893ccfSSadaf Ebrahimi             VK_NULL_HANDLE,
6413*b7893ccfSSadaf Ebrahimi             0};
6414*b7893ccfSSadaf Ebrahimi 
6415*b7893ccfSSadaf Ebrahimi         VkPipeline pipeline;
6416*b7893ccfSSadaf Ebrahimi         vkCreateGraphicsPipelines(m_device->handle(), VK_NULL_HANDLE, 1, &graphics_pipeline_create_info, nullptr, &pipeline);
6417*b7893ccfSSadaf Ebrahimi 
6418*b7893ccfSSadaf Ebrahimi         m_errorMonitor->VerifyNotFound();
6419*b7893ccfSSadaf Ebrahimi 
6420*b7893ccfSSadaf Ebrahimi         vkDestroyPipeline(m_device->handle(), pipeline, nullptr);
6421*b7893ccfSSadaf Ebrahimi         vkDestroyRenderPass(m_device->handle(), render_pass, nullptr);
6422*b7893ccfSSadaf Ebrahimi     }
6423*b7893ccfSSadaf Ebrahimi 
6424*b7893ccfSSadaf Ebrahimi     // try dynamic viewport and scissor
6425*b7893ccfSSadaf Ebrahimi     {
6426*b7893ccfSSadaf Ebrahimi         m_errorMonitor->ExpectSuccess();
6427*b7893ccfSSadaf Ebrahimi 
6428*b7893ccfSSadaf Ebrahimi         VkPipelineRasterizationStateCreateInfo pipeline_rasterization_state_create_info =
6429*b7893ccfSSadaf Ebrahimi             pipeline_rasterization_state_create_info_template;
6430*b7893ccfSSadaf Ebrahimi         pipeline_rasterization_state_create_info.rasterizerDiscardEnable = VK_FALSE;
6431*b7893ccfSSadaf Ebrahimi 
6432*b7893ccfSSadaf Ebrahimi         const VkPipelineViewportStateCreateInfo pipeline_viewport_state_create_info{
6433*b7893ccfSSadaf Ebrahimi             VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
6434*b7893ccfSSadaf Ebrahimi             nullptr,  // pNext
6435*b7893ccfSSadaf Ebrahimi             0,        // flags
6436*b7893ccfSSadaf Ebrahimi             1,
6437*b7893ccfSSadaf Ebrahimi             reinterpret_cast<const VkViewport *>(hopefully_undereferencable_pointer),
6438*b7893ccfSSadaf Ebrahimi             1,
6439*b7893ccfSSadaf Ebrahimi             reinterpret_cast<const VkRect2D *>(hopefully_undereferencable_pointer)};
6440*b7893ccfSSadaf Ebrahimi 
6441*b7893ccfSSadaf Ebrahimi         const VkPipelineDepthStencilStateCreateInfo pipeline_depth_stencil_state_create_info{
6442*b7893ccfSSadaf Ebrahimi             VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
6443*b7893ccfSSadaf Ebrahimi             nullptr,  // pNext
6444*b7893ccfSSadaf Ebrahimi             0,        // flags
6445*b7893ccfSSadaf Ebrahimi         };
6446*b7893ccfSSadaf Ebrahimi 
6447*b7893ccfSSadaf Ebrahimi         const VkPipelineColorBlendAttachmentState pipeline_color_blend_attachment_state = {};
6448*b7893ccfSSadaf Ebrahimi 
6449*b7893ccfSSadaf Ebrahimi         const VkPipelineColorBlendStateCreateInfo pipeline_color_blend_state_create_info{
6450*b7893ccfSSadaf Ebrahimi             VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
6451*b7893ccfSSadaf Ebrahimi             nullptr,  // pNext
6452*b7893ccfSSadaf Ebrahimi             0,        // flags
6453*b7893ccfSSadaf Ebrahimi             VK_FALSE,
6454*b7893ccfSSadaf Ebrahimi             VK_LOGIC_OP_CLEAR,
6455*b7893ccfSSadaf Ebrahimi             1,
6456*b7893ccfSSadaf Ebrahimi             &pipeline_color_blend_attachment_state,
6457*b7893ccfSSadaf Ebrahimi             {0.0f, 0.0f, 0.0f, 0.0f}};
6458*b7893ccfSSadaf Ebrahimi 
6459*b7893ccfSSadaf Ebrahimi         const VkDynamicState dynamic_states[2] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
6460*b7893ccfSSadaf Ebrahimi 
6461*b7893ccfSSadaf Ebrahimi         const VkPipelineDynamicStateCreateInfo pipeline_dynamic_state_create_info{
6462*b7893ccfSSadaf Ebrahimi             VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
6463*b7893ccfSSadaf Ebrahimi             nullptr,  // pNext
6464*b7893ccfSSadaf Ebrahimi             0,        // flags
6465*b7893ccfSSadaf Ebrahimi             2, dynamic_states};
6466*b7893ccfSSadaf Ebrahimi 
6467*b7893ccfSSadaf Ebrahimi         VkGraphicsPipelineCreateInfo graphics_pipeline_create_info{VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
6468*b7893ccfSSadaf Ebrahimi                                                                    nullptr,  // pNext
6469*b7893ccfSSadaf Ebrahimi                                                                    0,        // flags
6470*b7893ccfSSadaf Ebrahimi                                                                    1,        // stageCount
6471*b7893ccfSSadaf Ebrahimi                                                                    &vs.GetStageCreateInfo(),
6472*b7893ccfSSadaf Ebrahimi                                                                    &pipeline_vertex_input_state_create_info,
6473*b7893ccfSSadaf Ebrahimi                                                                    &pipeline_input_assembly_state_create_info,
6474*b7893ccfSSadaf Ebrahimi                                                                    nullptr,
6475*b7893ccfSSadaf Ebrahimi                                                                    &pipeline_viewport_state_create_info,
6476*b7893ccfSSadaf Ebrahimi                                                                    &pipeline_rasterization_state_create_info,
6477*b7893ccfSSadaf Ebrahimi                                                                    &pipeline_multisample_state_create_info,
6478*b7893ccfSSadaf Ebrahimi                                                                    &pipeline_depth_stencil_state_create_info,
6479*b7893ccfSSadaf Ebrahimi                                                                    &pipeline_color_blend_state_create_info,
6480*b7893ccfSSadaf Ebrahimi                                                                    &pipeline_dynamic_state_create_info,  // dynamic states
6481*b7893ccfSSadaf Ebrahimi                                                                    pipeline_layout,
6482*b7893ccfSSadaf Ebrahimi                                                                    m_renderPass,
6483*b7893ccfSSadaf Ebrahimi                                                                    0,  // subpass
6484*b7893ccfSSadaf Ebrahimi                                                                    VK_NULL_HANDLE,
6485*b7893ccfSSadaf Ebrahimi                                                                    0};
6486*b7893ccfSSadaf Ebrahimi 
6487*b7893ccfSSadaf Ebrahimi         VkPipeline pipeline;
6488*b7893ccfSSadaf Ebrahimi         vkCreateGraphicsPipelines(m_device->handle(), VK_NULL_HANDLE, 1, &graphics_pipeline_create_info, nullptr, &pipeline);
6489*b7893ccfSSadaf Ebrahimi 
6490*b7893ccfSSadaf Ebrahimi         m_errorMonitor->VerifyNotFound();
6491*b7893ccfSSadaf Ebrahimi 
6492*b7893ccfSSadaf Ebrahimi         vkDestroyPipeline(m_device->handle(), pipeline, nullptr);
6493*b7893ccfSSadaf Ebrahimi     }
6494*b7893ccfSSadaf Ebrahimi 
6495*b7893ccfSSadaf Ebrahimi     vkDestroyPipelineLayout(m_device->handle(), pipeline_layout, nullptr);
6496*b7893ccfSSadaf Ebrahimi }
6497*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,ExternalMemory)6498*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, ExternalMemory) {
6499*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Perform a copy through a pair of buffers linked by external memory");
6500*b7893ccfSSadaf Ebrahimi 
6501*b7893ccfSSadaf Ebrahimi #ifdef _WIN32
6502*b7893ccfSSadaf Ebrahimi     const auto ext_mem_extension_name = VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME;
6503*b7893ccfSSadaf Ebrahimi     const auto handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
6504*b7893ccfSSadaf Ebrahimi #else
6505*b7893ccfSSadaf Ebrahimi     const auto ext_mem_extension_name = VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME;
6506*b7893ccfSSadaf Ebrahimi     const auto handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
6507*b7893ccfSSadaf Ebrahimi #endif
6508*b7893ccfSSadaf Ebrahimi 
6509*b7893ccfSSadaf Ebrahimi     // Check for external memory instance extensions
6510*b7893ccfSSadaf Ebrahimi     std::vector<const char *> reqd_instance_extensions = {
6511*b7893ccfSSadaf Ebrahimi         {VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME}};
6512*b7893ccfSSadaf Ebrahimi     for (auto extension_name : reqd_instance_extensions) {
6513*b7893ccfSSadaf Ebrahimi         if (InstanceExtensionSupported(extension_name)) {
6514*b7893ccfSSadaf Ebrahimi             m_instance_extension_names.push_back(extension_name);
6515*b7893ccfSSadaf Ebrahimi         } else {
6516*b7893ccfSSadaf Ebrahimi             printf("%s Required instance extension %s not supported, skipping test\n", kSkipPrefix, extension_name);
6517*b7893ccfSSadaf Ebrahimi             return;
6518*b7893ccfSSadaf Ebrahimi         }
6519*b7893ccfSSadaf Ebrahimi     }
6520*b7893ccfSSadaf Ebrahimi 
6521*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
6522*b7893ccfSSadaf Ebrahimi 
6523*b7893ccfSSadaf Ebrahimi     // Check for import/export capability
6524*b7893ccfSSadaf Ebrahimi     VkPhysicalDeviceExternalBufferInfoKHR ebi = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR, nullptr, 0,
6525*b7893ccfSSadaf Ebrahimi                                                  VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, handle_type};
6526*b7893ccfSSadaf Ebrahimi     VkExternalBufferPropertiesKHR ebp = {VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR, nullptr, {0, 0, 0}};
6527*b7893ccfSSadaf Ebrahimi     auto vkGetPhysicalDeviceExternalBufferPropertiesKHR = (PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR)vkGetInstanceProcAddr(
6528*b7893ccfSSadaf Ebrahimi         instance(), "vkGetPhysicalDeviceExternalBufferPropertiesKHR");
6529*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(vkGetPhysicalDeviceExternalBufferPropertiesKHR != nullptr);
6530*b7893ccfSSadaf Ebrahimi     vkGetPhysicalDeviceExternalBufferPropertiesKHR(gpu(), &ebi, &ebp);
6531*b7893ccfSSadaf Ebrahimi     if (!(ebp.externalMemoryProperties.compatibleHandleTypes & handle_type) ||
6532*b7893ccfSSadaf Ebrahimi         !(ebp.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR) ||
6533*b7893ccfSSadaf Ebrahimi         !(ebp.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR)) {
6534*b7893ccfSSadaf Ebrahimi         printf("%s External buffer does not support importing and exporting, skipping test\n", kSkipPrefix);
6535*b7893ccfSSadaf Ebrahimi         return;
6536*b7893ccfSSadaf Ebrahimi     }
6537*b7893ccfSSadaf Ebrahimi 
6538*b7893ccfSSadaf Ebrahimi     // Check if dedicated allocation is required
6539*b7893ccfSSadaf Ebrahimi     bool dedicated_allocation =
6540*b7893ccfSSadaf Ebrahimi         ebp.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR;
6541*b7893ccfSSadaf Ebrahimi     if (dedicated_allocation) {
6542*b7893ccfSSadaf Ebrahimi         if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME)) {
6543*b7893ccfSSadaf Ebrahimi             m_device_extension_names.push_back(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
6544*b7893ccfSSadaf Ebrahimi             m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
6545*b7893ccfSSadaf Ebrahimi         } else {
6546*b7893ccfSSadaf Ebrahimi             printf("%s Dedicated allocation extension not supported, skipping test\n", kSkipPrefix);
6547*b7893ccfSSadaf Ebrahimi             return;
6548*b7893ccfSSadaf Ebrahimi         }
6549*b7893ccfSSadaf Ebrahimi     }
6550*b7893ccfSSadaf Ebrahimi 
6551*b7893ccfSSadaf Ebrahimi     // Check for external memory device extensions
6552*b7893ccfSSadaf Ebrahimi     if (DeviceExtensionSupported(gpu(), nullptr, ext_mem_extension_name)) {
6553*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(ext_mem_extension_name);
6554*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME);
6555*b7893ccfSSadaf Ebrahimi     } else {
6556*b7893ccfSSadaf Ebrahimi         printf("%s External memory extension not supported, skipping test\n", kSkipPrefix);
6557*b7893ccfSSadaf Ebrahimi         return;
6558*b7893ccfSSadaf Ebrahimi     }
6559*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
6560*b7893ccfSSadaf Ebrahimi 
6561*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT);
6562*b7893ccfSSadaf Ebrahimi 
6563*b7893ccfSSadaf Ebrahimi     VkMemoryPropertyFlags mem_flags = 0;
6564*b7893ccfSSadaf Ebrahimi     const VkDeviceSize buffer_size = 1024;
6565*b7893ccfSSadaf Ebrahimi 
6566*b7893ccfSSadaf Ebrahimi     // Create export and import buffers
6567*b7893ccfSSadaf Ebrahimi     const VkExternalMemoryBufferCreateInfoKHR external_buffer_info = {VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR,
6568*b7893ccfSSadaf Ebrahimi                                                                       nullptr, handle_type};
6569*b7893ccfSSadaf Ebrahimi     auto buffer_info = VkBufferObj::create_info(buffer_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
6570*b7893ccfSSadaf Ebrahimi     buffer_info.pNext = &external_buffer_info;
6571*b7893ccfSSadaf Ebrahimi     VkBufferObj buffer_export;
6572*b7893ccfSSadaf Ebrahimi     buffer_export.init_no_mem(*m_device, buffer_info);
6573*b7893ccfSSadaf Ebrahimi     VkBufferObj buffer_import;
6574*b7893ccfSSadaf Ebrahimi     buffer_import.init_no_mem(*m_device, buffer_info);
6575*b7893ccfSSadaf Ebrahimi 
6576*b7893ccfSSadaf Ebrahimi     // Allocation info
6577*b7893ccfSSadaf Ebrahimi     auto alloc_info = vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, buffer_export.memory_requirements(), mem_flags);
6578*b7893ccfSSadaf Ebrahimi 
6579*b7893ccfSSadaf Ebrahimi     // Add export allocation info to pNext chain
6580*b7893ccfSSadaf Ebrahimi     VkExportMemoryAllocateInfoKHR export_info = {VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR, nullptr, handle_type};
6581*b7893ccfSSadaf Ebrahimi     alloc_info.pNext = &export_info;
6582*b7893ccfSSadaf Ebrahimi 
6583*b7893ccfSSadaf Ebrahimi     // Add dedicated allocation info to pNext chain if required
6584*b7893ccfSSadaf Ebrahimi     VkMemoryDedicatedAllocateInfoKHR dedicated_info = {VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR, nullptr,
6585*b7893ccfSSadaf Ebrahimi                                                        VK_NULL_HANDLE, buffer_export.handle()};
6586*b7893ccfSSadaf Ebrahimi     if (dedicated_allocation) {
6587*b7893ccfSSadaf Ebrahimi         export_info.pNext = &dedicated_info;
6588*b7893ccfSSadaf Ebrahimi     }
6589*b7893ccfSSadaf Ebrahimi 
6590*b7893ccfSSadaf Ebrahimi     // Allocate memory to be exported
6591*b7893ccfSSadaf Ebrahimi     vk_testing::DeviceMemory memory_export;
6592*b7893ccfSSadaf Ebrahimi     memory_export.init(*m_device, alloc_info);
6593*b7893ccfSSadaf Ebrahimi 
6594*b7893ccfSSadaf Ebrahimi     // Bind exported memory
6595*b7893ccfSSadaf Ebrahimi     buffer_export.bind_memory(memory_export, 0);
6596*b7893ccfSSadaf Ebrahimi 
6597*b7893ccfSSadaf Ebrahimi #ifdef _WIN32
6598*b7893ccfSSadaf Ebrahimi     // Export memory to handle
6599*b7893ccfSSadaf Ebrahimi     auto vkGetMemoryWin32HandleKHR = (PFN_vkGetMemoryWin32HandleKHR)vkGetInstanceProcAddr(instance(), "vkGetMemoryWin32HandleKHR");
6600*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(vkGetMemoryWin32HandleKHR != nullptr);
6601*b7893ccfSSadaf Ebrahimi     VkMemoryGetWin32HandleInfoKHR mghi = {VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR, nullptr, memory_export.handle(),
6602*b7893ccfSSadaf Ebrahimi                                           handle_type};
6603*b7893ccfSSadaf Ebrahimi     HANDLE handle;
6604*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(vkGetMemoryWin32HandleKHR(m_device->device(), &mghi, &handle));
6605*b7893ccfSSadaf Ebrahimi 
6606*b7893ccfSSadaf Ebrahimi     VkImportMemoryWin32HandleInfoKHR import_info = {VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR, nullptr, handle_type,
6607*b7893ccfSSadaf Ebrahimi                                                     handle};
6608*b7893ccfSSadaf Ebrahimi #else
6609*b7893ccfSSadaf Ebrahimi     // Export memory to fd
6610*b7893ccfSSadaf Ebrahimi     auto vkGetMemoryFdKHR = (PFN_vkGetMemoryFdKHR)vkGetInstanceProcAddr(instance(), "vkGetMemoryFdKHR");
6611*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(vkGetMemoryFdKHR != nullptr);
6612*b7893ccfSSadaf Ebrahimi     VkMemoryGetFdInfoKHR mgfi = {VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR, nullptr, memory_export.handle(), handle_type};
6613*b7893ccfSSadaf Ebrahimi     int fd;
6614*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(vkGetMemoryFdKHR(m_device->device(), &mgfi, &fd));
6615*b7893ccfSSadaf Ebrahimi 
6616*b7893ccfSSadaf Ebrahimi     VkImportMemoryFdInfoKHR import_info = {VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR, nullptr, handle_type, fd};
6617*b7893ccfSSadaf Ebrahimi #endif
6618*b7893ccfSSadaf Ebrahimi 
6619*b7893ccfSSadaf Ebrahimi     // Import memory
6620*b7893ccfSSadaf Ebrahimi     alloc_info = vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, buffer_import.memory_requirements(), mem_flags);
6621*b7893ccfSSadaf Ebrahimi     alloc_info.pNext = &import_info;
6622*b7893ccfSSadaf Ebrahimi     vk_testing::DeviceMemory memory_import;
6623*b7893ccfSSadaf Ebrahimi     memory_import.init(*m_device, alloc_info);
6624*b7893ccfSSadaf Ebrahimi 
6625*b7893ccfSSadaf Ebrahimi     // Bind imported memory
6626*b7893ccfSSadaf Ebrahimi     buffer_import.bind_memory(memory_import, 0);
6627*b7893ccfSSadaf Ebrahimi 
6628*b7893ccfSSadaf Ebrahimi     // Create test buffers and fill input buffer
6629*b7893ccfSSadaf Ebrahimi     VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
6630*b7893ccfSSadaf Ebrahimi     VkBufferObj buffer_input;
6631*b7893ccfSSadaf Ebrahimi     buffer_input.init_as_src_and_dst(*m_device, buffer_size, mem_prop);
6632*b7893ccfSSadaf Ebrahimi     auto input_mem = (uint8_t *)buffer_input.memory().map();
6633*b7893ccfSSadaf Ebrahimi     for (uint32_t i = 0; i < buffer_size; i++) {
6634*b7893ccfSSadaf Ebrahimi         input_mem[i] = (i & 0xFF);
6635*b7893ccfSSadaf Ebrahimi     }
6636*b7893ccfSSadaf Ebrahimi     buffer_input.memory().unmap();
6637*b7893ccfSSadaf Ebrahimi     VkBufferObj buffer_output;
6638*b7893ccfSSadaf Ebrahimi     buffer_output.init_as_src_and_dst(*m_device, buffer_size, mem_prop);
6639*b7893ccfSSadaf Ebrahimi 
6640*b7893ccfSSadaf Ebrahimi     // Copy from input buffer to output buffer through the exported/imported memory
6641*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
6642*b7893ccfSSadaf Ebrahimi     VkBufferCopy copy_info = {0, 0, buffer_size};
6643*b7893ccfSSadaf Ebrahimi     vkCmdCopyBuffer(m_commandBuffer->handle(), buffer_input.handle(), buffer_export.handle(), 1, &copy_info);
6644*b7893ccfSSadaf Ebrahimi     // Insert memory barrier to guarantee copy order
6645*b7893ccfSSadaf Ebrahimi     VkMemoryBarrier mem_barrier = {VK_STRUCTURE_TYPE_MEMORY_BARRIER, nullptr, VK_ACCESS_TRANSFER_WRITE_BIT,
6646*b7893ccfSSadaf Ebrahimi                                    VK_ACCESS_TRANSFER_READ_BIT};
6647*b7893ccfSSadaf Ebrahimi     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
6648*b7893ccfSSadaf Ebrahimi                          &mem_barrier, 0, nullptr, 0, nullptr);
6649*b7893ccfSSadaf Ebrahimi     vkCmdCopyBuffer(m_commandBuffer->handle(), buffer_import.handle(), buffer_output.handle(), 1, &copy_info);
6650*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
6651*b7893ccfSSadaf Ebrahimi     m_commandBuffer->QueueCommandBuffer();
6652*b7893ccfSSadaf Ebrahimi 
6653*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
6654*b7893ccfSSadaf Ebrahimi }
6655*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,ParameterLayerFeatures2Capture)6656*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, ParameterLayerFeatures2Capture) {
6657*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Ensure parameter_validation_layer correctly captures physical device features");
6658*b7893ccfSSadaf Ebrahimi     if (InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
6659*b7893ccfSSadaf Ebrahimi         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6660*b7893ccfSSadaf Ebrahimi     } else {
6661*b7893ccfSSadaf Ebrahimi         printf("%s Did not find VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME; skipped.\n", kSkipPrefix);
6662*b7893ccfSSadaf Ebrahimi         return;
6663*b7893ccfSSadaf Ebrahimi     }
6664*b7893ccfSSadaf Ebrahimi 
6665*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
6666*b7893ccfSSadaf Ebrahimi 
6667*b7893ccfSSadaf Ebrahimi     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
6668*b7893ccfSSadaf Ebrahimi         (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
6669*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
6670*b7893ccfSSadaf Ebrahimi 
6671*b7893ccfSSadaf Ebrahimi     VkResult err;
6672*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
6673*b7893ccfSSadaf Ebrahimi 
6674*b7893ccfSSadaf Ebrahimi     VkPhysicalDeviceFeatures2KHR features2;
6675*b7893ccfSSadaf Ebrahimi     features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
6676*b7893ccfSSadaf Ebrahimi     features2.pNext = nullptr;
6677*b7893ccfSSadaf Ebrahimi 
6678*b7893ccfSSadaf Ebrahimi     vkGetPhysicalDeviceFeatures2KHR(gpu(), &features2);
6679*b7893ccfSSadaf Ebrahimi 
6680*b7893ccfSSadaf Ebrahimi     // We're not creating a valid m_device, but the phy wrapper is useful
6681*b7893ccfSSadaf Ebrahimi     vk_testing::PhysicalDevice physical_device(gpu());
6682*b7893ccfSSadaf Ebrahimi     vk_testing::QueueCreateInfoArray queue_info(physical_device.queue_properties());
6683*b7893ccfSSadaf Ebrahimi     // Only request creation with queuefamilies that have at least one queue
6684*b7893ccfSSadaf Ebrahimi     std::vector<VkDeviceQueueCreateInfo> create_queue_infos;
6685*b7893ccfSSadaf Ebrahimi     auto qci = queue_info.data();
6686*b7893ccfSSadaf Ebrahimi     for (uint32_t i = 0; i < queue_info.size(); ++i) {
6687*b7893ccfSSadaf Ebrahimi         if (qci[i].queueCount) {
6688*b7893ccfSSadaf Ebrahimi             create_queue_infos.push_back(qci[i]);
6689*b7893ccfSSadaf Ebrahimi         }
6690*b7893ccfSSadaf Ebrahimi     }
6691*b7893ccfSSadaf Ebrahimi 
6692*b7893ccfSSadaf Ebrahimi     VkDeviceCreateInfo dev_info = {};
6693*b7893ccfSSadaf Ebrahimi     dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
6694*b7893ccfSSadaf Ebrahimi     dev_info.pNext = &features2;
6695*b7893ccfSSadaf Ebrahimi     dev_info.flags = 0;
6696*b7893ccfSSadaf Ebrahimi     dev_info.queueCreateInfoCount = create_queue_infos.size();
6697*b7893ccfSSadaf Ebrahimi     dev_info.pQueueCreateInfos = create_queue_infos.data();
6698*b7893ccfSSadaf Ebrahimi     dev_info.enabledLayerCount = 0;
6699*b7893ccfSSadaf Ebrahimi     dev_info.ppEnabledLayerNames = nullptr;
6700*b7893ccfSSadaf Ebrahimi     dev_info.enabledExtensionCount = 0;
6701*b7893ccfSSadaf Ebrahimi     dev_info.ppEnabledExtensionNames = nullptr;
6702*b7893ccfSSadaf Ebrahimi     dev_info.pEnabledFeatures = nullptr;
6703*b7893ccfSSadaf Ebrahimi 
6704*b7893ccfSSadaf Ebrahimi     VkDevice device;
6705*b7893ccfSSadaf Ebrahimi     err = vkCreateDevice(gpu(), &dev_info, nullptr, &device);
6706*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
6707*b7893ccfSSadaf Ebrahimi 
6708*b7893ccfSSadaf Ebrahimi     if (features2.features.samplerAnisotropy) {
6709*b7893ccfSSadaf Ebrahimi         // Test that the parameter layer is caching the features correctly using CreateSampler
6710*b7893ccfSSadaf Ebrahimi         VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
6711*b7893ccfSSadaf Ebrahimi         // If the features were not captured correctly, this should cause an error
6712*b7893ccfSSadaf Ebrahimi         sampler_ci.anisotropyEnable = VK_TRUE;
6713*b7893ccfSSadaf Ebrahimi         sampler_ci.maxAnisotropy = physical_device.properties().limits.maxSamplerAnisotropy;
6714*b7893ccfSSadaf Ebrahimi 
6715*b7893ccfSSadaf Ebrahimi         VkSampler sampler = VK_NULL_HANDLE;
6716*b7893ccfSSadaf Ebrahimi         err = vkCreateSampler(device, &sampler_ci, nullptr, &sampler);
6717*b7893ccfSSadaf Ebrahimi         ASSERT_VK_SUCCESS(err);
6718*b7893ccfSSadaf Ebrahimi         vkDestroySampler(device, sampler, nullptr);
6719*b7893ccfSSadaf Ebrahimi     } else {
6720*b7893ccfSSadaf Ebrahimi         printf("%s Feature samplerAnisotropy not enabled;  parameter_layer check skipped.\n", kSkipPrefix);
6721*b7893ccfSSadaf Ebrahimi     }
6722*b7893ccfSSadaf Ebrahimi 
6723*b7893ccfSSadaf Ebrahimi     // Verify the core validation layer has captured the physical device features by creating a a query pool.
6724*b7893ccfSSadaf Ebrahimi     if (features2.features.pipelineStatisticsQuery) {
6725*b7893ccfSSadaf Ebrahimi         VkQueryPool query_pool;
6726*b7893ccfSSadaf Ebrahimi         VkQueryPoolCreateInfo qpci{};
6727*b7893ccfSSadaf Ebrahimi         qpci.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
6728*b7893ccfSSadaf Ebrahimi         qpci.queryType = VK_QUERY_TYPE_PIPELINE_STATISTICS;
6729*b7893ccfSSadaf Ebrahimi         qpci.queryCount = 1;
6730*b7893ccfSSadaf Ebrahimi         err = vkCreateQueryPool(device, &qpci, nullptr, &query_pool);
6731*b7893ccfSSadaf Ebrahimi         ASSERT_VK_SUCCESS(err);
6732*b7893ccfSSadaf Ebrahimi 
6733*b7893ccfSSadaf Ebrahimi         vkDestroyQueryPool(device, query_pool, nullptr);
6734*b7893ccfSSadaf Ebrahimi     } else {
6735*b7893ccfSSadaf Ebrahimi         printf("%s Feature pipelineStatisticsQuery not enabled;  core_validation_layer check skipped.\n", kSkipPrefix);
6736*b7893ccfSSadaf Ebrahimi     }
6737*b7893ccfSSadaf Ebrahimi 
6738*b7893ccfSSadaf Ebrahimi     vkDestroyDevice(device, nullptr);
6739*b7893ccfSSadaf Ebrahimi 
6740*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
6741*b7893ccfSSadaf Ebrahimi }
6742*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,GetMemoryRequirements2)6743*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, GetMemoryRequirements2) {
6744*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
6745*b7893ccfSSadaf Ebrahimi         "Get memory requirements with VK_KHR_get_memory_requirements2 instead of core entry points and verify layers do not emit "
6746*b7893ccfSSadaf Ebrahimi         "errors when objects are bound and used");
6747*b7893ccfSSadaf Ebrahimi 
6748*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
6749*b7893ccfSSadaf Ebrahimi 
6750*b7893ccfSSadaf Ebrahimi     // Check for VK_KHR_get_memory_requirementes2 extensions
6751*b7893ccfSSadaf Ebrahimi     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME)) {
6752*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
6753*b7893ccfSSadaf Ebrahimi     } else {
6754*b7893ccfSSadaf Ebrahimi         printf("%s %s not supported, skipping test\n", kSkipPrefix, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
6755*b7893ccfSSadaf Ebrahimi         return;
6756*b7893ccfSSadaf Ebrahimi     }
6757*b7893ccfSSadaf Ebrahimi 
6758*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
6759*b7893ccfSSadaf Ebrahimi 
6760*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT);
6761*b7893ccfSSadaf Ebrahimi 
6762*b7893ccfSSadaf Ebrahimi     // Create a test buffer
6763*b7893ccfSSadaf Ebrahimi     VkBufferObj buffer;
6764*b7893ccfSSadaf Ebrahimi     buffer.init_no_mem(*m_device,
6765*b7893ccfSSadaf Ebrahimi                        VkBufferObj::create_info(1024, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT));
6766*b7893ccfSSadaf Ebrahimi 
6767*b7893ccfSSadaf Ebrahimi     // Use extension to get buffer memory requirements
6768*b7893ccfSSadaf Ebrahimi     auto vkGetBufferMemoryRequirements2KHR = reinterpret_cast<PFN_vkGetBufferMemoryRequirements2KHR>(
6769*b7893ccfSSadaf Ebrahimi         vkGetDeviceProcAddr(m_device->device(), "vkGetBufferMemoryRequirements2KHR"));
6770*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(vkGetBufferMemoryRequirements2KHR != nullptr);
6771*b7893ccfSSadaf Ebrahimi     VkBufferMemoryRequirementsInfo2KHR buffer_info = {VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR, nullptr,
6772*b7893ccfSSadaf Ebrahimi                                                       buffer.handle()};
6773*b7893ccfSSadaf Ebrahimi     VkMemoryRequirements2KHR buffer_reqs = {VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR};
6774*b7893ccfSSadaf Ebrahimi     vkGetBufferMemoryRequirements2KHR(m_device->device(), &buffer_info, &buffer_reqs);
6775*b7893ccfSSadaf Ebrahimi 
6776*b7893ccfSSadaf Ebrahimi     // Allocate and bind buffer memory
6777*b7893ccfSSadaf Ebrahimi     vk_testing::DeviceMemory buffer_memory;
6778*b7893ccfSSadaf Ebrahimi     buffer_memory.init(*m_device, vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, buffer_reqs.memoryRequirements, 0));
6779*b7893ccfSSadaf Ebrahimi     vkBindBufferMemory(m_device->device(), buffer.handle(), buffer_memory.handle(), 0);
6780*b7893ccfSSadaf Ebrahimi 
6781*b7893ccfSSadaf Ebrahimi     // Create a test image
6782*b7893ccfSSadaf Ebrahimi     auto image_ci = vk_testing::Image::create_info();
6783*b7893ccfSSadaf Ebrahimi     image_ci.imageType = VK_IMAGE_TYPE_2D;
6784*b7893ccfSSadaf Ebrahimi     image_ci.extent.width = 32;
6785*b7893ccfSSadaf Ebrahimi     image_ci.extent.height = 32;
6786*b7893ccfSSadaf Ebrahimi     image_ci.format = VK_FORMAT_R8G8B8A8_UNORM;
6787*b7893ccfSSadaf Ebrahimi     image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
6788*b7893ccfSSadaf Ebrahimi     image_ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
6789*b7893ccfSSadaf Ebrahimi     vk_testing::Image image;
6790*b7893ccfSSadaf Ebrahimi     image.init_no_mem(*m_device, image_ci);
6791*b7893ccfSSadaf Ebrahimi 
6792*b7893ccfSSadaf Ebrahimi     // Use extension to get image memory requirements
6793*b7893ccfSSadaf Ebrahimi     auto vkGetImageMemoryRequirements2KHR = reinterpret_cast<PFN_vkGetImageMemoryRequirements2KHR>(
6794*b7893ccfSSadaf Ebrahimi         vkGetDeviceProcAddr(m_device->device(), "vkGetImageMemoryRequirements2KHR"));
6795*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(vkGetImageMemoryRequirements2KHR != nullptr);
6796*b7893ccfSSadaf Ebrahimi     VkImageMemoryRequirementsInfo2KHR image_info = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR, nullptr,
6797*b7893ccfSSadaf Ebrahimi                                                     image.handle()};
6798*b7893ccfSSadaf Ebrahimi     VkMemoryRequirements2KHR image_reqs = {VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR};
6799*b7893ccfSSadaf Ebrahimi     vkGetImageMemoryRequirements2KHR(m_device->device(), &image_info, &image_reqs);
6800*b7893ccfSSadaf Ebrahimi 
6801*b7893ccfSSadaf Ebrahimi     // Allocate and bind image memory
6802*b7893ccfSSadaf Ebrahimi     vk_testing::DeviceMemory image_memory;
6803*b7893ccfSSadaf Ebrahimi     image_memory.init(*m_device, vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, image_reqs.memoryRequirements, 0));
6804*b7893ccfSSadaf Ebrahimi     vkBindImageMemory(m_device->device(), image.handle(), image_memory.handle(), 0);
6805*b7893ccfSSadaf Ebrahimi 
6806*b7893ccfSSadaf Ebrahimi     // Now execute arbitrary commands that use the test buffer and image
6807*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
6808*b7893ccfSSadaf Ebrahimi 
6809*b7893ccfSSadaf Ebrahimi     // Fill buffer with 0
6810*b7893ccfSSadaf Ebrahimi     vkCmdFillBuffer(m_commandBuffer->handle(), buffer.handle(), 0, VK_WHOLE_SIZE, 0);
6811*b7893ccfSSadaf Ebrahimi 
6812*b7893ccfSSadaf Ebrahimi     // Transition and clear image
6813*b7893ccfSSadaf Ebrahimi     const auto subresource_range = image.subresource_range(VK_IMAGE_ASPECT_COLOR_BIT);
6814*b7893ccfSSadaf Ebrahimi     const auto barrier = image.image_memory_barrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
6815*b7893ccfSSadaf Ebrahimi                                                     VK_IMAGE_LAYOUT_GENERAL, subresource_range);
6816*b7893ccfSSadaf Ebrahimi     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
6817*b7893ccfSSadaf Ebrahimi                          nullptr, 0, nullptr, 1, &barrier);
6818*b7893ccfSSadaf Ebrahimi     const VkClearColorValue color = {};
6819*b7893ccfSSadaf Ebrahimi     vkCmdClearColorImage(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, &color, 1, &subresource_range);
6820*b7893ccfSSadaf Ebrahimi 
6821*b7893ccfSSadaf Ebrahimi     // Submit and verify no validation errors
6822*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
6823*b7893ccfSSadaf Ebrahimi     m_commandBuffer->QueueCommandBuffer();
6824*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
6825*b7893ccfSSadaf Ebrahimi }
6826*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,BindMemory2)6827*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, BindMemory2) {
6828*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
6829*b7893ccfSSadaf Ebrahimi         "Bind memory with VK_KHR_bind_memory2 instead of core entry points and verify layers do not emit errors when objects are "
6830*b7893ccfSSadaf Ebrahimi         "used");
6831*b7893ccfSSadaf Ebrahimi 
6832*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
6833*b7893ccfSSadaf Ebrahimi 
6834*b7893ccfSSadaf Ebrahimi     // Check for VK_KHR_get_memory_requirementes2 extensions
6835*b7893ccfSSadaf Ebrahimi     if (DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME)) {
6836*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
6837*b7893ccfSSadaf Ebrahimi     } else {
6838*b7893ccfSSadaf Ebrahimi         printf("%s %s not supported, skipping test\n", kSkipPrefix, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
6839*b7893ccfSSadaf Ebrahimi         return;
6840*b7893ccfSSadaf Ebrahimi     }
6841*b7893ccfSSadaf Ebrahimi 
6842*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
6843*b7893ccfSSadaf Ebrahimi 
6844*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess(VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT);
6845*b7893ccfSSadaf Ebrahimi 
6846*b7893ccfSSadaf Ebrahimi     // Create a test buffer
6847*b7893ccfSSadaf Ebrahimi     VkBufferObj buffer;
6848*b7893ccfSSadaf Ebrahimi     buffer.init_no_mem(*m_device, VkBufferObj::create_info(1024, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
6849*b7893ccfSSadaf Ebrahimi 
6850*b7893ccfSSadaf Ebrahimi     // Allocate buffer memory
6851*b7893ccfSSadaf Ebrahimi     vk_testing::DeviceMemory buffer_memory;
6852*b7893ccfSSadaf Ebrahimi     buffer_memory.init(*m_device, vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, buffer.memory_requirements(), 0));
6853*b7893ccfSSadaf Ebrahimi 
6854*b7893ccfSSadaf Ebrahimi     // Bind buffer memory with extension
6855*b7893ccfSSadaf Ebrahimi     auto vkBindBufferMemory2KHR =
6856*b7893ccfSSadaf Ebrahimi         reinterpret_cast<PFN_vkBindBufferMemory2KHR>(vkGetDeviceProcAddr(m_device->device(), "vkBindBufferMemory2KHR"));
6857*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(vkBindBufferMemory2KHR != nullptr);
6858*b7893ccfSSadaf Ebrahimi     VkBindBufferMemoryInfoKHR buffer_bind_info = {VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR, nullptr, buffer.handle(),
6859*b7893ccfSSadaf Ebrahimi                                                   buffer_memory.handle(), 0};
6860*b7893ccfSSadaf Ebrahimi     vkBindBufferMemory2KHR(m_device->device(), 1, &buffer_bind_info);
6861*b7893ccfSSadaf Ebrahimi 
6862*b7893ccfSSadaf Ebrahimi     // Create a test image
6863*b7893ccfSSadaf Ebrahimi     auto image_ci = vk_testing::Image::create_info();
6864*b7893ccfSSadaf Ebrahimi     image_ci.imageType = VK_IMAGE_TYPE_2D;
6865*b7893ccfSSadaf Ebrahimi     image_ci.extent.width = 32;
6866*b7893ccfSSadaf Ebrahimi     image_ci.extent.height = 32;
6867*b7893ccfSSadaf Ebrahimi     image_ci.format = VK_FORMAT_R8G8B8A8_UNORM;
6868*b7893ccfSSadaf Ebrahimi     image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
6869*b7893ccfSSadaf Ebrahimi     image_ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
6870*b7893ccfSSadaf Ebrahimi     vk_testing::Image image;
6871*b7893ccfSSadaf Ebrahimi     image.init_no_mem(*m_device, image_ci);
6872*b7893ccfSSadaf Ebrahimi 
6873*b7893ccfSSadaf Ebrahimi     // Allocate image memory
6874*b7893ccfSSadaf Ebrahimi     vk_testing::DeviceMemory image_memory;
6875*b7893ccfSSadaf Ebrahimi     image_memory.init(*m_device, vk_testing::DeviceMemory::get_resource_alloc_info(*m_device, image.memory_requirements(), 0));
6876*b7893ccfSSadaf Ebrahimi 
6877*b7893ccfSSadaf Ebrahimi     // Bind image memory with extension
6878*b7893ccfSSadaf Ebrahimi     auto vkBindImageMemory2KHR =
6879*b7893ccfSSadaf Ebrahimi         reinterpret_cast<PFN_vkBindImageMemory2KHR>(vkGetDeviceProcAddr(m_device->device(), "vkBindImageMemory2KHR"));
6880*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(vkBindImageMemory2KHR != nullptr);
6881*b7893ccfSSadaf Ebrahimi     VkBindImageMemoryInfoKHR image_bind_info = {VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR, nullptr, image.handle(),
6882*b7893ccfSSadaf Ebrahimi                                                 image_memory.handle(), 0};
6883*b7893ccfSSadaf Ebrahimi     vkBindImageMemory2KHR(m_device->device(), 1, &image_bind_info);
6884*b7893ccfSSadaf Ebrahimi 
6885*b7893ccfSSadaf Ebrahimi     // Now execute arbitrary commands that use the test buffer and image
6886*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
6887*b7893ccfSSadaf Ebrahimi 
6888*b7893ccfSSadaf Ebrahimi     // Fill buffer with 0
6889*b7893ccfSSadaf Ebrahimi     vkCmdFillBuffer(m_commandBuffer->handle(), buffer.handle(), 0, VK_WHOLE_SIZE, 0);
6890*b7893ccfSSadaf Ebrahimi 
6891*b7893ccfSSadaf Ebrahimi     // Transition and clear image
6892*b7893ccfSSadaf Ebrahimi     const auto subresource_range = image.subresource_range(VK_IMAGE_ASPECT_COLOR_BIT);
6893*b7893ccfSSadaf Ebrahimi     const auto barrier = image.image_memory_barrier(0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
6894*b7893ccfSSadaf Ebrahimi                                                     VK_IMAGE_LAYOUT_GENERAL, subresource_range);
6895*b7893ccfSSadaf Ebrahimi     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
6896*b7893ccfSSadaf Ebrahimi                          nullptr, 0, nullptr, 1, &barrier);
6897*b7893ccfSSadaf Ebrahimi     const VkClearColorValue color = {};
6898*b7893ccfSSadaf Ebrahimi     vkCmdClearColorImage(m_commandBuffer->handle(), image.handle(), VK_IMAGE_LAYOUT_GENERAL, &color, 1, &subresource_range);
6899*b7893ccfSSadaf Ebrahimi 
6900*b7893ccfSSadaf Ebrahimi     // Submit and verify no validation errors
6901*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
6902*b7893ccfSSadaf Ebrahimi     m_commandBuffer->QueueCommandBuffer();
6903*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
6904*b7893ccfSSadaf Ebrahimi }
6905*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CreatePipelineWithCoreChecksDisabled)6906*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CreatePipelineWithCoreChecksDisabled) {
6907*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Test CreatePipeline while the CoreChecks validation object is disabled");
6908*b7893ccfSSadaf Ebrahimi 
6909*b7893ccfSSadaf Ebrahimi     // Enable KHR validation features extension
6910*b7893ccfSSadaf Ebrahimi     VkValidationFeatureDisableEXT disables[] = {VK_VALIDATION_FEATURE_DISABLE_CORE_CHECKS_EXT};
6911*b7893ccfSSadaf Ebrahimi     VkValidationFeaturesEXT features = {};
6912*b7893ccfSSadaf Ebrahimi     features.sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT;
6913*b7893ccfSSadaf Ebrahimi     features.disabledValidationFeatureCount = 1;
6914*b7893ccfSSadaf Ebrahimi     features.pDisabledValidationFeatures = disables;
6915*b7893ccfSSadaf Ebrahimi 
6916*b7893ccfSSadaf Ebrahimi     VkCommandPoolCreateFlags pool_flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
6917*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init(nullptr, nullptr, pool_flags, &features));
6918*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6919*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
6920*b7893ccfSSadaf Ebrahimi     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
6921*b7893ccfSSadaf Ebrahimi     VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
6922*b7893ccfSSadaf Ebrahimi                                                  VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
6923*b7893ccfSSadaf Ebrahimi 
6924*b7893ccfSSadaf Ebrahimi     CreatePipelineHelper pipe(*this);
6925*b7893ccfSSadaf Ebrahimi     pipe.InitInfo();
6926*b7893ccfSSadaf Ebrahimi     pipe.gp_ci_.pInputAssemblyState = &iasci;
6927*b7893ccfSSadaf Ebrahimi     pipe.shader_stages_ = {vs.GetStageCreateInfo(), fs.GetStageCreateInfo()};
6928*b7893ccfSSadaf Ebrahimi     pipe.InitState();
6929*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
6930*b7893ccfSSadaf Ebrahimi     pipe.CreateGraphicsPipeline();
6931*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
6932*b7893ccfSSadaf Ebrahimi }
6933*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CreatePipeineWithTessellationDomainOrigin)6934*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CreatePipeineWithTessellationDomainOrigin) {
6935*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
6936*b7893ccfSSadaf Ebrahimi         "Test CreatePipeline when VkPipelineTessellationStateCreateInfo.pNext include "
6937*b7893ccfSSadaf Ebrahimi         "VkPipelineTessellationDomainOriginStateCreateInfo");
6938*b7893ccfSSadaf Ebrahimi 
6939*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
6940*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6941*b7893ccfSSadaf Ebrahimi 
6942*b7893ccfSSadaf Ebrahimi     if (!m_device->phy().features().tessellationShader) {
6943*b7893ccfSSadaf Ebrahimi         printf("%s Device does not support tessellation shaders; skipped.\n", kSkipPrefix);
6944*b7893ccfSSadaf Ebrahimi         return;
6945*b7893ccfSSadaf Ebrahimi     }
6946*b7893ccfSSadaf Ebrahimi 
6947*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
6948*b7893ccfSSadaf Ebrahimi     VkShaderObj tcs(m_device, bindStateTscShaderText, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
6949*b7893ccfSSadaf Ebrahimi     VkShaderObj tes(m_device, bindStateTeshaderText, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
6950*b7893ccfSSadaf Ebrahimi     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
6951*b7893ccfSSadaf Ebrahimi 
6952*b7893ccfSSadaf Ebrahimi     VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
6953*b7893ccfSSadaf Ebrahimi                                                  VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
6954*b7893ccfSSadaf Ebrahimi 
6955*b7893ccfSSadaf Ebrahimi     VkPipelineTessellationDomainOriginStateCreateInfo tessellationDomainOriginStateInfo = {
6956*b7893ccfSSadaf Ebrahimi         VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO, VK_NULL_HANDLE,
6957*b7893ccfSSadaf Ebrahimi         VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT};
6958*b7893ccfSSadaf Ebrahimi 
6959*b7893ccfSSadaf Ebrahimi     VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
6960*b7893ccfSSadaf Ebrahimi                                                &tessellationDomainOriginStateInfo, 0, 3};
6961*b7893ccfSSadaf Ebrahimi 
6962*b7893ccfSSadaf Ebrahimi     CreatePipelineHelper pipe(*this);
6963*b7893ccfSSadaf Ebrahimi     pipe.InitInfo();
6964*b7893ccfSSadaf Ebrahimi     pipe.gp_ci_.pTessellationState = &tsci;
6965*b7893ccfSSadaf Ebrahimi     pipe.gp_ci_.pInputAssemblyState = &iasci;
6966*b7893ccfSSadaf Ebrahimi     pipe.shader_stages_ = {vs.GetStageCreateInfo(), tcs.GetStageCreateInfo(), tes.GetStageCreateInfo(), fs.GetStageCreateInfo()};
6967*b7893ccfSSadaf Ebrahimi     pipe.InitState();
6968*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
6969*b7893ccfSSadaf Ebrahimi     pipe.CreateGraphicsPipeline();
6970*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
6971*b7893ccfSSadaf Ebrahimi }
6972*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,MultiplaneImageCopyBufferToImage)6973*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, MultiplaneImageCopyBufferToImage) {
6974*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Positive test of multiplane copy buffer to image");
6975*b7893ccfSSadaf Ebrahimi     // Enable KHR multiplane req'd extensions
6976*b7893ccfSSadaf Ebrahimi     bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
6977*b7893ccfSSadaf Ebrahimi                                                     VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_SPEC_VERSION);
6978*b7893ccfSSadaf Ebrahimi     if (mp_extensions) {
6979*b7893ccfSSadaf Ebrahimi         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
6980*b7893ccfSSadaf Ebrahimi     }
6981*b7893ccfSSadaf Ebrahimi     SetTargetApiVersion(VK_API_VERSION_1_1);
6982*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
6983*b7893ccfSSadaf Ebrahimi     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
6984*b7893ccfSSadaf Ebrahimi     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
6985*b7893ccfSSadaf Ebrahimi     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
6986*b7893ccfSSadaf Ebrahimi     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
6987*b7893ccfSSadaf Ebrahimi     if (mp_extensions) {
6988*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
6989*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
6990*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
6991*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME);
6992*b7893ccfSSadaf Ebrahimi     } else {
6993*b7893ccfSSadaf Ebrahimi         printf("%s test requires KHR multiplane extensions, not available.  Skipping.\n", kSkipPrefix);
6994*b7893ccfSSadaf Ebrahimi         return;
6995*b7893ccfSSadaf Ebrahimi     }
6996*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
6997*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
6998*b7893ccfSSadaf Ebrahimi 
6999*b7893ccfSSadaf Ebrahimi     VkImageCreateInfo ci = {};
7000*b7893ccfSSadaf Ebrahimi     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7001*b7893ccfSSadaf Ebrahimi     ci.pNext = NULL;
7002*b7893ccfSSadaf Ebrahimi     ci.flags = 0;
7003*b7893ccfSSadaf Ebrahimi     ci.imageType = VK_IMAGE_TYPE_2D;
7004*b7893ccfSSadaf Ebrahimi     ci.format = VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR;  // All planes of equal extent
7005*b7893ccfSSadaf Ebrahimi     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
7006*b7893ccfSSadaf Ebrahimi     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
7007*b7893ccfSSadaf Ebrahimi     ci.extent = {16, 16, 1};
7008*b7893ccfSSadaf Ebrahimi     ci.mipLevels = 1;
7009*b7893ccfSSadaf Ebrahimi     ci.arrayLayers = 1;
7010*b7893ccfSSadaf Ebrahimi     ci.samples = VK_SAMPLE_COUNT_1_BIT;
7011*b7893ccfSSadaf Ebrahimi     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
7012*b7893ccfSSadaf Ebrahimi     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
7013*b7893ccfSSadaf Ebrahimi 
7014*b7893ccfSSadaf Ebrahimi     VkFormatFeatureFlags features = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
7015*b7893ccfSSadaf Ebrahimi     bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
7016*b7893ccfSSadaf Ebrahimi     if (!supported) {
7017*b7893ccfSSadaf Ebrahimi         printf("%s Multiplane image format not supported.  Skipping test.\n", kSkipPrefix);
7018*b7893ccfSSadaf Ebrahimi         return;  // Assume there's low ROI on searching for different mp formats
7019*b7893ccfSSadaf Ebrahimi     }
7020*b7893ccfSSadaf Ebrahimi 
7021*b7893ccfSSadaf Ebrahimi     VkImageObj image(m_device);
7022*b7893ccfSSadaf Ebrahimi     image.init(&ci);
7023*b7893ccfSSadaf Ebrahimi 
7024*b7893ccfSSadaf Ebrahimi     m_commandBuffer->reset();
7025*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
7026*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
7027*b7893ccfSSadaf Ebrahimi     image.ImageMemoryBarrier(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, 0, VK_ACCESS_TRANSFER_WRITE_BIT,
7028*b7893ccfSSadaf Ebrahimi                              VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
7029*b7893ccfSSadaf Ebrahimi 
7030*b7893ccfSSadaf Ebrahimi     std::array<VkImageAspectFlagBits, 3> aspects = {VK_IMAGE_ASPECT_PLANE_0_BIT, VK_IMAGE_ASPECT_PLANE_1_BIT,
7031*b7893ccfSSadaf Ebrahimi                                                     VK_IMAGE_ASPECT_PLANE_2_BIT};
7032*b7893ccfSSadaf Ebrahimi     std::array<VkBufferObj, 3> buffers;
7033*b7893ccfSSadaf Ebrahimi     VkMemoryPropertyFlags reqs = 0;
7034*b7893ccfSSadaf Ebrahimi 
7035*b7893ccfSSadaf Ebrahimi     VkBufferImageCopy copy = {};
7036*b7893ccfSSadaf Ebrahimi     copy.imageSubresource.layerCount = 1;
7037*b7893ccfSSadaf Ebrahimi     copy.imageExtent.depth = 1;
7038*b7893ccfSSadaf Ebrahimi     copy.imageExtent.height = 16;
7039*b7893ccfSSadaf Ebrahimi     copy.imageExtent.width = 16;
7040*b7893ccfSSadaf Ebrahimi 
7041*b7893ccfSSadaf Ebrahimi     for (size_t i = 0; i < aspects.size(); ++i) {
7042*b7893ccfSSadaf Ebrahimi         buffers[i].init_as_src(*m_device, (VkDeviceSize)16 * 16 * 1, reqs);
7043*b7893ccfSSadaf Ebrahimi         copy.imageSubresource.aspectMask = aspects[i];
7044*b7893ccfSSadaf Ebrahimi         vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffers[i].handle(), image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
7045*b7893ccfSSadaf Ebrahimi                                1, &copy);
7046*b7893ccfSSadaf Ebrahimi     }
7047*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
7048*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
7049*b7893ccfSSadaf Ebrahimi }
7050*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,MultiplaneImageTests)7051*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, MultiplaneImageTests) {
7052*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Positive test of multiplane image operations");
7053*b7893ccfSSadaf Ebrahimi 
7054*b7893ccfSSadaf Ebrahimi     // Enable KHR multiplane req'd extensions
7055*b7893ccfSSadaf Ebrahimi     bool mp_extensions = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
7056*b7893ccfSSadaf Ebrahimi                                                     VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_SPEC_VERSION);
7057*b7893ccfSSadaf Ebrahimi     if (mp_extensions) {
7058*b7893ccfSSadaf Ebrahimi         m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7059*b7893ccfSSadaf Ebrahimi     }
7060*b7893ccfSSadaf Ebrahimi     SetTargetApiVersion(VK_API_VERSION_1_1);
7061*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
7062*b7893ccfSSadaf Ebrahimi     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
7063*b7893ccfSSadaf Ebrahimi     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
7064*b7893ccfSSadaf Ebrahimi     mp_extensions = mp_extensions && DeviceExtensionSupported(gpu(), nullptr, VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
7065*b7893ccfSSadaf Ebrahimi     if (mp_extensions) {
7066*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
7067*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
7068*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME);
7069*b7893ccfSSadaf Ebrahimi     } else {
7070*b7893ccfSSadaf Ebrahimi         printf("%s test requires KHR multiplane extensions, not available.  Skipping.\n", kSkipPrefix);
7071*b7893ccfSSadaf Ebrahimi         return;
7072*b7893ccfSSadaf Ebrahimi     }
7073*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
7074*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7075*b7893ccfSSadaf Ebrahimi 
7076*b7893ccfSSadaf Ebrahimi     // Create aliased function pointers for 1.0 and 1.1 contexts
7077*b7893ccfSSadaf Ebrahimi 
7078*b7893ccfSSadaf Ebrahimi     PFN_vkBindImageMemory2KHR vkBindImageMemory2Function = nullptr;
7079*b7893ccfSSadaf Ebrahimi     PFN_vkGetImageMemoryRequirements2KHR vkGetImageMemoryRequirements2Function = nullptr;
7080*b7893ccfSSadaf Ebrahimi     PFN_vkGetPhysicalDeviceMemoryProperties2KHR vkGetPhysicalDeviceMemoryProperties2Function = nullptr;
7081*b7893ccfSSadaf Ebrahimi 
7082*b7893ccfSSadaf Ebrahimi     if (DeviceValidationVersion() >= VK_API_VERSION_1_1) {
7083*b7893ccfSSadaf Ebrahimi         vkBindImageMemory2Function = vkBindImageMemory2;
7084*b7893ccfSSadaf Ebrahimi         vkGetImageMemoryRequirements2Function = vkGetImageMemoryRequirements2;
7085*b7893ccfSSadaf Ebrahimi         vkGetPhysicalDeviceMemoryProperties2Function = vkGetPhysicalDeviceMemoryProperties2;
7086*b7893ccfSSadaf Ebrahimi     } else {
7087*b7893ccfSSadaf Ebrahimi         vkBindImageMemory2Function = (PFN_vkBindImageMemory2KHR)vkGetDeviceProcAddr(m_device->handle(), "vkBindImageMemory2KHR");
7088*b7893ccfSSadaf Ebrahimi         vkGetImageMemoryRequirements2Function =
7089*b7893ccfSSadaf Ebrahimi             (PFN_vkGetImageMemoryRequirements2KHR)vkGetDeviceProcAddr(m_device->handle(), "vkGetImageMemoryRequirements2KHR");
7090*b7893ccfSSadaf Ebrahimi         vkGetPhysicalDeviceMemoryProperties2Function = (PFN_vkGetPhysicalDeviceMemoryProperties2KHR)vkGetDeviceProcAddr(
7091*b7893ccfSSadaf Ebrahimi             m_device->handle(), "vkGetPhysicalDeviceMemoryProperties2KHR");
7092*b7893ccfSSadaf Ebrahimi     }
7093*b7893ccfSSadaf Ebrahimi 
7094*b7893ccfSSadaf Ebrahimi     if (!vkBindImageMemory2Function || !vkGetImageMemoryRequirements2Function || !vkGetPhysicalDeviceMemoryProperties2Function) {
7095*b7893ccfSSadaf Ebrahimi         printf("%s Did not find required device extension support; test skipped.\n", kSkipPrefix);
7096*b7893ccfSSadaf Ebrahimi         return;
7097*b7893ccfSSadaf Ebrahimi     }
7098*b7893ccfSSadaf Ebrahimi 
7099*b7893ccfSSadaf Ebrahimi     VkImageCreateInfo ci = {};
7100*b7893ccfSSadaf Ebrahimi     ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
7101*b7893ccfSSadaf Ebrahimi     ci.pNext = NULL;
7102*b7893ccfSSadaf Ebrahimi     ci.flags = 0;
7103*b7893ccfSSadaf Ebrahimi     ci.imageType = VK_IMAGE_TYPE_2D;
7104*b7893ccfSSadaf Ebrahimi     ci.format = VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR;  // All planes of equal extent
7105*b7893ccfSSadaf Ebrahimi     ci.tiling = VK_IMAGE_TILING_OPTIMAL;
7106*b7893ccfSSadaf Ebrahimi     ci.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
7107*b7893ccfSSadaf Ebrahimi     ci.extent = {128, 128, 1};
7108*b7893ccfSSadaf Ebrahimi     ci.mipLevels = 1;
7109*b7893ccfSSadaf Ebrahimi     ci.arrayLayers = 1;
7110*b7893ccfSSadaf Ebrahimi     ci.samples = VK_SAMPLE_COUNT_1_BIT;
7111*b7893ccfSSadaf Ebrahimi     ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
7112*b7893ccfSSadaf Ebrahimi     ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
7113*b7893ccfSSadaf Ebrahimi 
7114*b7893ccfSSadaf Ebrahimi     // Verify format
7115*b7893ccfSSadaf Ebrahimi     VkFormatFeatureFlags features = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
7116*b7893ccfSSadaf Ebrahimi     bool supported = ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features);
7117*b7893ccfSSadaf Ebrahimi     if (!supported) {
7118*b7893ccfSSadaf Ebrahimi         printf("%s Multiplane image format not supported.  Skipping test.\n", kSkipPrefix);
7119*b7893ccfSSadaf Ebrahimi         return;  // Assume there's low ROI on searching for different mp formats
7120*b7893ccfSSadaf Ebrahimi     }
7121*b7893ccfSSadaf Ebrahimi 
7122*b7893ccfSSadaf Ebrahimi     VkImage image;
7123*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(vkCreateImage(device(), &ci, NULL, &image));
7124*b7893ccfSSadaf Ebrahimi 
7125*b7893ccfSSadaf Ebrahimi     // Allocate & bind memory
7126*b7893ccfSSadaf Ebrahimi     VkPhysicalDeviceMemoryProperties phys_mem_props;
7127*b7893ccfSSadaf Ebrahimi     vkGetPhysicalDeviceMemoryProperties(gpu(), &phys_mem_props);
7128*b7893ccfSSadaf Ebrahimi     VkMemoryRequirements mem_reqs;
7129*b7893ccfSSadaf Ebrahimi     vkGetImageMemoryRequirements(device(), image, &mem_reqs);
7130*b7893ccfSSadaf Ebrahimi     VkDeviceMemory mem_obj = VK_NULL_HANDLE;
7131*b7893ccfSSadaf Ebrahimi     VkMemoryPropertyFlagBits mem_props = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
7132*b7893ccfSSadaf Ebrahimi     for (uint32_t type = 0; type < phys_mem_props.memoryTypeCount; type++) {
7133*b7893ccfSSadaf Ebrahimi         if ((mem_reqs.memoryTypeBits & (1 << type)) &&
7134*b7893ccfSSadaf Ebrahimi             ((phys_mem_props.memoryTypes[type].propertyFlags & mem_props) == mem_props)) {
7135*b7893ccfSSadaf Ebrahimi             VkMemoryAllocateInfo alloc_info = {};
7136*b7893ccfSSadaf Ebrahimi             alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
7137*b7893ccfSSadaf Ebrahimi             alloc_info.allocationSize = mem_reqs.size;
7138*b7893ccfSSadaf Ebrahimi             alloc_info.memoryTypeIndex = type;
7139*b7893ccfSSadaf Ebrahimi             ASSERT_VK_SUCCESS(vkAllocateMemory(device(), &alloc_info, NULL, &mem_obj));
7140*b7893ccfSSadaf Ebrahimi             break;
7141*b7893ccfSSadaf Ebrahimi         }
7142*b7893ccfSSadaf Ebrahimi     }
7143*b7893ccfSSadaf Ebrahimi 
7144*b7893ccfSSadaf Ebrahimi     if (VK_NULL_HANDLE == mem_obj) {
7145*b7893ccfSSadaf Ebrahimi         printf("%s Unable to allocate image memory. Skipping test.\n", kSkipPrefix);
7146*b7893ccfSSadaf Ebrahimi         vkDestroyImage(device(), image, NULL);
7147*b7893ccfSSadaf Ebrahimi         return;
7148*b7893ccfSSadaf Ebrahimi     }
7149*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(vkBindImageMemory(device(), image, mem_obj, 0));
7150*b7893ccfSSadaf Ebrahimi 
7151*b7893ccfSSadaf Ebrahimi     // Copy plane 0 to plane 2
7152*b7893ccfSSadaf Ebrahimi     VkImageCopy copyRegion = {};
7153*b7893ccfSSadaf Ebrahimi     copyRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_0_BIT_KHR;
7154*b7893ccfSSadaf Ebrahimi     copyRegion.srcSubresource.mipLevel = 0;
7155*b7893ccfSSadaf Ebrahimi     copyRegion.srcSubresource.baseArrayLayer = 0;
7156*b7893ccfSSadaf Ebrahimi     copyRegion.srcSubresource.layerCount = 1;
7157*b7893ccfSSadaf Ebrahimi     copyRegion.srcOffset = {0, 0, 0};
7158*b7893ccfSSadaf Ebrahimi     copyRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_2_BIT_KHR;
7159*b7893ccfSSadaf Ebrahimi     copyRegion.dstSubresource.mipLevel = 0;
7160*b7893ccfSSadaf Ebrahimi     copyRegion.dstSubresource.baseArrayLayer = 0;
7161*b7893ccfSSadaf Ebrahimi     copyRegion.dstSubresource.layerCount = 1;
7162*b7893ccfSSadaf Ebrahimi     copyRegion.dstOffset = {0, 0, 0};
7163*b7893ccfSSadaf Ebrahimi     copyRegion.extent.width = 128;
7164*b7893ccfSSadaf Ebrahimi     copyRegion.extent.height = 128;
7165*b7893ccfSSadaf Ebrahimi     copyRegion.extent.depth = 1;
7166*b7893ccfSSadaf Ebrahimi 
7167*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
7168*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
7169*b7893ccfSSadaf Ebrahimi     m_commandBuffer->CopyImage(image, VK_IMAGE_LAYOUT_GENERAL, image, VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
7170*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
7171*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
7172*b7893ccfSSadaf Ebrahimi 
7173*b7893ccfSSadaf Ebrahimi     vkFreeMemory(device(), mem_obj, NULL);
7174*b7893ccfSSadaf Ebrahimi     vkDestroyImage(device(), image, NULL);
7175*b7893ccfSSadaf Ebrahimi 
7176*b7893ccfSSadaf Ebrahimi     // Repeat bind test on a DISJOINT multi-planar image, with per-plane memory objects, using API2 variants
7177*b7893ccfSSadaf Ebrahimi     //
7178*b7893ccfSSadaf Ebrahimi     features |= VK_FORMAT_FEATURE_DISJOINT_BIT;
7179*b7893ccfSSadaf Ebrahimi     ci.flags = VK_IMAGE_CREATE_DISJOINT_BIT;
7180*b7893ccfSSadaf Ebrahimi     if (ImageFormatAndFeaturesSupported(instance(), gpu(), ci, features)) {
7181*b7893ccfSSadaf Ebrahimi         ASSERT_VK_SUCCESS(vkCreateImage(device(), &ci, NULL, &image));
7182*b7893ccfSSadaf Ebrahimi 
7183*b7893ccfSSadaf Ebrahimi         // Allocate & bind memory
7184*b7893ccfSSadaf Ebrahimi         VkPhysicalDeviceMemoryProperties2 phys_mem_props2 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2};
7185*b7893ccfSSadaf Ebrahimi         vkGetPhysicalDeviceMemoryProperties2Function(gpu(), &phys_mem_props2);
7186*b7893ccfSSadaf Ebrahimi         VkImagePlaneMemoryRequirementsInfo image_plane_req = {VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO};
7187*b7893ccfSSadaf Ebrahimi         VkImageMemoryRequirementsInfo2 mem_req_info2 = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2};
7188*b7893ccfSSadaf Ebrahimi         mem_req_info2.pNext = &image_plane_req;
7189*b7893ccfSSadaf Ebrahimi         mem_req_info2.image = image;
7190*b7893ccfSSadaf Ebrahimi         VkMemoryRequirements2 mem_reqs2 = {VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2};
7191*b7893ccfSSadaf Ebrahimi 
7192*b7893ccfSSadaf Ebrahimi         VkDeviceMemory p0_mem, p1_mem, p2_mem;
7193*b7893ccfSSadaf Ebrahimi         mem_props = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
7194*b7893ccfSSadaf Ebrahimi         VkMemoryAllocateInfo alloc_info = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};
7195*b7893ccfSSadaf Ebrahimi 
7196*b7893ccfSSadaf Ebrahimi         // Plane 0
7197*b7893ccfSSadaf Ebrahimi         image_plane_req.planeAspect = VK_IMAGE_ASPECT_PLANE_0_BIT;
7198*b7893ccfSSadaf Ebrahimi         vkGetImageMemoryRequirements2Function(device(), &mem_req_info2, &mem_reqs2);
7199*b7893ccfSSadaf Ebrahimi         uint32_t mem_type = 0;
7200*b7893ccfSSadaf Ebrahimi         for (mem_type = 0; mem_type < phys_mem_props2.memoryProperties.memoryTypeCount; mem_type++) {
7201*b7893ccfSSadaf Ebrahimi             if ((mem_reqs2.memoryRequirements.memoryTypeBits & (1 << mem_type)) &&
7202*b7893ccfSSadaf Ebrahimi                 ((phys_mem_props2.memoryProperties.memoryTypes[mem_type].propertyFlags & mem_props) == mem_props)) {
7203*b7893ccfSSadaf Ebrahimi                 alloc_info.memoryTypeIndex = mem_type;
7204*b7893ccfSSadaf Ebrahimi                 break;
7205*b7893ccfSSadaf Ebrahimi             }
7206*b7893ccfSSadaf Ebrahimi         }
7207*b7893ccfSSadaf Ebrahimi         alloc_info.allocationSize = mem_reqs2.memoryRequirements.size;
7208*b7893ccfSSadaf Ebrahimi         ASSERT_VK_SUCCESS(vkAllocateMemory(device(), &alloc_info, NULL, &p0_mem));
7209*b7893ccfSSadaf Ebrahimi 
7210*b7893ccfSSadaf Ebrahimi         // Plane 1 & 2 use same memory type
7211*b7893ccfSSadaf Ebrahimi         image_plane_req.planeAspect = VK_IMAGE_ASPECT_PLANE_1_BIT;
7212*b7893ccfSSadaf Ebrahimi         vkGetImageMemoryRequirements2Function(device(), &mem_req_info2, &mem_reqs2);
7213*b7893ccfSSadaf Ebrahimi         alloc_info.allocationSize = mem_reqs2.memoryRequirements.size;
7214*b7893ccfSSadaf Ebrahimi         ASSERT_VK_SUCCESS(vkAllocateMemory(device(), &alloc_info, NULL, &p1_mem));
7215*b7893ccfSSadaf Ebrahimi 
7216*b7893ccfSSadaf Ebrahimi         image_plane_req.planeAspect = VK_IMAGE_ASPECT_PLANE_2_BIT;
7217*b7893ccfSSadaf Ebrahimi         vkGetImageMemoryRequirements2Function(device(), &mem_req_info2, &mem_reqs2);
7218*b7893ccfSSadaf Ebrahimi         alloc_info.allocationSize = mem_reqs2.memoryRequirements.size;
7219*b7893ccfSSadaf Ebrahimi         ASSERT_VK_SUCCESS(vkAllocateMemory(device(), &alloc_info, NULL, &p2_mem));
7220*b7893ccfSSadaf Ebrahimi 
7221*b7893ccfSSadaf Ebrahimi         // Set up 3-plane binding
7222*b7893ccfSSadaf Ebrahimi         VkBindImageMemoryInfo bind_info[3];
7223*b7893ccfSSadaf Ebrahimi         for (int plane = 0; plane < 3; plane++) {
7224*b7893ccfSSadaf Ebrahimi             bind_info[plane].sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO;
7225*b7893ccfSSadaf Ebrahimi             bind_info[plane].pNext = nullptr;
7226*b7893ccfSSadaf Ebrahimi             bind_info[plane].image = image;
7227*b7893ccfSSadaf Ebrahimi             bind_info[plane].memoryOffset = 0;
7228*b7893ccfSSadaf Ebrahimi         }
7229*b7893ccfSSadaf Ebrahimi         bind_info[0].memory = p0_mem;
7230*b7893ccfSSadaf Ebrahimi         bind_info[1].memory = p1_mem;
7231*b7893ccfSSadaf Ebrahimi         bind_info[2].memory = p2_mem;
7232*b7893ccfSSadaf Ebrahimi 
7233*b7893ccfSSadaf Ebrahimi         m_errorMonitor->ExpectSuccess();
7234*b7893ccfSSadaf Ebrahimi         vkBindImageMemory2Function(device(), 3, bind_info);
7235*b7893ccfSSadaf Ebrahimi         m_errorMonitor->VerifyNotFound();
7236*b7893ccfSSadaf Ebrahimi 
7237*b7893ccfSSadaf Ebrahimi         vkFreeMemory(device(), p0_mem, NULL);
7238*b7893ccfSSadaf Ebrahimi         vkFreeMemory(device(), p1_mem, NULL);
7239*b7893ccfSSadaf Ebrahimi         vkFreeMemory(device(), p2_mem, NULL);
7240*b7893ccfSSadaf Ebrahimi         vkDestroyImage(device(), image, NULL);
7241*b7893ccfSSadaf Ebrahimi     }
7242*b7893ccfSSadaf Ebrahimi 
7243*b7893ccfSSadaf Ebrahimi     // Test that changing the layout of ASPECT_COLOR also changes the layout of the individual planes
7244*b7893ccfSSadaf Ebrahimi     VkBufferObj buffer;
7245*b7893ccfSSadaf Ebrahimi     VkMemoryPropertyFlags reqs = 0;
7246*b7893ccfSSadaf Ebrahimi     buffer.init_as_src(*m_device, (VkDeviceSize)128 * 128 * 3, reqs);
7247*b7893ccfSSadaf Ebrahimi     VkImageObj mpimage(m_device);
7248*b7893ccfSSadaf Ebrahimi     mpimage.Init(256, 256, 1, VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
7249*b7893ccfSSadaf Ebrahimi                  VK_IMAGE_TILING_OPTIMAL, 0);
7250*b7893ccfSSadaf Ebrahimi     VkBufferImageCopy copy_region = {};
7251*b7893ccfSSadaf Ebrahimi     copy_region.bufferRowLength = 128;
7252*b7893ccfSSadaf Ebrahimi     copy_region.bufferImageHeight = 128;
7253*b7893ccfSSadaf Ebrahimi     copy_region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_PLANE_1_BIT_KHR;
7254*b7893ccfSSadaf Ebrahimi     copy_region.imageSubresource.layerCount = 1;
7255*b7893ccfSSadaf Ebrahimi     copy_region.imageExtent.height = 64;
7256*b7893ccfSSadaf Ebrahimi     copy_region.imageExtent.width = 64;
7257*b7893ccfSSadaf Ebrahimi     copy_region.imageExtent.depth = 1;
7258*b7893ccfSSadaf Ebrahimi 
7259*b7893ccfSSadaf Ebrahimi     vkResetCommandBuffer(m_commandBuffer->handle(), 0);
7260*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
7261*b7893ccfSSadaf Ebrahimi     mpimage.ImageMemoryBarrier(m_commandBuffer, VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
7262*b7893ccfSSadaf Ebrahimi     vkCmdCopyBufferToImage(m_commandBuffer->handle(), buffer.handle(), mpimage.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
7263*b7893ccfSSadaf Ebrahimi                            &copy_region);
7264*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
7265*b7893ccfSSadaf Ebrahimi     m_commandBuffer->QueueCommandBuffer(false);
7266*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
7267*b7893ccfSSadaf Ebrahimi 
7268*b7893ccfSSadaf Ebrahimi     // Test to verify that views of multiplanar images have layouts tracked correctly
7269*b7893ccfSSadaf Ebrahimi     // by changing the image's layout then using a view of that image
7270*b7893ccfSSadaf Ebrahimi     VkImageView view;
7271*b7893ccfSSadaf Ebrahimi     VkImageViewCreateInfo ivci = {};
7272*b7893ccfSSadaf Ebrahimi     ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
7273*b7893ccfSSadaf Ebrahimi     ivci.image = mpimage.handle();
7274*b7893ccfSSadaf Ebrahimi     ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
7275*b7893ccfSSadaf Ebrahimi     ivci.format = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR;
7276*b7893ccfSSadaf Ebrahimi     ivci.subresourceRange.layerCount = 1;
7277*b7893ccfSSadaf Ebrahimi     ivci.subresourceRange.baseMipLevel = 0;
7278*b7893ccfSSadaf Ebrahimi     ivci.subresourceRange.levelCount = 1;
7279*b7893ccfSSadaf Ebrahimi     ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7280*b7893ccfSSadaf Ebrahimi     vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
7281*b7893ccfSSadaf Ebrahimi 
7282*b7893ccfSSadaf Ebrahimi     OneOffDescriptorSet descriptor_set(m_device,
7283*b7893ccfSSadaf Ebrahimi                                        {
7284*b7893ccfSSadaf Ebrahimi                                            {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr},
7285*b7893ccfSSadaf Ebrahimi                                        });
7286*b7893ccfSSadaf Ebrahimi 
7287*b7893ccfSSadaf Ebrahimi     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
7288*b7893ccfSSadaf Ebrahimi     VkSampler sampler;
7289*b7893ccfSSadaf Ebrahimi 
7290*b7893ccfSSadaf Ebrahimi     VkResult err;
7291*b7893ccfSSadaf Ebrahimi     err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
7292*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
7293*b7893ccfSSadaf Ebrahimi 
7294*b7893ccfSSadaf Ebrahimi     const VkPipelineLayoutObj pipeline_layout(m_device, {&descriptor_set.layout_});
7295*b7893ccfSSadaf Ebrahimi     descriptor_set.WriteDescriptorImageInfo(0, view, sampler);
7296*b7893ccfSSadaf Ebrahimi     descriptor_set.UpdateDescriptorSets();
7297*b7893ccfSSadaf Ebrahimi 
7298*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
7299*b7893ccfSSadaf Ebrahimi     VkShaderObj fs(m_device, bindStateFragSamplerShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
7300*b7893ccfSSadaf Ebrahimi     VkPipelineObj pipe(m_device);
7301*b7893ccfSSadaf Ebrahimi     pipe.AddShader(&vs);
7302*b7893ccfSSadaf Ebrahimi     pipe.AddShader(&fs);
7303*b7893ccfSSadaf Ebrahimi     pipe.AddDefaultColorAttachment();
7304*b7893ccfSSadaf Ebrahimi     pipe.CreateVKPipeline(pipeline_layout.handle(), renderPass());
7305*b7893ccfSSadaf Ebrahimi 
7306*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
7307*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
7308*b7893ccfSSadaf Ebrahimi     VkImageMemoryBarrier img_barrier = {};
7309*b7893ccfSSadaf Ebrahimi     img_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
7310*b7893ccfSSadaf Ebrahimi     img_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
7311*b7893ccfSSadaf Ebrahimi     img_barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
7312*b7893ccfSSadaf Ebrahimi     img_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7313*b7893ccfSSadaf Ebrahimi     img_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
7314*b7893ccfSSadaf Ebrahimi     img_barrier.image = mpimage.handle();
7315*b7893ccfSSadaf Ebrahimi     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
7316*b7893ccfSSadaf Ebrahimi     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
7317*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7318*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.baseArrayLayer = 0;
7319*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.baseMipLevel = 0;
7320*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.layerCount = 1;
7321*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.levelCount = 1;
7322*b7893ccfSSadaf Ebrahimi     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7323*b7893ccfSSadaf Ebrahimi                          VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1, &img_barrier);
7324*b7893ccfSSadaf Ebrahimi     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
7325*b7893ccfSSadaf Ebrahimi     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
7326*b7893ccfSSadaf Ebrahimi     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout.handle(), 0, 1,
7327*b7893ccfSSadaf Ebrahimi                             &descriptor_set.set_, 0, nullptr);
7328*b7893ccfSSadaf Ebrahimi 
7329*b7893ccfSSadaf Ebrahimi     VkViewport viewport = {0, 0, 16, 16, 0, 1};
7330*b7893ccfSSadaf Ebrahimi     VkRect2D scissor = {{0, 0}, {16, 16}};
7331*b7893ccfSSadaf Ebrahimi     vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
7332*b7893ccfSSadaf Ebrahimi     vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
7333*b7893ccfSSadaf Ebrahimi 
7334*b7893ccfSSadaf Ebrahimi     m_commandBuffer->Draw(1, 0, 0, 0);
7335*b7893ccfSSadaf Ebrahimi     m_commandBuffer->EndRenderPass();
7336*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
7337*b7893ccfSSadaf Ebrahimi     VkSubmitInfo submit_info = {};
7338*b7893ccfSSadaf Ebrahimi     submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
7339*b7893ccfSSadaf Ebrahimi     submit_info.commandBufferCount = 1;
7340*b7893ccfSSadaf Ebrahimi     submit_info.pCommandBuffers = &m_commandBuffer->handle();
7341*b7893ccfSSadaf Ebrahimi     vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
7342*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
7343*b7893ccfSSadaf Ebrahimi 
7344*b7893ccfSSadaf Ebrahimi     vkQueueWaitIdle(m_device->m_queue);
7345*b7893ccfSSadaf Ebrahimi     vkDestroyImageView(m_device->device(), view, NULL);
7346*b7893ccfSSadaf Ebrahimi     vkDestroySampler(m_device->device(), sampler, nullptr);
7347*b7893ccfSSadaf Ebrahimi }
7348*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,ApiVersionZero)7349*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, ApiVersionZero) {
7350*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Check that apiVersion = 0 is valid.");
7351*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
7352*b7893ccfSSadaf Ebrahimi     app_info.apiVersion = 0U;
7353*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
7354*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
7355*b7893ccfSSadaf Ebrahimi }
7356*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,RayTracingPipelineNV)7357*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, RayTracingPipelineNV) {
7358*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Test VK_NV_ray_tracing.");
7359*b7893ccfSSadaf Ebrahimi 
7360*b7893ccfSSadaf Ebrahimi     if (!CreateNVRayTracingPipelineHelper::InitInstanceExtensions(*this, m_instance_extension_names)) {
7361*b7893ccfSSadaf Ebrahimi         return;
7362*b7893ccfSSadaf Ebrahimi     }
7363*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
7364*b7893ccfSSadaf Ebrahimi 
7365*b7893ccfSSadaf Ebrahimi     PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR =
7366*b7893ccfSSadaf Ebrahimi         (PFN_vkGetPhysicalDeviceFeatures2KHR)vkGetInstanceProcAddr(instance(), "vkGetPhysicalDeviceFeatures2KHR");
7367*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(vkGetPhysicalDeviceFeatures2KHR != nullptr);
7368*b7893ccfSSadaf Ebrahimi 
7369*b7893ccfSSadaf Ebrahimi     if (!CreateNVRayTracingPipelineHelper::InitDeviceExtensions(*this, m_device_extension_names)) {
7370*b7893ccfSSadaf Ebrahimi         return;
7371*b7893ccfSSadaf Ebrahimi     }
7372*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
7373*b7893ccfSSadaf Ebrahimi 
7374*b7893ccfSSadaf Ebrahimi     auto ignore_update = [](CreateNVRayTracingPipelineHelper &helper) {};
7375*b7893ccfSSadaf Ebrahimi     CreateNVRayTracingPipelineHelper::OneshotPositiveTest(*this, ignore_update);
7376*b7893ccfSSadaf Ebrahimi }
7377*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,ViewportArray2NV)7378*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, ViewportArray2NV) {
7379*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Test to validate VK_NV_viewport_array2");
7380*b7893ccfSSadaf Ebrahimi 
7381*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
7382*b7893ccfSSadaf Ebrahimi 
7383*b7893ccfSSadaf Ebrahimi     VkPhysicalDeviceFeatures available_features = {};
7384*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&available_features));
7385*b7893ccfSSadaf Ebrahimi 
7386*b7893ccfSSadaf Ebrahimi     if (!available_features.multiViewport) {
7387*b7893ccfSSadaf Ebrahimi         printf("%s VkPhysicalDeviceFeatures::multiViewport is not supported, skipping tests\n", kSkipPrefix);
7388*b7893ccfSSadaf Ebrahimi         return;
7389*b7893ccfSSadaf Ebrahimi     }
7390*b7893ccfSSadaf Ebrahimi     if (!available_features.tessellationShader) {
7391*b7893ccfSSadaf Ebrahimi         printf("%s VkPhysicalDeviceFeatures::tessellationShader is not supported, skipping tests\n", kSkipPrefix);
7392*b7893ccfSSadaf Ebrahimi         return;
7393*b7893ccfSSadaf Ebrahimi     }
7394*b7893ccfSSadaf Ebrahimi     if (!available_features.geometryShader) {
7395*b7893ccfSSadaf Ebrahimi         printf("%s VkPhysicalDeviceFeatures::geometryShader is not supported, skipping tests\n", kSkipPrefix);
7396*b7893ccfSSadaf Ebrahimi         return;
7397*b7893ccfSSadaf Ebrahimi     }
7398*b7893ccfSSadaf Ebrahimi 
7399*b7893ccfSSadaf Ebrahimi     if (DeviceExtensionSupported(gpu(), nullptr, VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME)) {
7400*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME);
7401*b7893ccfSSadaf Ebrahimi     } else {
7402*b7893ccfSSadaf Ebrahimi         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME);
7403*b7893ccfSSadaf Ebrahimi         return;
7404*b7893ccfSSadaf Ebrahimi     }
7405*b7893ccfSSadaf Ebrahimi 
7406*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
7407*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7408*b7893ccfSSadaf Ebrahimi 
7409*b7893ccfSSadaf Ebrahimi     const char tcs_src[] = R"(
7410*b7893ccfSSadaf Ebrahimi         #version 450
7411*b7893ccfSSadaf Ebrahimi         layout(vertices = 3) out;
7412*b7893ccfSSadaf Ebrahimi 
7413*b7893ccfSSadaf Ebrahimi         void main() {
7414*b7893ccfSSadaf Ebrahimi             gl_TessLevelOuter[0] = 4.0f;
7415*b7893ccfSSadaf Ebrahimi             gl_TessLevelOuter[1] = 4.0f;
7416*b7893ccfSSadaf Ebrahimi             gl_TessLevelOuter[2] = 4.0f;
7417*b7893ccfSSadaf Ebrahimi             gl_TessLevelInner[0] = 3.0f;
7418*b7893ccfSSadaf Ebrahimi 
7419*b7893ccfSSadaf Ebrahimi             gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
7420*b7893ccfSSadaf Ebrahimi         })";
7421*b7893ccfSSadaf Ebrahimi 
7422*b7893ccfSSadaf Ebrahimi     // Create tessellation control and fragment shader here since they will not be
7423*b7893ccfSSadaf Ebrahimi     // modified by the different test cases.
7424*b7893ccfSSadaf Ebrahimi     VkShaderObj tcs(m_device, tcs_src, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
7425*b7893ccfSSadaf Ebrahimi     VkShaderObj fs(m_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
7426*b7893ccfSSadaf Ebrahimi 
7427*b7893ccfSSadaf Ebrahimi     std::vector<VkViewport> vps = {{0.0f, 0.0f, m_width / 2.0f, m_height}, {m_width / 2.0f, 0.0f, m_width / 2.0f, m_height}};
7428*b7893ccfSSadaf Ebrahimi     std::vector<VkRect2D> scs = {
7429*b7893ccfSSadaf Ebrahimi         {{0, 0}, {static_cast<uint32_t>(m_width) / 2, static_cast<uint32_t>(m_height)}},
7430*b7893ccfSSadaf Ebrahimi         {{static_cast<int32_t>(m_width) / 2, 0}, {static_cast<uint32_t>(m_width) / 2, static_cast<uint32_t>(m_height)}}};
7431*b7893ccfSSadaf Ebrahimi 
7432*b7893ccfSSadaf Ebrahimi     enum class TestStage { VERTEX = 0, TESSELLATION_EVAL = 1, GEOMETRY = 2 };
7433*b7893ccfSSadaf Ebrahimi     std::array<TestStage, 3> vertex_stages = {{TestStage::VERTEX, TestStage::TESSELLATION_EVAL, TestStage::GEOMETRY}};
7434*b7893ccfSSadaf Ebrahimi 
7435*b7893ccfSSadaf Ebrahimi     // Verify that the usage of gl_ViewportMask[] in the allowed vertex processing
7436*b7893ccfSSadaf Ebrahimi     // stages does not cause any errors.
7437*b7893ccfSSadaf Ebrahimi     for (auto stage : vertex_stages) {
7438*b7893ccfSSadaf Ebrahimi         m_errorMonitor->ExpectSuccess();
7439*b7893ccfSSadaf Ebrahimi 
7440*b7893ccfSSadaf Ebrahimi         VkPipelineInputAssemblyStateCreateInfo iaci = {VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO};
7441*b7893ccfSSadaf Ebrahimi         iaci.topology = (stage != TestStage::VERTEX) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
7442*b7893ccfSSadaf Ebrahimi 
7443*b7893ccfSSadaf Ebrahimi         VkPipelineTessellationStateCreateInfo tsci = {VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO};
7444*b7893ccfSSadaf Ebrahimi         tsci.patchControlPoints = 3;
7445*b7893ccfSSadaf Ebrahimi 
7446*b7893ccfSSadaf Ebrahimi         const VkPipelineLayoutObj pl(m_device);
7447*b7893ccfSSadaf Ebrahimi 
7448*b7893ccfSSadaf Ebrahimi         VkPipelineObj pipe(m_device);
7449*b7893ccfSSadaf Ebrahimi         pipe.AddDefaultColorAttachment();
7450*b7893ccfSSadaf Ebrahimi         pipe.SetInputAssembly(&iaci);
7451*b7893ccfSSadaf Ebrahimi         pipe.SetViewport(vps);
7452*b7893ccfSSadaf Ebrahimi         pipe.SetScissor(scs);
7453*b7893ccfSSadaf Ebrahimi         pipe.AddShader(&fs);
7454*b7893ccfSSadaf Ebrahimi 
7455*b7893ccfSSadaf Ebrahimi         std::stringstream vs_src, tes_src, geom_src;
7456*b7893ccfSSadaf Ebrahimi 
7457*b7893ccfSSadaf Ebrahimi         vs_src << R"(
7458*b7893ccfSSadaf Ebrahimi             #version 450
7459*b7893ccfSSadaf Ebrahimi             #extension GL_NV_viewport_array2 : require
7460*b7893ccfSSadaf Ebrahimi 
7461*b7893ccfSSadaf Ebrahimi             vec2 positions[3] = { vec2( 0.0f, -0.5f),
7462*b7893ccfSSadaf Ebrahimi                                   vec2( 0.5f,  0.5f),
7463*b7893ccfSSadaf Ebrahimi                                   vec2(-0.5f,  0.5f)
7464*b7893ccfSSadaf Ebrahimi                                 };
7465*b7893ccfSSadaf Ebrahimi             void main() {)";
7466*b7893ccfSSadaf Ebrahimi         // Write viewportMask if the vertex shader is the last vertex processing stage.
7467*b7893ccfSSadaf Ebrahimi         if (stage == TestStage::VERTEX) {
7468*b7893ccfSSadaf Ebrahimi             vs_src << "gl_ViewportMask[0] = 3;\n";
7469*b7893ccfSSadaf Ebrahimi         }
7470*b7893ccfSSadaf Ebrahimi         vs_src << R"(
7471*b7893ccfSSadaf Ebrahimi                 gl_Position = vec4(positions[gl_VertexIndex % 3], 0.0, 1.0);
7472*b7893ccfSSadaf Ebrahimi             })";
7473*b7893ccfSSadaf Ebrahimi 
7474*b7893ccfSSadaf Ebrahimi         VkShaderObj vs(m_device, vs_src.str().c_str(), VK_SHADER_STAGE_VERTEX_BIT, this);
7475*b7893ccfSSadaf Ebrahimi         pipe.AddShader(&vs);
7476*b7893ccfSSadaf Ebrahimi 
7477*b7893ccfSSadaf Ebrahimi         std::unique_ptr<VkShaderObj> tes, geom;
7478*b7893ccfSSadaf Ebrahimi 
7479*b7893ccfSSadaf Ebrahimi         if (stage >= TestStage::TESSELLATION_EVAL) {
7480*b7893ccfSSadaf Ebrahimi             tes_src << R"(
7481*b7893ccfSSadaf Ebrahimi                 #version 450
7482*b7893ccfSSadaf Ebrahimi                 #extension GL_NV_viewport_array2 : require
7483*b7893ccfSSadaf Ebrahimi                 layout(triangles) in;
7484*b7893ccfSSadaf Ebrahimi 
7485*b7893ccfSSadaf Ebrahimi                 void main() {
7486*b7893ccfSSadaf Ebrahimi                    gl_Position = (gl_in[0].gl_Position * gl_TessCoord.x +
7487*b7893ccfSSadaf Ebrahimi                                   gl_in[1].gl_Position * gl_TessCoord.y +
7488*b7893ccfSSadaf Ebrahimi                                   gl_in[2].gl_Position * gl_TessCoord.z);)";
7489*b7893ccfSSadaf Ebrahimi             // Write viewportMask if the tess eval shader is the last vertex processing stage.
7490*b7893ccfSSadaf Ebrahimi             if (stage == TestStage::TESSELLATION_EVAL) {
7491*b7893ccfSSadaf Ebrahimi                 tes_src << "gl_ViewportMask[0] = 3;\n";
7492*b7893ccfSSadaf Ebrahimi             }
7493*b7893ccfSSadaf Ebrahimi             tes_src << "}";
7494*b7893ccfSSadaf Ebrahimi 
7495*b7893ccfSSadaf Ebrahimi             tes = std::unique_ptr<VkShaderObj>(
7496*b7893ccfSSadaf Ebrahimi                 new VkShaderObj(m_device, tes_src.str().c_str(), VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this));
7497*b7893ccfSSadaf Ebrahimi             pipe.AddShader(tes.get());
7498*b7893ccfSSadaf Ebrahimi             pipe.AddShader(&tcs);
7499*b7893ccfSSadaf Ebrahimi             pipe.SetTessellation(&tsci);
7500*b7893ccfSSadaf Ebrahimi         }
7501*b7893ccfSSadaf Ebrahimi 
7502*b7893ccfSSadaf Ebrahimi         if (stage >= TestStage::GEOMETRY) {
7503*b7893ccfSSadaf Ebrahimi             geom_src << R"(
7504*b7893ccfSSadaf Ebrahimi                 #version 450
7505*b7893ccfSSadaf Ebrahimi                 #extension GL_NV_viewport_array2 : require
7506*b7893ccfSSadaf Ebrahimi                 layout(triangles)   in;
7507*b7893ccfSSadaf Ebrahimi                 layout(triangle_strip, max_vertices = 3) out;
7508*b7893ccfSSadaf Ebrahimi 
7509*b7893ccfSSadaf Ebrahimi                 void main() {
7510*b7893ccfSSadaf Ebrahimi                    gl_ViewportMask[0] = 3;
7511*b7893ccfSSadaf Ebrahimi                    for(int i = 0; i < 3; ++i) {
7512*b7893ccfSSadaf Ebrahimi                        gl_Position = gl_in[i].gl_Position;
7513*b7893ccfSSadaf Ebrahimi                        EmitVertex();
7514*b7893ccfSSadaf Ebrahimi                     }
7515*b7893ccfSSadaf Ebrahimi                 })";
7516*b7893ccfSSadaf Ebrahimi 
7517*b7893ccfSSadaf Ebrahimi             geom =
7518*b7893ccfSSadaf Ebrahimi                 std::unique_ptr<VkShaderObj>(new VkShaderObj(m_device, geom_src.str().c_str(), VK_SHADER_STAGE_GEOMETRY_BIT, this));
7519*b7893ccfSSadaf Ebrahimi             pipe.AddShader(geom.get());
7520*b7893ccfSSadaf Ebrahimi         }
7521*b7893ccfSSadaf Ebrahimi 
7522*b7893ccfSSadaf Ebrahimi         pipe.CreateVKPipeline(pl.handle(), renderPass());
7523*b7893ccfSSadaf Ebrahimi         m_errorMonitor->VerifyNotFound();
7524*b7893ccfSSadaf Ebrahimi     }
7525*b7893ccfSSadaf Ebrahimi }
7526*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,HostQueryResetSuccess)7527*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, HostQueryResetSuccess) {
7528*b7893ccfSSadaf Ebrahimi     // This is a positive test. No failures are expected.
7529*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Use vkResetQueryPoolEXT normally");
7530*b7893ccfSSadaf Ebrahimi 
7531*b7893ccfSSadaf Ebrahimi     if (!InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) {
7532*b7893ccfSSadaf Ebrahimi         printf("%s Did not find required instance extension %s; skipped.\n", kSkipPrefix,
7533*b7893ccfSSadaf Ebrahimi                VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7534*b7893ccfSSadaf Ebrahimi         return;
7535*b7893ccfSSadaf Ebrahimi     }
7536*b7893ccfSSadaf Ebrahimi 
7537*b7893ccfSSadaf Ebrahimi     m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7538*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
7539*b7893ccfSSadaf Ebrahimi 
7540*b7893ccfSSadaf Ebrahimi     if (!DeviceExtensionSupported(gpu(), nullptr, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME)) {
7541*b7893ccfSSadaf Ebrahimi         printf("%s Extension %s not supported by device; skipped.\n", kSkipPrefix, VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
7542*b7893ccfSSadaf Ebrahimi         return;
7543*b7893ccfSSadaf Ebrahimi     }
7544*b7893ccfSSadaf Ebrahimi 
7545*b7893ccfSSadaf Ebrahimi     m_device_extension_names.push_back(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
7546*b7893ccfSSadaf Ebrahimi 
7547*b7893ccfSSadaf Ebrahimi     VkPhysicalDeviceHostQueryResetFeaturesEXT host_query_reset_features{};
7548*b7893ccfSSadaf Ebrahimi     host_query_reset_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT;
7549*b7893ccfSSadaf Ebrahimi     host_query_reset_features.hostQueryReset = VK_TRUE;
7550*b7893ccfSSadaf Ebrahimi 
7551*b7893ccfSSadaf Ebrahimi     VkPhysicalDeviceFeatures2 pd_features2{};
7552*b7893ccfSSadaf Ebrahimi     pd_features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
7553*b7893ccfSSadaf Ebrahimi     pd_features2.pNext = &host_query_reset_features;
7554*b7893ccfSSadaf Ebrahimi 
7555*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &pd_features2));
7556*b7893ccfSSadaf Ebrahimi 
7557*b7893ccfSSadaf Ebrahimi     auto fpvkResetQueryPoolEXT = (PFN_vkResetQueryPoolEXT)vkGetDeviceProcAddr(m_device->device(), "vkResetQueryPoolEXT");
7558*b7893ccfSSadaf Ebrahimi 
7559*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
7560*b7893ccfSSadaf Ebrahimi 
7561*b7893ccfSSadaf Ebrahimi     VkQueryPool query_pool;
7562*b7893ccfSSadaf Ebrahimi     VkQueryPoolCreateInfo query_pool_create_info{};
7563*b7893ccfSSadaf Ebrahimi     query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
7564*b7893ccfSSadaf Ebrahimi     query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
7565*b7893ccfSSadaf Ebrahimi     query_pool_create_info.queryCount = 1;
7566*b7893ccfSSadaf Ebrahimi     vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
7567*b7893ccfSSadaf Ebrahimi     fpvkResetQueryPoolEXT(m_device->device(), query_pool, 0, 1);
7568*b7893ccfSSadaf Ebrahimi     vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
7569*b7893ccfSSadaf Ebrahimi 
7570*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
7571*b7893ccfSSadaf Ebrahimi }
7572*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CreatePipelineFragmentOutputNotConsumedButAlphaToCoverageEnabled)7573*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CreatePipelineFragmentOutputNotConsumedButAlphaToCoverageEnabled) {
7574*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION(
7575*b7893ccfSSadaf Ebrahimi         "Test that no warning is produced when writing to non-existing color attachment if alpha to coverage is enabled.");
7576*b7893ccfSSadaf Ebrahimi 
7577*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
7578*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget(0u));
7579*b7893ccfSSadaf Ebrahimi 
7580*b7893ccfSSadaf Ebrahimi     VkPipelineMultisampleStateCreateInfo ms_state_ci = {};
7581*b7893ccfSSadaf Ebrahimi     ms_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
7582*b7893ccfSSadaf Ebrahimi     ms_state_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
7583*b7893ccfSSadaf Ebrahimi     ms_state_ci.alphaToCoverageEnable = VK_TRUE;
7584*b7893ccfSSadaf Ebrahimi 
7585*b7893ccfSSadaf Ebrahimi     const auto set_info = [&](CreatePipelineHelper &helper) {
7586*b7893ccfSSadaf Ebrahimi         helper.pipe_ms_state_ci_ = ms_state_ci;
7587*b7893ccfSSadaf Ebrahimi         helper.cb_ci_.attachmentCount = 0;
7588*b7893ccfSSadaf Ebrahimi     };
7589*b7893ccfSSadaf Ebrahimi     CreatePipelineHelper::OneshotTest(*this, set_info, VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT, "", true);
7590*b7893ccfSSadaf Ebrahimi }
7591*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,UseFirstQueueUnqueried)7592*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, UseFirstQueueUnqueried) {
7593*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Use first queue family and one queue without first querying with vkGetPhysicalDeviceQueueFamilyProperties");
7594*b7893ccfSSadaf Ebrahimi 
7595*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
7596*b7893ccfSSadaf Ebrahimi 
7597*b7893ccfSSadaf Ebrahimi     const float q_priority[] = {1.0f};
7598*b7893ccfSSadaf Ebrahimi     VkDeviceQueueCreateInfo queue_ci = {};
7599*b7893ccfSSadaf Ebrahimi     queue_ci.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
7600*b7893ccfSSadaf Ebrahimi     queue_ci.queueFamilyIndex = 0;
7601*b7893ccfSSadaf Ebrahimi     queue_ci.queueCount = 1;
7602*b7893ccfSSadaf Ebrahimi     queue_ci.pQueuePriorities = q_priority;
7603*b7893ccfSSadaf Ebrahimi 
7604*b7893ccfSSadaf Ebrahimi     VkDeviceCreateInfo device_ci = {};
7605*b7893ccfSSadaf Ebrahimi     device_ci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
7606*b7893ccfSSadaf Ebrahimi     device_ci.queueCreateInfoCount = 1;
7607*b7893ccfSSadaf Ebrahimi     device_ci.pQueueCreateInfos = &queue_ci;
7608*b7893ccfSSadaf Ebrahimi 
7609*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
7610*b7893ccfSSadaf Ebrahimi     VkDevice test_device;
7611*b7893ccfSSadaf Ebrahimi     vkCreateDevice(gpu(), &device_ci, nullptr, &test_device);
7612*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
7613*b7893ccfSSadaf Ebrahimi 
7614*b7893ccfSSadaf Ebrahimi     vkDestroyDevice(test_device, nullptr);
7615*b7893ccfSSadaf Ebrahimi }
7616*b7893ccfSSadaf Ebrahimi 
7617*b7893ccfSSadaf Ebrahimi // Android loader returns an error in this case
7618*b7893ccfSSadaf Ebrahimi #if !defined(ANDROID)
TEST_F(VkPositiveLayerTest,GetDevProcAddrNullPtr)7619*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, GetDevProcAddrNullPtr) {
7620*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Call GetDeviceProcAddr on an enabled instance extension expecting nullptr");
7621*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
7622*b7893ccfSSadaf Ebrahimi 
7623*b7893ccfSSadaf Ebrahimi     if (InstanceExtensionSupported(VK_KHR_SURFACE_EXTENSION_NAME)) {
7624*b7893ccfSSadaf Ebrahimi         m_instance_extension_names.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
7625*b7893ccfSSadaf Ebrahimi     } else {
7626*b7893ccfSSadaf Ebrahimi         printf("%s %s not supported, skipping test\n", kSkipPrefix, VK_KHR_SURFACE_EXTENSION_NAME);
7627*b7893ccfSSadaf Ebrahimi         return;
7628*b7893ccfSSadaf Ebrahimi     }
7629*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
7630*b7893ccfSSadaf Ebrahimi 
7631*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
7632*b7893ccfSSadaf Ebrahimi     auto fpDestroySurface = (PFN_vkCreateValidationCacheEXT)vkGetDeviceProcAddr(m_device->device(), "vkDestroySurfaceKHR");
7633*b7893ccfSSadaf Ebrahimi     if (fpDestroySurface) {
7634*b7893ccfSSadaf Ebrahimi         m_errorMonitor->SetError("Null was expected!");
7635*b7893ccfSSadaf Ebrahimi     }
7636*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
7637*b7893ccfSSadaf Ebrahimi }
7638*b7893ccfSSadaf Ebrahimi #endif
7639*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,CmdCopySwapchainImage)7640*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, CmdCopySwapchainImage) {
7641*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Run vkCmdCopyImage with a swapchain image");
7642*b7893ccfSSadaf Ebrahimi 
7643*b7893ccfSSadaf Ebrahimi #if defined(VK_USE_PLATFORM_ANDROID_KHR)
7644*b7893ccfSSadaf Ebrahimi     printf(
7645*b7893ccfSSadaf Ebrahimi         "%s According to VUID-01631, VkBindImageMemoryInfo-memory should be NULL. But Android will crash if memory is NULL, "
7646*b7893ccfSSadaf Ebrahimi         "skipping CmdCopySwapchainImage test\n",
7647*b7893ccfSSadaf Ebrahimi         kSkipPrefix);
7648*b7893ccfSSadaf Ebrahimi     return;
7649*b7893ccfSSadaf Ebrahimi #endif
7650*b7893ccfSSadaf Ebrahimi 
7651*b7893ccfSSadaf Ebrahimi     SetTargetApiVersion(VK_API_VERSION_1_1);
7652*b7893ccfSSadaf Ebrahimi 
7653*b7893ccfSSadaf Ebrahimi     if (!AddSurfaceInstanceExtension()) {
7654*b7893ccfSSadaf Ebrahimi         printf("%s surface extensions not supported, skipping CmdCopySwapchainImage test\n", kSkipPrefix);
7655*b7893ccfSSadaf Ebrahimi         return;
7656*b7893ccfSSadaf Ebrahimi     }
7657*b7893ccfSSadaf Ebrahimi 
7658*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
7659*b7893ccfSSadaf Ebrahimi 
7660*b7893ccfSSadaf Ebrahimi     if (!AddSwapchainDeviceExtension()) {
7661*b7893ccfSSadaf Ebrahimi         printf("%s swapchain extensions not supported, skipping CmdCopySwapchainImage test\n", kSkipPrefix);
7662*b7893ccfSSadaf Ebrahimi         return;
7663*b7893ccfSSadaf Ebrahimi     }
7664*b7893ccfSSadaf Ebrahimi 
7665*b7893ccfSSadaf Ebrahimi     if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
7666*b7893ccfSSadaf Ebrahimi         printf("%s VkBindImageMemoryInfo requires Vulkan 1.1+, skipping test\n", kSkipPrefix);
7667*b7893ccfSSadaf Ebrahimi         return;
7668*b7893ccfSSadaf Ebrahimi     }
7669*b7893ccfSSadaf Ebrahimi 
7670*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
7671*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7672*b7893ccfSSadaf Ebrahimi     if (!InitSwapchain()) {
7673*b7893ccfSSadaf Ebrahimi         printf("%s Cannot create surface or swapchain, skipping CmdCopySwapchainImage test\n", kSkipPrefix);
7674*b7893ccfSSadaf Ebrahimi         return;
7675*b7893ccfSSadaf Ebrahimi     }
7676*b7893ccfSSadaf Ebrahimi 
7677*b7893ccfSSadaf Ebrahimi     auto image_create_info = lvl_init_struct<VkImageCreateInfo>();
7678*b7893ccfSSadaf Ebrahimi     image_create_info.imageType = VK_IMAGE_TYPE_2D;
7679*b7893ccfSSadaf Ebrahimi     image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
7680*b7893ccfSSadaf Ebrahimi     image_create_info.extent.width = 64;
7681*b7893ccfSSadaf Ebrahimi     image_create_info.extent.height = 64;
7682*b7893ccfSSadaf Ebrahimi     image_create_info.extent.depth = 1;
7683*b7893ccfSSadaf Ebrahimi     image_create_info.mipLevels = 1;
7684*b7893ccfSSadaf Ebrahimi     image_create_info.arrayLayers = 1;
7685*b7893ccfSSadaf Ebrahimi     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
7686*b7893ccfSSadaf Ebrahimi     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
7687*b7893ccfSSadaf Ebrahimi     image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
7688*b7893ccfSSadaf Ebrahimi     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
7689*b7893ccfSSadaf Ebrahimi     image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
7690*b7893ccfSSadaf Ebrahimi 
7691*b7893ccfSSadaf Ebrahimi     VkImageObj srcImage(m_device);
7692*b7893ccfSSadaf Ebrahimi     srcImage.init(&image_create_info);
7693*b7893ccfSSadaf Ebrahimi 
7694*b7893ccfSSadaf Ebrahimi     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
7695*b7893ccfSSadaf Ebrahimi 
7696*b7893ccfSSadaf Ebrahimi     auto image_swapchain_create_info = lvl_init_struct<VkImageSwapchainCreateInfoKHR>();
7697*b7893ccfSSadaf Ebrahimi     image_swapchain_create_info.swapchain = m_swapchain;
7698*b7893ccfSSadaf Ebrahimi     image_create_info.pNext = &image_swapchain_create_info;
7699*b7893ccfSSadaf Ebrahimi 
7700*b7893ccfSSadaf Ebrahimi     VkImage image_from_swapchain;
7701*b7893ccfSSadaf Ebrahimi     vkCreateImage(device(), &image_create_info, NULL, &image_from_swapchain);
7702*b7893ccfSSadaf Ebrahimi 
7703*b7893ccfSSadaf Ebrahimi     auto bind_swapchain_info = lvl_init_struct<VkBindImageMemorySwapchainInfoKHR>();
7704*b7893ccfSSadaf Ebrahimi     bind_swapchain_info.swapchain = m_swapchain;
7705*b7893ccfSSadaf Ebrahimi     bind_swapchain_info.imageIndex = 0;
7706*b7893ccfSSadaf Ebrahimi 
7707*b7893ccfSSadaf Ebrahimi     auto bind_info = lvl_init_struct<VkBindImageMemoryInfo>(&bind_swapchain_info);
7708*b7893ccfSSadaf Ebrahimi     bind_info.image = image_from_swapchain;
7709*b7893ccfSSadaf Ebrahimi     bind_info.memory = VK_NULL_HANDLE;
7710*b7893ccfSSadaf Ebrahimi     bind_info.memoryOffset = 0;
7711*b7893ccfSSadaf Ebrahimi 
7712*b7893ccfSSadaf Ebrahimi     vkBindImageMemory2(m_device->device(), 1, &bind_info);
7713*b7893ccfSSadaf Ebrahimi 
7714*b7893ccfSSadaf Ebrahimi     VkImageCopy copy_region = {};
7715*b7893ccfSSadaf Ebrahimi     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7716*b7893ccfSSadaf Ebrahimi     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7717*b7893ccfSSadaf Ebrahimi     copy_region.srcSubresource.mipLevel = 0;
7718*b7893ccfSSadaf Ebrahimi     copy_region.dstSubresource.mipLevel = 0;
7719*b7893ccfSSadaf Ebrahimi     copy_region.srcSubresource.baseArrayLayer = 0;
7720*b7893ccfSSadaf Ebrahimi     copy_region.dstSubresource.baseArrayLayer = 0;
7721*b7893ccfSSadaf Ebrahimi     copy_region.srcSubresource.layerCount = 1;
7722*b7893ccfSSadaf Ebrahimi     copy_region.dstSubresource.layerCount = 1;
7723*b7893ccfSSadaf Ebrahimi     copy_region.srcOffset = {0, 0, 0};
7724*b7893ccfSSadaf Ebrahimi     copy_region.dstOffset = {0, 0, 0};
7725*b7893ccfSSadaf Ebrahimi     copy_region.extent = {10, 10, 1};
7726*b7893ccfSSadaf Ebrahimi 
7727*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
7728*b7893ccfSSadaf Ebrahimi 
7729*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
7730*b7893ccfSSadaf Ebrahimi     vkCmdCopyImage(m_commandBuffer->handle(), srcImage.handle(), VK_IMAGE_LAYOUT_GENERAL, image_from_swapchain,
7731*b7893ccfSSadaf Ebrahimi                    VK_IMAGE_LAYOUT_GENERAL, 1, &copy_region);
7732*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
7733*b7893ccfSSadaf Ebrahimi 
7734*b7893ccfSSadaf Ebrahimi     vkDestroyImage(m_device->device(), image_from_swapchain, NULL);
7735*b7893ccfSSadaf Ebrahimi     DestroySwapchain();
7736*b7893ccfSSadaf Ebrahimi }
7737*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,TransferImageToSwapchainDeviceGroup)7738*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, TransferImageToSwapchainDeviceGroup) {
7739*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Transfer an image to a swapchain's image  between device group");
7740*b7893ccfSSadaf Ebrahimi 
7741*b7893ccfSSadaf Ebrahimi #if defined(VK_USE_PLATFORM_ANDROID_KHR)
7742*b7893ccfSSadaf Ebrahimi     printf(
7743*b7893ccfSSadaf Ebrahimi         "%s According to VUID-01631, VkBindImageMemoryInfo-memory should be NULL. But Android will crash if memory is NULL, "
7744*b7893ccfSSadaf Ebrahimi         "skipping test\n",
7745*b7893ccfSSadaf Ebrahimi         kSkipPrefix);
7746*b7893ccfSSadaf Ebrahimi     return;
7747*b7893ccfSSadaf Ebrahimi #endif
7748*b7893ccfSSadaf Ebrahimi 
7749*b7893ccfSSadaf Ebrahimi     SetTargetApiVersion(VK_API_VERSION_1_1);
7750*b7893ccfSSadaf Ebrahimi 
7751*b7893ccfSSadaf Ebrahimi     if (!AddSurfaceInstanceExtension()) {
7752*b7893ccfSSadaf Ebrahimi         printf("%s surface extensions not supported, skipping test\n", kSkipPrefix);
7753*b7893ccfSSadaf Ebrahimi         return;
7754*b7893ccfSSadaf Ebrahimi     }
7755*b7893ccfSSadaf Ebrahimi 
7756*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
7757*b7893ccfSSadaf Ebrahimi 
7758*b7893ccfSSadaf Ebrahimi     if (!AddSwapchainDeviceExtension()) {
7759*b7893ccfSSadaf Ebrahimi         printf("%s swapchain extensions not supported, skipping test\n", kSkipPrefix);
7760*b7893ccfSSadaf Ebrahimi         return;
7761*b7893ccfSSadaf Ebrahimi     }
7762*b7893ccfSSadaf Ebrahimi 
7763*b7893ccfSSadaf Ebrahimi     if (DeviceValidationVersion() < VK_API_VERSION_1_1) {
7764*b7893ccfSSadaf Ebrahimi         printf("%s VkBindImageMemoryInfo requires Vulkan 1.1+, skipping test\n", kSkipPrefix);
7765*b7893ccfSSadaf Ebrahimi         return;
7766*b7893ccfSSadaf Ebrahimi     }
7767*b7893ccfSSadaf Ebrahimi     uint32_t physical_device_group_count = 0;
7768*b7893ccfSSadaf Ebrahimi     vkEnumeratePhysicalDeviceGroups(instance(), &physical_device_group_count, nullptr);
7769*b7893ccfSSadaf Ebrahimi 
7770*b7893ccfSSadaf Ebrahimi     if (physical_device_group_count == 0) {
7771*b7893ccfSSadaf Ebrahimi         printf("%s physical_device_group_count is 0, skipping test\n", kSkipPrefix);
7772*b7893ccfSSadaf Ebrahimi         return;
7773*b7893ccfSSadaf Ebrahimi     }
7774*b7893ccfSSadaf Ebrahimi 
7775*b7893ccfSSadaf Ebrahimi     std::vector<VkPhysicalDeviceGroupProperties> physical_device_group(physical_device_group_count,
7776*b7893ccfSSadaf Ebrahimi                                                                        {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES});
7777*b7893ccfSSadaf Ebrahimi     vkEnumeratePhysicalDeviceGroups(instance(), &physical_device_group_count, physical_device_group.data());
7778*b7893ccfSSadaf Ebrahimi     VkDeviceGroupDeviceCreateInfo create_device_pnext = {};
7779*b7893ccfSSadaf Ebrahimi     create_device_pnext.sType = VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO;
7780*b7893ccfSSadaf Ebrahimi     create_device_pnext.physicalDeviceCount = physical_device_group[0].physicalDeviceCount;
7781*b7893ccfSSadaf Ebrahimi     create_device_pnext.pPhysicalDevices = physical_device_group[0].physicalDevices;
7782*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState(nullptr, &create_device_pnext, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT));
7783*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
7784*b7893ccfSSadaf Ebrahimi     if (!InitSwapchain(VK_IMAGE_USAGE_TRANSFER_DST_BIT)) {
7785*b7893ccfSSadaf Ebrahimi         printf("%s Cannot create surface or swapchain, skipping test\n", kSkipPrefix);
7786*b7893ccfSSadaf Ebrahimi         return;
7787*b7893ccfSSadaf Ebrahimi     }
7788*b7893ccfSSadaf Ebrahimi 
7789*b7893ccfSSadaf Ebrahimi     auto image_create_info = lvl_init_struct<VkImageCreateInfo>();
7790*b7893ccfSSadaf Ebrahimi     image_create_info.imageType = VK_IMAGE_TYPE_2D;
7791*b7893ccfSSadaf Ebrahimi     image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
7792*b7893ccfSSadaf Ebrahimi     image_create_info.extent.width = 64;
7793*b7893ccfSSadaf Ebrahimi     image_create_info.extent.height = 64;
7794*b7893ccfSSadaf Ebrahimi     image_create_info.extent.depth = 1;
7795*b7893ccfSSadaf Ebrahimi     image_create_info.mipLevels = 1;
7796*b7893ccfSSadaf Ebrahimi     image_create_info.arrayLayers = 1;
7797*b7893ccfSSadaf Ebrahimi     image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
7798*b7893ccfSSadaf Ebrahimi     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
7799*b7893ccfSSadaf Ebrahimi     image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
7800*b7893ccfSSadaf Ebrahimi     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
7801*b7893ccfSSadaf Ebrahimi     image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
7802*b7893ccfSSadaf Ebrahimi 
7803*b7893ccfSSadaf Ebrahimi     VkImageObj src_Image(m_device);
7804*b7893ccfSSadaf Ebrahimi     src_Image.init(&image_create_info);
7805*b7893ccfSSadaf Ebrahimi 
7806*b7893ccfSSadaf Ebrahimi     image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
7807*b7893ccfSSadaf Ebrahimi     image_create_info.flags = VK_IMAGE_CREATE_ALIAS_BIT;
7808*b7893ccfSSadaf Ebrahimi 
7809*b7893ccfSSadaf Ebrahimi     auto image_swapchain_create_info = lvl_init_struct<VkImageSwapchainCreateInfoKHR>();
7810*b7893ccfSSadaf Ebrahimi     image_swapchain_create_info.swapchain = m_swapchain;
7811*b7893ccfSSadaf Ebrahimi     image_create_info.pNext = &image_swapchain_create_info;
7812*b7893ccfSSadaf Ebrahimi 
7813*b7893ccfSSadaf Ebrahimi     VkImage peer_image;
7814*b7893ccfSSadaf Ebrahimi     vkCreateImage(device(), &image_create_info, NULL, &peer_image);
7815*b7893ccfSSadaf Ebrahimi 
7816*b7893ccfSSadaf Ebrahimi     auto bind_devicegroup_info = lvl_init_struct<VkBindImageMemoryDeviceGroupInfo>();
7817*b7893ccfSSadaf Ebrahimi     bind_devicegroup_info.deviceIndexCount = 2;
7818*b7893ccfSSadaf Ebrahimi     std::array<uint32_t, 2> deviceIndices = {0, 0};
7819*b7893ccfSSadaf Ebrahimi     bind_devicegroup_info.pDeviceIndices = deviceIndices.data();
7820*b7893ccfSSadaf Ebrahimi     bind_devicegroup_info.splitInstanceBindRegionCount = 0;
7821*b7893ccfSSadaf Ebrahimi     bind_devicegroup_info.pSplitInstanceBindRegions = nullptr;
7822*b7893ccfSSadaf Ebrahimi 
7823*b7893ccfSSadaf Ebrahimi     auto bind_swapchain_info = lvl_init_struct<VkBindImageMemorySwapchainInfoKHR>(&bind_devicegroup_info);
7824*b7893ccfSSadaf Ebrahimi     bind_swapchain_info.swapchain = m_swapchain;
7825*b7893ccfSSadaf Ebrahimi     bind_swapchain_info.imageIndex = 0;
7826*b7893ccfSSadaf Ebrahimi 
7827*b7893ccfSSadaf Ebrahimi     auto bind_info = lvl_init_struct<VkBindImageMemoryInfo>(&bind_swapchain_info);
7828*b7893ccfSSadaf Ebrahimi     bind_info.image = peer_image;
7829*b7893ccfSSadaf Ebrahimi     bind_info.memory = VK_NULL_HANDLE;
7830*b7893ccfSSadaf Ebrahimi     bind_info.memoryOffset = 0;
7831*b7893ccfSSadaf Ebrahimi 
7832*b7893ccfSSadaf Ebrahimi     vkBindImageMemory2(m_device->device(), 1, &bind_info);
7833*b7893ccfSSadaf Ebrahimi 
7834*b7893ccfSSadaf Ebrahimi     uint32_t swapchain_images_count = 0;
7835*b7893ccfSSadaf Ebrahimi     vkGetSwapchainImagesKHR(device(), m_swapchain, &swapchain_images_count, nullptr);
7836*b7893ccfSSadaf Ebrahimi     std::vector<VkImage> swapchain_images;
7837*b7893ccfSSadaf Ebrahimi     swapchain_images.resize(swapchain_images_count);
7838*b7893ccfSSadaf Ebrahimi     vkGetSwapchainImagesKHR(device(), m_swapchain, &swapchain_images_count, swapchain_images.data());
7839*b7893ccfSSadaf Ebrahimi 
7840*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
7841*b7893ccfSSadaf Ebrahimi 
7842*b7893ccfSSadaf Ebrahimi     auto img_barrier = lvl_init_struct<VkImageMemoryBarrier>();
7843*b7893ccfSSadaf Ebrahimi     img_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
7844*b7893ccfSSadaf Ebrahimi     img_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7845*b7893ccfSSadaf Ebrahimi     img_barrier.image = swapchain_images[0];
7846*b7893ccfSSadaf Ebrahimi     img_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
7847*b7893ccfSSadaf Ebrahimi     img_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
7848*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7849*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.baseArrayLayer = 0;
7850*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.baseMipLevel = 0;
7851*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.layerCount = 1;
7852*b7893ccfSSadaf Ebrahimi     img_barrier.subresourceRange.levelCount = 1;
7853*b7893ccfSSadaf Ebrahimi     vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0,
7854*b7893ccfSSadaf Ebrahimi                          nullptr, 0, nullptr, 1, &img_barrier);
7855*b7893ccfSSadaf Ebrahimi 
7856*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
7857*b7893ccfSSadaf Ebrahimi     m_commandBuffer->QueueCommandBuffer();
7858*b7893ccfSSadaf Ebrahimi 
7859*b7893ccfSSadaf Ebrahimi     m_commandBuffer->reset();
7860*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
7861*b7893ccfSSadaf Ebrahimi 
7862*b7893ccfSSadaf Ebrahimi     VkImageCopy copy_region = {};
7863*b7893ccfSSadaf Ebrahimi     copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7864*b7893ccfSSadaf Ebrahimi     copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
7865*b7893ccfSSadaf Ebrahimi     copy_region.srcSubresource.mipLevel = 0;
7866*b7893ccfSSadaf Ebrahimi     copy_region.dstSubresource.mipLevel = 0;
7867*b7893ccfSSadaf Ebrahimi     copy_region.srcSubresource.baseArrayLayer = 0;
7868*b7893ccfSSadaf Ebrahimi     copy_region.dstSubresource.baseArrayLayer = 0;
7869*b7893ccfSSadaf Ebrahimi     copy_region.srcSubresource.layerCount = 1;
7870*b7893ccfSSadaf Ebrahimi     copy_region.dstSubresource.layerCount = 1;
7871*b7893ccfSSadaf Ebrahimi     copy_region.srcOffset = {0, 0, 0};
7872*b7893ccfSSadaf Ebrahimi     copy_region.dstOffset = {0, 0, 0};
7873*b7893ccfSSadaf Ebrahimi     copy_region.extent = {10, 10, 1};
7874*b7893ccfSSadaf Ebrahimi     vkCmdCopyImage(m_commandBuffer->handle(), src_Image.handle(), VK_IMAGE_LAYOUT_GENERAL, peer_image,
7875*b7893ccfSSadaf Ebrahimi                    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copy_region);
7876*b7893ccfSSadaf Ebrahimi 
7877*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
7878*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
7879*b7893ccfSSadaf Ebrahimi     m_commandBuffer->QueueCommandBuffer();
7880*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
7881*b7893ccfSSadaf Ebrahimi 
7882*b7893ccfSSadaf Ebrahimi     vkDestroyImage(m_device->device(), peer_image, NULL);
7883*b7893ccfSSadaf Ebrahimi     DestroySwapchain();
7884*b7893ccfSSadaf Ebrahimi }
7885*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,RenderPassValidStages)7886*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, RenderPassValidStages) {
7887*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Create render pass with valid stages");
7888*b7893ccfSSadaf Ebrahimi 
7889*b7893ccfSSadaf Ebrahimi     bool rp2_supported = InstanceExtensionSupported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7890*b7893ccfSSadaf Ebrahimi     if (rp2_supported) m_instance_extension_names.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
7891*b7893ccfSSadaf Ebrahimi 
7892*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
7893*b7893ccfSSadaf Ebrahimi     if (rp2_supported) rp2_supported = CheckCreateRenderPass2Support(this, m_device_extension_names);
7894*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
7895*b7893ccfSSadaf Ebrahimi 
7896*b7893ccfSSadaf Ebrahimi     VkSubpassDescription sci[2] = {};
7897*b7893ccfSSadaf Ebrahimi     sci[0].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
7898*b7893ccfSSadaf Ebrahimi     sci[1].pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
7899*b7893ccfSSadaf Ebrahimi 
7900*b7893ccfSSadaf Ebrahimi     VkSubpassDependency dependency = {};
7901*b7893ccfSSadaf Ebrahimi     // to be filled later by tests
7902*b7893ccfSSadaf Ebrahimi 
7903*b7893ccfSSadaf Ebrahimi     VkRenderPassCreateInfo rpci = {};
7904*b7893ccfSSadaf Ebrahimi     rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
7905*b7893ccfSSadaf Ebrahimi     rpci.subpassCount = 2;
7906*b7893ccfSSadaf Ebrahimi     rpci.pSubpasses = sci;
7907*b7893ccfSSadaf Ebrahimi     rpci.dependencyCount = 1;
7908*b7893ccfSSadaf Ebrahimi     rpci.pDependencies = &dependency;
7909*b7893ccfSSadaf Ebrahimi 
7910*b7893ccfSSadaf Ebrahimi     const VkPipelineStageFlags kGraphicsStages =
7911*b7893ccfSSadaf Ebrahimi         VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT |
7912*b7893ccfSSadaf Ebrahimi         VK_PIPELINE_STAGE_VERTEX_INPUT_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
7913*b7893ccfSSadaf Ebrahimi         VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
7914*b7893ccfSSadaf Ebrahimi         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
7915*b7893ccfSSadaf Ebrahimi 
7916*b7893ccfSSadaf Ebrahimi     dependency.srcSubpass = 0;
7917*b7893ccfSSadaf Ebrahimi     dependency.dstSubpass = 1;
7918*b7893ccfSSadaf Ebrahimi     dependency.srcStageMask = kGraphicsStages;
7919*b7893ccfSSadaf Ebrahimi     dependency.dstStageMask = kGraphicsStages;
7920*b7893ccfSSadaf Ebrahimi     PositiveTestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2_supported);
7921*b7893ccfSSadaf Ebrahimi 
7922*b7893ccfSSadaf Ebrahimi     dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
7923*b7893ccfSSadaf Ebrahimi     dependency.dstSubpass = 0;
7924*b7893ccfSSadaf Ebrahimi     dependency.srcStageMask = kGraphicsStages | VK_PIPELINE_STAGE_HOST_BIT;
7925*b7893ccfSSadaf Ebrahimi     dependency.dstStageMask = kGraphicsStages;
7926*b7893ccfSSadaf Ebrahimi     PositiveTestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2_supported);
7927*b7893ccfSSadaf Ebrahimi 
7928*b7893ccfSSadaf Ebrahimi     dependency.srcSubpass = 0;
7929*b7893ccfSSadaf Ebrahimi     dependency.dstSubpass = VK_SUBPASS_EXTERNAL;
7930*b7893ccfSSadaf Ebrahimi     dependency.srcStageMask = kGraphicsStages;
7931*b7893ccfSSadaf Ebrahimi     dependency.dstStageMask = VK_PIPELINE_STAGE_HOST_BIT;
7932*b7893ccfSSadaf Ebrahimi     PositiveTestRenderPassCreate(m_errorMonitor, m_device->device(), &rpci, rp2_supported);
7933*b7893ccfSSadaf Ebrahimi }
7934*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,SampleMaskOverrideCoverageNV)7935*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, SampleMaskOverrideCoverageNV) {
7936*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Test to validate VK_NV_sample_mask_override_coverage");
7937*b7893ccfSSadaf Ebrahimi 
7938*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
7939*b7893ccfSSadaf Ebrahimi 
7940*b7893ccfSSadaf Ebrahimi     if (DeviceExtensionSupported(gpu(), nullptr, VK_NV_SAMPLE_MASK_OVERRIDE_COVERAGE_EXTENSION_NAME)) {
7941*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_NV_SAMPLE_MASK_OVERRIDE_COVERAGE_EXTENSION_NAME);
7942*b7893ccfSSadaf Ebrahimi     } else {
7943*b7893ccfSSadaf Ebrahimi         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_NV_SAMPLE_MASK_OVERRIDE_COVERAGE_EXTENSION_NAME);
7944*b7893ccfSSadaf Ebrahimi         return;
7945*b7893ccfSSadaf Ebrahimi     }
7946*b7893ccfSSadaf Ebrahimi 
7947*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
7948*b7893ccfSSadaf Ebrahimi 
7949*b7893ccfSSadaf Ebrahimi     const char vs_src[] = R"(
7950*b7893ccfSSadaf Ebrahimi         #version 450
7951*b7893ccfSSadaf Ebrahimi         layout(location=0) out vec4  fragColor;
7952*b7893ccfSSadaf Ebrahimi 
7953*b7893ccfSSadaf Ebrahimi         const vec2 pos[3] = { vec2( 0.0f, -0.5f),
7954*b7893ccfSSadaf Ebrahimi                               vec2( 0.5f,  0.5f),
7955*b7893ccfSSadaf Ebrahimi                               vec2(-0.5f,  0.5f)
7956*b7893ccfSSadaf Ebrahimi                             };
7957*b7893ccfSSadaf Ebrahimi         void main()
7958*b7893ccfSSadaf Ebrahimi         {
7959*b7893ccfSSadaf Ebrahimi             gl_Position = vec4(pos[gl_VertexIndex % 3], 0.0f, 1.0f);
7960*b7893ccfSSadaf Ebrahimi             fragColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);
7961*b7893ccfSSadaf Ebrahimi         })";
7962*b7893ccfSSadaf Ebrahimi 
7963*b7893ccfSSadaf Ebrahimi     const char fs_src[] = R"(
7964*b7893ccfSSadaf Ebrahimi         #version 450
7965*b7893ccfSSadaf Ebrahimi         #extension GL_NV_sample_mask_override_coverage : require
7966*b7893ccfSSadaf Ebrahimi 
7967*b7893ccfSSadaf Ebrahimi         layout(location = 0) in  vec4 fragColor;
7968*b7893ccfSSadaf Ebrahimi         layout(location = 0) out vec4 outColor;
7969*b7893ccfSSadaf Ebrahimi 
7970*b7893ccfSSadaf Ebrahimi         layout(override_coverage) out int gl_SampleMask[];
7971*b7893ccfSSadaf Ebrahimi 
7972*b7893ccfSSadaf Ebrahimi         void main()
7973*b7893ccfSSadaf Ebrahimi         {
7974*b7893ccfSSadaf Ebrahimi             gl_SampleMask[0] = 0xff;
7975*b7893ccfSSadaf Ebrahimi             outColor = fragColor;
7976*b7893ccfSSadaf Ebrahimi         })";
7977*b7893ccfSSadaf Ebrahimi 
7978*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
7979*b7893ccfSSadaf Ebrahimi 
7980*b7893ccfSSadaf Ebrahimi     const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_8_BIT;
7981*b7893ccfSSadaf Ebrahimi 
7982*b7893ccfSSadaf Ebrahimi     VkAttachmentDescription cAttachment = {};
7983*b7893ccfSSadaf Ebrahimi     cAttachment.format = VK_FORMAT_B8G8R8A8_UNORM;
7984*b7893ccfSSadaf Ebrahimi     cAttachment.samples = sampleCount;
7985*b7893ccfSSadaf Ebrahimi     cAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
7986*b7893ccfSSadaf Ebrahimi     cAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
7987*b7893ccfSSadaf Ebrahimi     cAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
7988*b7893ccfSSadaf Ebrahimi     cAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
7989*b7893ccfSSadaf Ebrahimi     cAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
7990*b7893ccfSSadaf Ebrahimi     cAttachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
7991*b7893ccfSSadaf Ebrahimi 
7992*b7893ccfSSadaf Ebrahimi     VkAttachmentReference cAttachRef = {};
7993*b7893ccfSSadaf Ebrahimi     cAttachRef.attachment = 0;
7994*b7893ccfSSadaf Ebrahimi     cAttachRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
7995*b7893ccfSSadaf Ebrahimi 
7996*b7893ccfSSadaf Ebrahimi     VkSubpassDescription subpass = {};
7997*b7893ccfSSadaf Ebrahimi     subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
7998*b7893ccfSSadaf Ebrahimi     subpass.colorAttachmentCount = 1;
7999*b7893ccfSSadaf Ebrahimi     subpass.pColorAttachments = &cAttachRef;
8000*b7893ccfSSadaf Ebrahimi 
8001*b7893ccfSSadaf Ebrahimi     VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO};
8002*b7893ccfSSadaf Ebrahimi     rpci.attachmentCount = 1;
8003*b7893ccfSSadaf Ebrahimi     rpci.pAttachments = &cAttachment;
8004*b7893ccfSSadaf Ebrahimi     rpci.subpassCount = 1;
8005*b7893ccfSSadaf Ebrahimi     rpci.pSubpasses = &subpass;
8006*b7893ccfSSadaf Ebrahimi 
8007*b7893ccfSSadaf Ebrahimi     VkRenderPass rp;
8008*b7893ccfSSadaf Ebrahimi     vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
8009*b7893ccfSSadaf Ebrahimi 
8010*b7893ccfSSadaf Ebrahimi     const VkPipelineLayoutObj pl(m_device);
8011*b7893ccfSSadaf Ebrahimi 
8012*b7893ccfSSadaf Ebrahimi     VkSampleMask sampleMask = 0x01;
8013*b7893ccfSSadaf Ebrahimi     VkPipelineMultisampleStateCreateInfo msaa = {VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO};
8014*b7893ccfSSadaf Ebrahimi     msaa.rasterizationSamples = sampleCount;
8015*b7893ccfSSadaf Ebrahimi     msaa.sampleShadingEnable = VK_FALSE;
8016*b7893ccfSSadaf Ebrahimi     msaa.pSampleMask = &sampleMask;
8017*b7893ccfSSadaf Ebrahimi 
8018*b7893ccfSSadaf Ebrahimi     VkPipelineObj pipe(m_device);
8019*b7893ccfSSadaf Ebrahimi     pipe.AddDefaultColorAttachment();
8020*b7893ccfSSadaf Ebrahimi     pipe.SetMSAA(&msaa);
8021*b7893ccfSSadaf Ebrahimi 
8022*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, vs_src, VK_SHADER_STAGE_VERTEX_BIT, this);
8023*b7893ccfSSadaf Ebrahimi     pipe.AddShader(&vs);
8024*b7893ccfSSadaf Ebrahimi 
8025*b7893ccfSSadaf Ebrahimi     VkShaderObj fs(m_device, fs_src, VK_SHADER_STAGE_FRAGMENT_BIT, this);
8026*b7893ccfSSadaf Ebrahimi     pipe.AddShader(&fs);
8027*b7893ccfSSadaf Ebrahimi 
8028*b7893ccfSSadaf Ebrahimi     // Create pipeline and make sure that the usage of NV_sample_mask_override_coverage
8029*b7893ccfSSadaf Ebrahimi     // in the fragment shader does not cause any errors.
8030*b7893ccfSSadaf Ebrahimi     pipe.CreateVKPipeline(pl.handle(), rp);
8031*b7893ccfSSadaf Ebrahimi 
8032*b7893ccfSSadaf Ebrahimi     vkDestroyRenderPass(m_device->device(), rp, nullptr);
8033*b7893ccfSSadaf Ebrahimi 
8034*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
8035*b7893ccfSSadaf Ebrahimi }
8036*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,TestRasterizationDiscardEnableTrue)8037*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, TestRasterizationDiscardEnableTrue) {
8038*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Ensure it doesn't crash and trigger error msg when rasterizerDiscardEnable = true");
8039*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
8040*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8041*b7893ccfSSadaf Ebrahimi 
8042*b7893ccfSSadaf Ebrahimi     VkAttachmentDescription att[1] = {{}};
8043*b7893ccfSSadaf Ebrahimi     att[0].format = VK_FORMAT_R8G8B8A8_UNORM;
8044*b7893ccfSSadaf Ebrahimi     att[0].samples = VK_SAMPLE_COUNT_4_BIT;
8045*b7893ccfSSadaf Ebrahimi     att[0].initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
8046*b7893ccfSSadaf Ebrahimi     att[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
8047*b7893ccfSSadaf Ebrahimi     VkAttachmentReference cr = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
8048*b7893ccfSSadaf Ebrahimi     VkSubpassDescription sp = {};
8049*b7893ccfSSadaf Ebrahimi     sp.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
8050*b7893ccfSSadaf Ebrahimi     sp.colorAttachmentCount = 1;
8051*b7893ccfSSadaf Ebrahimi     sp.pColorAttachments = &cr;
8052*b7893ccfSSadaf Ebrahimi     VkRenderPassCreateInfo rpi = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO};
8053*b7893ccfSSadaf Ebrahimi     rpi.attachmentCount = 1;
8054*b7893ccfSSadaf Ebrahimi     rpi.pAttachments = att;
8055*b7893ccfSSadaf Ebrahimi     rpi.subpassCount = 1;
8056*b7893ccfSSadaf Ebrahimi     rpi.pSubpasses = &sp;
8057*b7893ccfSSadaf Ebrahimi     VkRenderPass rp;
8058*b7893ccfSSadaf Ebrahimi     vkCreateRenderPass(m_device->device(), &rpi, nullptr, &rp);
8059*b7893ccfSSadaf Ebrahimi 
8060*b7893ccfSSadaf Ebrahimi     CreatePipelineHelper pipe(*this);
8061*b7893ccfSSadaf Ebrahimi     pipe.InitInfo();
8062*b7893ccfSSadaf Ebrahimi     pipe.gp_ci_.pViewportState = nullptr;
8063*b7893ccfSSadaf Ebrahimi     pipe.gp_ci_.pMultisampleState = nullptr;
8064*b7893ccfSSadaf Ebrahimi     pipe.gp_ci_.pDepthStencilState = nullptr;
8065*b7893ccfSSadaf Ebrahimi     pipe.gp_ci_.pColorBlendState = nullptr;
8066*b7893ccfSSadaf Ebrahimi     pipe.gp_ci_.renderPass = rp;
8067*b7893ccfSSadaf Ebrahimi 
8068*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
8069*b7893ccfSSadaf Ebrahimi     // Skip the test in NexusPlayer. The driver crashes when pViewportState, pMultisampleState, pDepthStencilState, pColorBlendState
8070*b7893ccfSSadaf Ebrahimi     // are NULL.
8071*b7893ccfSSadaf Ebrahimi     pipe.rs_state_ci_.rasterizerDiscardEnable = VK_TRUE;
8072*b7893ccfSSadaf Ebrahimi     pipe.InitState();
8073*b7893ccfSSadaf Ebrahimi     pipe.CreateGraphicsPipeline();
8074*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
8075*b7893ccfSSadaf Ebrahimi     vkDestroyRenderPass(m_device->device(), rp, nullptr);
8076*b7893ccfSSadaf Ebrahimi }
8077*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,TestSamplerDataForCombinedImageSampler)8078*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, TestSamplerDataForCombinedImageSampler) {
8079*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Shader code uses sampler data for CombinedImageSampler");
8080*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
8081*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8082*b7893ccfSSadaf Ebrahimi 
8083*b7893ccfSSadaf Ebrahimi     const std::string fsSource = R"(
8084*b7893ccfSSadaf Ebrahimi                    OpCapability Shader
8085*b7893ccfSSadaf Ebrahimi                    OpMemoryModel Logical GLSL450
8086*b7893ccfSSadaf Ebrahimi                    OpEntryPoint Fragment %main "main"
8087*b7893ccfSSadaf Ebrahimi                    OpExecutionMode %main OriginUpperLeft
8088*b7893ccfSSadaf Ebrahimi 
8089*b7893ccfSSadaf Ebrahimi                    OpDecorate %InputData DescriptorSet 0
8090*b7893ccfSSadaf Ebrahimi                    OpDecorate %InputData Binding 0
8091*b7893ccfSSadaf Ebrahimi                    OpDecorate %SamplerData DescriptorSet 0
8092*b7893ccfSSadaf Ebrahimi                    OpDecorate %SamplerData Binding 0
8093*b7893ccfSSadaf Ebrahimi 
8094*b7893ccfSSadaf Ebrahimi                %void = OpTypeVoid
8095*b7893ccfSSadaf Ebrahimi                 %f32 = OpTypeFloat 32
8096*b7893ccfSSadaf Ebrahimi               %Image = OpTypeImage %f32 2D 0 0 0 1 Rgba32f
8097*b7893ccfSSadaf Ebrahimi            %ImagePtr = OpTypePointer UniformConstant %Image
8098*b7893ccfSSadaf Ebrahimi           %InputData = OpVariable %ImagePtr UniformConstant
8099*b7893ccfSSadaf Ebrahimi             %Sampler = OpTypeSampler
8100*b7893ccfSSadaf Ebrahimi          %SamplerPtr = OpTypePointer UniformConstant %Sampler
8101*b7893ccfSSadaf Ebrahimi         %SamplerData = OpVariable %SamplerPtr UniformConstant
8102*b7893ccfSSadaf Ebrahimi        %SampledImage = OpTypeSampledImage %Image
8103*b7893ccfSSadaf Ebrahimi 
8104*b7893ccfSSadaf Ebrahimi                %func = OpTypeFunction %void
8105*b7893ccfSSadaf Ebrahimi                %main = OpFunction %void None %func
8106*b7893ccfSSadaf Ebrahimi                  %40 = OpLabel
8107*b7893ccfSSadaf Ebrahimi            %call_smp = OpLoad %Sampler %SamplerData
8108*b7893ccfSSadaf Ebrahimi                    OpReturn
8109*b7893ccfSSadaf Ebrahimi                    OpFunctionEnd)";
8110*b7893ccfSSadaf Ebrahimi 
8111*b7893ccfSSadaf Ebrahimi     VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
8112*b7893ccfSSadaf Ebrahimi 
8113*b7893ccfSSadaf Ebrahimi     CreatePipelineHelper pipe(*this);
8114*b7893ccfSSadaf Ebrahimi     pipe.InitInfo();
8115*b7893ccfSSadaf Ebrahimi     pipe.dsl_bindings_ = {
8116*b7893ccfSSadaf Ebrahimi         {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_ALL, nullptr},
8117*b7893ccfSSadaf Ebrahimi     };
8118*b7893ccfSSadaf Ebrahimi     pipe.shader_stages_ = {fs.GetStageCreateInfo(), pipe.vs_->GetStageCreateInfo()};
8119*b7893ccfSSadaf Ebrahimi     pipe.InitState();
8120*b7893ccfSSadaf Ebrahimi     pipe.CreateGraphicsPipeline();
8121*b7893ccfSSadaf Ebrahimi 
8122*b7893ccfSSadaf Ebrahimi     VkImageObj image(m_device);
8123*b7893ccfSSadaf Ebrahimi     image.Init(32, 32, 1, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
8124*b7893ccfSSadaf Ebrahimi     VkImageView view = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
8125*b7893ccfSSadaf Ebrahimi 
8126*b7893ccfSSadaf Ebrahimi     VkSamplerCreateInfo sampler_ci = SafeSaneSamplerCreateInfo();
8127*b7893ccfSSadaf Ebrahimi     VkSampler sampler;
8128*b7893ccfSSadaf Ebrahimi     vkCreateSampler(m_device->device(), &sampler_ci, nullptr, &sampler);
8129*b7893ccfSSadaf Ebrahimi 
8130*b7893ccfSSadaf Ebrahimi     uint32_t qfi = 0;
8131*b7893ccfSSadaf Ebrahimi     VkBufferCreateInfo buffer_create_info = {};
8132*b7893ccfSSadaf Ebrahimi     buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
8133*b7893ccfSSadaf Ebrahimi     buffer_create_info.size = 1024;
8134*b7893ccfSSadaf Ebrahimi     buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
8135*b7893ccfSSadaf Ebrahimi     buffer_create_info.queueFamilyIndexCount = 1;
8136*b7893ccfSSadaf Ebrahimi     buffer_create_info.pQueueFamilyIndices = &qfi;
8137*b7893ccfSSadaf Ebrahimi 
8138*b7893ccfSSadaf Ebrahimi     VkBufferObj buffer;
8139*b7893ccfSSadaf Ebrahimi     buffer.init(*m_device, buffer_create_info);
8140*b7893ccfSSadaf Ebrahimi 
8141*b7893ccfSSadaf Ebrahimi     pipe.descriptor_set_->WriteDescriptorImageInfo(0, view, sampler, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
8142*b7893ccfSSadaf Ebrahimi     pipe.descriptor_set_->UpdateDescriptorSets();
8143*b7893ccfSSadaf Ebrahimi 
8144*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
8145*b7893ccfSSadaf Ebrahimi     m_commandBuffer->BeginRenderPass(m_renderPassBeginInfo);
8146*b7893ccfSSadaf Ebrahimi     vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_);
8147*b7893ccfSSadaf Ebrahimi     vkCmdBindDescriptorSets(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.pipeline_layout_.handle(), 0, 1,
8148*b7893ccfSSadaf Ebrahimi                             &pipe.descriptor_set_->set_, 0, NULL);
8149*b7893ccfSSadaf Ebrahimi 
8150*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
8151*b7893ccfSSadaf Ebrahimi     vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
8152*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
8153*b7893ccfSSadaf Ebrahimi 
8154*b7893ccfSSadaf Ebrahimi     vkCmdEndRenderPass(m_commandBuffer->handle());
8155*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
8156*b7893ccfSSadaf Ebrahimi     vkDestroySampler(m_device->device(), sampler, NULL);
8157*b7893ccfSSadaf Ebrahimi }
8158*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,NotPointSizeGeometryShaderSuccess)8159*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, NotPointSizeGeometryShaderSuccess) {
8160*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Create a pipeline using TOPOLOGY_POINT_LIST, but geometry shader doesn't include PointSize.");
8161*b7893ccfSSadaf Ebrahimi 
8162*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
8163*b7893ccfSSadaf Ebrahimi 
8164*b7893ccfSSadaf Ebrahimi     if ((!m_device->phy().features().geometryShader)) {
8165*b7893ccfSSadaf Ebrahimi         printf("%s Device does not support the required geometry shader features; skipped.\n", kSkipPrefix);
8166*b7893ccfSSadaf Ebrahimi         return;
8167*b7893ccfSSadaf Ebrahimi     }
8168*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8169*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitViewport());
8170*b7893ccfSSadaf Ebrahimi 
8171*b7893ccfSSadaf Ebrahimi     VkShaderObj gs(m_device, bindStateGeomShaderText, VK_SHADER_STAGE_GEOMETRY_BIT, this);
8172*b7893ccfSSadaf Ebrahimi 
8173*b7893ccfSSadaf Ebrahimi     CreatePipelineHelper pipe(*this);
8174*b7893ccfSSadaf Ebrahimi     pipe.InitInfo();
8175*b7893ccfSSadaf Ebrahimi     pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), gs.GetStageCreateInfo(), pipe.fs_->GetStageCreateInfo()};
8176*b7893ccfSSadaf Ebrahimi     pipe.ia_ci_.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
8177*b7893ccfSSadaf Ebrahimi     pipe.InitState();
8178*b7893ccfSSadaf Ebrahimi 
8179*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
8180*b7893ccfSSadaf Ebrahimi     pipe.CreateGraphicsPipeline();
8181*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
8182*b7893ccfSSadaf Ebrahimi }
8183*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,SubpassWithReadOnlyLayoutWithoutDependency)8184*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, SubpassWithReadOnlyLayoutWithoutDependency) {
8185*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("When both subpasses' attachments are the same and layouts are read-only, they don't need dependency.");
8186*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(Init());
8187*b7893ccfSSadaf Ebrahimi 
8188*b7893ccfSSadaf Ebrahimi     auto depth_format = FindSupportedDepthStencilFormat(gpu());
8189*b7893ccfSSadaf Ebrahimi     if (!depth_format) {
8190*b7893ccfSSadaf Ebrahimi         printf("%s No Depth + Stencil format found. Skipped.\n", kSkipPrefix);
8191*b7893ccfSSadaf Ebrahimi         return;
8192*b7893ccfSSadaf Ebrahimi     }
8193*b7893ccfSSadaf Ebrahimi 
8194*b7893ccfSSadaf Ebrahimi     // A renderpass with one color attachment.
8195*b7893ccfSSadaf Ebrahimi     VkAttachmentDescription attachment = {0,
8196*b7893ccfSSadaf Ebrahimi                                           depth_format,
8197*b7893ccfSSadaf Ebrahimi                                           VK_SAMPLE_COUNT_1_BIT,
8198*b7893ccfSSadaf Ebrahimi                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
8199*b7893ccfSSadaf Ebrahimi                                           VK_ATTACHMENT_STORE_OP_STORE,
8200*b7893ccfSSadaf Ebrahimi                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
8201*b7893ccfSSadaf Ebrahimi                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
8202*b7893ccfSSadaf Ebrahimi                                           VK_IMAGE_LAYOUT_UNDEFINED,
8203*b7893ccfSSadaf Ebrahimi                                           VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL};
8204*b7893ccfSSadaf Ebrahimi     const int size = 2;
8205*b7893ccfSSadaf Ebrahimi     std::array<VkAttachmentDescription, size> attachments = {attachment, attachment};
8206*b7893ccfSSadaf Ebrahimi 
8207*b7893ccfSSadaf Ebrahimi     VkAttachmentReference att_ref_depth_stencil = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL};
8208*b7893ccfSSadaf Ebrahimi 
8209*b7893ccfSSadaf Ebrahimi     std::array<VkSubpassDescription, size> subpasses;
8210*b7893ccfSSadaf Ebrahimi     subpasses[0] = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 0, 0, nullptr, nullptr, &att_ref_depth_stencil, 0, nullptr};
8211*b7893ccfSSadaf Ebrahimi     subpasses[1] = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 0, 0, nullptr, nullptr, &att_ref_depth_stencil, 0, nullptr};
8212*b7893ccfSSadaf Ebrahimi 
8213*b7893ccfSSadaf Ebrahimi     VkRenderPassCreateInfo rpci = {
8214*b7893ccfSSadaf Ebrahimi         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, size, attachments.data(), size, subpasses.data(), 0, nullptr};
8215*b7893ccfSSadaf Ebrahimi 
8216*b7893ccfSSadaf Ebrahimi     VkRenderPass rp;
8217*b7893ccfSSadaf Ebrahimi     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
8218*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
8219*b7893ccfSSadaf Ebrahimi 
8220*b7893ccfSSadaf Ebrahimi     // A compatible framebuffer.
8221*b7893ccfSSadaf Ebrahimi     VkImageObj image(m_device);
8222*b7893ccfSSadaf Ebrahimi     image.Init(32, 32, 1, depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_TILING_LINEAR, 0);
8223*b7893ccfSSadaf Ebrahimi     ASSERT_TRUE(image.initialized());
8224*b7893ccfSSadaf Ebrahimi 
8225*b7893ccfSSadaf Ebrahimi     VkImageViewCreateInfo ivci = {VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
8226*b7893ccfSSadaf Ebrahimi                                   nullptr,
8227*b7893ccfSSadaf Ebrahimi                                   0,
8228*b7893ccfSSadaf Ebrahimi                                   image.handle(),
8229*b7893ccfSSadaf Ebrahimi                                   VK_IMAGE_VIEW_TYPE_2D,
8230*b7893ccfSSadaf Ebrahimi                                   depth_format,
8231*b7893ccfSSadaf Ebrahimi                                   {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
8232*b7893ccfSSadaf Ebrahimi                                    VK_COMPONENT_SWIZZLE_IDENTITY},
8233*b7893ccfSSadaf Ebrahimi                                   {VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0, 1, 0, 1}};
8234*b7893ccfSSadaf Ebrahimi 
8235*b7893ccfSSadaf Ebrahimi     VkImageView view;
8236*b7893ccfSSadaf Ebrahimi     err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
8237*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
8238*b7893ccfSSadaf Ebrahimi     std::array<VkImageView, size> views = {view, view};
8239*b7893ccfSSadaf Ebrahimi 
8240*b7893ccfSSadaf Ebrahimi     VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, size, views.data(), 32, 32, 1};
8241*b7893ccfSSadaf Ebrahimi     VkFramebuffer fb;
8242*b7893ccfSSadaf Ebrahimi     err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
8243*b7893ccfSSadaf Ebrahimi     ASSERT_VK_SUCCESS(err);
8244*b7893ccfSSadaf Ebrahimi 
8245*b7893ccfSSadaf Ebrahimi     VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
8246*b7893ccfSSadaf Ebrahimi     m_commandBuffer->begin();
8247*b7893ccfSSadaf Ebrahimi     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
8248*b7893ccfSSadaf Ebrahimi     vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
8249*b7893ccfSSadaf Ebrahimi     vkCmdEndRenderPass(m_commandBuffer->handle());
8250*b7893ccfSSadaf Ebrahimi     m_commandBuffer->end();
8251*b7893ccfSSadaf Ebrahimi 
8252*b7893ccfSSadaf Ebrahimi     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
8253*b7893ccfSSadaf Ebrahimi     vkDestroyRenderPass(m_device->device(), rp, nullptr);
8254*b7893ccfSSadaf Ebrahimi     vkDestroyImageView(m_device->device(), view, nullptr);
8255*b7893ccfSSadaf Ebrahimi }
8256*b7893ccfSSadaf Ebrahimi 
TEST_F(VkPositiveLayerTest,GeometryShaderPassthroughNV)8257*b7893ccfSSadaf Ebrahimi TEST_F(VkPositiveLayerTest, GeometryShaderPassthroughNV) {
8258*b7893ccfSSadaf Ebrahimi     TEST_DESCRIPTION("Test to validate VK_NV_geometry_shader_passthrough");
8259*b7893ccfSSadaf Ebrahimi 
8260*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitFramework(myDbgFunc, m_errorMonitor));
8261*b7893ccfSSadaf Ebrahimi 
8262*b7893ccfSSadaf Ebrahimi     VkPhysicalDeviceFeatures available_features = {};
8263*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(GetPhysicalDeviceFeatures(&available_features));
8264*b7893ccfSSadaf Ebrahimi 
8265*b7893ccfSSadaf Ebrahimi     if (!available_features.geometryShader) {
8266*b7893ccfSSadaf Ebrahimi         printf("%s VkPhysicalDeviceFeatures::geometryShader is not supported, skipping test\n", kSkipPrefix);
8267*b7893ccfSSadaf Ebrahimi         return;
8268*b7893ccfSSadaf Ebrahimi     }
8269*b7893ccfSSadaf Ebrahimi 
8270*b7893ccfSSadaf Ebrahimi     if (DeviceExtensionSupported(gpu(), nullptr, VK_NV_GEOMETRY_SHADER_PASSTHROUGH_EXTENSION_NAME)) {
8271*b7893ccfSSadaf Ebrahimi         m_device_extension_names.push_back(VK_NV_GEOMETRY_SHADER_PASSTHROUGH_EXTENSION_NAME);
8272*b7893ccfSSadaf Ebrahimi     } else {
8273*b7893ccfSSadaf Ebrahimi         printf("%s %s Extension not supported, skipping tests\n", kSkipPrefix, VK_NV_GEOMETRY_SHADER_PASSTHROUGH_EXTENSION_NAME);
8274*b7893ccfSSadaf Ebrahimi         return;
8275*b7893ccfSSadaf Ebrahimi     }
8276*b7893ccfSSadaf Ebrahimi 
8277*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitState());
8278*b7893ccfSSadaf Ebrahimi     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
8279*b7893ccfSSadaf Ebrahimi 
8280*b7893ccfSSadaf Ebrahimi     const char vs_src[] = R"(
8281*b7893ccfSSadaf Ebrahimi         #version 450
8282*b7893ccfSSadaf Ebrahimi 
8283*b7893ccfSSadaf Ebrahimi         out gl_PerVertex {
8284*b7893ccfSSadaf Ebrahimi             vec4 gl_Position;
8285*b7893ccfSSadaf Ebrahimi         };
8286*b7893ccfSSadaf Ebrahimi 
8287*b7893ccfSSadaf Ebrahimi         layout(location = 0) out ColorBlock {vec4 vertexColor;};
8288*b7893ccfSSadaf Ebrahimi 
8289*b7893ccfSSadaf Ebrahimi         const vec2 positions[3] = { vec2( 0.0f, -0.5f),
8290*b7893ccfSSadaf Ebrahimi                                     vec2( 0.5f,  0.5f),
8291*b7893ccfSSadaf Ebrahimi                                     vec2(-0.5f,  0.5f)
8292*b7893ccfSSadaf Ebrahimi                                   };
8293*b7893ccfSSadaf Ebrahimi 
8294*b7893ccfSSadaf Ebrahimi         const vec4 colors[3] = { vec4(1.0f, 0.0f, 0.0f, 1.0f),
8295*b7893ccfSSadaf Ebrahimi                                  vec4(0.0f, 1.0f, 0.0f, 1.0f),
8296*b7893ccfSSadaf Ebrahimi                                  vec4(0.0f, 0.0f, 1.0f, 1.0f)
8297*b7893ccfSSadaf Ebrahimi                                };
8298*b7893ccfSSadaf Ebrahimi         void main()
8299*b7893ccfSSadaf Ebrahimi         {
8300*b7893ccfSSadaf Ebrahimi             vertexColor = colors[gl_VertexIndex % 3];
8301*b7893ccfSSadaf Ebrahimi             gl_Position = vec4(positions[gl_VertexIndex % 3], 0.0, 1.0);
8302*b7893ccfSSadaf Ebrahimi         })";
8303*b7893ccfSSadaf Ebrahimi 
8304*b7893ccfSSadaf Ebrahimi     const char gs_src[] = R"(
8305*b7893ccfSSadaf Ebrahimi         #version 450
8306*b7893ccfSSadaf Ebrahimi         #extension GL_NV_geometry_shader_passthrough: require
8307*b7893ccfSSadaf Ebrahimi 
8308*b7893ccfSSadaf Ebrahimi         layout(triangles) in;
8309*b7893ccfSSadaf Ebrahimi         layout(triangle_strip, max_vertices = 3) out;
8310*b7893ccfSSadaf Ebrahimi 
8311*b7893ccfSSadaf Ebrahimi         layout(passthrough) in gl_PerVertex {vec4 gl_Position;};
8312*b7893ccfSSadaf Ebrahimi         layout(location = 0, passthrough) in ColorBlock {vec4 vertexColor;};
8313*b7893ccfSSadaf Ebrahimi 
8314*b7893ccfSSadaf Ebrahimi         void main()
8315*b7893ccfSSadaf Ebrahimi         {
8316*b7893ccfSSadaf Ebrahimi            gl_Layer = 0;
8317*b7893ccfSSadaf Ebrahimi         })";
8318*b7893ccfSSadaf Ebrahimi 
8319*b7893ccfSSadaf Ebrahimi     const char fs_src[] = R"(
8320*b7893ccfSSadaf Ebrahimi         #version 450
8321*b7893ccfSSadaf Ebrahimi 
8322*b7893ccfSSadaf Ebrahimi         layout(location = 0) in ColorBlock {vec4 vertexColor;};
8323*b7893ccfSSadaf Ebrahimi         layout(location = 0) out vec4 outColor;
8324*b7893ccfSSadaf Ebrahimi 
8325*b7893ccfSSadaf Ebrahimi         void main() {
8326*b7893ccfSSadaf Ebrahimi             outColor = vertexColor;
8327*b7893ccfSSadaf Ebrahimi         })";
8328*b7893ccfSSadaf Ebrahimi 
8329*b7893ccfSSadaf Ebrahimi     m_errorMonitor->ExpectSuccess();
8330*b7893ccfSSadaf Ebrahimi 
8331*b7893ccfSSadaf Ebrahimi     const VkPipelineLayoutObj pl(m_device);
8332*b7893ccfSSadaf Ebrahimi 
8333*b7893ccfSSadaf Ebrahimi     VkPipelineObj pipe(m_device);
8334*b7893ccfSSadaf Ebrahimi     pipe.AddDefaultColorAttachment();
8335*b7893ccfSSadaf Ebrahimi 
8336*b7893ccfSSadaf Ebrahimi     VkShaderObj vs(m_device, vs_src, VK_SHADER_STAGE_VERTEX_BIT, this);
8337*b7893ccfSSadaf Ebrahimi     pipe.AddShader(&vs);
8338*b7893ccfSSadaf Ebrahimi 
8339*b7893ccfSSadaf Ebrahimi     VkShaderObj gs(m_device, gs_src, VK_SHADER_STAGE_GEOMETRY_BIT, this);
8340*b7893ccfSSadaf Ebrahimi     pipe.AddShader(&gs);
8341*b7893ccfSSadaf Ebrahimi 
8342*b7893ccfSSadaf Ebrahimi     VkShaderObj fs(m_device, fs_src, VK_SHADER_STAGE_FRAGMENT_BIT, this);
8343*b7893ccfSSadaf Ebrahimi     pipe.AddShader(&fs);
8344*b7893ccfSSadaf Ebrahimi 
8345*b7893ccfSSadaf Ebrahimi     // Create pipeline and make sure that the usage of NV_geometry_shader_passthrough
8346*b7893ccfSSadaf Ebrahimi     // in the fragment shader does not cause any errors.
8347*b7893ccfSSadaf Ebrahimi     pipe.CreateVKPipeline(pl.handle(), renderPass());
8348*b7893ccfSSadaf Ebrahimi 
8349*b7893ccfSSadaf Ebrahimi     m_errorMonitor->VerifyNotFound();
8350*b7893ccfSSadaf Ebrahimi }
8351