/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2019 The Khronos Group Inc.
 * Copyright (c) 2019 Intel Corporation.
 *
 * 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 VK_KHR_pipeline_executable_properties
 *
 * These tests creates compute and graphics pipelines with a variety of
 * stages both with and without a pipeline cache and exercise the new
 * queries provided by VK_KHR_pipeline_executable_properties.
 *
 * For each query type, it asserts that the query works and doesn't crash
 * and returns consistent results:
 *
 *  - The tests assert that the same set of pipeline executables is
 *    reported regardless of whether or not a pipeline cache is used.
 *
 *  - For each pipeline executable, the tests assert that the same set of
 *    statistics is returned regardless of whether or not a pipeline cache
 *    is used.
 *
 *  - For each pipeline executable, the tests assert that the same set of
 *    statistics is returned regardless of whether or not
 *    CAPTURE_INTERNAL_REPRESENTATIONS_BIT is set.
 *
 *  - For each pipeline executable, the tests assert that the same set of
 *    internal representations is returned regardless of whether or not a
 *    pipeline cache is used.
 *
 *  - For each string returned (statistic names, etc.) the tests assert
 *    that the string is NULL terminated.
 *
 *  - For each statistic, the tests compare the results of the two
 *    compilations and report any differences.  (Statistics differing
 *    between two compilations is not considered a failure.)
 *
 *  - For each binary internal representation, the tests attempt to assert
 *    that the amount of data returned by the implementation matches the
 *    amount the implementation claims.  (It's impossible to exactly do
 *    this but the tests give it a good try.)
 *
 * All of the returned data is recorded in the output file.
 *
 *//*--------------------------------------------------------------------*/

#include "vktPipelineExecutablePropertiesTests.hpp"
#include "vktPipelineVertexUtil.hpp"
#include "vktTestCase.hpp"
#include "vktTestCaseUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkBuilderUtil.hpp"
#include "vkRefUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkObjUtil.hpp"
#include "tcuTestLog.hpp"

#include <sstream>
#include <vector>

namespace vkt
{
namespace pipeline
{

using namespace vk;

namespace
{
enum
{
	VK_MAX_SHADER_STAGES = 6,
};

enum
{
	PIPELINE_CACHE_NDX_INITIAL = 0,
	PIPELINE_CACHE_NDX_CACHED = 1,
	PIPELINE_CACHE_NDX_COUNT,
};

// helper functions

std::string getShaderFlagStr (const VkShaderStageFlagBits	shader,
							  bool							isDescription)
{
	std::ostringstream desc;
	switch(shader)
	{
		case VK_SHADER_STAGE_VERTEX_BIT:
		{
			desc << ((isDescription) ? "vertex" : "vertex_stage");
			break;
		}
		case VK_SHADER_STAGE_FRAGMENT_BIT:
		{
			desc << ((isDescription) ? "fragment" : "fragment_stage");
			break;
		}
		case VK_SHADER_STAGE_GEOMETRY_BIT:
		{
			desc << ((isDescription) ? "geometry" : "geometry_stage");
			break;
		}
		case VK_SHADER_STAGE_COMPUTE_BIT:
		{
			desc << ((isDescription) ? "compute" : "compute_stage");
			break;
		}
		case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
		{
			desc << ((isDescription) ? "tessellation control" : "tessellation_control_stage");
			break;
		}
		case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
		{
			desc << ((isDescription) ? "tessellation evaluation" : "tessellation_evaluation_stage");
			break;
		}
	  default:
		desc << "unknown shader stage!";
		DE_FATAL("Unknown shader Stage!");
		break;
	};

	return desc.str();
}

std::string getShaderFlagsStr (const VkShaderStageFlags	flags)
{
	std::ostringstream stream;
	bool empty = true;
	for (deUint32 b = 0; b < 8 * sizeof(flags); b++)
	{
		if (flags & (1u << b))
		{
			if (empty)
			{
				empty = false;
			}
			else
			{
				stream << ", ";
			}

			stream << getShaderFlagStr((VkShaderStageFlagBits)(1u << b), true);
		}
	}

	if (empty)
	{
		stream << "none";
	}

	return stream.str();
}

// helper classes
class ExecutablePropertiesTestParam
{
public:
								ExecutablePropertiesTestParam	(const VkShaderStageFlagBits*	shaders,
																 deUint32						count,
																 deBool							testStatistics,
																 deBool							testInternalRepresentations);
	virtual						~ExecutablePropertiesTestParam	(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; }
	deBool						getTestStatistics				(void)			const	{ return m_testStatistics; }
	deBool						getTestInternalRepresentations	(void)			const	{ return m_testInternalRepresentations; }

protected:
	VkShaderStageFlagBits		m_shaders[VK_MAX_SHADER_STAGES];
	size_t						m_shaderCount;
	bool						m_testStatistics;
	bool						m_testInternalRepresentations;
};

ExecutablePropertiesTestParam::ExecutablePropertiesTestParam (const VkShaderStageFlagBits* shaders, deUint32 count, deBool testStatistics, deBool testInternalRepresentations)
{
	DE_ASSERT(count <= VK_MAX_SHADER_STAGES);
	for (deUint32 ndx = 0; ndx < count; ndx++)
		m_shaders[ndx] = shaders[ndx];
	m_shaderCount					= count;
	m_testStatistics				= testStatistics;
	m_testInternalRepresentations	= testInternalRepresentations;
}

ExecutablePropertiesTestParam::~ExecutablePropertiesTestParam (void)
{
}

const std::string ExecutablePropertiesTestParam::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);
	}

	if (m_testStatistics)
	{
		result += "_statistics";
	}

	if (m_testInternalRepresentations)
	{
		result += "_internal_representations";
	}

	return result;
}

const std::string ExecutablePropertiesTestParam::generateTestDescription (void) const
{
	std::string result;
	if (m_testStatistics)
	{
		result += "Get pipeline executable statistics";
		if (m_testInternalRepresentations)
		{
			result += " and internal representations";
		}
	}
	else if (m_testInternalRepresentations)
	{
		result += "Get pipeline executable internal representations";
	}
	else
	{
		result += "Get pipeline executable properties";
	}

	result += " with " + getShaderFlagStr(m_shaders[0], 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);
	VkPipeline				buildPipeline					(tcu::UVec2						renderSize,
															 VkRenderPass					renderPass,
															 VkPipelineCache				cache,
															 VkPipelineLayout				pipelineLayout,
															 VkPipelineCreateFlags			flags);
	void					resetBuilder					(void);

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::resetBuilder (void)
{
	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++;
}

VkPipeline SimpleGraphicsPipelineBuilder::buildPipeline (tcu::UVec2 renderSize, VkRenderPass renderPass, VkPipelineCache cache,
														 VkPipelineLayout pipelineLayout, VkPipelineCreateFlags flags)
{
	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;
		flags,												// 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;
		DE_NULL,											// VkPipeline										basePipelineHandle;
		0,													// deInt32											basePipelineIndex;
	};
	VkPipeline pipeline;
	vk.createGraphicsPipelines(vkDevice, cache, 1u, &graphicsPipelineParams, DE_NULL, &pipeline);
	return pipeline;
}

void SimpleGraphicsPipelineBuilder::enableTessellationStage (deUint32 patchControlPoints)
{
	m_patchControlPoints = patchControlPoints;
}

template <class Test>
vkt::TestCase* newTestCase (tcu::TestContext&		testContext,
							const ExecutablePropertiesTestParam*	testParam)
{
	return new Test(testContext,
					testParam->generateTestName().c_str(),
					testParam->generateTestDescription().c_str(),
					testParam);
}

// Test Classes
class ExecutablePropertiesTest : public vkt::TestCase
{
public:
							ExecutablePropertiesTest(tcu::TestContext&		testContext,
										   const std::string&		name,
										   const std::string&		description,
										   const ExecutablePropertiesTestParam*	param)
								: vkt::TestCase (testContext, name, description)
								, m_param (*param)
								{ }
	virtual					~ExecutablePropertiesTest (void) { }
protected:
	const ExecutablePropertiesTestParam	m_param;
};

class ExecutablePropertiesTestInstance : public vkt::TestInstance
{
public:
							ExecutablePropertiesTestInstance			(Context&				context,
															 const ExecutablePropertiesTestParam*	param);
	virtual					~ExecutablePropertiesTestInstance			(void);
	virtual tcu::TestStatus iterate							(void);
protected:
	virtual tcu::TestStatus verifyStatistics				(deUint32 binaryNdx);
	virtual tcu::TestStatus verifyInternalRepresentations	(deUint32 binaryNdx);
	virtual tcu::TestStatus verifyTestResult				(void);
protected:
	const ExecutablePropertiesTestParam*	m_param;

	Move<VkPipelineCache>	m_cache;
	deBool					m_extensions;

	VkPipeline				m_pipeline[PIPELINE_CACHE_NDX_COUNT];
};

ExecutablePropertiesTestInstance::ExecutablePropertiesTestInstance (Context&					context,
												const ExecutablePropertiesTestParam*	param)
	: TestInstance		(context)
	, m_param			(param)
	, m_extensions		(m_context.requireDeviceExtension("VK_KHR_pipeline_executable_properties"))
{
	const DeviceInterface&	vk				= m_context.getDeviceInterface();
	const VkDevice			vkDevice		= m_context.getDevice();

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

ExecutablePropertiesTestInstance::~ExecutablePropertiesTestInstance (void)
{
}

tcu::TestStatus ExecutablePropertiesTestInstance::iterate (void)
{
	return verifyTestResult();
}

bool
checkString(const char *string, size_t size)
{
	size_t i = 0;
	for (; i < size; i++)
	{
		if (string[i] == 0)
		{
			break;
		}
	}

	// The string needs to be non-empty and null terminated
	if (i == 0 || i >= size)
	{
		return false;
	}

	// The rest of the string should be zero
	for (; i < size; i++)
	{
		if (string[i] != 0)
		{
			return false;
		}
	}

	return true;
}

tcu::TestStatus ExecutablePropertiesTestInstance::verifyStatistics (deUint32 executableNdx)
{
	const DeviceInterface&		vk			= m_context.getDeviceInterface();
	const VkDevice				vkDevice	= m_context.getDevice();
	tcu::TestLog				&log		= m_context.getTestContext().getLog();

	std::vector<VkPipelineExecutableStatisticKHR> statistics[PIPELINE_CACHE_NDX_COUNT];

	for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
	{
		const VkPipelineExecutableInfoKHR pipelineExecutableInfo =
		{
			VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR,	// VkStructureType					sType;
			DE_NULL,										// const void*						pNext;
			m_pipeline[ndx],								// VkPipeline						pipeline;
			executableNdx,									// uint32_t							executableIndex;
		};

		deUint32 statisticCount = 0;
		VK_CHECK(vk.getPipelineExecutableStatisticsKHR(vkDevice, &pipelineExecutableInfo, &statisticCount, DE_NULL));

		if (statisticCount == 0)
		{
			continue;
		}

		statistics[ndx].resize(statisticCount);
		for (deUint32 statNdx = 0; statNdx < statisticCount; statNdx++)
		{
			deMemset(&statistics[ndx][statNdx], 0, sizeof(statistics[ndx][statNdx]));
			statistics[ndx][statNdx].sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR;
			statistics[ndx][statNdx].pNext = DE_NULL;
		}
		VK_CHECK(vk.getPipelineExecutableStatisticsKHR(vkDevice, &pipelineExecutableInfo, &statisticCount, &statistics[ndx][0]));

		for (deUint32 statNdx = 0; statNdx < statisticCount; statNdx++)
		{
			if (!checkString(statistics[ndx][statNdx].name, DE_LENGTH_OF_ARRAY(statistics[ndx][statNdx].name)))
			{
				return tcu::TestStatus::fail("Invalid statistic name string");
			}

			for (deUint32 otherNdx = 0; otherNdx < statNdx; otherNdx++)
			{
				if (deMemCmp(statistics[ndx][statNdx].name, statistics[ndx][otherNdx].name,
							 DE_LENGTH_OF_ARRAY(statistics[ndx][statNdx].name)) == 0)
				{
					return tcu::TestStatus::fail("Statistic name string not unique within the executable");
				}
			}

			if (!checkString(statistics[ndx][statNdx].description, DE_LENGTH_OF_ARRAY(statistics[ndx][statNdx].description)))
			{
				return tcu::TestStatus::fail("Invalid statistic description string");
			}

			if (statistics[ndx][statNdx].format == VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR)
			{
				if (statistics[ndx][statNdx].value.b32 != VK_TRUE && statistics[ndx][statNdx].value.b32 != VK_FALSE)
				{
					return tcu::TestStatus::fail("Boolean statistic is neither VK_TRUE nor VK_FALSE");
				}
			}
		}
	}

	if (statistics[0].size() != statistics[1].size())
	{
		return tcu::TestStatus::fail("Identical pipelines have different numbers of statistics");
	}

	if (statistics[0].size() == 0)
	{
		return tcu::TestStatus::pass("No statistics reported");
	}

	// Both compiles had better have specified the same infos
	for (deUint32 statNdx0 = 0; statNdx0 < statistics[0].size(); statNdx0++)
	{
		deUint32 statNdx1 = 0;
		for (; statNdx1 < statistics[1].size(); statNdx1++)
		{
			if (deMemCmp(statistics[0][statNdx0].name, statistics[1][statNdx1].name,
						 DE_LENGTH_OF_ARRAY(statistics[0][statNdx0].name)) == 0)
			{
				break;
			}
		}
		if (statNdx1 >= statistics[1].size())
		{
			return tcu::TestStatus::fail("Identical pipelines have different statistics");
		}

		if (deMemCmp(statistics[0][statNdx0].description, statistics[1][statNdx1].description,
					 DE_LENGTH_OF_ARRAY(statistics[0][statNdx0].description)) != 0)
		{
			return tcu::TestStatus::fail("Invalid binary description string");
		}

		if (statistics[0][statNdx0].format != statistics[1][statNdx1].format)
		{
			return tcu::TestStatus::fail("Identical pipelines have statistics with different formats");
		}

		switch (statistics[0][statNdx0].format)
		{
			case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR:
			{
				bool match = statistics[0][statNdx0].value.b32 == statistics[1][statNdx1].value.b32;
				log << tcu::TestLog::Message
					<< statistics[0][statNdx0].name << ": "
					<< (statistics[0][statNdx0].value.b32 ? "VK_TRUE" : "VK_FALSE")
					<< (match ? "" : " (non-deterministic)")
					<< " (" << statistics[0][statNdx0].description << ")"
					<< tcu::TestLog::EndMessage;
				break;
			}
			case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_INT64_KHR:
			{
				bool match = statistics[0][statNdx0].value.i64 == statistics[1][statNdx1].value.i64;
				log << tcu::TestLog::Message
					<< statistics[0][statNdx0].name << ": "
					<< statistics[0][statNdx0].value.i64
					<< (match ? "" : " (non-deterministic)")
					<< " (" << statistics[0][statNdx0].description << ")"
					<< tcu::TestLog::EndMessage;
				break;
			}
			case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR:
			{
				bool match = statistics[0][statNdx0].value.u64 == statistics[1][statNdx1].value.u64;
				log << tcu::TestLog::Message
					<< statistics[0][statNdx0].name << ": "
					<< statistics[0][statNdx0].value.u64
					<< (match ? "" : " (non-deterministic)")
					<< " (" << statistics[0][statNdx0].description << ")"
					<< tcu::TestLog::EndMessage;
				break;
			}
			case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_FLOAT64_KHR:
			{
				bool match = statistics[0][statNdx0].value.f64 == statistics[1][statNdx1].value.f64;
				log << tcu::TestLog::Message
					<< statistics[0][statNdx0].name << ": "
					<< statistics[0][statNdx0].value.f64
					<< (match ? "" : " (non-deterministic)")
					<< " (" << statistics[0][statNdx0].description << ")"
					<< tcu::TestLog::EndMessage;
				break;
			}
			default:
				return tcu::TestStatus::fail("Invalid statistic format");
		}
	}

	return tcu::TestStatus::pass("Pass");
}

tcu::TestStatus ExecutablePropertiesTestInstance::verifyInternalRepresentations (deUint32 executableNdx)
{
	const DeviceInterface&		vk			= m_context.getDeviceInterface();
	const VkDevice				vkDevice	= m_context.getDevice();
	tcu::TestLog				&log		= m_context.getTestContext().getLog();

	// We only care about internal representations on the second pipeline.
	// We still compile twice to ensure that we still get the right thing
	// even if the pipeline is hot in the cache.
	const VkPipelineExecutableInfoKHR pipelineExecutableInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR,	// VkStructureType					sType;
		DE_NULL,										// const void*						pNext;
		m_pipeline[1],									// VkPipeline						pipeline;
		executableNdx,									// uint32_t							executableIndex;
	};

	std::vector<VkPipelineExecutableInternalRepresentationKHR> irs;
	std::vector<std::vector<deUint8>> irDatas;

	deUint32 irCount = 0;
	VK_CHECK(vk.getPipelineExecutableInternalRepresentationsKHR(vkDevice, &pipelineExecutableInfo, &irCount, DE_NULL));

	if (irCount == 0)
	{
		return tcu::TestStatus::pass("No internal representations reported");
	}

	irs.resize(irCount);
	irDatas.resize(irCount);
	for (deUint32 irNdx = 0; irNdx < irCount; irNdx++)
	{
		deMemset(&irs[irNdx], 0, sizeof(irs[irNdx]));
		irs[irNdx].sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR;
		irs[irNdx].pNext = DE_NULL;
	}
	VK_CHECK(vk.getPipelineExecutableInternalRepresentationsKHR(vkDevice, &pipelineExecutableInfo, &irCount, &irs[0]));

	for (deUint32 irNdx = 0; irNdx < irCount; irNdx++)
	{
		if (!checkString(irs[irNdx].name, DE_LENGTH_OF_ARRAY(irs[irNdx].name)))
		{
			return tcu::TestStatus::fail("Invalid internal representation name string");
		}

		for (deUint32 otherNdx = 0; otherNdx < irNdx; otherNdx++)
		{
			if (deMemCmp(irs[irNdx].name, irs[otherNdx].name,
						 DE_LENGTH_OF_ARRAY(irs[irNdx].name)) == 0)
			{
				return tcu::TestStatus::fail("Internal representation name string not unique within the executable");
			}
		}

		if (!checkString(irs[irNdx].description, DE_LENGTH_OF_ARRAY(irs[irNdx].description)))
		{
			return tcu::TestStatus::fail("Invalid binary description string");
		}

		if (irs[irNdx].dataSize == 0)
		{
			return tcu::TestStatus::fail("Internal representation has no data");
		}

		irDatas[irNdx].resize(irs[irNdx].dataSize);
		irs[irNdx].pData = &irDatas[irNdx][0];
		if (irs[irNdx].isText)
		{
			// For binary data the size is important.  We check that the
			// implementation fills the whole buffer by filling it with
			// garbage first and then looking for that same garbage later.
			for (size_t i = 0; i < irs[irNdx].dataSize; i++)
			{
				irDatas[irNdx][i] = (deUint8)(37 * (17 + i));
			}
		}
	}

	VK_CHECK(vk.getPipelineExecutableInternalRepresentationsKHR(vkDevice, &pipelineExecutableInfo, &irCount, &irs[0]));

	for (deUint32 irNdx = 0; irNdx < irCount; irNdx++)
	{
		if (irs[irNdx].isText)
		{
			if (!checkString((char *)irs[irNdx].pData, irs[irNdx].dataSize))
			{
				return tcu::TestStatus::fail("Textual internal representation isn't a valid string");
			}
			log << tcu::TestLog::Section(irs[irNdx].name, irs[irNdx].description)
				<< tcu::LogKernelSource((char *)irs[irNdx].pData)
				<< tcu::TestLog::EndSection;
		}
		else
		{
			size_t maxMatchingChunkSize = 0;
			size_t matchingChunkSize = 0;
			for (size_t i = 0; i < irs[irNdx].dataSize; i++)
			{
				if (irDatas[irNdx][i] == (deUint8)(37 * (17 + i)))
				{
					matchingChunkSize++;
					if (matchingChunkSize > maxMatchingChunkSize)
					{
						maxMatchingChunkSize = matchingChunkSize;
					}
				}
				else
				{
					matchingChunkSize = 0;
				}
			}

			// 64 bytes of our random data still being in the buffer probably
			// isn't a coincidence
			if (matchingChunkSize == irs[irNdx].dataSize || matchingChunkSize >= 64)
			{
				return tcu::TestStatus::fail("Implementation didn't fill the whole internal representation data buffer");
			}

			log << tcu::TestLog::Section(irs[irNdx].name, irs[irNdx].description)
				<< tcu::TestLog::Message << "Received " << irs[irNdx].dataSize << "B of binary data" << tcu::TestLog::EndMessage
				<< tcu::TestLog::EndSection;
		}
	}

	return tcu::TestStatus::pass("Pass");
}

tcu::TestStatus ExecutablePropertiesTestInstance::verifyTestResult (void)
{
	const DeviceInterface&		vk			= m_context.getDeviceInterface();
	const VkDevice				vkDevice	= m_context.getDevice();
	tcu::TestLog				&log		= m_context.getTestContext().getLog();

	std::vector<VkPipelineExecutablePropertiesKHR> props[PIPELINE_CACHE_NDX_COUNT];

	for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
	{
		const VkPipelineInfoKHR pipelineInfo =
		{
			VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR,	// VkStructureType					sType;
			DE_NULL,								// const void*						pNext;
			m_pipeline[ndx],						// VkPipeline						pipeline;

		};
		deUint32 executableCount = 0;
		VK_CHECK(vk.getPipelineExecutablePropertiesKHR(vkDevice, &pipelineInfo, &executableCount, DE_NULL));

		if (executableCount == 0)
		{
			continue;
		}

		props[ndx].resize(executableCount);
		for (deUint32 execNdx = 0; execNdx < executableCount; execNdx++)
		{
			deMemset(&props[ndx][execNdx], 0, sizeof(props[ndx][execNdx]));
			props[ndx][execNdx].sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_PROPERTIES_KHR;
			props[ndx][execNdx].pNext = DE_NULL;
		}
		VK_CHECK(vk.getPipelineExecutablePropertiesKHR(vkDevice, &pipelineInfo, &executableCount, &props[ndx][0]));

		for (deUint32 execNdx = 0; execNdx < executableCount; execNdx++)
		{
			if (!checkString(props[ndx][execNdx].name, DE_LENGTH_OF_ARRAY(props[ndx][execNdx].name)))
			{
				return tcu::TestStatus::fail("Invalid binary name string");
			}

			for (deUint32 otherNdx = 0; otherNdx < execNdx; otherNdx++)
			{
				if (deMemCmp(props[ndx][execNdx].name, props[ndx][otherNdx].name,
							 DE_LENGTH_OF_ARRAY(props[ndx][execNdx].name)) == 0)
				{
					return tcu::TestStatus::fail("Binary name string not unique within the pipeline");
				}
			}

			if (!checkString(props[ndx][execNdx].description, DE_LENGTH_OF_ARRAY(props[ndx][execNdx].description)))
			{
				return tcu::TestStatus::fail("Invalid binary description string");
			}

			// Check that the binary only contains stages actually used to
			// compile the pipeline
			VkShaderStageFlags stages = props[ndx][execNdx].stages;
			for (deUint32 stageNdx = 0; stageNdx < m_param->getShaderCount(); stageNdx++)
			{
				stages &= ~m_param->getShaderFlag(stageNdx);
			}
			if (stages != 0)
			{
				return tcu::TestStatus::fail("Binary uses unprovided stage");
			}
		}
	}

	if (props[0].size() != props[1].size())
	{
		return tcu::TestStatus::fail("Identical pipelines have different numbers of props");
	}

	if (props[0].size() == 0)
	{
		return tcu::TestStatus::pass("No executables reported");
	}

	// Both compiles had better have specified the same infos
	for (deUint32 execNdx0 = 0; execNdx0 < props[0].size(); execNdx0++)
	{
		deUint32 execNdx1 = 0;
		for (; execNdx1 < props[1].size(); execNdx1++)
		{
			if (deMemCmp(props[0][execNdx0].name, props[1][execNdx1].name,
						 DE_LENGTH_OF_ARRAY(props[0][execNdx0].name)) == 0)
			{
				break;
			}
		}
		if (execNdx1 >= props[1].size())
		{
			return tcu::TestStatus::fail("Identical pipelines have different sets of executables");
		}

		if (deMemCmp(props[0][execNdx0].description, props[1][execNdx1].description,
					 DE_LENGTH_OF_ARRAY(props[0][execNdx0].description)) != 0)
		{
			return tcu::TestStatus::fail("Same binary has different descriptions");
		}

		if (props[0][execNdx0].stages != props[1][execNdx1].stages)
		{
			return tcu::TestStatus::fail("Same binary has different stages");
		}

		if (props[0][execNdx0].subgroupSize != props[1][execNdx1].subgroupSize)
		{
			return tcu::TestStatus::fail("Same binary has different subgroup sizes");
		}
	}

	log << tcu::TestLog::Section("Binaries", "Binaries reported for this pipeline");
	log << tcu::TestLog::Message << "Pipeline reported " << props[0].size() << " props" << tcu::TestLog::EndMessage;

	tcu::TestStatus status = tcu::TestStatus::pass("Pass");
	for (deUint32 execNdx = 0; execNdx < props[0].size(); execNdx++)
	{
		log << tcu::TestLog::Section(props[0][execNdx].name, props[0][execNdx].description);
		log << tcu::TestLog::Message << "Name: " << props[0][execNdx].name << tcu::TestLog::EndMessage;
		log << tcu::TestLog::Message << "Description: " << props[0][execNdx].description << tcu::TestLog::EndMessage;
		log << tcu::TestLog::Message << "Stages: " << getShaderFlagsStr(props[0][execNdx].stages) << tcu::TestLog::EndMessage;
		log << tcu::TestLog::Message << "Subgroup Size: " << props[0][execNdx].subgroupSize << tcu::TestLog::EndMessage;

		if (m_param->getTestStatistics())
		{
			status = verifyStatistics(execNdx);
			if (status.getCode() != QP_TEST_RESULT_PASS)
			{
				log << tcu::TestLog::EndSection;
				break;
			}
		}

		if (m_param->getTestInternalRepresentations())
		{
			status = verifyInternalRepresentations(execNdx);
			if (status.getCode() != QP_TEST_RESULT_PASS)
			{
				log << tcu::TestLog::EndSection;
				break;
			}
		}

		log << tcu::TestLog::EndSection;
	}

	log << tcu::TestLog::EndSection;

	return status;
}

class GraphicsExecutablePropertiesTest : public ExecutablePropertiesTest
{
public:
							GraphicsExecutablePropertiesTest	(tcu::TestContext&		testContext,
													 const std::string&	name,
													 const std::string&	description,
													 const ExecutablePropertiesTestParam*	param)
								: ExecutablePropertiesTest (testContext, name, description, param)
								{ }
	virtual					~GraphicsExecutablePropertiesTest	(void) { }
	virtual void			initPrograms		(SourceCollections&	programCollection) const;
	virtual TestInstance*	createInstance		(Context&				context) const;
};

class GraphicsExecutablePropertiesTestInstance : public ExecutablePropertiesTestInstance
{
public:
							GraphicsExecutablePropertiesTestInstance	(Context&				context,
															 const ExecutablePropertiesTestParam*	param);
	virtual					~GraphicsExecutablePropertiesTestInstance	(void);
protected:
	const tcu::UVec2					m_renderSize;
	const VkFormat						m_colorFormat;
	const VkFormat						m_depthFormat;
	Move<VkPipelineLayout>				m_pipelineLayout;

	SimpleGraphicsPipelineBuilder		m_pipelineBuilder;
	SimpleGraphicsPipelineBuilder		m_missPipelineBuilder;
	Move<VkRenderPass>					m_renderPass;
};

void GraphicsExecutablePropertiesTest::initPrograms (SourceCollections& programCollection) const
{
	for (deUint32 shaderNdx = 0; shaderNdx < m_param.getShaderCount(); shaderNdx++)
	{
		switch(m_param.getShaderFlag(shaderNdx))
		{
		case VK_SHADER_STAGE_VERTEX_BIT:
			programCollection.glslSources.add("color_vert") << glu::VertexSource(
						"#version 310 es\n"
						"layout(location = 0) in vec4 position;\n"
						"layout(location = 1) in vec4 color;\n"
						"layout(location = 0) out highp vec4 vtxColor;\n"
						"void main (void)\n"
						"{\n"
						"  gl_Position = position;\n"
						"  vtxColor = color;\n"
						"}\n");
					break;
		case VK_SHADER_STAGE_FRAGMENT_BIT:
			programCollection.glslSources.add("color_frag") << glu::FragmentSource(
						"#version 310 es\n"
						"layout(location = 0) in highp vec4 vtxColor;\n"
						"layout(location = 0) out highp vec4 fragColor;\n"
						"void main (void)\n"
						"{\n"
						"  fragColor = vtxColor;\n"
						"}\n");
			break;

		case VK_SHADER_STAGE_GEOMETRY_BIT:
			programCollection.glslSources.add("dummy_geo") << glu::GeometrySource(
						"#version 450 \n"
						"layout(triangles) in;\n"
						"layout(triangle_strip, max_vertices = 3) out;\n"
						"layout(location = 0) in highp vec4 in_vtxColor[];\n"
						"layout(location = 0) out highp vec4 vtxColor;\n"
						"out gl_PerVertex { vec4 gl_Position; float gl_PointSize; };\n"
						"in gl_PerVertex { vec4 gl_Position; float gl_PointSize; } 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"
						"    gl_PointSize = gl_in[ndx].gl_PointSize;\n"
						"    vtxColor    = in_vtxColor[ndx];\n"
						"    EmitVertex();\n"
						"  }\n"
						"  EndPrimitive();\n"
						"}\n");
			break;

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

				case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
					programCollection.glslSources.add("basic_tes") << glu::TessellationEvaluationSource(
						"#version 450 \n"
						"layout(triangles, fractional_even_spacing, ccw) in;\n"
						"layout(location = 0) in highp vec4 colors[];\n"
						"layout(location = 0) out highp vec4 vtxColor;\n"
						"out gl_PerVertex { vec4 gl_Position; float gl_PointSize; };\n"
						"in gl_PerVertex { vec4 gl_Position; float gl_PointSize; } 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);\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"
						"  gl_PointSize = gl_in[0].gl_PointSize;"
						"  vtxColor = color;\n"
						"}\n");
					break;

				default:
					DE_FATAL("Unknown Shader Stage!");
					break;
		};
	}
}

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

GraphicsExecutablePropertiesTestInstance::GraphicsExecutablePropertiesTestInstance (Context&					context,
																const ExecutablePropertiesTestParam*	param)
	: ExecutablePropertiesTestInstance		(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 pipeline layout
	{
		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
		{
			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
			DE_NULL,											// const void*						pNext;
			0u,													// VkPipelineLayoutCreateFlags		flags;
			0u,													// deUint32							setLayoutCount;
			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
			0u,													// deUint32							pushConstantRangeCount;
			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
		};

		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
	}

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

	// Bind shader stages

	VkPhysicalDeviceFeatures	features = m_context.getDeviceFeatures();
	for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
	{
		for (deUint32 shaderNdx = 0; shaderNdx < m_param->getShaderCount(); shaderNdx++)
		{
			switch(m_param->getShaderFlag(shaderNdx))
			{
			case VK_SHADER_STAGE_VERTEX_BIT:
				m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_VERTEX_BIT, "color_vert", "main");
				break;
			case VK_SHADER_STAGE_FRAGMENT_BIT:
				m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_FRAGMENT_BIT, "color_frag", "main");
				break;
			case VK_SHADER_STAGE_GEOMETRY_BIT:
				if (features.geometryShader == VK_FALSE)
				{
					TCU_THROW(NotSupportedError, "Geometry Shader Not Supported");
				}
				else
				{
					m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_GEOMETRY_BIT, "dummy_geo", "main");
				}
				break;
			case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
				if (features.tessellationShader == VK_FALSE)
				{
					TCU_THROW(NotSupportedError, "Tessellation Not Supported");
				}
				else
				{
					m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "basic_tcs", "main");
					m_pipelineBuilder.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);
				}
				break;
			default:
				DE_FATAL("Unknown Shader Stage!");
				break;
			};

		}

		VkPipelineCreateFlags flags = 0;
		if (param->getTestStatistics())
		{
			flags |= VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR;
		}

		// Only check gather internal representations on the second
		// pipeline.  This way, it's more obvious if they failed to capture
		// due to the pipeline being cached.
		if (ndx == PIPELINE_CACHE_NDX_CACHED && param->getTestInternalRepresentations())
		{
			flags |= VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR;
		}

		m_pipeline[ndx] = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass, *m_cache, *m_pipelineLayout, flags);
		m_pipelineBuilder.resetBuilder();
	}
}

GraphicsExecutablePropertiesTestInstance::~GraphicsExecutablePropertiesTestInstance (void)
{
}

class ComputeExecutablePropertiesTest : public ExecutablePropertiesTest
{
public:
							ComputeExecutablePropertiesTest	(tcu::TestContext&		testContext,
													 const std::string&		name,
													 const std::string&		description,
													 const ExecutablePropertiesTestParam*	param)
								: ExecutablePropertiesTest	(testContext, name, description, param)
								{ }
	virtual					~ComputeExecutablePropertiesTest	(void) { }
	virtual void			initPrograms			(SourceCollections&	programCollection) const;
	virtual TestInstance*	createInstance			(Context&				context) const;
};

class ComputeExecutablePropertiesTestInstance : public ExecutablePropertiesTestInstance
{
public:
							ComputeExecutablePropertiesTestInstance	(Context&				context,
															 const ExecutablePropertiesTestParam*	param);
	virtual					~ComputeExecutablePropertiesTestInstance	(void);
protected:
	void					buildDescriptorSets				(deUint32 ndx);
	void					buildShader						(deUint32 ndx);
	void					buildPipeline					(deUint32 ndx);
protected:
	Move<VkBuffer>					m_inputBuf;
	de::MovePtr<Allocation>		m_inputBufferAlloc;
	Move<VkShaderModule>			m_computeShaderModule[PIPELINE_CACHE_NDX_COUNT];

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

void ComputeExecutablePropertiesTest::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* ComputeExecutablePropertiesTest::createInstance (Context& context) const
{
	return new ComputeExecutablePropertiesTestInstance(context, &m_param);
}

void ComputeExecutablePropertiesTestInstance::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);
}

void ComputeExecutablePropertiesTestInstance::buildShader (deUint32 ndx)
{
	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[ndx] = createShaderModule(vk, vkDevice, &shaderModuleCreateInfo);
}

void ComputeExecutablePropertiesTestInstance::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[ndx],									// VkShaderModule					module;
		"main",															// const char*						pName;
		DE_NULL,														// const VkSpecializationInfo*		pSpecializationInfo;
	};

	VkPipelineCreateFlags flags = 0;
	if (m_param->getTestStatistics())
	{
		flags |= VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR;
	}

	// Only check gather internal representations on the second
	// pipeline.  This way, it's more obvious if they failed to capture
	// due to the pipeline being cached.
	if (ndx == PIPELINE_CACHE_NDX_CACHED && m_param->getTestInternalRepresentations())
	{
		flags |= VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR;
	}

	const VkComputePipelineCreateInfo pipelineCreateInfo =
	{
		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,				// VkStructureType					sType;
		DE_NULL,													// const void*						pNext;
		flags,														// VkPipelineCreateFlags			flags;
		stageCreateInfo,											// VkPipelineShaderStageCreateInfo	stage;
		*m_pipelineLayout[ndx],										// VkPipelineLayout					layout;
		(VkPipeline)0,												// VkPipeline						basePipelineHandle;
		0u,															// deInt32							basePipelineIndex;
	};

	vk.createComputePipelines(vkDevice, *m_cache, 1u, &pipelineCreateInfo, DE_NULL, &m_pipeline[ndx]);
}

ComputeExecutablePropertiesTestInstance::ComputeExecutablePropertiesTestInstance (Context&				context,
													const ExecutablePropertiesTestParam*	param)
	: ExecutablePropertiesTestInstance (context, param)
{
	for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
	{
		buildDescriptorSets(ndx);
		buildShader(ndx);
		buildPipeline(ndx);
	}
}

ComputeExecutablePropertiesTestInstance::~ComputeExecutablePropertiesTestInstance (void)
{
}

} // anonymous

tcu::TestCaseGroup* createExecutablePropertiesTests (tcu::TestContext& testCtx)
{

	de::MovePtr<tcu::TestCaseGroup> binaryInfoTests (new tcu::TestCaseGroup(testCtx, "executable_properties", "pipeline binary statistics tests"));

	// Graphics Pipeline Tests
	{
		de::MovePtr<tcu::TestCaseGroup> graphicsTests (new tcu::TestCaseGroup(testCtx, "graphics", "Test pipeline binary info 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 ExecutablePropertiesTestParam testParams[] =
		{
			ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE, DE_FALSE),
			ExecutablePropertiesTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), DE_FALSE, DE_FALSE),
			ExecutablePropertiesTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), DE_FALSE, DE_FALSE),
			ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_TRUE, DE_FALSE),
			ExecutablePropertiesTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), DE_TRUE, DE_FALSE),
			ExecutablePropertiesTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), DE_TRUE, DE_FALSE),
			ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE, DE_TRUE),
			ExecutablePropertiesTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), DE_FALSE, DE_TRUE),
			ExecutablePropertiesTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), DE_FALSE, DE_TRUE),
			ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_TRUE, DE_TRUE),
			ExecutablePropertiesTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), DE_TRUE, DE_TRUE),
			ExecutablePropertiesTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), DE_TRUE, DE_TRUE),
		};

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

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

	// Compute Pipeline Tests
	{
		de::MovePtr<tcu::TestCaseGroup> computeTests (new tcu::TestCaseGroup(testCtx, "compute", "Test pipeline binary info with compute pipeline."));

		const VkShaderStageFlagBits testParamShaders0[] =
		{
			VK_SHADER_STAGE_COMPUTE_BIT,
		};
		const ExecutablePropertiesTestParam testParams[] =
		{
			ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE, DE_FALSE),
			ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_TRUE, DE_FALSE),
			ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE, DE_TRUE),
			ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_TRUE, DE_TRUE),
		};

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

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

	return binaryInfoTests.release();
}

} // pipeline

} // vkt
