--- /dev/null
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2018 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Descriptor set tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktApiDescriptorSetTests.hpp"
+#include "vktTestCaseUtil.hpp"
+
+#include "vkRefUtil.hpp"
+#include "vkPrograms.hpp"
+
+namespace vkt
+{
+namespace api
+{
+
+namespace
+{
+
+using namespace std;
+using namespace vk;
+
+// Descriptor set layout used to create a pipeline layout is destroyed prior to creating a pipeline
+Move<VkPipelineLayout> createPipelineLayoutDestroyDescriptorSetLayout (const DeviceInterface& vk, const VkDevice& device)
+{
+ const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutInfo =
+ {
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkDescriptorSetLayoutCreateFlags)0, // VkDescriptorSetLayoutCreateFlags flags;
+ 0u, // deUint32 bindingCount;
+ DE_NULL, // const VkDescriptorSetLayoutBinding* pBindings;
+ };
+
+ Unique<VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout(vk, device, &descriptorSetLayoutInfo));
+
+ const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
+ 1u, // deUint32 setLayoutCount;
+ &descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
+ 0u, // deUint32 pushConstantRangeCount;
+ DE_NULL // const VkPushConstantRange* pPushConstantRanges;
+ };
+
+ return createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
+}
+
+tcu::TestStatus descriptorSetLayoutLifetimeGraphicsTest (Context& context)
+{
+ const DeviceInterface& vk = context.getDeviceInterface();
+ const VkDevice device = context.getDevice();
+
+ Unique<VkPipelineLayout> pipelineLayout (createPipelineLayoutDestroyDescriptorSetLayout(vk, device));
+
+ const Unique<VkShaderModule> vertexShaderModule (createShaderModule(vk, device, context.getBinaryCollection().get("vertex"), 0));
+
+ const VkPipelineShaderStageCreateInfo shaderStageCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
+ VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
+ vertexShaderModule.get(), // VkShaderModule shader;
+ "main", // const char* pName;
+ DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
+ };
+
+ const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
+ 0u, // deUint32 vertexBindingDescriptionCount;
+ DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
+ 0u, // deUint32 vertexAttributeDescriptionCount;
+ DE_NULL // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
+ };
+
+ const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
+ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // VkPrimitiveTopology topology;
+ VK_FALSE // VkBool32 primitiveRestartEnable;
+ };
+
+ const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
+ VK_FALSE, // VkBool32 depthClampEnable;
+ VK_TRUE, // VkBool32 rasterizerDiscardEnable;
+ VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
+ VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
+ VK_FRONT_FACE_CLOCKWISE, // VkFrontFace frontFace;
+ VK_FALSE, // VkBool32 depthBiasEnable;
+ 0.0f, // float depthBiasConstantFactor;
+ 0.0f, // float depthBiasClamp;
+ 0.0f, // float depthBiasSlopeFactor;
+ 1.0f // float lineWidth;
+ };
+
+ const VkSubpassDescription subpassDescription =
+ {
+ (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
+ VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
+ 0u, // deUint32 inputAttachmentCount
+ DE_NULL, // const VkAttachmentReference* pInputAttachments
+ 0u, // deUint32 colorAttachmentCount
+ DE_NULL, // const VkAttachmentReference* pColorAttachments
+ DE_NULL, // const VkAttachmentReference* pResolveAttachments
+ DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment
+ 0u, // deUint32 preserveAttachmentCount
+ DE_NULL // const deUint32* pPreserveAttachments
+ };
+
+ const VkRenderPassCreateInfo renderPassCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
+ 0u, // deUint32 attachmentCount
+ DE_NULL, // const VkAttachmentDescription* pAttachments
+ 1u, // deUint32 subpassCount
+ &subpassDescription, // const VkSubpassDescription* pSubpasses
+ 0u, // deUint32 dependencyCount
+ DE_NULL // const VkSubpassDependency* pDependencies
+ };
+
+ Unique<VkRenderPass> renderPass (createRenderPass(vk, device, &renderPassCreateInfo));
+
+ const VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
+ 1u, // deUint32 stageCount;
+ &shaderStageCreateInfo, // const VkPipelineShaderStageCreateInfo* pStages;
+ &vertexInputStateCreateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
+ &inputAssemblyStateCreateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
+ DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
+ DE_NULL, // const VkPipelineViewportStateCreateInfo* pViewportState;
+ &rasterizationStateCreateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
+ DE_NULL, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
+ DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
+ DE_NULL, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
+ DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
+ pipelineLayout.get(), // VkPipelineLayout layout;
+ renderPass.get(), // VkRenderPass renderPass;
+ 0u, // deUint32 subpass;
+ DE_NULL, // VkPipeline basePipelineHandle;
+ 0 // int basePipelineIndex;
+ };
+
+ Unique<VkPipeline> graphicsPipeline (createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineCreateInfo));
+
+ // Test should always pass
+ return tcu::TestStatus::pass("Pass");
+}
+
+tcu::TestStatus descriptorSetLayoutLifetimeComputeTest (Context& context)
+{
+ const DeviceInterface& vk = context.getDeviceInterface();
+ const VkDevice device = context.getDevice();
+
+ Unique<VkPipelineLayout> pipelineLayout (createPipelineLayoutDestroyDescriptorSetLayout(vk, device));
+
+ const Unique<VkShaderModule> computeShaderModule (createShaderModule(vk, device, context.getBinaryCollection().get("compute"), 0));
+
+ const VkPipelineShaderStageCreateInfo shaderStageCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
+ VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
+ computeShaderModule.get(), // VkShaderModule shader;
+ "main", // const char* pName;
+ DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
+ };
+
+ const VkComputePipelineCreateInfo computePipelineCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType
+ DE_NULL, // const void* pNext
+ (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags
+ shaderStageCreateInfo, // VkPipelineShaderStageCreateInfo stage
+ pipelineLayout.get(), // VkPipelineLayout layout
+ DE_NULL, // VkPipeline basePipelineHandle
+ 0 // int basePipelineIndex
+ };
+
+ Unique<VkPipeline> computePipeline (createComputePipeline(vk, device, DE_NULL, &computePipelineCreateInfo));
+
+ // Test should always pass
+ return tcu::TestStatus::pass("Pass");
+}
+
+} // anonymous
+
+void createDescriptorSetLayoutLifetimeGraphicsSource (SourceCollections& dst)
+{
+ dst.glslSources.add("vertex") << glu::VertexSource(
+ "#version 310 es\n"
+ "void main (void)\n"
+ "{\n"
+ " gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
+ "}\n");
+}
+
+void createDescriptorSetLayoutLifetimeComputeSource (SourceCollections& dst)
+{
+ dst.glslSources.add("compute") << glu::ComputeSource(
+ "#version 310 es\n"
+ "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
+ "void main (void)\n"
+ "{\n"
+ "}\n");
+}
+
+tcu::TestCaseGroup* createDescriptorSetLayoutLifetimeTests (tcu::TestContext& testCtx)
+{
+ de::MovePtr<tcu::TestCaseGroup> descriptorSetLayoutLifetimeTests(new tcu::TestCaseGroup(testCtx, "descriptor_set_layout_lifetime", "Descriptor set layout lifetime tests"));
+
+ addFunctionCaseWithPrograms(descriptorSetLayoutLifetimeTests.get(), "graphics", "Test descriptor set layout lifetime in graphics pipeline", createDescriptorSetLayoutLifetimeGraphicsSource, descriptorSetLayoutLifetimeGraphicsTest);
+ addFunctionCaseWithPrograms(descriptorSetLayoutLifetimeTests.get(), "compute", "Test descriptor set layout lifetime in compute pipeline", createDescriptorSetLayoutLifetimeComputeSource, descriptorSetLayoutLifetimeComputeTest);
+
+ return descriptorSetLayoutLifetimeTests.release();
+}
+
+tcu::TestCaseGroup* createDescriptorSetTests (tcu::TestContext& testCtx)
+{
+ de::MovePtr<tcu::TestCaseGroup> descriptorSetTests(new tcu::TestCaseGroup(testCtx, "descriptor_set", "Descriptor set tests"));
+
+ descriptorSetTests->addChild(createDescriptorSetLayoutLifetimeTests(testCtx));
+
+ return descriptorSetTests.release();
+}
+
+} // api
+} // vkt