--- /dev/null
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 ARM Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice(s) and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * The Materials are Confidential Information as defined by the
+ * Khronos Membership Agreement until designated non-confidential by Khronos,
+ * at which point this condition clause shall be removed.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*!
+ * \file
+ * \brief Pipeline Cache Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktPipelineCacheTests.hpp"
+#include "vktPipelineClearUtil.hpp"
+#include "vktPipelineImageUtil.hpp"
+#include "vktPipelineVertexUtil.hpp"
+#include "vktTestCase.hpp"
+#include "vktTestCaseUtil.hpp"
+#include "vkImageUtil.hpp"
+#include "vkMemUtil.hpp"
+#include "vkPrograms.hpp"
+#include "vkBuilderUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkRef.hpp"
+#include "vkRefUtil.hpp"
+#include "tcuImageCompare.hpp"
+#include "deUniquePtr.hpp"
+#include "deMemory.h"
+#include "vkTypeUtil.hpp"
+
+#include <sstream>
+#include <vector>
+
+namespace vkt
+{
+namespace pipeline
+{
+
+using namespace vk;
+
+namespace
+{
+enum
+{
+ VK_MAX_SHADER_STAGES = 6,
+};
+
+// helper functions
+
+std::string getShaderFlagStr (const VkShaderStageFlagBits shader,
+ bool isDescription)
+{
+ std::ostringstream desc;
+ switch(shader)
+ {
+ case VK_SHADER_STAGE_VERTEX_BIT:
+ {
+ desc << ((isDescription) ? "vertex stage" : "vertex_stage");
+ break;
+ }
+ case VK_SHADER_STAGE_FRAGMENT_BIT:
+ {
+ desc << ((isDescription) ? "fragment stage" : "fragment_stage");
+ break;
+ }
+ case VK_SHADER_STAGE_GEOMETRY_BIT:
+ {
+ desc << ((isDescription) ? "geometry stage" : "geometry_stage");
+ break;
+ }
+ case VK_SHADER_STAGE_COMPUTE_BIT:
+ {
+ desc << ((isDescription) ? "compute stage" : "compute_stage");
+ break;
+ }
+ case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
+ {
+ desc << ((isDescription) ? "tessellation control stage" : "tessellation_control_stage");
+ break;
+ }
+ case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
+ {
+ desc << ((isDescription) ? "tessellation evaluation stage" : "tessellation_evaluation_stage");
+ break;
+ }
+ default:
+ desc << "unknown shader stage!";
+ DE_ASSERT(!"Unknown shader Stage!");
+ break;
+ };
+
+ return desc.str();
+}
+
+// helper classes
+class CacheTestParam
+{
+public:
+ CacheTestParam (const VkShaderStageFlagBits* shaders,
+ deUint32 count);
+ virtual ~CacheTestParam (void);
+ virtual const std::string generateTestName (void) const;
+ virtual const std::string generateTestDescription (void) const;
+ VkShaderStageFlagBits getShaderFlag (deUint32 ndx) const { return m_shaders[ndx]; }
+ deUint32 getShaderCount (void) const { return (deUint32)m_shaderCount; }
+protected:
+ VkShaderStageFlagBits m_shaders[VK_MAX_SHADER_STAGES];
+ size_t m_shaderCount;
+};
+
+CacheTestParam::CacheTestParam (const VkShaderStageFlagBits* shaders, deUint32 count)
+{
+ DE_ASSERT(count <= VK_MAX_SHADER_STAGES);
+ for (deUint32 ndx = 0; ndx < count; ndx++)
+ m_shaders[ndx] = shaders[ndx];
+ m_shaderCount = count;
+}
+
+CacheTestParam::~CacheTestParam (void)
+{
+}
+
+const std::string CacheTestParam::generateTestName (void) const
+{
+ std::string result(getShaderFlagStr(m_shaders[0], false));
+
+ for(deUint32 ndx = 1; ndx < m_shaderCount; ndx++)
+ result += '_' + getShaderFlagStr(m_shaders[ndx], false) ;
+
+ return result;
+}
+
+const std::string CacheTestParam::generateTestDescription (void) const
+{
+ std::string result("Create pipeline cache with " + getShaderFlagStr(m_shaders[0], true));
+
+ for(deUint32 ndx = 1; ndx < m_shaderCount; ndx++)
+ result += ' ' + getShaderFlagStr(m_shaders[ndx], true);
+
+ return result;
+}
+
+class SimpleGraphicsPipelineBuilder
+{
+public:
+ SimpleGraphicsPipelineBuilder (Context& context);
+ ~SimpleGraphicsPipelineBuilder (void) { }
+ void bindShaderStage (VkShaderStageFlagBits stage,
+ const char* sourceName,
+ const char* entryName);
+ void enableTessellationStage (deUint32 patchControlPoints);
+ Move<VkPipeline> buildPipeline (tcu::UVec2 renderSize,
+ VkRenderPass renderPass,
+ VkPipelineCache cache);
+protected:
+ Context& m_context;
+
+ Move<VkShaderModule> m_shaderModules[VK_MAX_SHADER_STAGES];
+ deUint32 m_shaderStageCount;
+ VkPipelineShaderStageCreateInfo m_shaderStageInfo[VK_MAX_SHADER_STAGES];
+
+ deUint32 m_patchControlPoints;
+
+ Move<VkPipelineLayout> m_pipelineLayout;
+ Move<VkPipeline> m_graphicsPipelines;
+
+};
+
+SimpleGraphicsPipelineBuilder::SimpleGraphicsPipelineBuilder (Context& context)
+ : m_context(context)
+{
+ m_patchControlPoints = 0;
+ m_shaderStageCount = 0;
+}
+
+void SimpleGraphicsPipelineBuilder::bindShaderStage (VkShaderStageFlagBits stage,
+ const char* sourceName,
+ const char* entryName)
+{
+ const DeviceInterface& vk = m_context.getDeviceInterface();
+ const VkDevice vkDevice = m_context.getDevice();
+
+ // Create shader module
+ deUint32* code = (deUint32*)m_context.getBinaryCollection().get(sourceName).getBinary();
+ deUint32 codeSize = (deUint32)m_context.getBinaryCollection().get(sourceName).getSize();
+
+ const VkShaderModuleCreateInfo moduleCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkShaderModuleCreateFlags flags;
+ codeSize, // deUintptr codeSize;
+ code, // const deUint32* pCode;
+ };
+
+ m_shaderModules[m_shaderStageCount] = createShaderModule(vk, vkDevice, &moduleCreateInfo);
+
+ // Prepare shader stage info
+ m_shaderStageInfo[m_shaderStageCount].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+ m_shaderStageInfo[m_shaderStageCount].pNext = DE_NULL;
+ m_shaderStageInfo[m_shaderStageCount].flags = 0u;
+ m_shaderStageInfo[m_shaderStageCount].stage = stage;
+ m_shaderStageInfo[m_shaderStageCount].module = *m_shaderModules[m_shaderStageCount];
+ m_shaderStageInfo[m_shaderStageCount].pName = entryName;
+ m_shaderStageInfo[m_shaderStageCount].pSpecializationInfo = DE_NULL;
+
+ m_shaderStageCount++;
+}
+
+Move<VkPipeline> SimpleGraphicsPipelineBuilder::buildPipeline (tcu::UVec2 renderSize, VkRenderPass renderPass, VkPipelineCache cache)
+{
+ const DeviceInterface& vk = m_context.getDeviceInterface();
+ const VkDevice vkDevice = m_context.getDevice();
+
+ // Create pipeline layout
+ {
+ const VkPipelineLayoutCreateInfo pipelineLayoutParams =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkPipelineLayoutCreateFlags flags;
+ 0u, // deUint32 setLayoutCount;
+ DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
+ 0u, // deUint32 pushConstantRangeCount;
+ DE_NULL // const VkPushConstantRange* pPushConstantRanges;
+ };
+
+ m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
+ }
+
+ // Create pipeline
+ const VkVertexInputBindingDescription vertexInputBindingDescription =
+ {
+ 0u, // deUint32 binding;
+ sizeof(Vertex4RGBA), // deUint32 strideInBytes;
+ VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
+ };
+
+ const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
+ {
+ {
+ 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 offsetInBytes;
+ }
+ };
+
+ const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkPipelineVertexInputStateCreateFlags flags;
+ 1u, // deUint32 vertexBindingDescriptionCount;
+ &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
+ 2u, // deUint32 vertexAttributeDescriptionCount;
+ vertexInputAttributeDescriptions, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
+ };
+
+ const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkPipelineInputAssemblyStateCreateFlags flags;
+ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology;
+ VK_FALSE, // VkBool32 primitiveRestartEnable;
+ };
+
+ const VkViewport viewport =
+ {
+ 0.0f, // float originX;
+ 0.0f, // float originY;
+ (float)renderSize.x(), // float width;
+ (float)renderSize.y(), // float height;
+ 0.0f, // float minDepth;
+ 1.0f // float maxDepth;
+ };
+ const VkRect2D scissor =
+ {
+ { 0, 0 }, // VkOffset2D offset;
+ { renderSize.x(), renderSize.y() } // VkExtent2D extent;
+ };
+ const VkPipelineViewportStateCreateInfo viewportStateParams =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkPipelineViewportStateCreateFlags flags;
+ 1u, // deUint32 viewportCount;
+ &viewport, // const VkViewport* pViewports;
+ 1u, // deUint32 scissorCount;
+ &scissor // const VkRect2D* pScissors;
+ };
+
+ const VkPipelineRasterizationStateCreateInfo rasterStateParams =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 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_COUNTER_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_ONE, // VkBlendFactor srcColorBlendFactor;
+ VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
+ VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
+ VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
+ VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
+ VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
+ VK_COLOR_COMPONENT_R_BIT |
+ VK_COLOR_COMPONENT_G_BIT |
+ VK_COLOR_COMPONENT_B_BIT |
+ VK_COLOR_COMPONENT_A_BIT // VkColorComponentFlags colorWriteMask;
+ };
+
+ const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkPipelineColorBlendStateCreateFlags flags;
+ VK_FALSE, // VkBool32 logicOpEnable;
+ VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
+ 1u, // deUint32 attachmentCount;
+ &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
+ { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4];
+ };
+
+ const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // 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 VkPipelineDynamicStateCreateInfo dynamicStateParams =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkPipelineDynamicStateCreateFlags flags;
+ 0u, // deUint32 dynamicStateCount;
+ DE_NULL, // const VkDynamicState* pDynamicStates;
+ };
+
+ VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkPipelineDepthStencilStateCreateFlags flags;
+ VK_TRUE, // VkBool32 depthTestEnable;
+ VK_TRUE, // VkBool32 depthWriteEnable;
+ VK_COMPARE_OP_LESS_OR_EQUAL, // VkCompareOp depthCompareOp;
+ VK_FALSE, // VkBool32 depthBoundsTestEnable;
+ VK_FALSE, // VkBool32 stencilTestEnable;
+ // VkStencilOpState front;
+ {
+ VK_STENCIL_OP_KEEP, // VkStencilOp failOp;
+ VK_STENCIL_OP_KEEP, // VkStencilOp passOp;
+ VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp;
+ VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
+ 0u, // deUint32 compareMask;
+ 0u, // deUint32 writeMask;
+ 0u, // deUint32 reference;
+ },
+ // VkStencilOpState back;
+ {
+ VK_STENCIL_OP_KEEP, // VkStencilOp failOp;
+ VK_STENCIL_OP_KEEP, // VkStencilOp passOp;
+ VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp;
+ VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
+ 0u, // deUint32 compareMask;
+ 0u, // deUint32 writeMask;
+ 0u, // deUint32 reference;
+ },
+ -1.0f, // float minDepthBounds;
+ +1.0f, // float maxDepthBounds;
+ };
+
+ const VkPipelineTessellationStateCreateInfo* pTessCreateInfo = DE_NULL;
+ if (m_patchControlPoints > 0)
+ {
+ const VkPipelineTessellationStateCreateInfo tessStateCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkPipelineTesselationStateCreateFlags flags;
+ m_patchControlPoints, // deUint32 patchControlPoints;
+ };
+
+ pTessCreateInfo = &tessStateCreateInfo;
+ }
+
+ const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
+ {
+ VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkPipelineCreateFlags flags;
+ m_shaderStageCount, // deUint32 stageCount;
+ m_shaderStageInfo, // const VkPipelineShaderStageCreateInfo* pStages;
+ &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
+ &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
+ pTessCreateInfo, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
+ &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
+ &rasterStateParams, // const VkPipelineRasterizationStateCreateInfo* pRasterState;
+ &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
+ &depthStencilStateParams, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
+ &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
+ &dynamicStateParams, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
+ *m_pipelineLayout, // VkPipelineLayout layout;
+ renderPass, // VkRenderPass renderPass;
+ 0u, // deUint32 subpass;
+ 0u, // VkPipeline basePipelineHandle;
+ 0, // deInt32 basePipelineIndex;
+ };
+
+ return createGraphicsPipeline(vk, vkDevice, cache, &graphicsPipelineParams);
+}
+
+void SimpleGraphicsPipelineBuilder::enableTessellationStage (deUint32 patchControlPoints)
+{
+ m_patchControlPoints = patchControlPoints;
+}
+
+template <class Test>
+vkt::TestCase* newTestCase (tcu::TestContext& testContext,
+ const CacheTestParam* testParam)
+{
+ return new Test(testContext,
+ testParam->generateTestName().c_str(),
+ testParam->generateTestDescription().c_str(),
+ testParam);
+}
+
+Move<VkBuffer> createBufferAndBindMemory (Context& context, VkDeviceSize size, VkBufferUsageFlags usage, de::MovePtr<Allocation>* pAlloc)
+{
+ const DeviceInterface& vk = context.getDeviceInterface();
+ const VkDevice vkDevice = context.getDevice();
+ const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
+ SimpleAllocator* memAlloc = new SimpleAllocator(vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
+
+ const VkBufferCreateInfo vertexBufferParams =
+ {
+ VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkBufferCreateFlags flags;
+ size, // VkDeviceSize size;
+ usage, // VkBufferUsageFlags usage;
+ VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
+ 1u, // deUint32 queueFamilyCount;
+ &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
+ };
+
+ Move<VkBuffer> vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
+
+ DE_ASSERT(pAlloc);
+ *pAlloc = memAlloc->allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
+ VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, (*pAlloc)->getMemory(), (*pAlloc)->getOffset()));
+
+ return vertexBuffer;
+}
+
+Move<VkImage> createImage2DAndBindMemory (Context& context,
+ VkFormat format,
+ deUint32 width,
+ deUint32 height,
+ VkImageUsageFlags usage,
+ VkSampleCountFlagBits sampleCount,
+ de::details::MovePtr<Allocation>* pAlloc)
+{
+ const DeviceInterface& vk = context.getDeviceInterface();
+ const VkDevice vkDevice = context.getDevice();
+ const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
+ SimpleAllocator* memAlloc = new SimpleAllocator(vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
+
+ 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;
+ format, // VkFormat format;
+ { width, height, 1u }, // VkExtent3D extent;
+ 1u, // deUint32 mipLevels;
+ 1u, // deUint32 arraySize;
+ sampleCount, // deUint32 samples;
+ VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
+ usage, // VkImageUsageFlags usage;
+ VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
+ 1u, // deUint32 queueFamilyCount;
+ &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
+ VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
+ };
+
+ Move<VkImage> image = createImage(vk, vkDevice, &colorImageParams);
+
+ DE_ASSERT(pAlloc);
+ *pAlloc = memAlloc->allocate(getImageMemoryRequirements(vk, vkDevice, *image), MemoryRequirement::Any);
+ VK_CHECK(vk.bindImageMemory(vkDevice, *image, (*pAlloc)->getMemory(), (*pAlloc)->getOffset()));
+
+ return image;
+}
+
+// Test Classes
+class CacheTest : public vkt::TestCase
+{
+public:
+ CacheTest(tcu::TestContext& testContext,
+ const std::string& name,
+ const std::string& description,
+ const CacheTestParam* param)
+ : vkt::TestCase (testContext, name, description)
+ , m_param (*param)
+ { }
+ virtual ~CacheTest (void) { }
+protected:
+ const CacheTestParam m_param;
+};
+
+class CacheTestInstance : public vkt::TestInstance
+{
+public:
+ enum
+ {
+ PIPELINE_CACHE_NDX_NO_CACHE,
+ PIPELINE_CACHE_NDX_CACHED,
+ PIPELINE_CACHE_NDX_COUNT,
+ };
+ CacheTestInstance (Context& context,
+ const CacheTestParam* param);
+ virtual ~CacheTestInstance (void);
+ virtual tcu::TestStatus iterate (void);
+protected:
+ virtual tcu::TestStatus verifyTestResult (void) = 0;
+ virtual void prepareCommandBuffer (void) = 0;
+protected:
+ const CacheTestParam* m_param;
+
+ Move<VkCommandPool> m_cmdPool;
+ Move<VkCommandBuffer> m_cmdBuffer;
+ Move<VkFence> m_fence;
+ Move<VkPipelineCache> m_cache;
+};
+
+CacheTestInstance::CacheTestInstance (Context& context,
+ const CacheTestParam* param)
+ : TestInstance (context)
+ , m_param (param)
+{
+ const DeviceInterface& vk = m_context.getDeviceInterface();
+ const VkDevice vkDevice = m_context.getDevice();
+ const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
+
+ // Create command pool
+ {
+ const VkCommandPoolCreateInfo cmdPoolParams =
+ {
+ VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
+ queueFamilyIndex, // deUint32 queueFamilyIndex;
+ };
+
+ m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
+ }
+
+ // Create command buffer
+ {
+ const VkCommandBufferAllocateInfo cmdAllocateParams =
+ {
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ *m_cmdPool, // VkCommandPool cmdPool;
+ VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
+ 1u, // deUint32 bufferCount;
+ };
+
+ m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdAllocateParams);
+ }
+
+ // Create fence
+ {
+ const VkFenceCreateInfo fenceParams =
+ {
+ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkFenceCreateFlags flags;
+ };
+
+ m_fence = createFence(vk, vkDevice, &fenceParams);
+ }
+
+ // Create the Pipeline Cache
+ {
+ const VkPipelineCacheCreateInfo pipelineCacheCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkPipelineCacheCreateFlags flags;
+ 0u, // deUintptr initialDataSize;
+ DE_NULL, // const void* pInitialData;
+ };
+
+ m_cache = createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo);
+ }
+}
+
+CacheTestInstance::~CacheTestInstance (void)
+{
+}
+
+tcu::TestStatus CacheTestInstance::iterate (void)
+{
+ const DeviceInterface& vk = m_context.getDeviceInterface();
+ const VkDevice vkDevice = m_context.getDevice();
+ const VkQueue queue = m_context.getUniversalQueue();
+
+ prepareCommandBuffer();
+
+ VK_CHECK(vk.resetFences(vkDevice, 1u, &m_fence.get()));
+
+ const VkSubmitInfo submitInfo =
+ {
+ VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // deUint32 waitSemaphoreCount;
+ DE_NULL, // const VkSemaphore* pWaitSemaphores;
+ (const VkPipelineStageFlags*)DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask;
+ 1u, // deUint32 commandBufferCount;
+ &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
+ 0u, // deUint32 signalSemaphoreCount;
+ DE_NULL, // const VkSemaphore* pSignalSemaphores;
+ };
+ VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *m_fence));
+
+ VK_CHECK(vk.waitForFences(vkDevice, 1u, &m_fence.get(), true, ~(0ull) /* infinity*/));
+
+ return verifyTestResult();
+}
+
+class GraphicsCacheTest : public CacheTest
+{
+public:
+ GraphicsCacheTest (tcu::TestContext& testContext,
+ const std::string& name,
+ const std::string& description,
+ const CacheTestParam* param)
+ : CacheTest (testContext, name, description, param)
+ { }
+ virtual ~GraphicsCacheTest (void) { }
+ virtual void initPrograms (SourceCollections& programCollection) const;
+ virtual TestInstance* createInstance (Context& context) const;
+};
+
+class GraphicsCacheTestInstance : public CacheTestInstance
+{
+public:
+ GraphicsCacheTestInstance (Context& context,
+ const CacheTestParam* param);
+ virtual ~GraphicsCacheTestInstance (void);
+protected:
+ void prepareRenderPass (VkFramebuffer framebuffer, VkPipeline pipeline);
+ virtual void prepareCommandBuffer (void);
+ virtual tcu::TestStatus verifyTestResult (void);
+
+protected:
+ const tcu::UVec2 m_renderSize;
+ const VkFormat m_colorFormat;
+ const VkFormat m_depthFormat;
+
+ Move<VkImage> m_depthImage;
+ de::MovePtr<Allocation> m_depthImageAlloc;
+ de::MovePtr<Allocation> m_colorImageAlloc;
+ Move<VkImageView> m_depthAttachmentView;
+
+ Move<VkBuffer> m_vertexBuffer;
+ std::vector<Vertex4RGBA> m_vertices;
+
+ SimpleGraphicsPipelineBuilder m_pipelineBuilder;
+ Move<VkRenderPass> m_renderPass;
+
+ Move<VkImage> m_colorImage[PIPELINE_CACHE_NDX_COUNT];
+ Move<VkImageView> m_colorAttachmentView[PIPELINE_CACHE_NDX_COUNT];
+ Move<VkFramebuffer> m_framebuffer[PIPELINE_CACHE_NDX_COUNT];
+ Move<VkPipeline> m_pipeline[PIPELINE_CACHE_NDX_COUNT];
+};
+
+void GraphicsCacheTest::initPrograms (SourceCollections& programCollection) const
+{
+ for (deUint32 shaderNdx = 0; shaderNdx < m_param.getShaderCount(); shaderNdx++)
+ {
+ switch(m_param.getShaderFlag(shaderNdx))
+ {
+ case VK_SHADER_STAGE_VERTEX_BIT:
+ programCollection.glslSources.add("color_vert") << glu::VertexSource(
+ "#version 310 es\n"
+ "layout(location = 0) in vec4 position;\n"
+ "layout(location = 1) in vec4 color;\n"
+ "layout(location = 0) out highp vec4 vtxColor;\n"
+ "void main (void)\n"
+ "{\n"
+ " gl_Position = position;\n"
+ " vtxColor = color;\n"
+ "}\n");
+ break;
+
+ case VK_SHADER_STAGE_FRAGMENT_BIT:
+ programCollection.glslSources.add("color_frag") << glu::FragmentSource(
+ "#version 310 es\n"
+ "layout(location = 0) in highp vec4 vtxColor;\n"
+ "layout(location = 0) out highp vec4 fragColor;\n"
+ "void main (void)\n"
+ "{\n"
+ " fragColor = vtxColor;\n"
+ "}\n");
+ break;
+
+ case VK_SHADER_STAGE_GEOMETRY_BIT:
+ programCollection.glslSources.add("dummy_geo") << glu::GeometrySource(
+ "#version 450 \n"
+ "layout (triangles) in;\n"
+ "layout (triangle_strip, max_vertices = 3) out;\n"
+ "void main (void)\n"
+ "{\n"
+ " for(int ndx=0; ndx<3; ndx++)\n"
+ " {\n"
+ " gl_Position = gl_in[ndx].gl_Position;\n"
+ " EmitVertex();\n"
+ " }\n"
+ " EndPrimitive();\n"
+ "}\n");
+ break;
+
+ case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
+ programCollection.glslSources.add("basic_tcs") << glu::TessellationControlSource(
+ "#version 450 \n"
+ "layout(vertices = 3) out;\n"
+ "in highp vec4 color[];\n"
+ "out highp vec4 vtxColor[];\n"
+ "void main()\n"
+ "{\n"
+ " gl_TessLevelOuter[0] = 4.0;\n"
+ " gl_TessLevelOuter[1] = 4.0;\n"
+ " gl_TessLevelOuter[2] = 4.0;\n"
+ " gl_TessLevelInner[0] = 4.0;\n"
+ " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
+ " vtxColor[gl_InvocationID] = color[gl_InvocationID];\n"
+ "}\n");
+ break;
+
+ case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
+ programCollection.glslSources.add("basic_tes") << glu::TessellationEvaluationSource(
+ "#version 450 \n"
+ "layout(triangles, fractional_even_spacing, ccw) in;\n"
+ "in highp vec4 colors[];\n"
+ "out highp vec4 vtxColor;\n"
+ "void main() \n"
+ "{\n"
+ " float u = gl_TessCoord.x;\n"
+ " float v = gl_TessCoord.y;\n"
+ " float w = gl_TessCoord.z;\n"
+ " vec4 pos = vec4(0);\n"
+ " vec4 color = vec4(0);\n"
+ " pos.xyz += u * gl_in[0].gl_Position.xyz;\n"
+ " color.xyz += u * colors[0].xyz;\n"
+ " pos.xyz += v * gl_in[1].gl_Position.xyz;\n"
+ " color.xyz += v * colors[1].xyz;\n"
+ " pos.xyz += w * gl_in[2].gl_Position.xyz;\n"
+ " color.xyz += w * colors[2].xyz;\n"
+ " pos.w = 1.0;\n"
+ " color.w = 1.0;\n"
+ " gl_Position = pos;\n"
+ " vtxColor = color;\n"
+ "}\n");
+ break;
+
+ default:
+ DE_ASSERT(!"Unknown Shader Stage!");
+ break;
+ };
+ }
+}
+
+TestInstance* GraphicsCacheTest::createInstance (Context& context) const
+{
+ return new GraphicsCacheTestInstance(context, &m_param);
+}
+
+GraphicsCacheTestInstance::GraphicsCacheTestInstance (Context& context,
+ const CacheTestParam* param)
+ : CacheTestInstance (context,param)
+ , m_renderSize (32u, 32u)
+ , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
+ , m_depthFormat (VK_FORMAT_D24_UNORM_S8_UINT)
+ , m_pipelineBuilder (context)
+{
+ const DeviceInterface& vk = m_context.getDeviceInterface();
+ const VkDevice vkDevice = m_context.getDevice();
+
+ // Create vertex buffer
+ {
+ de::MovePtr<Allocation> bufferAlloc;
+ m_vertexBuffer = createBufferAndBindMemory(m_context, 1024u, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, &bufferAlloc);
+
+ m_vertices = createOverlappingQuads();
+ // Load vertices into vertex buffer
+ deMemcpy(bufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
+ flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), 1024u);
+ }
+
+ // Create render pass
+ {
+ const VkAttachmentDescription colorAttachmentDescription =
+ {
+ 0u, // VkAttachmentDescriptionFlags flags;
+ m_colorFormat, // 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 VkAttachmentDescription depthAttachmentDescription =
+ {
+ 0u, // VkAttachmentDescriptionFlags flags;
+ m_depthFormat, // VkFormat format;
+ VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
+ VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
+ VK_ATTACHMENT_STORE_OP_DONT_CARE, // 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_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
+ };
+
+ const VkAttachmentDescription attachments[2] =
+ {
+ colorAttachmentDescription,
+ depthAttachmentDescription
+ };
+
+ const VkAttachmentReference colorAttachmentReference =
+ {
+ 0u, // deUint32 attachment;
+ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
+ };
+
+ const VkAttachmentReference depthAttachmentReference =
+ {
+ 1u, // deUint32 attachment;
+ VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout layout;
+ };
+
+ const VkSubpassDescription subpassDescription =
+ {
+ 0u, // VkSubpassDescriptionFlags flags;
+ VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
+ 0u, // deUint32 inputAttachmentCount;
+ DE_NULL, // const VkAttachmentReference* pInputAttachments;
+ 1u, // deUint32 colorAttachmentCount;
+ &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
+ DE_NULL, // const VkAttachmentReference* pResolveAttachments;
+ &depthAttachmentReference, // const VkAttachmentReference* pDepthStencilAttachment;
+ 0u, // deUint32 preserveAttachmentCount;
+ DE_NULL // const VkAttachmentReference* pPreserveAttachments;
+ };
+
+ const VkRenderPassCreateInfo renderPassParams =
+ {
+ VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkRenderPassCreateFlags flags;
+ 2u, // deUint32 attachmentCount;
+ attachments, // const VkAttachmentDescription* pAttachments;
+ 1u, // deUint32 subpassCount;
+ &subpassDescription, // const VkSubpassDescription* pSubpasses;
+ 0u, // deUint32 dependencyCount;
+ DE_NULL // const VkSubpassDependency* pDependencies;
+ };
+
+ m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
+ }
+
+ const VkComponentMapping ComponentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
+ // Create color image
+ {
+ m_colorImage[PIPELINE_CACHE_NDX_NO_CACHE] = createImage2DAndBindMemory(m_context,
+ m_colorFormat,
+ m_renderSize.x(),
+ m_renderSize.y(),
+ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
+ VK_SAMPLE_COUNT_1_BIT,
+ &m_colorImageAlloc);
+ m_colorImage[PIPELINE_CACHE_NDX_CACHED] = createImage2DAndBindMemory(m_context,
+ m_colorFormat,
+ m_renderSize.x(),
+ m_renderSize.y(),
+ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
+ VK_SAMPLE_COUNT_1_BIT,
+ &m_colorImageAlloc);
+ }
+
+ // Create depth image
+ {
+ m_depthImage = createImage2DAndBindMemory(m_context,
+ m_depthFormat,
+ m_renderSize.x(),
+ m_renderSize.y(),
+ VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
+ VK_SAMPLE_COUNT_1_BIT,
+ &m_depthImageAlloc);
+ }
+
+ // Create color attachment view
+ {
+ VkImageViewCreateInfo colorAttachmentViewParams =
+ {
+ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkImageViewCreateFlags flags;
+ *m_colorImage[PIPELINE_CACHE_NDX_NO_CACHE], // VkImage image;
+ VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
+ m_colorFormat, // VkFormat format;
+ ComponentMappingRGBA, // VkComponentMapping components;
+ { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
+ };
+
+ m_colorAttachmentView[PIPELINE_CACHE_NDX_NO_CACHE] = createImageView(vk, vkDevice, &colorAttachmentViewParams);
+
+ colorAttachmentViewParams.image = *m_colorImage[PIPELINE_CACHE_NDX_CACHED];
+ m_colorAttachmentView[PIPELINE_CACHE_NDX_CACHED] = createImageView(vk, vkDevice, &colorAttachmentViewParams);
+ }
+
+ // Create depth attachment view
+ {
+ const VkImageViewCreateInfo depthAttachmentViewParams =
+ {
+ VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkImageViewCreateFlags flags;
+ *m_depthImage, // VkImage image;
+ VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
+ m_depthFormat, // VkFormat format;
+ ComponentMappingRGBA, // VkComponentMapping components;
+ { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
+ };
+
+ m_depthAttachmentView = createImageView(vk, vkDevice, &depthAttachmentViewParams);
+ }
+
+ // Create framebuffer
+ {
+ VkImageView attachmentBindInfos[2] =
+ {
+ *m_colorAttachmentView[PIPELINE_CACHE_NDX_NO_CACHE],
+ *m_depthAttachmentView,
+ };
+
+ const VkFramebufferCreateInfo framebufferParams =
+ {
+ VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkFramebufferCreateFlags flags;
+ *m_renderPass, // 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_framebuffer[PIPELINE_CACHE_NDX_NO_CACHE] = createFramebuffer(vk, vkDevice, &framebufferParams);
+
+ attachmentBindInfos[0] = *m_colorAttachmentView[PIPELINE_CACHE_NDX_CACHED];
+ m_framebuffer[PIPELINE_CACHE_NDX_CACHED] = createFramebuffer(vk, vkDevice, &framebufferParams);
+ }
+
+ // Bind shader stages
+ VkPhysicalDeviceFeatures features = m_context.getDeviceFeatures();
+ for (deUint32 shaderNdx = 0; shaderNdx < m_param->getShaderCount(); shaderNdx++)
+ {
+ switch(m_param->getShaderFlag(shaderNdx))
+ {
+ case VK_SHADER_STAGE_VERTEX_BIT:
+ m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_VERTEX_BIT, "color_vert", "main");
+ break;
+ case VK_SHADER_STAGE_FRAGMENT_BIT:
+ m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_FRAGMENT_BIT, "color_frag", "main");
+ break;
+ case VK_SHADER_STAGE_GEOMETRY_BIT:
+ if (features.geometryShader == VK_FALSE)
+ {
+ TCU_THROW(NotSupportedError, "Geometry Shader Not Supported");
+ }
+ else
+ {
+ m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_GEOMETRY_BIT, "dummy_geo", "main");
+ }
+ break;
+ case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
+ if (features.tessellationShader == VK_FALSE)
+ {
+ TCU_THROW(NotSupportedError, "Tessellation Not Supported");
+ }
+ else
+ {
+ m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "basic_tcs", "main");
+ }
+ break;
+ case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
+ if (features.tessellationShader == VK_FALSE)
+ {
+ TCU_THROW(NotSupportedError, "Tessellation Not Supported");
+ }
+ else
+ {
+ m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "basic_tes", "main");
+ }
+ break;
+ default:
+ DE_ASSERT(!"Unknown Shader Stage!");
+ break;
+ };
+ }
+
+ m_pipeline[PIPELINE_CACHE_NDX_NO_CACHE] = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass, *m_cache);
+ m_pipeline[PIPELINE_CACHE_NDX_CACHED] = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass, *m_cache);
+}
+
+GraphicsCacheTestInstance::~GraphicsCacheTestInstance (void)
+{
+}
+
+void GraphicsCacheTestInstance::prepareRenderPass (VkFramebuffer framebuffer, VkPipeline pipeline)
+{
+ const DeviceInterface& vk = m_context.getDeviceInterface();
+
+ const VkClearValue attachmentClearValues[2] =
+ {
+ defaultClearValue(m_colorFormat),
+ defaultClearValue(m_depthFormat),
+ };
+
+ const VkRenderPassBeginInfo renderPassBeginInfo =
+ {
+ VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ *m_renderPass, // VkRenderPass renderPass;
+ framebuffer, // VkFramebuffer framebuffer;
+ { { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } }, // VkRect2D renderArea;
+ 2u, // deUint32 clearValueCount;
+ attachmentClearValues // const VkClearValue* pClearValues;
+ };
+
+ vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
+
+ vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
+ VkDeviceSize offsets = 0u;
+ vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &offsets);
+ vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1u, 0u, 0u);
+
+ vk.cmdEndRenderPass(*m_cmdBuffer);
+}
+
+void GraphicsCacheTestInstance::prepareCommandBuffer (void)
+{
+ const DeviceInterface& vk = m_context.getDeviceInterface();
+
+ const VkCommandBufferBeginInfo cmdBufferBeginInfo =
+ {
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkCommandBufferUsageFlags flags;
+ (const VkCommandBufferInheritanceInfo*)DE_NULL,
+ };
+
+ VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
+
+ prepareRenderPass(*m_framebuffer[PIPELINE_CACHE_NDX_NO_CACHE], *m_pipeline[PIPELINE_CACHE_NDX_NO_CACHE]);
+
+ prepareRenderPass(*m_framebuffer[PIPELINE_CACHE_NDX_CACHED], *m_pipeline[PIPELINE_CACHE_NDX_CACHED]);
+
+ VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
+}
+
+tcu::TestStatus GraphicsCacheTestInstance::verifyTestResult (void)
+{
+ const DeviceInterface& vk = m_context.getDeviceInterface();
+ const VkDevice vkDevice = m_context.getDevice();
+ const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
+ SimpleAllocator* memAlloc = new SimpleAllocator(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
+
+ const VkQueue queue = m_context.getUniversalQueue();
+ de::MovePtr<tcu::TextureLevel> resultNoCache = readColorAttachment(vk,
+ vkDevice,
+ queue,
+ queueFamilyIndex,
+ *memAlloc,
+ *m_colorImage[PIPELINE_CACHE_NDX_NO_CACHE],
+ m_colorFormat,
+ m_renderSize);
+ de::MovePtr<tcu::TextureLevel> resultCache = readColorAttachment(vk,
+ vkDevice,
+ queue,
+ queueFamilyIndex,
+ *memAlloc,
+ *m_colorImage[PIPELINE_CACHE_NDX_CACHED],
+ m_colorFormat,
+ m_renderSize);
+
+ bool compareOk = tcu::intThresholdCompare(m_context.getTestContext().getLog(),
+ "IntImageCompare",
+ "Image comparison",
+ resultNoCache->getAccess(),
+ resultCache->getAccess(),
+ tcu::UVec4(1, 1, 1, 1),
+ tcu::COMPARE_LOG_RESULT);
+
+ if (compareOk)
+ return tcu::TestStatus::pass("Render images w/o cached pipeline match.");
+ else
+ return tcu::TestStatus::fail("Render Images mismatch.");
+}
+
+class ComputeCacheTest : public CacheTest
+{
+public:
+ ComputeCacheTest (tcu::TestContext& testContext,
+ const std::string& name,
+ const std::string& description,
+ const CacheTestParam* param)
+ : CacheTest (testContext, name, description, param)
+ { }
+ virtual ~ComputeCacheTest (void) { }
+ virtual void initPrograms (SourceCollections& programCollection) const;
+ virtual TestInstance* createInstance (Context& context) const;
+};
+
+class ComputeCacheTestInstance : public CacheTestInstance
+{
+public:
+ ComputeCacheTestInstance (Context& context,
+ const CacheTestParam* param);
+ virtual ~ComputeCacheTestInstance (void);
+ virtual void prepareCommandBuffer (void);
+protected:
+ virtual tcu::TestStatus verifyTestResult (void);
+ void buildBuffers (void);
+ void buildDescriptorSets (deUint32 ndx);
+ void buildShader (void);
+ void buildPipeline (deUint32 ndx);
+protected:
+ Move<VkBuffer> m_inputBuf;
+ Move<VkShaderModule> m_computeShaderModule;
+
+ Move<VkBuffer> m_outputBuf[PIPELINE_CACHE_NDX_COUNT];
+ de::MovePtr<Allocation> m_outputBufferAlloc[PIPELINE_CACHE_NDX_COUNT];
+
+ Move<VkDescriptorPool> m_descriptorPool[PIPELINE_CACHE_NDX_COUNT];
+ Move<VkDescriptorSetLayout> m_descriptorSetLayout[PIPELINE_CACHE_NDX_COUNT];
+ Move<VkDescriptorSet> m_descriptorSet[PIPELINE_CACHE_NDX_COUNT];
+
+ Move<VkPipelineLayout> m_pipelineLayout[PIPELINE_CACHE_NDX_COUNT];
+ Move<VkPipeline> m_pipeline[PIPELINE_CACHE_NDX_COUNT];
+};
+
+void ComputeCacheTest::initPrograms (SourceCollections& programCollection) const
+{
+ programCollection.glslSources.add("basic_compute") << glu::ComputeSource(
+ "#version 310 es\n"
+ "layout(local_size_x = 128) in;\n"
+ "layout(std430) buffer;\n"
+ "layout(binding = 0) readonly buffer Input0\n"
+ "{\n"
+ " vec4 elements[];\n"
+ "} input_data0;\n"
+ "layout(binding = 1) writeonly buffer Output\n"
+ "{\n"
+ " vec4 elements[];\n"
+ "} output_data;\n"
+ "void main()\n"
+ "{\n"
+ " uint ident = gl_GlobalInvocationID.x;\n"
+ " output_data.elements[ident] = input_data0.elements[ident] * input_data0.elements[ident];\n"
+ "}");
+}
+
+TestInstance* ComputeCacheTest::createInstance (Context& context) const
+{
+ return new ComputeCacheTestInstance(context, &m_param);
+}
+
+void ComputeCacheTestInstance::buildBuffers (void)
+{
+ const DeviceInterface& vk = m_context.getDeviceInterface();
+ const VkDevice vkDevice = m_context.getDevice();
+
+ // Create buffer object, allocate storage, and generate input data
+ const VkDeviceSize size = sizeof(tcu::Vec4) * 128u;
+ de::MovePtr<Allocation> bufferAlloc;
+ m_inputBuf = createBufferAndBindMemory(m_context, size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, &bufferAlloc);
+
+ // Initialize input buffer
+ tcu::Vec4* pVec = reinterpret_cast<tcu::Vec4*>(bufferAlloc->getHostPtr());
+ for (deUint32 ndx = 0u; ndx < 128u; ndx++)
+ {
+ for (deUint32 component = 0u; component < 4u; component++)
+ pVec[ndx][component]= (float)(ndx * (component + 1u));
+ }
+ flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), size);
+
+ // Clear the output buffer
+ for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
+ {
+ m_outputBuf[ndx] = createBufferAndBindMemory(m_context, size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, &m_outputBufferAlloc[ndx]);
+
+ pVec = reinterpret_cast<tcu::Vec4*>(m_outputBufferAlloc[ndx]->getHostPtr());
+ memset(pVec, 0u, size);
+ flushMappedMemoryRange(vk, vkDevice, m_outputBufferAlloc[ndx]->getMemory(), m_outputBufferAlloc[ndx]->getOffset(), size);
+ }
+}
+
+void ComputeCacheTestInstance::buildDescriptorSets (deUint32 ndx)
+{
+ const DeviceInterface& vk = m_context.getDeviceInterface();
+ const VkDevice vkDevice = m_context.getDevice();
+
+ // Create descriptor set layout
+ DescriptorSetLayoutBuilder descLayoutBuilder;
+
+ for (deUint32 bindingNdx = 0u; bindingNdx < 2u; bindingNdx++)
+ descLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
+
+ m_descriptorSetLayout[ndx] = descLayoutBuilder.build(vk, vkDevice);
+
+ std::vector<VkDescriptorBufferInfo> descriptorInfos;
+ descriptorInfos.push_back(makeDescriptorBufferInfo(*m_inputBuf, 0u, sizeof(tcu::Vec4) * 128u));
+ descriptorInfos.push_back(makeDescriptorBufferInfo(*m_outputBuf[ndx], 0u, sizeof(tcu::Vec4) * 128u));
+
+ // Create descriptor pool
+ m_descriptorPool[ndx] = DescriptorPoolBuilder().addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2u).build(vk,
+ vkDevice,
+ VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
+ 1u);
+
+ // Create descriptor set
+ const VkDescriptorSetAllocateInfo descriptorSetAllocInfo =
+ {
+ VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ *m_descriptorPool[ndx], // VkDescriptorPool descriptorPool;
+ 1u, // deUint32 setLayoutCount;
+ &m_descriptorSetLayout[ndx].get(), // const VkDescriptorSetLayout* pSetLayouts;
+ };
+ m_descriptorSet[ndx] = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocInfo);
+
+ DescriptorSetUpdateBuilder builder;
+ for (deUint32 descriptorNdx = 0u; descriptorNdx < 2u; descriptorNdx++)
+ {
+ builder.writeSingle(*m_descriptorSet[ndx],
+ DescriptorSetUpdateBuilder::Location::binding(descriptorNdx),
+ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
+ &descriptorInfos[descriptorNdx]);
+ }
+ builder.update(vk, vkDevice);
+}
+
+void ComputeCacheTestInstance::buildShader (void)
+{
+ const DeviceInterface& vk = m_context.getDeviceInterface();
+ const VkDevice vkDevice = m_context.getDevice();
+
+ // Create compute shader
+ VkShaderModuleCreateInfo shaderModuleCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkShaderModuleCreateFlags flags;
+ m_context.getBinaryCollection().get("basic_compute").getSize(), // deUintptr codeSize;
+ (deUint32*)m_context.getBinaryCollection().get("basic_compute").getBinary(), // const deUint32* pCode;
+ };
+ m_computeShaderModule = createShaderModule(vk, vkDevice, &shaderModuleCreateInfo);
+}
+
+void ComputeCacheTestInstance::buildPipeline (deUint32 ndx)
+{
+ const DeviceInterface& vk = m_context.getDeviceInterface();
+ const VkDevice vkDevice = m_context.getDevice();
+
+ // Create compute pipeline layout
+ const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkPipelineLayoutCreateFlags flags;
+ 1u, // deUint32 setLayoutCount;
+ &m_descriptorSetLayout[ndx].get(), // const VkDescriptorSetLayout* pSetLayouts;
+ 0u, // deUint32 pushConstantRangeCount;
+ DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
+ };
+
+ m_pipelineLayout[ndx] = createPipelineLayout(vk, vkDevice, &pipelineLayoutCreateInfo);
+
+ 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 pipelineCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkPipelineCreateFlags flags;
+ stageCreateInfo, // VkPipelineShaderStageCreateInfo stage;
+ *m_pipelineLayout[ndx], // VkPipelineLayout layout;
+ (VkPipeline)0, // VkPipeline basePipelineHandle;
+ 0u, // deInt32 basePipelineIndex;
+ };
+
+ m_pipeline[ndx] = createComputePipeline(vk, vkDevice, *m_cache, &pipelineCreateInfo);
+}
+
+ComputeCacheTestInstance::ComputeCacheTestInstance (Context& context,
+ const CacheTestParam* param)
+ : CacheTestInstance (context, param)
+{
+ buildBuffers();
+
+ buildDescriptorSets(PIPELINE_CACHE_NDX_NO_CACHE);
+
+ buildDescriptorSets(PIPELINE_CACHE_NDX_CACHED);
+
+ buildShader();
+
+ buildPipeline(PIPELINE_CACHE_NDX_NO_CACHE);
+
+ buildPipeline(PIPELINE_CACHE_NDX_CACHED);
+}
+
+ComputeCacheTestInstance::~ComputeCacheTestInstance (void)
+{
+}
+
+void ComputeCacheTestInstance::prepareCommandBuffer (void)
+{
+ const DeviceInterface& vk = m_context.getDeviceInterface();
+
+ const VkCommandBufferBeginInfo cmdBufferBeginInfo =
+ {
+ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkCommandBufferUsageFlags flags;
+ (const VkCommandBufferInheritanceInfo*)DE_NULL,
+ };
+
+ VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
+
+ for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
+ {
+ vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipeline[ndx]);
+ vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout[ndx], 0u, 1u, &m_descriptorSet[ndx].get(), 0u, DE_NULL);
+ vk.cmdDispatch(*m_cmdBuffer, 128u, 1u, 1u);
+ }
+
+ VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
+}
+
+tcu::TestStatus ComputeCacheTestInstance::verifyTestResult (void)
+{
+ const DeviceInterface& vk = m_context.getDeviceInterface();
+ const VkDevice vkDevice = m_context.getDevice();
+
+ // Read the content of output buffers
+ invalidateMappedMemoryRange(vk,
+ vkDevice,
+ m_outputBufferAlloc[PIPELINE_CACHE_NDX_NO_CACHE]->getMemory(),
+ m_outputBufferAlloc[PIPELINE_CACHE_NDX_NO_CACHE]->getOffset(),
+ sizeof(tcu::Vec4) * 128u);
+
+ invalidateMappedMemoryRange(vk,
+ vkDevice,
+ m_outputBufferAlloc[PIPELINE_CACHE_NDX_CACHED]->getMemory(),
+ m_outputBufferAlloc[PIPELINE_CACHE_NDX_CACHED]->getOffset(),
+ sizeof(tcu::Vec4) * 128u);
+ // Compare the content
+ deUint8* bufNoCache = reinterpret_cast<deUint8*>(m_outputBufferAlloc[PIPELINE_CACHE_NDX_NO_CACHE]->getHostPtr());
+ deUint8* bufCached = reinterpret_cast<deUint8*>(m_outputBufferAlloc[PIPELINE_CACHE_NDX_CACHED]->getHostPtr());
+ for (deUint32 ndx = 0u; ndx < sizeof(tcu::Vec4) * 128u; ndx++)
+ {
+ if (bufNoCache[ndx] != bufCached[ndx])
+ {
+ return tcu::TestStatus::fail("Output buffers w/o cached pipeline mismatch.");
+ }
+ }
+
+ return tcu::TestStatus::pass("Output buffers w/o cached pipeline match.");
+}
+
+class MergeCacheTest : public GraphicsCacheTest
+{
+public:
+ MergeCacheTest (tcu::TestContext& testContext,
+ const std::string& name,
+ const std::string& description,
+ const CacheTestParam* param)
+ : GraphicsCacheTest (testContext, name, description, param)
+ { }
+ virtual ~MergeCacheTest (void) { }
+ virtual TestInstance* createInstance (Context& context) const;
+};
+
+class MergeCacheTestInstance : public GraphicsCacheTestInstance
+{
+public:
+ MergeCacheTestInstance (Context& context,
+ const CacheTestParam* param);
+ virtual ~MergeCacheTestInstance (void);
+protected:
+protected:
+ Move<VkPipelineCache> m_cacheGetData;
+ Move<VkPipelineCache> m_cacheEmpty;
+ Move<VkPipelineCache> m_cacheMerged;
+ deUint8* m_data;
+};
+
+TestInstance* MergeCacheTest::createInstance (Context& context) const
+{
+ return new MergeCacheTestInstance(context, &m_param);
+}
+
+MergeCacheTestInstance::MergeCacheTestInstance (Context& context, const CacheTestParam* param)
+ : GraphicsCacheTestInstance (context, param)
+ , m_data (DE_NULL)
+{
+ const DeviceInterface& vk = m_context.getDeviceInterface();
+ const VkDevice vkDevice = m_context.getDevice();
+
+ // Create more pipeline caches
+ {
+ // Create a empty cache as one of source cache
+ VkPipelineCacheCreateInfo pipelineCacheCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkPipelineCacheCreateFlags flags;
+ 0u, // deUintptr initialDataSize;
+ DE_NULL, // const void* pInitialData;
+ };
+ m_cacheEmpty = createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo);
+
+ // Create a empty cache for merge destination cache
+ m_cacheMerged = createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo);
+
+ // Create a cache with init data from m_cache
+ size_t dataSize = 0u;
+ VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, DE_NULL));
+
+ m_data = new deUint8[dataSize];
+ DE_ASSERT(m_data);
+ VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, (void*)m_data));
+
+ pipelineCacheCreateInfo.initialDataSize = dataSize;
+ pipelineCacheCreateInfo.pInitialData = m_data;
+ m_cacheGetData = createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo);
+ }
+
+ // Merge the caches
+ const VkPipelineCache sourceCaches[] =
+ {
+ *m_cacheEmpty,
+ *m_cacheGetData,
+ };
+ VK_CHECK(vk.mergePipelineCaches(vkDevice, *m_cacheMerged, 2u, sourceCaches));
+
+ // Create pipeline from merged cache
+ m_pipeline[PIPELINE_CACHE_NDX_CACHED] = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass, *m_cacheMerged);
+}
+
+MergeCacheTestInstance::~MergeCacheTestInstance (void)
+{
+ delete[] m_data;
+}
+
+} // anonymous
+
+tcu::TestCaseGroup* createCacheTests (tcu::TestContext& testCtx)
+{
+
+ de::MovePtr<tcu::TestCaseGroup> cacheTests (new tcu::TestCaseGroup(testCtx, "cache", "pipeline cache tests"));
+
+ // Graphics Pipeline Tests
+ {
+ de::MovePtr<tcu::TestCaseGroup> graphicsTests (new tcu::TestCaseGroup(testCtx, "graphics_tests", "Test pipeline cache with graphics pipeline."));
+
+ const VkShaderStageFlagBits testParamShaders0[] =
+ {
+ VK_SHADER_STAGE_VERTEX_BIT,
+ VK_SHADER_STAGE_FRAGMENT_BIT,
+ };
+ const VkShaderStageFlagBits testParamShaders1[] =
+ {
+ VK_SHADER_STAGE_VERTEX_BIT,
+ VK_SHADER_STAGE_GEOMETRY_BIT,
+ VK_SHADER_STAGE_FRAGMENT_BIT,
+ };
+ const VkShaderStageFlagBits testParamShaders2[] =
+ {
+ VK_SHADER_STAGE_VERTEX_BIT,
+ VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
+ VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
+ VK_SHADER_STAGE_FRAGMENT_BIT,
+ };
+ const CacheTestParam* testParams[] =
+ {
+ new CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0)),
+ new CacheTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1)),
+ new CacheTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2)),
+ };
+
+ for(deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
+ {
+ graphicsTests->addChild(newTestCase<GraphicsCacheTest>(testCtx,testParams[i]));
+ delete testParams[i];
+ }
+ cacheTests->addChild(graphicsTests.release());
+ }
+
+ // Graphics Pipeline Tests
+ {
+ de::MovePtr<tcu::TestCaseGroup> computeTests (new tcu::TestCaseGroup(testCtx, "compute_tests", "Test pipeline cache with compute pipeline."));
+
+ const VkShaderStageFlagBits testParamShaders0[] =
+ {
+ VK_SHADER_STAGE_COMPUTE_BIT,
+ };
+
+ const CacheTestParam* testParams[] =
+ {
+ new CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0)),
+ };
+ for(deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
+ {
+ computeTests->addChild(newTestCase<ComputeCacheTest>(testCtx,testParams[i]));
+ delete testParams[i];
+ }
+ cacheTests->addChild(computeTests.release());
+ }
+
+ // Misc Tests
+ {
+ de::MovePtr<tcu::TestCaseGroup> miscTests (new tcu::TestCaseGroup(testCtx, "misc_tests", "Misc tests that can not be categorized to other group."));
+
+ const VkShaderStageFlagBits testParamShaders[] =
+ {
+ VK_SHADER_STAGE_VERTEX_BIT,
+ VK_SHADER_STAGE_FRAGMENT_BIT,
+ };
+
+ CacheTestParam* testParam = new CacheTestParam(testParamShaders, DE_LENGTH_OF_ARRAY(testParamShaders));
+ miscTests->addChild(new MergeCacheTest(testCtx,
+ "merge_cache_test",
+ "Merge the caches test.",
+ testParam));
+ delete testParam;
+
+ cacheTests->addChild(miscTests.release());
+ }
+
+ return cacheTests.release();
+}
+
+} // pipeline
+
+} // vkt