Test remaining descriptor types in push descriptor test
authorAri Suonpaa <ari.suonpaa@siru.fi>
Thu, 30 Aug 2018 05:27:33 +0000 (08:27 +0300)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Fri, 5 Oct 2018 12:46:05 +0000 (08:46 -0400)
The initial push descriptor test was only testing uniform and storage
buffers. This commit adds the remaining descriptor types.

New tests:

dEQP-VK.pipeline.push_descriptor.*

Components: Vulkan

VK-GL-CTS issue: 1320
Change-Id: I742ad32edc724344b2e69d48127b44c179832711

android/cts/master/vk-master.txt
external/vulkancts/modules/vulkan/pipeline/vktPipelinePushDescriptorTests.cpp
external/vulkancts/mustpass/1.1.3/vk-default-no-waivers.txt
external/vulkancts/mustpass/1.1.3/vk-default.txt

index 6c9a026..99dbc00 100755 (executable)
@@ -168977,6 +168977,34 @@ dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls1_storage_buffer
 dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls2_storage_buffer
 dEQP-VK.pipeline.push_descriptor.graphics.binding1_numcalls2_storage_buffer
 dEQP-VK.pipeline.push_descriptor.graphics.binding3_numcalls2_storage_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls1_combined_image_sampler
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls2_combined_image_sampler
+dEQP-VK.pipeline.push_descriptor.graphics.binding1_numcalls2_combined_image_sampler
+dEQP-VK.pipeline.push_descriptor.graphics.binding3_numcalls2_combined_image_sampler
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls1_sampler
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls2_sampler
+dEQP-VK.pipeline.push_descriptor.graphics.binding1_numcalls2_sampler
+dEQP-VK.pipeline.push_descriptor.graphics.binding3_numcalls2_sampler
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls1_sampled_image
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls2_sampled_image
+dEQP-VK.pipeline.push_descriptor.graphics.binding1_numcalls2_sampled_image
+dEQP-VK.pipeline.push_descriptor.graphics.binding3_numcalls2_sampled_image
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls1_storage_image
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls2_storage_image
+dEQP-VK.pipeline.push_descriptor.graphics.binding1_numcalls2_storage_image
+dEQP-VK.pipeline.push_descriptor.graphics.binding3_numcalls2_storage_image
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls1_uniform_texel_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls2_uniform_texel_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding1_numcalls2_uniform_texel_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding3_numcalls2_uniform_texel_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls1_storage_texel_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls2_storage_texel_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding1_numcalls2_storage_texel_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding3_numcalls2_storage_texel_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls1_input_attachment
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls2_input_attachment
+dEQP-VK.pipeline.push_descriptor.graphics.binding1_numcalls2_input_attachment
+dEQP-VK.pipeline.push_descriptor.graphics.binding3_numcalls2_input_attachment
 dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls1_uniform_buffer
 dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls2_uniform_buffer
 dEQP-VK.pipeline.push_descriptor.compute.binding1_numcalls2_uniform_buffer
@@ -168985,6 +169013,30 @@ dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls1_storage_buffer
 dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls2_storage_buffer
 dEQP-VK.pipeline.push_descriptor.compute.binding1_numcalls2_storage_buffer
 dEQP-VK.pipeline.push_descriptor.compute.binding3_numcalls2_storage_buffer
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls1_combined_image_sampler
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls2_combined_image_sampler
+dEQP-VK.pipeline.push_descriptor.compute.binding1_numcalls2_combined_image_sampler
+dEQP-VK.pipeline.push_descriptor.compute.binding3_numcalls2_combined_image_sampler
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls1_sampler
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls2_sampler
+dEQP-VK.pipeline.push_descriptor.compute.binding1_numcalls2_sampler
+dEQP-VK.pipeline.push_descriptor.compute.binding3_numcalls2_sampler
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls1_sampled_image
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls2_sampled_image
+dEQP-VK.pipeline.push_descriptor.compute.binding1_numcalls2_sampled_image
+dEQP-VK.pipeline.push_descriptor.compute.binding3_numcalls2_sampled_image
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls1_storage_image
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls2_storage_image
+dEQP-VK.pipeline.push_descriptor.compute.binding1_numcalls2_storage_image
+dEQP-VK.pipeline.push_descriptor.compute.binding3_numcalls2_storage_image
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls1_uniform_texel_buffer
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls2_uniform_texel_buffer
+dEQP-VK.pipeline.push_descriptor.compute.binding1_numcalls2_uniform_texel_buffer
+dEQP-VK.pipeline.push_descriptor.compute.binding3_numcalls2_uniform_texel_buffer
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls1_storage_texel_buffer
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls2_storage_texel_buffer
+dEQP-VK.pipeline.push_descriptor.compute.binding1_numcalls2_storage_texel_buffer
+dEQP-VK.pipeline.push_descriptor.compute.binding3_numcalls2_storage_texel_buffer
 dEQP-VK.pipeline.spec_constant.graphics.vertex.default_value.bool
 dEQP-VK.pipeline.spec_constant.graphics.vertex.default_value.int
 dEQP-VK.pipeline.spec_constant.graphics.vertex.default_value.uint
index f1155a7..71838f2 100644 (file)
 #include "tcuTestLog.hpp"
 #include <vector>
 
-// TODO: Currently only uniform and storage buffer descriptor types are tested.
-//
-// Tests for the following descriptor types are still missing:
-// - VK_DESCRIPTOR_TYPE_SAMPLER
-// - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
-// - VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
-// - VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
-// - VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
-// - VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
-// - VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT
-
 namespace vkt
 {
 namespace pipeline
@@ -66,9 +55,15 @@ using namespace std;
 
 namespace
 {
-typedef vector<VkExtensionProperties>          Extensions;
-typedef de::SharedPtr<Unique<VkBuffer> >       VkBufferSp;
-typedef de::SharedPtr<Allocation>                      AllocationSp;
+typedef vector<VkExtensionProperties>                  Extensions;
+typedef de::SharedPtr<Unique<VkBuffer> >               VkBufferSp;
+typedef de::SharedPtr<Unique<VkImage> >                        VkImageSp;
+typedef de::SharedPtr<Unique<VkImageView> >            VkImageViewSp;
+typedef de::SharedPtr<Unique<VkBufferView> >   VkBufferViewSp;
+typedef de::SharedPtr<Allocation>                              AllocationSp;
+typedef de::SharedPtr<Unique<VkRenderPass> >   VkRenderPassSp;
+typedef de::SharedPtr<Unique<VkFramebuffer> >  VkFramebufferSp;
+typedef de::SharedPtr<Unique<VkPipeline> >             VkPipelineSp;
 
 struct TestParams
 {
@@ -184,6 +179,29 @@ vector<Vertex4RGBA> createQuads (deUint32 numQuads, float size)
        return vertices;
 }
 
+vector<Vertex4Tex4> createTexQuads (deUint32 numQuads, float size)
+{
+       vector<Vertex4Tex4>     vertices;
+
+       for (deUint32 quadNdx = 0; quadNdx < numQuads; quadNdx++)
+       {
+               const float                     xOffset                         = -0.5f + (float)quadNdx;
+               const Vertex4Tex4       lowerLeftVertex         = {tcu::Vec4(-size + xOffset, -size, 0.0f, 1.0f), tcu::Vec4(-0.2f, -0.2f, 0.0f, 0.0f)};
+               const Vertex4Tex4       lowerRightVertex        = {tcu::Vec4(size + xOffset, -size, 0.0f, 1.0f), tcu::Vec4(1.2f, -0.2f, 0.0f, 0.0f)};
+               const Vertex4Tex4       UpperLeftVertex         = {tcu::Vec4(-size + xOffset, size, 0.0f, 1.0f), tcu::Vec4(-0.2f, 1.2f, 0.0f, 0.0f)};
+               const Vertex4Tex4       UpperRightVertex        = {tcu::Vec4(size + xOffset, size, 0.0f, 1.0f), tcu::Vec4(1.2f, 1.2f, 0.0f, 0.0f)};
+
+               vertices.push_back(lowerLeftVertex);
+               vertices.push_back(lowerRightVertex);
+               vertices.push_back(UpperLeftVertex);
+               vertices.push_back(UpperLeftVertex);
+               vertices.push_back(lowerRightVertex);
+               vertices.push_back(UpperRightVertex);
+       }
+
+       return vertices;
+}
+
 static const tcu::Vec4 testColors[] =
 {
        tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
@@ -214,7 +232,6 @@ private:
        SimpleAllocator                         m_allocator;
        const tcu::UVec2                        m_renderSize;
        const VkFormat                          m_colorFormat;
-       VkImageCreateInfo                       m_colorImageCreateInfo;
        Move<VkImage>                           m_colorImage;
        de::MovePtr<Allocation>         m_colorImageAlloc;
        Move<VkImageView>                       m_colorAttachmentView;
@@ -280,8 +297,7 @@ void PushDescriptorBufferGraphicsTestInstance::init (void)
                        VK_IMAGE_LAYOUT_UNDEFINED,                                                                                              // VkImageLayout                        initialLayout;
                };
 
-               m_colorImageCreateInfo  = colorImageParams;
-               m_colorImage                    = createImage(m_vkd, *m_device, &m_colorImageCreateInfo);
+               m_colorImage                    = createImage(m_vkd, *m_device, &colorImageParams);
 
                // Allocate and bind color image memory
                m_colorImageAlloc               = m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, *m_colorImage), MemoryRequirement::Any);
@@ -292,14 +308,14 @@ void PushDescriptorBufferGraphicsTestInstance::init (void)
        {
                const VkImageViewCreateInfo colorAttachmentViewParams =
                {
-                       VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                              sType;
-                       DE_NULL,                                                                                // const void*                                  pNext;
-                       0u,                                                                                             // VkImageViewCreateFlags               flags;
-                       *m_colorImage,                                                                  // VkImage                                              image;
-                       VK_IMAGE_VIEW_TYPE_2D,                                                  // VkImageViewType                              viewType;
-                       m_colorFormat,                                                                  // VkFormat                                             format;
-                       componentMappingRGBA,                                                   // VkChannelMapping                             channels;
-                       { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },  // VkImageSubresourceRange              subresourceRange;
+                       VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
+                       DE_NULL,                                                                                // const void*                          pNext;
+                       0u,                                                                                             // VkImageViewCreateFlags       flags;
+                       *m_colorImage,                                                                  // VkImage                                      image;
+                       VK_IMAGE_VIEW_TYPE_2D,                                                  // VkImageViewType                      viewType;
+                       m_colorFormat,                                                                  // VkFormat                                     format;
+                       componentMappingRGBA,                                                   // VkChannelMapping                     channels;
+                       { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },  // VkImageSubresourceRange      subresourceRange;
                };
 
                m_colorAttachmentView = createImageView(m_vkd, *m_device, &colorAttachmentViewParams);
@@ -317,15 +333,15 @@ void PushDescriptorBufferGraphicsTestInstance::init (void)
 
                const VkFramebufferCreateInfo   framebufferParams               =
                {
-                       VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,      // VkStructureType                              sType;
-                       DE_NULL,                                                                        // const void*                                  pNext;
-                       0u,                                                                                     // VkFramebufferCreateFlags             flags;
-                       *m_renderPass,                                                          // VkRenderPass                                 renderPass;
-                       1u,                                                                                     // deUint32                                             attachmentCount;
-                       attachmentBindInfos,                                            // const VkImageView*                   pAttachments;
-                       (deUint32)m_renderSize.x(),                                     // deUint32                                             width;
-                       (deUint32)m_renderSize.y(),                                     // deUint32                                             height;
-                       1u                                                                                      // deUint32                                             layers;
+                       VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,      // VkStructureType                      sType;
+                       DE_NULL,                                                                        // const void*                          pNext;
+                       0u,                                                                                     // VkFramebufferCreateFlags     flags;
+                       *m_renderPass,                                                          // VkRenderPass                         renderPass;
+                       1u,                                                                                     // deUint32                                     attachmentCount;
+                       attachmentBindInfos,                                            // const VkImageView*           pAttachments;
+                       (deUint32)m_renderSize.x(),                                     // deUint32                                     width;
+                       (deUint32)m_renderSize.y(),                                     // deUint32                                     height;
+                       1u                                                                                      // deUint32                                     layers;
                };
 
                m_framebuffer = createFramebuffer(m_vkd, *m_device, &framebufferParams);
@@ -336,20 +352,20 @@ void PushDescriptorBufferGraphicsTestInstance::init (void)
                // Create descriptor set layout
                const VkDescriptorSetLayoutBinding              descriptorSetLayoutBinding              =
                {
-                       m_params.binding,                                       // uint32_t              binding;
-                       m_params.descriptorType,                        // VkDescriptorType      descriptorType;
-                       1u,                                                                     // uint32_t              descriptorCount;
-                       VK_SHADER_STAGE_VERTEX_BIT,                     // VkShaderStageFlags    stageFlags;
-                       DE_NULL                                                         // const VkSampler*      pImmutableSamplers;
+                       m_params.binding,                                       // uint32_t                             binding;
+                       m_params.descriptorType,                        // VkDescriptorType             descriptorType;
+                       1u,                                                                     // uint32_t                             descriptorCount;
+                       VK_SHADER_STAGE_VERTEX_BIT,                     // VkShaderStageFlags   stageFlags;
+                       DE_NULL                                                         // const VkSampler*             pImmutableSamplers;
                };
 
                const VkDescriptorSetLayoutCreateInfo   descriptorSetLayoutCreateInfo   =
                {
-                       VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,            // VkStructureType                        sType;
-                       DE_NULL,                                                                                                        // const void*                            pNext;
-                       VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,        // VkDescriptorSetLayoutCreateFlags       flags;
-                       1u,                                                                                                                     // uint32_t                               bindingCount;
-                       &descriptorSetLayoutBinding                                                                     // const VkDescriptorSetLayoutBinding*    pBindings;
+                       VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,            // VkStructureType                                              sType;
+                       DE_NULL,                                                                                                        // const void*                                                  pNext;
+                       VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,        // VkDescriptorSetLayoutCreateFlags             flags;
+                       1u,                                                                                                                     // uint32_t                                                             bindingCount;
+                       &descriptorSetLayoutBinding                                                                     // const VkDescriptorSetLayoutBinding*  pBindings;
                };
 
                m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, DE_NULL);
@@ -443,21 +459,21 @@ void PushDescriptorBufferGraphicsTestInstance::init (void)
                const vector<VkViewport>                                        viewports                                                       (1, makeViewport(m_renderSize));
                const vector<VkRect2D>                                          scissors                                                        (1, makeRect2D(m_renderSize));
 
-               m_graphicsPipelines = makeGraphicsPipeline(m_vkd,                                               // const DeviceInterface&                        vk
-                                                                                                  *m_device,                                   // const VkDevice                                device
-                                                                                                  *m_pipelineLayout,                   // const VkPipelineLayout                        pipelineLayout
-                                                                                                  *m_vertexShaderModule,               // const VkShaderModule                          vertexShaderModule
-                                                                                                  DE_NULL,                                             // const VkShaderModule                          tessellationControlShaderModule
-                                                                                                  DE_NULL,                                             // const VkShaderModule                          tessellationEvalShaderModule
-                                                                                                  DE_NULL,                                             // const VkShaderModule                          geometryShaderModule
-                                                                                                  *m_fragmentShaderModule,             // const VkShaderModule                          fragmentShaderModule
-                                                                                                  *m_renderPass,                               // const VkRenderPass                            renderPass
-                                                                                                  viewports,                                   // const std::vector<VkViewport>&                viewports
-                                                                                                  scissors,                                    // const std::vector<VkRect2D>&                  scissors
-                                                                                                  topology,                                    // const VkPrimitiveTopology                     topology
-                                                                                                  0u,                                                  // const deUint32                                subpass
-                                                                                                  0u,                                                  // const deUint32                                patchControlPoints
-                                                                                                  &vertexInputStateParams);    // const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
+               m_graphicsPipelines = makeGraphicsPipeline(m_vkd,                                               // const DeviceInterface&                                               vk
+                                                                                                  *m_device,                                   // const VkDevice                                                               device
+                                                                                                  *m_pipelineLayout,                   // const VkPipelineLayout                                               pipelineLayout
+                                                                                                  *m_vertexShaderModule,               // const VkShaderModule                                                 vertexShaderModule
+                                                                                                  DE_NULL,                                             // const VkShaderModule                                                 tessellationControlShaderModule
+                                                                                                  DE_NULL,                                             // const VkShaderModule                                                 tessellationEvalShaderModule
+                                                                                                  DE_NULL,                                             // const VkShaderModule                                                 geometryShaderModule
+                                                                                                  *m_fragmentShaderModule,             // const VkShaderModule                                                 fragmentShaderModule
+                                                                                                  *m_renderPass,                               // const VkRenderPass                                                   renderPass
+                                                                                                  viewports,                                   // const std::vector<VkViewport>&                               viewports
+                                                                                                  scissors,                                    // const std::vector<VkRect2D>&                                 scissors
+                                                                                                  topology,                                    // const VkPrimitiveTopology                                    topology
+                                                                                                  0u,                                                  // const deUint32                                                               subpass
+                                                                                                  0u,                                                  // const deUint32                                                               patchControlPoints
+                                                                                                  &vertexInputStateParams);    // const VkPipelineVertexInputStateCreateInfo*  vertexInputStateCreateInfo
        }
 
        // Create vertex buffer
@@ -503,23 +519,23 @@ void PushDescriptorBufferGraphicsTestInstance::init (void)
                {
                        VkDescriptorBufferInfo descriptorBufferInfo =
                        {
-                               **m_buffers[quadNdx],   // VkBuffer        buffer;
-                               0u,                                             // VkDeviceSize    offset;
-                               16u                                             // VkDeviceSize    range;
+                               **m_buffers[quadNdx],   // VkBuffer                     buffer;
+                               0u,                                             // VkDeviceSize         offset;
+                               16u                                             // VkDeviceSize         range;
                        };
 
                        VkWriteDescriptorSet writeDescriptorSet =
                        {
-                               VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType                  sType;
-                               DE_NULL,                                                                // const void*                      pNext;
-                               0u,                                                                             // VkDescriptorSet                  dstSet;
-                               m_params.binding,                                               // uint32_t                         dstBinding;
-                               0u,                                                                             // uint32_t                         dstArrayElement;
-                               1u,                                                                             // uint32_t                         descriptorCount;
-                               m_params.descriptorType,                                // VkDescriptorType                 descriptorType;
-                               DE_NULL,                                                                // const VkDescriptorImageInfo*     pImageInfo;
-                               &descriptorBufferInfo,                                  // const VkDescriptorBufferInfo*    pBufferInfo;
-                               DE_NULL                                                                 // const VkBufferView*              pTexelBufferView;
+                               VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType                                      sType;
+                               DE_NULL,                                                                // const void*                                          pNext;
+                               0u,                                                                             // VkDescriptorSet                                      dstSet;
+                               m_params.binding,                                               // uint32_t                                                     dstBinding;
+                               0u,                                                                             // uint32_t                                                     dstArrayElement;
+                               1u,                                                                             // uint32_t                                                     descriptorCount;
+                               m_params.descriptorType,                                // VkDescriptorType                                     descriptorType;
+                               DE_NULL,                                                                // const VkDescriptorImageInfo*         pImageInfo;
+                               &descriptorBufferInfo,                                  // const VkDescriptorBufferInfo*        pBufferInfo;
+                               DE_NULL                                                                 // const VkBufferView*                          pTexelBufferView;
                        };
 
                        m_vkd.cmdPushDescriptorSetKHR(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &writeDescriptorSet);
@@ -711,28 +727,28 @@ void PushDescriptorBufferComputeTestInstance::init (void)
                const VkDescriptorSetLayoutBinding              descriptorSetLayoutBindings[]   =
                {
                        {
-                               m_params.binding,                               // uint32_t              binding;
-                               m_params.descriptorType,                // VkDescriptorType      descriptorType;
-                               1u,                                                             // uint32_t              descriptorCount;
-                               VK_SHADER_STAGE_COMPUTE_BIT,    // VkShaderStageFlags    stageFlags;
-                               DE_NULL                                                 // const VkSampler*      pImmutableSamplers;
+                               m_params.binding,                               // uint32_t                             binding;
+                               m_params.descriptorType,                // VkDescriptorType             descriptorType;
+                               1u,                                                             // uint32_t                             descriptorCount;
+                               VK_SHADER_STAGE_COMPUTE_BIT,    // VkShaderStageFlags   stageFlags;
+                               DE_NULL                                                 // const VkSampler*             pImmutableSamplers;
                        },
                        {
-                               m_params.binding + 1,                           // uint32_t              binding;
-                               VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,      // VkDescriptorType      descriptorType;
-                               1u,                                                                     // uint32_t              descriptorCount;
-                               VK_SHADER_STAGE_COMPUTE_BIT,            // VkShaderStageFlags    stageFlags;
-                               DE_NULL                                                         // const VkSampler*      pImmutableSamplers;
+                               m_params.binding + 1,                           // uint32_t                             binding;
+                               VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,      // VkDescriptorType             descriptorType;
+                               1u,                                                                     // uint32_t                             descriptorCount;
+                               VK_SHADER_STAGE_COMPUTE_BIT,            // VkShaderStageFlags   stageFlags;
+                               DE_NULL                                                         // const VkSampler*             pImmutableSamplers;
                        }
                };
 
                const VkDescriptorSetLayoutCreateInfo   descriptorSetLayoutCreateInfo   =
                {
-                       VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,            // VkStructureType                        sType;
-                       DE_NULL,                                                                                                        // const void*                            pNext;
-                       VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,        // VkDescriptorSetLayoutCreateFlags       flags;
-                       2u,                                                                                                                     // uint32_t                               bindingCount;
-                       descriptorSetLayoutBindings                                                                     // const VkDescriptorSetLayoutBinding*    pBindings;
+                       VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,            // VkStructureType                                              sType;
+                       DE_NULL,                                                                                                        // const void*                                                  pNext;
+                       VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,        // VkDescriptorSetLayoutCreateFlags             flags;
+                       2u,                                                                                                                     // uint32_t                                                             bindingCount;
+                       descriptorSetLayoutBindings                                                                     // const VkDescriptorSetLayoutBinding*  pBindings;
                };
 
                m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, DE_NULL);
@@ -807,24 +823,24 @@ void PushDescriptorBufferComputeTestInstance::init (void)
        {
                const VkPipelineShaderStageCreateInfo   stageCreateInfo =
                {
-                       VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                              sType;
-                       DE_NULL,                                                                                                // const void*                                                  pNext;
-                       0u,                                                                                                             // VkPipelineShaderStageCreateFlags             flags;
-                       VK_SHADER_STAGE_COMPUTE_BIT,                                                    // VkShaderStageFlagBits                                stage;
-                       *m_computeShaderModule,                                                                 // VkShaderModule                                               module;
-                       "main",                                                                                                 // const char*                                                  pName;
-                       DE_NULL                                                                                                 // const VkSpecializationInfo*                  pSpecializationInfo;
+                       VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                      sType;
+                       DE_NULL,                                                                                                // const void*                                          pNext;
+                       0u,                                                                                                             // VkPipelineShaderStageCreateFlags     flags;
+                       VK_SHADER_STAGE_COMPUTE_BIT,                                                    // VkShaderStageFlagBits                        stage;
+                       *m_computeShaderModule,                                                                 // VkShaderModule                                       module;
+                       "main",                                                                                                 // const char*                                          pName;
+                       DE_NULL                                                                                                 // const VkSpecializationInfo*          pSpecializationInfo;
                };
 
                const VkComputePipelineCreateInfo               createInfo              =
                {
-                       VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,                 // VkStructureType                    sType;
-                       DE_NULL,                                                                                                // const void*                        pNext;
-                       0u,                                                                                                             // VkPipelineCreateFlags              flags;
-                       stageCreateInfo,                                                                                // VkPipelineShaderStageCreateInfo    stage;
-                       *m_pipelineLayout,                                                                              // VkPipelineLayout                   layout;
-                       (VkPipeline)0,                                                                                  // VkPipeline                         basePipelineHandle;
-                       0u,                                                                                                             // int32_t                            basePipelineIndex;
+                       VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,                 // VkStructureType                                      sType;
+                       DE_NULL,                                                                                                // const void*                                          pNext;
+                       0u,                                                                                                             // VkPipelineCreateFlags                        flags;
+                       stageCreateInfo,                                                                                // VkPipelineShaderStageCreateInfo      stage;
+                       *m_pipelineLayout,                                                                              // VkPipelineLayout                                     layout;
+                       (VkPipeline)0,                                                                                  // VkPipeline                                           basePipelineHandle;
+                       0u,                                                                                                             // int32_t                                                      basePipelineIndex;
                };
 
                m_computePipeline = createComputePipeline(m_vkd, *m_device, (vk::VkPipelineCache)0u, &createInfo);
@@ -845,43 +861,43 @@ void PushDescriptorBufferComputeTestInstance::init (void)
                {
                        VkDescriptorBufferInfo descriptorBufferInfoUbo          =
                        {
-                               **m_buffers[dispatchNdx],       // VkBuffer        buffer;
-                               0u,                                                     // VkDeviceSize    offset;
-                               16u                                                     // VkDeviceSize    range;
+                               **m_buffers[dispatchNdx],       // VkBuffer                     buffer;
+                               0u,                                                     // VkDeviceSize         offset;
+                               16u                                                     // VkDeviceSize         range;
                        };
 
                        VkDescriptorBufferInfo descriptorBufferInfoOutput       =
                        {
-                               *m_outputBuffer,        // VkBuffer        buffer;
-                               16u * dispatchNdx,      // VkDeviceSize    offset;
-                               16u                                     // VkDeviceSize    range;
+                               *m_outputBuffer,        // VkBuffer                     buffer;
+                               16u * dispatchNdx,      // VkDeviceSize         offset;
+                               16u                                     // VkDeviceSize         range;
                        };
 
                        VkWriteDescriptorSet writeDescriptorSets[] =
                        {
                                {
-                                       VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType                  sType;
-                                       DE_NULL,                                                                // const void*                      pNext;
-                                       0u,                                                                             // VkDescriptorSet                  dstSet;
-                                       m_params.binding,                                               // uint32_t                         dstBinding;
-                                       0u,                                                                             // uint32_t                         dstArrayElement;
-                                       1u,                                                                             // uint32_t                         descriptorCount;
-                                       m_params.descriptorType,                                // VkDescriptorType                 descriptorType;
-                                       DE_NULL,                                                                // const VkDescriptorImageInfo*     pImageInfo;
-                                       &descriptorBufferInfoUbo,                               // const VkDescriptorBufferInfo*    pBufferInfo;
-                                       DE_NULL                                                                 // const VkBufferView*              pTexelBufferView;
+                                       VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType                                      sType;
+                                       DE_NULL,                                                                // const void*                                          pNext;
+                                       0u,                                                                             // VkDescriptorSet                                      dstSet;
+                                       m_params.binding,                                               // uint32_t                                                     dstBinding;
+                                       0u,                                                                             // uint32_t                                                     dstArrayElement;
+                                       1u,                                                                             // uint32_t                                                     descriptorCount;
+                                       m_params.descriptorType,                                // VkDescriptorType                                     descriptorType;
+                                       DE_NULL,                                                                // const VkDescriptorImageInfo*         pImageInfo;
+                                       &descriptorBufferInfoUbo,                               // const VkDescriptorBufferInfo*        pBufferInfo;
+                                       DE_NULL                                                                 // const VkBufferView*                          pTexelBufferView;
                                },
                                {
-                                       VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType                  sType;
-                                       DE_NULL,                                                                // const void*                      pNext;
-                                       0u,                                                                             // VkDescriptorSet                  dstSet;
-                                       m_params.binding + 1,                                   // uint32_t                         dstBinding;
-                                       0u,                                                                             // uint32_t                         dstArrayElement;
-                                       1u,                                                                             // uint32_t                         descriptorCount;
-                                       VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,              // VkDescriptorType                 descriptorType;
-                                       DE_NULL,                                                                // const VkDescriptorImageInfo*     pImageInfo;
-                                       &descriptorBufferInfoOutput,                    // const VkDescriptorBufferInfo*    pBufferInfo;
-                                       DE_NULL                                                                 // const VkBufferView*              pTexelBufferView;
+                                       VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType                                      sType;
+                                       DE_NULL,                                                                // const void*                                          pNext;
+                                       0u,                                                                             // VkDescriptorSet                                      dstSet;
+                                       m_params.binding + 1,                                   // uint32_t                                                     dstBinding;
+                                       0u,                                                                             // uint32_t                                                     dstArrayElement;
+                                       1u,                                                                             // uint32_t                                                     descriptorCount;
+                                       VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,              // VkDescriptorType                                     descriptorType;
+                                       DE_NULL,                                                                // const VkDescriptorImageInfo*         pImageInfo;
+                                       &descriptorBufferInfoOutput,                    // const VkDescriptorBufferInfo*        pBufferInfo;
+                                       DE_NULL                                                                 // const VkBufferView*                          pTexelBufferView;
                                }
                        };
 
@@ -974,43 +990,3223 @@ void PushDescriptorBufferComputeTest::initPrograms (SourceCollections& sourceCol
        sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
 }
 
-} // anonymous
+class PushDescriptorImageGraphicsTestInstance : public vkt::TestInstance
+{
+public:
+                                                               PushDescriptorImageGraphicsTestInstance         (Context& context, const TestParams& params);
+       virtual                                         ~PushDescriptorImageGraphicsTestInstance        (void);
+       void                                            init                                                                            (void);
+       virtual tcu::TestStatus         iterate                                                                         (void);
+       tcu::TestStatus                         verifyImage                                                                     (void);
 
-tcu::TestCaseGroup* createPushDescriptorTests (tcu::TestContext& testCtx)
+private:
+       const TestParams                                m_params;
+       const PlatformInterface&                m_vkp;
+       const Extensions                                m_instanceExtensions;
+       const Unique<VkInstance>                m_instance;
+       const InstanceDriver                    m_vki;
+       const VkPhysicalDevice                  m_physicalDevice;
+       const deUint32                                  m_queueFamilyIndex;
+       const Extensions                                m_deviceExtensions;
+       const Unique<VkDevice>                  m_device;
+       const DeviceDriver                              m_vkd;
+       const VkQueue                                   m_queue;
+       SimpleAllocator                                 m_allocator;
+       const tcu::UVec2                                m_renderSize;
+       const tcu::UVec2                                m_textureSize;
+       const VkFormat                                  m_colorFormat;
+       Move<VkImage>                                   m_colorImage;
+       de::MovePtr<Allocation>                 m_colorImageAlloc;
+       Move<VkImageView>                               m_colorAttachmentView;
+       vector<VkImageSp>                               m_textureImages;
+       vector<AllocationSp>                    m_textureImageAllocs;
+       vector<VkImageViewSp>                   m_textureViews;
+       Move<VkSampler>                                 m_whiteBorderSampler;
+       Move<VkSampler>                                 m_blackBorderSampler;
+       Move<VkRenderPass>                              m_renderPass;
+       Move<VkFramebuffer>                             m_framebuffer;
+       Move<VkShaderModule>                    m_vertexShaderModule;
+       Move<VkShaderModule>                    m_fragmentShaderModule;
+       Move<VkBuffer>                                  m_vertexBuffer;
+       de::MovePtr<Allocation>                 m_vertexBufferAlloc;
+       Move<VkDescriptorSetLayout>             m_descriptorSetLayout;
+       Move<VkPipelineLayout>                  m_pipelineLayout;
+       Move<VkPipeline>                                m_graphicsPipelines;
+       Move<VkCommandPool>                             m_cmdPool;
+       Move<VkCommandBuffer>                   m_cmdBuffer;
+       vector<Vertex4Tex4>                             m_vertices;
+};
+
+PushDescriptorImageGraphicsTestInstance::PushDescriptorImageGraphicsTestInstance (Context& context, const TestParams& params)
+       : vkt::TestInstance             (context)
+       , m_params                              (params)
+       , m_vkp                                 (context.getPlatformInterface())
+       , m_instanceExtensions  (enumerateInstanceExtensionProperties(m_vkp, DE_NULL))
+       , m_instance                    (createInstanceWithGetPhysicalDeviceProperties2(m_vkp, context.getUsedApiVersion(), m_instanceExtensions))
+       , m_vki                                 (m_vkp, *m_instance)
+       , m_physicalDevice              (chooseDevice(m_vki, *m_instance, context.getTestContext().getCommandLine()))
+       , m_queueFamilyIndex    (findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT))
+       , m_deviceExtensions    (enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
+       , m_device                              (createDeviceWithPushDescriptor(m_vkp, *m_instance, m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex))
+       , m_vkd                                 (m_vkp, *m_instance, *m_device)
+       , m_queue                               (getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
+       , m_allocator                   (m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
+       , m_renderSize                  (32, 32)
+       , m_textureSize                 (32, 32)
+       , m_colorFormat                 (VK_FORMAT_R8G8B8A8_UNORM)
+       , m_vertices                    (createTexQuads(params.numCalls, 0.25f))
 {
-       const TestParams params[] =
+}
+
+void PushDescriptorImageGraphicsTestInstance::init (void)
+{
+       const VkComponentMapping                componentMappingRGBA    = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
+
+       // Create color image
        {
-               { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0u, 1u },
-               { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 0u, 2u },
-               { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1u, 2u },
-               { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 3u, 2u },
-               { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0u, 1u },
-               { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0u, 2u },
-               { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u, 2u },
-               { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 3u, 2u },
-       };
 
-       de::MovePtr<tcu::TestCaseGroup> pushDescriptorTests     (new tcu::TestCaseGroup(testCtx, "push_descriptor", "Push descriptor tests"));
+               const VkImageCreateInfo         colorImageParams                =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                    // VkStructureType                      sType;
+                       DE_NULL,                                                                                                                                // const void*                          pNext;
+                       0u,                                                                                                                                             // VkImageCreateFlags           flags;
+                       VK_IMAGE_TYPE_2D,                                                                                                               // VkImageType                          imageType;
+                       m_colorFormat,                                                                                                                  // VkFormat                                     format;
+                       { m_renderSize.x(), m_renderSize.y(), 1u },                                                             // VkExtent3D                           extent;
+                       1u,                                                                                                                                             // deUint32                                     mipLevels;
+                       1u,                                                                                                                                             // deUint32                                     arrayLayers;
+                       VK_SAMPLE_COUNT_1_BIT,                                                                                                  // VkSampleCountFlagBits        samples;
+                       VK_IMAGE_TILING_OPTIMAL,                                                                                                // VkImageTiling                        tiling;
+                       VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,  // VkImageUsageFlags            usage;
+                       VK_SHARING_MODE_EXCLUSIVE,                                                                                              // VkSharingMode                        sharingMode;
+                       1u,                                                                                                                                             // deUint32                                     queueFamilyIndexCount;
+                       &m_queueFamilyIndex,                                                                                                    // const deUint32*                      pQueueFamilyIndices;
+                       VK_IMAGE_LAYOUT_UNDEFINED                                                                                               // VkImageLayout                        initialLayout;
+               };
 
-       de::MovePtr<tcu::TestCaseGroup> graphicsTests           (new tcu::TestCaseGroup(testCtx, "graphics", "graphics pipeline"));
-       de::MovePtr<tcu::TestCaseGroup> computeTests            (new tcu::TestCaseGroup(testCtx, "compute", "compute pipeline"));
+               m_colorImage                    = createImage(m_vkd, *m_device, &colorImageParams);
 
-       for (deUint32 testIdx = 0; testIdx < DE_LENGTH_OF_ARRAY(params); testIdx++)
+               // Allocate and bind color image memory
+               m_colorImageAlloc               = m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, *m_colorImage), MemoryRequirement::Any);
+               VK_CHECK(m_vkd.bindImageMemory(*m_device, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
+       }
+
+       // Create color attachment view
        {
-               string testName;
-               testName += "binding" + de::toString(params[testIdx].binding) + "_numcalls" + de::toString(params[testIdx].numCalls);
-               switch(params[testIdx].descriptorType)
+               const VkImageViewCreateInfo colorAttachmentViewParams =
                {
-                       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
-                               testName += "_uniform_buffer";
-                               graphicsTests->addChild(new PushDescriptorBufferGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
-                               computeTests->addChild(new PushDescriptorBufferComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
+                       VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
+                       DE_NULL,                                                                                // const void*                          pNext;
+                       0u,                                                                                             // VkImageViewCreateFlags       flags;
+                       *m_colorImage,                                                                  // VkImage                                      image;
+                       VK_IMAGE_VIEW_TYPE_2D,                                                  // VkImageViewType                      viewType;
+                       m_colorFormat,                                                                  // VkFormat                                     format;
+                       componentMappingRGBA,                                                   // VkChannelMapping                     channels;
+                       { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }   // VkImageSubresourceRange      subresourceRange;
+               };
+
+               m_colorAttachmentView = createImageView(m_vkd, *m_device, &colorAttachmentViewParams);
+       }
+
+       // Create texture images
+       for (deUint32 texIdx = 0; texIdx < 2; texIdx++)
+       {
+               VkImageUsageFlags                       usageFlags                      = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+               if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
+                       usageFlags |= VK_IMAGE_USAGE_SAMPLED_BIT;
+               if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
+                       usageFlags |= VK_IMAGE_USAGE_STORAGE_BIT;
+
+               const VkImageCreateInfo         textureImageParams      =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                    // VkStructureType                      sType;
+                       DE_NULL,                                                                                // const void*                          pNext;
+                       0u,                                                                                             // VkImageCreateFlags           flags;
+                       VK_IMAGE_TYPE_2D,                                                               // VkImageType                          imageType;
+                       m_colorFormat,                                                                  // VkFormat                                     format;
+                       { m_textureSize.x(), m_textureSize.y(), 1u },   // VkExtent3D                           extent;
+                       1u,                                                                                             // deUint32                                     mipLevels;
+                       1u,                                                                                             // deUint32                                     arrayLayers;
+                       VK_SAMPLE_COUNT_1_BIT,                                                  // VkSampleCountFlagBits        samples;
+                       VK_IMAGE_TILING_OPTIMAL,                                                // VkImageTiling                        tiling;
+                       usageFlags,                                                                             // VkImageUsageFlags            usage;
+                       VK_SHARING_MODE_EXCLUSIVE,                                              // VkSharingMode                        sharingMode;
+                       1u,                                                                                             // deUint32                                     queueFamilyIndexCount;
+                       &m_queueFamilyIndex,                                                    // const deUint32*                      pQueueFamilyIndices;
+                       VK_IMAGE_LAYOUT_UNDEFINED                                               // VkImageLayout                        initialLayout;
+               };
+
+               m_textureImages.push_back(VkImageSp(new Unique<VkImage>(createImage(m_vkd, *m_device, &textureImageParams))));
+
+               // Allocate and bind texture image memory
+               m_textureImageAllocs.push_back(AllocationSp(m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, **m_textureImages.back()), MemoryRequirement::Any).release()));
+               VK_CHECK(m_vkd.bindImageMemory(*m_device, **m_textureImages.back(), m_textureImageAllocs.back()->getMemory(), m_textureImageAllocs.back()->getOffset()));
+       }
+
+       // Create texture image views
+       for (deUint32 texIdx = 0; texIdx < 2; texIdx++)
+       {
+               const VkImageViewCreateInfo textureViewParams =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
+                       DE_NULL,                                                                                // const void*                          pNext;
+                       0u,                                                                                             // VkImageViewCreateFlags       flags;
+                       **m_textureImages[texIdx],                                              // VkImage                                      image;
+                       VK_IMAGE_VIEW_TYPE_2D,                                                  // VkImageViewType                      viewType;
+                       m_colorFormat,                                                                  // VkFormat                                     format;
+                       componentMappingRGBA,                                                   // VkChannelMapping                     channels;
+                       { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }   // VkImageSubresourceRange      subresourceRange;
+               };
+
+               m_textureViews.push_back(VkImageViewSp(new Unique<VkImageView>(createImageView(m_vkd, *m_device, &textureViewParams))));
+       }
+
+       VkClearValue    clearValues[2];
+       clearValues[0].color.float32[0] = 0.0f;
+       clearValues[0].color.float32[1] = 1.0f;
+       clearValues[0].color.float32[2] = 0.0f;
+       clearValues[0].color.float32[3] = 1.0f;
+       clearValues[1].color.float32[0] = 1.0f;
+       clearValues[1].color.float32[1] = 0.0f;
+       clearValues[1].color.float32[2] = 0.0f;
+       clearValues[1].color.float32[3] = 1.0f;
+
+       // Clear textures
+       for (deUint32 texIdx = 0; texIdx < 2; texIdx++)
+       {
+               const VkImageAspectFlags        aspectMask      = VK_IMAGE_ASPECT_COLOR_BIT;
+               Move<VkCommandPool>                     cmdPool;
+               Move<VkCommandBuffer>           cmdBuffer;
+
+               cmdPool         = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
+               cmdBuffer       = allocateCommandBuffer(m_vkd, *m_device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+
+               const VkImageMemoryBarrier preImageBarrier =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType                      sType;
+                       DE_NULL,                                                                // const void*                          pNext;
+                       0u,                                                                             // VkAccessFlags                        srcAccessMask;
+                       VK_ACCESS_TRANSFER_WRITE_BIT,                   // VkAccessFlags                        dstAccessMask;
+                       VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                        oldLayout;
+                       VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout                        newLayout;
+                       VK_QUEUE_FAMILY_IGNORED,                                // deUint32                                     srcQueueFamilyIndex;
+                       VK_QUEUE_FAMILY_IGNORED,                                // deUint32                                     dstQueueFamilyIndex;
+                       **m_textureImages[texIdx],                              // VkImage                                      image;
+                       {                                                                               // VkImageSubresourceRange      subresourceRange;
+                               aspectMask,                                                     // VkImageAspect                        aspect;
+                               0u,                                                                     // deUint32                                     baseMipLevel;
+                               1u,                                                                     // deUint32                                     mipLevels;
+                               0u,                                                                     // deUint32                                     baseArraySlice;
+                               1u                                                                      // deUint32                                     arraySize;
+                       }
+               };
+
+               const VkImageMemoryBarrier postImageBarrier =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
+                       DE_NULL,                                                                        // const void*                          pNext;
+                       VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
+                       VK_ACCESS_SHADER_READ_BIT,                                      // VkAccessFlags                        dstAccessMask;
+                       VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
+                       VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,       // VkImageLayout                        newLayout;
+                       VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
+                       VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
+                       **m_textureImages[texIdx],                                      // VkImage                                      image;
+                       {                                                                                       // VkImageSubresourceRange      subresourceRange;
+                               aspectMask,                                                             // VkImageAspect                        aspect;
+                               0u,                                                                             // deUint32                                     baseMipLevel;
+                               1u,                                                                             // deUint32                                     mipLevels;
+                               0u,                                                                             // deUint32                                     baseArraySlice;
+                               1u                                                                              // deUint32                                     arraySize;
+                       }
+               };
+
+               const VkImageSubresourceRange clearRange        =
+               {
+                       aspectMask,     // VkImageAspectFlags   aspectMask;
+                       0u,                     // deUint32                             baseMipLevel;
+                       1u,                     // deUint32                             levelCount;
+                       0u,                     // deUint32                             baseArrayLayer;
+                       1u                      // deUint32                             layerCount;
+               };
+
+               beginCommandBuffer(m_vkd, *cmdBuffer);
+               m_vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
+               m_vkd.cmdClearColorImage(*cmdBuffer, **m_textureImages[texIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValues[texIdx].color, 1, &clearRange);
+               m_vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
+               endCommandBuffer(m_vkd, *cmdBuffer);
+
+               submitCommandsAndWait(m_vkd, *m_device, m_queue, cmdBuffer.get());
+       }
+
+       // Create samplers: one with white and one with black border color to have a visible effect on switching the sampler
+       {
+               VkSamplerCreateInfo samplerParams =
+               {
+                       VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,          // VkStructureType              sType;
+                       DE_NULL,                                                                        // const void*                  pNext;
+                       0u,                                                                                     // VkSamplerCreateFlags flags;
+                       VK_FILTER_NEAREST,                                                      // VkFilter                             magFilter;
+                       VK_FILTER_NEAREST,                                                      // VkFilter                             minFilter;
+                       VK_SAMPLER_MIPMAP_MODE_NEAREST,                         // VkSamplerMipmapMode  mipmapMode;
+                       VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,        // VkSamplerAddressMode addressModeU;
+                       VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,        // VkSamplerAddressMode addressModeV;
+                       VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,        // VkSamplerAddressMode addressModeW;
+                       0.0f,                                                                           // float                                mipLodBias;
+                       VK_FALSE,                                                                       // VkBool32                             anisotropyEnable;
+                       0.0f,                                                                           // float                                maxAnisotropy;
+                       VK_FALSE,                                                                       // VkBool32                             compareEnable;
+                       VK_COMPARE_OP_NEVER,                                            // VkCompareOp                  compareOp;
+                       0.0f,                                                                           // float                                minLod;
+                       0.0f,                                                                           // float                                maxLod;
+                       VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,                     // VkBorderColor                borderColor;
+                       VK_FALSE                                                                        // VkBool32                             unnormalizedCoordinates;
+               };
+
+               m_whiteBorderSampler = createSampler(m_vkd, *m_device, &samplerParams);
+               samplerParams.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
+               m_blackBorderSampler = createSampler(m_vkd, *m_device, &samplerParams);
+       }
+
+       // Create render pass
+       {
+               const VkAttachmentDescription   attachmentDescription   =
+               {
+                       (VkAttachmentDescriptionFlags)0,                        // VkAttachmentDescriptionFlags flags
+                       VK_FORMAT_R8G8B8A8_UNORM,                                       // VkFormat                                             format
+                       VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits                samples
+                       VK_ATTACHMENT_LOAD_OP_CLEAR,                            // VkAttachmentLoadOp                   loadOp
+                       VK_ATTACHMENT_STORE_OP_STORE,                           // VkAttachmentStoreOp                  storeOp
+                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        // VkAttachmentLoadOp                   stencilLoadOp
+                       VK_ATTACHMENT_STORE_OP_DONT_CARE,                       // VkAttachmentStoreOp                  stencilStoreOp
+                       VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                                initialLayout
+                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout                                finalLayout
+               };
+
+               const VkAttachmentReference             resultAttachmentRef             =
+               {
+                       0u,                                                                                     // deUint32                     attachment
+                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout        layout
+               };
+
+               const VkSubpassDescription              subpassDescription              =
+               {
+                       (VkSubpassDescriptionFlags)0,                           // VkSubpassDescriptionFlags    flags
+                       VK_PIPELINE_BIND_POINT_GRAPHICS,                        // VkPipelineBindPoint                  pipelineBindPoint
+                       0u,                                                                                     // deUint32                                             inputAttachmentCount
+                       DE_NULL,                                                                        // const VkAttachmentReference* pInputAttachments
+                       1u,                                                                                     // deUint32                                             colorAttachmentCount
+                       &resultAttachmentRef,                                           // const VkAttachmentReference* pColorAttachments
+                       DE_NULL,                                                                        // const VkAttachmentReference* pResolveAttachments
+                       DE_NULL,                                                                        // const VkAttachmentReference* pDepthStencilAttachment
+                       0u,                                                                                     // deUint32                                             preserveAttachmentCount
+                       DE_NULL                                                                         // const deUint32*                              pPreserveAttachments
+               };
+
+               const VkRenderPassCreateInfo    renderPassInfo                  =
+               {
+                       VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,      // VkStructureTypei                                     sType
+                       DE_NULL,                                                                        // const void*                                          pNext
+                       (VkRenderPassCreateFlags)0,                                     // VkRenderPassCreateFlags                      flags
+                       1u,                                                                                     // deUint32                                                     attachmentCount
+                       &attachmentDescription,                                         // const VkAttachmentDescription*       pAttachments
+                       1u,                                                                                     // deUint32                                                     subpassCount
+                       &subpassDescription,                                            // const VkSubpassDescription*          pSubpasses
+                       0u,                                                                                     // deUint32                                                     dependencyCount
+                       DE_NULL                                                                         // const VkSubpassDependency*           pDependencies
+               };
+
+               m_renderPass = createRenderPass(m_vkd, *m_device, &renderPassInfo);
+       }
+
+       // Create framebuffer
+       {
+               const VkImageView                               attachmentBindInfos[]   =
+               {
+                       *m_colorAttachmentView
+               };
+
+               const VkFramebufferCreateInfo   framebufferParams               =
+               {
+                       VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,      // VkStructureType                      sType;
+                       DE_NULL,                                                                        // const void*                          pNext;
+                       0u,                                                                                     // VkFramebufferCreateFlags     flags;
+                       *m_renderPass,                                                          // VkRenderPass                         renderPass;
+                       1u,                                                                                     // deUint32                                     attachmentCount;
+                       attachmentBindInfos,                                            // const VkImageView*           pAttachments;
+                       (deUint32)m_renderSize.x(),                                     // deUint32                                     width;
+                       (deUint32)m_renderSize.y(),                                     // deUint32                                     height;
+                       1u                                                                                      // deUint32                                     layers;
+               };
+
+               m_framebuffer = createFramebuffer(m_vkd, *m_device, &framebufferParams);
+       }
+
+       // Create pipeline layout
+       {
+               // Create descriptor set layout
+               vector<VkDescriptorSetLayoutBinding>    layoutBindings;
+
+               switch(m_params.descriptorType)
+               {
+                       case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+                               {
+                                       const VkDescriptorSetLayoutBinding              descriptorSetLayoutBinding              =
+                                       {
+                                               m_params.binding,                                                       // uint32_t                             binding;
+                                               VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,      // VkDescriptorType             descriptorType;
+                                               1u,                                                                                     // uint32_t                             descriptorCount;
+                                               VK_SHADER_STAGE_FRAGMENT_BIT,                           // VkShaderStageFlags   stageFlags;
+                                               DE_NULL                                                                         // const VkSampler*             pImmutableSamplers;
+                                       };
+                                       layoutBindings.push_back(descriptorSetLayoutBinding);
+                               }
                                break;
 
-                       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
-                               testName += "_storage_buffer";
-                               graphicsTests->addChild(new PushDescriptorBufferGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
-                               computeTests->addChild(new PushDescriptorBufferComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
+                       case VK_DESCRIPTOR_TYPE_SAMPLER:
+                               {
+                                       const VkDescriptorSetLayoutBinding              descriptorSetLayoutBindingSampler       =
+                                       {
+                                               m_params.binding,                               // uint32_t                             binding;
+                                               VK_DESCRIPTOR_TYPE_SAMPLER,             // VkDescriptorType             descriptorType;
+                                               1u,                                                             // uint32_t                             descriptorCount;
+                                               VK_SHADER_STAGE_FRAGMENT_BIT,   // VkShaderStageFlags   stageFlags;
+                                               DE_NULL                                                 // const VkSampler*             pImmutableSamplers;
+                                       };
+                                       const VkDescriptorSetLayoutBinding              descriptorSetLayoutBindingTex   =
+                                       {
+                                               m_params.binding + 1,                           // uint32_t                             binding;
+                                               VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,       // VkDescriptorType             descriptorType;
+                                               1u,                                                                     // uint32_t                             descriptorCount;
+                                               VK_SHADER_STAGE_FRAGMENT_BIT,           // VkShaderStageFlags   stageFlags;
+                                               DE_NULL                                                         // const VkSampler*             pImmutableSamplers;
+                                       };
+                                       layoutBindings.push_back(descriptorSetLayoutBindingSampler);
+                                       layoutBindings.push_back(descriptorSetLayoutBindingTex);
+                               }
+                               break;
+
+                       case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
+                               {
+                                       const VkDescriptorSetLayoutBinding              descriptorSetLayoutBindingSampler       =
+                                       {
+                                               m_params.binding + 1,                   // uint32_t                             binding;
+                                               VK_DESCRIPTOR_TYPE_SAMPLER,             // VkDescriptorType             descriptorType;
+                                               1u,                                                             // uint32_t                             descriptorCount;
+                                               VK_SHADER_STAGE_FRAGMENT_BIT,   // VkShaderStageFlags   stageFlags;
+                                               DE_NULL                                                 // const VkSampler*             pImmutableSamplers;
+                                       };
+                                       const VkDescriptorSetLayoutBinding              descriptorSetLayoutBindingTex   =
+                                       {
+                                               m_params.binding,                                       // uint32_t                             binding;
+                                               VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,       // VkDescriptorType             descriptorType;
+                                               1u,                                                                     // uint32_t                             descriptorCount;
+                                               VK_SHADER_STAGE_FRAGMENT_BIT,           // VkShaderStageFlags   stageFlags;
+                                               DE_NULL                                                         // const VkSampler*             pImmutableSamplers;
+                                       };
+                                       layoutBindings.push_back(descriptorSetLayoutBindingSampler);
+                                       layoutBindings.push_back(descriptorSetLayoutBindingTex);
+                               }
+                               break;
+
+                       case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+                               {
+                                       const VkDescriptorSetLayoutBinding              descriptorSetLayoutBinding              =
+                                       {
+                                               m_params.binding,                                       // uint32_t                             binding;
+                                               VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,       // VkDescriptorType             descriptorType;
+                                               1u,                                                                     // uint32_t                             descriptorCount;
+                                               VK_SHADER_STAGE_FRAGMENT_BIT,           // VkShaderStageFlags   stageFlags;
+                                               DE_NULL                                                         // const VkSampler*             pImmutableSamplers;
+                                       };
+                                       layoutBindings.push_back(descriptorSetLayoutBinding);
+                               }
+                               break;
+
+                       default:
+                               DE_FATAL("unexpected descriptor type");
+                               break;
+               };
+
+               const VkDescriptorSetLayoutCreateInfo   descriptorSetLayoutCreateInfo   =
+               {
+                       VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,            // VkStructureType                                              sType;
+                       DE_NULL,                                                                                                        // const void*                                                  pNext;
+                       VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,        // VkDescriptorSetLayoutCreateFlags             flags;
+                       (deUint32)layoutBindings.size(),                                                        // uint32_t                                                             bindingCount;
+                       layoutBindings.data()                                                                           // const VkDescriptorSetLayoutBinding*  pBindings;
+               };
+
+               m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, DE_NULL);
+
+               // Create pipeline layout
+               const VkPipelineLayoutCreateInfo                pipelineLayoutParams                    =
+               {
+                       VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,  // VkStructureType                              sType;
+                       DE_NULL,                                                                                // const void*                                  pNext;
+                       0u,                                                                                             // VkPipelineLayoutCreateFlags  flags;
+                       1u,                                                                                             // deUint32                                             descriptorSetCount;
+                       &(*m_descriptorSetLayout),                                              // const VkDescriptorSetLayout* pSetLayouts;
+                       0u,                                                                                             // deUint32                                             pushConstantRangeCount;
+                       DE_NULL                                                                                 // const VkPushDescriptorRange* pPushDescriptorRanges;
+               };
+
+               m_pipelineLayout = createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
+       }
+
+       // Create shaders
+       {
+               m_vertexShaderModule    = createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("vert"), 0u);
+               m_fragmentShaderModule  = createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("frag"), 0u);
+       }
+
+       // Create pipeline
+       {
+               const VkVertexInputBindingDescription           vertexInputBindingDescription           =
+               {
+                       0u,                                                     // deUint32                                     binding;
+                       sizeof(Vertex4Tex4),            // deUint32                                     strideInBytes;
+                       VK_VERTEX_INPUT_RATE_VERTEX     // VkVertexInputStepRate        stepRate;
+               };
+
+               const VkVertexInputAttributeDescription         vertexInputAttributeDescriptions[]      =
+               {
+                       {
+                               0u,                                                                             // deUint32     location;
+                               0u,                                                                             // deUint32     binding;
+                               VK_FORMAT_R32G32B32A32_SFLOAT,                  // VkFormat     format;
+                               0u                                                                              // deUint32     offsetInBytes;
+                       },
+                       {
+                               1u,                                                                             // deUint32     location;
+                               0u,                                                                             // deUint32     binding;
+                               VK_FORMAT_R32G32B32A32_SFLOAT,                  // VkFormat     format;
+                               DE_OFFSET_OF(Vertex4Tex4, texCoord),    // deUint32     offset;
+                       }
+               };
+
+               const VkPipelineVertexInputStateCreateInfo      vertexInputStateParams                          =
+               {
+                       VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,      // VkStructureType                                                      sType;
+                       DE_NULL,                                                                                                        // const void*                                                          pNext;
+                       0u,                                                                                                                     // vkPipelineVertexInputStateCreateFlags        flags;
+                       1u,                                                                                                                     // deUint32                                                                     bindingCount;
+                       &vertexInputBindingDescription,                                                         // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
+                       2u,                                                                                                                     // deUint32                                                                     attributeCount;
+                       vertexInputAttributeDescriptions                                                        // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
+               };
+
+               const VkPrimitiveTopology                                       topology                                                        = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
+
+               const vector<VkViewport>                                        viewports                                                       (1, makeViewport(m_renderSize));
+               const vector<VkRect2D>                                          scissors                                                        (1, makeRect2D(m_renderSize));
+
+               m_graphicsPipelines = makeGraphicsPipeline(m_vkd,                                               // const DeviceInterface&                                               vk
+                                                                                                  *m_device,                                   // const VkDevice                                                               device
+                                                                                                  *m_pipelineLayout,                   // const VkPipelineLayout                                               pipelineLayout
+                                                                                                  *m_vertexShaderModule,               // const VkShaderModule                                                 vertexShaderModule
+                                                                                                  DE_NULL,                                             // const VkShaderModule                                                 tessellationControlShaderModule
+                                                                                                  DE_NULL,                                             // const VkShaderModule                                                 tessellationEvalShaderModule
+                                                                                                  DE_NULL,                                             // const VkShaderModule                                                 geometryShaderModule
+                                                                                                  *m_fragmentShaderModule,             // const VkShaderModule                                                 fragmentShaderModule
+                                                                                                  *m_renderPass,                               // const VkRenderPass                                                   renderPass
+                                                                                                  viewports,                                   // const std::vector<VkViewport>&                               viewports
+                                                                                                  scissors,                                    // const std::vector<VkRect2D>&                                 scissors
+                                                                                                  topology,                                    // const VkPrimitiveTopology                                    topology
+                                                                                                  0u,                                                  // const deUint32                                                               subpass
+                                                                                                  0u,                                                  // const deUint32                                                               patchControlPoints
+                                                                                                  &vertexInputStateParams);    // const VkPipelineVertexInputStateCreateInfo*  vertexInputStateCreateInfo
+       }
+
+       // Create vertex buffer
+       {
+               const VkBufferCreateInfo vertexBufferParams =
+               {
+                       VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,                                           // VkStructureType              sType;
+                       DE_NULL,                                                                                                        // const void*                  pNext;
+                       0u,                                                                                                                     // VkBufferCreateFlags  flags;
+                       (VkDeviceSize)(sizeof(Vertex4RGBA) * m_vertices.size()),        // VkDeviceSize                 size;
+                       VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                                                      // VkBufferUsageFlags   usage;
+                       VK_SHARING_MODE_EXCLUSIVE,                                                                      // VkSharingMode                sharingMode;
+                       1u,                                                                                                                     // deUint32                             queueFamilyCount;
+                       &m_queueFamilyIndex                                                                                     // const deUint32*              pQueueFamilyIndices;
+               };
+
+               m_vertexBuffer          = createBuffer(m_vkd, *m_device, &vertexBufferParams);
+               m_vertexBufferAlloc     = m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_vertexBuffer), MemoryRequirement::HostVisible);
+
+               VK_CHECK(m_vkd.bindBufferMemory(*m_device, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
+
+               // Load vertices into vertex buffer
+               deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4Tex4));
+               flushMappedMemoryRange(m_vkd, *m_device, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset(), vertexBufferParams.size);
+       }
+
+       // Create command pool
+       m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
+
+       // Create command buffer
+       {
+               const VkClearValue      attachmentClearValue    = defaultClearValue(m_colorFormat);
+               const VkDeviceSize      vertexBufferOffset              = 0;
+
+               m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+               beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
+               beginRenderPass(m_vkd, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), attachmentClearValue);
+               m_vkd.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines);
+               m_vkd.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
+
+               // Draw quads. Switch sampler or image view depending on the test.
+               vector<VkSampler>       samplers;
+               vector<VkImageView> imageViews;
+
+               samplers.push_back(*m_whiteBorderSampler);
+               if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
+               {
+                       // Vary sampler between draws
+                       samplers.push_back(*m_blackBorderSampler);
+               }
+               else
+               {
+                       // Usa a single sampler
+                       samplers.push_back(*m_whiteBorderSampler);
+               }
+
+               imageViews.push_back(**m_textureViews[0]);
+               if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
+               {
+                       // Vary image view between draws
+                       imageViews.push_back(**m_textureViews[1]);
+               }
+               else
+               {
+                       // Usa a single image view
+                       imageViews.push_back(**m_textureViews[0]);
+               }
+
+               for (deUint32 quadNdx = 0; quadNdx < m_params.numCalls; quadNdx++)
+               {
+                       VkDescriptorImageInfo   descriptorImageInfo     =
+                       {
+                               samplers[quadNdx],                                                      // VkSampler            sampler;
+                               imageViews[quadNdx],                                            // VkImageView          imageView;
+                               VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL        // VkImageLayout        imageLayout;
+                       };
+
+                       VkWriteDescriptorSet    writeDescriptorSet      =
+                       {
+                               VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType                                      sType;
+                               DE_NULL,                                                                // const void*                                          pNext;
+                               0u,                                                                             // VkDescriptorSet                                      dstSet;
+                               m_params.binding,                                               // uint32_t                                                     dstBinding;
+                               0u,                                                                             // uint32_t                                                     dstArrayElement;
+                               1u,                                                                             // uint32_t                                                     descriptorCount;
+                               m_params.descriptorType,                                // VkDescriptorType                                     descriptorType;
+                               &descriptorImageInfo,                                   // const VkDescriptorImageInfo*         pImageInfo;
+                               DE_NULL,                                                                // const VkDescriptorBufferInfo*        pBufferInfo;
+                               DE_NULL                                                                 // const VkBufferView*                          pTexelBufferView;
+                       };
+
+                       vector<VkWriteDescriptorSet> writeDescriptorSets;
+                       writeDescriptorSets.push_back(writeDescriptorSet);
+
+                       if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
+                       {
+                               // Sampler also needs an image.
+                               writeDescriptorSet.dstBinding++;
+                               writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
+                               writeDescriptorSets.push_back(writeDescriptorSet);
+                       }
+                       else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
+                       {
+                               // Image also needs a sampler.
+                               writeDescriptorSet.dstBinding++;
+                               writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
+                               writeDescriptorSets.push_back(writeDescriptorSet);
+                       }
+
+                       m_vkd.cmdPushDescriptorSetKHR(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, (deUint32)writeDescriptorSets.size(), writeDescriptorSets.data());
+                       m_vkd.cmdDraw(*m_cmdBuffer, 6, 1, 6 * quadNdx, 0);
+               }
+
+               endRenderPass(m_vkd, *m_cmdBuffer);
+               endCommandBuffer(m_vkd, *m_cmdBuffer);
+       }
+}
+
+PushDescriptorImageGraphicsTestInstance::~PushDescriptorImageGraphicsTestInstance (void)
+{
+}
+
+tcu::TestStatus PushDescriptorImageGraphicsTestInstance::iterate (void)
+{
+       init();
+
+       submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());
+
+       return verifyImage();
+}
+
+tcu::TestStatus PushDescriptorImageGraphicsTestInstance::verifyImage (void)
+{
+       const tcu::TextureFormat        tcuColorFormat  = mapVkFormat(m_colorFormat);
+       const tcu::TextureFormat        tcuDepthFormat  = tcu::TextureFormat();
+       const ColorVertexShader         vertexShader;
+       const ColorFragmentShader       fragmentShader  (tcuColorFormat, tcuDepthFormat);
+       const rr::Program                       program                 (&vertexShader, &fragmentShader);
+       ReferenceRenderer                       refRenderer             (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
+       bool                                            compareOk               = false;
+
+       // Render reference image
+       {
+               vector<Vertex4RGBA>     refQuadsOuter   = createQuads(m_params.numCalls, 0.25f);
+               vector<Vertex4RGBA>     refQuadsInner   = createQuads(m_params.numCalls, 0.25f * 0.8f);
+               tcu::Vec4                       outerColor[2];
+               tcu::Vec4                       innerColor[2];
+               const bool                      hasBorder               = m_params.descriptorType != VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
+
+               if (hasBorder)
+               {
+                       outerColor[0] = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
+                       innerColor[0] = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
+                       if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
+                               outerColor[1] = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
+                       else
+                               outerColor[1] = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
+                       if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
+                               innerColor[1] = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
+                       else
+                               innerColor[1] = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
+               }
+               else
+               {
+                       outerColor[0] = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
+                       outerColor[1] = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
+               }
+
+               for (deUint32 quadIdx = 0; quadIdx < m_params.numCalls; quadIdx++)
+                       for (deUint32 vertexIdx = 0; vertexIdx < 6; vertexIdx++)
+                       {
+                               const deUint32 idx = quadIdx * 6 + vertexIdx;
+                               refQuadsOuter[idx].color.xyzw() = outerColor[quadIdx];
+                               refQuadsInner[idx].color.xyzw() = innerColor[quadIdx];
+                       }
+
+               if (hasBorder)
+                       refQuadsOuter.insert(refQuadsOuter.end(), refQuadsInner.begin(), refQuadsInner.end());
+
+               refRenderer.draw(rr::RenderState(refRenderer.getViewportState()), rr::PRIMITIVETYPE_TRIANGLES, refQuadsOuter);
+       }
+
+       // Compare result with reference image
+       {
+               de::MovePtr<tcu::TextureLevel> result = readColorAttachment(m_vkd, *m_device, m_queue, m_queueFamilyIndex, m_allocator, *m_colorImage, m_colorFormat, m_renderSize);
+
+               compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
+                                                                                                                         "IntImageCompare",
+                                                                                                                         "Image comparison",
+                                                                                                                         refRenderer.getAccess(),
+                                                                                                                         result->getAccess(),
+                                                                                                                         tcu::UVec4(2, 2, 2, 2),
+                                                                                                                         tcu::IVec3(1, 1, 0),
+                                                                                                                         true,
+                                                                                                                         tcu::COMPARE_LOG_RESULT);
+       }
+
+       if (compareOk)
+               return tcu::TestStatus::pass("Result image matches reference");
+       else
+               return tcu::TestStatus::fail("Image mismatch");
+}
+
+class PushDescriptorImageGraphicsTest : public vkt::TestCase
+{
+public:
+                                               PushDescriptorImageGraphicsTest         (tcu::TestContext&      testContext,
+                                                                                                                        const string&          name,
+                                                                                                                        const string&          description,
+                                                                                                                        const TestParams&      params);
+                                               ~PushDescriptorImageGraphicsTest        (void);
+       void                            initPrograms                                            (SourceCollections& sourceCollections) const;
+       TestInstance*           createInstance                                          (Context& context) const;
+
+protected:
+       const TestParams        m_params;
+};
+
+PushDescriptorImageGraphicsTest::PushDescriptorImageGraphicsTest       (tcu::TestContext&      testContext,
+                                                                                                                                       const string&           name,
+                                                                                                                                       const string&           description,
+                                                                                                                                       const TestParams&       params)
+       : vkt::TestCase (testContext, name, description)
+       , m_params              (params)
+{
+}
+
+PushDescriptorImageGraphicsTest::~PushDescriptorImageGraphicsTest (void)
+{
+}
+
+TestInstance* PushDescriptorImageGraphicsTest::createInstance (Context& context) const
+{
+       return new PushDescriptorImageGraphicsTestInstance(context, m_params);
+}
+
+void PushDescriptorImageGraphicsTest::initPrograms (SourceCollections& sourceCollections) const
+{
+       const string    vertexSrc       =
+               "#version 450\n"
+               "layout(location = 0) in highp vec4 position;\n"
+               "layout(location = 1) in highp vec4 texcoordVtx;\n"
+               "layout(location = 0) out highp vec2 texcoordFrag;\n"
+               "\n"
+               "out gl_PerVertex { vec4 gl_Position; };\n"
+               "\n"
+               "void main()\n"
+               "{\n"
+               "       gl_Position = position;\n"
+               "       texcoordFrag = texcoordVtx.xy;\n"
+               "}\n";
+
+       sourceCollections.glslSources.add("vert") << glu::VertexSource(vertexSrc);
+
+       if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
+       {
+               const string    fragmentSrc     =
+                       "#version 450\n"
+                       "layout(location = 0) in highp vec2 texcoordFrag;\n"
+                       "layout(location = 0) out highp vec4 fragColor;\n"
+                       "layout(set = 0, binding = " + de::toString(m_params.binding) + ") uniform sampler2D combinedSampler;\n"
+                       "\n"
+                       "void main (void)\n"
+                       "{\n"
+                       "       fragColor = texture(combinedSampler, texcoordFrag);\n"
+                       "}\n";
+
+               sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
+       }
+       else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
+       {
+               const string    fragmentSrc     =
+                       "#version 450\n"
+                       "layout(location = 0) in highp vec2 texcoordFrag;\n"
+                       "layout(location = 0) out highp vec4 fragColor;\n"
+                       "layout(set = 0, binding = " + de::toString(m_params.binding) + ") uniform sampler texSampler;\n"
+                       "layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") uniform texture2D texImage;\n"
+                       "\n"
+                       "void main (void)\n"
+                       "{\n"
+                       "       fragColor = texture(sampler2D(texImage, texSampler), texcoordFrag);\n"
+                       "}\n";
+
+               sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
+       }
+       else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
+       {
+               const string    fragmentSrc     =
+                       "#version 450\n"
+                       "layout(location = 0) in highp vec2 texcoordFrag;\n"
+                       "layout(location = 0) out highp vec4 fragColor;\n"
+                       "layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") uniform sampler texSampler;\n"
+                       "layout(set = 0, binding = " + de::toString(m_params.binding) + ") uniform texture2D texImage;\n"
+                       "\n"
+                       "void main (void)\n"
+                       "{\n"
+                       "       fragColor = texture(sampler2D(texImage, texSampler), texcoordFrag);\n"
+                       "}\n";
+
+               sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
+       }
+       else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
+       {
+               const string    fragmentSrc     =
+                       "#version 450\n"
+                       "layout(location = 0) in highp vec2 texcoordFrag;\n"
+                       "layout(location = 0) out highp vec4 fragColor;\n"
+                       "layout(set = 0, binding = " + de::toString(m_params.binding) + ", rgba8) uniform readonly image2D storageImage;\n"
+                       "\n"
+                       "void main (void)\n"
+                       "{\n"
+                       "       fragColor = imageLoad(storageImage, ivec2(0));\n"
+                       "}\n";
+
+               sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
+       }
+       else
+       {
+               DE_FATAL("Unexpected descriptor type");
+       }
+}
+
+class PushDescriptorImageComputeTestInstance : public vkt::TestInstance
+{
+public:
+                                                               PushDescriptorImageComputeTestInstance  (Context& context, const TestParams& params);
+       virtual                                         ~PushDescriptorImageComputeTestInstance (void);
+       void                                            init                                                                    (void);
+       virtual tcu::TestStatus         iterate                                                                 (void);
+       tcu::TestStatus                         verifyOutput                                                    (void);
+
+private:
+       const TestParams                        m_params;
+       const PlatformInterface&        m_vkp;
+       const Extensions                        m_instanceExtensions;
+       const Unique<VkInstance>        m_instance;
+       const InstanceDriver            m_vki;
+       const VkPhysicalDevice          m_physicalDevice;
+       const deUint32                          m_queueFamilyIndex;
+       const Extensions                        m_deviceExtensions;
+       const Unique<VkDevice>          m_device;
+       const DeviceDriver                      m_vkd;
+       const VkQueue                           m_queue;
+       SimpleAllocator                         m_allocator;
+       const tcu::UVec2                        m_textureSize;
+       const VkFormat                          m_colorFormat;
+       Move<VkShaderModule>            m_computeShaderModule;
+       vector<VkImageSp>                       m_textureImages;
+       vector<AllocationSp>            m_textureImageAllocs;
+       vector<VkImageViewSp>           m_textureViews;
+       Move<VkSampler>                         m_whiteBorderSampler;
+       Move<VkSampler>                         m_blackBorderSampler;
+       Move<VkBuffer>                          m_outputBuffer;
+       de::MovePtr<Allocation>         m_outputBufferAlloc;
+       Move<VkDescriptorSetLayout>     m_descriptorSetLayout;
+       Move<VkPipelineLayout>          m_pipelineLayout;
+       Move<VkPipeline>                        m_computePipeline;
+       Move<VkCommandPool>                     m_cmdPool;
+       Move<VkCommandBuffer>           m_cmdBuffer;
+       deUint32                                        m_outputBufferBinding;
+};
+
+PushDescriptorImageComputeTestInstance::PushDescriptorImageComputeTestInstance (Context& context, const TestParams& params)
+       : vkt::TestInstance             (context)
+       , m_params                              (params)
+       , m_vkp                                 (context.getPlatformInterface())
+       , m_instanceExtensions  (enumerateInstanceExtensionProperties(m_vkp, DE_NULL))
+       , m_instance                    (createInstanceWithGetPhysicalDeviceProperties2(m_vkp, context.getUsedApiVersion(), m_instanceExtensions))
+       , m_vki                                 (m_vkp, *m_instance)
+       , m_physicalDevice              (chooseDevice(m_vki, *m_instance, context.getTestContext().getCommandLine()))
+       , m_queueFamilyIndex    (findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT))
+       , m_deviceExtensions    (enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
+       , m_device                              (createDeviceWithPushDescriptor(m_vkp, *m_instance, m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex))
+       , m_vkd                                 (m_vkp, *m_instance, *m_device)
+       , m_queue                               (getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
+       , m_allocator                   (m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
+       , m_textureSize                 (32, 32)
+       , m_colorFormat                 (VK_FORMAT_R8G8B8A8_UNORM)
+       , m_outputBufferBinding (0)
+{
+}
+
+void PushDescriptorImageComputeTestInstance::init (void)
+{
+       const VkComponentMapping                componentMappingRGBA    = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
+
+       // Create texture images
+       for (deUint32 texIdx = 0; texIdx < 2; texIdx++)
+       {
+               VkImageUsageFlags                       usageFlags                      = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+               if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
+                       usageFlags |= VK_IMAGE_USAGE_SAMPLED_BIT;
+               if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
+                       usageFlags |= VK_IMAGE_USAGE_STORAGE_BIT;
+
+               const VkImageCreateInfo         textureImageParams      =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                    // VkStructureType                      sType;
+                       DE_NULL,                                                                                // const void*                          pNext;
+                       0u,                                                                                             // VkImageCreateFlags           flags;
+                       VK_IMAGE_TYPE_2D,                                                               // VkImageType                          imageType;
+                       m_colorFormat,                                                                  // VkFormat                                     format;
+                       { m_textureSize.x(), m_textureSize.y(), 1u },   // VkExtent3D                           extent;
+                       1u,                                                                                             // deUint32                                     mipLevels;
+                       1u,                                                                                             // deUint32                                     arrayLayers;
+                       VK_SAMPLE_COUNT_1_BIT,                                                  // VkSampleCountFlagBits        samples;
+                       VK_IMAGE_TILING_OPTIMAL,                                                // VkImageTiling                        tiling;
+                       usageFlags,                                                                             // VkImageUsageFlags            usage;
+                       VK_SHARING_MODE_EXCLUSIVE,                                              // VkSharingMode                        sharingMode;
+                       1u,                                                                                             // deUint32                                     queueFamilyIndexCount;
+                       &m_queueFamilyIndex,                                                    // const deUint32*                      pQueueFamilyIndices;
+                       VK_IMAGE_LAYOUT_UNDEFINED                                               // VkImageLayout                        initialLayout;
+               };
+
+               m_textureImages.push_back(VkImageSp(new Unique<VkImage>(createImage(m_vkd, *m_device, &textureImageParams))));
+
+               // Allocate and bind texture image memory
+               m_textureImageAllocs.push_back(AllocationSp(m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, **m_textureImages.back()), MemoryRequirement::Any).release()));
+               VK_CHECK(m_vkd.bindImageMemory(*m_device, **m_textureImages.back(), m_textureImageAllocs.back()->getMemory(), m_textureImageAllocs.back()->getOffset()));
+       }
+
+       // Create texture image views
+       for (deUint32 texIdx = 0; texIdx < 2; texIdx++)
+       {
+               const VkImageViewCreateInfo textureViewParams =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
+                       DE_NULL,                                                                                // const void*                          pNext;
+                       0u,                                                                                             // VkImageViewCreateFlags       flags;
+                       **m_textureImages[texIdx],                                              // VkImage                                      image;
+                       VK_IMAGE_VIEW_TYPE_2D,                                                  // VkImageViewType                      viewType;
+                       m_colorFormat,                                                                  // VkFormat                                     format;
+                       componentMappingRGBA,                                                   // VkChannelMapping                     channels;
+                       { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }   // VkImageSubresourceRange      subresourceRange;
+               };
+
+               m_textureViews.push_back(VkImageViewSp(new Unique<VkImageView>(createImageView(m_vkd, *m_device, &textureViewParams))));
+       }
+
+       VkClearValue    clearValues[2];
+       clearValues[0].color.float32[0] = 0.0f;
+       clearValues[0].color.float32[1] = 1.0f;
+       clearValues[0].color.float32[2] = 0.0f;
+       clearValues[0].color.float32[3] = 1.0f;
+       clearValues[1].color.float32[0] = 1.0f;
+       clearValues[1].color.float32[1] = 0.0f;
+       clearValues[1].color.float32[2] = 0.0f;
+       clearValues[1].color.float32[3] = 1.0f;
+
+       // Clear textures
+       for (deUint32 texIdx = 0; texIdx < 2; texIdx++)
+       {
+               const VkImageAspectFlags                aspectMask      = VK_IMAGE_ASPECT_COLOR_BIT;
+               Move<VkCommandPool>                             cmdPool;
+               Move<VkCommandBuffer>                   cmdBuffer;
+
+               cmdPool         = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
+               cmdBuffer       = allocateCommandBuffer(m_vkd, *m_device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+
+               const VkImageMemoryBarrier preImageBarrier =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType                      sType;
+                       DE_NULL,                                                                // const void*                          pNext;
+                       0u,                                                                             // VkAccessFlags                        srcAccessMask;
+                       VK_ACCESS_TRANSFER_WRITE_BIT,                   // VkAccessFlags                        dstAccessMask;
+                       VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                        oldLayout;
+                       VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout                        newLayout;
+                       VK_QUEUE_FAMILY_IGNORED,                                // deUint32                                     srcQueueFamilyIndex;
+                       VK_QUEUE_FAMILY_IGNORED,                                // deUint32                                     dstQueueFamilyIndex;
+                       **m_textureImages[texIdx],                              // VkImage                                      image;
+                       {                                                                               // VkImageSubresourceRange      subresourceRange;
+                               aspectMask,                                                     // VkImageAspect                        aspect;
+                               0u,                                                                     // deUint32                                     baseMipLevel;
+                               1u,                                                                     // deUint32                                     mipLevels;
+                               0u,                                                                     // deUint32                                     baseArraySlice;
+                               1u                                                                      // deUint32                                     arraySize;
+                       }
+               };
+
+               const VkImageMemoryBarrier postImageBarrier =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
+                       DE_NULL,                                                                        // const void*                          pNext;
+                       VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
+                       VK_ACCESS_SHADER_READ_BIT,                                      // VkAccessFlags                        dstAccessMask;
+                       VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
+                       VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,       // VkImageLayout                        newLayout;
+                       VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
+                       VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
+                       **m_textureImages[texIdx],                                      // VkImage                                      image;
+                       {                                                                                       // VkImageSubresourceRange      subresourceRange;
+                               aspectMask,                                                             // VkImageAspect                        aspect;
+                               0u,                                                                             // deUint32                                     baseMipLevel;
+                               1u,                                                                             // deUint32                                     mipLevels;
+                               0u,                                                                             // deUint32                                     baseArraySlice;
+                               1u                                                                              // deUint32                                     arraySize;
+                       }
+               };
+
+               const VkImageSubresourceRange clearRange        =
+               {
+                       aspectMask,     // VkImageAspectFlags   aspectMask;
+                       0u,                     // deUint32                             baseMipLevel;
+                       1u,                     // deUint32                             levelCount;
+                       0u,                     // deUint32                             baseArrayLayer;
+                       1u                      // deUint32                             layerCount;
+               };
+
+               beginCommandBuffer(m_vkd, *cmdBuffer);
+               m_vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
+               m_vkd.cmdClearColorImage(*cmdBuffer, **m_textureImages[texIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValues[texIdx].color, 1, &clearRange);
+               m_vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
+               endCommandBuffer(m_vkd, *cmdBuffer);
+
+               submitCommandsAndWait(m_vkd, *m_device, m_queue, cmdBuffer.get());
+       }
+
+       // Create samplers: one with white and one with black border color to have a visible effect on switching the sampler
+       {
+               VkSamplerCreateInfo samplerParams =
+               {
+                       VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,          // VkStructureType              sType;
+                       DE_NULL,                                                                        // const void*                  pNext;
+                       0u,                                                                                     // VkSamplerCreateFlags flags;
+                       VK_FILTER_NEAREST,                                                      // VkFilter                             magFilter;
+                       VK_FILTER_NEAREST,                                                      // VkFilter                             minFilter;
+                       VK_SAMPLER_MIPMAP_MODE_NEAREST,                         // VkSamplerMipmapMode  mipmapMode;
+                       VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,        // VkSamplerAddressMode addressModeU;
+                       VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,        // VkSamplerAddressMode addressModeV;
+                       VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,        // VkSamplerAddressMode addressModeW;
+                       0.0f,                                                                           // float                                mipLodBias;
+                       VK_FALSE,                                                                       // VkBool32                             anisotropyEnable;
+                       0.0f,                                                                           // float                                maxAnisotropy;
+                       VK_FALSE,                                                                       // VkBool32                             compareEnable;
+                       VK_COMPARE_OP_NEVER,                                            // VkCompareOp                  compareOp;
+                       0.0f,                                                                           // float                                minLod;
+                       0.0f,                                                                           // float                                maxLod;
+                       VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,                     // VkBorderColor                borderColor;
+                       VK_FALSE                                                                        // VkBool32                             unnormalizedCoordinates;
+               };
+
+               m_whiteBorderSampler = createSampler(m_vkd, *m_device, &samplerParams);
+               samplerParams.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
+               m_blackBorderSampler = createSampler(m_vkd, *m_device, &samplerParams);
+       }
+
+       // Create pipeline layout
+       {
+               // Create descriptor set layout
+               vector<VkDescriptorSetLayoutBinding>    layoutBindings;
+
+               switch(m_params.descriptorType)
+               {
+                       case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+                               {
+                                       const VkDescriptorSetLayoutBinding              descriptorSetLayoutBinding              =
+                                       {
+                                               m_params.binding,                                                       // uint32_t                             binding;
+                                               VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,      // VkDescriptorType             descriptorType;
+                                               1u,                                                                                     // uint32_t                             descriptorCount;
+                                               VK_SHADER_STAGE_COMPUTE_BIT,                            // VkShaderStageFlags   stageFlags;
+                                               DE_NULL                                                                         // const VkSampler*             pImmutableSamplers;
+                                       };
+                                       layoutBindings.push_back(descriptorSetLayoutBinding);
+                                       m_outputBufferBinding = m_params.binding + 1;
+                               }
+                               break;
+
+                       case VK_DESCRIPTOR_TYPE_SAMPLER:
+                               {
+                                       const VkDescriptorSetLayoutBinding              descriptorSetLayoutBindingSampler       =
+                                       {
+                                               m_params.binding,                               // uint32_t                             binding;
+                                               VK_DESCRIPTOR_TYPE_SAMPLER,             // VkDescriptorType             descriptorType;
+                                               1u,                                                             // uint32_t                             descriptorCount;
+                                               VK_SHADER_STAGE_COMPUTE_BIT,    // VkShaderStageFlags   stageFlags;
+                                               DE_NULL                                                 // const VkSampler*             pImmutableSamplers;
+                                       };
+                                       const VkDescriptorSetLayoutBinding              descriptorSetLayoutBindingTex   =
+                                       {
+                                               m_params.binding + 1,                           // uint32_t                             binding;
+                                               VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,       // VkDescriptorType             descriptorType;
+                                               1u,                                                                     // uint32_t                             descriptorCount;
+                                               VK_SHADER_STAGE_COMPUTE_BIT,            // VkShaderStageFlags   stageFlags;
+                                               DE_NULL                                                         // const VkSampler*             pImmutableSamplers;
+                                       };
+                                       layoutBindings.push_back(descriptorSetLayoutBindingSampler);
+                                       layoutBindings.push_back(descriptorSetLayoutBindingTex);
+                                       m_outputBufferBinding = m_params.binding + 2;
+                               }
+                               break;
+
+                       case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
+                               {
+                                       const VkDescriptorSetLayoutBinding              descriptorSetLayoutBindingSampler       =
+                                       {
+                                               m_params.binding + 1,                   // uint32_t                             binding;
+                                               VK_DESCRIPTOR_TYPE_SAMPLER,             // VkDescriptorType             descriptorType;
+                                               1u,                                                             // uint32_t                             descriptorCount;
+                                               VK_SHADER_STAGE_COMPUTE_BIT,    // VkShaderStageFlags   stageFlags;
+                                               DE_NULL                                                 // const VkSampler*             pImmutableSamplers;
+                                       };
+                                       const VkDescriptorSetLayoutBinding              descriptorSetLayoutBindingTex   =
+                                       {
+                                               m_params.binding,                                       // uint32_t                             binding;
+                                               VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,       // VkDescriptorType             descriptorType;
+                                               1u,                                                                     // uint32_t                             descriptorCount;
+                                               VK_SHADER_STAGE_COMPUTE_BIT,            // VkShaderStageFlags   stageFlags;
+                                               DE_NULL                                                         // const VkSampler*             pImmutableSamplers;
+                                       };
+                                       layoutBindings.push_back(descriptorSetLayoutBindingSampler);
+                                       layoutBindings.push_back(descriptorSetLayoutBindingTex);
+                                       m_outputBufferBinding = m_params.binding + 2;
+                               }
+                               break;
+
+                       case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+                               {
+                                       const VkDescriptorSetLayoutBinding              descriptorSetLayoutBinding              =
+                                       {
+                                               m_params.binding,                                       // uint32_t                             binding;
+                                               VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,       // VkDescriptorType             descriptorType;
+                                               1u,                                                                     // uint32_t                             descriptorCount;
+                                               VK_SHADER_STAGE_COMPUTE_BIT,            // VkShaderStageFlags   stageFlags;
+                                               DE_NULL                                                         // const VkSampler*             pImmutableSamplers;
+                                       };
+                                       layoutBindings.push_back(descriptorSetLayoutBinding);
+                                       m_outputBufferBinding = m_params.binding + 1;
+                               }
+                               break;
+
+                       default:
+                               DE_FATAL("unexpected descriptor type");
+                               break;
+               };
+
+               const VkDescriptorSetLayoutBinding              descriptorSetLayoutBindingOutputBuffer  =
+               {
+                       m_outputBufferBinding,                          // uint32_t                             binding;
+                       VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,      // VkDescriptorType             descriptorType;
+                       1u,                                                                     // uint32_t                             descriptorCount;
+                       VK_SHADER_STAGE_COMPUTE_BIT,            // VkShaderStageFlags   stageFlags;
+                       DE_NULL                                                         // const VkSampler*             pImmutableSamplers;
+               };
+
+               layoutBindings.push_back(descriptorSetLayoutBindingOutputBuffer);
+
+               const VkDescriptorSetLayoutCreateInfo   descriptorSetLayoutCreateInfo   =
+               {
+                       VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,            // VkStructureType                                              sType;
+                       DE_NULL,                                                                                                        // const void*                                                  pNext;
+                       VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,        // VkDescriptorSetLayoutCreateFlags             flags;
+                       (deUint32)layoutBindings.size(),                                                        // uint32_t                                                             bindingCount;
+                       layoutBindings.data()                                                                           // const VkDescriptorSetLayoutBinding*  pBindings;
+               };
+
+               m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, DE_NULL);
+
+               // Create pipeline layout
+               const VkPipelineLayoutCreateInfo                pipelineLayoutParams                    =
+               {
+                       VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,  // VkStructureType                              sType;
+                       DE_NULL,                                                                                // const void*                                  pNext;
+                       0u,                                                                                             // VkPipelineLayoutCreateFlags  flags;
+                       1u,                                                                                             // deUint32                                             descriptorSetCount;
+                       &(*m_descriptorSetLayout),                                              // const VkDescriptorSetLayout* pSetLayouts;
+                       0u,                                                                                             // deUint32                                             pushConstantRangeCount;
+                       DE_NULL                                                                                 // const VkPushDescriptorRange* pPushDescriptorRanges;
+               };
+
+               m_pipelineLayout = createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
+       }
+
+       // Create output buffer
+       {
+               const VkBufferCreateInfo bufferCreateInfo =
+               {
+                       VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,   // VkStructureType              sType;
+                       DE_NULL,                                                                // const void*                  pNext;
+                       0u,                                                                             // VkBufferCreateFlags  flags
+                       64u,                                                                    // VkDeviceSize                 size;
+                       VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,             // VkBufferUsageFlags   usage;
+                       VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
+                       1u,                                                                             // deUint32                             queueFamilyCount;
+                       &m_queueFamilyIndex                                             // const deUint32*              pQueueFamilyIndices;
+               };
+
+               m_outputBuffer          = createBuffer(m_vkd, *m_device, &bufferCreateInfo);
+               m_outputBufferAlloc     = m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_outputBuffer), MemoryRequirement::HostVisible);
+               VK_CHECK(m_vkd.bindBufferMemory(*m_device, *m_outputBuffer, m_outputBufferAlloc->getMemory(), m_outputBufferAlloc->getOffset()));
+       }
+
+       // Create shader
+       {
+               m_computeShaderModule = createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("compute"), 0u);
+       }
+
+       // Create pipeline
+       {
+               const VkPipelineShaderStageCreateInfo   stageCreateInfo =
+               {
+                       VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                      sType;
+                       DE_NULL,                                                                                                // const void*                                          pNext;
+                       0u,                                                                                                             // VkPipelineShaderStageCreateFlags     flags;
+                       VK_SHADER_STAGE_COMPUTE_BIT,                                                    // VkShaderStageFlagBits                        stage;
+                       *m_computeShaderModule,                                                                 // VkShaderModule                                       module;
+                       "main",                                                                                                 // const char*                                          pName;
+                       DE_NULL                                                                                                 // const VkSpecializationInfo*          pSpecializationInfo;
+               };
+
+               const VkComputePipelineCreateInfo               createInfo              =
+               {
+                       VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,                 // VkStructureType                                      sType;
+                       DE_NULL,                                                                                                // const void*                                          pNext;
+                       0u,                                                                                                             // VkPipelineCreateFlags                        flags;
+                       stageCreateInfo,                                                                                // VkPipelineShaderStageCreateInfo      stage;
+                       *m_pipelineLayout,                                                                              // VkPipelineLayout                                     layout;
+                       (VkPipeline)0,                                                                                  // VkPipeline                                           basePipelineHandle;
+                       0u,                                                                                                             // int32_t                                                      basePipelineIndex;
+               };
+
+               m_computePipeline = createComputePipeline(m_vkd, *m_device, (vk::VkPipelineCache)0u, &createInfo);
+       }
+
+       // Create command pool
+       m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
+
+       // Create command buffer
+       {
+               m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+               beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
+               m_vkd.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipeline);
+
+               // Dispatch: Each dispatch switches the input image.
+               // Output buffer is exposed as a 2 x vec4 sized window.
+               for (deUint32 dispatchNdx = 0; dispatchNdx < m_params.numCalls; dispatchNdx++)
+               {
+                       vector<VkSampler>       samplers;
+                       vector<VkImageView> imageViews;
+
+                       samplers.push_back(*m_whiteBorderSampler);
+                       if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
+                       {
+                               // Vary sampler between draws
+                               samplers.push_back(*m_blackBorderSampler);
+                       }
+                       else
+                       {
+                               // Usa a single sampler
+                               samplers.push_back(*m_whiteBorderSampler);
+                       }
+
+                       imageViews.push_back(**m_textureViews[0]);
+                       if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER || m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
+                       {
+                               // Vary image view between draws
+                               imageViews.push_back(**m_textureViews[1]);
+                       }
+                       else
+                       {
+                               // Usa a single image view
+                               imageViews.push_back(**m_textureViews[0]);
+                       }
+
+                       const VkDescriptorImageInfo     descriptorImageInfo     =
+                       {
+                               samplers[dispatchNdx],                                          // VkSampler            sampler;
+                               imageViews[dispatchNdx],                                        // VkImageView          imageView;
+                               VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL        // VkImageLayout        imageLayout;
+                       };
+
+                       VkWriteDescriptorSet    writeDescriptorSet              =
+                       {
+                               VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType                                      sType;
+                               DE_NULL,                                                                // const void*                                          pNext;
+                               0u,                                                                             // VkDescriptorSet                                      dstSet;
+                               m_params.binding,                                               // uint32_t                                                     dstBinding;
+                               0u,                                                                             // uint32_t                                                     dstArrayElement;
+                               1u,                                                                             // uint32_t                                                     descriptorCount;
+                               m_params.descriptorType,                                // VkDescriptorType                                     descriptorType;
+                               &descriptorImageInfo,                                   // const VkDescriptorImageInfo*         pImageInfo;
+                               DE_NULL,                                                                // const VkDescriptorBufferInfo*        pBufferInfo;
+                               DE_NULL                                                                 // const VkBufferView*                          pTexelBufferView;
+                       };
+
+                       vector<VkWriteDescriptorSet> writeDescriptorSets;
+                       writeDescriptorSets.push_back(writeDescriptorSet);
+
+                       if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
+                       {
+                               // Sampler also needs an image.
+                               writeDescriptorSet.dstBinding++;
+                               writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
+                               writeDescriptorSets.push_back(writeDescriptorSet);
+                       }
+                       else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
+                       {
+                               // Image also needs a sampler.
+                               writeDescriptorSet.dstBinding++;
+                               writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
+                               writeDescriptorSets.push_back(writeDescriptorSet);
+                       }
+
+                       const VkDescriptorBufferInfo descriptorBufferInfoOutput =
+                       {
+                               *m_outputBuffer,        // VkBuffer             buffer;
+                               32u * dispatchNdx,      // VkDeviceSize offset;
+                               32u                                     // VkDeviceSize range;
+                       };
+
+                       // Write output buffer descriptor set
+                       const VkWriteDescriptorSet      writeDescriptorSetOutput        =
+                       {
+                               VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType                                      sType;
+                               DE_NULL,                                                                // const void*                                          pNext;
+                               0u,                                                                             // VkDescriptorSet                                      dstSet;
+                               m_outputBufferBinding,                                  // uint32_t                                                     dstBinding;
+                               0u,                                                                             // uint32_t                                                     dstArrayElement;
+                               1u,                                                                             // uint32_t                                                     descriptorCount;
+                               VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,              // VkDescriptorType                                     descriptorType;
+                               DE_NULL,                                                                // const VkDescriptorImageInfo*         pImageInfo;
+                               &descriptorBufferInfoOutput,                    // const VkDescriptorBufferInfo*        pBufferInfo;
+                               DE_NULL                                                                 // const VkBufferView*                          pTexelBufferView;
+                       };
+
+                       writeDescriptorSets.push_back(writeDescriptorSetOutput);
+
+                       m_vkd.cmdPushDescriptorSetKHR(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, (deUint32)writeDescriptorSets.size(), writeDescriptorSets.data());
+                       m_vkd.cmdDispatch(*m_cmdBuffer, 1, 1, 1);
+               }
+
+               endCommandBuffer(m_vkd, *m_cmdBuffer);
+       }
+}
+
+PushDescriptorImageComputeTestInstance::~PushDescriptorImageComputeTestInstance (void)
+{
+}
+
+tcu::TestStatus PushDescriptorImageComputeTestInstance::iterate (void)
+{
+       init();
+
+       submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());
+
+       return verifyOutput();
+}
+
+tcu::TestStatus PushDescriptorImageComputeTestInstance::verifyOutput (void)
+{
+       float ref[16];
+       invalidateMappedMemoryRange(m_vkd, *m_device, m_outputBufferAlloc->getMemory(), m_outputBufferAlloc->getOffset(), (size_t)64u);
+
+       switch(m_params.descriptorType)
+       {
+               case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+                       // Dispatch 1: inner & outer = green
+                       ref[0] = ref[4] = 0.0f;
+                       ref[1] = ref[5] = 1.0f;
+                       ref[2] = ref[6] = 0.0f;
+                       ref[3] = ref[7] = 1.0f;
+
+                       // Dispatch 2: inner & outer = red
+                       ref[8] = ref[12] = 1.0f;
+                       ref[9] = ref[13] = 0.0f;
+                       ref[10] = ref[14] = 0.0f;
+                       ref[11] = ref[15] = 1.0f;
+                       break;
+
+               case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+                       // Dispatch 1: inner = green, outer = white
+                       ref[0] = 0.0f;
+                       ref[1] = 1.0f;
+                       ref[2] = 0.0f;
+                       ref[3] = 1.0f;
+
+                       ref[4] = 1.0f;
+                       ref[5] = 1.0f;
+                       ref[6] = 1.0f;
+                       ref[7] = 1.0f;
+
+                       // Dispatch 2: inner = red, outer = black
+                       ref[8] = 1.0f;
+                       ref[9] = 0.0f;
+                       ref[10] = 0.0f;
+                       ref[11] = 1.0f;
+
+                       ref[12] = 0.0f;
+                       ref[13] = 0.0f;
+                       ref[14] = 0.0f;
+                       ref[15] = 1.0f;
+                       break;
+
+               case VK_DESCRIPTOR_TYPE_SAMPLER:
+                       // Dispatch 1: inner = green, outer = white
+                       ref[0] = 0.0f;
+                       ref[1] = 1.0f;
+                       ref[2] = 0.0f;
+                       ref[3] = 1.0f;
+
+                       ref[4] = 1.0f;
+                       ref[5] = 1.0f;
+                       ref[6] = 1.0f;
+                       ref[7] = 1.0f;
+
+                       // Dispatch 2: inner = green, outer = black
+                       ref[8] = 0.0f;
+                       ref[9] = 1.0f;
+                       ref[10] = 0.0f;
+                       ref[11] = 1.0f;
+
+                       ref[12] = 0.0f;
+                       ref[13] = 0.0f;
+                       ref[14] = 0.0f;
+                       ref[15] = 1.0f;
+                       break;
+
+               case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
+                       // Dispatch 1: inner = green, outer = white
+                       ref[0] = 0.0f;
+                       ref[1] = 1.0f;
+                       ref[2] = 0.0f;
+                       ref[3] = 1.0f;
+
+                       ref[4] = 1.0f;
+                       ref[5] = 1.0f;
+                       ref[6] = 1.0f;
+                       ref[7] = 1.0f;
+
+                       // Dispatch 2: inner = red, outer = white
+                       ref[8] = 1.0f;
+                       ref[9] = 0.0f;
+                       ref[10] = 0.0f;
+                       ref[11] = 1.0f;
+
+                       ref[12] = 1.0f;
+                       ref[13] = 1.0f;
+                       ref[14] = 1.0f;
+                       ref[15] = 1.0f;
+                       break;
+
+               default:
+                       DE_FATAL("unexpected descriptor type");
+                       break;
+       };
+
+       // Verify result
+       if (deMemCmp((void*)ref, m_outputBufferAlloc->getHostPtr(), (size_t)(32u * m_params.numCalls)))
+       {
+               const float* ptr = (float*)m_outputBufferAlloc->getHostPtr();
+               std::string debugMsg = "Output buffer contents:\n";
+
+               for (deUint32 i = 0; i < m_params.numCalls * 8; i++)
+                       debugMsg += de::toString(ptr[i]) + " vs " + de::toString(ref[i]) + "\n";
+
+               m_context.getTestContext().getLog() << tcu::TestLog::Message << debugMsg << tcu::TestLog::EndMessage;
+               return tcu::TestStatus::fail("Output mismatch");
+       }
+       return tcu::TestStatus::pass("Output matches expected values");
+}
+
+class PushDescriptorImageComputeTest : public vkt::TestCase
+{
+public:
+                                               PushDescriptorImageComputeTest  (tcu::TestContext&      testContext,
+                                                                                                                const string&          name,
+                                                                                                                const string&          description,
+                                                                                                                const TestParams&      params);
+                                               ~PushDescriptorImageComputeTest (void);
+       void                            initPrograms                                    (SourceCollections& sourceCollections) const;
+       TestInstance*           createInstance                                  (Context& context) const;
+
+protected:
+       const TestParams        m_params;
+};
+
+PushDescriptorImageComputeTest::PushDescriptorImageComputeTest (tcu::TestContext&      testContext,
+                                                                                                                                const string&          name,
+                                                                                                                                const string&          description,
+                                                                                                                                const TestParams&      params)
+       : vkt::TestCase (testContext, name, description)
+       , m_params              (params)
+{
+}
+
+PushDescriptorImageComputeTest::~PushDescriptorImageComputeTest (void)
+{
+}
+
+TestInstance* PushDescriptorImageComputeTest::createInstance (Context& context) const
+{
+       return new PushDescriptorImageComputeTestInstance(context, m_params);
+}
+
+void PushDescriptorImageComputeTest::initPrograms (SourceCollections& sourceCollections) const
+{
+       if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
+       {
+               const string    computeSrc      =
+                       "#version 450\n"
+                       "layout(set = 0, binding = " + de::toString(m_params.binding) + ") uniform sampler2D combinedSampler;\n"
+                       "layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") writeonly buffer Output\n"
+                       "{\n"
+                       "       vec4 innerColor;\n"
+                       "       vec4 outerColor;\n"
+                       "} outData;\n"
+                       "\n"
+                       "void main()\n"
+                       "{\n"
+                       "       outData.innerColor = texture(combinedSampler, vec2(0.5));\n"
+                       "       outData.outerColor = texture(combinedSampler, vec2(-0.1));\n"
+                       "}\n";
+
+               sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
+       }
+       else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
+       {
+               const string    computeSrc      =
+                       "#version 450\n"
+                       "layout(set = 0, binding = " + de::toString(m_params.binding) + ") uniform sampler texSampler;\n"
+                       "layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") uniform texture2D texImage;\n"
+                       "layout(set = 0, binding = " + de::toString(m_params.binding + 2) + ") writeonly buffer Output\n"
+                       "{\n"
+                       "       vec4 innerColor;\n"
+                       "       vec4 outerColor;\n"
+                       "} outData;\n"
+                       "\n"
+                       "void main()\n"
+                       "{\n"
+                       "       outData.innerColor = texture(sampler2D(texImage, texSampler), vec2(0.5));\n"
+                       "       outData.outerColor = texture(sampler2D(texImage, texSampler), vec2(-0.1));\n"
+                       "}\n";
+
+               sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
+       }
+       else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
+       {
+               const string    computeSrc      =
+                       "#version 450\n"
+                       "layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") uniform sampler texSampler;\n"
+                       "layout(set = 0, binding = " + de::toString(m_params.binding) + ") uniform texture2D texImage;\n"
+                       "layout(set = 0, binding = " + de::toString(m_params.binding + 2) + ") writeonly buffer Output\n"
+                       "{\n"
+                       "       vec4 innerColor;\n"
+                       "       vec4 outerColor;\n"
+                       "} outData;\n"
+                       "\n"
+                       "void main()\n"
+                       "{\n"
+                       "       outData.innerColor = texture(sampler2D(texImage, texSampler), vec2(0.5));\n"
+                       "       outData.outerColor = texture(sampler2D(texImage, texSampler), vec2(-0.1));\n"
+                       "}\n";
+
+               sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
+       }
+       else if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
+       {
+               const string    computeSrc      =
+                       "#version 450\n"
+                       "layout(set = 0, binding = " + de::toString(m_params.binding) + ", rgba8) uniform readonly image2D storageImage;\n"
+                       "layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") writeonly buffer Output\n"
+                       "{\n"
+                       "       vec4 innerColor;\n"
+                       "       vec4 outerColor;\n"
+                       "} outData;\n"
+                       "\n"
+                       "void main()\n"
+                       "{\n"
+                       "       outData.innerColor = imageLoad(storageImage, ivec2(0));\n"
+                       "       outData.outerColor = imageLoad(storageImage, ivec2(0));\n"
+                       "}\n";
+
+               sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
+       }
+       else
+       {
+               DE_FATAL("Unexpected descriptor type");
+       }
+}
+
+class PushDescriptorTexelBufferGraphicsTestInstance : public vkt::TestInstance
+{
+public:
+                                                               PushDescriptorTexelBufferGraphicsTestInstance   (Context& context, const TestParams& params);
+       virtual                                         ~PushDescriptorTexelBufferGraphicsTestInstance  (void);
+       void                                            init                                                                                    (void);
+       virtual tcu::TestStatus         iterate                                                                                 (void);
+       tcu::TestStatus                         verifyImage                                                                             (void);
+
+private:
+       const TestParams                                m_params;
+       const PlatformInterface&                m_vkp;
+       const Extensions                                m_instanceExtensions;
+       const Unique<VkInstance>                m_instance;
+       const InstanceDriver                    m_vki;
+       const VkPhysicalDevice                  m_physicalDevice;
+       const deUint32                                  m_queueFamilyIndex;
+       const Extensions                                m_deviceExtensions;
+       const Unique<VkDevice>                  m_device;
+       const DeviceDriver                              m_vkd;
+       const VkQueue                                   m_queue;
+       SimpleAllocator                                 m_allocator;
+       const tcu::UVec2                                m_renderSize;
+       const VkFormat                                  m_colorFormat;
+       Move<VkImage>                                   m_colorImage;
+       de::MovePtr<Allocation>                 m_colorImageAlloc;
+       Move<VkImageView>                               m_colorAttachmentView;
+       vector<VkBufferSp>                              m_buffers;
+       vector<AllocationSp>                    m_bufferAllocs;
+       vector<VkBufferViewSp>                  m_bufferViews;
+       const VkFormat                                  m_bufferFormat;
+       Move<VkRenderPass>                              m_renderPass;
+       Move<VkFramebuffer>                             m_framebuffer;
+       Move<VkShaderModule>                    m_vertexShaderModule;
+       Move<VkShaderModule>                    m_fragmentShaderModule;
+       Move<VkBuffer>                                  m_vertexBuffer;
+       de::MovePtr<Allocation>                 m_vertexBufferAlloc;
+       Move<VkDescriptorSetLayout>             m_descriptorSetLayout;
+       Move<VkPipelineLayout>                  m_pipelineLayout;
+       Move<VkPipeline>                                m_graphicsPipelines;
+       Move<VkCommandPool>                             m_cmdPool;
+       Move<VkCommandBuffer>                   m_cmdBuffer;
+       vector<Vertex4RGBA>                             m_vertices;
+};
+
+PushDescriptorTexelBufferGraphicsTestInstance::PushDescriptorTexelBufferGraphicsTestInstance (Context& context, const TestParams& params)
+       : vkt::TestInstance             (context)
+       , m_params                              (params)
+       , m_vkp                                 (context.getPlatformInterface())
+       , m_instanceExtensions  (enumerateInstanceExtensionProperties(m_vkp, DE_NULL))
+       , m_instance                    (createInstanceWithGetPhysicalDeviceProperties2(m_vkp, context.getUsedApiVersion(), m_instanceExtensions))
+       , m_vki                                 (m_vkp, *m_instance)
+       , m_physicalDevice              (chooseDevice(m_vki, *m_instance, context.getTestContext().getCommandLine()))
+       , m_queueFamilyIndex    (findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT))
+       , m_deviceExtensions    (enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
+       , m_device                              (createDeviceWithPushDescriptor(m_vkp, *m_instance, m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex))
+       , m_vkd                                 (m_vkp, *m_instance, *m_device)
+       , m_queue                               (getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
+       , m_allocator                   (m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
+       , m_renderSize                  (32, 32)
+       , m_colorFormat                 (VK_FORMAT_R8G8B8A8_UNORM)
+       , m_bufferFormat                (VK_FORMAT_R32G32B32A32_SFLOAT)
+       , m_vertices                    (createQuads(params.numCalls, 0.25f))
+{
+}
+
+void PushDescriptorTexelBufferGraphicsTestInstance::init (void)
+{
+       const VkComponentMapping                componentMappingRGBA    = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
+
+       // Create color image
+       {
+
+               const VkImageCreateInfo         colorImageParams                =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                    // VkStructureType                      sType;
+                       DE_NULL,                                                                                                                                // const void*                          pNext;
+                       0u,                                                                                                                                             // VkImageCreateFlags           flags;
+                       VK_IMAGE_TYPE_2D,                                                                                                               // VkImageType                          imageType;
+                       m_colorFormat,                                                                                                                  // VkFormat                                     format;
+                       { m_renderSize.x(), m_renderSize.y(), 1u },                                                             // VkExtent3D                           extent;
+                       1u,                                                                                                                                             // deUint32                                     mipLevels;
+                       1u,                                                                                                                                             // deUint32                                     arrayLayers;
+                       VK_SAMPLE_COUNT_1_BIT,                                                                                                  // VkSampleCountFlagBits        samples;
+                       VK_IMAGE_TILING_OPTIMAL,                                                                                                // VkImageTiling                        tiling;
+                       VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,  // VkImageUsageFlags            usage;
+                       VK_SHARING_MODE_EXCLUSIVE,                                                                                              // VkSharingMode                        sharingMode;
+                       1u,                                                                                                                                             // deUint32                                     queueFamilyIndexCount;
+                       &m_queueFamilyIndex,                                                                                                    // const deUint32*                      pQueueFamilyIndices;
+                       VK_IMAGE_LAYOUT_UNDEFINED                                                                                               // VkImageLayout                        initialLayout;
+               };
+
+               m_colorImage                    = createImage(m_vkd, *m_device, &colorImageParams);
+
+               // Allocate and bind color image memory
+               m_colorImageAlloc               = m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, *m_colorImage), MemoryRequirement::Any);
+               VK_CHECK(m_vkd.bindImageMemory(*m_device, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
+       }
+
+       // Create color attachment view
+       {
+               const VkImageViewCreateInfo colorAttachmentViewParams =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                              sType;
+                       DE_NULL,                                                                                // const void*                                  pNext;
+                       0u,                                                                                             // VkImageViewCreateFlags               flags;
+                       *m_colorImage,                                                                  // VkImage                                              image;
+                       VK_IMAGE_VIEW_TYPE_2D,                                                  // VkImageViewType                              viewType;
+                       m_colorFormat,                                                                  // VkFormat                                             format;
+                       componentMappingRGBA,                                                   // VkChannelMapping                             channels;
+                       { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }   // VkImageSubresourceRange              subresourceRange;
+               };
+
+               m_colorAttachmentView = createImageView(m_vkd, *m_device, &colorAttachmentViewParams);
+       }
+
+       // Create buffers
+       for (deUint32 bufIdx = 0; bufIdx < DE_LENGTH_OF_ARRAY(testColors); bufIdx++)
+       {
+               const VkBufferUsageFlags        usageFlags                      = m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ? VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
+
+               const VkBufferCreateInfo        bufferCreateInfo        =
+               {
+                       VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,   // VkStructureType              sType;
+                       DE_NULL,                                                                // const void*                  pNext;
+                       0u,                                                                             // VkBufferCreateFlags  flags
+                       16u,                                                                    // VkDeviceSize                 size;
+                       usageFlags,                                                             // VkBufferUsageFlags   usage;
+                       VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
+                       1u,                                                                             // deUint32                             queueFamilyCount;
+                       &m_queueFamilyIndex                                             // const deUint32*              pQueueFamilyIndices;
+               };
+
+               m_buffers.push_back(VkBufferSp(new Unique<VkBuffer>(createBuffer(m_vkd, *m_device, &bufferCreateInfo))));
+               m_bufferAllocs.push_back(AllocationSp(m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, **m_buffers[bufIdx]), MemoryRequirement::HostVisible).release()));
+               VK_CHECK(m_vkd.bindBufferMemory(*m_device, **m_buffers[bufIdx], m_bufferAllocs[bufIdx]->getMemory(), m_bufferAllocs[bufIdx]->getOffset()));
+
+               deMemcpy(m_bufferAllocs[bufIdx]->getHostPtr(), &testColors[bufIdx], 16u);
+               flushMappedMemoryRange(m_vkd, *m_device, m_bufferAllocs[bufIdx]->getMemory(), m_bufferAllocs[bufIdx]->getOffset(), 16u);
+       }
+
+       // Create buffer views
+       for (deUint32 bufIdx = 0; bufIdx < DE_LENGTH_OF_ARRAY(testColors); bufIdx++)
+       {
+               const VkBufferViewCreateInfo bufferViewParams =
+               {
+                       VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,      // VkStructureType                      sType;
+                       DE_NULL,                                                                        // const void*                          pNext;
+                       0u,                                                                                     // VkBufferViewCreateFlags      flags;
+                       **m_buffers[bufIdx],                                            // VkBuffer                                     buffer;
+                       m_bufferFormat,                                                         // VkFormat                                     format;
+                       0u,                                                                                     // VkDeviceSize                         offset;
+                       VK_WHOLE_SIZE                                                           // VkDeviceSize                         range;
+               };
+
+               m_bufferViews.push_back(VkBufferViewSp(new Unique<VkBufferView>(createBufferView(m_vkd, *m_device, &bufferViewParams))));
+       }
+
+       // Create render pass
+       m_renderPass = makeRenderPass(m_vkd, *m_device, m_colorFormat);
+
+       // Create framebuffer
+       {
+               const VkImageView                               attachmentBindInfos[]   =
+               {
+                       *m_colorAttachmentView
+               };
+
+               const VkFramebufferCreateInfo   framebufferParams               =
+               {
+                       VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,      // VkStructureType                      sType;
+                       DE_NULL,                                                                        // const void*                          pNext;
+                       0u,                                                                                     // VkFramebufferCreateFlags     flags;
+                       *m_renderPass,                                                          // VkRenderPass                         renderPass;
+                       1u,                                                                                     // deUint32                                     attachmentCount;
+                       attachmentBindInfos,                                            // const VkImageView*           pAttachments;
+                       (deUint32)m_renderSize.x(),                                     // deUint32                                     width;
+                       (deUint32)m_renderSize.y(),                                     // deUint32                                     height;
+                       1u                                                                                      // deUint32                                     layers;
+               };
+
+               m_framebuffer = createFramebuffer(m_vkd, *m_device, &framebufferParams);
+       }
+
+       // Create pipeline layout
+       {
+               const VkDescriptorSetLayoutBinding              descriptorSetLayoutBinding              =
+               {
+                       m_params.binding,                               // uint32_t                             binding;
+                       m_params.descriptorType,                // VkDescriptorType             descriptorType;
+                       1u,                                                             // uint32_t                             descriptorCount;
+                       VK_SHADER_STAGE_FRAGMENT_BIT,   // VkShaderStageFlags   stageFlags;
+                       DE_NULL                                                 // const VkSampler*             pImmutableSamplers;
+               };
+
+               const VkDescriptorSetLayoutCreateInfo   descriptorSetLayoutCreateInfo   =
+               {
+                       VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,            // VkStructureType                                              sType;
+                       DE_NULL,                                                                                                        // const void*                                                  pNext;
+                       VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,        // VkDescriptorSetLayoutCreateFlags             flags;
+                       1u,                                                                                                                     // uint32_t                                                             bindingCount;
+                       &descriptorSetLayoutBinding                                                                     // const VkDescriptorSetLayoutBinding*  pBindings;
+               };
+
+               m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, DE_NULL);
+
+               const VkPipelineLayoutCreateInfo                pipelineLayoutParams                    =
+               {
+                       VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,  // VkStructureType                              sType;
+                       DE_NULL,                                                                                // const void*                                  pNext;
+                       0u,                                                                                             // VkPipelineLayoutCreateFlags  flags;
+                       1u,                                                                                             // deUint32                                             descriptorSetCount;
+                       &(*m_descriptorSetLayout),                                              // const VkDescriptorSetLayout* pSetLayouts;
+                       0u,                                                                                             // deUint32                                             pushConstantRangeCount;
+                       DE_NULL                                                                                 // const VkPushDescriptorRange* pPushDescriptorRanges;
+               };
+
+               m_pipelineLayout = createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
+       }
+
+       // Create shaders
+       {
+               m_vertexShaderModule    = createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("vert"), 0u);
+               m_fragmentShaderModule  = createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("frag"), 0u);
+       }
+
+       // Create pipeline
+       {
+               const VkVertexInputBindingDescription           vertexInputBindingDescription           =
+               {
+                       0u,                                                     // deUint32                                     binding;
+                       sizeof(Vertex4RGBA),            // deUint32                                     strideInBytes;
+                       VK_VERTEX_INPUT_RATE_VERTEX     // VkVertexInputStepRate        stepRate;
+               };
+
+               const VkVertexInputAttributeDescription         vertexInputAttributeDescriptions[]      =
+               {
+                       {
+                               0u,                                                                     // deUint32     location;
+                               0u,                                                                     // deUint32     binding;
+                               VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat     format;
+                               0u                                                                      // deUint32     offsetInBytes;
+                       },
+                       {
+                               1u,                                                                     // deUint32     location;
+                               0u,                                                                     // deUint32     binding;
+                               VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat     format;
+                               DE_OFFSET_OF(Vertex4RGBA, color)        // deUint32     offset;
+                       }
+               };
+
+               const VkPipelineVertexInputStateCreateInfo      vertexInputStateParams                          =
+               {
+                       VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,      // VkStructureType                                                      sType;
+                       DE_NULL,                                                                                                        // const void*                                                          pNext;
+                       0u,                                                                                                                     // vkPipelineVertexInputStateCreateFlags        flags;
+                       1u,                                                                                                                     // deUint32                                                                     bindingCount;
+                       &vertexInputBindingDescription,                                                         // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
+                       2u,                                                                                                                     // deUint32                                                                     attributeCount;
+                       vertexInputAttributeDescriptions                                                        // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
+               };
+
+               const VkPrimitiveTopology                                       topology                                                        = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
+
+               const vector<VkViewport>                                        viewports                                                       (1, makeViewport(m_renderSize));
+               const vector<VkRect2D>                                          scissors                                                        (1, makeRect2D(m_renderSize));
+
+               m_graphicsPipelines = makeGraphicsPipeline(m_vkd,                                               // const DeviceInterface&                                               vk
+                                                                                                  *m_device,                                   // const VkDevice                                                               device
+                                                                                                  *m_pipelineLayout,                   // const VkPipelineLayout                                               pipelineLayout
+                                                                                                  *m_vertexShaderModule,               // const VkShaderModule                                                 vertexShaderModule
+                                                                                                  DE_NULL,                                             // const VkShaderModule                                                 tessellationControlShaderModule
+                                                                                                  DE_NULL,                                             // const VkShaderModule                                                 tessellationEvalShaderModule
+                                                                                                  DE_NULL,                                             // const VkShaderModule                                                 geometryShaderModule
+                                                                                                  *m_fragmentShaderModule,             // const VkShaderModule                                                 fragmentShaderModule
+                                                                                                  *m_renderPass,                               // const VkRenderPass                                                   renderPass
+                                                                                                  viewports,                                   // const std::vector<VkViewport>&                               viewports
+                                                                                                  scissors,                                    // const std::vector<VkRect2D>&                                 scissors
+                                                                                                  topology,                                    // const VkPrimitiveTopology                                    topology
+                                                                                                  0u,                                                  // const deUint32                                                               subpass
+                                                                                                  0u,                                                  // const deUint32                                                               patchControlPoints
+                                                                                                  &vertexInputStateParams);    // const VkPipelineVertexInputStateCreateInfo*  vertexInputStateCreateInfo
+       }
+
+       // Create vertex buffer
+       {
+               const VkBufferCreateInfo vertexBufferParams =
+               {
+                       VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,                                           // VkStructureType              sType;
+                       DE_NULL,                                                                                                        // const void*                  pNext;
+                       0u,                                                                                                                     // VkBufferCreateFlags  flags;
+                       (VkDeviceSize)(sizeof(Vertex4RGBA) * m_vertices.size()),        // VkDeviceSize                 size;
+                       VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                                                      // VkBufferUsageFlags   usage;
+                       VK_SHARING_MODE_EXCLUSIVE,                                                                      // VkSharingMode                sharingMode;
+                       1u,                                                                                                                     // deUint32                             queueFamilyCount;
+                       &m_queueFamilyIndex                                                                                     // const deUint32*              pQueueFamilyIndices;
+               };
+
+               m_vertexBuffer          = createBuffer(m_vkd, *m_device, &vertexBufferParams);
+               m_vertexBufferAlloc     = m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_vertexBuffer), MemoryRequirement::HostVisible);
+
+               VK_CHECK(m_vkd.bindBufferMemory(*m_device, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
+
+               // Load vertices into vertex buffer
+               deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
+               flushMappedMemoryRange(m_vkd, *m_device, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset(), vertexBufferParams.size);
+       }
+
+       // Create command pool
+       m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
+
+       // Create command buffer
+       {
+               const VkClearValue      attachmentClearValue    = defaultClearValue(m_colorFormat);
+               const VkDeviceSize      vertexBufferOffset              = 0;
+
+               m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+               beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
+               beginRenderPass(m_vkd, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), attachmentClearValue);
+               m_vkd.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines);
+               m_vkd.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
+
+               // Draw quads. Switch buffer view between draws.
+               for (deUint32 quadNdx = 0; quadNdx < m_params.numCalls; quadNdx++)
+               {
+                       VkWriteDescriptorSet    writeDescriptorSet      =
+                       {
+                               VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType                                      sType;
+                               DE_NULL,                                                                // const void*                                          pNext;
+                               0u,                                                                             // VkDescriptorSet                                      dstSet;
+                               m_params.binding,                                               // uint32_t                                                     dstBinding;
+                               0u,                                                                             // uint32_t                                                     dstArrayElement;
+                               1u,                                                                             // uint32_t                                                     descriptorCount;
+                               m_params.descriptorType,                                // VkDescriptorType                                     descriptorType;
+                               DE_NULL,                                                                // const VkDescriptorImageInfo*         pImageInfo;
+                               DE_NULL,                                                                // const VkDescriptorBufferInfo*        pBufferInfo;
+                               &m_bufferViews[quadNdx]->get()                  // const VkBufferView*                          pTexelBufferView;
+                       };
+
+                       m_vkd.cmdPushDescriptorSetKHR(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1u, &writeDescriptorSet);
+                       m_vkd.cmdDraw(*m_cmdBuffer, 6, 1, 6 * quadNdx, 0);
+               }
+
+               endRenderPass(m_vkd, *m_cmdBuffer);
+               endCommandBuffer(m_vkd, *m_cmdBuffer);
+       }
+}
+
+PushDescriptorTexelBufferGraphicsTestInstance::~PushDescriptorTexelBufferGraphicsTestInstance (void)
+{
+}
+
+tcu::TestStatus PushDescriptorTexelBufferGraphicsTestInstance::iterate (void)
+{
+       init();
+
+       submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());
+
+       return verifyImage();
+}
+
+tcu::TestStatus PushDescriptorTexelBufferGraphicsTestInstance::verifyImage (void)
+{
+       const tcu::TextureFormat        tcuColorFormat  = mapVkFormat(m_colorFormat);
+       const tcu::TextureFormat        tcuDepthFormat  = tcu::TextureFormat();
+       const ColorVertexShader         vertexShader;
+       const ColorFragmentShader       fragmentShader  (tcuColorFormat, tcuDepthFormat);
+       const rr::Program                       program                 (&vertexShader, &fragmentShader);
+       ReferenceRenderer                       refRenderer             (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
+       bool                                            compareOk               = false;
+
+       // Render reference image
+       {
+               for (deUint32 quadIdx = 0; quadIdx < m_params.numCalls; quadIdx++)
+                       for (deUint32 vertexIdx = 0; vertexIdx < 6; vertexIdx++)
+                               m_vertices[quadIdx * 6 + vertexIdx].color.xyzw() = testColors[quadIdx];
+
+               refRenderer.draw(rr::RenderState(refRenderer.getViewportState()), rr::PRIMITIVETYPE_TRIANGLES, m_vertices);
+       }
+
+       // Compare result with reference image
+       {
+               de::MovePtr<tcu::TextureLevel> result = readColorAttachment(m_vkd, *m_device, m_queue, m_queueFamilyIndex, m_allocator, *m_colorImage, m_colorFormat, m_renderSize);
+
+               compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
+                                                                                                                         "IntImageCompare",
+                                                                                                                         "Image comparison",
+                                                                                                                         refRenderer.getAccess(),
+                                                                                                                         result->getAccess(),
+                                                                                                                         tcu::UVec4(2, 2, 2, 2),
+                                                                                                                         tcu::IVec3(1, 1, 0),
+                                                                                                                         true,
+                                                                                                                         tcu::COMPARE_LOG_RESULT);
+       }
+
+       if (compareOk)
+               return tcu::TestStatus::pass("Result image matches reference");
+       else
+               return tcu::TestStatus::fail("Image mismatch");
+}
+
+class PushDescriptorTexelBufferGraphicsTest : public vkt::TestCase
+{
+public:
+                                               PushDescriptorTexelBufferGraphicsTest   (tcu::TestContext&      testContext,
+                                                                                                                                const string&          name,
+                                                                                                                                const string&          description,
+                                                                                                                                const TestParams&      params);
+                                               ~PushDescriptorTexelBufferGraphicsTest  (void);
+       void                            initPrograms                                            (SourceCollections& sourceCollections) const;
+       TestInstance*           createInstance                                          (Context& context) const;
+
+protected:
+       const TestParams        m_params;
+};
+
+PushDescriptorTexelBufferGraphicsTest::PushDescriptorTexelBufferGraphicsTest   (tcu::TestContext&      testContext,
+                                                                                                                                                                const string&          name,
+                                                                                                                                                                const string&          description,
+                                                                                                                                                                const TestParams&      params)
+       : vkt::TestCase (testContext, name, description)
+       , m_params              (params)
+{
+}
+
+PushDescriptorTexelBufferGraphicsTest::~PushDescriptorTexelBufferGraphicsTest (void)
+{
+}
+
+TestInstance* PushDescriptorTexelBufferGraphicsTest::createInstance (Context& context) const
+{
+       return new PushDescriptorTexelBufferGraphicsTestInstance(context, m_params);
+}
+
+void PushDescriptorTexelBufferGraphicsTest::initPrograms (SourceCollections& sourceCollections) const
+{
+       const string    vertexSrc       =
+               "#version 450\n"
+               "layout(location = 0) in highp vec4 position;\n"
+               "layout(location = 1) in highp vec4 texcoordVtx;\n"
+               "layout(location = 0) out highp vec2 texcoordFrag;\n"
+               "\n"
+               "out gl_PerVertex { vec4 gl_Position; };\n"
+               "\n"
+               "void main()\n"
+               "{\n"
+               "       gl_Position = position;\n"
+               "       texcoordFrag = texcoordVtx.xy;\n"
+               "}\n";
+
+       sourceCollections.glslSources.add("vert") << glu::VertexSource(vertexSrc);
+
+       if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER)
+       {
+               const string    fragmentSrc     =
+                       "#version 450\n"
+                       "layout(location = 0) in highp vec2 texcoordFrag;\n"
+                       "layout(location = 0) out highp vec4 fragColor;\n"
+                       "layout(set = 0, binding = " + de::toString(m_params.binding) + ") uniform textureBuffer texelBuffer;\n"
+                       "\n"
+                       "void main (void)\n"
+                       "{\n"
+                       "       fragColor = texelFetch(texelBuffer, 0);\n"
+                       "}\n";
+
+               sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
+       }
+       else
+       {
+               DE_ASSERT(m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
+               const string    fragmentSrc     =
+                       "#version 450\n"
+                       "layout(location = 0) in highp vec2 texcoordFrag;\n"
+                       "layout(location = 0) out highp vec4 fragColor;\n"
+                       "layout(set = 0, binding = " + de::toString(m_params.binding) + ", rgba32f) uniform readonly imageBuffer texelBuffer;\n"
+                       "\n"
+                       "void main (void)\n"
+                       "{\n"
+                       "       fragColor = imageLoad(texelBuffer, 0);\n"
+                       "}\n";
+
+               sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
+       }
+}
+
+class PushDescriptorTexelBufferComputeTestInstance : public vkt::TestInstance
+{
+public:
+                                                               PushDescriptorTexelBufferComputeTestInstance    (Context& context, const TestParams& params);
+       virtual                                         ~PushDescriptorTexelBufferComputeTestInstance   (void);
+       void                                            init                                                                                    (void);
+       virtual tcu::TestStatus         iterate                                                                                 (void);
+       tcu::TestStatus                         verifyOutput                                                                    (void);
+
+private:
+       const TestParams                        m_params;
+       const PlatformInterface&        m_vkp;
+       const Extensions                        m_instanceExtensions;
+       const Unique<VkInstance>        m_instance;
+       const InstanceDriver            m_vki;
+       const VkPhysicalDevice          m_physicalDevice;
+       const deUint32                          m_queueFamilyIndex;
+       const Extensions                        m_deviceExtensions;
+       const Unique<VkDevice>          m_device;
+       const DeviceDriver                      m_vkd;
+       const VkQueue                           m_queue;
+       SimpleAllocator                         m_allocator;
+       vector<VkBufferSp>                      m_buffers;
+       vector<AllocationSp>            m_bufferAllocs;
+       vector<VkBufferViewSp>          m_bufferViews;
+       const VkFormat                          m_bufferFormat;
+       Move<VkShaderModule>            m_computeShaderModule;
+       Move<VkBuffer>                          m_outputBuffer;
+       de::MovePtr<Allocation>         m_outputBufferAlloc;
+       Move<VkDescriptorSetLayout>     m_descriptorSetLayout;
+       Move<VkPipelineLayout>          m_pipelineLayout;
+       Move<VkPipeline>                        m_computePipeline;
+       Move<VkCommandPool>                     m_cmdPool;
+       Move<VkCommandBuffer>           m_cmdBuffer;
+};
+
+PushDescriptorTexelBufferComputeTestInstance::PushDescriptorTexelBufferComputeTestInstance (Context& context, const TestParams& params)
+       : vkt::TestInstance             (context)
+       , m_params                              (params)
+       , m_vkp                                 (context.getPlatformInterface())
+       , m_instanceExtensions  (enumerateInstanceExtensionProperties(m_vkp, DE_NULL))
+       , m_instance                    (createInstanceWithGetPhysicalDeviceProperties2(m_vkp, context.getUsedApiVersion(), m_instanceExtensions))
+       , m_vki                                 (m_vkp, *m_instance)
+       , m_physicalDevice              (chooseDevice(m_vki, *m_instance, context.getTestContext().getCommandLine()))
+       , m_queueFamilyIndex    (findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_COMPUTE_BIT))
+       , m_deviceExtensions    (enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
+       , m_device                              (createDeviceWithPushDescriptor(m_vkp, *m_instance, m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex))
+       , m_vkd                                 (m_vkp, *m_instance, *m_device)
+       , m_queue                               (getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
+       , m_allocator                   (m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
+       , m_bufferFormat                (VK_FORMAT_R32G32B32A32_SFLOAT)
+{
+}
+
+void PushDescriptorTexelBufferComputeTestInstance::init (void)
+{
+       // Create buffers
+       for (deUint32 bufIdx = 0; bufIdx < DE_LENGTH_OF_ARRAY(testColors); bufIdx++)
+       {
+               const VkBufferUsageFlags        usageFlags                      = m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ? VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
+
+               const VkBufferCreateInfo        bufferCreateInfo        =
+               {
+                       VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,   // VkStructureType              sType;
+                       DE_NULL,                                                                // const void*                  pNext;
+                       0u,                                                                             // VkBufferCreateFlags  flags
+                       16u,                                                                    // VkDeviceSize                 size;
+                       usageFlags,                                                             // VkBufferUsageFlags   usage;
+                       VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
+                       1u,                                                                             // deUint32                             queueFamilyCount;
+                       &m_queueFamilyIndex                                             // const deUint32*              pQueueFamilyIndices;
+               };
+
+               m_buffers.push_back(VkBufferSp(new Unique<VkBuffer>(createBuffer(m_vkd, *m_device, &bufferCreateInfo))));
+               m_bufferAllocs.push_back(AllocationSp(m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, **m_buffers[bufIdx]), MemoryRequirement::HostVisible).release()));
+               VK_CHECK(m_vkd.bindBufferMemory(*m_device, **m_buffers[bufIdx], m_bufferAllocs[bufIdx]->getMemory(), m_bufferAllocs[bufIdx]->getOffset()));
+
+               deMemcpy(m_bufferAllocs[bufIdx]->getHostPtr(), &testColors[bufIdx], 16u);
+               flushMappedMemoryRange(m_vkd, *m_device, m_bufferAllocs[bufIdx]->getMemory(), m_bufferAllocs[bufIdx]->getOffset(), 16u);
+       }
+
+       // Create buffer views
+       for (deUint32 bufIdx = 0; bufIdx < DE_LENGTH_OF_ARRAY(testColors); bufIdx++)
+       {
+               const VkBufferViewCreateInfo bufferViewParams =
+               {
+                       VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,      // VkStructureType                      sType;
+                       DE_NULL,                                                                        // const void*                          pNext;
+                       0u,                                                                                     // VkBufferViewCreateFlags      flags;
+                       **m_buffers[bufIdx],                                            // VkBuffer                                     buffer;
+                       m_bufferFormat,                                                         // VkFormat                                     format;
+                       0u,                                                                                     // VkDeviceSize                         offset;
+                       VK_WHOLE_SIZE                                                           // VkDeviceSize                         range;
+               };
+
+               m_bufferViews.push_back(VkBufferViewSp(new Unique<VkBufferView>(createBufferView(m_vkd, *m_device, &bufferViewParams))));
+       }
+
+       // Create pipeline layout
+       {
+               vector<VkDescriptorSetLayoutBinding>    layoutBindings;
+
+               const VkDescriptorSetLayoutBinding              descriptorSetLayoutBindings[]           =
+               {
+                       {
+                               m_params.binding,                               // uint32_t                             binding;
+                               m_params.descriptorType,                // VkDescriptorType             descriptorType;
+                               1u,                                                             // uint32_t                             descriptorCount;
+                               VK_SHADER_STAGE_COMPUTE_BIT,    // VkShaderStageFlags   stageFlags;
+                               DE_NULL                                                 // const VkSampler*             pImmutableSamplers;
+                       },
+                       {
+                               m_params.binding + 1,                           // uint32_t                             binding;
+                               VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,      // VkDescriptorType             descriptorType;
+                               1u,                                                                     // uint32_t                             descriptorCount;
+                               VK_SHADER_STAGE_COMPUTE_BIT,            // VkShaderStageFlags   stageFlags;
+                               DE_NULL                                                         // const VkSampler*             pImmutableSamplers;
+                       }
+               };
+
+               const VkDescriptorSetLayoutCreateInfo   descriptorSetLayoutCreateInfo   =
+               {
+                       VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,            // VkStructureType                                              sType;
+                       DE_NULL,                                                                                                        // const void*                                                  pNext;
+                       VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,        // VkDescriptorSetLayoutCreateFlags             flags;
+                       2u,                                                                                                                     // uint32_t                                                             bindingCount;
+                       descriptorSetLayoutBindings                                                                     // const VkDescriptorSetLayoutBinding*  pBindings;
+               };
+
+               m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, DE_NULL);
+
+               const VkPipelineLayoutCreateInfo                pipelineLayoutParams                    =
+               {
+                       VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,  // VkStructureType                              sType;
+                       DE_NULL,                                                                                // const void*                                  pNext;
+                       0u,                                                                                             // VkPipelineLayoutCreateFlags  flags;
+                       1u,                                                                                             // deUint32                                             descriptorSetCount;
+                       &(*m_descriptorSetLayout),                                              // const VkDescriptorSetLayout* pSetLayouts;
+                       0u,                                                                                             // deUint32                                             pushConstantRangeCount;
+                       DE_NULL                                                                                 // const VkPushDescriptorRange* pPushDescriptorRanges;
+               };
+
+               m_pipelineLayout = createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
+       }
+
+       // Create output buffer
+       {
+               const VkBufferCreateInfo bufferCreateInfo =
+               {
+                       VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,   // VkStructureType              sType;
+                       DE_NULL,                                                                // const void*                  pNext;
+                       0u,                                                                             // VkBufferCreateFlags  flags
+                       32u,                                                                    // VkDeviceSize                 size;
+                       VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,             // VkBufferUsageFlags   usage;
+                       VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
+                       1u,                                                                             // deUint32                             queueFamilyCount;
+                       &m_queueFamilyIndex                                             // const deUint32*              pQueueFamilyIndices;
+               };
+
+               m_outputBuffer          = createBuffer(m_vkd, *m_device, &bufferCreateInfo);
+               m_outputBufferAlloc     = m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_outputBuffer), MemoryRequirement::HostVisible);
+               VK_CHECK(m_vkd.bindBufferMemory(*m_device, *m_outputBuffer, m_outputBufferAlloc->getMemory(), m_outputBufferAlloc->getOffset()));
+       }
+
+       // Create shader
+       {
+               m_computeShaderModule = createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("compute"), 0u);
+       }
+
+       // Create pipeline
+       {
+               const VkPipelineShaderStageCreateInfo   stageCreateInfo =
+               {
+                       VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                      sType;
+                       DE_NULL,                                                                                                // const void*                                          pNext;
+                       0u,                                                                                                             // VkPipelineShaderStageCreateFlags     flags;
+                       VK_SHADER_STAGE_COMPUTE_BIT,                                                    // VkShaderStageFlagBits                        stage;
+                       *m_computeShaderModule,                                                                 // VkShaderModule                                       module;
+                       "main",                                                                                                 // const char*                                          pName;
+                       DE_NULL                                                                                                 // const VkSpecializationInfo*          pSpecializationInfo;
+               };
+
+               const VkComputePipelineCreateInfo               createInfo              =
+               {
+                       VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,                 // VkStructureType                                      sType;
+                       DE_NULL,                                                                                                // const void*                                          pNext;
+                       0u,                                                                                                             // VkPipelineCreateFlags                        flags;
+                       stageCreateInfo,                                                                                // VkPipelineShaderStageCreateInfo      stage;
+                       *m_pipelineLayout,                                                                              // VkPipelineLayout                                     layout;
+                       (VkPipeline)0,                                                                                  // VkPipeline                                           basePipelineHandle;
+                       0u,                                                                                                             // int32_t                                                      basePipelineIndex;
+               };
+
+               m_computePipeline = createComputePipeline(m_vkd, *m_device, (vk::VkPipelineCache)0u, &createInfo);
+       }
+
+       // Create command pool
+       m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
+
+       // Create command buffer
+       {
+               m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+               beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
+               m_vkd.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipeline);
+
+               // Dispatch: Each dispatch switches the input image.
+               // Output buffer is exposed as a vec4 sized window.
+               for (deUint32 dispatchNdx = 0; dispatchNdx < m_params.numCalls; dispatchNdx++)
+               {
+                       VkWriteDescriptorSet    writeDescriptorSet      =
+                       {
+                               VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType                                      sType;
+                               DE_NULL,                                                                // const void*                                          pNext;
+                               0u,                                                                             // VkDescriptorSet                                      dstSet;
+                               m_params.binding,                                               // uint32_t                                                     dstBinding;
+                               0u,                                                                             // uint32_t                                                     dstArrayElement;
+                               1u,                                                                             // uint32_t                                                     descriptorCount;
+                               m_params.descriptorType,                                // VkDescriptorType                                     descriptorType;
+                               DE_NULL,                                                                // const VkDescriptorImageInfo*         pImageInfo;
+                               DE_NULL,                                                                // const VkDescriptorBufferInfo*        pBufferInfo;
+                               &m_bufferViews[dispatchNdx]->get()              // const VkBufferView*                          pTexelBufferView;
+                       };
+
+                       vector<VkWriteDescriptorSet> writeDescriptorSets;
+                       writeDescriptorSets.push_back(writeDescriptorSet);
+
+                       const VkDescriptorBufferInfo descriptorBufferInfoOutput =
+                       {
+                               *m_outputBuffer,        // VkBuffer                     buffer;
+                               16u * dispatchNdx,      // VkDeviceSize         offset;
+                               16u                                     // VkDeviceSize         range;
+                       };
+
+                       // Write output buffer descriptor set
+                       const VkWriteDescriptorSet      writeDescriptorSetOutput        =
+                       {
+                               VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType                                      sType;
+                               DE_NULL,                                                                // const void*                                          pNext;
+                               0u,                                                                             // VkDescriptorSet                                      dstSet;
+                               m_params.binding + 1,                                   // uint32_t                                                     dstBinding;
+                               0u,                                                                             // uint32_t                                                     dstArrayElement;
+                               1u,                                                                             // uint32_t                                                     descriptorCount;
+                               VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,              // VkDescriptorType                                     descriptorType;
+                               DE_NULL,                                                                // const VkDescriptorImageInfo*         pImageInfo;
+                               &descriptorBufferInfoOutput,                    // const VkDescriptorBufferInfo*        pBufferInfo;
+                               DE_NULL                                                                 // const VkBufferView*                          pTexelBufferView;
+                       };
+
+                       writeDescriptorSets.push_back(writeDescriptorSetOutput);
+
+                       m_vkd.cmdPushDescriptorSetKHR(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, (deUint32)writeDescriptorSets.size(), writeDescriptorSets.data());
+                       m_vkd.cmdDispatch(*m_cmdBuffer, 1, 1, 1);
+               }
+
+               endCommandBuffer(m_vkd, *m_cmdBuffer);
+       }
+}
+
+PushDescriptorTexelBufferComputeTestInstance::~PushDescriptorTexelBufferComputeTestInstance (void)
+{
+}
+
+tcu::TestStatus PushDescriptorTexelBufferComputeTestInstance::iterate (void)
+{
+       init();
+
+       submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());
+
+       return verifyOutput();
+}
+
+tcu::TestStatus PushDescriptorTexelBufferComputeTestInstance::verifyOutput (void)
+{
+       const float ref[8] = { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f };
+       invalidateMappedMemoryRange(m_vkd, *m_device, m_outputBufferAlloc->getMemory(), m_outputBufferAlloc->getOffset(), (size_t)32u);
+
+       // Verify result
+       if (deMemCmp((void*)ref, m_outputBufferAlloc->getHostPtr(), (size_t)(16u * m_params.numCalls)))
+       {
+               const float* ptr = (float*)m_outputBufferAlloc->getHostPtr();
+               std::string debugMsg = "Output buffer contents:\n";
+
+               for (deUint32 i = 0; i < m_params.numCalls * 4; i++)
+                       debugMsg += de::toString(ptr[i]) + " vs " + de::toString(ref[i]) + "\n";
+
+               m_context.getTestContext().getLog() << tcu::TestLog::Message << debugMsg << tcu::TestLog::EndMessage;
+               return tcu::TestStatus::fail("Output mismatch");
+       }
+       return tcu::TestStatus::pass("Output matches expected values");
+}
+
+class PushDescriptorTexelBufferComputeTest : public vkt::TestCase
+{
+public:
+                                               PushDescriptorTexelBufferComputeTest    (tcu::TestContext&      testContext,
+                                                                                                                                const string&          name,
+                                                                                                                                const string&          description,
+                                                                                                                                const TestParams&      params);
+                                               ~PushDescriptorTexelBufferComputeTest   (void);
+       void                            initPrograms                                                    (SourceCollections& sourceCollections) const;
+       TestInstance*           createInstance                                                  (Context& context) const;
+
+protected:
+       const TestParams        m_params;
+};
+
+PushDescriptorTexelBufferComputeTest::PushDescriptorTexelBufferComputeTest     (tcu::TestContext&      testContext,
+                                                                                                                                                        const string&          name,
+                                                                                                                                                        const string&          description,
+                                                                                                                                                        const TestParams&      params)
+       : vkt::TestCase (testContext, name, description)
+       , m_params              (params)
+{
+}
+
+PushDescriptorTexelBufferComputeTest::~PushDescriptorTexelBufferComputeTest (void)
+{
+}
+
+TestInstance* PushDescriptorTexelBufferComputeTest::createInstance (Context& context) const
+{
+       return new PushDescriptorTexelBufferComputeTestInstance(context, m_params);
+}
+
+void PushDescriptorTexelBufferComputeTest::initPrograms (SourceCollections& sourceCollections) const
+{
+       if (m_params.descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER)
+       {
+               const string    computeSrc      =
+                       "#version 450\n"
+                       "layout(set = 0, binding = " + de::toString(m_params.binding) + ") uniform textureBuffer texelBuffer;\n"
+                       "layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") writeonly buffer Output\n"
+                       "{\n"
+                       "       vec4 color;\n"
+                       "} outData;\n"
+                       "\n"
+                       "void main()\n"
+                       "{\n"
+                       "       outData.color = texelFetch(texelBuffer, 0);\n"
+                       "}\n";
+
+               sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
+       }
+       else
+       {
+               DE_ASSERT(m_params.descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
+
+               const string    computeSrc      =
+                       "#version 450\n"
+                       "layout(set = 0, binding = " + de::toString(m_params.binding) + ", rgba32f) uniform readonly imageBuffer texelBuffer;\n"
+                       "layout(set = 0, binding = " + de::toString(m_params.binding + 1) + ") writeonly buffer Output\n"
+                       "{\n"
+                       "       vec4 color;\n"
+                       "} outData;\n"
+                       "\n"
+                       "void main()\n"
+                       "{\n"
+                       "       outData.color = imageLoad(texelBuffer, 0);\n"
+                       "}\n";
+
+               sourceCollections.glslSources.add("compute") << glu::ComputeSource(computeSrc);
+       }
+}
+
+class PushDescriptorInputAttachmentGraphicsTestInstance : public vkt::TestInstance
+{
+public:
+                                                               PushDescriptorInputAttachmentGraphicsTestInstance       (Context& context, const TestParams& params);
+       virtual                                         ~PushDescriptorInputAttachmentGraphicsTestInstance      (void);
+       void                                            init                                                                                            (void);
+       virtual tcu::TestStatus         iterate                                                                                         (void);
+       tcu::TestStatus                         verifyImage                                                                                     (void);
+
+private:
+       const TestParams                                m_params;
+       const PlatformInterface&                m_vkp;
+       const Extensions                                m_instanceExtensions;
+       const Unique<VkInstance>                m_instance;
+       const InstanceDriver                    m_vki;
+       const VkPhysicalDevice                  m_physicalDevice;
+       const deUint32                                  m_queueFamilyIndex;
+       const Extensions                                m_deviceExtensions;
+       const Unique<VkDevice>                  m_device;
+       const DeviceDriver                              m_vkd;
+       const VkQueue                                   m_queue;
+       SimpleAllocator                                 m_allocator;
+       const tcu::UVec2                                m_renderSize;
+       const tcu::UVec2                                m_textureSize;
+       const VkFormat                                  m_colorFormat;
+       Move<VkImage>                                   m_colorImage;
+       de::MovePtr<Allocation>                 m_colorImageAlloc;
+       Move<VkImageView>                               m_colorAttachmentView;
+       vector<VkImageSp>                               m_inputImages;
+       vector<AllocationSp>                    m_inputImageAllocs;
+       vector<VkImageViewSp>                   m_inputImageViews;
+       vector<VkRenderPassSp>                  m_renderPasses;
+       vector<VkFramebufferSp>                 m_framebuffers;
+       Move<VkShaderModule>                    m_vertexShaderModule;
+       Move<VkShaderModule>                    m_fragmentShaderModule;
+       Move<VkBuffer>                                  m_vertexBuffer;
+       de::MovePtr<Allocation>                 m_vertexBufferAlloc;
+       Move<VkDescriptorSetLayout>             m_descriptorSetLayout;
+       Move<VkPipelineLayout>                  m_pipelineLayout;
+       vector<VkPipelineSp>                    m_graphicsPipelines;
+       Move<VkCommandPool>                             m_cmdPool;
+       Move<VkCommandBuffer>                   m_cmdBuffer;
+       vector<Vertex4Tex4>                             m_vertices;
+};
+
+PushDescriptorInputAttachmentGraphicsTestInstance::PushDescriptorInputAttachmentGraphicsTestInstance (Context& context, const TestParams& params)
+       : vkt::TestInstance             (context)
+       , m_params                              (params)
+       , m_vkp                                 (context.getPlatformInterface())
+       , m_instanceExtensions  (enumerateInstanceExtensionProperties(m_vkp, DE_NULL))
+       , m_instance                    (createInstanceWithGetPhysicalDeviceProperties2(m_vkp, context.getUsedApiVersion(), m_instanceExtensions))
+       , m_vki                                 (m_vkp, *m_instance)
+       , m_physicalDevice              (chooseDevice(m_vki, *m_instance, context.getTestContext().getCommandLine()))
+       , m_queueFamilyIndex    (findQueueFamilyIndexWithCaps(m_vki, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT))
+       , m_deviceExtensions    (enumerateDeviceExtensionProperties(m_vki, m_physicalDevice, DE_NULL))
+       , m_device                              (createDeviceWithPushDescriptor(m_vkp, *m_instance, m_vki, m_physicalDevice, m_deviceExtensions, m_queueFamilyIndex))
+       , m_vkd                                 (m_vkp, *m_instance, *m_device)
+       , m_queue                               (getDeviceQueue(m_vkd, *m_device, m_queueFamilyIndex, 0u))
+       , m_allocator                   (m_vkd, *m_device, getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
+       , m_renderSize                  (32, 32)
+       , m_textureSize                 (32, 32)
+       , m_colorFormat                 (VK_FORMAT_R8G8B8A8_UNORM)
+       , m_vertices                    (createTexQuads(params.numCalls, 0.25f))
+{
+}
+
+void PushDescriptorInputAttachmentGraphicsTestInstance::init (void)
+{
+       const VkComponentMapping                componentMappingRGBA    = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
+
+       // Create color image
+       {
+
+               const VkImageCreateInfo         colorImageParams                =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                    // VkStructureType                      sType;
+                       DE_NULL,                                                                                                                                // const void*                          pNext;
+                       0u,                                                                                                                                             // VkImageCreateFlags           flags;
+                       VK_IMAGE_TYPE_2D,                                                                                                               // VkImageType                          imageType;
+                       m_colorFormat,                                                                                                                  // VkFormat                                     format;
+                       { m_renderSize.x(), m_renderSize.y(), 1u },                                                             // VkExtent3D                           extent;
+                       1u,                                                                                                                                             // deUint32                                     mipLevels;
+                       1u,                                                                                                                                             // deUint32                                     arrayLayers;
+                       VK_SAMPLE_COUNT_1_BIT,                                                                                                  // VkSampleCountFlagBits        samples;
+                       VK_IMAGE_TILING_OPTIMAL,                                                                                                // VkImageTiling                        tiling;
+                       VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,  // VkImageUsageFlags            usage;
+                       VK_SHARING_MODE_EXCLUSIVE,                                                                                              // VkSharingMode                        sharingMode;
+                       1u,                                                                                                                                             // deUint32                                     queueFamilyIndexCount;
+                       &m_queueFamilyIndex,                                                                                                    // const deUint32*                      pQueueFamilyIndices;
+                       VK_IMAGE_LAYOUT_UNDEFINED                                                                                               // VkImageLayout                        initialLayout;
+               };
+
+               m_colorImage            = createImage(m_vkd, *m_device, &colorImageParams);
+
+               // Allocate and bind color image memory
+               m_colorImageAlloc       = m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, *m_colorImage), MemoryRequirement::Any);
+               VK_CHECK(m_vkd.bindImageMemory(*m_device, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
+       }
+
+       // Create color attachment view
+       {
+               const VkImageViewCreateInfo colorAttachmentViewParams =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
+                       DE_NULL,                                                                                // const void*                          pNext;
+                       0u,                                                                                             // VkImageViewCreateFlags       flags;
+                       *m_colorImage,                                                                  // VkImage                                      image;
+                       VK_IMAGE_VIEW_TYPE_2D,                                                  // VkImageViewType                      viewType;
+                       m_colorFormat,                                                                  // VkFormat                                     format;
+                       componentMappingRGBA,                                                   // VkChannelMapping                     channels;
+                       { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }   // VkImageSubresourceRange      subresourceRange;
+               };
+
+               m_colorAttachmentView = createImageView(m_vkd, *m_device, &colorAttachmentViewParams);
+       }
+
+       // Create input images
+       for (deUint32 imageIdx = 0; imageIdx < 2; imageIdx++)
+       {
+               const VkImageUsageFlags         usageFlags                      = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
+
+               const VkImageCreateInfo         inputImageParams        =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                    // VkStructureType                      sType;
+                       DE_NULL,                                                                                // const void*                          pNext;
+                       0u,                                                                                             // VkImageCreateFlags           flags;
+                       VK_IMAGE_TYPE_2D,                                                               // VkImageType                          imageType;
+                       m_colorFormat,                                                                  // VkFormat                                     format;
+                       { m_textureSize.x(), m_textureSize.y(), 1u },   // VkExtent3D                           extent;
+                       1u,                                                                                             // deUint32                                     mipLevels;
+                       1u,                                                                                             // deUint32                                     arrayLayers;
+                       VK_SAMPLE_COUNT_1_BIT,                                                  // VkSampleCountFlagBits        samples;
+                       VK_IMAGE_TILING_OPTIMAL,                                                // VkImageTiling                        tiling;
+                       usageFlags,                                                                             // VkImageUsageFlags            usage;
+                       VK_SHARING_MODE_EXCLUSIVE,                                              // VkSharingMode                        sharingMode;
+                       1u,                                                                                             // deUint32                                     queueFamilyIndexCount;
+                       &m_queueFamilyIndex,                                                    // const deUint32*                      pQueueFamilyIndices;
+                       VK_IMAGE_LAYOUT_UNDEFINED                                               // VkImageLayout                        initialLayout;
+               };
+
+               m_inputImages.push_back(VkImageSp(new Unique<VkImage>(createImage(m_vkd, *m_device, &inputImageParams))));
+
+               // Allocate and bind image memory
+               m_inputImageAllocs.push_back(AllocationSp(m_allocator.allocate(getImageMemoryRequirements(m_vkd, *m_device, **m_inputImages.back()), MemoryRequirement::Any).release()));
+               VK_CHECK(m_vkd.bindImageMemory(*m_device, **m_inputImages.back(), m_inputImageAllocs.back()->getMemory(), m_inputImageAllocs.back()->getOffset()));
+       }
+
+       // Create texture image views
+       for (deUint32 imageIdx = 0; imageIdx < 2; imageIdx++)
+       {
+               const VkImageViewCreateInfo textureViewParams =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
+                       DE_NULL,                                                                                // const void*                          pNext;
+                       0u,                                                                                             // VkImageViewCreateFlags       flags;
+                       **m_inputImages[imageIdx],                                              // VkImage                                      image;
+                       VK_IMAGE_VIEW_TYPE_2D,                                                  // VkImageViewType                      viewType;
+                       m_colorFormat,                                                                  // VkFormat                                     format;
+                       componentMappingRGBA,                                                   // VkChannelMapping                     channels;
+                       { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }   // VkImageSubresourceRange      subresourceRange;
+               };
+
+               m_inputImageViews.push_back(VkImageViewSp(new Unique<VkImageView>(createImageView(m_vkd, *m_device, &textureViewParams))));
+       }
+
+       VkClearValue clearValues[2];
+       clearValues[0].color.float32[0] = 0.0f;
+       clearValues[0].color.float32[1] = 1.0f;
+       clearValues[0].color.float32[2] = 0.0f;
+       clearValues[0].color.float32[3] = 1.0f;
+       clearValues[1].color.float32[0] = 1.0f;
+       clearValues[1].color.float32[1] = 0.0f;
+       clearValues[1].color.float32[2] = 0.0f;
+       clearValues[1].color.float32[3] = 1.0f;
+
+       // Clear input images
+       for (deUint32 imageIdx = 0; imageIdx < 2; imageIdx++)
+       {
+               const VkImageAspectFlags        aspectMask      = VK_IMAGE_ASPECT_COLOR_BIT;
+               Move<VkCommandPool>                     cmdPool;
+               Move<VkCommandBuffer>           cmdBuffer;
+               const VkAccessFlags                     accessFlags     = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
+
+               cmdPool         = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
+               cmdBuffer       = allocateCommandBuffer(m_vkd, *m_device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+
+               const VkImageMemoryBarrier preImageBarrier =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType                      sType;
+                       DE_NULL,                                                                // const void*                          pNext;
+                       0u,                                                                             // VkAccessFlags                        srcAccessMask;
+                       VK_ACCESS_TRANSFER_WRITE_BIT,                   // VkAccessFlags                        dstAccessMask;
+                       VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                        oldLayout;
+                       VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout                        newLayout;
+                       VK_QUEUE_FAMILY_IGNORED,                                // deUint32                                     srcQueueFamilyIndex;
+                       VK_QUEUE_FAMILY_IGNORED,                                // deUint32                                     dstQueueFamilyIndex;
+                       **m_inputImages[imageIdx],                              // VkImage                                      image;
+                       {                                                                               // VkImageSubresourceRange      subresourceRange;
+                               aspectMask,                                                     // VkImageAspect                        aspect;
+                               0u,                                                                     // deUint32                                     baseMipLevel;
+                               1u,                                                                     // deUint32                                     mipLevels;
+                               0u,                                                                     // deUint32                                     baseArraySlice;
+                               1u                                                                      // deUint32                                     arraySize;
+                       }
+               };
+
+               const VkImageMemoryBarrier postImageBarrier =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
+                       DE_NULL,                                                                        // const void*                          pNext;
+                       VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
+                       accessFlags,                                                            // VkAccessFlags                        dstAccessMask;
+                       VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
+                       VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,       // VkImageLayout                        newLayout;
+                       VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
+                       VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
+                       **m_inputImages[imageIdx],                                      // VkImage                                      image;
+                       {                                                                                       // VkImageSubresourceRange      subresourceRange;
+                               aspectMask,                                                             // VkImageAspect                        aspect;
+                               0u,                                                                             // deUint32                                     baseMipLevel;
+                               1u,                                                                             // deUint32                                     mipLevels;
+                               0u,                                                                             // deUint32                                     baseArraySlice;
+                               1u                                                                              // deUint32                                     arraySize;
+                       }
+               };
+
+               const VkImageSubresourceRange clearRange        =
+               {
+                       aspectMask,     // VkImageAspectFlags   aspectMask;
+                       0u,                     // deUint32                             baseMipLevel;
+                       1u,                     // deUint32                             levelCount;
+                       0u,                     // deUint32                             baseArrayLayer;
+                       1u                      // deUint32                             layerCount;
+               };
+
+               beginCommandBuffer(m_vkd, *cmdBuffer);
+               m_vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
+               m_vkd.cmdClearColorImage(*cmdBuffer, **m_inputImages[imageIdx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValues[imageIdx].color, 1, &clearRange);
+               m_vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
+               endCommandBuffer(m_vkd, *cmdBuffer);
+
+               submitCommandsAndWait(m_vkd, *m_device, m_queue, cmdBuffer.get());
+       }
+
+       // Create render passes
+       for (deUint32 renderPassIdx = 0; renderPassIdx < 2; renderPassIdx++)
+       {
+               // The first pass clears the output image, and the second one draws on top of the first pass.
+               const VkAttachmentLoadOp                loadOps[]                                       =
+               {
+                       VK_ATTACHMENT_LOAD_OP_CLEAR,
+                       VK_ATTACHMENT_LOAD_OP_LOAD
+               };
+
+               const VkImageLayout                             initialLayouts[]                        =
+               {
+                       VK_IMAGE_LAYOUT_UNDEFINED,
+                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
+               };
+
+               const VkAttachmentDescription   attachmentDescriptions[]        =
+               {
+                       // Result attachment
+                       {
+                               (VkAttachmentDescriptionFlags)0,                        // VkAttachmentDescriptionFlags flags
+                               VK_FORMAT_R8G8B8A8_UNORM,                                       // VkFormat                                             format
+                               VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits                samples
+                               loadOps[renderPassIdx],                                         // VkAttachmentLoadOp                   loadOp
+                               VK_ATTACHMENT_STORE_OP_STORE,                           // VkAttachmentStoreOp                  storeOp
+                               VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        // VkAttachmentLoadOp                   stencilLoadOp
+                               VK_ATTACHMENT_STORE_OP_DONT_CARE,                       // VkAttachmentStoreOp                  stencilStoreOp
+                               initialLayouts[renderPassIdx],                          // VkImageLayout                                initialLayout
+                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout                                finalLayout
+                       },
+                       // Input attachment
+                       {
+                               (VkAttachmentDescriptionFlags)0,                        // VkAttachmentDescriptionFlags flags
+                               VK_FORMAT_R8G8B8A8_UNORM,                                       // VkFormat                                             format
+                               VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits                samples
+                               VK_ATTACHMENT_LOAD_OP_LOAD,                                     // VkAttachmentLoadOp                   loadOp
+                               VK_ATTACHMENT_STORE_OP_STORE,                           // VkAttachmentStoreOp                  storeOp
+                               VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        // VkAttachmentLoadOp                   stencilLoadOp
+                               VK_ATTACHMENT_STORE_OP_DONT_CARE,                       // VkAttachmentStoreOp                  stencilStoreOp
+                               VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,       // VkImageLayout                                initialLayout
+                               VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL        // VkImageLayout                                finalLayout
+                       }
+               };
+
+               const VkAttachmentReference             resultAttachmentRef             =
+               {
+                       0u,                                                                                     // deUint32                     attachment
+                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout        layout
+               };
+
+               const VkAttachmentReference             inputAttachmentRef              =
+               {
+                       1u,                                                                                     // deUint32                     attachment
+                       VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL        // VkImageLayout        layout
+               };
+
+               const VkSubpassDescription              subpassDescription              =
+               {
+                       (VkSubpassDescriptionFlags)0,                           // VkSubpassDescriptionFlags    flags
+                       VK_PIPELINE_BIND_POINT_GRAPHICS,                        // VkPipelineBindPoint                  pipelineBindPoint
+                       1u,                                                                                     // deUint32                                             inputAttachmentCount
+                       &inputAttachmentRef,                                                    // const VkAttachmentReference* pInputAttachments
+                       1u,                                                                                     // deUint32                                             colorAttachmentCount
+                       &resultAttachmentRef,                                           // const VkAttachmentReference* pColorAttachments
+                       DE_NULL,                                                                        // const VkAttachmentReference* pResolveAttachments
+                       DE_NULL,                                                                        // const VkAttachmentReference* pDepthStencilAttachment
+                       0u,                                                                                     // deUint32                                             preserveAttachmentCount
+                       DE_NULL                                                                         // const deUint32*                              pPreserveAttachments
+               };
+
+               const VkRenderPassCreateInfo    renderPassInfo                  =
+               {
+                       VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,      // VkStructureTypei                                     sType
+                       DE_NULL,                                                                        // const void*                                          pNext
+                       (VkRenderPassCreateFlags)0,                                     // VkRenderPassCreateFlags                      flags
+                       2u,                                                                                     // deUint32                                                     attachmentCount
+                       attachmentDescriptions,                                         // const VkAttachmentDescription*       pAttachments
+                       1u,                                                                                     // deUint32                                                     subpassCount
+                       &subpassDescription,                                            // const VkSubpassDescription*          pSubpasses
+                       0u,                                                                                     // deUint32                                                     dependencyCount
+                       DE_NULL                                                                         // const VkSubpassDependency*           pDependencies
+               };
+
+               m_renderPasses.push_back(VkRenderPassSp(new Unique<VkRenderPass>(createRenderPass(m_vkd, *m_device, &renderPassInfo))));
+       }
+
+       // Create framebuffers
+       for (deUint32 framebufferIdx = 0; framebufferIdx < 2; framebufferIdx++)
+       {
+               const VkImageView                               attachmentBindInfos[]   =
+               {
+                       *m_colorAttachmentView,
+                       **m_inputImageViews[framebufferIdx],
+               };
+
+               const VkFramebufferCreateInfo   framebufferParams               =
+               {
+                       VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,      // VkStructureType                      sType;
+                       DE_NULL,                                                                        // const void*                          pNext;
+                       0u,                                                                                     // VkFramebufferCreateFlags     flags;
+                       **m_renderPasses[framebufferIdx],                       // VkRenderPass                         renderPass;
+                       2u,                                                                                     // deUint32                                     attachmentCount;
+                       attachmentBindInfos,                                            // const VkImageView*           pAttachments;
+                       (deUint32)m_renderSize.x(),                                     // deUint32                                     width;
+                       (deUint32)m_renderSize.y(),                                     // deUint32                                     height;
+                       1u                                                                                      // deUint32                                     layers;
+               };
+
+               m_framebuffers.push_back(VkFramebufferSp(new Unique<VkFramebuffer>(createFramebuffer(m_vkd, *m_device, &framebufferParams))));
+       }
+
+       // Create pipeline layout
+       {
+               // Create descriptor set layout
+               const VkDescriptorSetLayoutBinding              descriptorSetLayoutBinding              =
+               {
+                       m_params.binding,                                               // uint32_t                             binding;
+                       VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,    // VkDescriptorType             descriptorType;
+                       1u,                                                                             // uint32_t                             descriptorCount;
+                       VK_SHADER_STAGE_FRAGMENT_BIT,                   // VkShaderStageFlags   stageFlags;
+                       DE_NULL                                                                 // const VkSampler*             pImmutableSamplers;
+               };
+
+               const VkDescriptorSetLayoutCreateInfo   descriptorSetLayoutCreateInfo   =
+               {
+                       VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,            // VkStructureType                                              sType;
+                       DE_NULL,                                                                                                        // const void*                                                  pNext;
+                       VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR,        // VkDescriptorSetLayoutCreateFlags             flags;
+                       1u,                                                                                                                     // uint32_t                                                             bindingCount;
+                       &descriptorSetLayoutBinding                                                                     // const VkDescriptorSetLayoutBinding*  pBindings;
+               };
+
+               m_descriptorSetLayout = createDescriptorSetLayout(m_vkd, *m_device, &descriptorSetLayoutCreateInfo, DE_NULL);
+
+               // Create pipeline layout
+               const VkPipelineLayoutCreateInfo                pipelineLayoutParams                    =
+               {
+                       VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,  // VkStructureType                              sType;
+                       DE_NULL,                                                                                // const void*                                  pNext;
+                       0u,                                                                                             // VkPipelineLayoutCreateFlags  flags;
+                       1u,                                                                                             // deUint32                                             descriptorSetCount;
+                       &(*m_descriptorSetLayout),                                              // const VkDescriptorSetLayout* pSetLayouts;
+                       0u,                                                                                             // deUint32                                             pushConstantRangeCount;
+                       DE_NULL                                                                                 // const VkPushDescriptorRange* pPushDescriptorRanges;
+               };
+
+               m_pipelineLayout = createPipelineLayout(m_vkd, *m_device, &pipelineLayoutParams);
+       }
+
+       // Create shaders
+       {
+               m_vertexShaderModule    = createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("vert"), 0u);
+               m_fragmentShaderModule  = createShaderModule(m_vkd, *m_device, m_context.getBinaryCollection().get("frag"), 0u);
+       }
+
+       // Create pipelines
+       for (deUint32 pipelineIdx = 0; pipelineIdx < 2; pipelineIdx++)
+       {
+               const VkVertexInputBindingDescription           vertexInputBindingDescription           =
+               {
+                       0u,                                                     // deUint32                                     binding;
+                       sizeof(Vertex4Tex4),            // deUint32                                     strideInBytes;
+                       VK_VERTEX_INPUT_RATE_VERTEX     // VkVertexInputStepRate        stepRate;
+               };
+
+               const VkVertexInputAttributeDescription         vertexInputAttributeDescriptions[]      =
+               {
+                       {
+                               0u,                                                                             // deUint32     location;
+                               0u,                                                                             // deUint32     binding;
+                               VK_FORMAT_R32G32B32A32_SFLOAT,                  // VkFormat     format;
+                               0u                                                                              // deUint32     offsetInBytes;
+                       },
+                       {
+                               1u,                                                                             // deUint32     location;
+                               0u,                                                                             // deUint32     binding;
+                               VK_FORMAT_R32G32B32A32_SFLOAT,                  // VkFormat     format;
+                               DE_OFFSET_OF(Vertex4Tex4, texCoord),    // deUint32     offset;
+                       }
+               };
+
+               const VkPipelineVertexInputStateCreateInfo      vertexInputStateParams                          =
+               {
+                       VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,      // VkStructureType                                                      sType;
+                       DE_NULL,                                                                                                        // const void*                                                          pNext;
+                       0u,                                                                                                                     // vkPipelineVertexInputStateCreateFlags        flags;
+                       1u,                                                                                                                     // deUint32                                                                     bindingCount;
+                       &vertexInputBindingDescription,                                                         // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
+                       2u,                                                                                                                     // deUint32                                                                     attributeCount;
+                       vertexInputAttributeDescriptions                                                        // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
+               };
+
+               const VkPrimitiveTopology                                       topology                                                        = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
+
+               const vector<VkViewport>                                        viewports                                                       (1, makeViewport(m_renderSize));
+               const vector<VkRect2D>                                          scissors                                                        (1, makeRect2D(m_renderSize));
+
+               m_graphicsPipelines.push_back(VkPipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(m_vkd,                                                   // const DeviceInterface&                                               vk
+                                                                                                                                                                                          *m_device,                                           // const VkDevice                                                               device
+                                                                                                                                                                                          *m_pipelineLayout,                           // const VkPipelineLayout                                               pipelineLayout
+                                                                                                                                                                                          *m_vertexShaderModule,                       // const VkShaderModule                                                 vertexShaderModule
+                                                                                                                                                                                          DE_NULL,                                                     // const VkShaderModule                                                 tessellationControlShaderModule
+                                                                                                                                                                                          DE_NULL,                                                     // const VkShaderModule                                                 tessellationEvalShaderModule
+                                                                                                                                                                                          DE_NULL,                                                     // const VkShaderModule                                                 geometryShaderModule
+                                                                                                                                                                                          *m_fragmentShaderModule,                     // const VkShaderModule                                                 fragmentShaderModule
+                                                                                                                                                                                          **m_renderPasses[pipelineIdx],       // const VkRenderPass                                                   renderPass
+                                                                                                                                                                                          viewports,                                           // const std::vector<VkViewport>&                               viewports
+                                                                                                                                                                                          scissors,                                            // const std::vector<VkRect2D>&                                 scissors
+                                                                                                                                                                                          topology,                                            // const VkPrimitiveTopology                                    topology
+                                                                                                                                                                                          0u,                                                          // const deUint32                                                               subpass
+                                                                                                                                                                                          0u,                                                          // const deUint32                                                               patchControlPoints
+                                                                                                                                                                                          &vertexInputStateParams))));         // const VkPipelineVertexInputStateCreateInfo*  vertexInputStateCreateInfo
+       }
+
+       // Create vertex buffer
+       {
+               const VkBufferCreateInfo vertexBufferParams =
+               {
+                       VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,                                           // VkStructureType              sType;
+                       DE_NULL,                                                                                                        // const void*                  pNext;
+                       0u,                                                                                                                     // VkBufferCreateFlags  flags;
+                       (VkDeviceSize)(sizeof(Vertex4RGBA) * m_vertices.size()),        // VkDeviceSize                 size;
+                       VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                                                      // VkBufferUsageFlags   usage;
+                       VK_SHARING_MODE_EXCLUSIVE,                                                                      // VkSharingMode                sharingMode;
+                       1u,                                                                                                                     // deUint32                             queueFamilyCount;
+                       &m_queueFamilyIndex                                                                                     // const deUint32*              pQueueFamilyIndices;
+               };
+
+               m_vertexBuffer          = createBuffer(m_vkd, *m_device, &vertexBufferParams);
+               m_vertexBufferAlloc     = m_allocator.allocate(getBufferMemoryRequirements(m_vkd, *m_device, *m_vertexBuffer), MemoryRequirement::HostVisible);
+
+               VK_CHECK(m_vkd.bindBufferMemory(*m_device, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
+
+               // Load vertices into vertex buffer
+               deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4Tex4));
+               flushMappedMemoryRange(m_vkd, *m_device, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset(), vertexBufferParams.size);
+       }
+
+       // Create command pool
+       m_cmdPool = createCommandPool(m_vkd, *m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, m_queueFamilyIndex);
+
+       // Create command buffer
+       {
+               const VkClearValue      attachmentClearValue    = defaultClearValue(m_colorFormat);
+               const VkDeviceSize      vertexBufferOffset              = 0;
+
+               m_cmdBuffer = allocateCommandBuffer(m_vkd, *m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+               beginCommandBuffer(m_vkd, *m_cmdBuffer, 0u);
+               for (deUint32 quadNdx = 0; quadNdx < m_params.numCalls; quadNdx++)
+               {
+                       beginRenderPass(m_vkd, *m_cmdBuffer, **m_renderPasses[quadNdx], **m_framebuffers[quadNdx], makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), attachmentClearValue);
+                       m_vkd.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_graphicsPipelines[quadNdx]);
+                       m_vkd.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
+
+                       VkDescriptorImageInfo   descriptorImageInfo     =
+                       {
+                               0,                                                              // VkSampler            sampler;
+                               **m_inputImageViews[quadNdx],   // VkImageView          imageView;
+                               VK_IMAGE_LAYOUT_GENERAL                 // VkImageLayout        imageLayout;
+                       };
+
+                       VkWriteDescriptorSet    writeDescriptorSet      =
+                       {
+                               VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType                                      sType;
+                               DE_NULL,                                                                // const void*                                          pNext;
+                               0u,                                                                             // VkDescriptorSet                                      dstSet;
+                               m_params.binding,                                               // uint32_t                                                     dstBinding;
+                               0u,                                                                             // uint32_t                                                     dstArrayElement;
+                               1u,                                                                             // uint32_t                                                     descriptorCount;
+                               m_params.descriptorType,                                // VkDescriptorType                                     descriptorType;
+                               &descriptorImageInfo,                                   // const VkDescriptorImageInfo*         pImageInfo;
+                               DE_NULL,                                                                // const VkDescriptorBufferInfo*        pBufferInfo;
+                               DE_NULL                                                                 // const VkBufferView*                          pTexelBufferView;
+                       };
+
+                       m_vkd.cmdPushDescriptorSetKHR(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &writeDescriptorSet);
+                       m_vkd.cmdDraw(*m_cmdBuffer, 6, 1, 6 * quadNdx, 0);
+
+                       endRenderPass(m_vkd, *m_cmdBuffer);
+               }
+
+               endCommandBuffer(m_vkd, *m_cmdBuffer);
+       }
+}
+
+PushDescriptorInputAttachmentGraphicsTestInstance::~PushDescriptorInputAttachmentGraphicsTestInstance (void)
+{
+}
+
+tcu::TestStatus PushDescriptorInputAttachmentGraphicsTestInstance::iterate (void)
+{
+       init();
+
+       submitCommandsAndWait(m_vkd, *m_device, m_queue, m_cmdBuffer.get());
+
+       return verifyImage();
+}
+
+tcu::TestStatus PushDescriptorInputAttachmentGraphicsTestInstance::verifyImage (void)
+{
+       const tcu::TextureFormat        tcuColorFormat  = mapVkFormat(m_colorFormat);
+       const tcu::TextureFormat        tcuDepthFormat  = tcu::TextureFormat();
+       const ColorVertexShader         vertexShader;
+       const ColorFragmentShader       fragmentShader  (tcuColorFormat, tcuDepthFormat);
+       const rr::Program                       program                 (&vertexShader, &fragmentShader);
+       ReferenceRenderer                       refRenderer             (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
+       bool                                            compareOk               = false;
+
+       // Render reference image
+       {
+               vector<Vertex4RGBA>     refQuads = createQuads(m_params.numCalls, 0.25f);
+               tcu::Vec4                       colors[2];
+
+               colors[0] = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
+               colors[1] = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
+
+               for (deUint32 quadIdx = 0; quadIdx < m_params.numCalls; quadIdx++)
+                       for (deUint32 vertexIdx = 0; vertexIdx < 6; vertexIdx++)
+                       {
+                               const deUint32 idx = quadIdx * 6 + vertexIdx;
+                               refQuads[idx].color.xyzw() = colors[quadIdx];
+                       }
+
+               refRenderer.draw(rr::RenderState(refRenderer.getViewportState()), rr::PRIMITIVETYPE_TRIANGLES, refQuads);
+       }
+
+       // Compare result with reference image
+       {
+               de::MovePtr<tcu::TextureLevel> result = readColorAttachment(m_vkd, *m_device, m_queue, m_queueFamilyIndex, m_allocator, *m_colorImage, m_colorFormat, m_renderSize);
+
+               compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
+                                                                                                                         "IntImageCompare",
+                                                                                                                         "Image comparison",
+                                                                                                                         refRenderer.getAccess(),
+                                                                                                                         result->getAccess(),
+                                                                                                                         tcu::UVec4(2, 2, 2, 2),
+                                                                                                                         tcu::IVec3(1, 1, 0),
+                                                                                                                         true,
+                                                                                                                         tcu::COMPARE_LOG_RESULT);
+       }
+
+       if (compareOk)
+               return tcu::TestStatus::pass("Result image matches reference");
+       else
+               return tcu::TestStatus::fail("Image mismatch");
+}
+
+class PushDescriptorInputAttachmentGraphicsTest : public vkt::TestCase
+{
+public:
+                                               PushDescriptorInputAttachmentGraphicsTest               (tcu::TestContext&      testContext,
+                                                                                                                        const string&          name,
+                                                                                                                        const string&          description,
+                                                                                                                        const TestParams&      params);
+                                               ~PushDescriptorInputAttachmentGraphicsTest      (void);
+       void                            initPrograms                                            (SourceCollections& sourceCollections) const;
+       TestInstance*           createInstance                                          (Context& context) const;
+
+protected:
+       const TestParams        m_params;
+};
+
+PushDescriptorInputAttachmentGraphicsTest::PushDescriptorInputAttachmentGraphicsTest   (tcu::TestContext&      testContext,
+                                                                                                                                       const string&           name,
+                                                                                                                                       const string&           description,
+                                                                                                                                       const TestParams&       params)
+       : vkt::TestCase (testContext, name, description)
+       , m_params              (params)
+{
+}
+
+PushDescriptorInputAttachmentGraphicsTest::~PushDescriptorInputAttachmentGraphicsTest (void)
+{
+}
+
+TestInstance* PushDescriptorInputAttachmentGraphicsTest::createInstance (Context& context) const
+{
+       return new PushDescriptorInputAttachmentGraphicsTestInstance(context, m_params);
+}
+
+void PushDescriptorInputAttachmentGraphicsTest::initPrograms (SourceCollections& sourceCollections) const
+{
+       const string    vertexSrc       =
+               "#version 450\n"
+               "layout(location = 0) in highp vec4 position;\n"
+               "layout(location = 1) in highp vec4 texcoordVtx;\n"
+               "layout(location = 0) out highp vec2 texcoordFrag;\n"
+               "\n"
+               "out gl_PerVertex { vec4 gl_Position; };\n"
+               "\n"
+               "void main()\n"
+               "{\n"
+               "       gl_Position = position;\n"
+               "       texcoordFrag = texcoordVtx.xy;\n"
+               "}\n";
+
+       sourceCollections.glslSources.add("vert") << glu::VertexSource(vertexSrc);
+
+       const string    fragmentSrc     =
+               "#version 450\n"
+               "layout(location = 0) in highp vec2 texcoordFrag;\n"
+               "layout(location = 0) out highp vec4 fragColor;\n"
+               "layout(input_attachment_index = 0, set = 0, binding = " + de::toString(m_params.binding) + ") uniform subpassInput inputColor;\n"
+               "\n"
+               "void main (void)\n"
+               "{\n"
+               "       fragColor = subpassLoad(inputColor);\n"
+               "}\n";
+
+       sourceCollections.glslSources.add("frag") << glu::FragmentSource(fragmentSrc);
+}
+
+} // anonymous
+
+tcu::TestCaseGroup* createPushDescriptorTests (tcu::TestContext& testCtx)
+{
+       const TestParams params[] =
+       {
+               { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,                    0u, 1u },
+               { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,                    0u, 2u },
+               { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,                    1u, 2u },
+               { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,                    3u, 2u },
+               { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,                    0u, 1u },
+               { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,                    0u, 2u },
+               { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,                    1u, 2u },
+               { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,                    3u, 2u },
+               { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,    0u, 1u },
+               { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,    0u, 2u },
+               { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,    1u, 2u },
+               { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,    3u, 2u },
+               { VK_DESCRIPTOR_TYPE_SAMPLER,                                   0u, 1u },
+               { VK_DESCRIPTOR_TYPE_SAMPLER,                                   0u, 2u },
+               { VK_DESCRIPTOR_TYPE_SAMPLER,                                   1u, 2u },
+               { VK_DESCRIPTOR_TYPE_SAMPLER,                                   3u, 2u },
+               { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,                             0u, 1u },
+               { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,                             0u, 2u },
+               { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,                             1u, 2u },
+               { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,                             3u, 2u },
+               { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,                             0u, 1u },
+               { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,                             0u, 2u },
+               { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,                             1u, 2u },
+               { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,                             3u, 2u },
+               { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,              0u, 1u },
+               { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,              0u, 2u },
+               { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,              1u, 2u },
+               { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,              3u, 2u },
+               { VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,              0u, 1u },
+               { VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,              0u, 2u },
+               { VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,              1u, 2u },
+               { VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,              3u, 2u },
+               { VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,                  0u, 1u },
+               { VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,                  0u, 2u },
+               { VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,                  1u, 2u },
+               { VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,                  3u, 2u }
+       };
+
+       de::MovePtr<tcu::TestCaseGroup> pushDescriptorTests     (new tcu::TestCaseGroup(testCtx, "push_descriptor", "Push descriptor tests"));
+
+       de::MovePtr<tcu::TestCaseGroup> graphicsTests           (new tcu::TestCaseGroup(testCtx, "graphics", "graphics pipeline"));
+       de::MovePtr<tcu::TestCaseGroup> computeTests            (new tcu::TestCaseGroup(testCtx, "compute", "compute pipeline"));
+
+       for (deUint32 testIdx = 0; testIdx < DE_LENGTH_OF_ARRAY(params); testIdx++)
+       {
+               string testName;
+               testName += "binding" + de::toString(params[testIdx].binding) + "_numcalls" + de::toString(params[testIdx].numCalls);
+               switch(params[testIdx].descriptorType)
+               {
+                       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
+                               testName += "_uniform_buffer";
+                               graphicsTests->addChild(new PushDescriptorBufferGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
+                               computeTests->addChild(new PushDescriptorBufferComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
+                               break;
+
+                       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
+                               testName += "_storage_buffer";
+                               graphicsTests->addChild(new PushDescriptorBufferGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
+                               computeTests->addChild(new PushDescriptorBufferComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
+                               break;
+
+                       case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+                               testName += "_combined_image_sampler";
+                               graphicsTests->addChild(new PushDescriptorImageGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
+                               computeTests->addChild(new PushDescriptorImageComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
+                               break;
+
+                       case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
+                               testName += "_sampled_image";
+                               graphicsTests->addChild(new PushDescriptorImageGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
+                               computeTests->addChild(new PushDescriptorImageComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
+                               break;
+
+                       case VK_DESCRIPTOR_TYPE_SAMPLER:
+                               testName += "_sampler";
+                               graphicsTests->addChild(new PushDescriptorImageGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
+                               computeTests->addChild(new PushDescriptorImageComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
+                               break;
+
+                       case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+                               testName += "_storage_image";
+                               graphicsTests->addChild(new PushDescriptorImageGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
+                               computeTests->addChild(new PushDescriptorImageComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
+                               break;
+
+                       case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
+                               testName += "_uniform_texel_buffer";
+                               graphicsTests->addChild(new PushDescriptorTexelBufferGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
+                               computeTests->addChild(new PushDescriptorTexelBufferComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
+                               break;
+
+                       case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
+                               testName += "_storage_texel_buffer";
+                               graphicsTests->addChild(new PushDescriptorTexelBufferGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
+                               computeTests->addChild(new PushDescriptorTexelBufferComputeTest(testCtx, testName.c_str(), "", params[testIdx]));
+                               break;
+
+                       case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
+                               testName += "_input_attachment";
+                               graphicsTests->addChild(new PushDescriptorInputAttachmentGraphicsTest(testCtx, testName.c_str(), "", params[testIdx]));
                                break;
 
                        default:
index 11d697e..b921495 100644 (file)
@@ -168982,6 +168982,34 @@ dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls1_storage_buffer
 dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls2_storage_buffer
 dEQP-VK.pipeline.push_descriptor.graphics.binding1_numcalls2_storage_buffer
 dEQP-VK.pipeline.push_descriptor.graphics.binding3_numcalls2_storage_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls1_combined_image_sampler
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls2_combined_image_sampler
+dEQP-VK.pipeline.push_descriptor.graphics.binding1_numcalls2_combined_image_sampler
+dEQP-VK.pipeline.push_descriptor.graphics.binding3_numcalls2_combined_image_sampler
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls1_sampler
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls2_sampler
+dEQP-VK.pipeline.push_descriptor.graphics.binding1_numcalls2_sampler
+dEQP-VK.pipeline.push_descriptor.graphics.binding3_numcalls2_sampler
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls1_sampled_image
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls2_sampled_image
+dEQP-VK.pipeline.push_descriptor.graphics.binding1_numcalls2_sampled_image
+dEQP-VK.pipeline.push_descriptor.graphics.binding3_numcalls2_sampled_image
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls1_storage_image
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls2_storage_image
+dEQP-VK.pipeline.push_descriptor.graphics.binding1_numcalls2_storage_image
+dEQP-VK.pipeline.push_descriptor.graphics.binding3_numcalls2_storage_image
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls1_uniform_texel_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls2_uniform_texel_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding1_numcalls2_uniform_texel_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding3_numcalls2_uniform_texel_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls1_storage_texel_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls2_storage_texel_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding1_numcalls2_storage_texel_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding3_numcalls2_storage_texel_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls1_input_attachment
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls2_input_attachment
+dEQP-VK.pipeline.push_descriptor.graphics.binding1_numcalls2_input_attachment
+dEQP-VK.pipeline.push_descriptor.graphics.binding3_numcalls2_input_attachment
 dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls1_uniform_buffer
 dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls2_uniform_buffer
 dEQP-VK.pipeline.push_descriptor.compute.binding1_numcalls2_uniform_buffer
@@ -168990,6 +169018,30 @@ dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls1_storage_buffer
 dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls2_storage_buffer
 dEQP-VK.pipeline.push_descriptor.compute.binding1_numcalls2_storage_buffer
 dEQP-VK.pipeline.push_descriptor.compute.binding3_numcalls2_storage_buffer
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls1_combined_image_sampler
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls2_combined_image_sampler
+dEQP-VK.pipeline.push_descriptor.compute.binding1_numcalls2_combined_image_sampler
+dEQP-VK.pipeline.push_descriptor.compute.binding3_numcalls2_combined_image_sampler
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls1_sampler
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls2_sampler
+dEQP-VK.pipeline.push_descriptor.compute.binding1_numcalls2_sampler
+dEQP-VK.pipeline.push_descriptor.compute.binding3_numcalls2_sampler
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls1_sampled_image
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls2_sampled_image
+dEQP-VK.pipeline.push_descriptor.compute.binding1_numcalls2_sampled_image
+dEQP-VK.pipeline.push_descriptor.compute.binding3_numcalls2_sampled_image
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls1_storage_image
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls2_storage_image
+dEQP-VK.pipeline.push_descriptor.compute.binding1_numcalls2_storage_image
+dEQP-VK.pipeline.push_descriptor.compute.binding3_numcalls2_storage_image
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls1_uniform_texel_buffer
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls2_uniform_texel_buffer
+dEQP-VK.pipeline.push_descriptor.compute.binding1_numcalls2_uniform_texel_buffer
+dEQP-VK.pipeline.push_descriptor.compute.binding3_numcalls2_uniform_texel_buffer
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls1_storage_texel_buffer
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls2_storage_texel_buffer
+dEQP-VK.pipeline.push_descriptor.compute.binding1_numcalls2_storage_texel_buffer
+dEQP-VK.pipeline.push_descriptor.compute.binding3_numcalls2_storage_texel_buffer
 dEQP-VK.pipeline.spec_constant.graphics.vertex.default_value.bool
 dEQP-VK.pipeline.spec_constant.graphics.vertex.default_value.int
 dEQP-VK.pipeline.spec_constant.graphics.vertex.default_value.uint
index f0b7849..064c486 100644 (file)
@@ -168982,6 +168982,34 @@ dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls1_storage_buffer
 dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls2_storage_buffer
 dEQP-VK.pipeline.push_descriptor.graphics.binding1_numcalls2_storage_buffer
 dEQP-VK.pipeline.push_descriptor.graphics.binding3_numcalls2_storage_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls1_combined_image_sampler
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls2_combined_image_sampler
+dEQP-VK.pipeline.push_descriptor.graphics.binding1_numcalls2_combined_image_sampler
+dEQP-VK.pipeline.push_descriptor.graphics.binding3_numcalls2_combined_image_sampler
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls1_sampler
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls2_sampler
+dEQP-VK.pipeline.push_descriptor.graphics.binding1_numcalls2_sampler
+dEQP-VK.pipeline.push_descriptor.graphics.binding3_numcalls2_sampler
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls1_sampled_image
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls2_sampled_image
+dEQP-VK.pipeline.push_descriptor.graphics.binding1_numcalls2_sampled_image
+dEQP-VK.pipeline.push_descriptor.graphics.binding3_numcalls2_sampled_image
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls1_storage_image
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls2_storage_image
+dEQP-VK.pipeline.push_descriptor.graphics.binding1_numcalls2_storage_image
+dEQP-VK.pipeline.push_descriptor.graphics.binding3_numcalls2_storage_image
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls1_uniform_texel_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls2_uniform_texel_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding1_numcalls2_uniform_texel_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding3_numcalls2_uniform_texel_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls1_storage_texel_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls2_storage_texel_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding1_numcalls2_storage_texel_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding3_numcalls2_storage_texel_buffer
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls1_input_attachment
+dEQP-VK.pipeline.push_descriptor.graphics.binding0_numcalls2_input_attachment
+dEQP-VK.pipeline.push_descriptor.graphics.binding1_numcalls2_input_attachment
+dEQP-VK.pipeline.push_descriptor.graphics.binding3_numcalls2_input_attachment
 dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls1_uniform_buffer
 dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls2_uniform_buffer
 dEQP-VK.pipeline.push_descriptor.compute.binding1_numcalls2_uniform_buffer
@@ -168990,6 +169018,30 @@ dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls1_storage_buffer
 dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls2_storage_buffer
 dEQP-VK.pipeline.push_descriptor.compute.binding1_numcalls2_storage_buffer
 dEQP-VK.pipeline.push_descriptor.compute.binding3_numcalls2_storage_buffer
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls1_combined_image_sampler
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls2_combined_image_sampler
+dEQP-VK.pipeline.push_descriptor.compute.binding1_numcalls2_combined_image_sampler
+dEQP-VK.pipeline.push_descriptor.compute.binding3_numcalls2_combined_image_sampler
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls1_sampler
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls2_sampler
+dEQP-VK.pipeline.push_descriptor.compute.binding1_numcalls2_sampler
+dEQP-VK.pipeline.push_descriptor.compute.binding3_numcalls2_sampler
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls1_sampled_image
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls2_sampled_image
+dEQP-VK.pipeline.push_descriptor.compute.binding1_numcalls2_sampled_image
+dEQP-VK.pipeline.push_descriptor.compute.binding3_numcalls2_sampled_image
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls1_storage_image
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls2_storage_image
+dEQP-VK.pipeline.push_descriptor.compute.binding1_numcalls2_storage_image
+dEQP-VK.pipeline.push_descriptor.compute.binding3_numcalls2_storage_image
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls1_uniform_texel_buffer
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls2_uniform_texel_buffer
+dEQP-VK.pipeline.push_descriptor.compute.binding1_numcalls2_uniform_texel_buffer
+dEQP-VK.pipeline.push_descriptor.compute.binding3_numcalls2_uniform_texel_buffer
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls1_storage_texel_buffer
+dEQP-VK.pipeline.push_descriptor.compute.binding0_numcalls2_storage_texel_buffer
+dEQP-VK.pipeline.push_descriptor.compute.binding1_numcalls2_storage_texel_buffer
+dEQP-VK.pipeline.push_descriptor.compute.binding3_numcalls2_storage_texel_buffer
 dEQP-VK.pipeline.spec_constant.graphics.vertex.default_value.bool
 dEQP-VK.pipeline.spec_constant.graphics.vertex.default_value.int
 dEQP-VK.pipeline.spec_constant.graphics.vertex.default_value.uint