Test pipeline layout lifetime after ending cmd buffer
authorRicardo Garcia <rgarcia@igalia.com>
Thu, 2 Jul 2020 15:29:10 +0000 (17:29 +0200)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Fri, 17 Jul 2020 08:53:07 +0000 (04:53 -0400)
This commit adds a new test to check the lifetime of a pipeline layout
object does not go beyond ending a command buffer that uses it. For
that, a pipeline layout object is destroyed just after ending a command
buffer that uses the layout both when binding a descriptor set and when
recording push constant values.

In addition, the code for other previously-existing pipeline layout
API tests (compute and graphics) has been unified and fixed by removing
an unneeded barrier and avoid requesting unneeded transfer image usage
flags that were unused and not checked to be available.

New test:
dEQP-VK.api.pipeline.pipeline_layout.lifetime.destroy_after_end

Affected tests:
dEQP-VK.api.pipeline.*

Components: Vulkan
VK-GL-CTS issue: 2398

Change-Id: Ie8709ce0f1407aac0380227b1f3548220ceb356d

android/cts/master/vk-master-2020-03-01.txt
android/cts/master/vk-master.txt
external/vulkancts/modules/vulkan/api/vktApiPipelineTests.cpp
external/vulkancts/mustpass/master/vk-default.txt

index d1e1cec..97ec33e 100644 (file)
@@ -52533,6 +52533,7 @@ dEQP-VK.api.external.memory.dma_buf.dedicated.image.info
 dEQP-VK.api.external.memory.dma_buf.dedicated.image.bind_export_import_bind
 dEQP-VK.api.external.memory.dma_buf.dedicated.image.export_bind_import_bind
 dEQP-VK.api.external.memory.dma_buf.dedicated.image.export_import_bind_bind
+dEQP-VK.api.pipeline.pipeline_layout.lifetime.destroy_after_end
 dEQP-VK.api.tooling_info.validate_getter
 dEQP-VK.api.tooling_info.validate_tools_properties
 dEQP-VK.api.tooling_info.validate_instance_layers
index d3c6b34..60093e7 100644 (file)
@@ -140455,6 +140455,7 @@ dEQP-VK.api.pipeline.renderpass.destroy_pipeline_renderpass
 dEQP-VK.api.pipeline.renderpass.framebuffer_compatible_renderpass
 dEQP-VK.api.pipeline.pipeline_layout.lifetime.graphics
 dEQP-VK.api.pipeline.pipeline_layout.lifetime.compute
+dEQP-VK.api.pipeline.pipeline_layout.lifetime.destroy_after_end
 dEQP-VK.api.invariance.random
 dEQP-VK.api.tooling_info.validate_getter
 dEQP-VK.api.tooling_info.validate_tools_properties
index 058f283..5533e49 100644 (file)
 #include "vkTypeUtil.hpp"
 #include "vkCmdUtil.hpp"
 #include "vkObjUtil.hpp"
+#include "vkBarrierUtil.hpp"
+#include "vkBufferWithMemory.hpp"
+#include "vkBuilderUtil.hpp"
+
+#include <vector>
+#include <sstream>
 
 namespace vkt
 {
@@ -47,16 +53,17 @@ using namespace vk;
 
 VkFormat getRenderTargetFormat (const InstanceInterface& vk, const VkPhysicalDevice& device)
 {
-       VkFormatProperties formatProperties;
+       const VkFormatFeatureFlags      featureFlags            = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
+       VkFormatProperties                      formatProperties;
 
        vk.getPhysicalDeviceFormatProperties(device, VK_FORMAT_B8G8R8A8_UNORM, &formatProperties);
 
-       if (formatProperties.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT || formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)
+       if ((formatProperties.linearTilingFeatures & featureFlags) || (formatProperties.optimalTilingFeatures & featureFlags))
                return VK_FORMAT_B8G8R8A8_UNORM;
 
        vk.getPhysicalDeviceFormatProperties(device, VK_FORMAT_R8G8B8A8_UNORM, &formatProperties);
 
-       if (formatProperties.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT || formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)
+       if ((formatProperties.linearTilingFeatures & featureFlags) || formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)
                return VK_FORMAT_R8G8B8A8_UNORM;
 
        TCU_THROW(NotSupportedError, "Device does not support VK_FORMAT_B8G8R8A8_UNORM nor VK_FORMAT_R8G8B8A8_UNORM");
@@ -108,9 +115,7 @@ tcu::TestStatus renderpassLifetimeTest (Context& context)
                1u,                                                                             // deUint32                 arrayLayers;
                VK_SAMPLE_COUNT_1_BIT,                                  // VkSampleCountFlagBits    samples;
                imageTiling,                                                    // VkImageTiling            tiling;
-               VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
-               | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
-               | VK_IMAGE_USAGE_TRANSFER_DST_BIT,              // VkImageUsageFlags        usage;
+               VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,    // VkImageUsageFlags        usage;
                VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode            sharingMode;
                0u,                                                                             // deUint32                 queueFamilyIndexCount;
                DE_NULL,                                                                // const deUint32*          pQueueFamilyIndices;
@@ -145,30 +150,6 @@ tcu::TestStatus renderpassLifetimeTest (Context& context)
 
        VK_CHECK(vk.beginCommandBuffer(commandBuffer.get(), &commandBufferBeginInfo));
 
-       {
-               const VkImageMemoryBarrier imageMemoryBarrier =
-               {
-                       VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType            sType;
-                       DE_NULL,                                                                        // const void*                pNext;
-                       (VkAccessFlags)0u,                                                      // VkAccessFlags              srcAccessMask;
-                       VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags              dstAccessMask;
-                       VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout              oldLayout;
-                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout              newLayout;
-                       0u,                                                                                     // deUint32                   srcQueueFamilyIndex;
-                       0u,                                                                                     // deUint32                   dstQueueFamilyIndex;
-                       attachmentImage.get(),                                          // VkImage                    image;
-                       {
-                               VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags    aspectMask;
-                               0u,                                                             // deUint32              baseMipLevel;
-                               1u,                                                             // deUint32              levelCount;
-                               0u,                                                             // deUint32              baseArrayLayer;(
-                               1u                                                              // deUint32              layerCount;
-                       }                                                                                       // VkImageSubresourceRange    subresourceRange;
-               };
-
-               vk.cmdPipelineBarrier(commandBuffer.get(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlagBits)0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageMemoryBarrier);
-       }
-
        const VkAttachmentDescription                                   attachmentDescription                   =
        {
                (VkAttachmentDescriptionFlags)0u,                       // VkAttachmentDescriptionFlags    flags;
@@ -545,9 +526,7 @@ tcu::TestStatus framebufferCompatibleRenderPassTest (Context& context)
                1u,                                                                             // deUint32                 arrayLayers;
                VK_SAMPLE_COUNT_1_BIT,                                  // VkSampleCountFlagBits    samples;
                imageTiling,                                                    // VkImageTiling            tiling;
-               VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
-               | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
-               | VK_IMAGE_USAGE_TRANSFER_DST_BIT,              // VkImageUsageFlags        usage;
+               VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,    // VkImageUsageFlags        usage;
                VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode            sharingMode;
                0u,                                                                             // deUint32                 queueFamilyIndexCount;
                DE_NULL,                                                                // const deUint32*          pQueueFamilyIndices;
@@ -733,7 +712,7 @@ Move<VkPipeline> createSimpleGraphicsPipeline (const DeviceInterface& vk, const
                0.0f,                                                                                                           // float                                      depthBiasConstantFactor;
                0.0f,                                                                                                           // float                                      depthBiasClamp;
                0.0f,                                                                                                           // float                                      depthBiasSlopeFactor;
-               1.0f                                                                                                            // float                                       ineWidth;
+               1.0f                                                                                                            // float                                      lineWidth;
        };
 
        const VkPipelineMultisampleStateCreateInfo              multisampleStateCreateInfo              =
@@ -825,35 +804,14 @@ Move<VkPipeline> createSimpleGraphicsPipeline (const DeviceInterface& vk, const
        return createGraphicsPipeline(vk, device, pipelineCache.get(), &graphicsPipelineCreateInfo);
 }
 
-void createPipelineLayoutLifetimeGraphicsSource (SourceCollections& dst)
-{
-       dst.glslSources.add("vertex") << glu::VertexSource(
-               "#version 450\n"
-               "\n"
-               "void main (void)\n"
-               "{\n"
-               "   gl_Position = vec4(1);\n"
-               "}\n");
-
-       dst.glslSources.add("fragment") << glu::FragmentSource(
-               "#version 450\n"
-               "\n"
-               "layout(location=0) out vec4 x;\n"
-               "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
-               "void main (void)\n"
-               "{\n"
-               "   x = vec4(bar.y);\n"
-               "}\n");
-}
-
-// This test has the same functionality as VkLayerTest.DescriptorSetCompatibility
-tcu::TestStatus pipelineLayoutLifetimeGraphicsTest (Context& context)
+tcu::TestStatus pipelineLayoutLifetimeTest (Context& context, VkPipelineBindPoint bindPoint)
 {
        const DeviceInterface&                                  vk                                                      = context.getDeviceInterface();
        const InstanceInterface&                                vki                                                     = context.getInstanceInterface();
        const VkDevice                                                  device                                          = context.getDevice();
        const VkPhysicalDevice                                  physicalDevice                          = context.getPhysicalDevice();
        const deUint32                                                  queueFamilyIndex                        = context.getUniversalQueueFamilyIndex();
+       const bool                                                              isGraphics                                      = (bindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS);
 
        const VkCommandPoolCreateInfo                   commandPoolParams                       =
        {
@@ -866,6 +824,7 @@ tcu::TestStatus pipelineLayoutLifetimeGraphicsTest (Context& context)
        const Unique<VkCommandPool>                             commandPool                                     (createCommandPool(vk, device, &commandPoolParams, DE_NULL));
        const Unique<VkCommandBuffer>                   commandBuffer                           (createCommandBuffer(vk, device, commandPool.get()));
 
+       // Begin command buffer.
        {
                const VkCommandBufferBeginInfo commandBufferBeginInfo =
                {
@@ -878,91 +837,99 @@ tcu::TestStatus pipelineLayoutLifetimeGraphicsTest (Context& context)
                VK_CHECK(vk.beginCommandBuffer(commandBuffer.get(), &commandBufferBeginInfo));
        }
 
-       const VkFormat                                                  format                                          = getRenderTargetFormat(vki, physicalDevice);
-       const VkFormatProperties                                formatProperties                        (getPhysicalDeviceFormatProperties(vki, physicalDevice, format));
-       const VkImageTiling                                             imageTiling                                     = (formatProperties.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? VK_IMAGE_TILING_LINEAR
-                                                                                                                                               : (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? VK_IMAGE_TILING_OPTIMAL
-                                                                                                                                               : VK_CORE_IMAGE_TILING_LAST;
+       // These will only be used for graphics pipelines.
+       Move<VkImage>                   attachmentImage;
+       de::MovePtr<Allocation> attachmentImageMemory;
+       Move<VkImageView>               attachmentImageView;
+       Move<VkRenderPass>              renderPass;
+       Move<VkFramebuffer>             frameBuffer;
 
-       const VkImageCreateInfo                                 imageCreateInfo                         =
+       if (isGraphics)
        {
-               VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType          sType;
-               DE_NULL,                                                                // const void*              pNext;
-               (VkImageCreateFlags)0u,                                 // VkImageCreateFlags       flags;
-               VK_IMAGE_TYPE_2D,                                               // VkImageType              imageType;
-               format,                                                                 // VkFormat                 format;
+               // Create image, render pass and framebuffer.
+               const VkFormat                          format                          = getRenderTargetFormat(vki, physicalDevice);
+               const VkFormatProperties        formatProperties        (getPhysicalDeviceFormatProperties(vki, physicalDevice, format));
+               const VkImageTiling                     imageTiling                     = (formatProperties.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? VK_IMAGE_TILING_LINEAR
+                                                                                                               : (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? VK_IMAGE_TILING_OPTIMAL
+                                                                                                               : VK_CORE_IMAGE_TILING_LAST;
+
+               const VkImageCreateInfo imageCreateInfo =
                {
-                       256u,   // deUint32    width;
-                       256u,   // deUint32    height;
-                       1u              // deUint32    depth;
-               },                                                                              // VkExtent3D               extent;
-               1u,                                                                             // deUint32                 mipLevels;
-               1u,                                                                             // deUint32                 arrayLayers;
-               VK_SAMPLE_COUNT_1_BIT,                                  // VkSampleCountFlagBits    samples;
-               imageTiling,                                                    // VkImageTiling            tiling;
-               VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
-               | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
-               | VK_IMAGE_USAGE_TRANSFER_DST_BIT,              // VkImageUsageFlags        usage;
-               VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode            sharingMode;
-               0u,                                                                             // deUint32                 queueFamilyIndexCount;
-               DE_NULL,                                                                // const deUint32*          pQueueFamilyIndices;
-               VK_IMAGE_LAYOUT_UNDEFINED                               // VkImageLayout            initialLayout;
-       };
+                       VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType          sType;
+                       DE_NULL,                                                                // const void*              pNext;
+                       (VkImageCreateFlags)0u,                                 // VkImageCreateFlags       flags;
+                       VK_IMAGE_TYPE_2D,                                               // VkImageType              imageType;
+                       format,                                                                 // VkFormat                 format;
+                       {
+                               256u,   // deUint32    width;
+                               256u,   // deUint32    height;
+                               1u              // deUint32    depth;
+                       },                                                                              // VkExtent3D               extent;
+                       1u,                                                                             // deUint32                 mipLevels;
+                       1u,                                                                             // deUint32                 arrayLayers;
+                       VK_SAMPLE_COUNT_1_BIT,                                  // VkSampleCountFlagBits    samples;
+                       imageTiling,                                                    // VkImageTiling            tiling;
+                       VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,    // VkImageUsageFlags        usage;
+                       VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode            sharingMode;
+                       0u,                                                                             // deUint32                 queueFamilyIndexCount;
+                       DE_NULL,                                                                // const deUint32*          pQueueFamilyIndices;
+                       VK_IMAGE_LAYOUT_UNDEFINED                               // VkImageLayout            initialLayout;
+               };
 
-       const Unique<VkImage>                                   attachmentImage                         (createImage(vk, device, &imageCreateInfo));
-       de::MovePtr<Allocation>                                 attachmentImageMemory           = context.getDefaultAllocator().allocate(getImageMemoryRequirements(vk, device, *attachmentImage), MemoryRequirement::Any);
+               attachmentImage                 = createImage(vk, device, &imageCreateInfo);
+               attachmentImageMemory   = context.getDefaultAllocator().allocate(getImageMemoryRequirements(vk, device, *attachmentImage), MemoryRequirement::Any);
 
-       VK_CHECK(vk.bindImageMemory(device, *attachmentImage, attachmentImageMemory->getMemory(), attachmentImageMemory->getOffset()));
+               VK_CHECK(vk.bindImageMemory(device, *attachmentImage, attachmentImageMemory->getMemory(), attachmentImageMemory->getOffset()));
 
-       changeColorAttachmentImageLayout(vk, commandBuffer.get(), attachmentImage.get());
+               changeColorAttachmentImageLayout(vk, commandBuffer.get(), attachmentImage.get());
 
-       const VkImageViewCreateInfo                             imageViewCreateInfo                     =
-       {
-               VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType            sType;
-               DE_NULL,                                                                        // const void*                pNext;
-               (VkImageViewCreateFlags)0u,                                     // VkImageViewCreateFlags     flags;
-               attachmentImage.get(),                                          // VkImage                    image;
-               VK_IMAGE_VIEW_TYPE_2D,                                          // VkImageViewType            viewType;
-               format,                                                                         // VkFormat                   format;
+               const VkImageViewCreateInfo imageViewCreateInfo =
                {
-                       VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle    r;
-                       VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle    g;
-                       VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle    b;
-                       VK_COMPONENT_SWIZZLE_A  // VkComponentSwizzle    a;
-               },                                                                                      // VkComponentMapping         components;
-               {
-                       VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags    aspectMask;
-                       0u,                                                     // deUint32              baseMipLevel;
-                       1u,                                                     // deUint32              levelCount;
-                       0u,                                                     // deUint32              baseArrayLayer;
-                       1u                                                      // deUint32              layerCount;
-               }                                                                                       // VkImageSubresourceRange    subresourceRange;
-       };
-
-       const Unique<VkImageView>                               attachmentImageView                     (createImageView(vk, device, &imageViewCreateInfo));
+                       VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType            sType;
+                       DE_NULL,                                                                        // const void*                pNext;
+                       (VkImageViewCreateFlags)0u,                                     // VkImageViewCreateFlags     flags;
+                       attachmentImage.get(),                                          // VkImage                    image;
+                       VK_IMAGE_VIEW_TYPE_2D,                                          // VkImageViewType            viewType;
+                       format,                                                                         // VkFormat                   format;
+                       {
+                               VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle    r;
+                               VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle    g;
+                               VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle    b;
+                               VK_COMPONENT_SWIZZLE_A  // VkComponentSwizzle    a;
+                       },                                                                                      // VkComponentMapping         components;
+                       {
+                               VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags    aspectMask;
+                               0u,                                                     // deUint32              baseMipLevel;
+                               1u,                                                     // deUint32              levelCount;
+                               0u,                                                     // deUint32              baseArrayLayer;
+                               1u                                                      // deUint32              layerCount;
+                       }                                                                                       // VkImageSubresourceRange    subresourceRange;
+               };
 
-       const Unique<VkRenderPass>                              renderPass                                      (createSimpleRenderPass(vk, device, format,
-                                                                                                                                                                                               VK_ATTACHMENT_LOAD_OP_CLEAR,
-                                                                                                                                                                                               VK_ATTACHMENT_LOAD_OP_DONT_CARE,
-                                                                                                                                                                                               VK_ATTACHMENT_STORE_OP_DONT_CARE,
-                                                                                                                                                                                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
+               attachmentImageView     = createImageView(vk, device, &imageViewCreateInfo);
+               renderPass                      = createSimpleRenderPass(vk, device, format,
+                                                                                                        VK_ATTACHMENT_LOAD_OP_CLEAR,
+                                                                                                        VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+                                                                                                        VK_ATTACHMENT_STORE_OP_DONT_CARE,
+                                                                                                        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
 
-       const VkFramebufferCreateInfo                   framebufferCreateInfo           =
-       {
-               VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,              // VkStructureType             sType;
-               DE_NULL,                                                                                // const void*                 pNext;
-               (VkFramebufferCreateFlags)0u,                                   // VkFramebufferCreateFlags    flags;
-               renderPass.get(),                                                               // VkRenderPass                renderPass;
-               1u,                                                                                             // deUint32                    attachmentCount;
-               &attachmentImageView.get(),                                             // const VkImageView*          pAttachments;
-               256u,                                                                                   // deUint32                    width;
-               256u,                                                                                   // deUint32                    height;
-               1u                                                                                              // deUint32                    layers;
-       };
+               const VkFramebufferCreateInfo framebufferCreateInfo =
+               {
+                       VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,              // VkStructureType             sType;
+                       DE_NULL,                                                                                // const void*                 pNext;
+                       (VkFramebufferCreateFlags)0u,                                   // VkFramebufferCreateFlags    flags;
+                       renderPass.get(),                                                               // VkRenderPass                renderPass;
+                       1u,                                                                                             // deUint32                    attachmentCount;
+                       &attachmentImageView.get(),                                             // const VkImageView*          pAttachments;
+                       256u,                                                                                   // deUint32                    width;
+                       256u,                                                                                   // deUint32                    height;
+                       1u                                                                                              // deUint32                    layers;
+               };
 
-       const Unique<VkFramebuffer>                             frameBuffer                                     (createFramebuffer(vk, device, &framebufferCreateInfo));
+               frameBuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
+       }
 
-       const VkDescriptorPoolSize                              descriptorPoolSizes[]           =
+       const VkDescriptorPoolSize descriptorPoolSizes[] =
        {
                {
                        VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,      // VkDescriptorType    type;
@@ -978,14 +945,14 @@ tcu::TestStatus pipelineLayoutLifetimeGraphicsTest (Context& context)
                }
        };
 
-       VkDescriptorPool                                                descriptorPool;
+       VkDescriptorPool descriptorPool;
        {
                const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo =
                {
                        VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,  // VkStructureType                sType;
                        DE_NULL,                                                                                // const void*                    pNext;
                        (VkDescriptorPoolCreateFlags)0u,                                // VkDescriptorPoolCreateFlags    flags;
-                       3,                                                                                              // deUint32                       maxSets;
+                       (isGraphics ? 3u : 5u),                                                 // deUint32                       maxSets;
                        DE_LENGTH_OF_ARRAY(descriptorPoolSizes),                // deUint32                       poolSizeCount;
                        descriptorPoolSizes                                                             // const VkDescriptorPoolSize*    pPoolSizes;
                };
@@ -993,7 +960,7 @@ tcu::TestStatus pipelineLayoutLifetimeGraphicsTest (Context& context)
                VK_CHECK(vk.createDescriptorPool(device, &descriptorPoolCreateInfo, DE_NULL, &descriptorPool));
        }
 
-       const VkDescriptorSetLayoutBinding              setLayoutBindingA[]                     =
+       const VkDescriptorSetLayoutBinding setLayoutBindingA[] =
        {
                {
                        0,                                                                      // deUint32              binding;
@@ -1004,18 +971,20 @@ tcu::TestStatus pipelineLayoutLifetimeGraphicsTest (Context& context)
                }
        };
 
-       const VkDescriptorSetLayoutBinding              setLayoutBindingB[]                     =
+       const auto shaderStage = (isGraphics ? VK_SHADER_STAGE_FRAGMENT_BIT : VK_SHADER_STAGE_COMPUTE_BIT);
+
+       const VkDescriptorSetLayoutBinding setLayoutBindingB[] =
        {
                {
                        0,                                                                      // deUint32              binding;
                        VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,      // VkDescriptorType      descriptorType;
                        5,                                                                      // deUint32              descriptorCount;
-                       VK_SHADER_STAGE_FRAGMENT_BIT,           // VkShaderStageFlags    stageFlags;
+                       shaderStage,                                            // VkShaderStageFlags    stageFlags;
                        DE_NULL                                                         // const VkSampler*      pImmutableSamplers;
                }
        };
 
-       const VkDescriptorSetLayoutBinding              setLayoutBindingC[]                     =
+       const VkDescriptorSetLayoutBinding setLayoutBindingC[] =
        {
                {
                        0,                                                                      // deUint32              binding;
@@ -1094,44 +1063,80 @@ tcu::TestStatus pipelineLayoutLifetimeGraphicsTest (Context& context)
                VK_CHECK(vk.createPipelineLayout(device, &pipelineLayoutCreateInfo, DE_NULL, &pipelineLayoutB));
        }
 
-       const Unique<VkShaderModule>                    vertexShaderModule                      (createShaderModule(vk, device, context.getBinaryCollection().get("vertex"), 0));
-       const Unique<VkShaderModule>                    fragmentShaderModule            (createShaderModule(vk, device, context.getBinaryCollection().get("fragment"), 0));
+       std::vector<Move<VkShaderModule>>       shaderModules;
+       Move<VkPipeline>                                        pipeline;
 
-       const VkPipelineShaderStageCreateInfo   shaderStageCreateInfos[]        =
+       if (isGraphics)
        {
+               shaderModules.push_back(createShaderModule(vk, device, context.getBinaryCollection().get("vertex"), 0));
+               shaderModules.push_back(createShaderModule(vk, device, context.getBinaryCollection().get("fragment"), 0));
+
+               const VkPipelineShaderStageCreateInfo   shaderStageCreateInfos[]        =
                {
-                       VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                     sType;
-                       DE_NULL,                                                                                                // const void*                         pNext;
-                       (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags    flags;
-                       VK_SHADER_STAGE_VERTEX_BIT,                                                             // VkShaderStageFlagBits               stage;
-                       vertexShaderModule.get(),                                                               // VkShaderModule                      shader;
-                       "main",                                                                                                 // const char*                         pName;
-                       DE_NULL,                                                                                                // const VkSpecializationInfo*         pSpecializationInfo;
-               },
+                       {
+                               VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                     sType;
+                               DE_NULL,                                                                                                // const void*                         pNext;
+                               (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags    flags;
+                               VK_SHADER_STAGE_VERTEX_BIT,                                                             // VkShaderStageFlagBits               stage;
+                               shaderModules[0].get(),                                                                 // VkShaderModule                      shader;
+                               "main",                                                                                                 // const char*                         pName;
+                               DE_NULL,                                                                                                // const VkSpecializationInfo*         pSpecializationInfo;
+                       },
+                       {
+                               VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                     sType;
+                               DE_NULL,                                                                                                // const void*                         pNext;
+                               (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags    flags;
+                               VK_SHADER_STAGE_FRAGMENT_BIT,                                                   // VkShaderStageFlagBits               stage;
+                               shaderModules[1].get(),                                                                 // VkShaderModule                      shader;
+                               "main",                                                                                                 // const char*                         pName;
+                               DE_NULL,                                                                                                // const VkSpecializationInfo*         pSpecializationInfo;
+                       }
+               };
+
+               pipeline = createSimpleGraphicsPipeline(vk, device, DE_LENGTH_OF_ARRAY(shaderStageCreateInfos), shaderStageCreateInfos, pipelineLayoutB, renderPass.get());
+       }
+       else
+       {
+               shaderModules.push_back(createShaderModule(vk, device, context.getBinaryCollection().get("compute"), 0));
+
+               const VkPipelineShaderStageCreateInfo   shaderStageCreateInfo           =
                {
                        VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                     sType;
                        DE_NULL,                                                                                                // const void*                         pNext;
                        (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags    flags;
-                       VK_SHADER_STAGE_FRAGMENT_BIT,                                                   // VkShaderStageFlagBits               stage;
-                       fragmentShaderModule.get(),                                                             // VkShaderModule                      shader;
+                       VK_SHADER_STAGE_COMPUTE_BIT,                                                    // VkShaderStageFlagBits               stage;
+                       shaderModules[0].get(),                                                         // VkShaderModule                      shader;
                        "main",                                                                                                 // const char*                         pName;
                        DE_NULL,                                                                                                // const VkSpecializationInfo*         pSpecializationInfo;
-               }
-       };
+               };
 
-       const Unique<VkPipeline>                                graphicsPipeline                        (createSimpleGraphicsPipeline(vk, device, DE_LENGTH_OF_ARRAY(shaderStageCreateInfos), shaderStageCreateInfos, pipelineLayoutB, renderPass.get()));
+               const VkComputePipelineCreateInfo               computePipelineCreateInfo       =
+               {
+                       VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType                    sType;
+                       DE_NULL,                                                                                // const void*                        pNext
+                       (VkPipelineCreateFlags)0,                                               // VkPipelineCreateFlags              flags
+                       shaderStageCreateInfo,                                                  // VkPipelineShaderStageCreateInfo    stage
+                       pipelineLayoutB,                                                                // VkPipelineLayout                   layout
+                       DE_NULL,                                                                                // VkPipeline                         basePipelineHandle
+                       0                                                                                               // int                                basePipelineIndex
+               };
 
-       beginRenderPass(vk, commandBuffer.get(), renderPass.get(), frameBuffer.get(), makeRect2D(0, 0, 256u, 256u), tcu::Vec4(0.25f, 0.25f, 0.25f, 0.0f));
+               pipeline = createComputePipeline(vk, device, DE_NULL, &computePipelineCreateInfo);
+       }
 
-       vk.cmdBindPipeline(commandBuffer.get(), VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
+       if (isGraphics)
+       {
+               beginRenderPass(vk, commandBuffer.get(), renderPass.get(), frameBuffer.get(), makeRect2D(0, 0, 256u, 256u), tcu::Vec4(0.25f, 0.25f, 0.25f, 0.0f));
+       }
+       vk.cmdBindPipeline(commandBuffer.get(), bindPoint, pipeline.get());
 
-       // Destroy the pipeline layout that was used to create the graphics pipeline
+       // Destroy the pipeline layout that was used to create the pipeline
        vk.destroyPipelineLayout(device, pipelineLayoutB, DE_NULL);
 
-       vk.cmdBindDescriptorSets(commandBuffer.get(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayoutAC.get(), 0u, DE_LENGTH_OF_ARRAY(setHandlesAC), setHandlesAC, 0u, DE_NULL);
-
-       vk.cmdBindDescriptorSets(commandBuffer.get(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayoutBC.get(), 1u, DE_LENGTH_OF_ARRAY(setHandlesC), setHandlesC, 0u, DE_NULL);
+       vk.cmdBindDescriptorSets(commandBuffer.get(), bindPoint, pipelineLayoutAC.get(), 0u, DE_LENGTH_OF_ARRAY(setHandlesAC), setHandlesAC, 0u, DE_NULL);
+       vk.cmdBindDescriptorSets(commandBuffer.get(), bindPoint, pipelineLayoutBC.get(), 1u, DE_LENGTH_OF_ARRAY(setHandlesC), setHandlesC, 0u, DE_NULL);
 
+       if (isGraphics)
        {
                const VkViewport        viewport        =
                {
@@ -1153,7 +1158,7 @@ tcu::TestStatus pipelineLayoutLifetimeGraphicsTest (Context& context)
                vk.cmdSetScissor(commandBuffer.get(), 0u, 1u, &scissor);
        }
 
-       vk.cmdBindDescriptorSets(commandBuffer.get(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayoutAC.get(), 0u, DE_LENGTH_OF_ARRAY(setHandlesAC), setHandlesAC, 0u, DE_NULL);
+       vk.cmdBindDescriptorSets(commandBuffer.get(), bindPoint, pipelineLayoutAC.get(), 0u, DE_LENGTH_OF_ARRAY(setHandlesAC), setHandlesAC, 0u, DE_NULL);
 
        vk.destroyDescriptorPool(device, descriptorPool, DE_NULL);
 
@@ -1161,6 +1166,33 @@ tcu::TestStatus pipelineLayoutLifetimeGraphicsTest (Context& context)
        return tcu::TestStatus::pass("Pass");
 }
 
+void createPipelineLayoutLifetimeGraphicsSource (SourceCollections& dst)
+{
+       dst.glslSources.add("vertex") << glu::VertexSource(
+               "#version 450\n"
+               "\n"
+               "void main (void)\n"
+               "{\n"
+               "   gl_Position = vec4(1);\n"
+               "}\n");
+
+       dst.glslSources.add("fragment") << glu::FragmentSource(
+               "#version 450\n"
+               "\n"
+               "layout(location=0) out vec4 x;\n"
+               "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n"
+               "void main (void)\n"
+               "{\n"
+               "   x = vec4(bar.y);\n"
+               "}\n");
+}
+
+// This test has the same functionality as VkLayerTest.DescriptorSetCompatibility
+tcu::TestStatus pipelineLayoutLifetimeGraphicsTest (Context& context)
+{
+       return pipelineLayoutLifetimeTest(context, VK_PIPELINE_BIND_POINT_GRAPHICS);
+}
+
 void createPipelineLayoutLifetimeComputeSource (SourceCollections& dst)
 {
        dst.glslSources.add("compute") << glu::ComputeSource(
@@ -1175,215 +1207,187 @@ void createPipelineLayoutLifetimeComputeSource (SourceCollections& dst)
 
 tcu::TestStatus pipelineLayoutLifetimeComputeTest (Context& context)
 {
-       const DeviceInterface&                                  vk                                                      = context.getDeviceInterface();
-       const VkDevice                                                  device                                          = context.getDevice();
-       const deUint32                                                  queueFamilyIndex                        = context.getUniversalQueueFamilyIndex();
-
-       const VkCommandPoolCreateInfo                   commandPoolParams                       =
-       {
-               VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,     // VkStructureType             sType;
-               DE_NULL,                                                                        // const void*                 pNext;
-               (VkCommandPoolCreateFlags)0u,                           // VkCommandPoolCreateFlags    flags;
-               queueFamilyIndex                                                        // deUint32                    queueFamilyIndex;
-       };
+       return pipelineLayoutLifetimeTest(context, VK_PIPELINE_BIND_POINT_COMPUTE);
+}
 
-       const Unique<VkCommandPool>                             commandPool                                     (createCommandPool(vk, device, &commandPoolParams, DE_NULL));
-       const Unique<VkCommandBuffer>                   commandBuffer                           (createCommandBuffer(vk, device, commandPool.get()));
+void checkSupport (Context& context)
+{
+       const InstanceInterface&        vki                             = context.getInstanceInterface();
+       const VkPhysicalDevice          physicalDevice  = context.getPhysicalDevice();
 
-       const VkDescriptorPoolSize                              descriptorPoolSizes[]           =
-       {
-               {
-                       VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,      // VkDescriptorType    type;
-                       10                                                                      // deUint32            descriptorCount;
-               },
-               {
-                       VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,       // VkDescriptorType    type;
-                       2                                                                       // deUint32            descriptorCount;
-               },
-               {
-                       VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,       // VkDescriptorType    type;
-                       2                                                                       // deUint32            descriptorCount;
-               }
-       };
+       // Throws exception if not supported
+       getRenderTargetFormat(vki, physicalDevice);
+}
 
-       VkDescriptorPool                                                descriptorPool;
-       {
-               const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo =
-               {
-                       VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,  // VkStructureType                sType;
-                       DE_NULL,                                                                                // const void*                    pNext;
-                       (VkDescriptorPoolCreateFlags)0u,                                // VkDescriptorPoolCreateFlags    flags;
-                       5,                                                                                              // deUint32                       maxSets;
-                       DE_LENGTH_OF_ARRAY(descriptorPoolSizes),                // deUint32                       poolSizeCount;
-                       descriptorPoolSizes                                                             // const VkDescriptorPoolSize*    pPoolSizes;
-               };
+void DestroyAfterEndPrograms (SourceCollections& programs)
+{
+       std::ostringstream comp;
+
+       comp
+               << "#version 450\n"
+               << "layout (local_size_x=1, local_size_y=1, local_size_z=1) in;\n"
+               << "layout (constant_id=0) const uint flag = 0;\n"
+               << "layout (push_constant, std430) uniform PushConstants {\n"
+               << "    uint base;\n"
+               << "};\n"
+               << "layout (set=0, binding=0, std430) buffer Block {\n"
+               << "    uint data[];\n"
+               << "};\n"
+               << "\n"
+               << "void main() {\n"
+               << "    if (flag != 0u) {\n"
+               << "        uint idx = gl_GlobalInvocationID.x;\n"
+               << "        data[idx] = data[idx] + base + idx;\n"
+               << "    }\n"
+               << "}\n"
+               ;
+
+       programs.glslSources.add("comp") << glu::ComputeSource(comp.str());
+}
 
-               VK_CHECK(vk.createDescriptorPool(device, &descriptorPoolCreateInfo, DE_NULL, &descriptorPool));
+tcu::TestStatus DestroyAfterEndTest (Context& context)
+{
+       const auto&     vkd             = context.getDeviceInterface();
+       const auto      device  = context.getDevice();
+       auto&           alloc   = context.getDefaultAllocator();
+       const auto      queue   = context.getUniversalQueue();
+       const auto      qIndex  = context.getUniversalQueueFamilyIndex();
+
+       const deUint32  kBufferElements = 100u;
+       const deUint32  kBufferSize             = kBufferElements * sizeof(deUint32);
+       const auto              kBufferSizeDS   = static_cast<VkDeviceSize>(kBufferSize);
+       const deUint32  kInitialValue   = 50u;
+       const deUint32  kFlagValue              = 1u;
+       const deUint32  kBaseValue              = 75u;
+
+       // Allocate and prepare buffer.
+       const auto                              bufferInfo      = vk::makeBufferCreateInfo(kBufferSizeDS, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
+       vk::BufferWithMemory    buffer          (vkd, device, alloc, bufferInfo, vk::MemoryRequirement::HostVisible);
+       auto&                                   bufferAlloc     = buffer.getAllocation();
+       void*                                   bufferPtr       = bufferAlloc.getHostPtr();
+       {
+               const std::vector<deUint32> bufferValues (kBufferElements, kInitialValue);
+               deMemcpy(bufferPtr, bufferValues.data(), kBufferSize);
+               vk::flushAlloc(vkd, device, bufferAlloc);
        }
 
-       const VkDescriptorSetLayoutBinding              setLayoutBindingA[]                     =
-       {
-               {
-                       0,                                                                      // deUint32              binding;
-                       VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,      // VkDescriptorType      descriptorType;
-                       5,                                                                      // deUint32              descriptorCount;
-                       VK_SHADER_STAGE_ALL,                            // VkShaderStageFlags    stageFlags;
-                       DE_NULL                                                         // const VkSampler*      pImmutableSamplers;
-               }
-       };
+       // Descriptor set layout.
+       vk::DescriptorSetLayoutBuilder layoutBuilder;
+       layoutBuilder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
+       const auto descriptorSetLayout = layoutBuilder.build(vkd, device);
 
-       const VkDescriptorSetLayoutBinding              setLayoutBindingB[]                     =
-       {
-               {
-                       0,                                                                      // deUint32              binding;
-                       VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,      // VkDescriptorType      descriptorType;
-                       5,                                                                      // deUint32              descriptorCount;
-                       VK_SHADER_STAGE_COMPUTE_BIT,            // VkShaderStageFlags    stageFlags;
-                       DE_NULL                                                         // const VkSampler*      pImmutableSamplers;
-               }
-       };
+       // Pipeline layout.
+       const auto pushConstantRange = vk::makePushConstantRange(vk::VK_SHADER_STAGE_COMPUTE_BIT, 0u, static_cast<deUint32>(sizeof(kBaseValue)));
 
-       const VkDescriptorSetLayoutBinding              setLayoutBindingC[]                     =
+       const vk::VkPipelineLayoutCreateInfo pipelineLayoutInfo =
        {
-               {
-                       0,                                                                      // deUint32              binding;
-                       VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,       // VkDescriptorType      descriptorType;
-                       2,                                                                      // deUint32              descriptorCount;
-                       VK_SHADER_STAGE_ALL,                            // VkShaderStageFlags    stageFlags;
-                       DE_NULL                                                         // const VkSampler*      pImmutableSamplers;
-               },
-               {
-                       1,                                                                      // deUint32              binding;
-                       VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,       // VkDescriptorType      descriptorType;
-                       2,                                                                      // deUint32              descriptorCount;
-                       VK_SHADER_STAGE_ALL,                            // VkShaderStageFlags    stageFlags;
-                       DE_NULL                                                         // const VkSampler*      pImmutableSamplers;
-               }
+               vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,      //      VkStructureType                                 sType;
+               nullptr,                                                                                        //      const void*                                             pNext;
+               0u,                                                                                                     //      VkPipelineLayoutCreateFlags             flags;
+               1u,                                                                                                     //      deUint32                                                setLayoutCount;
+               &descriptorSetLayout.get(),                                                     //      const VkDescriptorSetLayout*    pSetLayouts;
+               1u,                                                                                                     //      deUint32                                                pushConstantRangeCount;
+               &pushConstantRange,                                                                     //      const VkPushConstantRange*              pPushConstantRanges;
        };
 
-       const Move<VkDescriptorSetLayout>               descriptorSetLayouts[]          =
-       {
-               getDescriptorSetLayout(vk, device, DE_LENGTH_OF_ARRAY(setLayoutBindingA), setLayoutBindingA),
-               getDescriptorSetLayout(vk, device, DE_LENGTH_OF_ARRAY(setLayoutBindingB), setLayoutBindingB),
-               getDescriptorSetLayout(vk, device, DE_LENGTH_OF_ARRAY(setLayoutBindingC), setLayoutBindingC)
-       };
+       auto pipelineLayout = vk::createPipelineLayout(vkd, device, &pipelineLayoutInfo);
 
-       const VkDescriptorSetLayout                             setLayoutHandlesAC[]            =
-       {
-               descriptorSetLayouts[0].get(),
-               descriptorSetLayouts[2].get()
-       };
+       // Shader module.
+       const auto shaderModule = vk::createShaderModule(vkd, device, context.getBinaryCollection().get("comp"), 0u);
 
-       const VkDescriptorSetLayout                             setLayoutHandlesB[]                     =
-       {
-               descriptorSetLayouts[1].get()
-       };
+       // Pipeline, with shader and specialization info.
+       const auto specConstantSize = static_cast<deUintptr>(sizeof(kFlagValue));
 
-       const VkDescriptorSetLayout                             setLayoutHandlesBC[]            =
+       const vk::VkSpecializationMapEntry mapEntry =
        {
-               descriptorSetLayouts[1].get(),
-               descriptorSetLayouts[2].get()
+               0u,                                     //      deUint32        constantID;
+               0u,                                     //      deUint32        offset;
+               specConstantSize,       //      deUintptr       size;
        };
 
-       const VkDescriptorSet                                   descriptorSets[]                        =
+       const vk::VkSpecializationInfo specializationInfo =
        {
-               getDescriptorSet(vk, device, descriptorPool, descriptorSetLayouts[0].get()),
-               getDescriptorSet(vk, device, descriptorPool, descriptorSetLayouts[1].get()),
-               getDescriptorSet(vk, device, descriptorPool, descriptorSetLayouts[2].get())
+               1u,                                     //      deUint32                                                mapEntryCount;
+               &mapEntry,                      //      const VkSpecializationMapEntry* pMapEntries;
+               specConstantSize,       //      deUintptr                                               dataSize;
+               &kFlagValue,            //      const void*                                             pData;
        };
 
-       const VkDescriptorSet                                   setHandlesAC[]                          =
+       const VkPipelineShaderStageCreateInfo shaderInfo =
        {
-               descriptorSets[0],
-               descriptorSets[2]
+               vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,        //      VkStructureType                                         sType;
+               nullptr,                                                                                                        //      const void*                                                     pNext;
+               0u,                                                                                                                     //      VkPipelineShaderStageCreateFlags        flags;
+               vk::VK_SHADER_STAGE_COMPUTE_BIT,                                                        //      VkShaderStageFlagBits                           stage;
+               shaderModule.get(),                                                                                     //      VkShaderModule                                          module;
+               "main",                                                                                                         //      const char*                                                     pName;
+               &specializationInfo,                                                                            //      const VkSpecializationInfo*                     pSpecializationInfo;
        };
-
-       const VkDescriptorSet                                   setHandlesC[]                           =
+       const vk::VkComputePipelineCreateInfo pipelineInfo =
        {
-               descriptorSets[2]
+               vk::VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,                     //      VkStructureType                                 sType;
+               nullptr,                                                                                                        //      const void*                                             pNext;
+               0u,                                                                                                                     //      VkPipelineCreateFlags                   flags;
+               shaderInfo,                                                                                                     //      VkPipelineShaderStageCreateInfo stage;
+               pipelineLayout.get(),                                                                           //      VkPipelineLayout                                layout;
+               DE_NULL,                                                                                                        //      VkPipeline                                              basePipelineHandle;
+               0,                                                                                                                      //      deInt32                                                 basePipelineIndex;
        };
 
-       const Unique<VkPipelineLayout>                  pipelineLayoutAC                        (getPipelineLayout(vk, device, DE_LENGTH_OF_ARRAY(setLayoutHandlesAC), setLayoutHandlesAC));
-       const Unique<VkPipelineLayout>                  pipelineLayoutBC                        (getPipelineLayout(vk, device, DE_LENGTH_OF_ARRAY(setLayoutHandlesBC), setLayoutHandlesBC));
+       const auto pipeline = vk::createComputePipeline(vkd, device, DE_NULL, &pipelineInfo);
 
-       VkPipelineLayout                                                pipelineLayoutB;
-       {
-               const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
-               {
-                       VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,  // VkStructureType                 sType;
-                       DE_NULL,                                                                                // const void*                     pNext;
-                       (VkPipelineLayoutCreateFlags)0u,                                // VkPipelineLayoutCreateFlags     flags;
-                       DE_LENGTH_OF_ARRAY(setLayoutHandlesB),                  // deUint32                        setLayoutCount;
-                       setLayoutHandlesB,                                                              // const VkDescriptorSetLayout*    pSetLayouts;
-                       0u,                                                                                             // deUint32                        pushConstantRangeCount;
-                       DE_NULL                                                                                 // const VkPushConstantRange*      pPushConstantRanges;
-               };
+       // Descriptor set.
+       vk::DescriptorPoolBuilder descriptorPoolBuilder;
+       descriptorPoolBuilder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
+       const auto descriptorPool       = descriptorPoolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
+       const auto descriptorSet        = vk::makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get());
 
-               VK_CHECK(vk.createPipelineLayout(device, &pipelineLayoutCreateInfo, DE_NULL, &pipelineLayoutB));
-       }
+       // Update descriptor set with buffer.
+       vk::DescriptorSetUpdateBuilder updateBuilder;
+       const auto descriptorInfo = vk::makeDescriptorBufferInfo(buffer.get(), static_cast<VkDeviceSize>(0), kBufferSizeDS);
+       updateBuilder.writeSingle(descriptorSet.get(), vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo);
+       updateBuilder.update(vkd, device);
 
-       const Unique<VkShaderModule>                    computeShaderModule                     (createShaderModule(vk, device, context.getBinaryCollection().get("compute"), 0));
+       // Prepare command buffer.
+       const auto cmdPool              = vk::makeCommandPool(vkd, device, qIndex);
+       const auto cmdBufferPtr = vk::allocateCommandBuffer(vkd, device, cmdPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+       const auto cmdBuffer    = cmdBufferPtr.get();
+       const auto barrier              = vk::makeMemoryBarrier(vk::VK_ACCESS_SHADER_WRITE_BIT, vk::VK_ACCESS_HOST_READ_BIT);
 
-       const VkPipelineShaderStageCreateInfo   shaderStageCreateInfo           =
-       {
-               VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                     sType;
-               DE_NULL,                                                                                                // const void*                         pNext;
-               (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags    flags;
-               VK_SHADER_STAGE_COMPUTE_BIT,                                                    // VkShaderStageFlagBits               stage;
-               computeShaderModule.get(),                                                              // VkShaderModule                      shader;
-               "main",                                                                                                 // const char*                         pName;
-               DE_NULL,                                                                                                // const VkSpecializationInfo*         pSpecializationInfo;
-       };
+       vk::beginCommandBuffer(vkd, cmdBuffer);
+       vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, pipeline.get());
+       vkd.cmdBindDescriptorSets(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout.get(), 0u, 1u, &descriptorSet.get(), 0u, nullptr);
+       vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), vk::VK_SHADER_STAGE_COMPUTE_BIT, 0u, static_cast<deUint32>(sizeof(kBaseValue)), &kBaseValue);
+       vkd.cmdDispatch(cmdBuffer, kBufferElements, 1u, 1u);
+       vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &barrier, 0u, nullptr, 0u, nullptr);
+       vk::endCommandBuffer(vkd, cmdBuffer);
 
-       const VkComputePipelineCreateInfo               computePipelineCreateInfo       =
-       {
-               VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType                    sType;
-               DE_NULL,                                                                                // const void*                        pNext
-               (VkPipelineCreateFlags)0,                                               // VkPipelineCreateFlags              flags
-               shaderStageCreateInfo,                                                  // VkPipelineShaderStageCreateInfo    stage
-               pipelineLayoutB,                                                                // VkPipelineLayout                   layout
-               DE_NULL,                                                                                // VkPipeline                         basePipelineHandle
-               0                                                                                               // int                                basePipelineIndex
-       };
+       // Critical: delete pipeline layout just after recording command buffer. This is what the test is for.
+       pipelineLayout = decltype(pipelineLayout)();
+
+       // Submit commands.
+       vk::submitCommandsAndWait(vkd, device, queue, cmdBuffer);
 
-       const Unique<VkPipeline>                                computePipeline                         (createComputePipeline(vk, device, DE_NULL, &computePipelineCreateInfo));
+       // Check buffer.
+       vk::invalidateAlloc(vkd, device, bufferAlloc);
+       std::vector<deUint32> outputData (kBufferElements);
+       deMemcpy(outputData.data(), bufferPtr, kBufferSize);
 
+       for (deUint32 i = 0; i < kBufferElements; ++i)
        {
-               const VkCommandBufferBeginInfo commandBufferBeginInfo =
+               // This matches what the shader should calculate.
+               const auto expectedValue = kInitialValue + kBaseValue + i;
+               if (outputData[i] != expectedValue)
                {
-                       VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                          sType;
-                       DE_NULL,                                                                                // const void*                              pNext;
-                       VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,    // VkCommandBufferUsageFlags                flags;
-                       DE_NULL                                                                                 // const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
-               };
-
-               VK_CHECK(vk.beginCommandBuffer(commandBuffer.get(), &commandBufferBeginInfo));
+                       std::ostringstream msg;
+                       msg << "Unexpected value at buffer position " << i << ": expected " << expectedValue << " but found " << outputData[i];
+                       return tcu::TestStatus::fail(msg.str());
+               }
        }
 
-       vk.cmdBindPipeline(commandBuffer.get(), VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline.get());
-
-       // Destroy the pipeline layout that was used to create the compute pipeline
-       vk.destroyPipelineLayout(device, pipelineLayoutB, DE_NULL);
-
-       vk.cmdBindDescriptorSets(commandBuffer.get(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayoutAC.get(), 0u, DE_LENGTH_OF_ARRAY(setHandlesAC), setHandlesAC, 0u, DE_NULL);
-       vk.cmdBindDescriptorSets(commandBuffer.get(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayoutBC.get(), 1u, DE_LENGTH_OF_ARRAY(setHandlesC), setHandlesC, 0u, DE_NULL);
-       vk.cmdBindDescriptorSets(commandBuffer.get(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayoutAC.get(), 0u, DE_LENGTH_OF_ARRAY(setHandlesAC), setHandlesAC, 0u, DE_NULL);
-
-       vk.destroyDescriptorPool(device, descriptorPool, DE_NULL);
-
-       // Test should always pass
        return tcu::TestStatus::pass("Pass");
 }
 
-void checkSupport (Context& context)
-{
-       const InstanceInterface&        vki                             = context.getInstanceInterface();
-       const VkPhysicalDevice          physicalDevice  = context.getPhysicalDevice();
-
-       // Throws exception if not supported
-       getRenderTargetFormat(vki, physicalDevice);
-}
-
 tcu::TestCaseGroup* createrenderpassTests (tcu::TestContext& testCtx)
 {
        de::MovePtr<tcu::TestCaseGroup> renderPassTests(new tcu::TestCaseGroup(testCtx, "renderpass", "Renderpass tests"));
@@ -1400,6 +1404,7 @@ tcu::TestCaseGroup* createPipelineLayoutLifetimeTests (tcu::TestContext& testCtx
 
        addFunctionCaseWithPrograms(pipelineLayoutLifetimeTests.get(), "graphics", "Test pipeline layout lifetime in graphics pipeline", checkSupport, createPipelineLayoutLifetimeGraphicsSource, pipelineLayoutLifetimeGraphicsTest);
        addFunctionCaseWithPrograms(pipelineLayoutLifetimeTests.get(), "compute", "Test pipeline layout lifetime in compute pipeline", checkSupport, createPipelineLayoutLifetimeComputeSource, pipelineLayoutLifetimeComputeTest);
+       addFunctionCaseWithPrograms(pipelineLayoutLifetimeTests.get(), "destroy_after_end", "Test destroying the pipeline layout after vkEndCommandBuffer", DestroyAfterEndPrograms, DestroyAfterEndTest);
 
        return pipelineLayoutLifetimeTests.release();
 }
index 46d56fb..1ed17ce 100644 (file)
@@ -140454,6 +140454,7 @@ dEQP-VK.api.pipeline.renderpass.destroy_pipeline_renderpass
 dEQP-VK.api.pipeline.renderpass.framebuffer_compatible_renderpass
 dEQP-VK.api.pipeline.pipeline_layout.lifetime.graphics
 dEQP-VK.api.pipeline.pipeline_layout.lifetime.compute
+dEQP-VK.api.pipeline.pipeline_layout.lifetime.destroy_after_end
 dEQP-VK.api.invariance.random
 dEQP-VK.api.tooling_info.validate_getter
 dEQP-VK.api.tooling_info.validate_tools_properties