/*------------------------------------------------------------------------- * Vulkan Conformance Tests * ------------------------ * * Copyright (c) 2018 The Khronos Group Inc. * 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 Pipeline tests *//*--------------------------------------------------------------------*/ #include "vktApiPipelineTests.hpp" #include "vktTestCaseUtil.hpp" #include "deUniquePtr.hpp" #include "vkMemUtil.hpp" #include "vkRefUtil.hpp" #include "vkPrograms.hpp" #include "vkQueryUtil.hpp" #include "vkTypeUtil.hpp" #include "vkCmdUtil.hpp" #include "vkObjUtil.hpp" #include "vkBarrierUtil.hpp" #include "vkBufferWithMemory.hpp" #include "vkBuilderUtil.hpp" #include "vkImageUtil.hpp" #include "tcuTestLog.hpp" #include #include namespace vkt { namespace api { namespace { using namespace std; using namespace vk; VkFormat getRenderTargetFormat (const InstanceInterface& vk, const VkPhysicalDevice& device) { const VkFormatFeatureFlags featureFlags = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT; VkFormatProperties formatProperties; vk.getPhysicalDeviceFormatProperties(device, VK_FORMAT_B8G8R8A8_UNORM, &formatProperties); if ((formatProperties.linearTilingFeatures & featureFlags) || (formatProperties.optimalTilingFeatures & featureFlags)) return VK_FORMAT_B8G8R8A8_UNORM; vk.getPhysicalDeviceFormatProperties(device, VK_FORMAT_R8G8B8A8_UNORM, &formatProperties); if ((formatProperties.linearTilingFeatures & featureFlags) || formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) return VK_FORMAT_R8G8B8A8_UNORM; TCU_THROW(NotSupportedError, "Device does not support VK_FORMAT_B8G8R8A8_UNORM nor VK_FORMAT_R8G8B8A8_UNORM"); return VK_FORMAT_UNDEFINED; } Move createCommandBuffer (const DeviceInterface& vkd, VkDevice device, VkCommandPool commandPool) { const VkCommandBufferAllocateInfo allocateInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; commandPool, // VkCommandPool commandPool; VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; 1u // deUint32 commandBufferCount; }; return allocateCommandBuffer(vkd, device, &allocateInfo); } enum DrawTriangleMode { DTM_DESTROY_RENDER_PASS_AFTER_CREATING_PIPELINE = 0, DTM_DESTROY_PIPELINE_LAYOUT_AFTER_CREATING_PIPELINE, }; tcu::TestStatus drawTriangleTest (Context& context, DrawTriangleMode mode) { const DeviceInterface& vk = context.getDeviceInterface(); const InstanceInterface& vki = context.getInstanceInterface(); const VkDevice device = context.getDevice(); const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); const VkFormat format = getRenderTargetFormat(vki, physicalDevice); const VkFormatProperties formatProperties (getPhysicalDeviceFormatProperties(vki, physicalDevice, format)); const VkImageTiling imageTiling = (formatProperties.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? VK_IMAGE_TILING_LINEAR : (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? VK_IMAGE_TILING_OPTIMAL : VK_CORE_IMAGE_TILING_LAST; const VkImageCreateInfo attachmentImageCreateInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkImageCreateFlags)0u, // VkImageCreateFlags flags; VK_IMAGE_TYPE_2D, // VkImageType imageType; format, // VkFormat format; { 256u, // deUint32 width; 256u, // deUint32 height; 1u // deUint32 depth; }, // VkExtent3D extent; 1u, // deUint32 mipLevels; 1u, // deUint32 arrayLayers; VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; imageTiling, // VkImageTiling tiling; VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage; VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 0u, // deUint32 queueFamilyIndexCount; DE_NULL, // const deUint32* pQueueFamilyIndices; VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; }; const Unique attachmentImage (createImage(vk, device, &attachmentImageCreateInfo)); de::MovePtr attachmentImageMemory = context.getDefaultAllocator().allocate(getImageMemoryRequirements(vk, device, *attachmentImage), MemoryRequirement::Any); VK_CHECK(vk.bindImageMemory(device, *attachmentImage, attachmentImageMemory->getMemory(), attachmentImageMemory->getOffset())); const tcu::TextureFormat resultFormat = mapVkFormat(format); const VkDeviceSize imageSizeBytes = (VkDeviceSize)(resultFormat.getPixelSize() * 256 * 256); const VkBufferCreateInfo readImageBufferParams { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; 0u, // VkBufferCreateFlags flags; imageSizeBytes, // VkDeviceSize size; VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage; VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 0u, // deUint32 queueFamilyCount; DE_NULL, // const deUint32* pQueueFamilyIndices; }; const Unique readImageBuffer(createBuffer(vk, device, &readImageBufferParams)); const de::UniquePtr readImageBufferMemory(context.getDefaultAllocator().allocate(getBufferMemoryRequirements(vk, device, *readImageBuffer), MemoryRequirement::HostVisible)); VK_CHECK(vk.bindBufferMemory(device, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset())); const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); const VkCommandPoolCreateInfo commandPoolParams = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkCommandPoolCreateFlags)0u, // VkCommandPoolCreateFlags flags; queueFamilyIndex // deUint32 queueFamilyIndex; }; const Unique commandPool (createCommandPool(vk, device, &commandPoolParams, DE_NULL)); const Unique commandBuffer (createCommandBuffer(vk, device, commandPool.get())); const VkCommandBufferBeginInfo commandBufferBeginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; DE_NULL // const VkCommandBufferInheritanceInfo* pInheritanceInfo; }; VK_CHECK(vk.beginCommandBuffer(commandBuffer.get(), &commandBufferBeginInfo)); const VkAttachmentDescription attachmentDescription = { (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags; format, // 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 attachmentReference = { 0u, // deUint32 attachment; VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; }; const VkSubpassDescription subpassDescription = { (VkSubpassDescriptionFlags)0u, // VkSubpassDescriptionFlags flags; VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint 0u, // deUint32 inputAttachmentCount DE_NULL, // const VkAttachmentReference* pInputAttachments 1u, // deUint32 colorAttachmentCount &attachmentReference, // 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)0u, // VkRenderPassCreateFlags flags; 1u, // deUint32 attachmentCount &attachmentDescription, // const VkAttachmentDescription* pAttachments 1u, // deUint32 subpassCount &subpassDescription, // const VkSubpassDescription* pSubpasses 0u, // deUint32 dependencyCount DE_NULL // const VkSubpassDependency* pDependencies }; // When testing renderpass lifetime - create two compatible renderpasses, otherwise use just renderPassB VkRenderPass renderPassA; if (DTM_DESTROY_RENDER_PASS_AFTER_CREATING_PIPELINE == mode) VK_CHECK(vk.createRenderPass(device, &renderPassCreateInfo, DE_NULL, &renderPassA)); const Move renderPassB (createRenderPass(vk, device, &renderPassCreateInfo)); const VkImageViewCreateInfo attachmentImageViewCreateInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkImageViewCreateFlags)0u, // VkImageViewCreateFlags flags; attachmentImage.get(), // VkImage image; VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; format, // VkFormat format; { VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r; VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g; VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b; VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a; }, // VkComponentMapping components; { VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 0u, // deUint32 baseMipLevel; 1u, // deUint32 levelCount; 0u, // deUint32 baseArrayLayer; 1u // deUint32 layerCount; } // VkImageSubresourceRange subresourceRange; }; const Unique attachmentImageView (createImageView(vk, device, &attachmentImageViewCreateInfo)); const VkFramebufferCreateInfo framebufferCreateInfo = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkFramebufferCreateFlags)0u, // VkFramebufferCreateFlags flags; renderPassB.get(), // VkRenderPass renderPass; 1u, // deUint32 attachmentCount; &attachmentImageView.get(), // const VkImageView* pAttachments; 256u, // deUint32 width; 256u, // deUint32 height; 1u // deUint32 layers; }; const Unique frameBuffer (createFramebuffer(vk, device, &framebufferCreateInfo)); const Unique vertexShaderModule (createShaderModule(vk, device, context.getBinaryCollection().get("vertex"), 0)); const Unique fragmentShaderModule (createShaderModule(vk, device, context.getBinaryCollection().get("fragment"), 0)); const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkPipelineLayoutCreateFlags)0u, // VkPipelineLayoutCreateFlags flags; 0u, // deUint32 setLayoutCount; DE_NULL, // const VkDescriptorSetLayout* pSetLayouts; 0u, // deUint32 pushConstantRangeCount; DE_NULL // const VkPushConstantRange* pPushConstantRanges; }; Move pipelineLayout (createPipelineLayout(vk, device, &pipelineLayoutCreateInfo)); const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkPipelineVertexInputStateCreateFlags)0u, // VkPipelineVertexInputStateCreateFlags flags; 0u, // deUint32 vertexBindingDescriptionCount; DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 0u, // deUint32 vertexAttributeDescriptionCount; DE_NULL // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; }; const VkViewport viewport = { 0.0f, // float x; 0.0f, // float y; 64.0f, // float width; 64.0f, // float height; 0.0f, // float minDepth; 0.0f, // float maxDepth; }; const std::vector viewports (1, viewport); const std::vector scissors (1, makeRect2D(0, 0, 64u, 64u)); const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkPipelineRasterizationStateCreateFlags)0u, // VkPipelineRasterizationStateCreateFlags flags; VK_FALSE, // VkBool32 depthClampEnable; VK_FALSE, // 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 VkPipelineColorBlendAttachmentState colorBlendAttachmentState = { VK_FALSE, // VkBool32 blendEnable; VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcColorBlendFactor; VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor; VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcAlphaBlendFactor; VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor; VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; (VkColorComponentFlags)0xF // VkColorComponentFlags colorWriteMask; }; const VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkPipelineColorBlendStateCreateFlags)0u, // VkPipelineColorBlendStateCreateFlags flags; VK_FALSE, // VkBool32 logicOpEnable; VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp; 1u, // deUint32 attachmentCount; &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; { 1.0f, 1.0f, 1.0f, 1.0f } // float blendConstants[4]; }; VkRenderPass renderPassUsedForPipeline = *renderPassB; if (DTM_DESTROY_RENDER_PASS_AFTER_CREATING_PIPELINE == mode) renderPassUsedForPipeline = renderPassA; const Unique graphicsPipeline (makeGraphicsPipeline(vk, // const DeviceInterface& vk device, // const VkDevice device *pipelineLayout, // const VkPipelineLayout pipelineLayout *vertexShaderModule, // const VkShaderModule vertexShaderModule DE_NULL, // const VkShaderModule tessellationControlModule DE_NULL, // const VkShaderModule tessellationEvalModule DE_NULL, // const VkShaderModule geometryShaderModule *fragmentShaderModule, // const VkShaderModule fragmentShaderModule renderPassUsedForPipeline, // const VkRenderPass renderPass viewports, // const std::vector& viewports scissors, // const std::vector& scissors VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // const VkPrimitiveTopology topology 0u, // const deUint32 subpass 0u, // const deUint32 patchControlPoints &vertexInputStateCreateInfo, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo &rasterizationStateCreateInfo, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo &colorBlendStateCreateInfo)); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo if (DTM_DESTROY_PIPELINE_LAYOUT_AFTER_CREATING_PIPELINE == mode) pipelineLayout = decltype(pipelineLayout)(); beginRenderPass(vk, *commandBuffer, renderPassB.get(), frameBuffer.get(), makeRect2D(0, 0, 256u, 256u), tcu::Vec4(0.25f, 0.25f, 0.25f, 0.0f)); vk.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get()); // Destroy the renderpass that was used to create the graphics pipeline if (DTM_DESTROY_RENDER_PASS_AFTER_CREATING_PIPELINE == mode) vk.destroyRenderPass(device, renderPassA, DE_NULL); vk.cmdDraw(*commandBuffer, 3u, 1u, 0u, 0u); endRenderPass(vk, *commandBuffer); // Copy image to buffer { copyImageToBuffer(vk, *commandBuffer, *attachmentImage, *readImageBuffer, tcu::IVec2(256, 256)); } VK_CHECK(vk.endCommandBuffer(*commandBuffer)); const VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; 0u, // deUint32 waitSemaphoreCount; DE_NULL, // const VkSemaphore* pWaitSemaphores; DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask; 1u, // deUint32 commandBufferCount; &commandBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 0u, // deUint32 signalSemaphoreCount; DE_NULL // const VkSemaphore* pSignalSemaphores; }; vk::VkQueue queue = context.getUniversalQueue(); VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, DE_NULL)); VK_CHECK(vk.queueWaitIdle(queue)); VK_CHECK(vk.deviceWaitIdle(device)); invalidateAlloc(vk, device, *readImageBufferMemory); const tcu::ConstPixelBufferAccess resultAccess(resultFormat, 256, 256, 1, readImageBufferMemory->getHostPtr()); // check just one pixel tcu::Vec4 pixel = resultAccess.getPixel(1, 1); if ((pixel.x() < 0.9f) || (pixel.y() > 0.1f) || (pixel.z() > 0.1f) || (pixel.w() < 0.9f)) return tcu::TestStatus::fail("Fail"); tcu::TestLog& log = context.getTestContext().getLog(); log << tcu::TestLog::ImageSet("Image verification", "") << tcu::TestLog::Image("Result", "Result", resultAccess, tcu::Vec4(1.0f), tcu::Vec4(0.0f)) << tcu::TestLog::EndImageSet; return tcu::TestStatus::pass("Pass"); } tcu::TestStatus renderpassLifetimeTest(Context& context) { return drawTriangleTest(context, DTM_DESTROY_RENDER_PASS_AFTER_CREATING_PIPELINE); } void createDrawTriangleSource (SourceCollections& dst) { dst.glslSources.add("vertex") << glu::VertexSource( "#version 310 es\n" "void main (void)\n" "{\n" " gl_Position = vec4(float(1 - 2 * int(gl_VertexIndex != 1)),\n" " float(1 - 2 * int(gl_VertexIndex > 0)), 0.0, 1.0);\n" "}\n"); dst.glslSources.add("fragment") << glu::FragmentSource( "#version 310 es\n" "layout (location = 0) out highp vec4 color;\n" "void main (void)\n" "{\n" " color = vec4(1.0, 0.0, 0.0, 1.0);\n" "}\n"); } void changeColorAttachmentImageLayout (const DeviceInterface& vk, VkCommandBuffer commandBuffer, VkImage image) { const VkImageMemoryBarrier imageMemoryBarrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; DE_NULL, // const void* pNext; (VkAccessFlags)0u, // VkAccessFlags srcAccessMask; VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 0u, // deUint32 srcQueueFamilyIndex; 0u, // deUint32 dstQueueFamilyIndex; image, // VkImage image; { VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 0u, // deUint32 baseMipLevel; 1u, // deUint32 levelCount; 0u, // deUint32 baseArrayLayer;( 1u // deUint32 layerCount; } // VkImageSubresourceRange subresourceRange; }; vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlagBits)0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageMemoryBarrier); } Move createSimpleRenderPass (const DeviceInterface& vk, const VkDevice& device, VkFormat format, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp, VkAttachmentStoreOp stencilStoreOp, VkImageLayout layout) { const VkAttachmentDescription attachmentDescription = { (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags; format, // VkFormat format; VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; loadOp, // VkAttachmentLoadOp loadOp; VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; stencilLoadOp, // VkAttachmentLoadOp stencilLoadOp; stencilStoreOp, // VkAttachmentStoreOp stencilStoreOp; VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; layout // VkImageLayout finalLayout; }; const VkAttachmentReference attachmentReference = { 0u, // deUint32 attachment; layout // VkImageLayout layout; }; const VkSubpassDescription subpassDescription = { (VkSubpassDescriptionFlags)0u, // VkSubpassDescriptionFlags flags; VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint 0u, // deUint32 inputAttachmentCount DE_NULL, // const VkAttachmentReference* pInputAttachments 1u, // deUint32 colorAttachmentCount &attachmentReference, // 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)0u, // VkRenderPassCreateFlags flags; 1u, // deUint32 attachmentCount &attachmentDescription, // const VkAttachmentDescription* pAttachments 1u, // deUint32 subpassCount &subpassDescription, // const VkSubpassDescription* pSubpasses 0u, // deUint32 dependencyCount DE_NULL // const VkSubpassDependency* pDependencies }; return createRenderPass(vk, device, &renderPassCreateInfo); } // This test has the same functionality as VkLayerTest.RenderPassInUseDestroyedSignaled tcu::TestStatus framebufferCompatibleRenderPassTest (Context& context) { const DeviceInterface& vk = context.getDeviceInterface(); const InstanceInterface& vki = context.getInstanceInterface(); const VkDevice device = context.getDevice(); const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); const VkQueue queue = context.getUniversalQueue(); const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); const VkCommandPoolCreateInfo commandPoolParams = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkCommandPoolCreateFlags)0u, // VkCommandPoolCreateFlags flags; queueFamilyIndex // deUint32 queueFamilyIndex; }; const Unique commandPool (createCommandPool(vk, device, &commandPoolParams, DE_NULL)); const Unique commandBuffer (createCommandBuffer(vk, device, commandPool.get())); const VkCommandBufferBeginInfo commandBufferBeginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; DE_NULL // const VkCommandBufferInheritanceInfo* pInheritanceInfo; }; VK_CHECK(vk.beginCommandBuffer(commandBuffer.get(), &commandBufferBeginInfo)); const VkFormat format = getRenderTargetFormat(vki, physicalDevice); const VkFormatProperties formatProperties (getPhysicalDeviceFormatProperties(vki, physicalDevice, format)); const VkImageTiling imageTiling = (formatProperties.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? VK_IMAGE_TILING_LINEAR : (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? VK_IMAGE_TILING_OPTIMAL : VK_CORE_IMAGE_TILING_LAST; const VkImageCreateInfo imageCreateInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkImageCreateFlags)0u, // VkImageCreateFlags flags; VK_IMAGE_TYPE_2D, // VkImageType imageType; format, // VkFormat format; { 256u, // deUint32 width; 256u, // deUint32 height; 1u // deUint32 depth; }, // VkExtent3D extent; 1u, // deUint32 mipLevels; 1u, // deUint32 arrayLayers; VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; imageTiling, // VkImageTiling tiling; VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, // VkImageUsageFlags usage; VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 0u, // deUint32 queueFamilyIndexCount; DE_NULL, // const deUint32* pQueueFamilyIndices; VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; }; const Unique attachmentImage (createImage(vk, device, &imageCreateInfo)); de::MovePtr attachmentImageMemory = context.getDefaultAllocator().allocate(getImageMemoryRequirements(vk, device, *attachmentImage), MemoryRequirement::Any); VK_CHECK(vk.bindImageMemory(device, *attachmentImage, attachmentImageMemory->getMemory(), attachmentImageMemory->getOffset())); changeColorAttachmentImageLayout(vk, commandBuffer.get(), attachmentImage.get()); const VkImageViewCreateInfo imageViewCreateInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkImageViewCreateFlags)0u, // VkImageViewCreateFlags flags; attachmentImage.get(), // VkImage image; VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; format, // VkFormat format; { VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r; VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g; VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b; VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a; }, // VkComponentMapping components; { VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 0u, // deUint32 baseMipLevel; 1u, // deUint32 levelCount; 0u, // deUint32 baseArrayLayer; 1u // deUint32 layerCount; } // VkImageSubresourceRange subresourceRange; }; const Unique attachmentImageView (createImageView(vk, device, &imageViewCreateInfo)); Unique renderPassA (createSimpleRenderPass(vk, device, format, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); // Create framebuffer using the first render pass const VkFramebufferCreateInfo framebufferCreateInfo = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkFramebufferCreateFlags)0u, // VkFramebufferCreateFlags flags; renderPassA.get(), // VkRenderPass renderPass; 1u, // deUint32 attachmentCount; &attachmentImageView.get(), // const VkImageView* pAttachments; 256u, // deUint32 width; 256u, // deUint32 height; 1u // deUint32 layers; }; const Unique frameBuffer (createFramebuffer(vk, device, &framebufferCreateInfo)); const Unique renderPassB (createSimpleRenderPass(vk, device, format, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL)); beginRenderPass(vk, commandBuffer.get(), renderPassB.get(), frameBuffer.get(), makeRect2D(0, 0, 1u, 1u)); endRenderPass(vk, commandBuffer.get()); VK_CHECK(vk.endCommandBuffer(commandBuffer.get())); const VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; 0u, // deUint32 waitSemaphoreCount; DE_NULL, // const VkSemaphore* pWaitSemaphores; DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask; 1u, // deUint32 commandBufferCount; &commandBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 0u, // deUint32 signalSemaphoreCount; DE_NULL // const VkSemaphore* pSignalSemaphores; }; VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, DE_NULL)); VK_CHECK(vk.queueWaitIdle(queue)); // Test should always pass return tcu::TestStatus::pass("Pass"); } Move getDescriptorSetLayout (const DeviceInterface& vk, const VkDevice& device, deUint32 bindingCount, const VkDescriptorSetLayoutBinding* layoutBindings) { const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkDescriptorSetLayoutCreateFlags)0u, // VkDescriptorSetLayoutCreateFlags flags; bindingCount, // deUint32 bindingCount; layoutBindings // const VkDescriptorSetLayoutBinding* pBindings; }; return createDescriptorSetLayout(vk, device, &descriptorSetLayoutCreateInfo); } VkDescriptorSet getDescriptorSet (const DeviceInterface& vk, const VkDevice& device, VkDescriptorPool descriptorPool, VkDescriptorSetLayout setLayout) { const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; descriptorPool, // VkDescriptorPool descriptorPool; 1u, // deUint32 descriptorSetCount; &setLayout // const VkDescriptorSetLayout* pSetLayouts; }; VkDescriptorSet descriptorSet; VK_CHECK(vk.allocateDescriptorSets(device, &descriptorSetAllocateInfo, &descriptorSet)); return descriptorSet; } Move getPipelineLayout (const DeviceInterface& vk, const VkDevice& device, deUint32 setLayoutCount, const VkDescriptorSetLayout* setLayouts) { const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkPipelineLayoutCreateFlags)0u, // VkPipelineLayoutCreateFlags flags; setLayoutCount, // deUint32 setLayoutCount; setLayouts, // const VkDescriptorSetLayout* pSetLayouts; 0u, // deUint32 pushConstantRangeCount; DE_NULL // const VkPushConstantRange* pPushConstantRanges; }; return createPipelineLayout(vk, device, &pipelineLayoutCreateInfo); } Move createSimpleGraphicsPipeline (const DeviceInterface& vk, const VkDevice& device, deUint32 numShaderStages, const VkPipelineShaderStageCreateInfo* shaderStageCreateInfos, VkPipelineLayout pipelineLayout, VkRenderPass renderPass, de::SharedPtr resourceInterface) { #ifndef CTS_USES_VULKANSC DE_UNREF(resourceInterface); #endif // CTS_USES_VULKANSC 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 VkPipelineViewportStateCreateInfo viewPortStateCreateInfo = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags; 1, // deUint32 viewportCount; DE_NULL, // const VkViewport* pViewports; 1, // deUint32 scissorCount; DE_NULL // const VkRect2D* pScissors; }; 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_FALSE, // VkBool32 rasterizerDiscardEnable; VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; VK_CULL_MODE_BACK_BIT, // 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 VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags; VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples; VK_FALSE, // VkBool32 sampleShadingEnable; 0.0f, // float minSampleShading; DE_NULL, // const VkSampleMask* pSampleMask; VK_FALSE, // VkBool32 alphaToCoverageEnable; VK_FALSE // VkBool32 alphaToOneEnable; }; const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = { VK_FALSE, // VkBool32 blendEnable; VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcColorBlendFactor; VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor; VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcAlphaBlendFactor; VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor; VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; (VkColorComponentFlags)0xFu // VkColorComponentFlags colorWriteMask; }; const VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags; DE_FALSE, // VkBool32 logicOpEnable; VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp; 1, // deUint32 attachmentCount; &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; { 1.0f, 1.0f, 1.0f, 1.0f } // float blendConstants[4]; }; const VkDynamicState dynamicStates[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkPipelineDynamicStateCreateFlags)0u, // VkPipelineDynamicStateCreateFlags flags; DE_LENGTH_OF_ARRAY(dynamicStates), // deUint32 dynamicStateCount; dynamicStates // const VkDynamicState* pDynamicStates; }; const VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags; numShaderStages, // deUint32 stageCount; shaderStageCreateInfos, // const VkPipelineShaderStageCreateInfo* pStages; &vertexInputStateCreateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; &inputAssemblyStateCreateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; &viewPortStateCreateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState; &rasterizationStateCreateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState; &multisampleStateCreateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; &colorBlendStateCreateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; &dynamicStateCreateInfo, // const VkPipelineDynamicStateCreateInfo* pDynamicState; pipelineLayout, // VkPipelineLayout layout; renderPass, // VkRenderPass renderPass; 0u, // deUint32 subpass; DE_NULL, // VkPipeline basePipelineHandle; 0 // int basePipelineIndex; }; const VkPipelineCacheCreateInfo pipelineCacheCreateInfo = { VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; #ifndef CTS_USES_VULKANSC (VkPipelineCacheCreateFlags)0u, // VkPipelineCacheCreateFlags flags; 0, // size_t initialDataSize; DE_NULL // const void* pInitialData; #else VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT | VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT, // VkPipelineCacheCreateFlags flags; resourceInterface->getCacheDataSize(), // deUintptr initialDataSize; resourceInterface->getCacheData() // const void* pInitialData; #endif // CTS_USES_VULKANSC }; const Unique pipelineCache (createPipelineCache(vk, device, &pipelineCacheCreateInfo)); return createGraphicsPipeline(vk, device, pipelineCache.get(), &graphicsPipelineCreateInfo); } tcu::TestStatus pipelineLayoutLifetimeTest (Context& context, VkPipelineBindPoint bindPoint) { const DeviceInterface& vk = context.getDeviceInterface(); const InstanceInterface& vki = context.getInstanceInterface(); const VkDevice device = context.getDevice(); const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); const bool isGraphics = (bindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS); const VkCommandPoolCreateInfo commandPoolParams = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkCommandPoolCreateFlags)0u, // VkCommandPoolCreateFlags flags; queueFamilyIndex // deUint32 queueFamilyIndex; }; const Unique commandPool (createCommandPool(vk, device, &commandPoolParams, DE_NULL)); const Unique commandBuffer (createCommandBuffer(vk, device, commandPool.get())); // Begin command buffer. { const VkCommandBufferBeginInfo commandBufferBeginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; DE_NULL // const VkCommandBufferInheritanceInfo* pInheritanceInfo; }; VK_CHECK(vk.beginCommandBuffer(commandBuffer.get(), &commandBufferBeginInfo)); } // These will only be used for graphics pipelines. Move attachmentImage; de::MovePtr attachmentImageMemory; Move attachmentImageView; Move renderPass; Move frameBuffer; if (isGraphics) { // Create image, render pass and framebuffer. const VkFormat format = getRenderTargetFormat(vki, physicalDevice); const VkFormatProperties formatProperties (getPhysicalDeviceFormatProperties(vki, physicalDevice, format)); const VkImageTiling imageTiling = (formatProperties.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? VK_IMAGE_TILING_LINEAR : (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) ? VK_IMAGE_TILING_OPTIMAL : VK_CORE_IMAGE_TILING_LAST; const VkImageCreateInfo imageCreateInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkImageCreateFlags)0u, // VkImageCreateFlags flags; VK_IMAGE_TYPE_2D, // VkImageType imageType; format, // VkFormat format; { 256u, // deUint32 width; 256u, // deUint32 height; 1u // deUint32 depth; }, // VkExtent3D extent; 1u, // deUint32 mipLevels; 1u, // deUint32 arrayLayers; VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; imageTiling, // VkImageTiling tiling; VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, // VkImageUsageFlags usage; VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 0u, // deUint32 queueFamilyIndexCount; DE_NULL, // const deUint32* pQueueFamilyIndices; VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; }; attachmentImage = createImage(vk, device, &imageCreateInfo); attachmentImageMemory = context.getDefaultAllocator().allocate(getImageMemoryRequirements(vk, device, *attachmentImage), MemoryRequirement::Any); VK_CHECK(vk.bindImageMemory(device, *attachmentImage, attachmentImageMemory->getMemory(), attachmentImageMemory->getOffset())); changeColorAttachmentImageLayout(vk, commandBuffer.get(), attachmentImage.get()); const VkImageViewCreateInfo imageViewCreateInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkImageViewCreateFlags)0u, // VkImageViewCreateFlags flags; attachmentImage.get(), // VkImage image; VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; format, // VkFormat format; { VK_COMPONENT_SWIZZLE_R, // VkComponentSwizzle r; VK_COMPONENT_SWIZZLE_G, // VkComponentSwizzle g; VK_COMPONENT_SWIZZLE_B, // VkComponentSwizzle b; VK_COMPONENT_SWIZZLE_A // VkComponentSwizzle a; }, // VkComponentMapping components; { VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 0u, // deUint32 baseMipLevel; 1u, // deUint32 levelCount; 0u, // deUint32 baseArrayLayer; 1u // deUint32 layerCount; } // VkImageSubresourceRange subresourceRange; }; attachmentImageView = createImageView(vk, device, &imageViewCreateInfo); renderPass = createSimpleRenderPass(vk, device, format, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); const VkFramebufferCreateInfo framebufferCreateInfo = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkFramebufferCreateFlags)0u, // VkFramebufferCreateFlags flags; renderPass.get(), // VkRenderPass renderPass; 1u, // deUint32 attachmentCount; &attachmentImageView.get(), // const VkImageView* pAttachments; 256u, // deUint32 width; 256u, // deUint32 height; 1u // deUint32 layers; }; frameBuffer = createFramebuffer(vk, device, &framebufferCreateInfo); } const VkDescriptorPoolSize descriptorPoolSizes[] = { { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // VkDescriptorType type; 10 // deUint32 descriptorCount; }, { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // VkDescriptorType type; 2 // deUint32 descriptorCount; }, { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, // VkDescriptorType type; 2 // deUint32 descriptorCount; } }; const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkDescriptorPoolCreateFlags)0u, // VkDescriptorPoolCreateFlags flags; (isGraphics ? 3u : 5u), // deUint32 maxSets; DE_LENGTH_OF_ARRAY(descriptorPoolSizes), // deUint32 poolSizeCount; descriptorPoolSizes // const VkDescriptorPoolSize* pPoolSizes; }; Move descriptorPool = createDescriptorPool(vk, device, &descriptorPoolCreateInfo, DE_NULL); const VkDescriptorSetLayoutBinding setLayoutBindingA[] = { { 0, // deUint32 binding; VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // VkDescriptorType descriptorType; 5, // deUint32 descriptorCount; VK_SHADER_STAGE_ALL, // VkShaderStageFlags stageFlags; DE_NULL // const VkSampler* pImmutableSamplers; } }; const VkShaderStageFlags shaderStage = (isGraphics ? VK_SHADER_STAGE_FRAGMENT_BIT : VK_SHADER_STAGE_COMPUTE_BIT); const VkDescriptorSetLayoutBinding setLayoutBindingB[] = { { 0, // deUint32 binding; VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // VkDescriptorType descriptorType; 5, // deUint32 descriptorCount; (VkShaderStageFlags)shaderStage, // VkShaderStageFlags stageFlags; DE_NULL // const VkSampler* pImmutableSamplers; } }; const VkDescriptorSetLayoutBinding setLayoutBindingC[] = { { 0, // deUint32 binding; VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // VkDescriptorType descriptorType; 2, // deUint32 descriptorCount; VK_SHADER_STAGE_ALL, // VkShaderStageFlags stageFlags; DE_NULL // const VkSampler* pImmutableSamplers; }, { 1, // deUint32 binding; VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, // VkDescriptorType descriptorType; 2, // deUint32 descriptorCount; VK_SHADER_STAGE_ALL, // VkShaderStageFlags stageFlags; DE_NULL // const VkSampler* pImmutableSamplers; } }; const Move descriptorSetLayouts[] = { getDescriptorSetLayout(vk, device, DE_LENGTH_OF_ARRAY(setLayoutBindingA), setLayoutBindingA), getDescriptorSetLayout(vk, device, DE_LENGTH_OF_ARRAY(setLayoutBindingB), setLayoutBindingB), getDescriptorSetLayout(vk, device, DE_LENGTH_OF_ARRAY(setLayoutBindingC), setLayoutBindingC) }; const VkDescriptorSetLayout setLayoutHandlesAC[] = { descriptorSetLayouts[0].get(), descriptorSetLayouts[2].get() }; const VkDescriptorSetLayout setLayoutHandlesB[] = { descriptorSetLayouts[1].get() }; const VkDescriptorSetLayout setLayoutHandlesBC[] = { descriptorSetLayouts[1].get(), descriptorSetLayouts[2].get() }; const VkDescriptorSet descriptorSets[] = { getDescriptorSet(vk, device, descriptorPool.get(), descriptorSetLayouts[0].get()), getDescriptorSet(vk, device, descriptorPool.get(), descriptorSetLayouts[1].get()), getDescriptorSet(vk, device, descriptorPool.get(), descriptorSetLayouts[2].get()) }; const VkDescriptorSet setHandlesAC[] = { descriptorSets[0], descriptorSets[2] }; const VkDescriptorSet setHandlesC[] = { descriptorSets[2] }; const Unique pipelineLayoutAC (getPipelineLayout(vk, device, DE_LENGTH_OF_ARRAY(setLayoutHandlesAC), setLayoutHandlesAC)); const Unique pipelineLayoutBC (getPipelineLayout(vk, device, DE_LENGTH_OF_ARRAY(setLayoutHandlesBC), setLayoutHandlesBC)); VkPipelineLayout pipelineLayoutB; { const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkPipelineLayoutCreateFlags)0u, // VkPipelineLayoutCreateFlags flags; DE_LENGTH_OF_ARRAY(setLayoutHandlesB), // deUint32 setLayoutCount; setLayoutHandlesB, // const VkDescriptorSetLayout* pSetLayouts; 0u, // deUint32 pushConstantRangeCount; DE_NULL // const VkPushConstantRange* pPushConstantRanges; }; VK_CHECK(vk.createPipelineLayout(device, &pipelineLayoutCreateInfo, DE_NULL, &pipelineLayoutB)); } std::vector> shaderModules; Move pipeline; if (isGraphics) { shaderModules.push_back(createShaderModule(vk, device, context.getBinaryCollection().get("vertex"), 0)); shaderModules.push_back(createShaderModule(vk, device, context.getBinaryCollection().get("fragment"), 0)); const VkPipelineShaderStageCreateInfo shaderStageCreateInfos[] = { { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage; shaderModules[0].get(), // VkShaderModule shader; "main", // const char* pName; DE_NULL, // const VkSpecializationInfo* pSpecializationInfo; }, { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage; shaderModules[1].get(), // VkShaderModule shader; "main", // const char* pName; DE_NULL, // const VkSpecializationInfo* pSpecializationInfo; } }; pipeline = createSimpleGraphicsPipeline(vk, device, DE_LENGTH_OF_ARRAY(shaderStageCreateInfos), shaderStageCreateInfos, pipelineLayoutB, renderPass.get(), context.getResourceInterface()); } else { shaderModules.push_back(createShaderModule(vk, device, context.getBinaryCollection().get("compute"), 0)); const VkPipelineShaderStageCreateInfo shaderStageCreateInfo = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage; shaderModules[0].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 pipelineLayoutB, // VkPipelineLayout layout DE_NULL, // VkPipeline basePipelineHandle 0 // int basePipelineIndex }; pipeline = createComputePipeline(vk, device, DE_NULL, &computePipelineCreateInfo); } if (isGraphics) { beginRenderPass(vk, commandBuffer.get(), renderPass.get(), frameBuffer.get(), makeRect2D(0, 0, 256u, 256u), tcu::Vec4(0.25f, 0.25f, 0.25f, 0.0f)); } vk.cmdBindPipeline(commandBuffer.get(), bindPoint, pipeline.get()); // Destroy the pipeline layout that was used to create the pipeline vk.destroyPipelineLayout(device, pipelineLayoutB, DE_NULL); vk.cmdBindDescriptorSets(commandBuffer.get(), bindPoint, pipelineLayoutAC.get(), 0u, DE_LENGTH_OF_ARRAY(setHandlesAC), setHandlesAC, 0u, DE_NULL); vk.cmdBindDescriptorSets(commandBuffer.get(), bindPoint, pipelineLayoutBC.get(), 1u, DE_LENGTH_OF_ARRAY(setHandlesC), setHandlesC, 0u, DE_NULL); if (isGraphics) { const VkViewport viewport = { 0.0f, // float x; 0.0f, // float y; 16.0f, // float width; 16.0f, // float height; 0.0f, // float minDepth; 1.0f // float maxDepth; }; const VkRect2D scissor = { { 0u, 0u }, // VkOffset2D offset; { 16u, 16u } // VkExtent2D extent; }; vk.cmdSetViewport(commandBuffer.get(), 0u, 1u, &viewport); vk.cmdSetScissor(commandBuffer.get(), 0u, 1u, &scissor); } vk.cmdBindDescriptorSets(commandBuffer.get(), bindPoint, pipelineLayoutAC.get(), 0u, DE_LENGTH_OF_ARRAY(setHandlesAC), setHandlesAC, 0u, DE_NULL); // Test should always pass return tcu::TestStatus::pass("Pass"); } void createPipelineLayoutLifetimeGraphicsSource (SourceCollections& dst) { dst.glslSources.add("vertex") << glu::VertexSource( "#version 450\n" "\n" "void main (void)\n" "{\n" " gl_Position = vec4(1);\n" "}\n"); dst.glslSources.add("fragment") << glu::FragmentSource( "#version 450\n" "\n" "layout(location=0) out vec4 x;\n" "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n" "void main (void)\n" "{\n" " x = vec4(bar.y);\n" "}\n"); } // This test has the same functionality as VkLayerTest.DescriptorSetCompatibility tcu::TestStatus pipelineLayoutLifetimeGraphicsTest (Context& context) { return pipelineLayoutLifetimeTest(context, VK_PIPELINE_BIND_POINT_GRAPHICS); } void createPipelineLayoutLifetimeComputeSource (SourceCollections& dst) { dst.glslSources.add("compute") << glu::ComputeSource( "#version 450\n" "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" "layout(set=0) layout(binding=0) uniform foo { int x; int y; } bar;\n" "void main (void)\n" "{\n" " vec4 x = vec4(bar.y);\n" "}\n"); } tcu::TestStatus pipelineLayoutLifetimeComputeTest (Context& context) { return pipelineLayoutLifetimeTest(context, VK_PIPELINE_BIND_POINT_COMPUTE); } void checkSupport (Context& context) { const InstanceInterface& vki = context.getInstanceInterface(); const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); // Throws exception if not supported getRenderTargetFormat(vki, physicalDevice); } void destroyEarlyComputeSource(SourceCollections& programs) { std::string comp = "#version 450\n" "layout (local_size_x=1, local_size_y=1, local_size_z=1) in;\n" "layout (constant_id=0) const uint flag = 0;\n" "layout (push_constant, std430) uniform PushConstants {\n" " uint base;\n" "};\n" "layout (set=0, binding=0, std430) buffer Block {\n" " uint data[];\n" "};\n" "\n" "void main() {\n" " if (flag != 0u) {\n" " uint idx = gl_GlobalInvocationID.x;\n" " data[idx] = data[idx] + base + idx;\n" " }\n" "}\n"; programs.glslSources.add("comp") << glu::ComputeSource(comp); } void checkMaintenance4Support(Context& context) { context.requireDeviceFunctionality("VK_KHR_maintenance4"); } enum DestroyPipelineLayoutMode { DPLM_DESTROY_AFTER_END_COMMAND_BUFFER = 0, DPLM_DESTROY_AFTER_CREATE_COMPUTE_PIPELINES, }; tcu::TestStatus destroyEarlyTest (Context& context, DestroyPipelineLayoutMode mode) { const auto& vkd = context.getDeviceInterface(); const auto device = context.getDevice(); auto& alloc = context.getDefaultAllocator(); const auto queue = context.getUniversalQueue(); const auto qIndex = context.getUniversalQueueFamilyIndex(); const deUint32 kBufferElements = 100u; const deUint32 kBufferSize = kBufferElements * sizeof(deUint32); const auto kBufferSizeDS = static_cast(kBufferSize); const deUint32 kInitialValue = 50u; const deUint32 kFlagValue = 1u; const deUint32 kBaseValue = 75u; // Allocate and prepare buffer. const auto bufferInfo = vk::makeBufferCreateInfo(kBufferSizeDS, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); vk::BufferWithMemory buffer (vkd, device, alloc, bufferInfo, vk::MemoryRequirement::HostVisible); auto& bufferAlloc = buffer.getAllocation(); void* bufferPtr = bufferAlloc.getHostPtr(); { const std::vector bufferValues (kBufferElements, kInitialValue); deMemcpy(bufferPtr, bufferValues.data(), kBufferSize); vk::flushAlloc(vkd, device, bufferAlloc); } // Descriptor set layout. vk::DescriptorSetLayoutBuilder layoutBuilder; layoutBuilder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT); const auto descriptorSetLayout = layoutBuilder.build(vkd, device); // Pipeline layout. const auto pushConstantRange = vk::makePushConstantRange(vk::VK_SHADER_STAGE_COMPUTE_BIT, 0u, static_cast(sizeof(kBaseValue))); const vk::VkPipelineLayoutCreateInfo pipelineLayoutInfo = { vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; nullptr, // const void* pNext; 0u, // VkPipelineLayoutCreateFlags flags; 1u, // deUint32 setLayoutCount; &descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts; 1u, // deUint32 pushConstantRangeCount; &pushConstantRange, // const VkPushConstantRange* pPushConstantRanges; }; auto pipelineLayout = vk::createPipelineLayout(vkd, device, &pipelineLayoutInfo); // Shader module. const auto shaderModule = vk::createShaderModule(vkd, device, context.getBinaryCollection().get("comp"), 0u); // Pipeline, with shader and specialization info. const auto specConstantSize = static_cast(sizeof(kFlagValue)); const vk::VkSpecializationMapEntry mapEntry = { 0u, // deUint32 constantID; 0u, // deUint32 offset; specConstantSize, // deUintptr size; }; const vk::VkSpecializationInfo specializationInfo = { 1u, // deUint32 mapEntryCount; &mapEntry, // const VkSpecializationMapEntry* pMapEntries; specConstantSize, // deUintptr dataSize; &kFlagValue, // const void* pData; }; const VkPipelineShaderStageCreateInfo shaderInfo = { vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; nullptr, // const void* pNext; 0u, // VkPipelineShaderStageCreateFlags flags; vk::VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage; shaderModule.get(), // VkShaderModule module; "main", // const char* pName; &specializationInfo, // const VkSpecializationInfo* pSpecializationInfo; }; const vk::VkComputePipelineCreateInfo pipelineInfo = { vk::VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType; nullptr, // const void* pNext; 0u, // VkPipelineCreateFlags flags; shaderInfo, // VkPipelineShaderStageCreateInfo stage; pipelineLayout.get(), // VkPipelineLayout layout; DE_NULL, // VkPipeline basePipelineHandle; 0, // deInt32 basePipelineIndex; }; const auto pipeline = vk::createComputePipeline(vkd, device, DE_NULL, &pipelineInfo); // Delete pipeline layout just after creating pipeline - this is what the test is for if (DPLM_DESTROY_AFTER_CREATE_COMPUTE_PIPELINES == mode) pipelineLayout = decltype(pipelineLayout)(); // Descriptor set. vk::DescriptorPoolBuilder descriptorPoolBuilder; descriptorPoolBuilder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); const auto descriptorPool = descriptorPoolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); const auto descriptorSet = vk::makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get()); // Update descriptor set with buffer. vk::DescriptorSetUpdateBuilder updateBuilder; const auto descriptorInfo = vk::makeDescriptorBufferInfo(buffer.get(), static_cast(0), kBufferSizeDS); updateBuilder.writeSingle(descriptorSet.get(), vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo); updateBuilder.update(vkd, device); // Prepare command buffer. const auto cmdPool = vk::makeCommandPool(vkd, device, qIndex); const auto cmdBufferPtr = vk::allocateCommandBuffer(vkd, device, cmdPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY); const auto cmdBuffer = cmdBufferPtr.get(); const auto barrier = vk::makeMemoryBarrier(vk::VK_ACCESS_SHADER_WRITE_BIT, vk::VK_ACCESS_HOST_READ_BIT); // Create new pipeline layout that will be used during dispatch if (DPLM_DESTROY_AFTER_CREATE_COMPUTE_PIPELINES == mode) pipelineLayout = vk::createPipelineLayout(vkd, device, &pipelineLayoutInfo); vk::beginCommandBuffer(vkd, cmdBuffer); vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, pipeline.get()); vkd.cmdBindDescriptorSets(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout.get(), 0u, 1u, &descriptorSet.get(), 0u, nullptr); vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), vk::VK_SHADER_STAGE_COMPUTE_BIT, 0u, static_cast(sizeof(kBaseValue)), &kBaseValue); vkd.cmdDispatch(cmdBuffer, kBufferElements, 1u, 1u); vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &barrier, 0u, nullptr, 0u, nullptr); vk::endCommandBuffer(vkd, cmdBuffer); // Delete pipeline layout just after recording command buffer - this is what the test is for if (DPLM_DESTROY_AFTER_END_COMMAND_BUFFER == mode) pipelineLayout = decltype(pipelineLayout)(); // Submit commands. vk::submitCommandsAndWait(vkd, device, queue, cmdBuffer); // Check buffer. vk::invalidateAlloc(vkd, device, bufferAlloc); std::vector outputData (kBufferElements); deMemcpy(outputData.data(), bufferPtr, kBufferSize); for (deUint32 i = 0; i < kBufferElements; ++i) { // This matches what the shader should calculate. const auto expectedValue = kInitialValue + kBaseValue + i; if (outputData[i] != expectedValue) { std::ostringstream msg; msg << "Unexpected value at buffer position " << i << ": expected " << expectedValue << " but found " << outputData[i]; return tcu::TestStatus::fail(msg.str()); } } return tcu::TestStatus::pass("Pass"); } tcu::TestStatus destroyAfterEndCommndBufferTest(Context& context) { return destroyEarlyTest(context, DPLM_DESTROY_AFTER_END_COMMAND_BUFFER); } tcu::TestStatus destroyAfterCreateComputePipelineTest(Context& context) { return destroyEarlyTest(context, DPLM_DESTROY_AFTER_CREATE_COMPUTE_PIPELINES); } tcu::TestStatus destroyAfterCreateGraphicsPipelineTest(Context& context) { return drawTriangleTest(context, DTM_DESTROY_PIPELINE_LAYOUT_AFTER_CREATING_PIPELINE); } #ifndef CTS_USES_VULKANSC Move createSimpleGraphicsPipelineInvalidPointers (const DeviceInterface& vk, const VkDevice& device, deUint32 numShaderStages, const VkPipelineShaderStageCreateInfo* shaderStageCreateInfos, VkPipelineLayout pipelineLayout, VkRenderPass renderPass, de::SharedPtr resourceInterface) { #ifndef CTS_USES_VULKANSC DE_UNREF(resourceInterface); #endif // CTS_USES_VULKANSC const void *invalidPointer = reinterpret_cast(~(0)); 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; (const VkVertexInputAttributeDescription*)invalidPointer // 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; }; // Disable rasterization to test unused structs 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_BACK_BIT, // 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 VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags; numShaderStages, // deUint32 stageCount; shaderStageCreateInfos, // const VkPipelineShaderStageCreateInfo* pStages; &vertexInputStateCreateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; &inputAssemblyStateCreateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; (const VkPipelineViewportStateCreateInfo*)invalidPointer, // const VkPipelineViewportStateCreateInfo* pViewportState; &rasterizationStateCreateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState; (const VkPipelineMultisampleStateCreateInfo*)invalidPointer, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; (const VkPipelineDepthStencilStateCreateInfo*)invalidPointer, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; (const VkPipelineColorBlendStateCreateInfo*)invalidPointer, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; pipelineLayout, // VkPipelineLayout layout; renderPass, // VkRenderPass renderPass; 0u, // deUint32 subpass; DE_NULL, // VkPipeline basePipelineHandle; 0 // int basePipelineIndex; }; const VkPipelineCacheCreateInfo pipelineCacheCreateInfo = { VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; #ifndef CTS_USES_VULKANSC (VkPipelineCacheCreateFlags)0u, // VkPipelineCacheCreateFlags flags; 0, // size_t initialDataSize; DE_NULL // const void* pInitialData; #else VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT | VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT, // VkPipelineCacheCreateFlags flags; resourceInterface->getCacheDataSize(), // deUintptr initialDataSize; invalidPointer // const void* pInitialData; #endif // CTS_USES_VULKANSC }; const Unique pipelineCache (createPipelineCache(vk, device, &pipelineCacheCreateInfo)); return createGraphicsPipeline(vk, device, pipelineCache.get(), &graphicsPipelineCreateInfo); } tcu::TestStatus pipelineInvalidPointersUnusedStructsTest (Context& context, VkPipelineBindPoint bindPoint) { const DeviceInterface& vk = context.getDeviceInterface(); const VkDevice device = context.getDevice(); const VkQueue queue = context.getUniversalQueue(); const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); const bool isGraphics = (bindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS); const void *invalidPointer = reinterpret_cast(~(0)); const VkCommandPoolCreateInfo commandPoolParams = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkCommandPoolCreateFlags)0u, // VkCommandPoolCreateFlags flags; queueFamilyIndex // deUint32 queueFamilyIndex; }; const Unique commandPool (createCommandPool(vk, device, &commandPoolParams, DE_NULL)); const Unique commandBuffer (createCommandBuffer(vk, device, commandPool.get())); // Begin command buffer. { const VkCommandBufferBeginInfo commandBufferBeginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; DE_NULL // const VkCommandBufferInheritanceInfo* pInheritanceInfo; }; VK_CHECK(vk.beginCommandBuffer(commandBuffer.get(), &commandBufferBeginInfo)); } // These will only be used for graphics pipelines. Move renderPass; Move frameBuffer; { const VkSubpassDescription subpassDescription = { (VkSubpassDescriptionFlags)0u, // VkSubpassDescriptionFlags flags; VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint 0u, // deUint32 inputAttachmentCount (const VkAttachmentReference*)invalidPointer, // const VkAttachmentReference* pInputAttachments 0u, // deUint32 colorAttachmentCount (const VkAttachmentReference*)invalidPointer, // const VkAttachmentReference* pColorAttachments DE_NULL, // const VkAttachmentReference* pResolveAttachments DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment 0u, // deUint32 preserveAttachmentCount (const deUint32*)invalidPointer // const deUint32* pPreserveAttachments }; const VkRenderPassCreateInfo renderPassCreateInfo = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkRenderPassCreateFlags)0u, // VkRenderPassCreateFlags flags; 0u, // deUint32 attachmentCount (const VkAttachmentDescription*)invalidPointer, // const VkAttachmentDescription* pAttachments 1u, // deUint32 subpassCount &subpassDescription, // const VkSubpassDescription* pSubpasses 0u, // deUint32 dependencyCount (const VkSubpassDependency*)invalidPointer // const VkSubpassDependency* pDependencies }; renderPass = createRenderPass(vk, device, &renderPassCreateInfo); const VkFramebufferCreateInfo framebufferCreateInfo = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkFramebufferCreateFlags)0u, // VkFramebufferCreateFlags flags; renderPass.get(), // VkRenderPass renderPass; 0u, // deUint32 attachmentCount; (const VkImageView*)invalidPointer, // const VkImageView* pAttachments; 256u, // deUint32 width; 256u, // deUint32 height; 1u // deUint32 layers; }; frameBuffer = createFramebuffer(vk, device, &framebufferCreateInfo); } Move pipelineLayout; { const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkPipelineLayoutCreateFlags)0u, // VkPipelineLayoutCreateFlags flags; 0u, // deUint32 setLayoutCount; (const VkDescriptorSetLayout*)invalidPointer, // const VkDescriptorSetLayout* pSetLayouts; 0u, // deUint32 pushConstantRangeCount; (const VkPushConstantRange*)invalidPointer // const VkPushConstantRange* pPushConstantRanges; }; pipelineLayout = vk::createPipelineLayout(vk, device, &pipelineLayoutCreateInfo); } std::vector> shaderModules; Move pipeline; if (isGraphics) { shaderModules.push_back(createShaderModule(vk, device, context.getBinaryCollection().get("vertex"), 0)); const VkPipelineShaderStageCreateInfo shaderStageCreateInfos[] = { { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage; shaderModules[0].get(), // VkShaderModule shader; "main", // const char* pName; DE_NULL, // const VkSpecializationInfo* pSpecializationInfo; } }; pipeline = createSimpleGraphicsPipelineInvalidPointers(vk, device, DE_LENGTH_OF_ARRAY(shaderStageCreateInfos), shaderStageCreateInfos, *pipelineLayout, renderPass.get(), context.getResourceInterface()); } else { shaderModules.push_back(createShaderModule(vk, device, context.getBinaryCollection().get("compute"), 0)); const VkPipelineShaderStageCreateInfo shaderStageCreateInfo = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage; shaderModules[0].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, // VkPipelineLayout layout DE_NULL, // VkPipeline basePipelineHandle 0 // int basePipelineIndex }; pipeline = createComputePipeline(vk, device, DE_NULL, &computePipelineCreateInfo); } if (isGraphics) { beginRenderPass(vk, commandBuffer.get(), renderPass.get(), frameBuffer.get(), makeRect2D(0, 0, 256u, 256u), tcu::Vec4(0.25f, 0.25f, 0.25f, 0.0f)); } vk.cmdBindPipeline(commandBuffer.get(), bindPoint, pipeline.get()); if (isGraphics) { vk.cmdDraw(commandBuffer.get(), 1u, 1u, 0u, 0u); vk.cmdEndRenderPass(commandBuffer.get()); } else { vk.cmdDispatch(commandBuffer.get(), 1u, 1u, 1u); } vk.endCommandBuffer(commandBuffer.get()); const VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; DE_NULL, // const void* pNext; 0u, // deUint32 waitSemaphoreCount; DE_NULL, // const VkSemaphore* pWaitSemaphores; DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask; 1u, // deUint32 commandBufferCount; &commandBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 0u, // deUint32 signalSemaphoreCount; DE_NULL // const VkSemaphore* pSignalSemaphores; }; VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, DE_NULL)); VK_CHECK(vk.queueWaitIdle(queue)); // Test should always pass return tcu::TestStatus::pass("Pass"); } void createPipelineInvalidPointersUnusedStructsGraphicsSource (SourceCollections& dst) { dst.glslSources.add("vertex") << glu::VertexSource( "#version 450\n" "\n" "void main (void)\n" "{\n" " gl_Position = vec4(1.0f);\n" "}\n"); dst.glslSources.add("fragment") << glu::FragmentSource( "#version 450\n" "\n" "void main (void)\n" "{\n" "}\n"); } tcu::TestStatus pipelineInvalidPointersUnusedStructsGraphicsTest (Context& context) { return pipelineInvalidPointersUnusedStructsTest(context, VK_PIPELINE_BIND_POINT_GRAPHICS); } void createPipelineInvalidPointersUnusedStructsComputeSource (SourceCollections& dst) { dst.glslSources.add("compute") << glu::ComputeSource( "#version 450\n" "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" "void main (void)\n" "{\n" "}\n"); } tcu::TestStatus pipelineInvalidPointersUnusedStructsComputeTest (Context& context) { return pipelineInvalidPointersUnusedStructsTest(context, VK_PIPELINE_BIND_POINT_COMPUTE); } #endif // CTS_USES_VULKANSC tcu::TestCaseGroup* createrenderpassTests (tcu::TestContext& testCtx) { de::MovePtr renderPassTests(new tcu::TestCaseGroup(testCtx, "renderpass")); // Draw after destroying the renderpass used to create a pipeline addFunctionCaseWithPrograms(renderPassTests.get(), "destroy_pipeline_renderpass", checkSupport, createDrawTriangleSource, renderpassLifetimeTest); // Use a render pass with a framebuffer that was created using another compatible render pass addFunctionCase(renderPassTests.get(), "framebuffer_compatible_renderpass", checkSupport, framebufferCompatibleRenderPassTest); return renderPassTests.release(); } tcu::TestCaseGroup* createPipelineLayoutLifetimeTests (tcu::TestContext& testCtx) { de::MovePtr pipelineLayoutLifetimeTests(new tcu::TestCaseGroup(testCtx, "lifetime")); addFunctionCaseWithPrograms(pipelineLayoutLifetimeTests.get(), "graphics", checkSupport, createPipelineLayoutLifetimeGraphicsSource, pipelineLayoutLifetimeGraphicsTest); addFunctionCaseWithPrograms(pipelineLayoutLifetimeTests.get(), "compute", checkSupport, createPipelineLayoutLifetimeComputeSource, pipelineLayoutLifetimeComputeTest); addFunctionCaseWithPrograms(pipelineLayoutLifetimeTests.get(), "destroy_after_end", destroyEarlyComputeSource, destroyAfterEndCommndBufferTest); addFunctionCaseWithPrograms(pipelineLayoutLifetimeTests.get(), "destroy_after_compute_pipeline_construction", checkMaintenance4Support, destroyEarlyComputeSource, destroyAfterCreateComputePipelineTest); addFunctionCaseWithPrograms(pipelineLayoutLifetimeTests.get(), "destroy_after_graphics_pipeline_construction", checkMaintenance4Support, createDrawTriangleSource, destroyAfterCreateGraphicsPipelineTest); return pipelineLayoutLifetimeTests.release(); } tcu::TestCaseGroup* createPipelineLayoutTests (tcu::TestContext& testCtx) { de::MovePtr pipelineLayoutTests(new tcu::TestCaseGroup(testCtx, "pipeline_layout")); pipelineLayoutTests->addChild(createPipelineLayoutLifetimeTests(testCtx)); return pipelineLayoutTests.release(); } #ifndef CTS_USES_VULKANSC tcu::TestCaseGroup* createPipelineInvalidPointersUnusedStructsTests (tcu::TestContext& testCtx) { de::MovePtr pipelineInvalidPointersUnusedStructsTests(new tcu::TestCaseGroup(testCtx, "pipeline_invalid_pointers_unused_structs")); addFunctionCaseWithPrograms(pipelineInvalidPointersUnusedStructsTests.get(), "graphics", checkSupport, createPipelineInvalidPointersUnusedStructsGraphicsSource, pipelineInvalidPointersUnusedStructsGraphicsTest); addFunctionCaseWithPrograms(pipelineInvalidPointersUnusedStructsTests.get(), "compute", checkSupport, createPipelineInvalidPointersUnusedStructsComputeSource, pipelineInvalidPointersUnusedStructsComputeTest); return pipelineInvalidPointersUnusedStructsTests.release(); } #endif // CTS_USES_VULKANSC } // anonymous tcu::TestCaseGroup* createPipelineTests (tcu::TestContext& testCtx) { de::MovePtr pipelineTests(new tcu::TestCaseGroup(testCtx, "pipeline")); pipelineTests->addChild(createrenderpassTests(testCtx)); pipelineTests->addChild(createPipelineLayoutTests(testCtx)); #ifndef CTS_USES_VULKANSC pipelineTests->addChild(createPipelineInvalidPointersUnusedStructsTests(testCtx)); #endif // CTS_USES_VULKANSC return pipelineTests.release(); } } // api } // vkt