/*------------------------------------------------------------------------
 * 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 void			checkSupport		(Context&				context) 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;
			}
		}
	}
}

void GraphicsCacheTest::checkSupport (Context& context) const
{
	for (deUint32 shaderNdx = 0; shaderNdx < m_param.getShaderCount(); shaderNdx++)
	{
		switch(m_param.getShaderFlag(shaderNdx))
		{
			case VK_SHADER_STAGE_GEOMETRY_BIT:
				context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
				break;
			case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
			case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
				context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
				break;
			default:
				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
	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:
				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:
				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:
				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
