#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
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
{
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),
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;
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);
{
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);
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);
// 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);
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
{
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);
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);
{
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);
{
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;
}
};
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: