/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2015 The Khronos Group Inc.
 * Copyright (c) 2015 ARM Ltd.
 *
 * 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 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 "vkTypeUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"
#include "tcuImageCompare.hpp"
#include "deUniquePtr.hpp"
#include "deMemory.h"
#include "tcuTestLog.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_FATAL("Unknown shader Stage!");
		break;
	};

	return desc.str();
}

// helper classes
class CacheTestParam
{
public:
								CacheTestParam          (const VkShaderStageFlagBits* shaders,
														 deUint32                     count,
														 bool						  compileCacheMissShaders);
	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; }
	bool						getCompileMissShaders	(void)			const	{ return m_compileCacheMissShaders;	}
protected:
	VkShaderStageFlagBits       m_shaders[VK_MAX_SHADER_STAGES];
	size_t                      m_shaderCount;
	bool						m_compileCacheMissShaders;
};

CacheTestParam::CacheTestParam (const VkShaderStageFlagBits* shaders, deUint32 count, bool compileCacheMissShaders)
	: m_compileCacheMissShaders	(compileCacheMissShaders)
{
	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,
															 VkPipelineLayout		pipelineLayout);
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;
};

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, VkPipelineLayout pipelineLayout)
{
	const DeviceInterface&      vk                  = m_context.getDeviceInterface();
	const VkDevice              vkDevice            = m_context.getDevice();

	// 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;
		(m_patchControlPoints == 0 ? VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
								   : VK_PRIMITIVE_TOPOLOGY_PATCH_LIST), // VkPrimitiveTopology                      topology;
		VK_FALSE,                                                       // VkBool32                                 primitiveRestartEnable;
	};

	const VkViewport	viewport	= makeViewport(renderSize);
	const VkRect2D		scissor		= makeRect2D(renderSize);

	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;
	};

	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;
		},
		0.0f,                                                      // float                                    minDepthBounds;
		1.0f,                                                      // float                                    maxDepthBounds;
	};

	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;
	};
	const VkPipelineTessellationStateCreateInfo* pTessCreateInfo = (m_patchControlPoints > 0)
																  ? &tessStateCreateInfo
																  : DE_NULL;

	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;
		(const VkPipelineDynamicStateCreateInfo*)DE_NULL,   // const VkPipelineDynamicStateCreateInfo*          pDynamicState;
		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();

	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);

	*pAlloc = context.getDefaultAllocator().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();

	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);

	*pAlloc = context.getDefaultAllocator().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<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
	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);

	// Create command buffer
	m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

	// 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();

	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());

	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<VkPipelineLayout>              m_pipelineLayout;

	Move<VkImage>                       m_depthImage;
	de::MovePtr<Allocation>             m_depthImageAlloc;
	de::MovePtr<Allocation>             m_colorImageAlloc[PIPELINE_CACHE_NDX_COUNT];
	Move<VkImageView>                   m_depthAttachmentView;
	VkImageMemoryBarrier				m_imageLayoutBarriers[3];

	Move<VkBuffer>                      m_vertexBuffer;
	de::MovePtr<Allocation>				m_vertexBufferMemory;
	std::vector<Vertex4RGBA>            m_vertices;

	SimpleGraphicsPipelineBuilder       m_pipelineBuilder;
	SimpleGraphicsPipelineBuilder       m_missPipelineBuilder;
	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
{
	enum ShaderCacheOpType
	{
		SHADERS_CACHE_OP_HIT = 0,
		SHADERS_CACHE_OP_MISS,

		SHADERS_CACHE_OP_LAST
	};

	for (deUint32 shaderOpNdx = 0u; shaderOpNdx < SHADERS_CACHE_OP_LAST; shaderOpNdx++)
	{
		const ShaderCacheOpType shaderOp = (ShaderCacheOpType)shaderOpNdx;

		if (shaderOp == SHADERS_CACHE_OP_MISS && !m_param.getCompileMissShaders())
			continue;

		const std::string missHitDiff = (shaderOp == SHADERS_CACHE_OP_HIT ? "" : " + 0.1");
		const std::string missSuffix = (shaderOp == SHADERS_CACHE_OP_HIT ? "" : "_miss");

		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" + missSuffix) << 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" + missHitDiff + ";\n"
						"}\n");
					break;

				case VK_SHADER_STAGE_FRAGMENT_BIT:
					programCollection.glslSources.add("color_frag" + missSuffix) << 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" + missHitDiff + ";\n"
						"}\n");
					break;

				case VK_SHADER_STAGE_GEOMETRY_BIT:
					programCollection.glslSources.add("dummy_geo" + missSuffix) << glu::GeometrySource(
						"#version 450 \n"
						"layout(triangles) in;\n"
						"layout(triangle_strip, max_vertices = 3) out;\n"
						"layout(location = 0) in highp vec4 in_vtxColor[];\n"
						"layout(location = 0) out highp vec4 vtxColor;\n"
						"out gl_PerVertex { vec4 gl_Position; };\n"
						"in gl_PerVertex { vec4 gl_Position; } gl_in[];\n"
						"void main (void)\n"
						"{\n"
						"  for(int ndx=0; ndx<3; ndx++)\n"
						"  {\n"
						"    gl_Position = gl_in[ndx].gl_Position;\n"
						"    vtxColor    = in_vtxColor[ndx]" + missHitDiff + ";\n"
						"    EmitVertex();\n"
						"  }\n"
						"  EndPrimitive();\n"
						"}\n");
					break;

				case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
					programCollection.glslSources.add("basic_tcs" + missSuffix) << glu::TessellationControlSource(
						"#version 450 \n"
						"layout(vertices = 3) out;\n"
						"layout(location = 0) in highp vec4 color[];\n"
						"layout(location = 0) out highp vec4 vtxColor[];\n"
						"out gl_PerVertex { vec4 gl_Position; } gl_out[3];\n"
						"in gl_PerVertex { vec4 gl_Position; } gl_in[gl_MaxPatchVertices];\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]" + missHitDiff + ";\n"
						"}\n");
					break;

				case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
					programCollection.glslSources.add("basic_tes" + missSuffix) << glu::TessellationEvaluationSource(
						"#version 450 \n"
						"layout(triangles, fractional_even_spacing, ccw) in;\n"
						"layout(location = 0) in highp vec4 colors[];\n"
						"layout(location = 0) out highp vec4 vtxColor;\n"
						"out gl_PerVertex { vec4 gl_Position; };\n"
						"in gl_PerVertex { vec4 gl_Position; } gl_in[gl_MaxPatchVertices];\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)" + missHitDiff + ";\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_FATAL("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_D16_UNORM)
	, m_pipelineBuilder		(context)
	, m_missPipelineBuilder	(context)
{
	const DeviceInterface&  vk               = m_context.getDeviceInterface();
	const VkDevice          vkDevice         = m_context.getDevice();

	// Create vertex buffer
	{
		m_vertexBuffer = createBufferAndBindMemory(m_context, 1024u, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, &m_vertexBufferMemory);

		m_vertices          = createOverlappingQuads();
		// Load vertices into vertex buffer
		deMemcpy(m_vertexBufferMemory->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
		flushAlloc(vk, vkDevice, *m_vertexBufferMemory);
	}

	// Create render pass
	m_renderPass = makeRenderPass(vk, vkDevice, m_colorFormat, m_depthFormat);

	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[PIPELINE_CACHE_NDX_NO_CACHE]);
		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[PIPELINE_CACHE_NDX_CACHED]);
	}

	// 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);
	}

	// Set up image layout transition barriers
	{
		VkImageMemoryBarrier colorImageBarrier =
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType			sType;
			DE_NULL,											// const void*				pNext;
			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;
			VK_QUEUE_FAMILY_IGNORED,							// deUint32					srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,							// deUint32					dstQueueFamilyIndex;
			*m_colorImage[PIPELINE_CACHE_NDX_NO_CACHE],			// VkImage					image;
			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },		// VkImageSubresourceRange	subresourceRange;
		};

		m_imageLayoutBarriers[0] = colorImageBarrier;

		colorImageBarrier.image = *m_colorImage[PIPELINE_CACHE_NDX_CACHED];
		m_imageLayoutBarriers[1] = colorImageBarrier;

		const VkImageMemoryBarrier depthImageBarrier =
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType			sType;
			DE_NULL,											// const void*				pNext;
			0u,													// VkAccessFlags			srcAccessMask;
			VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
			VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout			oldLayout;
			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
			VK_QUEUE_FAMILY_IGNORED,							// deUint32					srcQueueFamilyIndex;
			VK_QUEUE_FAMILY_IGNORED,							// deUint32					dstQueueFamilyIndex;
			*m_depthImage,										// VkImage					image;
			{ VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u },		// VkImageSubresourceRange	subresourceRange;
		};

		m_imageLayoutBarriers[2] = depthImageBarrier;
	}
	// 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");
				if (m_param->getCompileMissShaders())
				{
					m_missPipelineBuilder.bindShaderStage(VK_SHADER_STAGE_VERTEX_BIT, "color_vert_miss", "main");
				}
				break;
			case VK_SHADER_STAGE_FRAGMENT_BIT:
				m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_FRAGMENT_BIT, "color_frag", "main");
				if (m_param->getCompileMissShaders())
				{
					m_missPipelineBuilder.bindShaderStage(VK_SHADER_STAGE_FRAGMENT_BIT, "color_frag_miss", "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");
					if (m_param->getCompileMissShaders())
					{
						m_missPipelineBuilder.bindShaderStage(VK_SHADER_STAGE_GEOMETRY_BIT, "dummy_geo_miss", "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");
					m_pipelineBuilder.enableTessellationStage(3);
					if (m_param->getCompileMissShaders())
					{
						m_missPipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "basic_tcs_miss", "main");
						m_missPipelineBuilder.enableTessellationStage(3);
					}
				}
				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");
					m_pipelineBuilder.enableTessellationStage(3);
					if (m_param->getCompileMissShaders())
					{
						m_missPipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "basic_tes_miss", "main");
						m_missPipelineBuilder.enableTessellationStage(3);
					}
				}
				break;
			default:
				DE_FATAL("Unknown Shader Stage!");
				break;
		};
	}

	// 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);
	}

	m_pipeline[PIPELINE_CACHE_NDX_NO_CACHE]	= m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass, *m_cache, *m_pipelineLayout);
	m_pipeline[PIPELINE_CACHE_NDX_CACHED]	= m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass, *m_cache, *m_pipelineLayout);
}

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),
	};

	beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), 2u, attachmentClearValues);

	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);

	endRenderPass(vk, *m_cmdBuffer);
}

void GraphicsCacheTestInstance::prepareCommandBuffer (void)
{
	const DeviceInterface&  vk               = m_context.getDeviceInterface();

	beginCommandBuffer(vk, *m_cmdBuffer, 0u);

	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
		0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(m_imageLayoutBarriers), m_imageLayoutBarriers);

	prepareRenderPass(*m_framebuffer[PIPELINE_CACHE_NDX_NO_CACHE], *m_pipeline[PIPELINE_CACHE_NDX_NO_CACHE]);

	// After the first render pass, the images are in correct layouts

	prepareRenderPass(*m_framebuffer[PIPELINE_CACHE_NDX_CACHED], *m_pipeline[PIPELINE_CACHE_NDX_CACHED]);

	endCommandBuffer(vk, *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();

	const VkQueue                   queue               = m_context.getUniversalQueue();
	de::MovePtr<tcu::TextureLevel>  resultNoCache       = readColorAttachment(vk,
																			  vkDevice,
																			  queue,
																			  queueFamilyIndex,
																			  m_context.getDefaultAllocator(),
																			  *m_colorImage[PIPELINE_CACHE_NDX_NO_CACHE],
																			  m_colorFormat,
																			  m_renderSize);
	de::MovePtr<tcu::TextureLevel>  resultCache         = readColorAttachment(vk,
																			  vkDevice,
																			  queue,
																			  queueFamilyIndex,
																			  m_context.getDefaultAllocator(),
																			  *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;
	de::MovePtr<Allocation>     m_inputBufferAlloc;
	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 = 1) 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;
	m_inputBuf = createBufferAndBindMemory(m_context, size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, &m_inputBufferAlloc);

	// Initialize input buffer
	tcu::Vec4* pVec = reinterpret_cast<tcu::Vec4*>(m_inputBufferAlloc->getHostPtr());
	for (deUint32 ndx = 0u; ndx < 128u; ndx++)
	{
		for (deUint32 component = 0u; component < 4u; component++)
			pVec[ndx][component]= (float)(ndx * (component + 1u));
	}
	flushAlloc(vk, vkDevice, *m_inputBufferAlloc);

	// 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());

		for (deUint32 i = 0; i < (size / sizeof(tcu::Vec4)); i++)
			pVec[i] = tcu::Vec4(0.0f);

		flushAlloc(vk, vkDevice, *m_outputBufferAlloc[ndx]);
	}
}

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();

	beginCommandBuffer(vk, *m_cmdBuffer, 0u);

	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);
	}

	endCommandBuffer(vk, *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
	invalidateAlloc(vk, vkDevice, *m_outputBufferAlloc[PIPELINE_CACHE_NDX_NO_CACHE]);

	invalidateAlloc(vk, vkDevice, *m_outputBufferAlloc[PIPELINE_CACHE_NDX_CACHED]);
	// 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 PipelineFromCacheTest : public GraphicsCacheTest
{
public:
							PipelineFromCacheTest		(tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param);
	virtual                 ~PipelineFromCacheTest		(void) {		}
	virtual TestInstance*   createInstance				(Context& context) const;
};

PipelineFromCacheTest::PipelineFromCacheTest (tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param)
	: GraphicsCacheTest(testContext, name, description, param)
{
}

class PipelineFromCacheTestInstance : public GraphicsCacheTestInstance
{
public:
							PipelineFromCacheTestInstance	(Context& context, const CacheTestParam* param);
	virtual                 ~PipelineFromCacheTestInstance	(void);
protected:
	Move<VkPipelineCache>   m_newCache;
	deUint8*                m_data;
};

TestInstance* PipelineFromCacheTest::createInstance (Context& context) const
{
	return new PipelineFromCacheTestInstance(context, &m_param);
}

PipelineFromCacheTestInstance::PipelineFromCacheTestInstance (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
	{
		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));

		const VkPipelineCacheCreateInfo pipelineCacheCreateInfo =
		{
			VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,           // VkStructureType             sType;
			DE_NULL,                                                // const void*                 pNext;
			0u,                                                     // VkPipelineCacheCreateFlags  flags;
			dataSize,                                               // deUintptr                   initialDataSize;
			m_data,                                                 // const void*                 pInitialData;
		};
		m_newCache = createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo);
	}
	m_pipeline[PIPELINE_CACHE_NDX_CACHED] = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass, *m_newCache, *m_pipelineLayout);
}

PipelineFromCacheTestInstance::~PipelineFromCacheTestInstance (void)
{
	delete[] m_data;
}

class PipelineFromIncompleteCacheTest : public GraphicsCacheTest
{
public:
							PipelineFromIncompleteCacheTest		(tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param);
	virtual                 ~PipelineFromIncompleteCacheTest	(void)			{}
	virtual TestInstance*   createInstance						(Context& context) const;
};

PipelineFromIncompleteCacheTest::PipelineFromIncompleteCacheTest (tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param)
	: GraphicsCacheTest(testContext, name, description, param)
{
}

class PipelineFromIncompleteCacheTestInstance : public GraphicsCacheTestInstance
{
public:
							PipelineFromIncompleteCacheTestInstance(Context& context, const CacheTestParam* param);
	virtual                 ~PipelineFromIncompleteCacheTestInstance(void);
protected:
protected:
	Move<VkPipelineCache>   m_newCache;
	deUint8*                m_data;
};

TestInstance* PipelineFromIncompleteCacheTest::createInstance (Context& context) const
{
	return new PipelineFromIncompleteCacheTestInstance(context, &m_param);
}

PipelineFromIncompleteCacheTestInstance::PipelineFromIncompleteCacheTestInstance (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
	{
		size_t  dataSize = 0u;
		VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, DE_NULL));

		if (dataSize == 0)
			TCU_THROW(NotSupportedError, "Empty pipeline cache - unable to test");

		dataSize--;

		m_data = new deUint8[dataSize];
		DE_ASSERT(m_data);
		if (vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, (void*)m_data) != VK_INCOMPLETE)
			TCU_THROW(TestError, "GetPipelineCacheData should return VK_INCOMPLETE state!");

		const VkPipelineCacheCreateInfo pipelineCacheCreateInfo =
		{
			VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,           // VkStructureType             sType;
			DE_NULL,                                                // const void*                 pNext;
			0u,                                                     // VkPipelineCacheCreateFlags  flags;
			dataSize,                                               // deUintptr                   initialDataSize;
			m_data,                                                 // const void*                 pInitialData;
		};
		m_newCache = createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo);
	}
	m_pipeline[PIPELINE_CACHE_NDX_CACHED] = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass, *m_newCache, *m_pipelineLayout);
}

PipelineFromIncompleteCacheTestInstance::~PipelineFromIncompleteCacheTestInstance (void)
{
	delete[] m_data;
}


enum MergeCacheType
{
	MERGE_CACHE_EMPTY = 0,
	MERGE_CACHE_FROM_DATA,
	MERGE_CACHE_HIT,
	MERGE_CACHE_MISS,
	MERGE_CACHE_MISS_AND_HIT,
	MERGE_CACHE_MERGED,

	MERGE_CACHE_TYPE_LAST = MERGE_CACHE_MERGED
};

std::string getMergeCacheTypeStr (MergeCacheType type)
{
	switch (type)
	{
		case MERGE_CACHE_EMPTY:
			return "empty";
		case MERGE_CACHE_FROM_DATA:
			return "from_data";
		case MERGE_CACHE_HIT:
			return "hit";
		case MERGE_CACHE_MISS_AND_HIT:
			return "misshit";
		case MERGE_CACHE_MISS:
			return "miss";
		case MERGE_CACHE_MERGED:
			return "merged";
	}
	TCU_FAIL("unhandled merge cache type");
}

std::string getMergeCacheTypesStr (const std::vector<MergeCacheType>& types)
{
	std::string ret;
	for (size_t idx = 0; idx < types.size(); ++idx)
	{
		if (ret.size())
			ret += '_';
		ret += getMergeCacheTypeStr(types[idx]);
	}
	return ret;
}


class MergeCacheTestParam
{
public:
	MergeCacheType				destCacheType;
	std::vector<MergeCacheType> srcCacheTypes;
};

class MergeCacheTest : public GraphicsCacheTest
{
public:
								MergeCacheTest      (tcu::TestContext&			testContext,
													 const std::string&			name,
													 const std::string&			description,
													 const CacheTestParam*		param,
													 const MergeCacheTestParam* mergeCacheParam)
									: GraphicsCacheTest (testContext, name, description, param)
									, m_mergeCacheParam	(*mergeCacheParam)
									{ }
	virtual						~MergeCacheTest     (void) { }
	virtual TestInstance*		createInstance      (Context&               context) const;
private:
	const MergeCacheTestParam	m_mergeCacheParam;
};

class MergeCacheTestInstance : public GraphicsCacheTestInstance
{
public:
							MergeCacheTestInstance  (Context&					context,
													 const CacheTestParam*		param,
													 const MergeCacheTestParam* mergeCacheParam);
private:
	Move<VkPipelineCache>	createPipelineCache		(const DeviceInterface& vk, VkDevice device, MergeCacheType type);

protected:
	Move<VkPipelineCache>   m_cacheMerged;
};

TestInstance* MergeCacheTest::createInstance (Context& context) const
{
	return new MergeCacheTestInstance(context, &m_param, &m_mergeCacheParam);
}

MergeCacheTestInstance::MergeCacheTestInstance (Context& context, const CacheTestParam* param, const MergeCacheTestParam* mergeCacheParam)
	: GraphicsCacheTestInstance (context, param)
{
	const DeviceInterface&  vk               = m_context.getDeviceInterface();
	const VkDevice          vkDevice         = m_context.getDevice();


	// Create a merge destination cache
	m_cacheMerged = createPipelineCache(vk, vkDevice, mergeCacheParam->destCacheType);

	// Create more pipeline caches
	std::vector<VkPipelineCache>	sourceCaches	(mergeCacheParam->srcCacheTypes.size());
	typedef de::SharedPtr<Move<VkPipelineCache> > PipelineCachePtr;
	std::vector<PipelineCachePtr>	sourceCachePtrs	(sourceCaches.size());
	{
		for (size_t sourceIdx = 0; sourceIdx < mergeCacheParam->srcCacheTypes.size(); sourceIdx++)
		{
			// vk::Move is not copyable, so create it on heap and wrap into de::SharedPtr
			PipelineCachePtr	pipelineCachePtr	(new Move<VkPipelineCache>());
			*pipelineCachePtr = createPipelineCache(vk, vkDevice, mergeCacheParam->srcCacheTypes[sourceIdx]);

			sourceCachePtrs[sourceIdx]	= pipelineCachePtr;
			sourceCaches[sourceIdx]		= **pipelineCachePtr;
		}
	}

	// Merge the caches
	VK_CHECK(vk.mergePipelineCaches(vkDevice, *m_cacheMerged, static_cast<deUint32>(sourceCaches.size()), &sourceCaches[0]));

	// Create pipeline from merged cache
	m_pipeline[PIPELINE_CACHE_NDX_CACHED] = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass, *m_cacheMerged, *m_pipelineLayout);
}

Move<VkPipelineCache> MergeCacheTestInstance::createPipelineCache (const DeviceInterface& vk, VkDevice device, MergeCacheType type)
{
	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;
	};

	switch (type)
	{
		case MERGE_CACHE_EMPTY:
		{
			return vk::createPipelineCache(vk, device, &pipelineCacheCreateInfo);
		}
		case MERGE_CACHE_FROM_DATA:
		{
			// Create a cache with init data from m_cache
			size_t  dataSize = 0u;
			VK_CHECK(vk.getPipelineCacheData(device, *m_cache, (deUintptr*)&dataSize, DE_NULL));

			std::vector<deUint8> data(dataSize);
			VK_CHECK(vk.getPipelineCacheData(device, *m_cache, (deUintptr*)&dataSize, &data[0]));

			pipelineCacheCreateInfo.initialDataSize = data.size();
			pipelineCacheCreateInfo.pInitialData = &data[0];
			return vk::createPipelineCache(vk, device, &pipelineCacheCreateInfo);
		}
		case MERGE_CACHE_HIT:
		{
			Move<VkPipelineCache> ret = createPipelineCache(vk, device, MERGE_CACHE_EMPTY);

			m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass, *ret, *m_pipelineLayout);

			return ret;
		}
		case MERGE_CACHE_MISS:
		{
			Move<VkPipelineCache> ret = createPipelineCache(vk, device, MERGE_CACHE_EMPTY);

			m_missPipelineBuilder.buildPipeline(m_renderSize, *m_renderPass, *ret, *m_pipelineLayout);

			return ret;
		}
		case MERGE_CACHE_MISS_AND_HIT:
		{
			Move<VkPipelineCache> ret = createPipelineCache(vk, device, MERGE_CACHE_EMPTY);

			m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass, *ret, *m_pipelineLayout);
			m_missPipelineBuilder.buildPipeline(m_renderSize, *m_renderPass, *ret, *m_pipelineLayout);

			return ret;
		}
		case MERGE_CACHE_MERGED:
		{
			Move<VkPipelineCache>	cache1			= createPipelineCache(vk, device, MERGE_CACHE_FROM_DATA);
			Move<VkPipelineCache>	cache2			= createPipelineCache(vk, device, MERGE_CACHE_HIT);
			Move<VkPipelineCache>	cache3			= createPipelineCache(vk, device, MERGE_CACHE_MISS);

			const VkPipelineCache	sourceCaches[]	=
			{
				*cache1,
				*cache2,
				*cache3
			};

			Move<VkPipelineCache> ret = createPipelineCache(vk, device, MERGE_CACHE_EMPTY);

			// Merge the caches
			VK_CHECK(vk.mergePipelineCaches(device, *ret, DE_LENGTH_OF_ARRAY(sourceCaches), sourceCaches));

			return ret;
		}
	}
	TCU_FAIL("unhandled merge cache type");
}

class CacheHeaderTest : public GraphicsCacheTest
{
public:
	CacheHeaderTest(tcu::TestContext&      testContext,
		const std::string&     name,
		const std::string&     description,
		const CacheTestParam*  param)
		: GraphicsCacheTest(testContext, name, description, param)
	{ }
	virtual                 ~CacheHeaderTest(void) { }
	virtual TestInstance*   createInstance(Context&               context) const;
};

class CacheHeaderTestInstance : public GraphicsCacheTestInstance
{
public:
							CacheHeaderTestInstance  (Context& context, const CacheTestParam*  param);
	virtual                 ~CacheHeaderTestInstance (void);
protected:
	deUint8*                m_data;

	struct CacheHeader
	{
		deUint32 HeaderLength;
		deUint32 HeaderVersion;
		deUint32 VendorID;
		deUint32 DeviceID;
		deUint8 PipelineCacheUUID[VK_UUID_SIZE];
	} m_header;
};

TestInstance* CacheHeaderTest::createInstance (Context& context) const
{
	return new CacheHeaderTestInstance(context, &m_param);
}

CacheHeaderTestInstance::CacheHeaderTestInstance (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 cache with init data from m_cache
		size_t  dataSize = 0u;
		VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, DE_NULL));

		if (dataSize < sizeof(m_header))
			TCU_THROW(TestError, "Pipeline cache size is smaller than header size");

		m_data = new deUint8[dataSize];
		DE_ASSERT(m_data);
		VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, (void*)m_data));

		deMemcpy(&m_header, m_data, sizeof(m_header));

		if (m_header.HeaderLength - VK_UUID_SIZE != 16)
			TCU_THROW(TestError, "Invalid header size!");

		if (m_header.HeaderVersion != 1)
			TCU_THROW(TestError, "Invalid header version!");

		if (m_header.VendorID != m_context.getDeviceProperties().vendorID)
			TCU_THROW(TestError, "Invalid header vendor ID!");

		if (m_header.DeviceID != m_context.getDeviceProperties().deviceID)
			TCU_THROW(TestError, "Invalid header device ID!");

		if (deMemCmp(&m_header.PipelineCacheUUID, &m_context.getDeviceProperties().pipelineCacheUUID, VK_UUID_SIZE) != 0)
			TCU_THROW(TestError, "Invalid header pipeline cache UUID!");
	}
}

CacheHeaderTestInstance::~CacheHeaderTestInstance (void)
{
	delete[] m_data;
}

class InvalidSizeTest : public GraphicsCacheTest
{
public:
							InvalidSizeTest		(tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param);
	virtual                 ~InvalidSizeTest	(void)	 {}
	virtual TestInstance*   createInstance		(Context& context) const;
};

InvalidSizeTest::InvalidSizeTest (tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param)
	: GraphicsCacheTest(testContext, name, description, param)
{
}

class InvalidSizeTestInstance : public GraphicsCacheTestInstance
{
public:
							InvalidSizeTestInstance		(Context& context, const CacheTestParam*  param);
	virtual                 ~InvalidSizeTestInstance	(void);
protected:
	deUint8*                m_data;
	deUint8*                m_zeroBlock;
};

TestInstance* InvalidSizeTest::createInstance (Context& context) const
{
	return new InvalidSizeTestInstance(context, &m_param);
}

InvalidSizeTestInstance::InvalidSizeTestInstance (Context& context, const CacheTestParam* param)
	: GraphicsCacheTestInstance	(context, param)
	, m_data					(DE_NULL)
	, m_zeroBlock				(DE_NULL)
{
	const DeviceInterface&  vk			= m_context.getDeviceInterface();
	const VkDevice          vkDevice	= m_context.getDevice();

	// Create more pipeline caches
	try
	{
		// Create a cache with init data from m_cache
		size_t dataSize			= 0u;
		size_t savedDataSize	= 0u;
		VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, DE_NULL));
		savedDataSize = dataSize;

		// If the value of dataSize is less than the maximum size that can be retrieved by the pipeline cache,
		// at most pDataSize bytes will be written to pData, and vkGetPipelineCacheData will return VK_INCOMPLETE.
		dataSize--;

		m_data = new deUint8[savedDataSize];
		deMemset(m_data, 0, savedDataSize);
		DE_ASSERT(m_data);
		if (vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, (void*)m_data) != VK_INCOMPLETE)
			TCU_THROW(TestError, "GetPipelineCacheData should return VK_INCOMPLETE state!");

		delete[] m_data;
		m_data = DE_NULL;

		// If the value of dataSize is less than what is necessary to store the header,
		// nothing will be written to pData and zero will be written to dataSize.
		dataSize = 16 + VK_UUID_SIZE - 1;

		m_data = new deUint8[savedDataSize];
		deMemset(m_data, 0, savedDataSize);
		DE_ASSERT(m_data);
		if (vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, (void*)m_data) != VK_INCOMPLETE)
			TCU_THROW(TestError, "GetPipelineCacheData should return VK_INCOMPLETE state!");

		m_zeroBlock = new deUint8[savedDataSize];
		deMemset(m_zeroBlock, 0, savedDataSize);
		if (deMemCmp(m_data, m_zeroBlock, savedDataSize) != 0 || dataSize != 0)
			TCU_THROW(TestError, "Data needs to be empty and data size should be 0 when invalid size is passed to GetPipelineCacheData!");
	}
	catch (...)
	{
		delete[] m_data;
		delete[] m_zeroBlock;
		throw;
	}
}

InvalidSizeTestInstance::~InvalidSizeTestInstance (void)
{
	delete[] m_data;
	delete[] m_zeroBlock;
}

class ZeroSizeTest : public GraphicsCacheTest
{
public:
							ZeroSizeTest	(tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param);
	virtual					~ZeroSizeTest	(void) {}
	virtual TestInstance*	createInstance	(Context& context) const;
};

ZeroSizeTest::ZeroSizeTest (tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param)
	: GraphicsCacheTest(testContext, name, description, param)
{
}

class ZeroSizeTestInstance : public GraphicsCacheTestInstance
{
public:
							ZeroSizeTestInstance	(Context& context, const CacheTestParam* param);
	virtual					~ZeroSizeTestInstance	(void);
protected:
	deUint8*				m_data;
	deUint8*				m_zeroBlock;
};

TestInstance* ZeroSizeTest::createInstance (Context& context) const
{
	return new ZeroSizeTestInstance(context, &m_param);
}

ZeroSizeTestInstance::ZeroSizeTestInstance (Context& context, const CacheTestParam* param)
	: GraphicsCacheTestInstance	(context, param)
	, m_data					(DE_NULL)
	, m_zeroBlock				(DE_NULL)
{
	const DeviceInterface&	vk			= m_context.getDeviceInterface();
	const VkDevice			vkDevice	= m_context.getDevice();

	// Create more pipeline caches
	try
	{
		// 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];
		deMemset(m_data, 0, dataSize);
		DE_ASSERT(m_data);

		VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, (void*)m_data));

		{
			// Create a cache with initialDataSize = 0 & pInitialData != NULL
			const VkPipelineCacheCreateInfo	pipelineCacheCreateInfo	=
			{
				VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,	// VkStructureType             sType;
				DE_NULL,										// const void*                 pNext;
				0u,												// VkPipelineCacheCreateFlags  flags;
				0u,												// deUintptr                   initialDataSize;
				m_data,											// const void*                 pInitialData;
			};

			const Unique<VkPipelineCache>	pipelineCache			(createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo));
		}
	}
	catch (...)
	{
		delete[] m_data;
		delete[] m_zeroBlock;
		throw;
	}
}

ZeroSizeTestInstance::~ZeroSizeTestInstance (void)
{
	delete[] m_data;
	delete[] m_zeroBlock;
}

class InvalidBlobTest : public GraphicsCacheTest
{
public:
							InvalidBlobTest		(tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param);
	virtual					~InvalidBlobTest	(void) {}
	virtual TestInstance*	createInstance		(Context& context) const;
};

InvalidBlobTest::InvalidBlobTest (tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param)
	: GraphicsCacheTest(testContext, name, description, param)
{
}

class InvalidBlobTestInstance : public GraphicsCacheTestInstance
{
public:
							InvalidBlobTestInstance		(Context& context, const CacheTestParam* param);
	virtual					~InvalidBlobTestInstance	(void);
protected:
	deUint8*				m_data;
	deUint8*				m_zeroBlock;
};

TestInstance* InvalidBlobTest::createInstance (Context& context) const
{
	return new InvalidBlobTestInstance(context, &m_param);
}

InvalidBlobTestInstance::InvalidBlobTestInstance (Context& context, const CacheTestParam* param)
	: GraphicsCacheTestInstance	(context, param)
	, m_data					(DE_NULL)
	, m_zeroBlock				(DE_NULL)
{
	const DeviceInterface&	vk			= m_context.getDeviceInterface();
	const VkDevice			vkDevice	= m_context.getDevice();

	// Create more pipeline caches
	try
	{
		// 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];
		deMemset(m_data, 0, dataSize);
		DE_ASSERT(m_data);

		VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, (void*)m_data));

		const struct
		{
			deUint32	offset;
			std::string	name;
		} headerLayout[] =
		{
			{ 4u,	"pipeline cache header version"	},
			{ 8u,	"vendor ID"						},
			{ 12u,	"device ID"						},
			{ 16u,	"pipeline cache ID"				}
		};

		for (deUint32 i = 0u; i < DE_LENGTH_OF_ARRAY(headerLayout); i++)
		{
			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Creating pipeline cache using previously retrieved data with invalid " << headerLayout[i].name << tcu::TestLog::EndMessage;

			m_data[headerLayout[i].offset] = (deUint8)(m_data[headerLayout[i].offset] + 13u);	// Add arbitrary number to create an invalid value

			const VkPipelineCacheCreateInfo	pipelineCacheCreateInfo	=
			{
				VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,	// VkStructureType             sType;
				DE_NULL,										// const void*                 pNext;
				0u,												// VkPipelineCacheCreateFlags  flags;
				dataSize,										// deUintptr                   initialDataSize;
				m_data,											// const void*                 pInitialData;
			};

			const Unique<VkPipelineCache>	pipelineCache			(createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo));

			m_data[headerLayout[i].offset] = (deUint8)(m_data[headerLayout[i].offset] - 13u);	// Return to original value
		}
	}
	catch (...)
	{
		delete[] m_data;
		delete[] m_zeroBlock;
		throw;
	}
}

InvalidBlobTestInstance::~InvalidBlobTestInstance (void)
{
	delete[] m_data;
	delete[] m_zeroBlock;
}
} // 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[] =
		{
			CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), false),
			CacheTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), false),
			CacheTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), false),
		};

		for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
			graphicsTests->addChild(newTestCase<GraphicsCacheTest>(testCtx, &testParams[i]));

		cacheTests->addChild(graphicsTests.release());
	}

	// Graphics Pipeline Tests
	{
		de::MovePtr<tcu::TestCaseGroup> graphicsTests(new tcu::TestCaseGroup(testCtx, "pipeline_from_get_data", "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[] =
		{
			CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), false),
			CacheTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), false),
			CacheTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), false),
		};

		for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
			graphicsTests->addChild(newTestCase<PipelineFromCacheTest>(testCtx, &testParams[i]));

		cacheTests->addChild(graphicsTests.release());
	}

	// Graphics Pipeline Tests
	{
		de::MovePtr<tcu::TestCaseGroup> graphicsTests(new tcu::TestCaseGroup(testCtx, "pipeline_from_incomplete_get_data", "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[] =
		{
			CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), false),
			CacheTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), false),
			CacheTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), false),
		};

		for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
			graphicsTests->addChild(newTestCase<PipelineFromIncompleteCacheTest>(testCtx, &testParams[i]));

		cacheTests->addChild(graphicsTests.release());
	}

	// Compute 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[] =
		{
			CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), false),
		};

		for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
			computeTests->addChild(newTestCase<ComputeCacheTest>(testCtx, &testParams[i]));

		cacheTests->addChild(computeTests.release());
	}

	// Merge cache Tests
	{
		de::MovePtr<tcu::TestCaseGroup> mergeTests (new tcu::TestCaseGroup(testCtx, "merge", "Cache merging tests"));

		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[] =
		{
			CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), true),
			CacheTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), true),
			CacheTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), true),
		};

		for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
		{

			de::MovePtr<tcu::TestCaseGroup> mergeStagesTests(new tcu::TestCaseGroup(testCtx, testParams[i].generateTestName().c_str(), testParams[i].generateTestDescription().c_str()));

			for (deUint32 destTypeIdx = 0u; destTypeIdx <= MERGE_CACHE_TYPE_LAST; destTypeIdx++)
			for (deUint32 srcType1Idx = 0u; srcType1Idx <= MERGE_CACHE_TYPE_LAST; srcType1Idx++)
			{

				MergeCacheTestParam cacheTestParam;
				cacheTestParam.destCacheType = MergeCacheType(destTypeIdx);
				cacheTestParam.srcCacheTypes.push_back(MergeCacheType(srcType1Idx));

				// merge with one cache
				{
					std::string testName = "src_" + getMergeCacheTypesStr(cacheTestParam.srcCacheTypes) + "_dst_" + getMergeCacheTypeStr(cacheTestParam.destCacheType);
					mergeStagesTests->addChild(new MergeCacheTest(testCtx,
															testName.c_str(),
															"Merge the caches test.",
															&testParams[i],
															&cacheTestParam));
				}

				// merge with two caches
				for (deUint32 srcType2Idx = 0u; srcType2Idx <= MERGE_CACHE_TYPE_LAST; srcType2Idx++)
				{
					MergeCacheTestParam cacheTestParamTwoCaches = cacheTestParam;

					cacheTestParamTwoCaches.srcCacheTypes.push_back(MergeCacheType(srcType2Idx));

					std::string testName = "src_" + getMergeCacheTypesStr(cacheTestParamTwoCaches.srcCacheTypes) + "_dst_" + getMergeCacheTypeStr(cacheTestParamTwoCaches.destCacheType);
					mergeStagesTests->addChild(new MergeCacheTest(testCtx,
														   testName.c_str(),
														   "Merge the caches test.",
														   &testParams[i],
														   &cacheTestParamTwoCaches));
				}
			}
			mergeTests->addChild(mergeStagesTests.release());
		}
		cacheTests->addChild(mergeTests.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,
		};

		const CacheTestParam testParam(testParamShaders, DE_LENGTH_OF_ARRAY(testParamShaders), false);


		miscTests->addChild(new CacheHeaderTest(testCtx,
											   "cache_header_test",
											   "Cache header test.",
											   &testParam));

		miscTests->addChild(new InvalidSizeTest(testCtx,
												"invalid_size_test",
												"Invalid size test.",
												&testParam));

		miscTests->addChild(new ZeroSizeTest(testCtx,
											 "zero_size_test",
											 "Zero size test.",
											 &testParam));

		miscTests->addChild(new InvalidBlobTest(testCtx,
												"invalid_blob_test",
												"Invalid cache blob test.",
												&testParam));

		cacheTests->addChild(miscTests.release());
	}

	return cacheTests.release();
}

} // pipeline

} // vkt
