#ifndef _VKTTESSELLATIONUTIL_HPP
#define _VKTTESSELLATIONUTIL_HPP
/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2014 The Android Open Source Project
 * Copyright (c) 2016 The Khronos Group Inc.
 *
 * 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 Tessellation Utilities
 *//*--------------------------------------------------------------------*/

#include "vkDefs.hpp"
#include "vkMemUtil.hpp"
#include "vkRef.hpp"
#include "vkPrograms.hpp"
#include "vkRefUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkObjUtil.hpp"
#include "vktTestCase.hpp"

#include "tcuVector.hpp"
#include "tcuMaybe.hpp"

#include "deStringUtil.hpp"

#include <algorithm>  // sort
#include <iterator>   // distance

namespace vkt
{
namespace tessellation
{

class Buffer
{
public:
										Buffer			(const vk::DeviceInterface&		vk,
														 const vk::VkDevice				device,
														 vk::Allocator&					allocator,
														 const vk::VkBufferCreateInfo&	bufferCreateInfo,
														 const vk::MemoryRequirement	memoryRequirement)

											: m_buffer		(createBuffer(vk, device, &bufferCreateInfo))
											, m_allocation	(allocator.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), memoryRequirement))
										{
											VK_CHECK(vk.bindBufferMemory(device, *m_buffer, m_allocation->getMemory(), m_allocation->getOffset()));
										}

	const vk::VkBuffer&					get				(void) const { return *m_buffer; }
	const vk::VkBuffer&					operator*		(void) const { return get(); }
	vk::Allocation&						getAllocation	(void) const { return *m_allocation; }

private:
	const vk::Unique<vk::VkBuffer>		m_buffer;
	const de::UniquePtr<vk::Allocation>	m_allocation;

	// "deleted"
										Buffer			(const Buffer&);
	Buffer&								operator=		(const Buffer&);
};

class Image
{
public:
										Image			(const vk::DeviceInterface&		vk,
														 const vk::VkDevice				device,
														 vk::Allocator&					allocator,
														 const vk::VkImageCreateInfo&	imageCreateInfo,
														 const vk::MemoryRequirement	memoryRequirement)

											: m_image		(createImage(vk, device, &imageCreateInfo))
											, m_allocation	(allocator.allocate(getImageMemoryRequirements(vk, device, *m_image), memoryRequirement))
										{
											VK_CHECK(vk.bindImageMemory(device, *m_image, m_allocation->getMemory(), m_allocation->getOffset()));
										}

	const vk::VkImage&					get				(void) const { return *m_image; }
	const vk::VkImage&					operator*		(void) const { return get(); }
	vk::Allocation&						getAllocation	(void) const { return *m_allocation; }

private:
	const vk::Unique<vk::VkImage>		m_image;
	const de::UniquePtr<vk::Allocation>	m_allocation;

	// "deleted"
										Image			(const Image&);
	Image&								operator=		(const Image&);
};

class GraphicsPipelineBuilder
{
public:
								GraphicsPipelineBuilder	(void) : m_renderSize				(0, 0)
															   , m_shaderStageFlags			(0u)
															   , m_cullModeFlags			(vk::VK_CULL_MODE_NONE)
															   , m_frontFace				(vk::VK_FRONT_FACE_COUNTER_CLOCKWISE)
															   , m_patchControlPoints		(1u)
															   , m_blendEnable				(false)
															   , m_primitiveTopology		(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
															   , m_tessellationDomainOrigin	(tcu::Nothing) {}

	GraphicsPipelineBuilder&	setRenderSize					(const tcu::IVec2& size) { m_renderSize = size; return *this; }
	GraphicsPipelineBuilder&	setShader						(const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkShaderStageFlagBits stage, const vk::ProgramBinary& binary, const vk::VkSpecializationInfo* specInfo);
	GraphicsPipelineBuilder&	setPatchControlPoints			(const deUint32 controlPoints) { m_patchControlPoints = controlPoints; return *this; }
	GraphicsPipelineBuilder&	setCullModeFlags				(const vk::VkCullModeFlags cullModeFlags) { m_cullModeFlags = cullModeFlags; return *this; }
	GraphicsPipelineBuilder&	setFrontFace					(const vk::VkFrontFace frontFace) { m_frontFace = frontFace; return *this; }
	GraphicsPipelineBuilder&	setBlend						(const bool enable) { m_blendEnable = enable; return *this; }

	//! Applies only to pipelines without tessellation shaders.
	GraphicsPipelineBuilder&	setPrimitiveTopology			(const vk::VkPrimitiveTopology topology) { m_primitiveTopology = topology; return *this; }

	GraphicsPipelineBuilder&	addVertexBinding				(const vk::VkVertexInputBindingDescription vertexBinding) { m_vertexInputBindings.push_back(vertexBinding); return *this; }
	GraphicsPipelineBuilder&	addVertexAttribute				(const vk::VkVertexInputAttributeDescription vertexAttribute) { m_vertexInputAttributes.push_back(vertexAttribute); return *this; }

	//! Basic vertex input configuration (uses biding 0, location 0, etc.)
	GraphicsPipelineBuilder&	setVertexInputSingleAttribute	(const vk::VkFormat vertexFormat, const deUint32 stride);

	//! If tessellation domain origin is set, pipeline requires VK__maintenance2
	GraphicsPipelineBuilder&	setTessellationDomainOrigin		(const vk::VkTessellationDomainOrigin domainOrigin) { return setTessellationDomainOrigin(tcu::just(domainOrigin)); }
	GraphicsPipelineBuilder&	setTessellationDomainOrigin		(const tcu::Maybe<vk::VkTessellationDomainOrigin>& domainOrigin) { m_tessellationDomainOrigin = domainOrigin; return *this; }

	vk::Move<vk::VkPipeline>	build							(const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkPipelineLayout pipelineLayout, const vk::VkRenderPass renderPass);

private:
	tcu::IVec2											m_renderSize;
	vk::Move<vk::VkShaderModule>						m_vertexShaderModule;
	vk::Move<vk::VkShaderModule>						m_fragmentShaderModule;
	vk::Move<vk::VkShaderModule>						m_geometryShaderModule;
	vk::Move<vk::VkShaderModule>						m_tessControlShaderModule;
	vk::Move<vk::VkShaderModule>						m_tessEvaluationShaderModule;
	std::vector<vk::VkPipelineShaderStageCreateInfo>	m_shaderStages;
	std::vector<vk::VkVertexInputBindingDescription>	m_vertexInputBindings;
	std::vector<vk::VkVertexInputAttributeDescription>	m_vertexInputAttributes;
	vk::VkShaderStageFlags								m_shaderStageFlags;
	vk::VkCullModeFlags									m_cullModeFlags;
	vk::VkFrontFace										m_frontFace;
	deUint32											m_patchControlPoints;
	bool												m_blendEnable;
	vk::VkPrimitiveTopology								m_primitiveTopology;
	tcu::Maybe<vk::VkTessellationDomainOrigin>			m_tessellationDomainOrigin;

	GraphicsPipelineBuilder (const GraphicsPipelineBuilder&); // "deleted"
	GraphicsPipelineBuilder& operator= (const GraphicsPipelineBuilder&);
};

struct TessLevels
{
	float inner[2];
	float outer[4];
};

enum TessPrimitiveType
{
	TESSPRIMITIVETYPE_TRIANGLES = 0,
	TESSPRIMITIVETYPE_QUADS,
	TESSPRIMITIVETYPE_ISOLINES,

	TESSPRIMITIVETYPE_LAST,
};

enum SpacingMode
{
	SPACINGMODE_EQUAL = 0,
	SPACINGMODE_FRACTIONAL_ODD,
	SPACINGMODE_FRACTIONAL_EVEN,

	SPACINGMODE_LAST,
};

enum Winding
{
	WINDING_CCW = 0,
	WINDING_CW,

	WINDING_LAST,
};

enum ShaderLanguage
{
	SHADER_LANGUAGE_GLSL = 0,
	SHADER_LANGUAGE_HLSL = 1,

	SHADER_LANGUAGE_LAST,
};

enum FeatureFlagBits
{
	FEATURE_TESSELLATION_SHADER							= 1u << 0,
	FEATURE_GEOMETRY_SHADER								= 1u << 1,
	FEATURE_SHADER_FLOAT_64								= 1u << 2,
	FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS			= 1u << 3,
	FEATURE_FRAGMENT_STORES_AND_ATOMICS					= 1u << 4,
	FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE	= 1u << 5,
};
typedef deUint32 FeatureFlags;

vk::VkImageCreateInfo			makeImageCreateInfo							(const tcu::IVec2& size, const vk::VkFormat format, const vk::VkImageUsageFlags usage, const deUint32 numArrayLayers);
vk::Move<vk::VkPipeline>		makeComputePipeline							(const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkPipelineLayout pipelineLayout, const vk::VkShaderModule shaderModule, const vk::VkSpecializationInfo* specInfo);
vk::Move<vk::VkRenderPass>		makeRenderPassWithoutAttachments			(const vk::DeviceInterface& vk, const vk::VkDevice device);
vk::VkBufferImageCopy			makeBufferImageCopy							(const vk::VkExtent3D extent, const vk::VkImageSubresourceLayers subresourceLayers);
void							beginRenderPassWithRasterizationDisabled	(const vk::DeviceInterface& vk, const vk::VkCommandBuffer commandBuffer, const vk::VkRenderPass renderPass, const vk::VkFramebuffer framebuffer);
void							requireFeatures								(const vk::InstanceInterface& vki, const vk::VkPhysicalDevice physDevice, const FeatureFlags flags);
float							getClampedTessLevel							(const SpacingMode mode, const float tessLevel);
int								getRoundedTessLevel							(const SpacingMode mode, const float clampedTessLevel);
int								getClampedRoundedTessLevel					(const SpacingMode mode, const float tessLevel);
void							getClampedRoundedTriangleTessLevels			(const SpacingMode mode, const float* innerSrc, const float* outerSrc, int* innerDst, int* outerDst);
void							getClampedRoundedQuadTessLevels				(const SpacingMode mode, const float* innerSrc, const float* outerSrc, int* innerDst, int* outerDst);
void							getClampedRoundedIsolineTessLevels			(const SpacingMode mode, const float* outerSrc, int* outerDst);
int								numOuterTessellationLevels					(const TessPrimitiveType primitiveType);
std::string						getTessellationLevelsString					(const TessLevels& tessLevels, const TessPrimitiveType primitiveType);
std::string						getTessellationLevelsString					(const float* inner, const float* outer);
bool							isPatchDiscarded							(const TessPrimitiveType primitiveType, const float* outerLevels);
std::vector<tcu::Vec3>			generateReferenceTriangleTessCoords			(const SpacingMode spacingMode, const int inner, const int outer0, const int outer1, const int outer2);
std::vector<tcu::Vec3>			generateReferenceQuadTessCoords				(const SpacingMode spacingMode, const int inner0, const int inner1, const int outer0, const int outer1, const int outer2, const int outer3);
std::vector<tcu::Vec3>			generateReferenceIsolineTessCoords			(const int outer0, const int outer1);
int								referenceVertexCount						(const TessPrimitiveType primitiveType, const SpacingMode spacingMode, const bool usePointMode, const float* innerLevels, const float* outerLevels);
int								referencePrimitiveCount						(const TessPrimitiveType primitiveType, const SpacingMode spacingMode, const bool usePointMode, const float* innerLevels, const float* outerLevels);
int								numVerticesPerPrimitive						(const TessPrimitiveType primitiveType, const bool usePointMode);

static inline const char* getTessPrimitiveTypeShaderName (const TessPrimitiveType type, bool forSpirv = false)
{
	static std::string primitiveName[][2] =
	{
		// glsl name	spirv name
		{ "triangles", "Triangles"},
		{ "quads"	 , "Quads" },
		{ "isolines" , "Isolines" }
	};

	if (type >= TESSPRIMITIVETYPE_LAST)
	{
		DE_FATAL("Unexpected primitive type.");
		return DE_NULL;
	}

	return primitiveName[type][forSpirv].c_str();
}

static inline const char* getDomainName (const TessPrimitiveType type)
{
	switch (type)
	{
		case TESSPRIMITIVETYPE_TRIANGLES:	return "tri";
		case TESSPRIMITIVETYPE_QUADS:		return "quad";
		case TESSPRIMITIVETYPE_ISOLINES:	return "isoline";
		default:
			DE_FATAL("Unexpected primitive type.");
			return DE_NULL;
	}
}

static inline const char* getOutputTopologyName (const TessPrimitiveType type, const Winding winding, const bool usePointMode)
{
	if (usePointMode)
		return "point";
	else if (type == TESSPRIMITIVETYPE_TRIANGLES || type == TESSPRIMITIVETYPE_QUADS)
		return (winding == WINDING_CCW ? "triangle_ccw" : "triangle_cw");
	else if (type == TESSPRIMITIVETYPE_ISOLINES)
		return "line";

	DE_FATAL("Unexpected primitive type.");
	return DE_NULL;
}

static inline const char* getSpacingModeShaderName (SpacingMode mode, bool forSpirv = false)
{
	static std::string spacingName[][2] =
	{
		// glsl name					spirv name
		{ "equal_spacing",				"SpacingEqual"},
		{ "fractional_odd_spacing",		"SpacingFractionalOdd" },
		{ "fractional_even_spacing",	"SpacingFractionalEven" }
	};

	if (mode >= SPACINGMODE_LAST)
	{
		DE_FATAL("Unexpected spacing type.");
		return DE_NULL;
	}

	return spacingName[mode][forSpirv].c_str();
}

static inline const char* getPartitioningShaderName (SpacingMode mode)
{
	switch (mode)
	{
		case SPACINGMODE_EQUAL:				return "integer";
		case SPACINGMODE_FRACTIONAL_ODD:	return "fractional_odd";
		case SPACINGMODE_FRACTIONAL_EVEN:	return "fractional_even";
		default:
			DE_FATAL("Unexpected spacing mode.");
			return DE_NULL;
	}
}

static inline const char* getWindingShaderName (const Winding winding)
{
	switch (winding)
	{
		case WINDING_CCW:	return "ccw";
		case WINDING_CW:	return "cw";
		default:
			DE_FATAL("Unexpected winding type.");
			return DE_NULL;
	}
}

static inline const char* getShaderLanguageName (const ShaderLanguage language)
{
	switch (language)
	{
		case SHADER_LANGUAGE_GLSL:	return "glsl";
		case SHADER_LANGUAGE_HLSL:	return "hlsl";
		default:
			DE_FATAL("Unexpected shader language.");
			return DE_NULL;
	}
}

static inline const char* getGeometryShaderInputPrimitiveTypeShaderName (const TessPrimitiveType type, const bool usePointMode)
{
	if (usePointMode)
		return "points";

	switch (type)
	{
		case TESSPRIMITIVETYPE_TRIANGLES:
		case TESSPRIMITIVETYPE_QUADS:
			return "triangles";

		case TESSPRIMITIVETYPE_ISOLINES:
			return "lines";

		default:
			DE_FATAL("Unexpected primitive type.");
			return DE_NULL;
	}
}

static inline const char* getGeometryShaderOutputPrimitiveTypeShaderName (const TessPrimitiveType type, const bool usePointMode)
{
	if (usePointMode)
		return "points";

	switch (type)
	{
		case TESSPRIMITIVETYPE_TRIANGLES:
		case TESSPRIMITIVETYPE_QUADS:
			return "triangle_strip";

		case TESSPRIMITIVETYPE_ISOLINES:
			return "line_strip";

		default:
			DE_FATAL("Unexpected primitive type.");
			return DE_NULL;
	}
}

static inline const vk::VkPhysicalDevicePortabilitySubsetFeaturesKHR* getPortability (const Context& context)
{
	if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset"))
		return &context.getPortabilitySubsetFeatures();
	return DE_NULL;
}

static inline void checkIsolines (const vk::VkPhysicalDevicePortabilitySubsetFeaturesKHR& features)
{
	if (!features.tessellationIsolines)
		TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Tessellation iso lines are not supported by this implementation");
}

static inline void checkPrimitive (const vk::VkPhysicalDevicePortabilitySubsetFeaturesKHR& features, const TessPrimitiveType primitive)
{
	if (primitive == TESSPRIMITIVETYPE_ISOLINES)
		checkIsolines(features);
}

static inline void checkSupportPrimitive (Context& context, const TessPrimitiveType primitive)
{
	if (const vk::VkPhysicalDevicePortabilitySubsetFeaturesKHR* const features = getPortability(context))
		checkPrimitive(*features, primitive);
}

static inline void checkPointMode (const vk::VkPhysicalDevicePortabilitySubsetFeaturesKHR& features)
{
	if (!features.tessellationPointMode)
		TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Tessellation point mode is not supported by this implementation");
}

template<typename T>
inline std::size_t sizeInBytes (const std::vector<T>& vec)
{
	return vec.size() * sizeof(vec[0]);
}

template <typename T>
static std::vector<T> sorted (const std::vector<T>& unsorted)
{
	std::vector<T> result = unsorted;
	std::sort(result.begin(), result.end());
	return result;
}

template <typename T, typename P>
static std::vector<T> sorted (const std::vector<T>& unsorted, P pred)
{
	std::vector<T> result = unsorted;
	std::sort(result.begin(), result.end(), pred);
	return result;
}

template <typename IterT>
std::string elemsStr (const IterT& begin, const IterT& end, int wrapLengthParam = 0, int numIndentationSpaces = 0)
{
	const int			bigInt			= ~0u/2;
	const std::string	baseIndentation	= std::string(numIndentationSpaces, ' ');
	const std::string	deepIndentation	= baseIndentation + std::string(4, ' ');
	const int			wrapLength		= wrapLengthParam > 0 ? wrapLengthParam : bigInt;
	const int			length			= static_cast<int>(std::distance(begin, end));
	std::string			result;

	if (length > wrapLength)
		result += "(amount: " + de::toString(length) + ") ";
	result += std::string() + "{" + (length > wrapLength ? "\n"+deepIndentation : " ");

	{
		int index = 0;
		for (IterT it = begin; it != end; ++it)
		{
			if (it != begin)
				result += std::string() + ", " + (index % wrapLength == 0 ? "\n"+deepIndentation : "");
			result += de::toString(*it);
			index++;
		}

		result += length > wrapLength ? "\n"+baseIndentation : " ";
	}

	result += "}";
	return result;
}

template <typename ContainerT>
std::string containerStr (const ContainerT& c, int wrapLengthParam = 0, int numIndentationSpaces = 0)
{
	return elemsStr(c.begin(), c.end(), wrapLengthParam, numIndentationSpaces);
}

//! Copy 'count' objects of type T from 'memory' into a vector.
//! 'offset' is the offset of first object in memory, and 'stride' is the distance between consecutive objects.
template<typename T>
std::vector<T> readInterleavedData (const int count, const void* memory, const int offset, const int stride)
{
	std::vector<T> results(count);
	const deUint8* pData = static_cast<const deUint8*>(memory) + offset;

	for (int i = 0; i < count; ++i)
	{
		deMemcpy(&results[i], pData, sizeof(T));
		pData += stride;
	}

	return results;
}

template <typename CaseDef, typename = bool>
struct PointMode
{
	static void check(const vk::VkPhysicalDevicePortabilitySubsetFeaturesKHR&, const CaseDef)
	{
	}
};

template <typename CaseDef>
struct PointMode<CaseDef, decltype(CaseDef().usePointMode)>
{
	static void check(const vk::VkPhysicalDevicePortabilitySubsetFeaturesKHR& features, const CaseDef caseDef)
	{
		if (caseDef.usePointMode)
			checkPointMode(features);
	}
};

template <typename CaseDef>
void checkSupportCase (Context& context, const CaseDef caseDef)
{
	if (const vk::VkPhysicalDevicePortabilitySubsetFeaturesKHR* const features = getPortability(context))
	{
		PointMode<CaseDef>::check(*features, caseDef);
		checkPrimitive(*features, caseDef.primitiveType);
	}
}

} // tessellation
} // vkt

#endif // _VKTTESSELLATIONUTIL_HPP
