/*------------------------------------------------------------------------
 * 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 Timestamp Tests
 *//*--------------------------------------------------------------------*/

#include "vktPipelineTimestampTests.hpp"
#include "vktPipelineClearUtil.hpp"
#include "vktPipelineImageUtil.hpp"
#include "vktPipelineVertexUtil.hpp"
#include "vktPipelineReferenceRenderer.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 "deStringUtil.hpp"
#include "deMemory.h"

#include <sstream>
#include <vector>
#include <set>
#include <cctype>
#include <locale>
#include <limits>
#include <thread>
#include <chrono>
#include <time.h>
#include <algorithm>

#if (DE_OS == DE_OS_WIN32)
#	define VC_EXTRALEAN
#	define WIN32_LEAN_AND_MEAN
#	define NOMINMAX
#	include <windows.h>
#endif

namespace vkt
{
namespace pipeline
{

using namespace vk;

namespace
{
typedef std::vector<VkPipelineStageFlagBits> StageFlagVector;

// helper functions
#define GEN_DESC_STRING(name,postfix)                                      \
		do {                                                               \
		   for (std::string::size_type ndx = 0; ndx<strlen(#name); ++ndx)  \
			 if(isDescription && #name[ndx] == '_')                        \
			   desc << " ";                                                \
			 else                                                          \
			   desc << std::tolower(#name[ndx],loc);                       \
		   if (isDescription)                                              \
			 desc << " " << #postfix;                                      \
		   else                                                            \
			 desc << "_" << #postfix;                                      \
		} while (deGetFalse())

std::string getPipelineStageFlagStr (const VkPipelineStageFlagBits stage,
									 bool                          isDescription)
{
	std::ostringstream desc;
	std::locale loc;
	switch(stage)
	{
#define STAGE_CASE(p)                              \
		case VK_PIPELINE_STAGE_##p##_BIT:          \
		{                                          \
			GEN_DESC_STRING(p, stage);             \
			break;                                 \
		}
		STAGE_CASE(TOP_OF_PIPE);
		STAGE_CASE(DRAW_INDIRECT);
		STAGE_CASE(VERTEX_INPUT);
		STAGE_CASE(VERTEX_SHADER);
		STAGE_CASE(TESSELLATION_CONTROL_SHADER);
		STAGE_CASE(TESSELLATION_EVALUATION_SHADER);
		STAGE_CASE(GEOMETRY_SHADER);
		STAGE_CASE(FRAGMENT_SHADER);
		STAGE_CASE(EARLY_FRAGMENT_TESTS);
		STAGE_CASE(LATE_FRAGMENT_TESTS);
		STAGE_CASE(COLOR_ATTACHMENT_OUTPUT);
		STAGE_CASE(COMPUTE_SHADER);
		STAGE_CASE(TRANSFER);
		STAGE_CASE(HOST);
		STAGE_CASE(ALL_GRAPHICS);
		STAGE_CASE(ALL_COMMANDS);
#undef STAGE_CASE
	  default:
		desc << "unknown stage!";
		DE_FATAL("Unknown Stage!");
		break;
	};

	return desc.str();
}

enum TransferMethod
{
	TRANSFER_METHOD_COPY_BUFFER = 0,
	TRANSFER_METHOD_COPY_IMAGE,
	TRANSFER_METHOD_BLIT_IMAGE,
	TRANSFER_METHOD_COPY_BUFFER_TO_IMAGE,
	TRANSFER_METHOD_COPY_IMAGE_TO_BUFFER,
	TRANSFER_METHOD_UPDATE_BUFFER,
	TRANSFER_METHOD_FILL_BUFFER,
	TRANSFER_METHOD_CLEAR_COLOR_IMAGE,
	TRANSFER_METHOD_CLEAR_DEPTH_STENCIL_IMAGE,
	TRANSFER_METHOD_RESOLVE_IMAGE,
	TRANSFER_METHOD_COPY_QUERY_POOL_RESULTS,
	TRANSFER_METHOD_LAST
};

std::string getTransferMethodStr (const TransferMethod	method,
								  bool					isDescription)
{
	std::ostringstream	desc;
	std::locale			loc;

	switch(method)
	{
#define METHOD_CASE(p)                             \
		case TRANSFER_METHOD_##p:                  \
		{                                          \
			GEN_DESC_STRING(p, method);            \
			break;                                 \
		}
	  METHOD_CASE(COPY_BUFFER)
	  METHOD_CASE(COPY_IMAGE)
	  METHOD_CASE(BLIT_IMAGE)
	  METHOD_CASE(COPY_BUFFER_TO_IMAGE)
	  METHOD_CASE(COPY_IMAGE_TO_BUFFER)
	  METHOD_CASE(UPDATE_BUFFER)
	  METHOD_CASE(FILL_BUFFER)
	  METHOD_CASE(CLEAR_COLOR_IMAGE)
	  METHOD_CASE(CLEAR_DEPTH_STENCIL_IMAGE)
	  METHOD_CASE(RESOLVE_IMAGE)
	  METHOD_CASE(COPY_QUERY_POOL_RESULTS)
#undef METHOD_CASE
	  default:
		desc << "unknown method!";
		DE_FATAL("Unknown method!");
		break;
	};

	return desc.str();
}

constexpr deUint32 MIN_TIMESTAMP_VALID_BITS = 36;
constexpr deUint32 MAX_TIMESTAMP_VALID_BITS = 64;

// Checks the number of valid bits for the given queue meets the spec requirements.
void checkValidBits (deUint32 validBits, deUint32 queueFamilyIndex)
{
	if (validBits < MIN_TIMESTAMP_VALID_BITS || validBits > MAX_TIMESTAMP_VALID_BITS)
	{
		std::ostringstream msg;
		msg << "Invalid value for timestampValidBits (" << validBits << ") in queue index " << queueFamilyIndex;
		TCU_FAIL(msg.str());
	}
}

// Returns the timestamp mask given the number of valid timestamp bits.
deUint64 timestampMaskFromValidBits (deUint32 validBits)
{
	return ((validBits == MAX_TIMESTAMP_VALID_BITS) ? std::numeric_limits<deUint64>::max() : ((1ULL << validBits) - 1));
}

// Checks support for timestamps and returns the timestamp mask.
deUint64 checkTimestampsSupported (Context& context)
{
	const InstanceInterface&					vki					= context.getInstanceInterface();
	const VkPhysicalDevice						physDevice			= context.getPhysicalDevice();
	const deUint32								queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
	const std::vector<VkQueueFamilyProperties>	queueProperties		= vk::getPhysicalDeviceQueueFamilyProperties(vki, physDevice);
	DE_ASSERT(queueFamilyIndex < queueProperties.size());
	const deUint32&								validBits			= queueProperties[queueFamilyIndex].timestampValidBits;

	if (validBits == 0)
		throw tcu::NotSupportedError("Universal queue does not support timestamps");

	checkValidBits(validBits, queueFamilyIndex);
	return timestampMaskFromValidBits(validBits);
}

void checkTimestampBits (deUint64 timestamp, deUint64 mask)
{
	// The spec says:
	// timestampValidBits is the unsigned integer count of meaningful bits in
	// the timestamps written via vkCmdWriteTimestamp. The valid range for the
	// count is 36..64 bits, or a value of 0, indicating no support for
	// timestamps. Bits outside the valid range are guaranteed to be zeros.
	if (timestamp > mask)
	{
		std::ostringstream msg;
		msg << std::hex << "Invalid device timestamp value 0x" << timestamp << " according to device timestamp mask 0x" << mask;
		TCU_FAIL(msg.str());
	}
}

// helper classes
class TimestampTestParam
{
public:
								TimestampTestParam		(const VkPipelineStageFlagBits*	stages,
														 const deUint32					stageCount,
														 const bool						inRenderPass,
														 const bool						hostQueryReset);
								~TimestampTestParam		(void);
	virtual const std::string	generateTestName		(void) const;
	virtual const std::string	generateTestDescription	(void) const;
	StageFlagVector				getStageVector			(void) const	{ return m_stageVec; }
	bool						getInRenderPass			(void) const	{ return m_inRenderPass; }
	bool						getHostQueryReset		(void) const	{ return m_hostQueryReset; }
	void						toggleInRenderPass		(void)			{ m_inRenderPass = !m_inRenderPass; }
	void						toggleHostQueryReset	(void)			{ m_hostQueryReset = !m_hostQueryReset; }
protected:
	StageFlagVector				m_stageVec;
	bool						m_inRenderPass;
	bool						m_hostQueryReset;
};

TimestampTestParam::TimestampTestParam (const VkPipelineStageFlagBits*	stages,
									    const deUint32					stageCount,
									    const bool						inRenderPass,
									    const bool						hostQueryReset)
	: m_inRenderPass(inRenderPass)
	, m_hostQueryReset(hostQueryReset)
{
	for (deUint32 ndx = 0; ndx < stageCount; ndx++)
	{
		m_stageVec.push_back(stages[ndx]);
	}
}

TimestampTestParam::~TimestampTestParam (void)
{
}

const std::string TimestampTestParam::generateTestName (void) const
{
	std::string result("");

	for (StageFlagVector::const_iterator it = m_stageVec.begin(); it != m_stageVec.end(); it++)
	{
		if(*it != VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
		{
			result += getPipelineStageFlagStr(*it, false) + '_';
		}
	}
	if(m_inRenderPass)
		result += "in_render_pass";
	else
		result += "out_of_render_pass";

	if(m_hostQueryReset)
		result += "_host_query_reset";

	return result;
}

const std::string TimestampTestParam::generateTestDescription (void) const
{
	std::string result("Record timestamp after ");

	for (StageFlagVector::const_iterator it = m_stageVec.begin(); it != m_stageVec.end(); it++)
	{
		if(*it != VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
		{
			result += getPipelineStageFlagStr(*it, true) + ' ';
		}
	}
	if(m_inRenderPass)
		result += " in the renderpass";
	else
		result += " out of the render pass";

	if(m_hostQueryReset)
		result += "and the host resets query pool";

	return result;
}

class TransferTimestampTestParam : public TimestampTestParam
{
public:
						TransferTimestampTestParam	(const VkPipelineStageFlagBits*	stages,
													 const deUint32					stageCount,
													 const bool						inRenderPass,
													 const bool						hostQueryReset,
													 const deUint32					methodNdx);
						~TransferTimestampTestParam	(void) { }
	const std::string	generateTestName			(void) const;
	const std::string	generateTestDescription		(void) const;
	TransferMethod		getMethod					(void) const { return m_method; }
protected:
	TransferMethod		m_method;
};

TransferTimestampTestParam::TransferTimestampTestParam (const VkPipelineStageFlagBits*	stages,
													    const deUint32					stageCount,
													    const bool						inRenderPass,
													    const bool						hostQueryReset,
													    const deUint32					methodNdx)
	: TimestampTestParam(stages, stageCount, inRenderPass, hostQueryReset)
{
	DE_ASSERT(methodNdx < (deUint32)TRANSFER_METHOD_LAST);

	m_method = (TransferMethod)methodNdx;
}

const std::string TransferTimestampTestParam::generateTestName (void) const
{
	std::string result("");

	for (StageFlagVector::const_iterator it = m_stageVec.begin(); it != m_stageVec.end(); it++)
	{
		if(*it != VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
		{
			result += getPipelineStageFlagStr(*it, false) + '_';
		}
	}

	result += "with_" + getTransferMethodStr(m_method, false);

	if(m_hostQueryReset)
		result += "_host_query_reset";

	return result;
}

const std::string TransferTimestampTestParam::generateTestDescription (void) const
{
	std::string result("");

	for (StageFlagVector::const_iterator it = m_stageVec.begin(); it != m_stageVec.end(); it++)
	{
		if(*it != VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)
		{
			result += getPipelineStageFlagStr(*it, true) + ' ';
		}
	}

	result += "with " + getTransferMethodStr(m_method, true);

	if(m_hostQueryReset)
		result += "and the host resets query pool";

	return result;
}

class TwoCmdBuffersTestParam : public TimestampTestParam
{
public:
							TwoCmdBuffersTestParam	(const VkPipelineStageFlagBits*	stages,
													 const deUint32					stageCount,
													 const bool						inRenderPass,
													 const bool						hostQueryReset,
													 const VkCommandBufferLevel		cmdBufferLevel);
							~TwoCmdBuffersTestParam	(void) { }
	VkCommandBufferLevel	getCmdBufferLevel		(void) const { return m_cmdBufferLevel; }
protected:
	VkCommandBufferLevel	m_cmdBufferLevel;
};

TwoCmdBuffersTestParam::TwoCmdBuffersTestParam	(const VkPipelineStageFlagBits*	stages,
												 const deUint32					stageCount,
												 const bool						inRenderPass,
												 const bool						hostQueryReset,
												 const VkCommandBufferLevel		cmdBufferLevel)
: TimestampTestParam(stages, stageCount, inRenderPass, hostQueryReset), m_cmdBufferLevel(cmdBufferLevel)
{
}

class SimpleGraphicsPipelineBuilder
{
public:
						 SimpleGraphicsPipelineBuilder  (Context& context);
						 ~SimpleGraphicsPipelineBuilder (void) { }

	void				bindShaderStage					(VkShaderStageFlagBits	stage,
														 const char*			source_name);

	void				enableTessellationStage			(deUint32              patchControlPoints);

	Move<VkPipeline>	buildPipeline					(tcu::UVec2            renderSize,
														 VkRenderPass          renderPass);
protected:
	enum
	{
		VK_MAX_SHADER_STAGES = 6,
	};

	Context&				m_context;

	Move<VkShaderModule>	m_shaderModules[VK_MAX_SHADER_STAGES];
	deUint32				m_shaderStageCount;
	VkShaderStageFlagBits	m_shaderStages[VK_MAX_SHADER_STAGES];

	deUint32				m_patchControlPoints;

	Move<VkPipelineLayout>	m_pipelineLayout;
	Move<VkPipeline>		m_graphicsPipelines;

};

SimpleGraphicsPipelineBuilder::SimpleGraphicsPipelineBuilder(Context& context)
	: m_context(context)
{
	m_patchControlPoints = 0;
	m_shaderStageCount   = 0;
}

void SimpleGraphicsPipelineBuilder::bindShaderStage (VkShaderStageFlagBits	stage,
													 const char*			source_name)
{
	const DeviceInterface&	vk			= m_context.getDeviceInterface();
	const VkDevice			vkDevice	= m_context.getDevice();

	// Create shader module
	deUint32*				pCode		= (deUint32*)m_context.getBinaryCollection().get(source_name).getBinary();
	deUint32				codeSize	= (deUint32)m_context.getBinaryCollection().get(source_name).getSize();

	const VkShaderModuleCreateInfo moduleCreateInfo =
	{
		VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,	// VkStructureType             sType;
		DE_NULL,										// const void*                 pNext;
		0u,												// VkShaderModuleCreateFlags   flags;
		codeSize,										// deUintptr                   codeSize;
		pCode,											// const deUint32*             pCode;
	};

	m_shaderModules[m_shaderStageCount] = createShaderModule(vk, vkDevice, &moduleCreateInfo);
	m_shaderStages[m_shaderStageCount] = stage;

	m_shaderStageCount++;
}

Move<VkPipeline> SimpleGraphicsPipelineBuilder::buildPipeline (tcu::UVec2 renderSize, VkRenderPass renderPass)
{
	const DeviceInterface&	vk						= m_context.getDeviceInterface();
	const VkDevice			vkDevice				= m_context.getDevice();
	VkShaderModule			vertShaderModule		= DE_NULL;
	VkShaderModule			tessControlShaderModule	= DE_NULL;
	VkShaderModule			tessEvalShaderModule	= DE_NULL;
	VkShaderModule			geomShaderModule		= DE_NULL;
	VkShaderModule			fragShaderModule		= DE_NULL;

	for (deUint32 i = 0; i < m_shaderStageCount; i++)
	{
		if (m_shaderStages[i] == VK_SHADER_STAGE_VERTEX_BIT)
			vertShaderModule = *m_shaderModules[i];
		else if (m_shaderStages[i] == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
			tessControlShaderModule = *m_shaderModules[i];
		else if (m_shaderStages[i] == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
			tessEvalShaderModule = *m_shaderModules[i];
		else if (m_shaderStages[i] == VK_SHADER_STAGE_GEOMETRY_BIT)
			geomShaderModule = *m_shaderModules[i];
		else if (m_shaderStages[i] == VK_SHADER_STAGE_FRAGMENT_BIT)
			fragShaderModule = *m_shaderModules[i];
	}

	// Create pipeline layout
	{
		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
		{
			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType                  sType;
			DE_NULL,										// const void*                      pNext;
			0u,												// VkPipelineLayoutCreateFlags      flags;
			0u,												// deUint32                         setLayoutCount;
			DE_NULL,										// const VkDescriptorSetLayout*     pSetLayouts;
			0u,												// deUint32                         pushConstantRangeCount;
			DE_NULL											// const VkPushConstantRange*       pPushConstantRanges;
		};

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

	// Create pipeline
	const VkVertexInputBindingDescription vertexInputBindingDescription =
	{
		0u,								// deUint32                 binding;
		sizeof(Vertex4RGBA),			// deUint32                 strideInBytes;
		VK_VERTEX_INPUT_RATE_VERTEX,	// VkVertexInputRate        inputRate;
	};

	const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
	{
		{
			0u,									// deUint32 location;
			0u,									// deUint32 binding;
			VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat format;
			0u									// deUint32 offsetInBytes;
		},
		{
			1u,									// deUint32 location;
			0u,									// deUint32 binding;
			VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat format;
			DE_OFFSET_OF(Vertex4RGBA, color),	// deUint32 offsetInBytes;
		}
	};

	const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType                          sType;
		DE_NULL,													// const void*                              pNext;
		0u,															// VkPipelineVertexInputStateCreateFlags    flags;
		1u,															// deUint32                                 vertexBindingDescriptionCount;
		&vertexInputBindingDescription,								// const VkVertexInputBindingDescription*   pVertexBindingDescriptions;
		2u,															// deUint32                                 vertexAttributeDescriptionCount;
		vertexInputAttributeDescriptions,							// const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
	};

	VkPrimitiveTopology primitiveTopology = (m_patchControlPoints > 0) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;

	const std::vector<VkViewport>	viewports	(1, makeViewport(renderSize));
	const std::vector<VkRect2D>		scissors	(1, makeRect2D(renderSize));

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

	return makeGraphicsPipeline(vk,							// const DeviceInterface&                        vk
								vkDevice,					// const VkDevice                                device
								*m_pipelineLayout,			// const VkPipelineLayout                        pipelineLayout
								vertShaderModule,			// const VkShaderModule                          vertexShaderModule
								tessControlShaderModule,	// const VkShaderModule                          tessellationControlModule
								tessEvalShaderModule,		// const VkShaderModule                          tessellationEvalModule
								geomShaderModule,			// const VkShaderModule                          geometryShaderModule
								fragShaderModule,			// const VkShaderModule                          fragmentShaderModule
								renderPass,					// const VkRenderPass                            renderPass
								viewports,					// const std::vector<VkViewport>&                viewports
								scissors,					// const std::vector<VkRect2D>&                  scissors
								primitiveTopology,			// const VkPrimitiveTopology                     topology
								0u,							// const deUint32                                subpass
								m_patchControlPoints,		// const deUint32                                patchControlPoints
								&vertexInputStateParams,	// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
								DE_NULL,					// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
								DE_NULL,					// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
								&depthStencilStateParams);	// const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
}

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

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

// Test Classes
class TimestampTest : public vkt::TestCase
{
public:
	enum
	{
		ENTRY_COUNT = 8
	};

							TimestampTest	(tcu::TestContext&			testContext,
											 const std::string&			name,
											 const std::string&			description,
											 const TimestampTestParam*	param)
											 : vkt::TestCase	(testContext, name, description)
											 , m_stages			(param->getStageVector())
											 , m_inRenderPass	(param->getInRenderPass())
											 , m_hostQueryReset	(param->getHostQueryReset())
											 { }
	virtual					~TimestampTest	(void) { }
	virtual void			initPrograms	(SourceCollections& programCollection) const;
	virtual TestInstance*	createInstance	(Context& context) const;
	virtual void			checkSupport	(Context& context) const;
protected:
	const StageFlagVector	m_stages;
	const bool				m_inRenderPass;
	const bool				m_hostQueryReset;
};

class TimestampTestInstance : public vkt::TestInstance
{
public:
							TimestampTestInstance		(Context&				context,
														 const StageFlagVector&	stages,
														 const bool				inRenderPass,
														 const bool				hostQueryReset);

	virtual					~TimestampTestInstance		(void);
	virtual tcu::TestStatus	iterate						(void);

protected:
	virtual tcu::TestStatus	verifyTimestamp				(void);
	virtual void            configCommandBuffer			(void);

	Move<VkBuffer>			createBufferAndBindMemory	(VkDeviceSize				size,
														 VkBufferUsageFlags			usage,
														 de::MovePtr<Allocation>*	pAlloc);

	Move<VkImage>			createImage2DAndBindMemory	(VkFormat					format,
														 deUint32					width,
														 deUint32					height,
														 VkImageUsageFlags			usage,
														 VkSampleCountFlagBits		sampleCount,
														 de::MovePtr<Allocation>*	pAlloc);

protected:
	const StageFlagVector	m_stages;
	bool					m_inRenderPass;
	bool					m_hostQueryReset;

	Move<VkCommandPool>		m_cmdPool;
	Move<VkCommandBuffer>	m_cmdBuffer;
	Move<VkQueryPool>		m_queryPool;
	deUint64*				m_timestampValues;
	deUint64*				m_timestampValuesHostQueryReset;
	deUint64				m_timestampMask;
};

void TimestampTest::initPrograms (SourceCollections& programCollection) const
{
	vkt::TestCase::initPrograms(programCollection);
}

void TimestampTest::checkSupport (Context& context) const
{
	// Check support for timestamp queries
	{
		const deUint32								queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
		const std::vector<VkQueueFamilyProperties>	queueProperties		= vk::getPhysicalDeviceQueueFamilyProperties(context.getInstanceInterface(), context.getPhysicalDevice());

		DE_ASSERT(queueFamilyIndex < (deUint32)queueProperties.size());

		if (!queueProperties[queueFamilyIndex].timestampValidBits)
			throw tcu::NotSupportedError("Universal queue does not support timestamps");
	}

	if (m_hostQueryReset)
	{
		// Check VK_EXT_host_query_reset is supported
		context.requireDeviceFunctionality("VK_EXT_host_query_reset");

		if(context.getHostQueryResetFeatures().hostQueryReset == VK_FALSE)
			throw tcu::NotSupportedError("Implementation doesn't support resetting queries from the host");
	}
}

TestInstance* TimestampTest::createInstance (Context& context) const
{
	return new TimestampTestInstance(context,m_stages,m_inRenderPass,m_hostQueryReset);
}

TimestampTestInstance::TimestampTestInstance (Context&					context,
											  const StageFlagVector&	stages,
											  const bool				inRenderPass,
											  const bool				hostQueryReset)
	: TestInstance		(context)
	, m_stages			(stages)
	, m_inRenderPass	(inRenderPass)
	, m_hostQueryReset	(hostQueryReset)
{
	const DeviceInterface&	vk					= context.getDeviceInterface();
	const VkDevice			vkDevice			= context.getDevice();
	const deUint32			queueFamilyIndex	= context.getUniversalQueueFamilyIndex();

	m_timestampMask = checkTimestampsSupported(context);

	// Create Query Pool
	{
		const VkQueryPoolCreateInfo queryPoolParams =
		{
		   VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,	// VkStructureType               sType;
		   DE_NULL,										// const void*                   pNext;
		   0u,											// VkQueryPoolCreateFlags        flags;
		   VK_QUERY_TYPE_TIMESTAMP,						// VkQueryType                   queryType;
		   TimestampTest::ENTRY_COUNT,					// deUint32                      entryCount;
		   0u,											// VkQueryPipelineStatisticFlags pipelineStatistics;
		};

		m_queryPool = createQueryPool(vk, vkDevice, &queryPoolParams);
	}

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

	// alloc timestamp values
	m_timestampValues = new deUint64[m_stages.size()];

	if (m_hostQueryReset)
		m_timestampValuesHostQueryReset = new deUint64[m_stages.size() * 2];
	else
		m_timestampValuesHostQueryReset = DE_NULL;
}

TimestampTestInstance::~TimestampTestInstance (void)
{
	delete[] m_timestampValues;
	m_timestampValues = NULL;

	delete[] m_timestampValuesHostQueryReset;
	m_timestampValuesHostQueryReset = NULL;
}

void TimestampTestInstance::configCommandBuffer (void)
{
	const DeviceInterface& vk = m_context.getDeviceInterface();

	beginCommandBuffer(vk, *m_cmdBuffer, 0u);

	if (!m_hostQueryReset)
		vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);

	deUint32 timestampEntry = 0;
	for (const auto& stage : m_stages)
	{
		vk.cmdWriteTimestamp(*m_cmdBuffer, stage, *m_queryPool, timestampEntry++);
	}

	endCommandBuffer(vk, *m_cmdBuffer);
}

tcu::TestStatus TimestampTestInstance::iterate (void)
{
	const DeviceInterface&	vk					= m_context.getDeviceInterface();
	const VkDevice			vkDevice			= m_context.getDevice();
	const VkQueue			queue				= m_context.getUniversalQueue();
	const deUint32			stageSize			= (deUint32)m_stages.size();

	configCommandBuffer();
	if (m_hostQueryReset)
	{
		vk.resetQueryPool(vkDevice, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
	}
	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());

	// Get timestamp value from query pool
	vk.getQueryPoolResults(vkDevice, *m_queryPool, 0u, stageSize, sizeof(deUint64) * stageSize, (void*)m_timestampValues, sizeof(deUint64), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);

	for (deUint32 ndx = 0; ndx < stageSize; ndx++)
	{
		m_timestampValues[ndx] &= m_timestampMask;
	}

	if(m_hostQueryReset)
	{
		// Initialize timestampValuesHostQueryReset values
		deMemset(m_timestampValuesHostQueryReset, 0, sizeof(deUint64) * stageSize * 2);

		for (deUint32 ndx = 0; ndx < stageSize; ndx++)
		{
			m_timestampValuesHostQueryReset[2 * ndx] = m_timestampValues[ndx];
		}

		// Host resets the query pool
		vk.resetQueryPool(vkDevice, *m_queryPool, 0u, stageSize);
		// Get timestamp value from query pool
		vk::VkResult res = vk.getQueryPoolResults(vkDevice, *m_queryPool, 0u, stageSize, sizeof(deUint64) * stageSize * 2, (void*)m_timestampValuesHostQueryReset, sizeof(deUint64) * 2, VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT);

		/* From Vulkan spec:
		 *
		 * If VK_QUERY_RESULT_WAIT_BIT and VK_QUERY_RESULT_PARTIAL_BIT are both not set then no result values are written to pData
		 * for queries that are in the unavailable state at the time of the call, and vkGetQueryPoolResults returns VK_NOT_READY.
		 * However, availability state is still written to pData for those queries if VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is set.
		 */
		if (res != vk::VK_NOT_READY)
			return tcu::TestStatus::fail("QueryPoolResults incorrect reset");

		for (deUint32 ndx = 0; ndx < stageSize; ndx++)
		{
			if ((m_timestampValuesHostQueryReset[2 * ndx] & m_timestampMask) != m_timestampValues[ndx])
				return tcu::TestStatus::fail("QueryPoolResults returned value was modified");
			if (m_timestampValuesHostQueryReset[2 * ndx + 1] != 0u)
				return tcu::TestStatus::fail("QueryPoolResults availability status is not zero");
		}
	}

	return verifyTimestamp();
}

tcu::TestStatus TimestampTestInstance::verifyTimestamp (void)
{
	for (deUint32 first = 0; first < m_stages.size(); first++)
	{
		for (deUint32 second = 0; second < first; second++)
		{
			if(m_timestampValues[first] < m_timestampValues[second])
			{
				return tcu::TestStatus::fail("Latter stage timestamp is smaller than the former stage timestamp.");
			}
		}
	}

	return tcu::TestStatus::pass("Timestamp increases steadily.");
}

Move<VkBuffer> TimestampTestInstance::createBufferAndBindMemory (VkDeviceSize size, VkBufferUsageFlags usage, de::MovePtr<Allocation>* pAlloc)
{
	const DeviceInterface&		vk					= m_context.getDeviceInterface();
	const VkDevice				vkDevice			= m_context.getDevice();
	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
	SimpleAllocator				memAlloc			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));

	const VkBufferCreateInfo	vertexBufferParams	=
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType      sType;
		DE_NULL,								// const void*          pNext;
		0u,										// VkBufferCreateFlags  flags;
		size,									// VkDeviceSize         size;
		usage,									// VkBufferUsageFlags   usage;
		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode        sharingMode;
		1u,										// deUint32             queueFamilyCount;
		&queueFamilyIndex						// const deUint32*      pQueueFamilyIndices;
	};

	Move<VkBuffer> vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
	de::MovePtr<Allocation> vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);

	VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));

	DE_ASSERT(pAlloc);
	*pAlloc = vertexBufferAlloc;

	return vertexBuffer;
}

Move<VkImage> TimestampTestInstance::createImage2DAndBindMemory (VkFormat							format,
																 deUint32							width,
																 deUint32							height,
																 VkImageUsageFlags					usage,
																 VkSampleCountFlagBits				sampleCount,
																 de::details::MovePtr<Allocation>*	pAlloc)
{
	const DeviceInterface&	vk					= m_context.getDeviceInterface();
	const VkDevice			vkDevice			= m_context.getDevice();
	const deUint32			queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
	SimpleAllocator			memAlloc			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));

	// Optimal tiling feature check
	VkFormatProperties		formatProperty;

	m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), format, &formatProperty);

	if((usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) && !(formatProperty.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
	{
		// Remove color attachment usage if the optimal tiling feature does not support it
		usage &= ~VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
	}
	if((usage & VK_IMAGE_USAGE_STORAGE_BIT) && !(formatProperty.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
	{
		// Remove storage usage if the optimal tiling feature does not support it
		usage &= ~VK_IMAGE_USAGE_STORAGE_BIT;
	}

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

	// Allocate and bind image memory
	de::MovePtr<Allocation> colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image), MemoryRequirement::Any);
	VK_CHECK(vk.bindImageMemory(vkDevice, *image, colorImageAlloc->getMemory(), colorImageAlloc->getOffset()));

	DE_ASSERT(pAlloc);
	*pAlloc = colorImageAlloc;

	return image;
}

template <class T>
class CalibratedTimestampTest : public vkt::TestCase
{
public:
								CalibratedTimestampTest		(tcu::TestContext&		testContext,
															 const std::string&		name,
															 const std::string&		description)
									: vkt::TestCase{testContext, name, description}
									{ }

	virtual						~CalibratedTimestampTest	(void) override { }
	virtual void				initPrograms				(SourceCollections&		programCollection) const override;
	virtual void				checkSupport				(Context&				context) const override;
	virtual vkt::TestInstance*	createInstance				(Context&				context) const override;
};

class CalibratedTimestampTestInstance : public vkt::TestInstance
{
public:
							CalibratedTimestampTestInstance		(Context& context);
	virtual                 ~CalibratedTimestampTestInstance	(void) override { }
	virtual tcu::TestStatus iterate								(void) override;
	virtual tcu::TestStatus runTest								(void) = 0;
protected:
	struct CalibratedTimestamp
	{
		CalibratedTimestamp(deUint64 timestamp_, deUint64 deviation_) : timestamp{timestamp_}, deviation(deviation_) { }
		CalibratedTimestamp() : timestamp{}, deviation{} { }
		deUint64 timestamp;
		deUint64 deviation;
	};

	std::vector<VkTimeDomainEXT>		getDomainSubset(const std::vector<VkTimeDomainEXT>& available, const std::vector<VkTimeDomainEXT>& interesting) const;
	std::string							domainName(VkTimeDomainEXT domain) const;
	deUint64							getHostNativeTimestamp(VkTimeDomainEXT hostDomain) const;
	deUint64							getHostNanoseconds(deUint64 hostTimestamp) const;
	deUint64							getDeviceNanoseconds(deUint64 devTicksDelta) const;
	std::vector<CalibratedTimestamp>	getCalibratedTimestamps(const std::vector<VkTimeDomainEXT>& domains);
	CalibratedTimestamp					getCalibratedTimestamp(VkTimeDomainEXT domain);
	void								appendQualityMessage(const std::string& message);

	void								verifyDevTimestampMask(deUint64 value) const;
	deUint64							absDiffWithOverflow(deUint64 a, deUint64 b, deUint64 mask = std::numeric_limits<deUint64>::max()) const;
	deUint64							positiveDiffWithOverflow(deUint64 before, deUint64 after, deUint64 mask = std::numeric_limits<deUint64>::max()) const;
	bool								outOfRange(deUint64 begin, deUint64 middle, deUint64 end) const;

	static constexpr deUint64		kBatchTimeLimitNanos		= 1000000000u;	// 1 sec.
	static constexpr deUint64		kDeviationErrorLimitNanos	=  100000000u;	// 100 ms.
	static constexpr deUint64		kDeviationWarningLimitNanos =   50000000u;	// 50 ms.
	static constexpr deUint64		kDefaultToleranceNanos		=  100000000u;	// 100 ms.

#if (DE_OS == DE_OS_WIN32)
    // Preprocessor used to avoid warning about unused variable.
	static constexpr deUint64		kNanosecondsPerSecond		= 1000000000u;
#endif
	static constexpr deUint64		kNanosecondsPerMillisecond	=    1000000u;

	std::string						m_qualityMessage;
	float							m_timestampPeriod;
	std::vector<VkTimeDomainEXT>	m_devDomains;
	std::vector<VkTimeDomainEXT>	m_hostDomains;
#if (DE_OS == DE_OS_WIN32)
	deUint64						m_frequency;
#endif

	Move<VkCommandPool>				m_cmdPool;
	Move<VkCommandBuffer>			m_cmdBuffer;
	Move<VkQueryPool>				m_queryPool;
	deUint64						m_devTimestampMask;
};

class CalibratedTimestampDevDomainTestInstance : public CalibratedTimestampTestInstance
{
public:
							CalibratedTimestampDevDomainTestInstance	(Context& context)
								: CalibratedTimestampTestInstance{context}
								{ }

	virtual                 ~CalibratedTimestampDevDomainTestInstance	(void) { }
	virtual tcu::TestStatus runTest										(void) override;
};

class CalibratedTimestampHostDomainTestInstance : public CalibratedTimestampTestInstance
{
public:
							CalibratedTimestampHostDomainTestInstance	(Context& context)
								: CalibratedTimestampTestInstance{context}
								{ }

	virtual                 ~CalibratedTimestampHostDomainTestInstance	(void) { }
	virtual tcu::TestStatus runTest										(void) override;
};

class CalibratedTimestampCalibrationTestInstance : public CalibratedTimestampTestInstance
{
public:
							CalibratedTimestampCalibrationTestInstance	(Context& context)
								: CalibratedTimestampTestInstance{context}
								{ }

	virtual                 ~CalibratedTimestampCalibrationTestInstance	(void) { }
	virtual tcu::TestStatus runTest										(void) override;
};

template <class T>
void CalibratedTimestampTest<T>::initPrograms (SourceCollections& programCollection) const
{
	vkt::TestCase::initPrograms(programCollection);
}

template <class T>
vkt::TestInstance* CalibratedTimestampTest<T>::createInstance (Context& context) const
{
	return new T{context};
}

template <class T>
void CalibratedTimestampTest<T>::checkSupport (Context& context) const
{
	context.requireDeviceFunctionality("VK_EXT_calibrated_timestamps");
}

CalibratedTimestampTestInstance::CalibratedTimestampTestInstance (Context& context)
	: TestInstance{context}
{
#if (DE_OS == DE_OS_WIN32)
	LARGE_INTEGER freq;
	if (!QueryPerformanceFrequency(&freq))
	{
		throw tcu::ResourceError("Unable to get clock frequency with QueryPerformanceFrequency");
	}
	if (freq.QuadPart <= 0)
	{
		throw tcu::ResourceError("QueryPerformanceFrequency did not return a positive number");
	}
	m_frequency = static_cast<deUint64>(freq.QuadPart);
#endif

	const InstanceInterface&	vki					= context.getInstanceInterface();
	const VkPhysicalDevice		physDevice			= context.getPhysicalDevice();
	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();

	// Get timestamp mask.
	m_devTimestampMask = checkTimestampsSupported(context);

	// Get calibreatable time domains.
	m_timestampPeriod = getPhysicalDeviceProperties(vki, physDevice).limits.timestampPeriod;

	deUint32 domainCount;
	VK_CHECK(vki.getPhysicalDeviceCalibrateableTimeDomainsEXT(physDevice, &domainCount, DE_NULL));
	if (domainCount == 0)
	{
		throw tcu::NotSupportedError("No calibrateable time domains found");
	}

	std::vector<VkTimeDomainEXT> domains;
	domains.resize(domainCount);
	VK_CHECK(vki.getPhysicalDeviceCalibrateableTimeDomainsEXT(physDevice, &domainCount, domains.data()));

	// Find the dev domain.
	std::vector<VkTimeDomainEXT> preferredDevDomains;
	preferredDevDomains.push_back(VK_TIME_DOMAIN_DEVICE_EXT);
	m_devDomains = getDomainSubset(domains, preferredDevDomains);

	// Find the host domain.
	std::vector<VkTimeDomainEXT> preferredHostDomains;
#if (DE_OS == DE_OS_WIN32)
	preferredHostDomains.push_back(VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT);
#else
	preferredHostDomains.push_back(VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT);
	preferredHostDomains.push_back(VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT);
#endif
	m_hostDomains = getDomainSubset(domains, preferredHostDomains);

	// Initialize command buffers and queries.
	const DeviceInterface&		vk				= context.getDeviceInterface();
	const VkDevice				vkDevice		= context.getDevice();

	const VkQueryPoolCreateInfo	queryPoolParams	=
	{
		VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,	// VkStructureType               sType;
		DE_NULL,									// const void*                   pNext;
		0u,											// VkQueryPoolCreateFlags        flags;
		VK_QUERY_TYPE_TIMESTAMP,					// VkQueryType                   queryType;
		1u,											// deUint32                      entryCount;
		0u,											// VkQueryPipelineStatisticFlags pipelineStatistics;
	};

	m_queryPool	= createQueryPool(vk, vkDevice, &queryPoolParams);
	m_cmdPool	= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
	m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

	beginCommandBuffer(vk, *m_cmdBuffer, 0u);
	vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, 1u);
	vk.cmdWriteTimestamp(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, *m_queryPool, 0u);
	endCommandBuffer(vk, *m_cmdBuffer);
}

std::vector<VkTimeDomainEXT> CalibratedTimestampTestInstance::getDomainSubset (const std::vector<VkTimeDomainEXT>& available, const std::vector<VkTimeDomainEXT>& interesting) const
{
	const std::set<VkTimeDomainEXT> availableSet	(begin(available),		end(available));
	const std::set<VkTimeDomainEXT> interestingSet	(begin(interesting),	end(interesting));

	std::vector<VkTimeDomainEXT> subset;
	std::set_intersection(begin(availableSet), end(availableSet), begin(interestingSet), end(interestingSet), std::back_inserter(subset));
	return subset;
}

std::string CalibratedTimestampTestInstance::domainName(VkTimeDomainEXT domain) const
{
	switch (domain)
	{
	case VK_TIME_DOMAIN_DEVICE_EXT:						return "Device Domain";
	case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:			return "Monotonic Clock";
	case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:		return "Raw Monotonic Clock";
	case VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT:	return "Query Performance Counter";
	default:											DE_ASSERT(DE_FALSE); return "Unknown Time Domain";
	}
}

deUint64 CalibratedTimestampTestInstance::getHostNativeTimestamp (VkTimeDomainEXT hostDomain) const
{
#if (DE_OS == DE_OS_WIN32)
	DE_ASSERT(hostDomain == VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT);
	LARGE_INTEGER result;
	if (!QueryPerformanceCounter(&result))
	{
		throw tcu::ResourceError("Unable to obtain host native timestamp for Win32");
	}
	if (result.QuadPart < 0)
	{
		throw tcu::ResourceError("Host-native timestamp for Win32 less than zero");
	}
	return static_cast<deUint64>(result.QuadPart);
#else
	DE_ASSERT(hostDomain == VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT ||
			  hostDomain == VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT);

#if defined(CLOCK_MONOTONIC_RAW)
	clockid_t id = ((hostDomain == VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT) ? CLOCK_MONOTONIC : CLOCK_MONOTONIC_RAW);
#else
	clockid_t id = CLOCK_MONOTONIC;
#endif
	struct timespec ts;
	if (clock_gettime(id, &ts) != 0)
	{
		throw tcu::ResourceError("Unable to obtain host native timestamp for POSIX");
	}
	return (static_cast<deUint64>(ts.tv_sec) * 1000000000ULL + ts.tv_nsec);
#endif
}

deUint64 CalibratedTimestampTestInstance::getHostNanoseconds (deUint64 hostTimestamp) const
{
#if (DE_OS == DE_OS_WIN32)
	deUint64	secs	= hostTimestamp / m_frequency;
	deUint64	nanos	= ((hostTimestamp % m_frequency) * kNanosecondsPerSecond) / m_frequency;

	return ((secs * kNanosecondsPerSecond) + nanos);
#else
	return hostTimestamp;
#endif
}

// This method will be used when devTicksDelta is (supposedly) a small amount of ticks between two events. We will check
// devTicksDelta is reasonably small for the calculation below to succeed without losing precision.
deUint64 CalibratedTimestampTestInstance::getDeviceNanoseconds (deUint64 devTicksDelta) const
{
	if (devTicksDelta > static_cast<deUint64>(std::numeric_limits<deUint32>::max()))
	{
		std::ostringstream msg;
		msg << "Number of device ticks too big for conversion to nanoseconds: " << devTicksDelta;
		throw tcu::InternalError(msg.str());
	}
	return static_cast<deUint64>(static_cast<double>(devTicksDelta) * m_timestampPeriod);
}

tcu::TestStatus CalibratedTimestampTestInstance::iterate (void)
{
	// Notes:
	//	1) Clocks may overflow.
	//	2) Because m_timestampPeriod is a floating point value, there may be less than one nano per tick.

	const tcu::TestStatus result = runTest();
	if (result.getCode() != QP_TEST_RESULT_PASS)
		return result;

	if (!m_qualityMessage.empty())
	{
		const std::string msg = "Warnings found: " + m_qualityMessage;
		return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, msg);
	}
	return tcu::TestStatus::pass("Pass");
}

// Verify all invalid timestamp bits are zero.
void CalibratedTimestampTestInstance::verifyDevTimestampMask (deUint64 value) const
{
	checkTimestampBits(value, m_devTimestampMask);
}

// Absolute difference between two timestamps A and B taking overflow into account. Pick the smallest difference between the two
// possibilities. We don't know beforehand if B > A or vice versa. Take the valid bit mask into account.
deUint64 CalibratedTimestampTestInstance::absDiffWithOverflow (deUint64 a, deUint64 b, deUint64 mask) const
{
	//	<---------+ range +-------->
	//
	//	+--------------------------+
	//	|         deUint64         |
	//	+------^-----------^-------+
	//	       +           +
	//	       a           b
	//	       +----------->
	//	       ccccccccccccc
	//	------>             +-------
	//	ddddddd             dddddddd

	DE_ASSERT(a <= mask);
	DE_ASSERT(b <= mask);

	const deUint64 c = ((a >= b) ? (a - b) : (b - a));

	if (c == 0u)
		return c;

	const deUint64 d = (mask - c) + 1;

	return ((c < d) ? c : d);
}

// Positive difference between both marks, advancing from before to after, taking overflow and the valid bit mask into account.
deUint64 CalibratedTimestampTestInstance::positiveDiffWithOverflow (deUint64 before, deUint64 after, deUint64 mask) const
{
	DE_ASSERT(before <= mask);
	DE_ASSERT(after  <= mask);

	return ((before <= after) ? (after - before) : ((mask - (before - after)) + 1));
}

// Return true if middle is not between begin and end, taking overflow into account.
bool CalibratedTimestampTestInstance::outOfRange (deUint64 begin, deUint64 middle, deUint64 end) const
{
	return (((begin <= end) && (middle < begin || middle > end	)) ||
			((begin >  end) && (middle > end   && middle < begin)));
}

std::vector<CalibratedTimestampTestInstance::CalibratedTimestamp> CalibratedTimestampTestInstance::getCalibratedTimestamps (const std::vector<VkTimeDomainEXT>& domains)
{
	std::vector<VkCalibratedTimestampInfoEXT> infos;

	for (auto domain : domains)
	{
		VkCalibratedTimestampInfoEXT info;
		info.sType = getStructureType<VkCalibratedTimestampInfoEXT>();
		info.pNext = DE_NULL;
		info.timeDomain = domain;
		infos.push_back(info);
	}

	std::vector<deUint64> timestamps(domains.size());
	deUint64			  deviation;

	const DeviceInterface&      vk          = m_context.getDeviceInterface();
	const VkDevice              vkDevice    = m_context.getDevice();

	VK_CHECK(vk.getCalibratedTimestampsEXT(vkDevice, static_cast<deUint32>(domains.size()), infos.data(), timestamps.data(), &deviation));

	if (deviation > kDeviationErrorLimitNanos)
	{
		throw tcu::InternalError("Calibrated maximum deviation too big");
	}
	else if (deviation > kDeviationWarningLimitNanos)
	{
		appendQualityMessage("Calibrated maximum deviation beyond desirable limits");
	}
	else if (deviation == 0 && domains.size() > 1)
	{
		appendQualityMessage("Calibrated maximum deviation reported as zero");
	}

	// Pack results.
	std::vector<CalibratedTimestamp> results;

	for (size_t i = 0; i < domains.size(); ++i)
	{
		if (domains[i] == VK_TIME_DOMAIN_DEVICE_EXT)
			verifyDevTimestampMask(timestamps[i]);
		results.emplace_back(timestamps[i], deviation);
	}

	return results;
}

CalibratedTimestampTestInstance::CalibratedTimestamp CalibratedTimestampTestInstance::getCalibratedTimestamp (VkTimeDomainEXT domain)
{
	// Single domain, single result.
	return getCalibratedTimestamps(std::vector<VkTimeDomainEXT>(1, domain))[0];
}

void CalibratedTimestampTestInstance::appendQualityMessage (const std::string& message)
{
	if (!m_qualityMessage.empty())
		m_qualityMessage += "; ";

	m_qualityMessage += message;
}

// Test device domain makes sense and is consistent with vkCmdWriteTimestamp().
tcu::TestStatus CalibratedTimestampDevDomainTestInstance::runTest (void)
{
	if (m_devDomains.empty())
		throw tcu::NotSupportedError("No suitable device time domains found");

	const DeviceInterface&      vk          = m_context.getDeviceInterface();
	const VkDevice              vkDevice    = m_context.getDevice();
	const VkQueue               queue       = m_context.getUniversalQueue();

	for (const auto devDomain : m_devDomains)
	{
		const CalibratedTimestamp	before		= getCalibratedTimestamp(devDomain);
		submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
		const CalibratedTimestamp	after		= getCalibratedTimestamp(devDomain);
		const deUint64				diffNanos	= getDeviceNanoseconds(positiveDiffWithOverflow(before.timestamp, after.timestamp, m_devTimestampMask));
		deUint64					written;
		VK_CHECK(vk.getQueryPoolResults(vkDevice, *m_queryPool, 0u, 1u, sizeof(written), &written, sizeof(written), (VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT)));
		verifyDevTimestampMask(written);

		if (diffNanos > kBatchTimeLimitNanos)
		{
			return tcu::TestStatus::fail(domainName(devDomain) + ": Batch of work took too long to execute");
		}

		if (outOfRange(before.timestamp, written, after.timestamp))
		{
			return tcu::TestStatus::fail(domainName(devDomain) + ": vkCmdWriteTimestamp() inconsistent with vkGetCalibratedTimestampsEXT()");
		}
	}

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

// Test host domain makes sense and is consistent with native host values.
tcu::TestStatus CalibratedTimestampHostDomainTestInstance::runTest (void)
{
	if (m_hostDomains.empty())
		throw tcu::NotSupportedError("No suitable host time domains found");

	for (const auto hostDomain : m_hostDomains)
	{
		const deUint64				before		= getHostNativeTimestamp(hostDomain);
		const CalibratedTimestamp	vkTS		= getCalibratedTimestamp(hostDomain);
		const deUint64				after		= getHostNativeTimestamp(hostDomain);
		const deUint64				diffNanos	= getHostNanoseconds(positiveDiffWithOverflow(before, after));

		if (diffNanos > kBatchTimeLimitNanos)
		{
			return tcu::TestStatus::fail(domainName(hostDomain) + ": Querying host domain took too long to execute");
		}

		if (outOfRange(before, vkTS.timestamp, after))
		{
			return tcu::TestStatus::fail(domainName(hostDomain) + ": vkGetCalibratedTimestampsEXT() inconsistent with native host API");
		}
	}

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

// Verify predictable timestamps and calibration possible.
tcu::TestStatus CalibratedTimestampCalibrationTestInstance::runTest (void)
{
	if (m_devDomains.empty())
		throw tcu::NotSupportedError("No suitable device time domains found");
	if (m_hostDomains.empty())
		throw tcu::NotSupportedError("No suitable host time domains found");

	// Sleep time.
	constexpr deUint32	kSleepMilliseconds	= 200;
	constexpr deUint32	kSleepNanoseconds	= kSleepMilliseconds * kNanosecondsPerMillisecond;

	for (const auto devDomain	: m_devDomains)
	for (const auto hostDomain	: m_hostDomains)
	{
		std::vector<VkTimeDomainEXT>	domains;
		domains.push_back(devDomain);	// Device results at index 0.
		domains.push_back(hostDomain);	// Host results at index 1.

		// Measure time.
		const std::vector<CalibratedTimestamp> before	= getCalibratedTimestamps(domains);
		std::this_thread::sleep_for(std::chrono::nanoseconds(kSleepNanoseconds));
		const std::vector<CalibratedTimestamp> after	= getCalibratedTimestamps(domains);

		// Check device timestamp is as expected.
		const deUint64 devBeforeTicks	= before[0].timestamp;
		const deUint64 devAfterTicks	= after[0].timestamp;
		const deUint64 devExpectedTicks	= ((devBeforeTicks + static_cast<deUint64>(static_cast<double>(kSleepNanoseconds) / m_timestampPeriod)) & m_devTimestampMask);
		const deUint64 devDiffNanos		= getDeviceNanoseconds(absDiffWithOverflow(devAfterTicks, devExpectedTicks, m_devTimestampMask));
		const deUint64 maxDevDiffNanos	= std::max({ kDefaultToleranceNanos, before[0].deviation + after[0].deviation });

		if (devDiffNanos > maxDevDiffNanos)
		{
			std::ostringstream msg;
			msg << "[" << domainName(devDomain) << "] Device expected timestamp differs " << devDiffNanos << " nanoseconds (expect value <= " << maxDevDiffNanos << ")";
			return tcu::TestStatus::fail(msg.str());
		}

		// Check host timestamp is as expected.
		const deUint64 hostBefore		= getHostNanoseconds(before[1].timestamp);
		const deUint64 hostAfter		= getHostNanoseconds(after[1].timestamp);
		const deUint64 hostExpected		= hostBefore + kSleepNanoseconds;
		const deUint64 hostDiff			= absDiffWithOverflow(hostAfter, hostExpected);
		const deUint64 maxHostDiff		= std::max({ kDefaultToleranceNanos, before[1].deviation + after[1].deviation });

		if (hostDiff > maxHostDiff)
		{
			std::ostringstream msg;
			msg << "[" << domainName(hostDomain) << "] Host expected timestamp differs " << hostDiff << " nanoseconds (expected value <= " << maxHostDiff << ")";
			return tcu::TestStatus::fail(msg.str());
		}
	}

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

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

class BasicGraphicsTestInstance : public TimestampTestInstance
{
public:
	enum
	{
		VK_MAX_SHADER_STAGES = 6,
	};
					BasicGraphicsTestInstance	(Context&				context,
												 const StageFlagVector	stages,
												 const bool				inRenderPass,
												 const bool				hostQueryReset);

	virtual			~BasicGraphicsTestInstance	(void);
protected:
	virtual void	configCommandBuffer			(void);
	virtual void	buildVertexBuffer			(void);
	virtual void	buildRenderPass				(VkFormat	colorFormat,
												 VkFormat	depthFormat);

	virtual void	buildFrameBuffer			(tcu::UVec2	renderSize,
												 VkFormat	colorFormat,
												 VkFormat	depthFormat);

protected:
	const tcu::UVec2				m_renderSize;
	const VkFormat					m_colorFormat;
	const VkFormat					m_depthFormat;

	Move<VkImage>					m_colorImage;
	de::MovePtr<Allocation>			m_colorImageAlloc;
	Move<VkImage>					m_depthImage;
	de::MovePtr<Allocation>			m_depthImageAlloc;
	Move<VkImageView>				m_colorAttachmentView;
	Move<VkImageView>				m_depthAttachmentView;
	Move<VkRenderPass>				m_renderPass;
	Move<VkFramebuffer>				m_framebuffer;
	VkImageMemoryBarrier			m_imageLayoutBarriers[2];

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

	SimpleGraphicsPipelineBuilder	m_pipelineBuilder;
	Move<VkPipeline>				m_graphicsPipelines;
};

void BasicGraphicsTest::initPrograms (SourceCollections& programCollection) const
{
	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");

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

TestInstance* BasicGraphicsTest::createInstance (Context& context) const
{
	return new BasicGraphicsTestInstance(context,m_stages,m_inRenderPass,m_hostQueryReset);
}

void BasicGraphicsTestInstance::buildVertexBuffer (void)
{
	const DeviceInterface&	vk			= m_context.getDeviceInterface();
	const VkDevice			vkDevice	= m_context.getDevice();

	// Create vertex buffer
	{
		m_vertexBuffer	= createBufferAndBindMemory(1024u, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, &m_vertexBufferAlloc);
		m_vertices		= createOverlappingQuads();

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

void BasicGraphicsTestInstance::buildRenderPass (VkFormat colorFormat, VkFormat depthFormat)
{
	const DeviceInterface&	vk			= m_context.getDeviceInterface();
	const VkDevice			vkDevice	= m_context.getDevice();

	// Create render pass
	m_renderPass = makeRenderPass(vk, vkDevice, colorFormat, depthFormat);
}

void BasicGraphicsTestInstance::buildFrameBuffer (tcu::UVec2 renderSize, VkFormat colorFormat, VkFormat depthFormat)
{
	const DeviceInterface&		vk						= m_context.getDeviceInterface();
	const VkDevice				vkDevice				= m_context.getDevice();
	const VkComponentMapping	ComponentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};

	// Create color image
	{
		m_colorImage = createImage2DAndBindMemory(colorFormat,
												  renderSize.x(),
												  renderSize.y(),
												  VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
												  VK_SAMPLE_COUNT_1_BIT,
												  &m_colorImageAlloc);
	}

	// Create depth image
	{
		m_depthImage = createImage2DAndBindMemory(depthFormat,
												  renderSize.x(),
												  renderSize.y(),
												  VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
												  VK_SAMPLE_COUNT_1_BIT,
												  &m_depthImageAlloc);
	}

	// Set up image layout transition barriers
	{
		const 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,										// VkImage					image;
			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },		// VkImageSubresourceRange	subresourceRange;
		};
		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[0] = colorImageBarrier;
		m_imageLayoutBarriers[1] = depthImageBarrier;
	}

	// Create color attachment view
	{
		const VkImageViewCreateInfo colorAttachmentViewParams =
		{
			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType          sType;
			DE_NULL,										// const void*              pNext;
			0u,												// VkImageViewCreateFlags   flags;
			*m_colorImage,									// VkImage                  image;
			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType          viewType;
			colorFormat,									// VkFormat                 format;
			ComponentMappingRGBA,							// VkComponentMapping       components;
			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },	// VkImageSubresourceRange  subresourceRange;
		};

		m_colorAttachmentView = 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;
			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
	{
		const VkImageView attachmentBindInfos[2] =
		{
			*m_colorAttachmentView,
			*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)renderSize.x(),					// deUint32                     width;
			(deUint32)renderSize.y(),					// deUint32                     height;
			1u,											// deUint32                     layers;
		};

		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
	}

}

BasicGraphicsTestInstance::BasicGraphicsTestInstance (Context&				context,
													  const StageFlagVector	stages,
													  const bool			inRenderPass,
													  const bool			hostQueryReset)
													  : TimestampTestInstance (context,stages,inRenderPass, hostQueryReset)
													  , m_renderSize		(32, 32)
													  , m_colorFormat		(VK_FORMAT_R8G8B8A8_UNORM)
													  , m_depthFormat		(VK_FORMAT_D16_UNORM)
													  , m_pipelineBuilder	(context)
{
	buildVertexBuffer();

	buildRenderPass(m_colorFormat, m_depthFormat);

	buildFrameBuffer(m_renderSize, m_colorFormat, m_depthFormat);

	m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_VERTEX_BIT, "color_vert");
	m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_FRAGMENT_BIT, "color_frag");

	m_graphicsPipelines = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass);

}

BasicGraphicsTestInstance::~BasicGraphicsTestInstance (void)
{
}

void BasicGraphicsTestInstance::configCommandBuffer (void)
{
	const DeviceInterface&		vk							= m_context.getDeviceInterface();

	const VkClearValue			attachmentClearValues[2]	=
	{
		defaultClearValue(m_colorFormat),
		defaultClearValue(m_depthFormat),
	};

	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_EARLY_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
		0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(m_imageLayoutBarriers), m_imageLayoutBarriers);

	if (!m_hostQueryReset)
		vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);

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

	vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines);
	VkDeviceSize offsets = 0u;
	vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &offsets);
	vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1u, 0u, 0u);

	if(m_inRenderPass)
	{
	  deUint32 timestampEntry = 0u;

	  for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
	  {
		  vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
	  }
	}

	endRenderPass(vk, *m_cmdBuffer);

	if(!m_inRenderPass)
	{
	  deUint32 timestampEntry = 0u;

	  for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
	  {
		  vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
	  }
	}

	endCommandBuffer(vk, *m_cmdBuffer);
}

class AdvGraphicsTest : public BasicGraphicsTest
{
public:
						  AdvGraphicsTest	(tcu::TestContext&			testContext,
											 const std::string&			name,
											 const std::string&			description,
											 const TimestampTestParam*	param)
							  : BasicGraphicsTest(testContext, name, description, param)
							  { }

	virtual               ~AdvGraphicsTest (void) { }
	virtual void          initPrograms     (SourceCollections& programCollection) const;
	virtual TestInstance* createInstance   (Context& context) const;
};

class AdvGraphicsTestInstance : public BasicGraphicsTestInstance
{
public:
				 AdvGraphicsTestInstance	(Context&				context,
											 const StageFlagVector	stages,
											 const bool				inRenderPass,
											 const bool				hostQueryReset);

	virtual      ~AdvGraphicsTestInstance	(void);
	virtual void configCommandBuffer		(void);

protected:
	virtual void featureSupportCheck		(void);

protected:
	VkPhysicalDeviceFeatures	m_features;
	deUint32					m_draw_count;
	de::MovePtr<Allocation>		m_indirectBufferAlloc;
	Move<VkBuffer>				m_indirectBuffer;
};

void AdvGraphicsTest::initPrograms (SourceCollections& programCollection) const
{
	BasicGraphicsTest::initPrograms(programCollection);

	programCollection.glslSources.add("dummy_geo") << glu::GeometrySource(
		"#version 310 es\n"
		"#extension GL_EXT_geometry_shader : enable\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"
		"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];\n"
		"    EmitVertex();\n"
		"  }\n"
		"  EndPrimitive();\n"
		"}\n");

	programCollection.glslSources.add("basic_tcs") << glu::TessellationControlSource(
		"#version 310 es\n"
		"#extension GL_EXT_tessellation_shader : enable\n"
		"layout(vertices = 3) out;\n"
		"layout(location = 0) in highp vec4 color[];\n"
		"layout(location = 0) out highp vec4 vtxColor[];\n"
		"void main()\n"
		"{\n"
		"  gl_TessLevelOuter[0] = 4.0;\n"
		"  gl_TessLevelOuter[1] = 4.0;\n"
		"  gl_TessLevelOuter[2] = 4.0;\n"
		"  gl_TessLevelInner[0] = 4.0;\n"
		"  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
		"  vtxColor[gl_InvocationID] = color[gl_InvocationID];\n"
		"}\n");

	programCollection.glslSources.add("basic_tes") << glu::TessellationEvaluationSource(
		"#version 310 es\n"
		"#extension GL_EXT_tessellation_shader : enable\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"
		"void main() \n"
		"{\n"
		"  float u = gl_TessCoord.x;\n"
		"  float v = gl_TessCoord.y;\n"
		"  float w = gl_TessCoord.z;\n"
		"  vec4 pos = vec4(0);\n"
		"  vec4 color = vec4(0);\n"
		"  pos.xyz += u * gl_in[0].gl_Position.xyz;\n"
		"  color.xyz += u * colors[0].xyz;\n"
		"  pos.xyz += v * gl_in[1].gl_Position.xyz;\n"
		"  color.xyz += v * colors[1].xyz;\n"
		"  pos.xyz += w * gl_in[2].gl_Position.xyz;\n"
		"  color.xyz += w * colors[2].xyz;\n"
		"  pos.w = 1.0;\n"
		"  color.w = 1.0;\n"
		"  gl_Position = pos;\n"
		"  vtxColor = color;\n"
		"}\n");
}

TestInstance* AdvGraphicsTest::createInstance (Context& context) const
{
	return new AdvGraphicsTestInstance(context,m_stages,m_inRenderPass,m_hostQueryReset);
}

void AdvGraphicsTestInstance::featureSupportCheck (void)
{
	for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
	{
		switch(*it)
		{
			case VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT:
				if (m_features.geometryShader == VK_FALSE)
				{
					TCU_THROW(NotSupportedError, "Geometry Shader Not Supported");
				}
				break;
			case VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT:
			case VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT:
				if (m_features.tessellationShader == VK_FALSE)
				{
					TCU_THROW(NotSupportedError, "Tessellation Not Supported");
				}
				break;
			case VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT:
			default:
				break;
		};
	}
}

AdvGraphicsTestInstance::AdvGraphicsTestInstance (Context&				context,
												  const StageFlagVector	stages,
												  const bool			inRenderPass,
												  const bool			hostQueryReset)
	: BasicGraphicsTestInstance(context, stages, inRenderPass, hostQueryReset)
{
	m_features = m_context.getDeviceFeatures();

	// If necessary feature is not supported, throw error and fail current test
	featureSupportCheck();

	if(m_features.geometryShader == VK_TRUE)
	{
		m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_GEOMETRY_BIT, "dummy_geo");
	}

	if(m_features.tessellationShader == VK_TRUE)
	{
		m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "basic_tcs");
		m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "basic_tes");
		m_pipelineBuilder.enableTessellationStage(3);
	}

	m_graphicsPipelines = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass);

	// Prepare the indirect draw buffer
	const DeviceInterface&	vk			= m_context.getDeviceInterface();
	const VkDevice			vkDevice	= m_context.getDevice();

	if(m_features.multiDrawIndirect == VK_TRUE)
	{
		m_draw_count = 2;
	}
	else
	{
		m_draw_count = 1;
	}

	m_indirectBuffer = createBufferAndBindMemory(32u, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, &m_indirectBufferAlloc);

	const VkDrawIndirectCommand indirectCmds[] =
	{
		{
			12u,	// deUint32    vertexCount;
			1u,		// deUint32    instanceCount;
			0u,		// deUint32    firstVertex;
			0u,		// deUint32    firstInstance;
		},
		{
			12u,	// deUint32    vertexCount;
			1u,		// deUint32    instanceCount;
			11u,	// deUint32    firstVertex;
			0u,		// deUint32    firstInstance;
		},
	};

	// Load data into indirect draw buffer
	deMemcpy(m_indirectBufferAlloc->getHostPtr(), indirectCmds, m_draw_count * sizeof(VkDrawIndirectCommand));
	flushAlloc(vk, vkDevice, *m_indirectBufferAlloc);

}

AdvGraphicsTestInstance::~AdvGraphicsTestInstance (void)
{
}

void AdvGraphicsTestInstance::configCommandBuffer (void)
{
	const DeviceInterface&		vk							= m_context.getDeviceInterface();

	const VkClearValue			attachmentClearValues[2]	=
	{
		defaultClearValue(m_colorFormat),
		defaultClearValue(m_depthFormat),
	};

	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_EARLY_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
		0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(m_imageLayoutBarriers), m_imageLayoutBarriers);

	if (!m_hostQueryReset)
		vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);

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

	vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines);

	VkDeviceSize offsets = 0u;
	vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &offsets);

	vk.cmdDrawIndirect(*m_cmdBuffer, *m_indirectBuffer, 0u, m_draw_count, sizeof(VkDrawIndirectCommand));

	if(m_inRenderPass)
	{
	  deUint32 timestampEntry = 0u;
	  for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
	  {
		  vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
	  }
	}

	endRenderPass(vk, *m_cmdBuffer);

	if(!m_inRenderPass)
	{
	  deUint32 timestampEntry = 0u;
	  for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
	  {
		  vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
	  }
	}

	endCommandBuffer(vk, *m_cmdBuffer);
}

class BasicComputeTest : public TimestampTest
{
public:
							BasicComputeTest	(tcu::TestContext&			testContext,
												 const std::string&			name,
												 const std::string&			description,
												 const TimestampTestParam*	param)
							  : TimestampTest(testContext, name, description, param)
							  { }

	virtual					~BasicComputeTest	(void) { }
	virtual void			initPrograms		(SourceCollections& programCollection) const;
	virtual TestInstance*	createInstance		(Context& context) const;
};

class BasicComputeTestInstance : public TimestampTestInstance
{
public:
					BasicComputeTestInstance	(Context&				context,
												 const StageFlagVector	stages,
												 const bool				inRenderPass,
												 const bool				hostQueryReset);

	virtual			~BasicComputeTestInstance	(void);
	virtual void	configCommandBuffer			(void);
protected:
	de::MovePtr<Allocation>     m_inputBufAlloc;
	Move<VkBuffer>              m_inputBuf;
	de::MovePtr<Allocation>     m_outputBufAlloc;
	Move<VkBuffer>              m_outputBuf;

	Move<VkDescriptorPool>      m_descriptorPool;
	Move<VkDescriptorSet>       m_descriptorSet;
	Move<VkDescriptorSetLayout> m_descriptorSetLayout;

	Move<VkPipelineLayout>      m_pipelineLayout;
	Move<VkShaderModule>        m_computeShaderModule;
	Move<VkPipeline>            m_computePipelines;
};

void BasicComputeTest::initPrograms (SourceCollections& programCollection) const
{
	TimestampTest::initPrograms(programCollection);

	programCollection.glslSources.add("basic_compute") << glu::ComputeSource(
		"#version 310 es\n"
		"layout(local_size_x = 128) in;\n"
		"layout(std430) buffer;\n"
		"layout(binding = 0) readonly buffer Input0\n"
		"{\n"
		"  vec4 elements[];\n"
		"} input_data0;\n"
		"layout(binding = 1) writeonly buffer Output\n"
		"{\n"
		"  vec4 elements[];\n"
		"} output_data;\n"
		"void main()\n"
		"{\n"
		"  uint ident = gl_GlobalInvocationID.x;\n"
		"  output_data.elements[ident] = input_data0.elements[ident] * input_data0.elements[ident];\n"
		"}");
}

TestInstance* BasicComputeTest::createInstance (Context& context) const
{
	return new BasicComputeTestInstance(context,m_stages,m_inRenderPass, m_hostQueryReset);
}

BasicComputeTestInstance::BasicComputeTestInstance (Context&				context,
												    const StageFlagVector	stages,
												    const bool				inRenderPass,
												    const bool				hostQueryReset)
	: TimestampTestInstance(context, stages, inRenderPass, hostQueryReset)
{
	const DeviceInterface&	vk			= context.getDeviceInterface();
	const VkDevice			vkDevice	= context.getDevice();

	// Create buffer object, allocate storage, and generate input data
	const VkDeviceSize		size		= sizeof(tcu::Vec4) * 128u * 128u;

	m_inputBuf = createBufferAndBindMemory(size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, &m_inputBufAlloc);

	// Load vertices into buffer
	tcu::Vec4*				pVec		= reinterpret_cast<tcu::Vec4*>(m_inputBufAlloc->getHostPtr());

	for (deUint32 ndx = 0u; ndx < (128u * 128u); ndx++)
	{
		for (deUint32 component = 0u; component < 4u; component++)
		{
			pVec[ndx][component]= (float)(ndx * (component + 1u));
		}
	}

	flushAlloc(vk, vkDevice, *m_inputBufAlloc);

	m_outputBuf = createBufferAndBindMemory(size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, &m_outputBufAlloc);

	std::vector<VkDescriptorBufferInfo> descriptorInfos;

	descriptorInfos.push_back(makeDescriptorBufferInfo(*m_inputBuf, 0u, size));
	descriptorInfos.push_back(makeDescriptorBufferInfo(*m_outputBuf, 0u, size));

	// 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 = descLayoutBuilder.build(vk, vkDevice);

	// Create descriptor pool
	m_descriptorPool = DescriptorPoolBuilder().addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2).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,								// VkDescriptorPool                descriptorPool;
		1u,												// deUint32                        setLayoutCount;
		&m_descriptorSetLayout.get(),					// const VkDescriptorSetLayout*    pSetLayouts;
	};
	m_descriptorSet   = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocInfo);

	DescriptorSetUpdateBuilder  builder;
	for (deUint32 descriptorNdx = 0u; descriptorNdx < 2u; descriptorNdx++)
	{
		builder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(descriptorNdx), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfos[descriptorNdx]);
	}
	builder.update(vk, vkDevice);

	// 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.get(),					// const VkDescriptorSetLayout*    pSetLayouts;
		0u,												// deUint32                        pushConstantRangeCount;
		DE_NULL,										// const VkPushConstantRange*      pPushConstantRanges;
	};

	m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutCreateInfo);

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

	// Create compute pipeline
	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,								// VkPipelineLayout                layout;
		(VkPipeline)0,									// VkPipeline                      basePipelineHandle;
		0u,												// deInt32                         basePipelineIndex;
	};

	m_computePipelines = createComputePipeline(vk, vkDevice, (VkPipelineCache)0u, &pipelineCreateInfo);
}

BasicComputeTestInstance::~BasicComputeTestInstance (void)
{
}

void BasicComputeTestInstance::configCommandBuffer (void)
{
	const DeviceInterface& vk = m_context.getDeviceInterface();

	beginCommandBuffer(vk, *m_cmdBuffer, 0u);

	if (!m_hostQueryReset)
		vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);

	vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipelines);
	vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL);
	vk.cmdDispatch(*m_cmdBuffer, 128u, 1u, 1u);

	deUint32 timestampEntry = 0u;
	for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
	{
		vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
	}

	endCommandBuffer(vk, *m_cmdBuffer);
}

class TransferTest : public TimestampTest
{
public:
							TransferTest	(tcu::TestContext&			testContext,
											 const std::string&			name,
											 const std::string&			description,
											 const TimestampTestParam*	param);

	virtual					~TransferTest	(void) { }
	virtual void			initPrograms	(SourceCollections& programCollection) const;
	virtual TestInstance*	createInstance	(Context& context) const;

protected:
	TransferMethod        m_method;
};

class TransferTestInstance : public TimestampTestInstance
{
public:
					TransferTestInstance	(Context&					context,
											 const StageFlagVector		stages,
											 const bool					inRenderPass,
											 const bool					hostQueryReset,
											 const TransferMethod		method);

	virtual         ~TransferTestInstance	(void);
	virtual void    configCommandBuffer		(void);
	virtual void	initialImageTransition	(VkCommandBuffer			cmdBuffer,
											 VkImage					image,
											 VkImageSubresourceRange	subRange,
											 VkImageLayout				layout);
protected:
	TransferMethod			m_method;

	VkDeviceSize			m_bufSize;
	Move<VkBuffer>			m_srcBuffer;
	Move<VkBuffer>			m_dstBuffer;
	de::MovePtr<Allocation> m_srcBufferAlloc;
	de::MovePtr<Allocation> m_dstBufferAlloc;

	VkFormat				m_imageFormat;
	deInt32					m_imageWidth;
	deInt32					m_imageHeight;
	VkDeviceSize			m_imageSize;
	Move<VkImage>			m_srcImage;
	Move<VkImage>			m_dstImage;
	Move<VkImage>			m_depthImage;
	Move<VkImage>			m_msImage;
	de::MovePtr<Allocation>	m_srcImageAlloc;
	de::MovePtr<Allocation>	m_dstImageAlloc;
	de::MovePtr<Allocation>	m_depthImageAlloc;
	de::MovePtr<Allocation>	m_msImageAlloc;
};

TransferTest::TransferTest (tcu::TestContext&			testContext,
						    const std::string&			name,
						    const std::string&			description,
						    const TimestampTestParam*	param)
	: TimestampTest(testContext, name, description, param)
{
	const TransferTimestampTestParam* transferParam = dynamic_cast<const TransferTimestampTestParam*>(param);
	m_method = transferParam->getMethod();
}

void TransferTest::initPrograms (SourceCollections& programCollection) const
{
	TimestampTest::initPrograms(programCollection);
}

TestInstance* TransferTest::createInstance (Context& context) const
{
  return new TransferTestInstance(context, m_stages, m_inRenderPass, m_hostQueryReset, m_method);
}

TransferTestInstance::TransferTestInstance (Context&				context,
										    const StageFlagVector	stages,
										    const bool				inRenderPass,
										    const bool				hostQueryReset,
										    const TransferMethod	method)
	: TimestampTestInstance(context, stages, inRenderPass, hostQueryReset)
	, m_method(method)
	, m_bufSize(256u)
	, m_imageFormat(VK_FORMAT_R8G8B8A8_UNORM)
	, m_imageWidth(4u)
	, m_imageHeight(4u)
	, m_imageSize(256u)
{
	const DeviceInterface&	vk			= context.getDeviceInterface();
	const VkDevice			vkDevice	= context.getDevice();

	// Create src buffer
	m_srcBuffer = createBufferAndBindMemory(m_bufSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, &m_srcBufferAlloc);

	// Init the source buffer memory
	char* pBuf = reinterpret_cast<char*>(m_srcBufferAlloc->getHostPtr());
	deMemset(pBuf, 0xFF, sizeof(char)*(size_t)m_bufSize);
	flushAlloc(vk, vkDevice, *m_srcBufferAlloc);

	// Create dst buffer
	m_dstBuffer	= createBufferAndBindMemory(m_bufSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, &m_dstBufferAlloc);

	// Create src/dst/depth image
	m_srcImage		= createImage2DAndBindMemory(m_imageFormat, m_imageWidth, m_imageHeight,
												 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
												 VK_SAMPLE_COUNT_1_BIT,
												 &m_srcImageAlloc);
	m_dstImage		= createImage2DAndBindMemory(m_imageFormat, m_imageWidth, m_imageHeight,
												 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
												 VK_SAMPLE_COUNT_1_BIT,
												 &m_dstImageAlloc);
	m_depthImage	= createImage2DAndBindMemory(VK_FORMAT_D16_UNORM, m_imageWidth, m_imageHeight,
												 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
												 VK_SAMPLE_COUNT_1_BIT,
												 &m_depthImageAlloc);
	m_msImage		= createImage2DAndBindMemory(m_imageFormat, m_imageWidth, m_imageHeight,
												 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
												 VK_SAMPLE_COUNT_4_BIT,
												 &m_msImageAlloc);
}

TransferTestInstance::~TransferTestInstance (void)
{
}

void TransferTestInstance::configCommandBuffer (void)
{
	const DeviceInterface& vk = m_context.getDeviceInterface();

	beginCommandBuffer(vk, *m_cmdBuffer, 0u);

	// Initialize buffer/image
	vk.cmdFillBuffer(*m_cmdBuffer, *m_dstBuffer, 0u, m_bufSize, 0x0);

	const VkClearColorValue srcClearValue =
	{
		{1.0f, 1.0f, 1.0f, 1.0f}
	};
	const VkClearColorValue dstClearValue =
	{
		{0.0f, 0.0f, 0.0f, 0.0f}
	};
	const struct VkImageSubresourceRange subRangeColor =
	{
		VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags  aspectMask;
		0u,							// deUint32            baseMipLevel;
		1u,							// deUint32            mipLevels;
		0u,							// deUint32            baseArrayLayer;
		1u,							// deUint32            arraySize;
	};
	const struct VkImageSubresourceRange subRangeDepth =
	{
		VK_IMAGE_ASPECT_DEPTH_BIT,	// VkImageAspectFlags  aspectMask;
		0u,							// deUint32            baseMipLevel;
		1u,							// deUint32            mipLevels;
		0u,							// deUint32            baseArrayLayer;
		1u,							// deUint32            arraySize;
	};

	initialImageTransition(*m_cmdBuffer, *m_srcImage, subRangeColor, VK_IMAGE_LAYOUT_GENERAL);
	initialImageTransition(*m_cmdBuffer, *m_dstImage, subRangeColor, VK_IMAGE_LAYOUT_GENERAL);

	vk.cmdClearColorImage(*m_cmdBuffer, *m_srcImage, VK_IMAGE_LAYOUT_GENERAL, &srcClearValue, 1u, &subRangeColor);
	vk.cmdClearColorImage(*m_cmdBuffer, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, &dstClearValue, 1u, &subRangeColor);

	// synchronize the Clear commands before starting any copy
	const vk::VkMemoryBarrier barrier =
	{
		vk::VK_STRUCTURE_TYPE_MEMORY_BARRIER,							// VkStructureType	sType;
		DE_NULL,														// const void*		pNext;
		vk::VK_ACCESS_TRANSFER_WRITE_BIT,								// VkAccessFlags	srcAccessMask;
		vk::VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags	dstAccessMask;
	};
	vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 1u, &barrier, 0u, DE_NULL, 0u, DE_NULL);

	if (!m_hostQueryReset)
		vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);

	// Copy Operations
	const VkImageSubresourceLayers imgSubResCopy =
	{
		VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags  aspectMask;
		0u,							// deUint32            mipLevel;
		0u,							// deUint32            baseArrayLayer;
		1u,							// deUint32            layerCount;
	};

	const VkOffset3D nullOffset  = {0u, 0u, 0u};
	const VkExtent3D imageExtent = {(deUint32)m_imageWidth, (deUint32)m_imageHeight, 1u};
	const VkOffset3D imageOffset = {(int)m_imageWidth, (int)m_imageHeight, 1};

	switch(m_method)
	{
		case TRANSFER_METHOD_COPY_BUFFER:
			{
				const VkBufferCopy  copyBufRegion =
					{
						0u,			// VkDeviceSize    srcOffset;
						0u,			// VkDeviceSize    destOffset;
						m_bufSize,	// VkDeviceSize    copySize;
					};

				vk.cmdCopyBuffer(*m_cmdBuffer, *m_srcBuffer, *m_dstBuffer, 1u, &copyBufRegion);
				break;
			}
		case TRANSFER_METHOD_COPY_IMAGE:
			{
				const VkImageCopy copyImageRegion =
				{
					imgSubResCopy,	// VkImageSubresourceCopy  srcSubresource;
					nullOffset,		// VkOffset3D              srcOffset;
					imgSubResCopy,	// VkImageSubresourceCopy  destSubresource;
					nullOffset,		// VkOffset3D              destOffset;
					imageExtent,	// VkExtent3D              extent;

				};

				vk.cmdCopyImage(*m_cmdBuffer, *m_srcImage, VK_IMAGE_LAYOUT_GENERAL, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, 1u, &copyImageRegion);
				break;
			}
		case TRANSFER_METHOD_COPY_BUFFER_TO_IMAGE:
			{
				const VkBufferImageCopy bufImageCopy =
				{
					0u,							// VkDeviceSize            bufferOffset;
					(deUint32)m_imageWidth,		// deUint32                bufferRowLength;
					(deUint32)m_imageHeight,	// deUint32                bufferImageHeight;
					imgSubResCopy,				// VkImageSubresourceCopy  imageSubresource;
					nullOffset,					// VkOffset3D              imageOffset;
					imageExtent,				// VkExtent3D              imageExtent;
				};

				vk.cmdCopyBufferToImage(*m_cmdBuffer, *m_srcBuffer, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, 1u, &bufImageCopy);
				break;
			}
		case TRANSFER_METHOD_COPY_IMAGE_TO_BUFFER:
			{
				const VkBufferImageCopy imgBufferCopy =
				{
					0u,							// VkDeviceSize            bufferOffset;
					(deUint32)m_imageWidth,		// deUint32                bufferRowLength;
					(deUint32)m_imageHeight,	// deUint32                bufferImageHeight;
					imgSubResCopy,				// VkImageSubresourceCopy  imageSubresource;
					nullOffset,					// VkOffset3D              imageOffset;
					imageExtent,				// VkExtent3D              imageExtent;
				};

				vk.cmdCopyImageToBuffer(*m_cmdBuffer, *m_srcImage, VK_IMAGE_LAYOUT_GENERAL, *m_dstBuffer, 1u, &imgBufferCopy);
				break;
			}
		case TRANSFER_METHOD_BLIT_IMAGE:
			{
				const VkImageBlit imageBlt =
				{
					imgSubResCopy,	// VkImageSubresourceCopy  srcSubresource;
					{
						nullOffset,
						imageOffset,
					},
					imgSubResCopy,	// VkImageSubresourceCopy  destSubresource;
					{
						nullOffset,
						imageOffset,
					}
				};

				vk.cmdBlitImage(*m_cmdBuffer, *m_srcImage, VK_IMAGE_LAYOUT_GENERAL, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, 1u, &imageBlt, VK_FILTER_NEAREST);
				break;
			}
		case TRANSFER_METHOD_CLEAR_COLOR_IMAGE:
			{
				vk.cmdClearColorImage(*m_cmdBuffer, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, &srcClearValue, 1u, &subRangeColor);
				break;
			}
		case TRANSFER_METHOD_CLEAR_DEPTH_STENCIL_IMAGE:
			{
				initialImageTransition(*m_cmdBuffer, *m_depthImage, subRangeDepth, VK_IMAGE_LAYOUT_GENERAL);

				const VkClearDepthStencilValue clearDSValue =
				{
					1.0f,	// float       depth;
					0u,		// deUint32    stencil;
				};

				vk.cmdClearDepthStencilImage(*m_cmdBuffer, *m_depthImage, VK_IMAGE_LAYOUT_GENERAL, &clearDSValue, 1u, &subRangeDepth);
				break;
			}
		case TRANSFER_METHOD_FILL_BUFFER:
			{
				vk.cmdFillBuffer(*m_cmdBuffer, *m_dstBuffer, 0u, m_bufSize, 0x0);
				break;
			}
		case TRANSFER_METHOD_UPDATE_BUFFER:
			{
				const deUint32 data[] =
				{
					0xdeadbeef, 0xabcdef00, 0x12345678
				};

				vk.cmdUpdateBuffer(*m_cmdBuffer, *m_dstBuffer, 0x10, sizeof(data), data);
				break;
			}
		case TRANSFER_METHOD_COPY_QUERY_POOL_RESULTS:
			{
				vk.cmdWriteTimestamp(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, *m_queryPool, 0u);
				vk.cmdCopyQueryPoolResults(*m_cmdBuffer, *m_queryPool, 0u, 1u, *m_dstBuffer, 0u, 8u, VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);

				const vk::VkBufferMemoryBarrier bufferBarrier =
				{
					vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
					DE_NULL,										// const void*		pNext;
					vk::VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
					vk::VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
					VK_QUEUE_FAMILY_IGNORED,						// deUint32			srcQueueFamilyIndex;
					VK_QUEUE_FAMILY_IGNORED,						// deUint32			dstQueueFamilyIndex;
					*m_dstBuffer,									// VkBuffer			buffer;
					0ull,											// VkDeviceSize		offset;
					VK_WHOLE_SIZE									// VkDeviceSize		size;
				};

				vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u,
									  0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);

				vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, 1u);
				break;
			}
		case TRANSFER_METHOD_RESOLVE_IMAGE:
			{
				const VkImageResolve imageResolve =
				{
					imgSubResCopy,                              // VkImageSubresourceLayers  srcSubresource;
					nullOffset,                                 // VkOffset3D                srcOffset;
					imgSubResCopy,                              // VkImageSubresourceLayers  destSubresource;
					nullOffset,                                 // VkOffset3D                destOffset;
					imageExtent,                                // VkExtent3D                extent;
				};

				initialImageTransition(*m_cmdBuffer, *m_msImage, subRangeColor, VK_IMAGE_LAYOUT_GENERAL);
				vk.cmdClearColorImage(*m_cmdBuffer, *m_msImage, VK_IMAGE_LAYOUT_GENERAL, &srcClearValue, 1u, &subRangeColor);
				vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 1u, &barrier, 0u, DE_NULL, 0u, DE_NULL);
				vk.cmdResolveImage(*m_cmdBuffer, *m_msImage, VK_IMAGE_LAYOUT_GENERAL, *m_dstImage, VK_IMAGE_LAYOUT_GENERAL, 1u, &imageResolve);
				break;
			}
		default:
			DE_FATAL("Unknown Transfer Method!");
			break;
	};

	deUint32 timestampEntry = 0u;

	for (StageFlagVector::const_iterator it = m_stages.begin(); it != m_stages.end(); it++)
	{
		vk.cmdWriteTimestamp(*m_cmdBuffer, *it, *m_queryPool, timestampEntry++);
	}

	endCommandBuffer(vk, *m_cmdBuffer);
}

void TransferTestInstance::initialImageTransition (VkCommandBuffer cmdBuffer, VkImage image, VkImageSubresourceRange subRange, VkImageLayout layout)
{
	const DeviceInterface&		vk				= m_context.getDeviceInterface();

	const VkImageMemoryBarrier	imageMemBarrier	=
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType          sType;
		DE_NULL,								// const void*              pNext;
		0u,										// VkAccessFlags            srcAccessMask;
		VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags            dstAccessMask;
		VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout            oldLayout;
		layout,									// VkImageLayout            newLayout;
		VK_QUEUE_FAMILY_IGNORED,				// uint32_t                 srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,				// uint32_t                 dstQueueFamilyIndex;
		image,									// VkImage                  image;
		subRange								// VkImageSubresourceRange  subresourceRange;
	};

	vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, DE_NULL, 0, DE_NULL, 1, &imageMemBarrier);
}

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

class ResetTimestampQueryBeforeCopyTestInstance : public vkt::TestInstance
{
public:
							ResetTimestampQueryBeforeCopyTestInstance	(Context& context);
	virtual					~ResetTimestampQueryBeforeCopyTestInstance	(void) { }
	virtual tcu::TestStatus	iterate										(void);
protected:
	struct TimestampWithAvailability
	{
		deUint64 timestamp;
		deUint64 availability;
	};

	Move<VkCommandPool>		m_cmdPool;
	Move<VkCommandBuffer>	m_cmdBuffer;
	Move<VkQueryPool>		m_queryPool;

	Move<VkBuffer>			m_resultBuffer;
	de::MovePtr<Allocation>	m_resultBufferMemory;
};

void ResetTimestampQueryBeforeCopyTest::initPrograms (SourceCollections& programCollection) const
{
	vkt::TestCase::initPrograms(programCollection);
}

TestInstance* ResetTimestampQueryBeforeCopyTest::createInstance (Context& context) const
{
	return new ResetTimestampQueryBeforeCopyTestInstance(context);
}

ResetTimestampQueryBeforeCopyTestInstance::ResetTimestampQueryBeforeCopyTestInstance (Context& context)
	: vkt::TestInstance(context)
{
	const DeviceInterface&	vk					= context.getDeviceInterface();
	const VkDevice			vkDevice			= context.getDevice();
	const deUint32			queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
	Allocator&				allocator			= m_context.getDefaultAllocator();

	// Check support for timestamp queries
	checkTimestampsSupported(context);

	const VkQueryPoolCreateInfo queryPoolParams =
	{
		VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,	// VkStructureType               sType;
		DE_NULL,									// const void*                   pNext;
		0u,											// VkQueryPoolCreateFlags        flags;
		VK_QUERY_TYPE_TIMESTAMP,					// VkQueryType                   queryType;
		1u,											// deUint32                      entryCount;
		0u,											// VkQueryPipelineStatisticFlags pipelineStatistics;
	};

	m_queryPool		= createQueryPool(vk, vkDevice, &queryPoolParams);
	m_cmdPool		= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
	m_cmdBuffer		= allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

	// Create results buffer.
	const VkBufferCreateInfo bufferCreateInfo =
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
		DE_NULL,									// const void*			pNext;
		0u,											// VkBufferCreateFlags	flags;
		sizeof(TimestampWithAvailability),			// VkDeviceSize			size;
		VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
		1u,											// deUint32				queueFamilyIndexCount;
		&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
	};

	m_resultBuffer			= createBuffer(vk, vkDevice, &bufferCreateInfo);
	m_resultBufferMemory	= allocator.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_resultBuffer), MemoryRequirement::HostVisible);
	VK_CHECK(vk.bindBufferMemory(vkDevice, *m_resultBuffer, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset()));

	const vk::VkBufferMemoryBarrier bufferBarrier =
	{
		vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
		DE_NULL,										// const void*		pNext;
		vk::VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
		vk::VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
		VK_QUEUE_FAMILY_IGNORED,						// deUint32			srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,						// deUint32			dstQueueFamilyIndex;
		*m_resultBuffer,								// VkBuffer			buffer;
		0ull,											// VkDeviceSize		offset;
		VK_WHOLE_SIZE									// VkDeviceSize		size;
	};

	// Prepare command buffer.
	beginCommandBuffer(vk, *m_cmdBuffer, 0u);
	vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, 1u);
	vk.cmdWriteTimestamp(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, *m_queryPool, 0u);
	vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, 1u);
	vk.cmdCopyQueryPoolResults(*m_cmdBuffer, *m_queryPool, 0u, 1u, *m_resultBuffer, 0u, sizeof(TimestampWithAvailability), (VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT));
	vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
	endCommandBuffer(vk, *m_cmdBuffer);
}

tcu::TestStatus ResetTimestampQueryBeforeCopyTestInstance::iterate (void)
{
	const DeviceInterface&		vk			= m_context.getDeviceInterface();
	const VkDevice				vkDevice	= m_context.getDevice();
	const VkQueue				queue		= m_context.getUniversalQueue();
	TimestampWithAvailability	ta;

	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
	invalidateAlloc(vk, vkDevice, *m_resultBufferMemory);
	deMemcpy(&ta, m_resultBufferMemory->getHostPtr(), sizeof(ta));
	return ((ta.availability != 0)? tcu::TestStatus::fail("Availability bit nonzero after resetting query") : tcu::TestStatus::pass("Pass"));
}


class TwoCmdBuffersTest : public TimestampTest
{
public:
							TwoCmdBuffersTest	(tcu::TestContext&				testContext,
												 const std::string&				name,
												 const std::string&				description,
												 const TwoCmdBuffersTestParam*	param)
: TimestampTest (testContext, name, description, param), m_cmdBufferLevel(param->getCmdBufferLevel()) { }
	virtual					~TwoCmdBuffersTest	(void) { }
	virtual TestInstance*	createInstance		(Context&						context) const;

protected:
	VkCommandBufferLevel	m_cmdBufferLevel;
};

class TwoCmdBuffersTestInstance : public TimestampTestInstance
{
public:
							TwoCmdBuffersTestInstance	(Context&				context,
														 const StageFlagVector	stages,
														 const bool				inRenderPass,
														 const bool				hostQueryReset,
														 VkCommandBufferLevel	cmdBufferLevel);
	virtual					~TwoCmdBuffersTestInstance	(void);
	virtual tcu::TestStatus	iterate						(void);
protected:
	virtual void			configCommandBuffer			(void);

protected:
	Move<VkCommandBuffer>	m_secondCmdBuffer;
	Move<VkBuffer>			m_dstBuffer;
	de::MovePtr<Allocation> m_dstBufferAlloc;
	VkCommandBufferLevel	m_cmdBufferLevel;
};

TestInstance* TwoCmdBuffersTest::createInstance (Context& context) const
{
	return new TwoCmdBuffersTestInstance(context, m_stages, m_inRenderPass, m_hostQueryReset, m_cmdBufferLevel);
}

TwoCmdBuffersTestInstance::TwoCmdBuffersTestInstance (Context&					context,
													  const StageFlagVector		stages,
													  const bool				inRenderPass,
													  const bool				hostQueryReset,
													  VkCommandBufferLevel		cmdBufferLevel)
: TimestampTestInstance (context, stages, inRenderPass, hostQueryReset), m_cmdBufferLevel(cmdBufferLevel)
{
	const DeviceInterface&	vk			= context.getDeviceInterface();
	const VkDevice			vkDevice	= context.getDevice();

	m_secondCmdBuffer	= allocateCommandBuffer(vk, vkDevice, *m_cmdPool, cmdBufferLevel);
	m_dstBuffer			= createBufferAndBindMemory(1024, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, &m_dstBufferAlloc);
}

TwoCmdBuffersTestInstance::~TwoCmdBuffersTestInstance (void)
{
}

void TwoCmdBuffersTestInstance::configCommandBuffer (void)
{
	const DeviceInterface&			vk					= m_context.getDeviceInterface();

	const VkCommandBufferBeginInfo	cmdBufferBeginInfo	=
	{
		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType                          sType;
		DE_NULL,										// const void*                              pNext;
		0u,												// VkCommandBufferUsageFlags                flags;
		(const VkCommandBufferInheritanceInfo*)DE_NULL	// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
	};

	const vk::VkBufferMemoryBarrier bufferBarrier =
	{
		vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
		DE_NULL,										// const void*		pNext;
		vk::VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
		vk::VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
		VK_QUEUE_FAMILY_IGNORED,						// deUint32			srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,						// deUint32			dstQueueFamilyIndex;
		*m_dstBuffer,									// VkBuffer			buffer;
		0ull,											// VkDeviceSize		offset;
		VK_WHOLE_SIZE									// VkDeviceSize		size;
	};

	if (m_cmdBufferLevel == VK_COMMAND_BUFFER_LEVEL_PRIMARY)
	{
		VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
		if (!m_hostQueryReset)
			vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
		vk.cmdWriteTimestamp(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, *m_queryPool, 0);
		VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
		VK_CHECK(vk.beginCommandBuffer(*m_secondCmdBuffer, &cmdBufferBeginInfo));
		vk.cmdCopyQueryPoolResults(*m_secondCmdBuffer, *m_queryPool, 0u, 1u, *m_dstBuffer, 0u, 0u, VK_QUERY_RESULT_WAIT_BIT);
		vk.cmdPipelineBarrier(*m_secondCmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u,
							  0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
		VK_CHECK(vk.endCommandBuffer(*m_secondCmdBuffer));
	}
	else
	{
		const VkCommandBufferInheritanceInfo inheritanceInfo		=
		{
			VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,	// VkStructureType                  sType;
			DE_NULL,											// const void*                      pNext;
			DE_NULL,											// VkRenderPass                     renderPass;
			0u,													// deUint32                         subpass;
			DE_NULL,											// VkFramebuffer                    framebuffer;
			VK_FALSE,											// VkBool32                         occlusionQueryEnable;
			0u,													// VkQueryControlFlags              queryFlags;
			0u													// VkQueryPipelineStatisticFlags    pipelineStatistics;
		};

		const VkCommandBufferBeginInfo cmdBufferBeginInfoSecondary	=
		{
			VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType                          sType;
			DE_NULL,										// const void*                              pNext;
			0u,												// VkCommandBufferUsageFlags                flags;
			&inheritanceInfo								// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
		};

		VK_CHECK(vk.beginCommandBuffer(*m_secondCmdBuffer, &cmdBufferBeginInfoSecondary));
		vk.cmdResetQueryPool(*m_secondCmdBuffer, *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
		vk.cmdWriteTimestamp(*m_secondCmdBuffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, *m_queryPool, 0);
		VK_CHECK(vk.endCommandBuffer(*m_secondCmdBuffer));
		VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
		vk.cmdExecuteCommands(m_cmdBuffer.get(), 1u, &m_secondCmdBuffer.get());
		vk.cmdCopyQueryPoolResults(*m_cmdBuffer, *m_queryPool, 0u, 1u, *m_dstBuffer, 0u, 0u, VK_QUERY_RESULT_WAIT_BIT);
		vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u,
							  0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
		VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
	}
}

tcu::TestStatus TwoCmdBuffersTestInstance::iterate (void)
{
	const DeviceInterface&		vk				= m_context.getDeviceInterface();
	const VkQueue				queue			= m_context.getUniversalQueue();

	configCommandBuffer();

	const VkCommandBuffer		cmdBuffers[]	= { m_cmdBuffer.get(), m_secondCmdBuffer.get() };

	const VkSubmitInfo			submitInfo		=
	{
		VK_STRUCTURE_TYPE_SUBMIT_INFO,									// VkStructureType                sType;
		DE_NULL,														// const void*                    pNext;
		0u,																// deUint32                       waitSemaphoreCount;
		DE_NULL,														// const VkSemaphore*             pWaitSemaphores;
		(const VkPipelineStageFlags*)DE_NULL,							// const VkPipelineStageFlags*    pWaitDstStageMask;
		m_cmdBufferLevel == VK_COMMAND_BUFFER_LEVEL_PRIMARY ? 2u : 1u,	// deUint32                       commandBufferCount;
		cmdBuffers,														// const VkCommandBuffer*         pCommandBuffers;
		0u,																// deUint32                       signalSemaphoreCount;
		DE_NULL,														// const VkSemaphore*             pSignalSemaphores;
	};

	if (m_hostQueryReset)
	{
		// Only reset the pool for the primary command buffer, the secondary command buffer will reset the pool by itself.
		vk.resetQueryPool(m_context.getDevice(), *m_queryPool, 0u, TimestampTest::ENTRY_COUNT);
	}

	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, DE_NULL));
	VK_CHECK(vk.queueWaitIdle(queue));

	// Always pass in case no crash occurred.
	return tcu::TestStatus::pass("Pass");
}

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

class ConsistentQueryResultsTestInstance : public vkt::TestInstance
{
public:
							ConsistentQueryResultsTestInstance	(Context& context);
	virtual					~ConsistentQueryResultsTestInstance	(void) { }
	virtual tcu::TestStatus	iterate								(void);
protected:
	Move<VkCommandPool>		m_cmdPool;
	Move<VkCommandBuffer>	m_cmdBuffer;
	Move<VkQueryPool>		m_queryPool;

	deUint64				m_timestampMask;
	Move<VkBuffer>			m_resultBuffer32Bits;
	Move<VkBuffer>			m_resultBuffer64Bits;
	de::MovePtr<Allocation>	m_resultBufferMemory32Bits;
	de::MovePtr<Allocation>	m_resultBufferMemory64Bits;
};

void ConsistentQueryResultsTest::initPrograms(SourceCollections& programCollection) const
{
	vkt::TestCase::initPrograms(programCollection);
}

TestInstance* ConsistentQueryResultsTest::createInstance(Context& context) const
{
	return new ConsistentQueryResultsTestInstance(context);
}

ConsistentQueryResultsTestInstance::ConsistentQueryResultsTestInstance(Context& context)
	: vkt::TestInstance(context)
{
	const DeviceInterface&	vk					= context.getDeviceInterface();
	const VkDevice			vkDevice			= context.getDevice();
	const deUint32			queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
	Allocator&				allocator			= m_context.getDefaultAllocator();

	// Check support for timestamp queries
	m_timestampMask = checkTimestampsSupported(context);

	const VkQueryPoolCreateInfo queryPoolParams =
	{
		VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,	// VkStructureType               sType;
		DE_NULL,									// const void*                   pNext;
		0u,											// VkQueryPoolCreateFlags        flags;
		VK_QUERY_TYPE_TIMESTAMP,					// VkQueryType                   queryType;
		1u,											// deUint32                      entryCount;
		0u,											// VkQueryPipelineStatisticFlags pipelineStatistics;
	};

	m_queryPool		= createQueryPool(vk, vkDevice, &queryPoolParams);
	m_cmdPool		= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
	m_cmdBuffer		= allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

	// Create results buffer.
	VkBufferCreateInfo bufferCreateInfo =
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
		DE_NULL,									// const void*			pNext;
		0u,											// VkBufferCreateFlags	flags;
		0u,											// VkDeviceSize			size;
		VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
		1u,											// deUint32				queueFamilyIndexCount;
		&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
	};

	// 32 bits.
	bufferCreateInfo.size		= sizeof(deUint32);
	m_resultBuffer32Bits		= createBuffer(vk, vkDevice, &bufferCreateInfo);
	m_resultBufferMemory32Bits	= allocator.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_resultBuffer32Bits), MemoryRequirement::HostVisible);
	VK_CHECK(vk.bindBufferMemory(vkDevice, *m_resultBuffer32Bits, m_resultBufferMemory32Bits->getMemory(), m_resultBufferMemory32Bits->getOffset()));

	// 64 bits.
	bufferCreateInfo.size		= sizeof(deUint64);
	m_resultBuffer64Bits		= createBuffer(vk, vkDevice, &bufferCreateInfo);
	m_resultBufferMemory64Bits	= allocator.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_resultBuffer64Bits), MemoryRequirement::HostVisible);
	VK_CHECK(vk.bindBufferMemory(vkDevice, *m_resultBuffer64Bits, m_resultBufferMemory64Bits->getMemory(), m_resultBufferMemory64Bits->getOffset()));

	vk::VkBufferMemoryBarrier bufferBarrier =
	{
		vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
		DE_NULL,										// const void*		pNext;
		vk::VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
		vk::VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
		VK_QUEUE_FAMILY_IGNORED,						// deUint32			srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,						// deUint32			dstQueueFamilyIndex;
		DE_NULL,										// VkBuffer			buffer;
		0ull,											// VkDeviceSize		offset;
		VK_WHOLE_SIZE									// VkDeviceSize		size;
	};

	// Prepare command buffer.
	beginCommandBuffer(vk, *m_cmdBuffer, 0u);
	vk.cmdResetQueryPool(*m_cmdBuffer, *m_queryPool, 0u, 1u);
	vk.cmdWriteTimestamp(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, *m_queryPool, 0u);

	// 32 bits.
	bufferBarrier.buffer = *m_resultBuffer32Bits;
	vk.cmdCopyQueryPoolResults(*m_cmdBuffer, *m_queryPool, 0u, 1u, *m_resultBuffer32Bits, 0u, sizeof(deUint32), VK_QUERY_RESULT_WAIT_BIT);
	vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);

	// 64 bits.
	bufferBarrier.buffer = *m_resultBuffer64Bits;
	vk.cmdCopyQueryPoolResults(*m_cmdBuffer, *m_queryPool, 0u, 1u, *m_resultBuffer64Bits, 0u, sizeof(deUint64), (VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT));
	vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);

	endCommandBuffer(vk, *m_cmdBuffer);
}

tcu::TestStatus ConsistentQueryResultsTestInstance::iterate(void)
{
	const DeviceInterface&      vk          = m_context.getDeviceInterface();
	const VkDevice              vkDevice    = m_context.getDevice();
	const VkQueue               queue       = m_context.getUniversalQueue();

	deUint32					tsBuffer32Bits;
	deUint64					tsBuffer64Bits;
	deUint32					tsGet32Bits;
	deUint64					tsGet64Bits;

	constexpr deUint32			maxDeUint32Value = std::numeric_limits<deUint32>::max();

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

	// Get results from buffers.
	invalidateAlloc(vk, vkDevice, *m_resultBufferMemory32Bits);
	invalidateAlloc(vk, vkDevice, *m_resultBufferMemory64Bits);
	deMemcpy(&tsBuffer32Bits, m_resultBufferMemory32Bits->getHostPtr(), sizeof(tsBuffer32Bits));
	deMemcpy(&tsBuffer64Bits, m_resultBufferMemory64Bits->getHostPtr(), sizeof(tsBuffer64Bits));

	// Get results with vkGetQueryPoolResults().
	VK_CHECK(vk.getQueryPoolResults(vkDevice, *m_queryPool, 0u, 1u, sizeof(tsGet32Bits), &tsGet32Bits, sizeof(tsGet32Bits), VK_QUERY_RESULT_WAIT_BIT));
	VK_CHECK(vk.getQueryPoolResults(vkDevice, *m_queryPool, 0u, 1u, sizeof(tsGet64Bits), &tsGet64Bits, sizeof(tsGet64Bits), (VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT)));

	// Check timestamp mask for both 64-bit results.
	checkTimestampBits(tsBuffer64Bits, m_timestampMask);
	checkTimestampBits(tsGet64Bits, m_timestampMask);

	// Check results are consistent.
	if (tsBuffer32Bits == tsGet32Bits &&
		tsBuffer64Bits == tsGet64Bits &&
		(((tsGet64Bits & maxDeUint32Value) == tsGet32Bits) ||
		((tsGet64Bits > maxDeUint32Value) && (maxDeUint32Value == tsGet32Bits))))
	{
		return tcu::TestStatus::pass("Pass");
	}

	std::ostringstream msg;
	msg << std::hex << "Results are inconsistent:"
		<< " B32=0x" << tsBuffer32Bits
		<< " B64=0x" << tsBuffer64Bits
		<< " G32=0x" << tsGet32Bits
		<< " G64=0x" << tsGet64Bits;
	return tcu::TestStatus::fail(msg.str());
}

} // anonymous

tcu::TestCaseGroup* createTimestampTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> timestampTests (new tcu::TestCaseGroup(testCtx, "timestamp", "timestamp tests"));

	// Basic Graphics Tests
	{
		de::MovePtr<tcu::TestCaseGroup> basicGraphicsTests (new tcu::TestCaseGroup(testCtx, "basic_graphics_tests", "Record timestamp in different pipeline stages of basic graphics tests"));

		const VkPipelineStageFlagBits basicGraphicsStages0[][2] =
		{
		  {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_VERTEX_INPUT_BIT},
		  {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_VERTEX_SHADER_BIT},
		  {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT},
		  {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT},
		  {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT},
		  {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT},
		  {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT},
		  {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,   VK_PIPELINE_STAGE_ALL_COMMANDS_BIT},
		};
		for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(basicGraphicsStages0); stageNdx++)
		{
			TimestampTestParam param(basicGraphicsStages0[stageNdx], 2u, true, false);
			basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, &param));
			param.toggleInRenderPass();
			basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, &param));
			// Host Query reset tests
			param.toggleHostQueryReset();
			basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, &param));
			param.toggleInRenderPass();
			basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, &param));
		}

		const VkPipelineStageFlagBits basicGraphicsStages1[][3] =
		{
		  {VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,      VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT},
		  {VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,  VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT},
		};
		for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(basicGraphicsStages1); stageNdx++)
		{
			TimestampTestParam param(basicGraphicsStages1[stageNdx], 3u, true, false);
			basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, &param));
			param.toggleInRenderPass();
			basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, &param));
			// Host Query reset tests
			param.toggleHostQueryReset();
			basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, &param));
			param.toggleInRenderPass();
			basicGraphicsTests->addChild(newTestCase<BasicGraphicsTest>(testCtx, &param));
		}

		timestampTests->addChild(basicGraphicsTests.release());
	}

	// Advanced Graphics Tests
	{
		de::MovePtr<tcu::TestCaseGroup> advGraphicsTests (new tcu::TestCaseGroup(testCtx, "advanced_graphics_tests", "Record timestamp in different pipeline stages of advanced graphics tests"));

		const VkPipelineStageFlagBits advGraphicsStages[][2] =
		{
			{VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT},
			{VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT},
			{VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT},
			{VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT},
		};
		for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(advGraphicsStages); stageNdx++)
		{
			TimestampTestParam param(advGraphicsStages[stageNdx], 2u, true, false);
			advGraphicsTests->addChild(newTestCase<AdvGraphicsTest>(testCtx, &param));
			param.toggleInRenderPass();
			advGraphicsTests->addChild(newTestCase<AdvGraphicsTest>(testCtx, &param));
			// Host Query reset tests
			param.toggleHostQueryReset();
			advGraphicsTests->addChild(newTestCase<AdvGraphicsTest>(testCtx, &param));
			param.toggleInRenderPass();
			advGraphicsTests->addChild(newTestCase<AdvGraphicsTest>(testCtx, &param));
		}

		timestampTests->addChild(advGraphicsTests.release());
	}

	// Basic Compute Tests
	{
		de::MovePtr<tcu::TestCaseGroup> basicComputeTests (new tcu::TestCaseGroup(testCtx, "basic_compute_tests", "Record timestamp for compute stages"));

		const VkPipelineStageFlagBits basicComputeStages[][2] =
		{
			{VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT},
			{VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT},
		};
		for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(basicComputeStages); stageNdx++)
		{
			TimestampTestParam param(basicComputeStages[stageNdx], 2u, false, false);
			basicComputeTests->addChild(newTestCase<BasicComputeTest>(testCtx, &param));
			// Host Query reset test
			param.toggleHostQueryReset();
			basicComputeTests->addChild(newTestCase<BasicComputeTest>(testCtx, &param));
		}

		timestampTests->addChild(basicComputeTests.release());
	}

	// Transfer Tests
	{
		de::MovePtr<tcu::TestCaseGroup> transferTests (new tcu::TestCaseGroup(testCtx, "transfer_tests", "Record timestamp for transfer stages"));

		const VkPipelineStageFlagBits transferStages[][2] =
		{
			{VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT},
			{VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_HOST_BIT},
		};
		for (deUint32 stageNdx = 0u; stageNdx < DE_LENGTH_OF_ARRAY(transferStages); stageNdx++)
		{
			for (deUint32 method = 0u; method < TRANSFER_METHOD_LAST; method++)
			{
				TransferTimestampTestParam param(transferStages[stageNdx], 2u, false, false, method);
				transferTests->addChild(newTestCase<TransferTest>(testCtx, &param));
				// Host Query reset test
				param.toggleHostQueryReset();
				transferTests->addChild(newTestCase<TransferTest>(testCtx, &param));
			}
		}

		timestampTests->addChild(transferTests.release());
	}

	// Calibrated Timestamp Tests.
	{
		de::MovePtr<tcu::TestCaseGroup> calibratedTimestampTests (new tcu::TestCaseGroup(testCtx, "calibrated", "VK_EXT_calibrated_timestamps tests"));

		calibratedTimestampTests->addChild(new CalibratedTimestampTest<CalibratedTimestampDevDomainTestInstance>	(testCtx, "dev_domain_test",	"Test device domain"));
		calibratedTimestampTests->addChild(new CalibratedTimestampTest<CalibratedTimestampHostDomainTestInstance>	(testCtx, "host_domain_test",	"Test host domain"));
		calibratedTimestampTests->addChild(new CalibratedTimestampTest<CalibratedTimestampCalibrationTestInstance>	(testCtx, "calibration_test",	"Test calibration using device and host domains"));

		timestampTests->addChild(calibratedTimestampTests.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 VkPipelineStageFlagBits miscStages[] = {VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT};
		TimestampTestParam param(miscStages, 1u, false, false);
		miscTests->addChild(new TimestampTest(testCtx,
											  "timestamp_only",
											  "Only write timestamp command in the commmand buffer",
											  &param));

		TwoCmdBuffersTestParam twoCmdBuffersParamPrimary(miscStages, 1u, false, false, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
		miscTests->addChild(new TwoCmdBuffersTest(testCtx,
												  "two_cmd_buffers_primary",
												  "Issue query in a command buffer and copy it on another primary command buffer",
												  &twoCmdBuffersParamPrimary));

		TwoCmdBuffersTestParam twoCmdBuffersParamSecondary(miscStages, 1u, false, false, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
		miscTests->addChild(new TwoCmdBuffersTest(testCtx,
												  "two_cmd_buffers_secondary",
												  "Issue query in a secondary command buffer and copy it on a primary command buffer",
												  &twoCmdBuffersParamSecondary));
		// Misc: Host Query Reset tests
		param.toggleHostQueryReset();
		miscTests->addChild(new TimestampTest(testCtx,
											  "timestamp_only_host_query_reset",
											  "Only write timestamp command in the commmand buffer",
											  &param));
		TwoCmdBuffersTestParam twoCmdBuffersParamPrimaryHostQueryReset(miscStages, 1u, false, true, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
		miscTests->addChild(new TwoCmdBuffersTest(testCtx,
												  "two_cmd_buffers_primary_host_query_reset",
												  "Issue query in a command buffer and copy it on another primary command buffer",
												  &twoCmdBuffersParamPrimaryHostQueryReset));

		TwoCmdBuffersTestParam twoCmdBuffersParamSecondaryHostQueryReset(miscStages, 1u, false, true, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
		miscTests->addChild(new TwoCmdBuffersTest(testCtx,
												  "two_cmd_buffers_secondary_host_query_reset",
												  "Issue query in a secondary command buffer and copy it on a primary command buffer",
												  &twoCmdBuffersParamSecondaryHostQueryReset));

		// Reset timestamp query before copying results.
		miscTests->addChild(new ResetTimestampQueryBeforeCopyTest(testCtx,
																  "reset_query_before_copy",
																  "Issue a timestamp query and reset it before copying results"));

		// Check consistency between 32 and 64 bits.
		miscTests->addChild(new ConsistentQueryResultsTest(testCtx,
														   "consistent_results",
														   "Check consistency between 32-bit and 64-bit timestamp"));

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

	return timestampTests.release();
}

} // pipeline

} // vkt
