xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/api/vktApiPipelineTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2018 The Khronos Group Inc.
6  * Copyright (c) 2018 Google Inc.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Pipeline tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktApiPipelineTests.hpp"
26 #include "vktTestCaseUtil.hpp"
27 
28 #include "deUniquePtr.hpp"
29 #include "vkMemUtil.hpp"
30 #include "vkRefUtil.hpp"
31 #include "vkPrograms.hpp"
32 #include "vkQueryUtil.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkCmdUtil.hpp"
35 #include "vkObjUtil.hpp"
36 #include "vkBarrierUtil.hpp"
37 #include "vkBufferWithMemory.hpp"
38 #include "vkBuilderUtil.hpp"
39 #include "vkImageUtil.hpp"
40 #include "tcuTestLog.hpp"
41 
42 #include <vector>
43 #include <sstream>
44 
45 namespace vkt
46 {
47 namespace api
48 {
49 
50 namespace
51 {
52 
53 using namespace std;
54 using namespace vk;
55 
getRenderTargetFormat(const InstanceInterface & vk,const VkPhysicalDevice & device)56 VkFormat getRenderTargetFormat(const InstanceInterface &vk, const VkPhysicalDevice &device)
57 {
58     const VkFormatFeatureFlags featureFlags = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
59     VkFormatProperties formatProperties;
60 
61     vk.getPhysicalDeviceFormatProperties(device, VK_FORMAT_B8G8R8A8_UNORM, &formatProperties);
62 
63     if ((formatProperties.linearTilingFeatures & featureFlags) ||
64         (formatProperties.optimalTilingFeatures & featureFlags))
65         return VK_FORMAT_B8G8R8A8_UNORM;
66 
67     vk.getPhysicalDeviceFormatProperties(device, VK_FORMAT_R8G8B8A8_UNORM, &formatProperties);
68 
69     if ((formatProperties.linearTilingFeatures & featureFlags) ||
70         formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)
71         return VK_FORMAT_R8G8B8A8_UNORM;
72 
73     TCU_THROW(NotSupportedError, "Device does not support VK_FORMAT_B8G8R8A8_UNORM nor VK_FORMAT_R8G8B8A8_UNORM");
74 
75     return VK_FORMAT_UNDEFINED;
76 }
77 
createCommandBuffer(const DeviceInterface & vkd,VkDevice device,VkCommandPool commandPool)78 Move<VkCommandBuffer> createCommandBuffer(const DeviceInterface &vkd, VkDevice device, VkCommandPool commandPool)
79 {
80     const VkCommandBufferAllocateInfo allocateInfo = {
81         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType         sType;
82         DE_NULL,                                        // const void*             pNext;
83         commandPool,                                    // VkCommandPool           commandPool;
84         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                // VkCommandBufferLevel    level;
85         1u                                              // uint32_t                commandBufferCount;
86     };
87 
88     return allocateCommandBuffer(vkd, device, &allocateInfo);
89 }
90 
91 enum DrawTriangleMode
92 {
93     DTM_DESTROY_RENDER_PASS_AFTER_CREATING_PIPELINE = 0,
94     DTM_DESTROY_PIPELINE_LAYOUT_AFTER_CREATING_PIPELINE,
95 };
96 
drawTriangleTest(Context & context,DrawTriangleMode mode)97 tcu::TestStatus drawTriangleTest(Context &context, DrawTriangleMode mode)
98 {
99     const DeviceInterface &vk             = context.getDeviceInterface();
100     const InstanceInterface &vki          = context.getInstanceInterface();
101     const VkDevice device                 = context.getDevice();
102     const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
103 
104     const VkFormat format = getRenderTargetFormat(vki, physicalDevice);
105     const VkFormatProperties formatProperties(getPhysicalDeviceFormatProperties(vki, physicalDevice, format));
106     const VkImageTiling imageTiling =
107         (formatProperties.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)  ? VK_IMAGE_TILING_LINEAR :
108         (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? VK_IMAGE_TILING_OPTIMAL :
109                                                                                             VK_CORE_IMAGE_TILING_LAST;
110 
111     const VkImageCreateInfo attachmentImageCreateInfo = {
112         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType          sType;
113         DE_NULL,                             // const void*              pNext;
114         (VkImageCreateFlags)0u,              // VkImageCreateFlags       flags;
115         VK_IMAGE_TYPE_2D,                    // VkImageType              imageType;
116         format,                              // VkFormat                 format;
117         {
118             256u,                                                              // uint32_t    width;
119             256u,                                                              // uint32_t    height;
120             1u                                                                 // uint32_t    depth;
121         },                                                                     // VkExtent3D               extent;
122         1u,                                                                    // uint32_t                 mipLevels;
123         1u,                                                                    // uint32_t                 arrayLayers;
124         VK_SAMPLE_COUNT_1_BIT,                                                 // VkSampleCountFlagBits    samples;
125         imageTiling,                                                           // VkImageTiling            tiling;
126         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags        usage;
127         VK_SHARING_MODE_EXCLUSIVE,                                             // VkSharingMode            sharingMode;
128         0u,                       // uint32_t                 queueFamilyIndexCount;
129         DE_NULL,                  // const uint32_t*          pQueueFamilyIndices;
130         VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout            initialLayout;
131     };
132 
133     const Unique<VkImage> attachmentImage(createImage(vk, device, &attachmentImageCreateInfo));
134     de::MovePtr<Allocation> attachmentImageMemory = context.getDefaultAllocator().allocate(
135         getImageMemoryRequirements(vk, device, *attachmentImage), MemoryRequirement::Any);
136 
137     VK_CHECK(vk.bindImageMemory(device, *attachmentImage, attachmentImageMemory->getMemory(),
138                                 attachmentImageMemory->getOffset()));
139 
140     const tcu::TextureFormat resultFormat = mapVkFormat(format);
141     const VkDeviceSize imageSizeBytes     = (VkDeviceSize)(resultFormat.getPixelSize() * 256 * 256);
142     const VkBufferCreateInfo readImageBufferParams{
143         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
144         DE_NULL,                              // const void* pNext;
145         0u,                                   // VkBufferCreateFlags flags;
146         imageSizeBytes,                       // VkDeviceSize size;
147         VK_BUFFER_USAGE_TRANSFER_DST_BIT,     // VkBufferUsageFlags usage;
148         VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode sharingMode;
149         0u,                                   // uint32_t queueFamilyCount;
150         DE_NULL,                              // const uint32_t* pQueueFamilyIndices;
151     };
152     const Unique<VkBuffer> readImageBuffer(createBuffer(vk, device, &readImageBufferParams));
153     const de::UniquePtr<Allocation> readImageBufferMemory(context.getDefaultAllocator().allocate(
154         getBufferMemoryRequirements(vk, device, *readImageBuffer), MemoryRequirement::HostVisible));
155 
156     VK_CHECK(vk.bindBufferMemory(device, *readImageBuffer, readImageBufferMemory->getMemory(),
157                                  readImageBufferMemory->getOffset()));
158 
159     const uint32_t queueFamilyIndex = context.getUniversalQueueFamilyIndex();
160 
161     const VkCommandPoolCreateInfo commandPoolParams = {
162         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType             sType;
163         DE_NULL,                                    // const void*                 pNext;
164         (VkCommandPoolCreateFlags)0u,               // VkCommandPoolCreateFlags    flags;
165         queueFamilyIndex                            // uint32_t                    queueFamilyIndex;
166     };
167 
168     const Unique<VkCommandPool> commandPool(createCommandPool(vk, device, &commandPoolParams, DE_NULL));
169     const Unique<VkCommandBuffer> commandBuffer(createCommandBuffer(vk, device, commandPool.get()));
170 
171     const VkCommandBufferBeginInfo commandBufferBeginInfo = {
172         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType                          sType;
173         DE_NULL,                                     // const void*                              pNext;
174         VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags                flags;
175         DE_NULL                                      // const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
176     };
177 
178     VK_CHECK(vk.beginCommandBuffer(commandBuffer.get(), &commandBufferBeginInfo));
179 
180     const VkAttachmentDescription attachmentDescription = {
181         (VkAttachmentDescriptionFlags)0u,        // VkAttachmentDescriptionFlags    flags;
182         format,                                  // VkFormat                        format;
183         VK_SAMPLE_COUNT_1_BIT,                   // VkSampleCountFlagBits           samples;
184         VK_ATTACHMENT_LOAD_OP_CLEAR,             // VkAttachmentLoadOp              loadOp;
185         VK_ATTACHMENT_STORE_OP_STORE,            // VkAttachmentStoreOp             storeOp;
186         VK_ATTACHMENT_LOAD_OP_DONT_CARE,         // VkAttachmentLoadOp              stencilLoadOp;
187         VK_ATTACHMENT_STORE_OP_DONT_CARE,        // VkAttachmentStoreOp             stencilStoreOp;
188         VK_IMAGE_LAYOUT_UNDEFINED,               // VkImageLayout                   initialLayout;
189         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout                   finalLayout;
190     };
191 
192     const VkAttachmentReference attachmentReference = {
193         0u,                                      // uint32_t attachment;
194         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
195     };
196 
197     const VkSubpassDescription subpassDescription = {
198         (VkSubpassDescriptionFlags)0u,   // VkSubpassDescriptionFlags       flags;
199         VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint             pipelineBindPoint
200         0u,                              // uint32_t                        inputAttachmentCount
201         DE_NULL,                         // const VkAttachmentReference*    pInputAttachments
202         1u,                              // uint32_t                        colorAttachmentCount
203         &attachmentReference,            // const VkAttachmentReference*    pColorAttachments
204         DE_NULL,                         // const VkAttachmentReference*    pResolveAttachments
205         DE_NULL,                         // const VkAttachmentReference*    pDepthStencilAttachment
206         0u,                              // uint32_t                        preserveAttachmentCount
207         DE_NULL                          // const uint32_t*                 pPreserveAttachments
208     };
209 
210     const VkRenderPassCreateInfo renderPassCreateInfo = {
211         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType                   sType;
212         DE_NULL,                                   // const void*                       pNext;
213         (VkRenderPassCreateFlags)0u,               // VkRenderPassCreateFlags           flags;
214         1u,                                        // uint32_t                          attachmentCount
215         &attachmentDescription,                    // const VkAttachmentDescription*    pAttachments
216         1u,                                        // uint32_t                          subpassCount
217         &subpassDescription,                       // const VkSubpassDescription*       pSubpasses
218         0u,                                        // uint32_t                          dependencyCount
219         DE_NULL                                    // const VkSubpassDependency*        pDependencies
220     };
221 
222     // When testing renderpass lifetime - create two compatible renderpasses, otherwise use just renderPassB
223     VkRenderPass renderPassA;
224     if (DTM_DESTROY_RENDER_PASS_AFTER_CREATING_PIPELINE == mode)
225         VK_CHECK(vk.createRenderPass(device, &renderPassCreateInfo, DE_NULL, &renderPassA));
226 
227     const Move<VkRenderPass> renderPassB(createRenderPass(vk, device, &renderPassCreateInfo));
228 
229     const VkImageViewCreateInfo attachmentImageViewCreateInfo = {
230         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType            sType;
231         DE_NULL,                                  // const void*                pNext;
232         (VkImageViewCreateFlags)0u,               // VkImageViewCreateFlags     flags;
233         attachmentImage.get(),                    // VkImage                    image;
234         VK_IMAGE_VIEW_TYPE_2D,                    // VkImageViewType            viewType;
235         format,                                   // VkFormat                   format;
236         {
237             VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle    r;
238             VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle    g;
239             VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle    b;
240             VK_COMPONENT_SWIZZLE_A  // VkComponentSwizzle    a;
241         },                          // VkComponentMapping         components;
242         {
243             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags    aspectMask;
244             0u,                        // uint32_t              baseMipLevel;
245             1u,                        // uint32_t              levelCount;
246             0u,                        // uint32_t              baseArrayLayer;
247             1u                         // uint32_t              layerCount;
248         }                              // VkImageSubresourceRange    subresourceRange;
249     };
250 
251     const Unique<VkImageView> attachmentImageView(createImageView(vk, device, &attachmentImageViewCreateInfo));
252 
253     const VkFramebufferCreateInfo framebufferCreateInfo = {
254         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType             sType;
255         DE_NULL,                                   // const void*                 pNext;
256         (VkFramebufferCreateFlags)0u,              // VkFramebufferCreateFlags    flags;
257         renderPassB.get(),                         // VkRenderPass                renderPass;
258         1u,                                        // uint32_t                    attachmentCount;
259         &attachmentImageView.get(),                // const VkImageView*          pAttachments;
260         256u,                                      // uint32_t                    width;
261         256u,                                      // uint32_t                    height;
262         1u                                         // uint32_t                    layers;
263     };
264 
265     const Unique<VkFramebuffer> frameBuffer(createFramebuffer(vk, device, &framebufferCreateInfo));
266 
267     const Unique<VkShaderModule> vertexShaderModule(
268         createShaderModule(vk, device, context.getBinaryCollection().get("vertex"), 0));
269     const Unique<VkShaderModule> fragmentShaderModule(
270         createShaderModule(vk, device, context.getBinaryCollection().get("fragment"), 0));
271 
272     const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
273         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType                     sType;
274         DE_NULL,                                       // const void*                         pNext;
275         (VkPipelineLayoutCreateFlags)0u,               // VkPipelineLayoutCreateFlags         flags;
276         0u,                                            // uint32_t                            setLayoutCount;
277         DE_NULL,                                       // const VkDescriptorSetLayout*        pSetLayouts;
278         0u,                                            // uint32_t                            pushConstantRangeCount;
279         DE_NULL                                        // const VkPushConstantRange*          pPushConstantRanges;
280     };
281 
282     Move<VkPipelineLayout> pipelineLayout(createPipelineLayout(vk, device, &pipelineLayoutCreateInfo));
283 
284     const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = {
285         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType                             sType;
286         DE_NULL,                                                   // const void*                                 pNext;
287         (VkPipelineVertexInputStateCreateFlags)0u,                 // VkPipelineVertexInputStateCreateFlags       flags;
288         0u,      // uint32_t                                    vertexBindingDescriptionCount;
289         DE_NULL, // const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
290         0u,      // uint32_t                                    vertexAttributeDescriptionCount;
291         DE_NULL  // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
292     };
293 
294     const VkViewport viewport = {
295         0.0f,  // float    x;
296         0.0f,  // float    y;
297         64.0f, // float    width;
298         64.0f, // float    height;
299         0.0f,  // float    minDepth;
300         0.0f,  // float    maxDepth;
301     };
302 
303     const std::vector<VkViewport> viewports(1, viewport);
304     const std::vector<VkRect2D> scissors(1, makeRect2D(0, 0, 64u, 64u));
305 
306     const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo = {
307         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType                            sType;
308         DE_NULL,                                                    // const void*                                pNext;
309         (VkPipelineRasterizationStateCreateFlags)0u,                // VkPipelineRasterizationStateCreateFlags    flags;
310         VK_FALSE,                // VkBool32                                   depthClampEnable;
311         VK_FALSE,                // VkBool32                                   rasterizerDiscardEnable;
312         VK_POLYGON_MODE_FILL,    // VkPolygonMode                              polygonMode;
313         VK_CULL_MODE_NONE,       // VkCullModeFlags                            cullMode;
314         VK_FRONT_FACE_CLOCKWISE, // VkFrontFace                                frontFace;
315         VK_FALSE,                // VkBool32                                   depthBiasEnable;
316         0.0f,                    // float                                      depthBiasConstantFactor;
317         0.0f,                    // float                                      depthBiasClamp;
318         0.0f,                    // float                                      depthBiasSlopeFactor;
319         1.0f                     // float                                      lineWidth;
320     };
321 
322     const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = {
323         VK_FALSE,                  // VkBool32                 blendEnable;
324         VK_BLEND_FACTOR_ZERO,      // VkBlendFactor            srcColorBlendFactor;
325         VK_BLEND_FACTOR_ZERO,      // VkBlendFactor            dstColorBlendFactor;
326         VK_BLEND_OP_ADD,           // VkBlendOp                colorBlendOp;
327         VK_BLEND_FACTOR_ZERO,      // VkBlendFactor            srcAlphaBlendFactor;
328         VK_BLEND_FACTOR_ZERO,      // VkBlendFactor            dstAlphaBlendFactor;
329         VK_BLEND_OP_ADD,           // VkBlendOp                alphaBlendOp;
330         (VkColorComponentFlags)0xF // VkColorComponentFlags    colorWriteMask;
331     };
332 
333     const VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo = {
334         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType                               sType;
335         DE_NULL,                                  // const void*                                   pNext;
336         (VkPipelineColorBlendStateCreateFlags)0u, // VkPipelineColorBlendStateCreateFlags          flags;
337         VK_FALSE,                                 // VkBool32                                      logicOpEnable;
338         VK_LOGIC_OP_CLEAR,                        // VkLogicOp                                     logicOp;
339         1u,                                       // uint32_t                                      attachmentCount;
340         &colorBlendAttachmentState,               // const VkPipelineColorBlendAttachmentState*    pAttachments;
341         {1.0f, 1.0f, 1.0f, 1.0f}                  // float                                         blendConstants[4];
342     };
343 
344     VkRenderPass renderPassUsedForPipeline = *renderPassB;
345     if (DTM_DESTROY_RENDER_PASS_AFTER_CREATING_PIPELINE == mode)
346         renderPassUsedForPipeline = renderPassA;
347 
348     const Unique<VkPipeline> graphicsPipeline(makeGraphicsPipeline(
349         vk,                                   // const DeviceInterface&                        vk
350         device,                               // const VkDevice                                device
351         *pipelineLayout,                      // const VkPipelineLayout                        pipelineLayout
352         *vertexShaderModule,                  // const VkShaderModule                          vertexShaderModule
353         DE_NULL,                              // const VkShaderModule                          tessellationControlModule
354         DE_NULL,                              // const VkShaderModule                          tessellationEvalModule
355         DE_NULL,                              // const VkShaderModule                          geometryShaderModule
356         *fragmentShaderModule,                // const VkShaderModule                          fragmentShaderModule
357         renderPassUsedForPipeline,            // const VkRenderPass                            renderPass
358         viewports,                            // const std::vector<VkViewport>&                viewports
359         scissors,                             // const std::vector<VkRect2D>&                  scissors
360         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // const VkPrimitiveTopology                     topology
361         0u,                                   // const uint32_t                                subpass
362         0u,                                   // const uint32_t                                patchControlPoints
363         &vertexInputStateCreateInfo,   // const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
364         &rasterizationStateCreateInfo, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
365         DE_NULL,                       // const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
366         DE_NULL,                       // const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
367         &colorBlendStateCreateInfo));  // const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
368 
369     if (DTM_DESTROY_PIPELINE_LAYOUT_AFTER_CREATING_PIPELINE == mode)
370         pipelineLayout = decltype(pipelineLayout)();
371 
372     beginRenderPass(vk, *commandBuffer, renderPassB.get(), frameBuffer.get(), makeRect2D(0, 0, 256u, 256u),
373                     tcu::Vec4(0.25f, 0.25f, 0.25f, 0.0f));
374 
375     vk.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
376 
377     // Destroy the renderpass that was used to create the graphics pipeline
378     if (DTM_DESTROY_RENDER_PASS_AFTER_CREATING_PIPELINE == mode)
379         vk.destroyRenderPass(device, renderPassA, DE_NULL);
380 
381     vk.cmdDraw(*commandBuffer, 3u, 1u, 0u, 0u);
382 
383     endRenderPass(vk, *commandBuffer);
384 
385     // Copy image to buffer
386     {
387         copyImageToBuffer(vk, *commandBuffer, *attachmentImage, *readImageBuffer, tcu::IVec2(256, 256));
388     }
389 
390     VK_CHECK(vk.endCommandBuffer(*commandBuffer));
391 
392     const VkSubmitInfo submitInfo = {
393         VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType                sType;
394         DE_NULL,                       // const void*                    pNext;
395         0u,                            // uint32_t                       waitSemaphoreCount;
396         DE_NULL,                       // const VkSemaphore*             pWaitSemaphores;
397         DE_NULL,                       // const VkPipelineStageFlags*    pWaitDstStageMask;
398         1u,                            // uint32_t                       commandBufferCount;
399         &commandBuffer.get(),          // const VkCommandBuffer*         pCommandBuffers;
400         0u,                            // uint32_t                       signalSemaphoreCount;
401         DE_NULL                        // const VkSemaphore*             pSignalSemaphores;
402     };
403 
404     vk::VkQueue queue = context.getUniversalQueue();
405 
406     VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, DE_NULL));
407     VK_CHECK(vk.queueWaitIdle(queue));
408     VK_CHECK(vk.deviceWaitIdle(device));
409 
410     invalidateAlloc(vk, device, *readImageBufferMemory);
411     const tcu::ConstPixelBufferAccess resultAccess(resultFormat, 256, 256, 1, readImageBufferMemory->getHostPtr());
412 
413     // check just one pixel
414     tcu::Vec4 pixel = resultAccess.getPixel(1, 1);
415     if ((pixel.x() < 0.9f) || (pixel.y() > 0.1f) || (pixel.z() > 0.1f) || (pixel.w() < 0.9f))
416         return tcu::TestStatus::fail("Fail");
417 
418     tcu::TestLog &log = context.getTestContext().getLog();
419     log << tcu::TestLog::ImageSet("Image verification", "")
420         << tcu::TestLog::Image("Result", "Result", resultAccess, tcu::Vec4(1.0f), tcu::Vec4(0.0f))
421         << tcu::TestLog::EndImageSet;
422 
423     return tcu::TestStatus::pass("Pass");
424 }
425 
renderpassLifetimeTest(Context & context)426 tcu::TestStatus renderpassLifetimeTest(Context &context)
427 {
428     return drawTriangleTest(context, DTM_DESTROY_RENDER_PASS_AFTER_CREATING_PIPELINE);
429 }
430 
createDrawTriangleSource(SourceCollections & dst)431 void createDrawTriangleSource(SourceCollections &dst)
432 {
433     dst.glslSources.add("vertex") << glu::VertexSource(
434         "#version 310 es\n"
435         "void main (void)\n"
436         "{\n"
437         "    gl_Position = vec4(float(1 - 2 * int(gl_VertexIndex != 1)),\n"
438         "                       float(1 - 2 * int(gl_VertexIndex > 0)), 0.0, 1.0);\n"
439         "}\n");
440 
441     dst.glslSources.add("fragment") << glu::FragmentSource("#version 310 es\n"
442                                                            "layout (location = 0) out highp vec4 color;\n"
443                                                            "void main (void)\n"
444                                                            "{\n"
445                                                            "    color = vec4(1.0, 0.0, 0.0, 1.0);\n"
446                                                            "}\n");
447 }
448 
changeColorAttachmentImageLayout(const DeviceInterface & vk,VkCommandBuffer commandBuffer,VkImage image)449 void changeColorAttachmentImageLayout(const DeviceInterface &vk, VkCommandBuffer commandBuffer, VkImage image)
450 {
451     const VkImageMemoryBarrier imageMemoryBarrier = {
452         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,   // VkStructureType            sType;
453         DE_NULL,                                  // const void*                pNext;
454         (VkAccessFlags)0u,                        // VkAccessFlags              srcAccessMask;
455         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,     // VkAccessFlags              dstAccessMask;
456         VK_IMAGE_LAYOUT_UNDEFINED,                // VkImageLayout              oldLayout;
457         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout              newLayout;
458         0u,                                       // uint32_t                   srcQueueFamilyIndex;
459         0u,                                       // uint32_t                   dstQueueFamilyIndex;
460         image,                                    // VkImage                    image;
461         {
462             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags    aspectMask;
463             0u,                        // uint32_t              baseMipLevel;
464             1u,                        // uint32_t              levelCount;
465             0u,                        // uint32_t              baseArrayLayer;(
466             1u                         // uint32_t              layerCount;
467         }                              // VkImageSubresourceRange    subresourceRange;
468     };
469 
470     vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
471                           (VkDependencyFlagBits)0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageMemoryBarrier);
472 }
473 
createSimpleRenderPass(const DeviceInterface & vk,const VkDevice & device,VkFormat format,VkAttachmentLoadOp loadOp,VkAttachmentLoadOp stencilLoadOp,VkAttachmentStoreOp stencilStoreOp,VkImageLayout layout)474 Move<VkRenderPass> createSimpleRenderPass(const DeviceInterface &vk, const VkDevice &device, VkFormat format,
475                                           VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp,
476                                           VkAttachmentStoreOp stencilStoreOp, VkImageLayout layout)
477 {
478     const VkAttachmentDescription attachmentDescription = {
479         (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags    flags;
480         format,                           // VkFormat                        format;
481         VK_SAMPLE_COUNT_1_BIT,            // VkSampleCountFlagBits           samples;
482         loadOp,                           // VkAttachmentLoadOp              loadOp;
483         VK_ATTACHMENT_STORE_OP_STORE,     // VkAttachmentStoreOp             storeOp;
484         stencilLoadOp,                    // VkAttachmentLoadOp              stencilLoadOp;
485         stencilStoreOp,                   // VkAttachmentStoreOp             stencilStoreOp;
486         VK_IMAGE_LAYOUT_UNDEFINED,        // VkImageLayout                   initialLayout;
487         layout                            // VkImageLayout                   finalLayout;
488     };
489 
490     const VkAttachmentReference attachmentReference = {
491         0u,    // uint32_t attachment;
492         layout // VkImageLayout layout;
493     };
494 
495     const VkSubpassDescription subpassDescription = {
496         (VkSubpassDescriptionFlags)0u,   // VkSubpassDescriptionFlags       flags;
497         VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint             pipelineBindPoint
498         0u,                              // uint32_t                        inputAttachmentCount
499         DE_NULL,                         // const VkAttachmentReference*    pInputAttachments
500         1u,                              // uint32_t                        colorAttachmentCount
501         &attachmentReference,            // const VkAttachmentReference*    pColorAttachments
502         DE_NULL,                         // const VkAttachmentReference*    pResolveAttachments
503         DE_NULL,                         // const VkAttachmentReference*    pDepthStencilAttachment
504         0u,                              // uint32_t                        preserveAttachmentCount
505         DE_NULL                          // const uint32_t*                 pPreserveAttachments
506     };
507 
508     const VkRenderPassCreateInfo renderPassCreateInfo = {
509         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType                   sType;
510         DE_NULL,                                   // const void*                       pNext;
511         (VkRenderPassCreateFlags)0u,               // VkRenderPassCreateFlags           flags;
512         1u,                                        // uint32_t                          attachmentCount
513         &attachmentDescription,                    // const VkAttachmentDescription*    pAttachments
514         1u,                                        // uint32_t                          subpassCount
515         &subpassDescription,                       // const VkSubpassDescription*       pSubpasses
516         0u,                                        // uint32_t                          dependencyCount
517         DE_NULL                                    // const VkSubpassDependency*        pDependencies
518     };
519 
520     return createRenderPass(vk, device, &renderPassCreateInfo);
521 }
522 
523 // This test has the same functionality as VkLayerTest.RenderPassInUseDestroyedSignaled
framebufferCompatibleRenderPassTest(Context & context)524 tcu::TestStatus framebufferCompatibleRenderPassTest(Context &context)
525 {
526     const DeviceInterface &vk             = context.getDeviceInterface();
527     const InstanceInterface &vki          = context.getInstanceInterface();
528     const VkDevice device                 = context.getDevice();
529     const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
530     const VkQueue queue                   = context.getUniversalQueue();
531     const uint32_t queueFamilyIndex       = context.getUniversalQueueFamilyIndex();
532 
533     const VkCommandPoolCreateInfo commandPoolParams = {
534         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType             sType;
535         DE_NULL,                                    // const void*                 pNext;
536         (VkCommandPoolCreateFlags)0u,               // VkCommandPoolCreateFlags    flags;
537         queueFamilyIndex                            // uint32_t                    queueFamilyIndex;
538     };
539 
540     const Unique<VkCommandPool> commandPool(createCommandPool(vk, device, &commandPoolParams, DE_NULL));
541     const Unique<VkCommandBuffer> commandBuffer(createCommandBuffer(vk, device, commandPool.get()));
542 
543     const VkCommandBufferBeginInfo commandBufferBeginInfo = {
544         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType                          sType;
545         DE_NULL,                                     // const void*                              pNext;
546         VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags                flags;
547         DE_NULL                                      // const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
548     };
549 
550     VK_CHECK(vk.beginCommandBuffer(commandBuffer.get(), &commandBufferBeginInfo));
551 
552     const VkFormat format = getRenderTargetFormat(vki, physicalDevice);
553     const VkFormatProperties formatProperties(getPhysicalDeviceFormatProperties(vki, physicalDevice, format));
554     const VkImageTiling imageTiling =
555         (formatProperties.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)  ? VK_IMAGE_TILING_LINEAR :
556         (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? VK_IMAGE_TILING_OPTIMAL :
557                                                                                             VK_CORE_IMAGE_TILING_LAST;
558 
559     const VkImageCreateInfo imageCreateInfo = {
560         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType          sType;
561         DE_NULL,                             // const void*              pNext;
562         (VkImageCreateFlags)0u,              // VkImageCreateFlags       flags;
563         VK_IMAGE_TYPE_2D,                    // VkImageType              imageType;
564         format,                              // VkFormat                 format;
565         {
566             256u,                            // uint32_t    width;
567             256u,                            // uint32_t    height;
568             1u                               // uint32_t    depth;
569         },                                   // VkExtent3D               extent;
570         1u,                                  // uint32_t                 mipLevels;
571         1u,                                  // uint32_t                 arrayLayers;
572         VK_SAMPLE_COUNT_1_BIT,               // VkSampleCountFlagBits    samples;
573         imageTiling,                         // VkImageTiling            tiling;
574         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, // VkImageUsageFlags        usage;
575         VK_SHARING_MODE_EXCLUSIVE,           // VkSharingMode            sharingMode;
576         0u,                                  // uint32_t                 queueFamilyIndexCount;
577         DE_NULL,                             // const uint32_t*          pQueueFamilyIndices;
578         VK_IMAGE_LAYOUT_UNDEFINED            // VkImageLayout            initialLayout;
579     };
580 
581     const Unique<VkImage> attachmentImage(createImage(vk, device, &imageCreateInfo));
582     de::MovePtr<Allocation> attachmentImageMemory = context.getDefaultAllocator().allocate(
583         getImageMemoryRequirements(vk, device, *attachmentImage), MemoryRequirement::Any);
584 
585     VK_CHECK(vk.bindImageMemory(device, *attachmentImage, attachmentImageMemory->getMemory(),
586                                 attachmentImageMemory->getOffset()));
587 
588     changeColorAttachmentImageLayout(vk, commandBuffer.get(), attachmentImage.get());
589 
590     const VkImageViewCreateInfo imageViewCreateInfo = {
591         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType            sType;
592         DE_NULL,                                  // const void*                pNext;
593         (VkImageViewCreateFlags)0u,               // VkImageViewCreateFlags     flags;
594         attachmentImage.get(),                    // VkImage                    image;
595         VK_IMAGE_VIEW_TYPE_2D,                    // VkImageViewType            viewType;
596         format,                                   // VkFormat                   format;
597         {
598             VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle    r;
599             VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle    g;
600             VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle    b;
601             VK_COMPONENT_SWIZZLE_A  // VkComponentSwizzle    a;
602         },                          // VkComponentMapping         components;
603         {
604             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags    aspectMask;
605             0u,                        // uint32_t              baseMipLevel;
606             1u,                        // uint32_t              levelCount;
607             0u,                        // uint32_t              baseArrayLayer;
608             1u                         // uint32_t              layerCount;
609         }                              // VkImageSubresourceRange    subresourceRange;
610     };
611 
612     const Unique<VkImageView> attachmentImageView(createImageView(vk, device, &imageViewCreateInfo));
613 
614     Unique<VkRenderPass> renderPassA(
615         createSimpleRenderPass(vk, device, format, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
616                                VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
617 
618     // Create framebuffer using the first render pass
619     const VkFramebufferCreateInfo framebufferCreateInfo = {
620         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType             sType;
621         DE_NULL,                                   // const void*                 pNext;
622         (VkFramebufferCreateFlags)0u,              // VkFramebufferCreateFlags    flags;
623         renderPassA.get(),                         // VkRenderPass                renderPass;
624         1u,                                        // uint32_t                    attachmentCount;
625         &attachmentImageView.get(),                // const VkImageView*          pAttachments;
626         256u,                                      // uint32_t                    width;
627         256u,                                      // uint32_t                    height;
628         1u                                         // uint32_t                    layers;
629     };
630 
631     const Unique<VkFramebuffer> frameBuffer(createFramebuffer(vk, device, &framebufferCreateInfo));
632 
633     const Unique<VkRenderPass> renderPassB(
634         createSimpleRenderPass(vk, device, format, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_LOAD_OP_LOAD,
635                                VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL));
636 
637     beginRenderPass(vk, commandBuffer.get(), renderPassB.get(), frameBuffer.get(), makeRect2D(0, 0, 1u, 1u));
638     endRenderPass(vk, commandBuffer.get());
639 
640     VK_CHECK(vk.endCommandBuffer(commandBuffer.get()));
641 
642     const VkSubmitInfo submitInfo = {
643         VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType                sType;
644         DE_NULL,                       // const void*                    pNext;
645         0u,                            // uint32_t                       waitSemaphoreCount;
646         DE_NULL,                       // const VkSemaphore*             pWaitSemaphores;
647         DE_NULL,                       // const VkPipelineStageFlags*    pWaitDstStageMask;
648         1u,                            // uint32_t                       commandBufferCount;
649         &commandBuffer.get(),          // const VkCommandBuffer*         pCommandBuffers;
650         0u,                            // uint32_t                       signalSemaphoreCount;
651         DE_NULL                        // const VkSemaphore*             pSignalSemaphores;
652     };
653 
654     VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, DE_NULL));
655     VK_CHECK(vk.queueWaitIdle(queue));
656 
657     // Test should always pass
658     return tcu::TestStatus::pass("Pass");
659 }
660 
getDescriptorSetLayout(const DeviceInterface & vk,const VkDevice & device,uint32_t bindingCount,const VkDescriptorSetLayoutBinding * layoutBindings)661 Move<VkDescriptorSetLayout> getDescriptorSetLayout(const DeviceInterface &vk, const VkDevice &device,
662                                                    uint32_t bindingCount,
663                                                    const VkDescriptorSetLayoutBinding *layoutBindings)
664 {
665     const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {
666         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType                        sType;
667         DE_NULL,                                             // const void*                            pNext;
668         (VkDescriptorSetLayoutCreateFlags)0u,                // VkDescriptorSetLayoutCreateFlags       flags;
669         bindingCount,                                        // uint32_t                               bindingCount;
670         layoutBindings                                       // const VkDescriptorSetLayoutBinding*    pBindings;
671     };
672 
673     return createDescriptorSetLayout(vk, device, &descriptorSetLayoutCreateInfo);
674 }
675 
getDescriptorSet(const DeviceInterface & vk,const VkDevice & device,VkDescriptorPool descriptorPool,VkDescriptorSetLayout setLayout)676 VkDescriptorSet getDescriptorSet(const DeviceInterface &vk, const VkDevice &device, VkDescriptorPool descriptorPool,
677                                  VkDescriptorSetLayout setLayout)
678 {
679     const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = {
680         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType                 sType;
681         DE_NULL,                                        // const void*                     pNext;
682         descriptorPool,                                 // VkDescriptorPool                descriptorPool;
683         1u,                                             // uint32_t                        descriptorSetCount;
684         &setLayout                                      // const VkDescriptorSetLayout*    pSetLayouts;
685     };
686 
687     VkDescriptorSet descriptorSet;
688     VK_CHECK(vk.allocateDescriptorSets(device, &descriptorSetAllocateInfo, &descriptorSet));
689 
690     return descriptorSet;
691 }
692 
getPipelineLayout(const DeviceInterface & vk,const VkDevice & device,uint32_t setLayoutCount,const VkDescriptorSetLayout * setLayouts)693 Move<VkPipelineLayout> getPipelineLayout(const DeviceInterface &vk, const VkDevice &device, uint32_t setLayoutCount,
694                                          const VkDescriptorSetLayout *setLayouts)
695 {
696     const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
697         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType                 sType;
698         DE_NULL,                                       // const void*                     pNext;
699         (VkPipelineLayoutCreateFlags)0u,               // VkPipelineLayoutCreateFlags     flags;
700         setLayoutCount,                                // uint32_t                        setLayoutCount;
701         setLayouts,                                    // const VkDescriptorSetLayout*    pSetLayouts;
702         0u,                                            // uint32_t                        pushConstantRangeCount;
703         DE_NULL                                        // const VkPushConstantRange*      pPushConstantRanges;
704     };
705 
706     return createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
707 }
708 
createSimpleGraphicsPipeline(const DeviceInterface & vk,const VkDevice & device,uint32_t numShaderStages,const VkPipelineShaderStageCreateInfo * shaderStageCreateInfos,VkPipelineLayout pipelineLayout,VkRenderPass renderPass,de::SharedPtr<vk::ResourceInterface> resourceInterface)709 Move<VkPipeline> createSimpleGraphicsPipeline(const DeviceInterface &vk, const VkDevice &device,
710                                               uint32_t numShaderStages,
711                                               const VkPipelineShaderStageCreateInfo *shaderStageCreateInfos,
712                                               VkPipelineLayout pipelineLayout, VkRenderPass renderPass,
713                                               de::SharedPtr<vk::ResourceInterface> resourceInterface)
714 {
715 #ifndef CTS_USES_VULKANSC
716     DE_UNREF(resourceInterface);
717 #endif // CTS_USES_VULKANSC
718     const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = {
719         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType                             sType;
720         DE_NULL,                                                   // const void*                                 pNext;
721         (VkPipelineVertexInputStateCreateFlags)0,                  // VkPipelineVertexInputStateCreateFlags       flags;
722         0u,      // uint32_t                                    vertexBindingDescriptionCount;
723         DE_NULL, // const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
724         0u,      // uint32_t                                    vertexAttributeDescriptionCount;
725         DE_NULL  // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
726     };
727 
728     const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo = {
729         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType                            sType;
730         DE_NULL,                                    // const void*                                pNext;
731         (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags    flags;
732         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,       // VkPrimitiveTopology                        topology;
733         VK_FALSE // VkBool32                                   primitiveRestartEnable;
734     };
735 
736     const VkPipelineViewportStateCreateInfo viewPortStateCreateInfo = {
737         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType                       sType;
738         DE_NULL,                                               // const void*                           pNext;
739         (VkPipelineViewportStateCreateFlags)0,                 // VkPipelineViewportStateCreateFlags    flags;
740         1,                                                     // uint32_t                              viewportCount;
741         DE_NULL,                                               // const VkViewport*                     pViewports;
742         1,                                                     // uint32_t                              scissorCount;
743         DE_NULL                                                // const VkRect2D*                       pScissors;
744     };
745 
746     const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo = {
747         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType                            sType;
748         DE_NULL,                                                    // const void*                                pNext;
749         (VkPipelineRasterizationStateCreateFlags)0,                 // VkPipelineRasterizationStateCreateFlags    flags;
750         VK_FALSE,                // VkBool32                                   depthClampEnable;
751         VK_FALSE,                // VkBool32                                   rasterizerDiscardEnable;
752         VK_POLYGON_MODE_FILL,    // VkPolygonMode                              polygonMode;
753         VK_CULL_MODE_BACK_BIT,   // VkCullModeFlags                            cullMode;
754         VK_FRONT_FACE_CLOCKWISE, // VkFrontFace                                frontFace;
755         VK_FALSE,                // VkBool32                                   depthBiasEnable;
756         0.0f,                    // float                                      depthBiasConstantFactor;
757         0.0f,                    // float                                      depthBiasClamp;
758         0.0f,                    // float                                      depthBiasSlopeFactor;
759         1.0f                     // float                                      lineWidth;
760     };
761 
762     const VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo = {
763         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType                          sType;
764         DE_NULL,                                                  // const void*                              pNext;
765         (VkPipelineMultisampleStateCreateFlags)0,                 // VkPipelineMultisampleStateCreateFlags    flags;
766         VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits                    rasterizationSamples;
767         VK_FALSE,              // VkBool32                                 sampleShadingEnable;
768         0.0f,                  // float                                    minSampleShading;
769         DE_NULL,               // const VkSampleMask*                      pSampleMask;
770         VK_FALSE,              // VkBool32                                 alphaToCoverageEnable;
771         VK_FALSE               // VkBool32                                 alphaToOneEnable;
772     };
773 
774     const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = {
775         VK_FALSE,                   // VkBool32                 blendEnable;
776         VK_BLEND_FACTOR_ZERO,       // VkBlendFactor            srcColorBlendFactor;
777         VK_BLEND_FACTOR_ZERO,       // VkBlendFactor            dstColorBlendFactor;
778         VK_BLEND_OP_ADD,            // VkBlendOp                colorBlendOp;
779         VK_BLEND_FACTOR_ZERO,       // VkBlendFactor            srcAlphaBlendFactor;
780         VK_BLEND_FACTOR_ZERO,       // VkBlendFactor            dstAlphaBlendFactor;
781         VK_BLEND_OP_ADD,            // VkBlendOp                alphaBlendOp;
782         (VkColorComponentFlags)0xFu // VkColorComponentFlags    colorWriteMask;
783     };
784 
785     const VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo = {
786         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType                               sType;
787         DE_NULL,                                 // const void*                                   pNext;
788         (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags          flags;
789         false,                                   // VkBool32                                      logicOpEnable;
790         VK_LOGIC_OP_CLEAR,                       // VkLogicOp                                     logicOp;
791         1,                                       // uint32_t                                      attachmentCount;
792         &colorBlendAttachmentState,              // const VkPipelineColorBlendAttachmentState*    pAttachments;
793         {1.0f, 1.0f, 1.0f, 1.0f}                 // float                                         blendConstants[4];
794     };
795 
796     const VkDynamicState dynamicStates[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
797 
798     const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo = {
799         VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType                      sType;
800         DE_NULL,                                              // const void*                          pNext;
801         (VkPipelineDynamicStateCreateFlags)0u,                // VkPipelineDynamicStateCreateFlags    flags;
802         DE_LENGTH_OF_ARRAY(dynamicStates),                    // uint32_t                             dynamicStateCount;
803         dynamicStates                                         // const VkDynamicState*                pDynamicStates;
804     };
805 
806     const VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo = {
807         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType                                  sType;
808         DE_NULL,                                         // const void*                                      pNext;
809         (VkPipelineCreateFlags)0,                        // VkPipelineCreateFlags                            flags;
810         numShaderStages,                                 // uint32_t                                         stageCount;
811         shaderStageCreateInfos,                          // const VkPipelineShaderStageCreateInfo*           pStages;
812         &vertexInputStateCreateInfo,   // const VkPipelineVertexInputStateCreateInfo*      pVertexInputState;
813         &inputAssemblyStateCreateInfo, // const VkPipelineInputAssemblyStateCreateInfo*    pInputAssemblyState;
814         DE_NULL,                       // const VkPipelineTessellationStateCreateInfo*     pTessellationState;
815         &viewPortStateCreateInfo,      // const VkPipelineViewportStateCreateInfo*         pViewportState;
816         &rasterizationStateCreateInfo, // const VkPipelineRasterizationStateCreateInfo*    pRasterizationState;
817         &multisampleStateCreateInfo,   // const VkPipelineMultisampleStateCreateInfo*      pMultisampleState;
818         DE_NULL,                       // const VkPipelineDepthStencilStateCreateInfo*     pDepthStencilState;
819         &colorBlendStateCreateInfo,    // const VkPipelineColorBlendStateCreateInfo*       pColorBlendState;
820         &dynamicStateCreateInfo,       // const VkPipelineDynamicStateCreateInfo*          pDynamicState;
821         pipelineLayout,                // VkPipelineLayout                                 layout;
822         renderPass,                    // VkRenderPass                                     renderPass;
823         0u,                            // uint32_t                                         subpass;
824         DE_NULL,                       // VkPipeline                                       basePipelineHandle;
825         0                              // int                                              basePipelineIndex;
826     };
827 
828     const VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {
829         VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType               sType;
830         DE_NULL,                                      // const void*                   pNext;
831 #ifndef CTS_USES_VULKANSC
832         (VkPipelineCacheCreateFlags)0u, // VkPipelineCacheCreateFlags    flags;
833         0,                              // size_t                        initialDataSize;
834         DE_NULL                         // const void*                   pInitialData;
835 #else
836         VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
837             VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT, // VkPipelineCacheCreateFlags    flags;
838         resourceInterface->getCacheDataSize(),                    // uintptr_t                     initialDataSize;
839         resourceInterface->getCacheData()                         // const void*                   pInitialData;
840 #endif // CTS_USES_VULKANSC
841     };
842 
843     const Unique<VkPipelineCache> pipelineCache(createPipelineCache(vk, device, &pipelineCacheCreateInfo));
844 
845     return createGraphicsPipeline(vk, device, pipelineCache.get(), &graphicsPipelineCreateInfo);
846 }
847 
pipelineLayoutLifetimeTest(Context & context,VkPipelineBindPoint bindPoint)848 tcu::TestStatus pipelineLayoutLifetimeTest(Context &context, VkPipelineBindPoint bindPoint)
849 {
850     const DeviceInterface &vk             = context.getDeviceInterface();
851     const InstanceInterface &vki          = context.getInstanceInterface();
852     const VkDevice device                 = context.getDevice();
853     const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
854     const uint32_t queueFamilyIndex       = context.getUniversalQueueFamilyIndex();
855     const bool isGraphics                 = (bindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS);
856 
857     const VkCommandPoolCreateInfo commandPoolParams = {
858         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType             sType;
859         DE_NULL,                                    // const void*                 pNext;
860         (VkCommandPoolCreateFlags)0u,               // VkCommandPoolCreateFlags    flags;
861         queueFamilyIndex                            // uint32_t                    queueFamilyIndex;
862     };
863 
864     const Unique<VkCommandPool> commandPool(createCommandPool(vk, device, &commandPoolParams, DE_NULL));
865     const Unique<VkCommandBuffer> commandBuffer(createCommandBuffer(vk, device, commandPool.get()));
866 
867     // Begin command buffer.
868     {
869         const VkCommandBufferBeginInfo commandBufferBeginInfo = {
870             VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType                          sType;
871             DE_NULL,                                     // const void*                              pNext;
872             VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags                flags;
873             DE_NULL                                      // const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
874         };
875 
876         VK_CHECK(vk.beginCommandBuffer(commandBuffer.get(), &commandBufferBeginInfo));
877     }
878 
879     // These will only be used for graphics pipelines.
880     Move<VkImage> attachmentImage;
881     de::MovePtr<Allocation> attachmentImageMemory;
882     Move<VkImageView> attachmentImageView;
883     Move<VkRenderPass> renderPass;
884     Move<VkFramebuffer> frameBuffer;
885 
886     if (isGraphics)
887     {
888         // Create image, render pass and framebuffer.
889         const VkFormat format = getRenderTargetFormat(vki, physicalDevice);
890         const VkFormatProperties formatProperties(getPhysicalDeviceFormatProperties(vki, physicalDevice, format));
891         const VkImageTiling imageTiling =
892             (formatProperties.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ?
893                 VK_IMAGE_TILING_LINEAR :
894             (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ?
895                 VK_IMAGE_TILING_OPTIMAL :
896                 VK_CORE_IMAGE_TILING_LAST;
897 
898         const VkImageCreateInfo imageCreateInfo = {
899             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType          sType;
900             DE_NULL,                             // const void*              pNext;
901             (VkImageCreateFlags)0u,              // VkImageCreateFlags       flags;
902             VK_IMAGE_TYPE_2D,                    // VkImageType              imageType;
903             format,                              // VkFormat                 format;
904             {
905                 256u,                            // uint32_t    width;
906                 256u,                            // uint32_t    height;
907                 1u                               // uint32_t    depth;
908             },                                   // VkExtent3D               extent;
909             1u,                                  // uint32_t                 mipLevels;
910             1u,                                  // uint32_t                 arrayLayers;
911             VK_SAMPLE_COUNT_1_BIT,               // VkSampleCountFlagBits    samples;
912             imageTiling,                         // VkImageTiling            tiling;
913             VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, // VkImageUsageFlags        usage;
914             VK_SHARING_MODE_EXCLUSIVE,           // VkSharingMode            sharingMode;
915             0u,                                  // uint32_t                 queueFamilyIndexCount;
916             DE_NULL,                             // const uint32_t*          pQueueFamilyIndices;
917             VK_IMAGE_LAYOUT_UNDEFINED            // VkImageLayout            initialLayout;
918         };
919 
920         attachmentImage       = createImage(vk, device, &imageCreateInfo);
921         attachmentImageMemory = context.getDefaultAllocator().allocate(
922             getImageMemoryRequirements(vk, device, *attachmentImage), MemoryRequirement::Any);
923 
924         VK_CHECK(vk.bindImageMemory(device, *attachmentImage, attachmentImageMemory->getMemory(),
925                                     attachmentImageMemory->getOffset()));
926 
927         changeColorAttachmentImageLayout(vk, commandBuffer.get(), attachmentImage.get());
928 
929         const VkImageViewCreateInfo imageViewCreateInfo = {
930             VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType            sType;
931             DE_NULL,                                  // const void*                pNext;
932             (VkImageViewCreateFlags)0u,               // VkImageViewCreateFlags     flags;
933             attachmentImage.get(),                    // VkImage                    image;
934             VK_IMAGE_VIEW_TYPE_2D,                    // VkImageViewType            viewType;
935             format,                                   // VkFormat                   format;
936             {
937                 VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle    r;
938                 VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle    g;
939                 VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle    b;
940                 VK_COMPONENT_SWIZZLE_A  // VkComponentSwizzle    a;
941             },                          // VkComponentMapping         components;
942             {
943                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags    aspectMask;
944                 0u,                        // uint32_t              baseMipLevel;
945                 1u,                        // uint32_t              levelCount;
946                 0u,                        // uint32_t              baseArrayLayer;
947                 1u                         // uint32_t              layerCount;
948             }                              // VkImageSubresourceRange    subresourceRange;
949         };
950 
951         attachmentImageView = createImageView(vk, device, &imageViewCreateInfo);
952         renderPass =
953             createSimpleRenderPass(vk, device, format, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
954                                    VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
955 
956         const VkFramebufferCreateInfo framebufferCreateInfo = {
957             VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType             sType;
958             DE_NULL,                                   // const void*                 pNext;
959             (VkFramebufferCreateFlags)0u,              // VkFramebufferCreateFlags    flags;
960             renderPass.get(),                          // VkRenderPass                renderPass;
961             1u,                                        // uint32_t                    attachmentCount;
962             &attachmentImageView.get(),                // const VkImageView*          pAttachments;
963             256u,                                      // uint32_t                    width;
964             256u,                                      // uint32_t                    height;
965             1u                                         // uint32_t                    layers;
966         };
967 
968         frameBuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
969     }
970 
971     const VkDescriptorPoolSize descriptorPoolSizes[] = {
972         {
973             VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // VkDescriptorType    type;
974             10                                 // uint32_t            descriptorCount;
975         },
976         {
977             VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // VkDescriptorType    type;
978             2                                 // uint32_t            descriptorCount;
979         },
980         {
981             VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, // VkDescriptorType    type;
982             2                                 // uint32_t            descriptorCount;
983         }};
984 
985     const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = {
986         VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType                sType;
987         DE_NULL,                                       // const void*                    pNext;
988         (VkDescriptorPoolCreateFlags)0u,               // VkDescriptorPoolCreateFlags    flags;
989         (isGraphics ? 3u : 5u),                        // uint32_t                       maxSets;
990         DE_LENGTH_OF_ARRAY(descriptorPoolSizes),       // uint32_t                       poolSizeCount;
991         descriptorPoolSizes                            // const VkDescriptorPoolSize*    pPoolSizes;
992     };
993 
994     Move<VkDescriptorPool> descriptorPool = createDescriptorPool(vk, device, &descriptorPoolCreateInfo, DE_NULL);
995 
996     const VkDescriptorSetLayoutBinding setLayoutBindingA[] = {{
997         0,                                 // uint32_t              binding;
998         VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // VkDescriptorType      descriptorType;
999         5,                                 // uint32_t              descriptorCount;
1000         VK_SHADER_STAGE_ALL,               // VkShaderStageFlags    stageFlags;
1001         DE_NULL                            // const VkSampler*      pImmutableSamplers;
1002     }};
1003 
1004     const VkShaderStageFlags shaderStage = (isGraphics ? VK_SHADER_STAGE_FRAGMENT_BIT : VK_SHADER_STAGE_COMPUTE_BIT);
1005 
1006     const VkDescriptorSetLayoutBinding setLayoutBindingB[] = {{
1007         0,                                 // uint32_t              binding;
1008         VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // VkDescriptorType      descriptorType;
1009         5,                                 // uint32_t              descriptorCount;
1010         (VkShaderStageFlags)shaderStage,   // VkShaderStageFlags    stageFlags;
1011         DE_NULL                            // const VkSampler*      pImmutableSamplers;
1012     }};
1013 
1014     const VkDescriptorSetLayoutBinding setLayoutBindingC[] = {
1015         {
1016             0,                                // uint32_t              binding;
1017             VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // VkDescriptorType      descriptorType;
1018             2,                                // uint32_t              descriptorCount;
1019             VK_SHADER_STAGE_ALL,              // VkShaderStageFlags    stageFlags;
1020             DE_NULL                           // const VkSampler*      pImmutableSamplers;
1021         },
1022         {
1023             1,                                // uint32_t              binding;
1024             VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, // VkDescriptorType      descriptorType;
1025             2,                                // uint32_t              descriptorCount;
1026             VK_SHADER_STAGE_ALL,              // VkShaderStageFlags    stageFlags;
1027             DE_NULL                           // const VkSampler*      pImmutableSamplers;
1028         }};
1029 
1030     const Move<VkDescriptorSetLayout> descriptorSetLayouts[] = {
1031         getDescriptorSetLayout(vk, device, DE_LENGTH_OF_ARRAY(setLayoutBindingA), setLayoutBindingA),
1032         getDescriptorSetLayout(vk, device, DE_LENGTH_OF_ARRAY(setLayoutBindingB), setLayoutBindingB),
1033         getDescriptorSetLayout(vk, device, DE_LENGTH_OF_ARRAY(setLayoutBindingC), setLayoutBindingC)};
1034 
1035     const VkDescriptorSetLayout setLayoutHandlesAC[] = {descriptorSetLayouts[0].get(), descriptorSetLayouts[2].get()};
1036 
1037     const VkDescriptorSetLayout setLayoutHandlesB[] = {descriptorSetLayouts[1].get()};
1038 
1039     const VkDescriptorSetLayout setLayoutHandlesBC[] = {descriptorSetLayouts[1].get(), descriptorSetLayouts[2].get()};
1040 
1041     const VkDescriptorSet descriptorSets[] = {
1042         getDescriptorSet(vk, device, descriptorPool.get(), descriptorSetLayouts[0].get()),
1043         getDescriptorSet(vk, device, descriptorPool.get(), descriptorSetLayouts[1].get()),
1044         getDescriptorSet(vk, device, descriptorPool.get(), descriptorSetLayouts[2].get())};
1045 
1046     const VkDescriptorSet setHandlesAC[] = {descriptorSets[0], descriptorSets[2]};
1047 
1048     const VkDescriptorSet setHandlesC[] = {descriptorSets[2]};
1049 
1050     const Unique<VkPipelineLayout> pipelineLayoutAC(
1051         getPipelineLayout(vk, device, DE_LENGTH_OF_ARRAY(setLayoutHandlesAC), setLayoutHandlesAC));
1052     const Unique<VkPipelineLayout> pipelineLayoutBC(
1053         getPipelineLayout(vk, device, DE_LENGTH_OF_ARRAY(setLayoutHandlesBC), setLayoutHandlesBC));
1054 
1055     VkPipelineLayout pipelineLayoutB;
1056     {
1057         const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
1058             VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType                 sType;
1059             DE_NULL,                                       // const void*                     pNext;
1060             (VkPipelineLayoutCreateFlags)0u,               // VkPipelineLayoutCreateFlags     flags;
1061             DE_LENGTH_OF_ARRAY(setLayoutHandlesB),         // uint32_t                        setLayoutCount;
1062             setLayoutHandlesB,                             // const VkDescriptorSetLayout*    pSetLayouts;
1063             0u,                                            // uint32_t                        pushConstantRangeCount;
1064             DE_NULL                                        // const VkPushConstantRange*      pPushConstantRanges;
1065         };
1066 
1067         VK_CHECK(vk.createPipelineLayout(device, &pipelineLayoutCreateInfo, DE_NULL, &pipelineLayoutB));
1068     }
1069 
1070     std::vector<Move<VkShaderModule>> shaderModules;
1071     Move<VkPipeline> pipeline;
1072 
1073     if (isGraphics)
1074     {
1075         shaderModules.push_back(createShaderModule(vk, device, context.getBinaryCollection().get("vertex"), 0));
1076         shaderModules.push_back(createShaderModule(vk, device, context.getBinaryCollection().get("fragment"), 0));
1077 
1078         const VkPipelineShaderStageCreateInfo shaderStageCreateInfos[] = {
1079             {
1080                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType                     sType;
1081                 DE_NULL,                                             // const void*                         pNext;
1082                 (VkPipelineShaderStageCreateFlags)0,                 // VkPipelineShaderStageCreateFlags    flags;
1083                 VK_SHADER_STAGE_VERTEX_BIT,                          // VkShaderStageFlagBits               stage;
1084                 shaderModules[0].get(),                              // VkShaderModule                      shader;
1085                 "main",                                              // const char*                         pName;
1086                 DE_NULL, // const VkSpecializationInfo*         pSpecializationInfo;
1087             },
1088             {
1089                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType                     sType;
1090                 DE_NULL,                                             // const void*                         pNext;
1091                 (VkPipelineShaderStageCreateFlags)0,                 // VkPipelineShaderStageCreateFlags    flags;
1092                 VK_SHADER_STAGE_FRAGMENT_BIT,                        // VkShaderStageFlagBits               stage;
1093                 shaderModules[1].get(),                              // VkShaderModule                      shader;
1094                 "main",                                              // const char*                         pName;
1095                 DE_NULL, // const VkSpecializationInfo*         pSpecializationInfo;
1096             }};
1097 
1098         pipeline =
1099             createSimpleGraphicsPipeline(vk, device, DE_LENGTH_OF_ARRAY(shaderStageCreateInfos), shaderStageCreateInfos,
1100                                          pipelineLayoutB, renderPass.get(), context.getResourceInterface());
1101     }
1102     else
1103     {
1104         shaderModules.push_back(createShaderModule(vk, device, context.getBinaryCollection().get("compute"), 0));
1105 
1106         const VkPipelineShaderStageCreateInfo shaderStageCreateInfo = {
1107             VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType                     sType;
1108             DE_NULL,                                             // const void*                         pNext;
1109             (VkPipelineShaderStageCreateFlags)0,                 // VkPipelineShaderStageCreateFlags    flags;
1110             VK_SHADER_STAGE_COMPUTE_BIT,                         // VkShaderStageFlagBits               stage;
1111             shaderModules[0].get(),                              // VkShaderModule                      shader;
1112             "main",                                              // const char*                         pName;
1113             DE_NULL, // const VkSpecializationInfo*         pSpecializationInfo;
1114         };
1115 
1116         const VkComputePipelineCreateInfo computePipelineCreateInfo = {
1117             VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType                    sType;
1118             DE_NULL,                                        // const void*                        pNext
1119             (VkPipelineCreateFlags)0,                       // VkPipelineCreateFlags              flags
1120             shaderStageCreateInfo,                          // VkPipelineShaderStageCreateInfo    stage
1121             pipelineLayoutB,                                // VkPipelineLayout                   layout
1122             DE_NULL,                                        // VkPipeline                         basePipelineHandle
1123             0                                               // int                                basePipelineIndex
1124         };
1125 
1126         pipeline = createComputePipeline(vk, device, DE_NULL, &computePipelineCreateInfo);
1127     }
1128 
1129     if (isGraphics)
1130     {
1131         beginRenderPass(vk, commandBuffer.get(), renderPass.get(), frameBuffer.get(), makeRect2D(0, 0, 256u, 256u),
1132                         tcu::Vec4(0.25f, 0.25f, 0.25f, 0.0f));
1133     }
1134     vk.cmdBindPipeline(commandBuffer.get(), bindPoint, pipeline.get());
1135 
1136     // Destroy the pipeline layout that was used to create the pipeline
1137     vk.destroyPipelineLayout(device, pipelineLayoutB, DE_NULL);
1138 
1139     vk.cmdBindDescriptorSets(commandBuffer.get(), bindPoint, pipelineLayoutAC.get(), 0u,
1140                              DE_LENGTH_OF_ARRAY(setHandlesAC), setHandlesAC, 0u, DE_NULL);
1141     vk.cmdBindDescriptorSets(commandBuffer.get(), bindPoint, pipelineLayoutBC.get(), 1u,
1142                              DE_LENGTH_OF_ARRAY(setHandlesC), setHandlesC, 0u, DE_NULL);
1143 
1144     if (isGraphics)
1145     {
1146         const VkViewport viewport = {
1147             0.0f,  // float    x;
1148             0.0f,  // float    y;
1149             16.0f, // float    width;
1150             16.0f, // float    height;
1151             0.0f,  // float    minDepth;
1152             1.0f   // float    maxDepth;
1153         };
1154 
1155         const VkRect2D scissor = {
1156             {0u, 0u},  // VkOffset2D    offset;
1157             {16u, 16u} // VkExtent2D    extent;
1158         };
1159 
1160         vk.cmdSetViewport(commandBuffer.get(), 0u, 1u, &viewport);
1161         vk.cmdSetScissor(commandBuffer.get(), 0u, 1u, &scissor);
1162     }
1163 
1164     vk.cmdBindDescriptorSets(commandBuffer.get(), bindPoint, pipelineLayoutAC.get(), 0u,
1165                              DE_LENGTH_OF_ARRAY(setHandlesAC), setHandlesAC, 0u, DE_NULL);
1166 
1167     // Test should always pass
1168     return tcu::TestStatus::pass("Pass");
1169 }
1170 
createPipelineLayoutLifetimeGraphicsSource(SourceCollections & dst)1171 void createPipelineLayoutLifetimeGraphicsSource(SourceCollections &dst)
1172 {
1173     dst.glslSources.add("vertex") << glu::VertexSource("#version 450\n"
1174                                                        "\n"
1175                                                        "void main (void)\n"
1176                                                        "{\n"
1177                                                        "   gl_Position = vec4(1);\n"
1178                                                        "}\n");
1179 
1180     dst.glslSources.add("fragment") << glu::FragmentSource(
1181         "#version 450\n"
1182         "\n"
1183         "layout(location=0) out vec4 x;\n"
1184         "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
1185         "void main (void)\n"
1186         "{\n"
1187         "   x = vec4(bar.y);\n"
1188         "}\n");
1189 }
1190 
1191 // This test has the same functionality as VkLayerTest.DescriptorSetCompatibility
pipelineLayoutLifetimeGraphicsTest(Context & context)1192 tcu::TestStatus pipelineLayoutLifetimeGraphicsTest(Context &context)
1193 {
1194     return pipelineLayoutLifetimeTest(context, VK_PIPELINE_BIND_POINT_GRAPHICS);
1195 }
1196 
createPipelineLayoutLifetimeComputeSource(SourceCollections & dst)1197 void createPipelineLayoutLifetimeComputeSource(SourceCollections &dst)
1198 {
1199     dst.glslSources.add("compute") << glu::ComputeSource(
1200         "#version 450\n"
1201         "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1202         "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
1203         "void main (void)\n"
1204         "{\n"
1205         "    vec4 x = vec4(bar.y);\n"
1206         "}\n");
1207 }
1208 
pipelineLayoutLifetimeComputeTest(Context & context)1209 tcu::TestStatus pipelineLayoutLifetimeComputeTest(Context &context)
1210 {
1211     return pipelineLayoutLifetimeTest(context, VK_PIPELINE_BIND_POINT_COMPUTE);
1212 }
1213 
checkSupport(Context & context)1214 void checkSupport(Context &context)
1215 {
1216     const InstanceInterface &vki          = context.getInstanceInterface();
1217     const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
1218 
1219     // Throws exception if not supported
1220     getRenderTargetFormat(vki, physicalDevice);
1221 }
1222 
destroyEarlyComputeSource(SourceCollections & programs)1223 void destroyEarlyComputeSource(SourceCollections &programs)
1224 {
1225     std::string comp = "#version 450\n"
1226                        "layout (local_size_x=1, local_size_y=1, local_size_z=1) in;\n"
1227                        "layout (constant_id=0) const uint flag = 0;\n"
1228                        "layout (push_constant, std430) uniform PushConstants {\n"
1229                        "    uint base;\n"
1230                        "};\n"
1231                        "layout (set=0, binding=0, std430) buffer Block {\n"
1232                        "    uint data[];\n"
1233                        "};\n"
1234                        "\n"
1235                        "void main() {\n"
1236                        "    if (flag != 0u) {\n"
1237                        "        uint idx = gl_GlobalInvocationID.x;\n"
1238                        "        data[idx] = data[idx] + base + idx;\n"
1239                        "    }\n"
1240                        "}\n";
1241 
1242     programs.glslSources.add("comp") << glu::ComputeSource(comp);
1243 }
1244 
checkMaintenance4Support(Context & context)1245 void checkMaintenance4Support(Context &context)
1246 {
1247     context.requireDeviceFunctionality("VK_KHR_maintenance4");
1248 }
1249 
1250 enum DestroyPipelineLayoutMode
1251 {
1252     DPLM_DESTROY_AFTER_END_COMMAND_BUFFER = 0,
1253     DPLM_DESTROY_AFTER_CREATE_COMPUTE_PIPELINES,
1254 };
1255 
destroyEarlyTest(Context & context,DestroyPipelineLayoutMode mode)1256 tcu::TestStatus destroyEarlyTest(Context &context, DestroyPipelineLayoutMode mode)
1257 {
1258     const auto &vkd   = context.getDeviceInterface();
1259     const auto device = context.getDevice();
1260     auto &alloc       = context.getDefaultAllocator();
1261     const auto queue  = context.getUniversalQueue();
1262     const auto qIndex = context.getUniversalQueueFamilyIndex();
1263 
1264     const uint32_t kBufferElements = 100u;
1265     const uint32_t kBufferSize     = kBufferElements * sizeof(uint32_t);
1266     const auto kBufferSizeDS       = static_cast<VkDeviceSize>(kBufferSize);
1267     const uint32_t kInitialValue   = 50u;
1268     const uint32_t kFlagValue      = 1u;
1269     const uint32_t kBaseValue      = 75u;
1270 
1271     // Allocate and prepare buffer.
1272     const auto bufferInfo = vk::makeBufferCreateInfo(kBufferSizeDS, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1273     vk::BufferWithMemory buffer(vkd, device, alloc, bufferInfo, vk::MemoryRequirement::HostVisible);
1274     auto &bufferAlloc = buffer.getAllocation();
1275     void *bufferPtr   = bufferAlloc.getHostPtr();
1276     {
1277         const std::vector<uint32_t> bufferValues(kBufferElements, kInitialValue);
1278         deMemcpy(bufferPtr, bufferValues.data(), kBufferSize);
1279         vk::flushAlloc(vkd, device, bufferAlloc);
1280     }
1281 
1282     // Descriptor set layout.
1283     vk::DescriptorSetLayoutBuilder layoutBuilder;
1284     layoutBuilder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1285     const auto descriptorSetLayout = layoutBuilder.build(vkd, device);
1286 
1287     // Pipeline layout.
1288     const auto pushConstantRange =
1289         vk::makePushConstantRange(vk::VK_SHADER_STAGE_COMPUTE_BIT, 0u, static_cast<uint32_t>(sizeof(kBaseValue)));
1290 
1291     const vk::VkPipelineLayoutCreateInfo pipelineLayoutInfo = {
1292         vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1293         nullptr,                                           // const void* pNext;
1294         0u,                                                // VkPipelineLayoutCreateFlags flags;
1295         1u,                                                // uint32_t setLayoutCount;
1296         &descriptorSetLayout.get(),                        // const VkDescriptorSetLayout* pSetLayouts;
1297         1u,                                                // uint32_t pushConstantRangeCount;
1298         &pushConstantRange,                                // const VkPushConstantRange* pPushConstantRanges;
1299     };
1300 
1301     auto pipelineLayout = vk::createPipelineLayout(vkd, device, &pipelineLayoutInfo);
1302 
1303     // Shader module.
1304     const auto shaderModule = vk::createShaderModule(vkd, device, context.getBinaryCollection().get("comp"), 0u);
1305 
1306     // Pipeline, with shader and specialization info.
1307     const auto specConstantSize = static_cast<uintptr_t>(sizeof(kFlagValue));
1308 
1309     const vk::VkSpecializationMapEntry mapEntry = {
1310         0u,               // uint32_t constantID;
1311         0u,               // uint32_t offset;
1312         specConstantSize, // uintptr_t size;
1313     };
1314 
1315     const vk::VkSpecializationInfo specializationInfo = {
1316         1u,               // uint32_t mapEntryCount;
1317         &mapEntry,        // const VkSpecializationMapEntry* pMapEntries;
1318         specConstantSize, // uintptr_t dataSize;
1319         &kFlagValue,      // const void* pData;
1320     };
1321 
1322     const VkPipelineShaderStageCreateInfo shaderInfo = {
1323         vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1324         nullptr,                                                 // const void* pNext;
1325         0u,                                                      // VkPipelineShaderStageCreateFlags flags;
1326         vk::VK_SHADER_STAGE_COMPUTE_BIT,                         // VkShaderStageFlagBits stage;
1327         shaderModule.get(),                                      // VkShaderModule module;
1328         "main",                                                  // const char* pName;
1329         &specializationInfo,                                     // const VkSpecializationInfo* pSpecializationInfo;
1330     };
1331     const vk::VkComputePipelineCreateInfo pipelineInfo = {
1332         vk::VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
1333         nullptr,                                            // const void* pNext;
1334         0u,                                                 // VkPipelineCreateFlags flags;
1335         shaderInfo,                                         // VkPipelineShaderStageCreateInfo stage;
1336         pipelineLayout.get(),                               // VkPipelineLayout layout;
1337         DE_NULL,                                            // VkPipeline basePipelineHandle;
1338         0,                                                  // int32_t basePipelineIndex;
1339     };
1340 
1341     const auto pipeline = vk::createComputePipeline(vkd, device, DE_NULL, &pipelineInfo);
1342 
1343     // Delete pipeline layout just after creating pipeline - this is what the test is for
1344     if (DPLM_DESTROY_AFTER_CREATE_COMPUTE_PIPELINES == mode)
1345         pipelineLayout = decltype(pipelineLayout)();
1346 
1347     // Descriptor set.
1348     vk::DescriptorPoolBuilder descriptorPoolBuilder;
1349     descriptorPoolBuilder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
1350     const auto descriptorPool =
1351         descriptorPoolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1352     const auto descriptorSet = vk::makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get());
1353 
1354     // Update descriptor set with buffer.
1355     vk::DescriptorSetUpdateBuilder updateBuilder;
1356     const auto descriptorInfo = vk::makeDescriptorBufferInfo(buffer.get(), static_cast<VkDeviceSize>(0), kBufferSizeDS);
1357     updateBuilder.writeSingle(descriptorSet.get(), vk::DescriptorSetUpdateBuilder::Location::binding(0u),
1358                               vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo);
1359     updateBuilder.update(vkd, device);
1360 
1361     // Prepare command buffer.
1362     const auto cmdPool = vk::makeCommandPool(vkd, device, qIndex);
1363     const auto cmdBufferPtr =
1364         vk::allocateCommandBuffer(vkd, device, cmdPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1365     const auto cmdBuffer = cmdBufferPtr.get();
1366     const auto barrier   = vk::makeMemoryBarrier(vk::VK_ACCESS_SHADER_WRITE_BIT, vk::VK_ACCESS_HOST_READ_BIT);
1367 
1368     // Create new pipeline layout that will be used during dispatch
1369     if (DPLM_DESTROY_AFTER_CREATE_COMPUTE_PIPELINES == mode)
1370         pipelineLayout = vk::createPipelineLayout(vkd, device, &pipelineLayoutInfo);
1371 
1372     vk::beginCommandBuffer(vkd, cmdBuffer);
1373     vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, pipeline.get());
1374     vkd.cmdBindDescriptorSets(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout.get(), 0u, 1u,
1375                               &descriptorSet.get(), 0u, nullptr);
1376     vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), vk::VK_SHADER_STAGE_COMPUTE_BIT, 0u,
1377                          static_cast<uint32_t>(sizeof(kBaseValue)), &kBaseValue);
1378     vkd.cmdDispatch(cmdBuffer, kBufferElements, 1u, 1u);
1379     vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u,
1380                            &barrier, 0u, nullptr, 0u, nullptr);
1381     vk::endCommandBuffer(vkd, cmdBuffer);
1382 
1383     // Delete pipeline layout just after recording command buffer - this is what the test is for
1384     if (DPLM_DESTROY_AFTER_END_COMMAND_BUFFER == mode)
1385         pipelineLayout = decltype(pipelineLayout)();
1386 
1387     // Submit commands.
1388     vk::submitCommandsAndWait(vkd, device, queue, cmdBuffer);
1389 
1390     // Check buffer.
1391     vk::invalidateAlloc(vkd, device, bufferAlloc);
1392     std::vector<uint32_t> outputData(kBufferElements);
1393     deMemcpy(outputData.data(), bufferPtr, kBufferSize);
1394 
1395     for (uint32_t i = 0; i < kBufferElements; ++i)
1396     {
1397         // This matches what the shader should calculate.
1398         const auto expectedValue = kInitialValue + kBaseValue + i;
1399         if (outputData[i] != expectedValue)
1400         {
1401             std::ostringstream msg;
1402             msg << "Unexpected value at buffer position " << i << ": expected " << expectedValue << " but found "
1403                 << outputData[i];
1404             return tcu::TestStatus::fail(msg.str());
1405         }
1406     }
1407 
1408     return tcu::TestStatus::pass("Pass");
1409 }
1410 
destroyAfterEndCommndBufferTest(Context & context)1411 tcu::TestStatus destroyAfterEndCommndBufferTest(Context &context)
1412 {
1413     return destroyEarlyTest(context, DPLM_DESTROY_AFTER_END_COMMAND_BUFFER);
1414 }
1415 
destroyAfterCreateComputePipelineTest(Context & context)1416 tcu::TestStatus destroyAfterCreateComputePipelineTest(Context &context)
1417 {
1418     return destroyEarlyTest(context, DPLM_DESTROY_AFTER_CREATE_COMPUTE_PIPELINES);
1419 }
1420 
destroyAfterCreateGraphicsPipelineTest(Context & context)1421 tcu::TestStatus destroyAfterCreateGraphicsPipelineTest(Context &context)
1422 {
1423     return drawTriangleTest(context, DTM_DESTROY_PIPELINE_LAYOUT_AFTER_CREATING_PIPELINE);
1424 }
1425 
1426 #ifndef CTS_USES_VULKANSC
1427 
createSimpleGraphicsPipelineInvalidPointers(const DeviceInterface & vk,const VkDevice & device,uint32_t numShaderStages,const VkPipelineShaderStageCreateInfo * shaderStageCreateInfos,VkPipelineLayout pipelineLayout,VkRenderPass renderPass,de::SharedPtr<vk::ResourceInterface> resourceInterface)1428 Move<VkPipeline> createSimpleGraphicsPipelineInvalidPointers(
1429     const DeviceInterface &vk, const VkDevice &device, uint32_t numShaderStages,
1430     const VkPipelineShaderStageCreateInfo *shaderStageCreateInfos, VkPipelineLayout pipelineLayout,
1431     VkRenderPass renderPass, de::SharedPtr<vk::ResourceInterface> resourceInterface)
1432 {
1433 #ifndef CTS_USES_VULKANSC
1434     DE_UNREF(resourceInterface);
1435 #endif // CTS_USES_VULKANSC
1436 
1437     const void *invalidPointer = reinterpret_cast<void *>(~(0));
1438 
1439     const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = {
1440         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType                             sType;
1441         DE_NULL,                                                   // const void*                                 pNext;
1442         (VkPipelineVertexInputStateCreateFlags)0,                  // VkPipelineVertexInputStateCreateFlags       flags;
1443         0u,      // uint32_t                                    vertexBindingDescriptionCount;
1444         DE_NULL, // const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
1445         0u,      // uint32_t                                    vertexAttributeDescriptionCount;
1446         (const VkVertexInputAttributeDescription *)
1447             invalidPointer // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
1448     };
1449 
1450     const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo = {
1451         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType                            sType;
1452         DE_NULL,                                    // const void*                                pNext;
1453         (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags    flags;
1454         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,       // VkPrimitiveTopology                        topology;
1455         VK_FALSE // VkBool32                                   primitiveRestartEnable;
1456     };
1457 
1458     // Disable rasterization to test unused structs
1459     const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo = {
1460         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType                            sType;
1461         DE_NULL,                                                    // const void*                                pNext;
1462         (VkPipelineRasterizationStateCreateFlags)0,                 // VkPipelineRasterizationStateCreateFlags    flags;
1463         VK_FALSE,                // VkBool32                                   depthClampEnable;
1464         VK_TRUE,                 // VkBool32                                   rasterizerDiscardEnable;
1465         VK_POLYGON_MODE_FILL,    // VkPolygonMode                              polygonMode;
1466         VK_CULL_MODE_BACK_BIT,   // VkCullModeFlags                            cullMode;
1467         VK_FRONT_FACE_CLOCKWISE, // VkFrontFace                                frontFace;
1468         VK_FALSE,                // VkBool32                                   depthBiasEnable;
1469         0.0f,                    // float                                      depthBiasConstantFactor;
1470         0.0f,                    // float                                      depthBiasClamp;
1471         0.0f,                    // float                                      depthBiasSlopeFactor;
1472         1.0f                     // float                                      lineWidth;
1473     };
1474 
1475     const VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo = {
1476         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType                                  sType;
1477         DE_NULL,                                         // const void*                                      pNext;
1478         (VkPipelineCreateFlags)0,                        // VkPipelineCreateFlags                            flags;
1479         numShaderStages,                                 // uint32_t                                         stageCount;
1480         shaderStageCreateInfos,                          // const VkPipelineShaderStageCreateInfo*           pStages;
1481         &vertexInputStateCreateInfo,   // const VkPipelineVertexInputStateCreateInfo*      pVertexInputState;
1482         &inputAssemblyStateCreateInfo, // const VkPipelineInputAssemblyStateCreateInfo*    pInputAssemblyState;
1483         DE_NULL,                       // const VkPipelineTessellationStateCreateInfo*     pTessellationState;
1484         (const VkPipelineViewportStateCreateInfo *)
1485             invalidPointer,            // const VkPipelineViewportStateCreateInfo*         pViewportState;
1486         &rasterizationStateCreateInfo, // const VkPipelineRasterizationStateCreateInfo*    pRasterizationState;
1487         (const VkPipelineMultisampleStateCreateInfo *)
1488             invalidPointer, // const VkPipelineMultisampleStateCreateInfo*      pMultisampleState;
1489         (const VkPipelineDepthStencilStateCreateInfo *)
1490             invalidPointer, // const VkPipelineDepthStencilStateCreateInfo*     pDepthStencilState;
1491         (const VkPipelineColorBlendStateCreateInfo *)
1492             invalidPointer, // const VkPipelineColorBlendStateCreateInfo*       pColorBlendState;
1493         DE_NULL,            // const VkPipelineDynamicStateCreateInfo*          pDynamicState;
1494         pipelineLayout,     // VkPipelineLayout                                 layout;
1495         renderPass,         // VkRenderPass                                     renderPass;
1496         0u,                 // uint32_t                                         subpass;
1497         DE_NULL,            // VkPipeline                                       basePipelineHandle;
1498         0                   // int                                              basePipelineIndex;
1499     };
1500 
1501     const VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {
1502         VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType               sType;
1503         DE_NULL,                                      // const void*                   pNext;
1504 #ifndef CTS_USES_VULKANSC
1505         (VkPipelineCacheCreateFlags)0u, // VkPipelineCacheCreateFlags    flags;
1506         0,                              // size_t                        initialDataSize;
1507         DE_NULL                         // const void*                   pInitialData;
1508 #else
1509         VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
1510             VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT, // VkPipelineCacheCreateFlags    flags;
1511         resourceInterface->getCacheDataSize(),                    // uintptr_t                     initialDataSize;
1512         invalidPointer                                            // const void*                   pInitialData;
1513 #endif // CTS_USES_VULKANSC
1514     };
1515 
1516     const Unique<VkPipelineCache> pipelineCache(createPipelineCache(vk, device, &pipelineCacheCreateInfo));
1517 
1518     return createGraphicsPipeline(vk, device, pipelineCache.get(), &graphicsPipelineCreateInfo);
1519 }
1520 
pipelineInvalidPointersUnusedStructsTest(Context & context,VkPipelineBindPoint bindPoint)1521 tcu::TestStatus pipelineInvalidPointersUnusedStructsTest(Context &context, VkPipelineBindPoint bindPoint)
1522 {
1523     const DeviceInterface &vk       = context.getDeviceInterface();
1524     const VkDevice device           = context.getDevice();
1525     const VkQueue queue             = context.getUniversalQueue();
1526     const uint32_t queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1527     const bool isGraphics           = (bindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS);
1528     const void *invalidPointer      = reinterpret_cast<void *>(~(0));
1529 
1530     const VkCommandPoolCreateInfo commandPoolParams = {
1531         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType             sType;
1532         DE_NULL,                                    // const void*                 pNext;
1533         (VkCommandPoolCreateFlags)0u,               // VkCommandPoolCreateFlags    flags;
1534         queueFamilyIndex                            // uint32_t                    queueFamilyIndex;
1535     };
1536 
1537     const Unique<VkCommandPool> commandPool(createCommandPool(vk, device, &commandPoolParams, DE_NULL));
1538     const Unique<VkCommandBuffer> commandBuffer(createCommandBuffer(vk, device, commandPool.get()));
1539 
1540     // Begin command buffer.
1541     {
1542         const VkCommandBufferBeginInfo commandBufferBeginInfo = {
1543             VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType                          sType;
1544             DE_NULL,                                     // const void*                              pNext;
1545             VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags                flags;
1546             DE_NULL                                      // const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
1547         };
1548 
1549         VK_CHECK(vk.beginCommandBuffer(commandBuffer.get(), &commandBufferBeginInfo));
1550     }
1551 
1552     // These will only be used for graphics pipelines.
1553     Move<VkRenderPass> renderPass;
1554     Move<VkFramebuffer> frameBuffer;
1555 
1556     {
1557         const VkSubpassDescription subpassDescription = {
1558             (VkSubpassDescriptionFlags)0u,                 // VkSubpassDescriptionFlags       flags;
1559             VK_PIPELINE_BIND_POINT_GRAPHICS,               // VkPipelineBindPoint             pipelineBindPoint
1560             0u,                                            // uint32_t                        inputAttachmentCount
1561             (const VkAttachmentReference *)invalidPointer, // const VkAttachmentReference*    pInputAttachments
1562             0u,                                            // uint32_t                        colorAttachmentCount
1563             (const VkAttachmentReference *)invalidPointer, // const VkAttachmentReference*    pColorAttachments
1564             DE_NULL,                                       // const VkAttachmentReference*    pResolveAttachments
1565             DE_NULL,                                       // const VkAttachmentReference*    pDepthStencilAttachment
1566             0u,                                            // uint32_t                        preserveAttachmentCount
1567             (const uint32_t *)invalidPointer               // const uint32_t*                 pPreserveAttachments
1568         };
1569 
1570         const VkRenderPassCreateInfo renderPassCreateInfo = {
1571             VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,       // VkStructureType                   sType;
1572             DE_NULL,                                         // const void*                       pNext;
1573             (VkRenderPassCreateFlags)0u,                     // VkRenderPassCreateFlags           flags;
1574             0u,                                              // uint32_t                          attachmentCount
1575             (const VkAttachmentDescription *)invalidPointer, // const VkAttachmentDescription*    pAttachments
1576             1u,                                              // uint32_t                          subpassCount
1577             &subpassDescription,                             // const VkSubpassDescription*       pSubpasses
1578             0u,                                              // uint32_t                          dependencyCount
1579             (const VkSubpassDependency *)invalidPointer      // const VkSubpassDependency*        pDependencies
1580         };
1581         renderPass = createRenderPass(vk, device, &renderPassCreateInfo);
1582 
1583         const VkFramebufferCreateInfo framebufferCreateInfo = {
1584             VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType             sType;
1585             DE_NULL,                                   // const void*                 pNext;
1586             (VkFramebufferCreateFlags)0u,              // VkFramebufferCreateFlags    flags;
1587             renderPass.get(),                          // VkRenderPass                renderPass;
1588             0u,                                        // uint32_t                    attachmentCount;
1589             (const VkImageView *)invalidPointer,       // const VkImageView*          pAttachments;
1590             256u,                                      // uint32_t                    width;
1591             256u,                                      // uint32_t                    height;
1592             1u                                         // uint32_t                    layers;
1593         };
1594 
1595         frameBuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
1596     }
1597 
1598     Move<VkPipelineLayout> pipelineLayout;
1599     {
1600         const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
1601             VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType                 sType;
1602             DE_NULL,                                       // const void*                     pNext;
1603             (VkPipelineLayoutCreateFlags)0u,               // VkPipelineLayoutCreateFlags     flags;
1604             0u,                                            // uint32_t                        setLayoutCount;
1605             (const VkDescriptorSetLayout *)invalidPointer, // const VkDescriptorSetLayout*    pSetLayouts;
1606             0u,                                            // uint32_t                        pushConstantRangeCount;
1607             (const VkPushConstantRange *)invalidPointer    // const VkPushConstantRange*      pPushConstantRanges;
1608         };
1609 
1610         pipelineLayout = vk::createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
1611     }
1612 
1613     std::vector<Move<VkShaderModule>> shaderModules;
1614     Move<VkPipeline> pipeline;
1615 
1616     if (isGraphics)
1617     {
1618         shaderModules.push_back(createShaderModule(vk, device, context.getBinaryCollection().get("vertex"), 0));
1619 
1620         const VkPipelineShaderStageCreateInfo shaderStageCreateInfos[] = {{
1621             VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType                     sType;
1622             DE_NULL,                                             // const void*                         pNext;
1623             (VkPipelineShaderStageCreateFlags)0,                 // VkPipelineShaderStageCreateFlags    flags;
1624             VK_SHADER_STAGE_VERTEX_BIT,                          // VkShaderStageFlagBits               stage;
1625             shaderModules[0].get(),                              // VkShaderModule                      shader;
1626             "main",                                              // const char*                         pName;
1627             DE_NULL, // const VkSpecializationInfo*         pSpecializationInfo;
1628         }};
1629 
1630         pipeline = createSimpleGraphicsPipelineInvalidPointers(vk, device, DE_LENGTH_OF_ARRAY(shaderStageCreateInfos),
1631                                                                shaderStageCreateInfos, *pipelineLayout,
1632                                                                renderPass.get(), context.getResourceInterface());
1633     }
1634     else
1635     {
1636         shaderModules.push_back(createShaderModule(vk, device, context.getBinaryCollection().get("compute"), 0));
1637 
1638         const VkPipelineShaderStageCreateInfo shaderStageCreateInfo = {
1639             VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType                     sType;
1640             DE_NULL,                                             // const void*                         pNext;
1641             (VkPipelineShaderStageCreateFlags)0,                 // VkPipelineShaderStageCreateFlags    flags;
1642             VK_SHADER_STAGE_COMPUTE_BIT,                         // VkShaderStageFlagBits               stage;
1643             shaderModules[0].get(),                              // VkShaderModule                      shader;
1644             "main",                                              // const char*                         pName;
1645             DE_NULL, // const VkSpecializationInfo*         pSpecializationInfo;
1646         };
1647 
1648         const VkComputePipelineCreateInfo computePipelineCreateInfo = {
1649             VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType                    sType;
1650             DE_NULL,                                        // const void*                        pNext
1651             (VkPipelineCreateFlags)0,                       // VkPipelineCreateFlags              flags
1652             shaderStageCreateInfo,                          // VkPipelineShaderStageCreateInfo    stage
1653             *pipelineLayout,                                // VkPipelineLayout                   layout
1654             DE_NULL,                                        // VkPipeline                         basePipelineHandle
1655             0                                               // int                                basePipelineIndex
1656         };
1657 
1658         pipeline = createComputePipeline(vk, device, DE_NULL, &computePipelineCreateInfo);
1659     }
1660 
1661     if (isGraphics)
1662     {
1663         beginRenderPass(vk, commandBuffer.get(), renderPass.get(), frameBuffer.get(), makeRect2D(0, 0, 256u, 256u),
1664                         tcu::Vec4(0.25f, 0.25f, 0.25f, 0.0f));
1665     }
1666     vk.cmdBindPipeline(commandBuffer.get(), bindPoint, pipeline.get());
1667 
1668     if (isGraphics)
1669     {
1670         vk.cmdDraw(commandBuffer.get(), 1u, 1u, 0u, 0u);
1671         vk.cmdEndRenderPass(commandBuffer.get());
1672     }
1673     else
1674     {
1675         vk.cmdDispatch(commandBuffer.get(), 1u, 1u, 1u);
1676     }
1677     vk.endCommandBuffer(commandBuffer.get());
1678 
1679     const VkSubmitInfo submitInfo = {
1680         VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType                sType;
1681         DE_NULL,                       // const void*                    pNext;
1682         0u,                            // uint32_t                       waitSemaphoreCount;
1683         DE_NULL,                       // const VkSemaphore*             pWaitSemaphores;
1684         DE_NULL,                       // const VkPipelineStageFlags*    pWaitDstStageMask;
1685         1u,                            // uint32_t                       commandBufferCount;
1686         &commandBuffer.get(),          // const VkCommandBuffer*         pCommandBuffers;
1687         0u,                            // uint32_t                       signalSemaphoreCount;
1688         DE_NULL                        // const VkSemaphore*             pSignalSemaphores;
1689     };
1690 
1691     VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, DE_NULL));
1692     VK_CHECK(vk.queueWaitIdle(queue));
1693 
1694     // Test should always pass
1695     return tcu::TestStatus::pass("Pass");
1696 }
1697 
createPipelineInvalidPointersUnusedStructsGraphicsSource(SourceCollections & dst)1698 void createPipelineInvalidPointersUnusedStructsGraphicsSource(SourceCollections &dst)
1699 {
1700     dst.glslSources.add("vertex") << glu::VertexSource("#version 450\n"
1701                                                        "\n"
1702                                                        "void main (void)\n"
1703                                                        "{\n"
1704                                                        "   gl_Position = vec4(1.0f);\n"
1705                                                        "}\n");
1706 
1707     dst.glslSources.add("fragment") << glu::FragmentSource("#version 450\n"
1708                                                            "\n"
1709                                                            "void main (void)\n"
1710                                                            "{\n"
1711                                                            "}\n");
1712 }
1713 
pipelineInvalidPointersUnusedStructsGraphicsTest(Context & context)1714 tcu::TestStatus pipelineInvalidPointersUnusedStructsGraphicsTest(Context &context)
1715 {
1716     return pipelineInvalidPointersUnusedStructsTest(context, VK_PIPELINE_BIND_POINT_GRAPHICS);
1717 }
1718 
createPipelineInvalidPointersUnusedStructsComputeSource(SourceCollections & dst)1719 void createPipelineInvalidPointersUnusedStructsComputeSource(SourceCollections &dst)
1720 {
1721     dst.glslSources.add("compute") << glu::ComputeSource(
1722         "#version 450\n"
1723         "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1724         "void main (void)\n"
1725         "{\n"
1726         "}\n");
1727 }
1728 
pipelineInvalidPointersUnusedStructsComputeTest(Context & context)1729 tcu::TestStatus pipelineInvalidPointersUnusedStructsComputeTest(Context &context)
1730 {
1731     return pipelineInvalidPointersUnusedStructsTest(context, VK_PIPELINE_BIND_POINT_COMPUTE);
1732 }
1733 
1734 #endif // CTS_USES_VULKANSC
1735 
createrenderpassTests(tcu::TestContext & testCtx)1736 tcu::TestCaseGroup *createrenderpassTests(tcu::TestContext &testCtx)
1737 {
1738     de::MovePtr<tcu::TestCaseGroup> renderPassTests(new tcu::TestCaseGroup(testCtx, "renderpass"));
1739 
1740     // Draw after destroying the renderpass used to create a pipeline
1741     addFunctionCaseWithPrograms(renderPassTests.get(), "destroy_pipeline_renderpass", checkSupport,
1742                                 createDrawTriangleSource, renderpassLifetimeTest);
1743     // Use a render pass with a framebuffer that was created using another compatible render pass
1744     addFunctionCase(renderPassTests.get(), "framebuffer_compatible_renderpass", checkSupport,
1745                     framebufferCompatibleRenderPassTest);
1746 
1747     return renderPassTests.release();
1748 }
1749 
createPipelineLayoutLifetimeTests(tcu::TestContext & testCtx)1750 tcu::TestCaseGroup *createPipelineLayoutLifetimeTests(tcu::TestContext &testCtx)
1751 {
1752     de::MovePtr<tcu::TestCaseGroup> pipelineLayoutLifetimeTests(new tcu::TestCaseGroup(testCtx, "lifetime"));
1753 
1754     addFunctionCaseWithPrograms(pipelineLayoutLifetimeTests.get(), "graphics", checkSupport,
1755                                 createPipelineLayoutLifetimeGraphicsSource, pipelineLayoutLifetimeGraphicsTest);
1756     addFunctionCaseWithPrograms(pipelineLayoutLifetimeTests.get(), "compute", checkSupport,
1757                                 createPipelineLayoutLifetimeComputeSource, pipelineLayoutLifetimeComputeTest);
1758     addFunctionCaseWithPrograms(pipelineLayoutLifetimeTests.get(), "destroy_after_end", destroyEarlyComputeSource,
1759                                 destroyAfterEndCommndBufferTest);
1760     addFunctionCaseWithPrograms(pipelineLayoutLifetimeTests.get(), "destroy_after_compute_pipeline_construction",
1761                                 checkMaintenance4Support, destroyEarlyComputeSource,
1762                                 destroyAfterCreateComputePipelineTest);
1763     addFunctionCaseWithPrograms(pipelineLayoutLifetimeTests.get(), "destroy_after_graphics_pipeline_construction",
1764                                 checkMaintenance4Support, createDrawTriangleSource,
1765                                 destroyAfterCreateGraphicsPipelineTest);
1766 
1767     return pipelineLayoutLifetimeTests.release();
1768 }
1769 
createPipelineLayoutTests(tcu::TestContext & testCtx)1770 tcu::TestCaseGroup *createPipelineLayoutTests(tcu::TestContext &testCtx)
1771 {
1772     de::MovePtr<tcu::TestCaseGroup> pipelineLayoutTests(new tcu::TestCaseGroup(testCtx, "pipeline_layout"));
1773 
1774     pipelineLayoutTests->addChild(createPipelineLayoutLifetimeTests(testCtx));
1775 
1776     return pipelineLayoutTests.release();
1777 }
1778 
1779 #ifndef CTS_USES_VULKANSC
createPipelineInvalidPointersUnusedStructsTests(tcu::TestContext & testCtx)1780 tcu::TestCaseGroup *createPipelineInvalidPointersUnusedStructsTests(tcu::TestContext &testCtx)
1781 {
1782     de::MovePtr<tcu::TestCaseGroup> pipelineInvalidPointersUnusedStructsTests(
1783         new tcu::TestCaseGroup(testCtx, "pipeline_invalid_pointers_unused_structs"));
1784 
1785     addFunctionCaseWithPrograms(pipelineInvalidPointersUnusedStructsTests.get(), "graphics", checkSupport,
1786                                 createPipelineInvalidPointersUnusedStructsGraphicsSource,
1787                                 pipelineInvalidPointersUnusedStructsGraphicsTest);
1788     addFunctionCaseWithPrograms(pipelineInvalidPointersUnusedStructsTests.get(), "compute", checkSupport,
1789                                 createPipelineInvalidPointersUnusedStructsComputeSource,
1790                                 pipelineInvalidPointersUnusedStructsComputeTest);
1791 
1792     return pipelineInvalidPointersUnusedStructsTests.release();
1793 }
1794 #endif // CTS_USES_VULKANSC
1795 
1796 } // namespace
1797 
createPipelineTests(tcu::TestContext & testCtx)1798 tcu::TestCaseGroup *createPipelineTests(tcu::TestContext &testCtx)
1799 {
1800     de::MovePtr<tcu::TestCaseGroup> pipelineTests(new tcu::TestCaseGroup(testCtx, "pipeline"));
1801 
1802     pipelineTests->addChild(createrenderpassTests(testCtx));
1803     pipelineTests->addChild(createPipelineLayoutTests(testCtx));
1804 #ifndef CTS_USES_VULKANSC
1805     pipelineTests->addChild(createPipelineInvalidPointersUnusedStructsTests(testCtx));
1806 #endif // CTS_USES_VULKANSC
1807 
1808     return pipelineTests.release();
1809 }
1810 
1811 } // namespace api
1812 } // namespace vkt
1813