/*------------------------------------------------------------------------
 * 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 Geometry Interaction - Passthrough
*//*--------------------------------------------------------------------*/

#include "vktTessellationGeometryPassthroughTests.hpp"
#include "vktTestCaseUtil.hpp"
#include "vktTessellationUtil.hpp"

#include "tcuTestLog.hpp"
#include "tcuImageCompare.hpp"

#include "vkDefs.hpp"
#include "vkBarrierUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkBuilderUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"

#include "deUniquePtr.hpp"

#include <string>
#include <vector>

namespace vkt
{
namespace tessellation
{

using namespace vk;

namespace
{

void addVertexAndFragmentShaders (vk::SourceCollections&  programCollection)
{
	// Vertex shader
	{
		std::ostringstream src;
		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
			<< "\n"
			<< "layout(location = 0) in  highp vec4 a_position;\n"
			<< "layout(location = 0) out highp vec4 v_vertex_color;\n"
			<< "\n"
			<< "void main (void)\n"
			<< "{\n"
			<< "    gl_Position = a_position;\n"
			<< "    v_vertex_color = vec4(a_position.x * 0.5 + 0.5, a_position.y * 0.5 + 0.5, 1.0, 0.4);\n"
			<< "}\n";

		programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
	}

	// Fragment shader
	{
		std::ostringstream src;
		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
			<< "\n"
			<< "layout(location = 0) in  highp   vec4 v_fragment_color;\n"
			<< "layout(location = 0) out mediump vec4 fragColor;\n"
			<< "void main (void)\n"
			<< "{\n"
			<< "	fragColor = v_fragment_color;\n"
			<< "}\n";

		programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
	}
}

//! Tessellation evaluation shader used in passthrough geometry shader case.
std::string generateTessellationEvaluationShader (const TessPrimitiveType primitiveType, const std::string& colorOutputName)
{
	std::ostringstream	src;
	src <<	glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
		<< "#extension GL_EXT_tessellation_shader : require\n"
		<< "layout(" << getTessPrimitiveTypeShaderName(primitiveType) << ") in;\n"
		<< "\n"
		<< "layout(location = 0) in  highp vec4 v_patch_color[];\n"
		<< "layout(location = 0) out highp vec4 " << colorOutputName << ";\n"
		<< "\n"
		<< "// note: No need to use precise gl_Position since we do not require gapless geometry\n"
		<< "void main (void)\n"
		<< "{\n";

	if (primitiveType == TESSPRIMITIVETYPE_TRIANGLES)
		src << "    vec3 weights = vec3(pow(gl_TessCoord.x, 1.3), pow(gl_TessCoord.y, 1.3), pow(gl_TessCoord.z, 1.3));\n"
			<< "    vec3 cweights = gl_TessCoord;\n"
			<< "    gl_Position = vec4(weights.x * gl_in[0].gl_Position.xyz + weights.y * gl_in[1].gl_Position.xyz + weights.z * gl_in[2].gl_Position.xyz, 1.0);\n"
			<< "    " << colorOutputName << " = cweights.x * v_patch_color[0] + cweights.y * v_patch_color[1] + cweights.z * v_patch_color[2];\n";
	else if (primitiveType == TESSPRIMITIVETYPE_QUADS || primitiveType == TESSPRIMITIVETYPE_ISOLINES)
		src << "    vec2 normalizedCoord = (gl_TessCoord.xy * 2.0 - vec2(1.0));\n"
			<< "    vec2 normalizedWeights = normalizedCoord * (vec2(1.0) - 0.3 * cos(normalizedCoord.yx * 1.57));\n"
			<< "    vec2 weights = normalizedWeights * 0.5 + vec2(0.5);\n"
			<< "    vec2 cweights = gl_TessCoord.xy;\n"
			<< "    gl_Position = mix(mix(gl_in[0].gl_Position, gl_in[1].gl_Position, weights.y), mix(gl_in[2].gl_Position, gl_in[3].gl_Position, weights.y), weights.x);\n"
			<< "    " << colorOutputName << " = mix(mix(v_patch_color[0], v_patch_color[1], cweights.y), mix(v_patch_color[2], v_patch_color[3], cweights.y), cweights.x);\n";
	else
		DE_ASSERT(false);

	src <<	"}\n";

	return src.str();
}

class IdentityGeometryShaderTestCase : public TestCase
{
public:
	void			initPrograms	(vk::SourceCollections& programCollection) const;
	void			checkSupport	(Context& context) const;
	TestInstance*	createInstance	(Context& context) const;

	IdentityGeometryShaderTestCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TessPrimitiveType primitiveType)
		: TestCase			(testCtx, name, description)
		, m_primitiveType	(primitiveType)
	{
	}

private:
	const TessPrimitiveType m_primitiveType;
};

void IdentityGeometryShaderTestCase::checkSupport (Context& context) const
{
#ifndef CTS_USES_VULKANSC
	checkSupportPrimitive(context, m_primitiveType);
#else
	DE_UNREF(context);
#endif // CTS_USES_VULKANSC
}

void IdentityGeometryShaderTestCase::initPrograms (vk::SourceCollections& programCollection) const
{
	addVertexAndFragmentShaders(programCollection);

	// Tessellation control
	{
		std::ostringstream src;
		src <<	glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
			<< "#extension GL_EXT_tessellation_shader : require\n"
			<< "layout(vertices = 4) out;\n"
			<< "\n"
			<< "layout(set = 0, binding = 0, std430) readonly restrict buffer TessLevels {\n"
			<< "    float inner0;\n"
			<< "    float inner1;\n"
			<< "    float outer0;\n"
			<< "    float outer1;\n"
			<< "    float outer2;\n"
			<< "    float outer3;\n"
			<< "} sb_levels;\n"
			<< "\n"
			<< "layout(location = 0) in  highp vec4 v_vertex_color[];\n"
			<< "layout(location = 0) out highp vec4 v_patch_color[];\n"
			<< "\n"
			<< "void main (void)\n"
			<< "{\n"
			<< "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
			<< "    v_patch_color[gl_InvocationID] = v_vertex_color[gl_InvocationID];\n"
			<< "\n"
			<< "    gl_TessLevelInner[0] = sb_levels.inner0;\n"
			<< "    gl_TessLevelInner[1] = sb_levels.inner1;\n"
			<< "    gl_TessLevelOuter[0] = sb_levels.outer0;\n"
			<< "    gl_TessLevelOuter[1] = sb_levels.outer1;\n"
			<< "    gl_TessLevelOuter[2] = sb_levels.outer2;\n"
			<< "    gl_TessLevelOuter[3] = sb_levels.outer3;\n"
			<<	"}\n";

		programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str());
	}

	// Tessellation evaluation shader
	{
		programCollection.glslSources.add("tese_to_frag")
			<< glu::TessellationEvaluationSource(generateTessellationEvaluationShader(m_primitiveType, "v_fragment_color"));
		programCollection.glslSources.add("tese_to_geom")
			<< glu::TessellationEvaluationSource(generateTessellationEvaluationShader(m_primitiveType, "v_evaluated_color"));
	}

	// Geometry shader
	{
		std::ostringstream	src;
		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
			<< "#extension GL_EXT_geometry_shader : require\n"
			<< "layout(" << getGeometryShaderInputPrimitiveTypeShaderName(m_primitiveType, false) << ") in;\n"
			<< "layout(" << getGeometryShaderOutputPrimitiveTypeShaderName(m_primitiveType, false)
						 << ", max_vertices=" << numVerticesPerPrimitive(m_primitiveType, false) << ") out;\n"
			<< "\n"
			<< "layout(location = 0) in  highp vec4 v_evaluated_color[];\n"
			<< "layout(location = 0) out highp vec4 v_fragment_color;\n"
			<< "\n"
			<< "void main (void)\n"
			<< "{\n"
			<< "    for (int ndx = 0; ndx < gl_in.length(); ++ndx)\n"
			<< "    {\n"
			<< "        gl_Position = gl_in[ndx].gl_Position;\n"
			<< "        v_fragment_color = v_evaluated_color[ndx];\n"
			<< "        EmitVertex();\n"
			<< "    }\n"
			<< "}\n";

		programCollection.glslSources.add("geom") << glu::GeometrySource(src.str());
	}
}

class IdentityTessellationShaderTestCase : public TestCase
{
public:
	void			initPrograms	(vk::SourceCollections& programCollection) const;
	void			checkSupport	(Context& context) const;
	TestInstance*	createInstance	(Context& context) const;

	IdentityTessellationShaderTestCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TessPrimitiveType primitiveType)
		: TestCase			(testCtx, name, description)
		, m_primitiveType	(primitiveType)
	{
	}

private:
	const TessPrimitiveType m_primitiveType;
};

void IdentityTessellationShaderTestCase::checkSupport (Context& context) const
{
#ifndef CTS_USES_VULKANSC
	checkSupportPrimitive(context, m_primitiveType);
#else
	DE_UNREF(context);
#endif // CTS_USES_VULKANSC
}

//! Geometry shader used in passthrough tessellation shader case.
std::string generateGeometryShader (const TessPrimitiveType primitiveType, const std::string& colorSourceName)
{
	const int numEmitVertices = (primitiveType == TESSPRIMITIVETYPE_ISOLINES ? 11 : 8);

	std::ostringstream src;
	src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
		<< "#extension GL_EXT_geometry_shader : require\n"
		<< "layout(" << getGeometryShaderInputPrimitiveTypeShaderName(primitiveType, false) << ") in;\n"
		<< "layout(" << getGeometryShaderOutputPrimitiveTypeShaderName(primitiveType, false)
					  << ", max_vertices=" << numEmitVertices << ") out;\n"
		<< "\n"
		<< "layout(location = 0) in  highp vec4 " << colorSourceName << "[];\n"
		<< "layout(location = 0) out highp vec4 v_fragment_color;\n"
		<< "\n"
		<< "void main (void)\n"
		<< "{\n";

	if (primitiveType == TESSPRIMITIVETYPE_TRIANGLES)
	{
		src << "	vec4 centerPos = (gl_in[0].gl_Position + gl_in[1].gl_Position + gl_in[2].gl_Position) / 3.0f;\n"
			<< "\n"
			<< "	for (int ndx = 0; ndx < 4; ++ndx)\n"
			<< "	{\n"
			<< "		gl_Position = centerPos + (centerPos - gl_in[ndx % 3].gl_Position);\n"
			<< "		v_fragment_color = " << colorSourceName << "[ndx % 3];\n"
			<< "		EmitVertex();\n"
			<< "\n"
			<< "		gl_Position = centerPos + 0.7 * (centerPos - gl_in[ndx % 3].gl_Position);\n"
			<< "		v_fragment_color = " << colorSourceName << "[ndx % 3];\n"
			<< "		EmitVertex();\n"
			<< "	}\n";
	}
	else if (primitiveType == TESSPRIMITIVETYPE_ISOLINES)
	{
		src << "	vec4 mdir = vec4(gl_in[0].gl_Position.y - gl_in[1].gl_Position.y, gl_in[1].gl_Position.x - gl_in[0].gl_Position.x, 0.0, 0.0);\n"
			<< "	for (int i = 0; i <= 10; ++i)\n"
			<< "	{\n"
			<< "		float xweight = cos(float(i) / 10.0 * 6.28) * 0.5 + 0.5;\n"
			<< "		float mweight = sin(float(i) / 10.0 * 6.28) * 0.1 + 0.1;\n"
			<< "		gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, xweight) + mweight * mdir;\n"
			<< "		v_fragment_color = mix(" << colorSourceName << "[0], " << colorSourceName << "[1], xweight);\n"
			<< "		EmitVertex();\n"
			<< "	}\n";
	}
	else
		DE_ASSERT(false);

	src << "}\n";

	return src.str();
}

void IdentityTessellationShaderTestCase::initPrograms (vk::SourceCollections& programCollection) const
{
	addVertexAndFragmentShaders(programCollection);

	// Tessellation control
	{
		std::ostringstream src;
		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
			<< "#extension GL_EXT_tessellation_shader : require\n"
			<< "layout(vertices = " << numVerticesPerPrimitive(m_primitiveType, false) << ") out;\n"
			<< "\n"
			<< "layout(location = 0) in  highp vec4 v_vertex_color[];\n"
			<< "layout(location = 0) out highp vec4 v_control_color[];\n"
			<< "\n"
			<< "void main (void)\n"
			<< "{\n"
			<< "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
			<< "    v_control_color[gl_InvocationID] = v_vertex_color[gl_InvocationID];\n"
			<< "\n"
			<< "    gl_TessLevelInner[0] = 1.0;\n"
			<< "    gl_TessLevelInner[1] = 1.0;\n"
			<< "    gl_TessLevelOuter[0] = 1.0;\n"
			<< "    gl_TessLevelOuter[1] = 1.0;\n"
			<< "    gl_TessLevelOuter[2] = 1.0;\n"
			<< "    gl_TessLevelOuter[3] = 1.0;\n"
			<<	"}\n";

		programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str());
	}

	// Tessellation evaluation shader
	{
		std::ostringstream src;
		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
			<< "#extension GL_EXT_tessellation_shader : require\n"
			<< "layout(" << getTessPrimitiveTypeShaderName(m_primitiveType) << ") in;\n"
			<< "\n"
			<< "layout(location = 0) in  highp vec4 v_control_color[];\n"
			<< "layout(location = 0) out highp vec4 v_evaluated_color;\n"
			<< "\n"
			<< "// note: No need to use precise gl_Position since we do not require gapless geometry\n"
			<< "void main (void)\n"
			<< "{\n";

		if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES)
			src << "    gl_Position = gl_TessCoord.x * gl_in[0].gl_Position + gl_TessCoord.y * gl_in[1].gl_Position + gl_TessCoord.z * gl_in[2].gl_Position;\n"
				<< "    v_evaluated_color = gl_TessCoord.x * v_control_color[0] + gl_TessCoord.y * v_control_color[1] + gl_TessCoord.z * v_control_color[2];\n";
		else if (m_primitiveType == TESSPRIMITIVETYPE_ISOLINES)
			src << "    gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
				<< "    v_evaluated_color = mix(v_control_color[0], v_control_color[1], gl_TessCoord.x);\n";
		else
			DE_ASSERT(false);

		src << "}\n";

		programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str());
	}

	// Geometry shader
	{
		programCollection.glslSources.add("geom_from_tese") << glu::GeometrySource(
			generateGeometryShader(m_primitiveType, "v_evaluated_color"));
		programCollection.glslSources.add("geom_from_vert") << glu::GeometrySource(
			generateGeometryShader(m_primitiveType, "v_vertex_color"));
	}
}

inline tcu::ConstPixelBufferAccess getPixelBufferAccess (const DeviceInterface& vk,
														 const VkDevice			device,
														 const Buffer&			colorBuffer,
														 const VkFormat			colorFormat,
														 const tcu::IVec2&		renderSize)
{
	const Allocation& alloc = colorBuffer.getAllocation();

	invalidateAlloc(vk, device, alloc);

	return tcu::ConstPixelBufferAccess(mapVkFormat(colorFormat), renderSize.x(), renderSize.y(), 1, alloc.getHostPtr());
}

//! When a test case disables tessellation stage and we need to derive a primitive type.
VkPrimitiveTopology getPrimitiveTopology (const TessPrimitiveType primitiveType)
{
	switch (primitiveType)
	{
		case TESSPRIMITIVETYPE_TRIANGLES:
		case TESSPRIMITIVETYPE_QUADS:
			return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;

		case TESSPRIMITIVETYPE_ISOLINES:
			return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;

		default:
			DE_ASSERT(false);
			return VK_PRIMITIVE_TOPOLOGY_LAST;
	}
}

enum Constants
{
	PIPELINE_CASES	= 2,
	RENDER_SIZE		= 256,
};

class PassthroughTestInstance : public TestInstance
{
public:
	struct PipelineDescription
	{
		bool		useTessellation;
		bool		useGeometry;
		std::string	tessEvalShaderName;
		std::string	geomShaderName;
		std::string description;

		PipelineDescription (void) : useTessellation(), useGeometry() {}
	};

	struct Params
	{
		bool					useTessLevels;
		TessLevels				tessLevels;
		TessPrimitiveType		primitiveType;
		int						inputPatchVertices;
		std::vector<tcu::Vec4>	vertices;
		PipelineDescription		pipelineCases[PIPELINE_CASES];	//!< Each test case renders with two pipelines and compares results
		std::string				message;

		Params (void) : useTessLevels(), tessLevels(), primitiveType(), inputPatchVertices() {}
	};

								PassthroughTestInstance	(Context& context, const Params& params) : TestInstance(context), m_params(params) {}
	tcu::TestStatus				iterate					(void);

private:
	const Params				m_params;
};

tcu::TestStatus PassthroughTestInstance::iterate (void)
{
	requireFeatures(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), FEATURE_TESSELLATION_SHADER | FEATURE_GEOMETRY_SHADER);
	DE_STATIC_ASSERT(PIPELINE_CASES == 2);

	const DeviceInterface&	vk					= m_context.getDeviceInterface();
	const VkDevice			device				= m_context.getDevice();
	const VkQueue			queue				= m_context.getUniversalQueue();
	const deUint32			queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
	Allocator&				allocator			= m_context.getDefaultAllocator();

	// Tessellation levels
	const Buffer tessLevelsBuffer (vk, device, allocator, makeBufferCreateInfo(sizeof(TessLevels), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);

	if (m_params.useTessLevels)
	{
		const Allocation& alloc				= tessLevelsBuffer.getAllocation();
		TessLevels* const bufferTessLevels	= static_cast<TessLevels*>(alloc.getHostPtr());

		*bufferTessLevels = m_params.tessLevels;
		flushAlloc(vk, device, alloc);
	}

	// Vertex attributes

	const VkDeviceSize	vertexDataSizeBytes	= sizeInBytes(m_params.vertices);
	const VkFormat		vertexFormat		= VK_FORMAT_R32G32B32A32_SFLOAT;
	const Buffer		vertexBuffer		(vk, device, allocator, makeBufferCreateInfo(vertexDataSizeBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible);

	{
		const Allocation& alloc = vertexBuffer.getAllocation();

		deMemcpy(alloc.getHostPtr(), &m_params.vertices[0], static_cast<std::size_t>(vertexDataSizeBytes));
		flushAlloc(vk, device, alloc);
	}

	// Descriptors - make descriptor for tessellation levels, even if we don't use them, to simplify code

	const Unique<VkDescriptorSetLayout> descriptorSetLayout(DescriptorSetLayoutBuilder()
		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
		.build(vk, device));

	const Unique<VkDescriptorPool> descriptorPool(DescriptorPoolBuilder()
		.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
		.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));

	const Unique<VkDescriptorSet> descriptorSet		   (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
	const VkDescriptorBufferInfo  tessLevelsBufferInfo = makeDescriptorBufferInfo(*tessLevelsBuffer, 0ull, sizeof(TessLevels));

	DescriptorSetUpdateBuilder()
		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &tessLevelsBufferInfo)
		.update(vk, device);

	// Color attachment

	const tcu::IVec2			  renderSize				 = tcu::IVec2(RENDER_SIZE, RENDER_SIZE);
	const VkFormat				  colorFormat				 = VK_FORMAT_R8G8B8A8_UNORM;
	const VkImageSubresourceRange colorImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
	const Image					  colorAttachmentImage		 (vk, device, allocator,
															 makeImageCreateInfo(renderSize, colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 1u),
															 MemoryRequirement::Any);

	// Color output buffer: image will be copied here for verification.
	//                      We use two buffers, one for each case.

	const VkDeviceSize	colorBufferSizeBytes		= renderSize.x()*renderSize.y() * tcu::getPixelSize(mapVkFormat(colorFormat));
	const Buffer		colorBuffer1				(vk, device, allocator, makeBufferCreateInfo(colorBufferSizeBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible);
	const Buffer		colorBuffer2				(vk, device, allocator, makeBufferCreateInfo(colorBufferSizeBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible);
	const Buffer* const colorBuffer[PIPELINE_CASES] = { &colorBuffer1, &colorBuffer2 };

	// Pipeline

	const Unique<VkImageView>		colorAttachmentView	(makeImageView(vk, device, *colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorImageSubresourceRange));
	const Unique<VkRenderPass>		renderPass			(makeRenderPass(vk, device, colorFormat));
	const Unique<VkFramebuffer>		framebuffer			(makeFramebuffer(vk, device, *renderPass, *colorAttachmentView, renderSize.x(), renderSize.y()));
	const Unique<VkPipelineLayout>	pipelineLayout		(makePipelineLayout(vk, device, *descriptorSetLayout));
	const Unique<VkCommandPool>		cmdPool				(makeCommandPool(vk, device, queueFamilyIndex));
	const Unique<VkCommandBuffer>	cmdBuffer			(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	// Message explaining the test
	{
		tcu::TestLog& log = m_context.getTestContext().getLog();
		log << tcu::TestLog::Message << m_params.message << tcu::TestLog::EndMessage;

		if (m_params.useTessLevels)
			log << tcu::TestLog::Message << "Tessellation levels: " << getTessellationLevelsString(m_params.tessLevels, m_params.primitiveType) << tcu::TestLog::EndMessage;
	}

	for (int pipelineNdx = 0; pipelineNdx < PIPELINE_CASES; ++pipelineNdx)
	{
		const PipelineDescription& pipelineDescription = m_params.pipelineCases[pipelineNdx];
		GraphicsPipelineBuilder	   pipelineBuilder;

		pipelineBuilder
			.setPrimitiveTopology		  (getPrimitiveTopology(m_params.primitiveType))
			.setRenderSize				  (renderSize)
			.setBlend					  (true)
			.setVertexInputSingleAttribute(vertexFormat, tcu::getPixelSize(mapVkFormat(vertexFormat)))
			.setPatchControlPoints		  (m_params.inputPatchVertices)
			.setShader					  (vk, device, VK_SHADER_STAGE_VERTEX_BIT,					m_context.getBinaryCollection().get("vert"), DE_NULL)
			.setShader					  (vk, device, VK_SHADER_STAGE_FRAGMENT_BIT,				m_context.getBinaryCollection().get("frag"), DE_NULL);

		if (pipelineDescription.useTessellation)
			pipelineBuilder
				.setShader				  (vk, device, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,	m_context.getBinaryCollection().get("tesc"), DE_NULL)
				.setShader				  (vk, device, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, m_context.getBinaryCollection().get(pipelineDescription.tessEvalShaderName), DE_NULL);

		if (pipelineDescription.useGeometry)
			pipelineBuilder
				.setShader				  (vk, device, VK_SHADER_STAGE_GEOMETRY_BIT,				m_context.getBinaryCollection().get(pipelineDescription.geomShaderName), DE_NULL);

		const Unique<VkPipeline> pipeline (pipelineBuilder.build(vk, device, *pipelineLayout, *renderPass));

		// Draw commands

		beginCommandBuffer(vk, *cmdBuffer);

		// Change color attachment image layout
		{
			// State is slightly different on the first iteration.
			const VkImageLayout currentLayout = (pipelineNdx == 0 ? VK_IMAGE_LAYOUT_UNDEFINED : VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
			const VkAccessFlags srcFlags	  = (pipelineNdx == 0 ? (VkAccessFlags)0          : (VkAccessFlags)VK_ACCESS_TRANSFER_READ_BIT);

			const VkImageMemoryBarrier colorAttachmentLayoutBarrier = makeImageMemoryBarrier(
				srcFlags, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
				currentLayout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
				*colorAttachmentImage, colorImageSubresourceRange);

			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u,
				0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentLayoutBarrier);
		}

		// Begin render pass
		{
			const VkRect2D	renderArea	= makeRect2D(renderSize);
			const tcu::Vec4	clearColor	(0.0f, 0.0f, 0.0f, 1.0f);

			beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderArea, clearColor);
		}

		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
		{
			const VkDeviceSize vertexBufferOffset = 0ull;
			vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
		}

		if (m_params.useTessLevels)
			vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);

		vk.cmdDraw(*cmdBuffer, static_cast<deUint32>(m_params.vertices.size()), 1u, 0u, 0u);
		endRenderPass(vk, *cmdBuffer);

		// Copy render result to a host-visible buffer
		copyImageToBuffer(vk, *cmdBuffer, *colorAttachmentImage, colorBuffer[pipelineNdx]->get(), renderSize);

		endCommandBuffer(vk, *cmdBuffer);
		submitCommandsAndWait(vk, device, queue, *cmdBuffer);
	}

	// Verify results

	tcu::ConstPixelBufferAccess image0 = getPixelBufferAccess(vk, device, *colorBuffer[0], colorFormat, renderSize);
	tcu::ConstPixelBufferAccess image1 = getPixelBufferAccess(vk, device, *colorBuffer[1], colorFormat, renderSize);

	const tcu::UVec4 colorThreshold    (8, 8, 8, 255);
	const tcu::IVec3 positionDeviation (1, 1, 0);		// 3x3 search kernel
	const bool		 ignoreOutOfBounds = true;

	tcu::TestLog& log = m_context.getTestContext().getLog();
	log << tcu::TestLog::Message
		<< "In image comparison:\n"
		<< "  Reference - " << m_params.pipelineCases[0].description << "\n"
		<< "  Result    - " << m_params.pipelineCases[1].description << "\n"
		<< tcu::TestLog::EndMessage;

	const bool ok = tcu::intThresholdPositionDeviationCompare(
		log, "ImageCompare", "Image comparison", image0, image1, colorThreshold, positionDeviation, ignoreOutOfBounds, tcu::COMPARE_LOG_RESULT);

	return (ok ? tcu::TestStatus::pass("OK") : tcu::TestStatus::fail("Image comparison failed"));
}

TestInstance* IdentityGeometryShaderTestCase::createInstance (Context& context) const
{
	PassthroughTestInstance::Params params;

	const float level		   = 14.0;
	params.useTessLevels	   = true;
	params.tessLevels.inner[0] = level;
	params.tessLevels.inner[1] = level;
	params.tessLevels.outer[0] = level;
	params.tessLevels.outer[1] = level;
	params.tessLevels.outer[2] = level;
	params.tessLevels.outer[3] = level;

	params.primitiveType	   = m_primitiveType;
	params.inputPatchVertices  = (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 3 : 4);

	params.vertices.push_back(tcu::Vec4( -0.9f, -0.9f, 0.0f, 1.0f ));
	params.vertices.push_back(tcu::Vec4( -0.9f,  0.9f, 0.0f, 1.0f ));
	params.vertices.push_back(tcu::Vec4(  0.9f, -0.9f, 0.0f, 1.0f ));
	params.vertices.push_back(tcu::Vec4(  0.9f,  0.9f, 0.0f, 1.0f ));

	params.pipelineCases[0].useTessellation		= true;
	params.pipelineCases[0].useGeometry			= true;
	params.pipelineCases[0].tessEvalShaderName	= "tese_to_geom";
	params.pipelineCases[0].geomShaderName		= "geom";
	params.pipelineCases[0].description			= "passthrough geometry shader";

	params.pipelineCases[1].useTessellation		= true;
	params.pipelineCases[1].useGeometry			= false;
	params.pipelineCases[1].tessEvalShaderName	= "tese_to_frag";
	params.pipelineCases[1].geomShaderName		= "geom";
	params.pipelineCases[1].description			= "no geometry shader in the pipeline";

	params.message = "Testing tessellating shader program output does not change when a passthrough geometry shader is attached.\n"
					 "Rendering two images, first with and second without a geometry shader. Expecting similar results.\n"
					 "Using additive blending to detect overlap.\n";

	return new PassthroughTestInstance(context, params);
}

TestInstance* IdentityTessellationShaderTestCase::createInstance (Context& context) const
{
	PassthroughTestInstance::Params params;

	params.useTessLevels	   = false;
	params.primitiveType	   = m_primitiveType;
	params.inputPatchVertices  = (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 3 : 2);

	params.vertices.push_back(	  tcu::Vec4( -0.4f,  0.4f, 0.0f, 1.0f ));
	params.vertices.push_back(	  tcu::Vec4(  0.0f, -0.5f, 0.0f, 1.0f ));
	if (params.inputPatchVertices == 3)
		params.vertices.push_back(tcu::Vec4(  0.4f,  0.4f, 0.0f, 1.0f ));

	params.pipelineCases[0].useTessellation		= true;
	params.pipelineCases[0].useGeometry			= true;
	params.pipelineCases[0].tessEvalShaderName	= "tese";
	params.pipelineCases[0].geomShaderName		= "geom_from_tese";
	params.pipelineCases[0].description			= "passthrough tessellation shaders";

	params.pipelineCases[1].useTessellation		= false;
	params.pipelineCases[1].useGeometry			= true;
	params.pipelineCases[1].tessEvalShaderName	= "tese";
	params.pipelineCases[1].geomShaderName		= "geom_from_vert";
	params.pipelineCases[1].description			= "no tessellation shaders in the pipeline";

	params.message = "Testing geometry shading shader program output does not change when a passthrough tessellation shader is attached.\n"
					 "Rendering two images, first with and second without a tessellation shader. Expecting similar results.\n"
					 "Using additive blending to detect overlap.\n";

	return new PassthroughTestInstance(context, params);
}

inline TestCase* makeIdentityGeometryShaderCase (tcu::TestContext& testCtx, const TessPrimitiveType primitiveType)
{
	return new IdentityGeometryShaderTestCase(
		testCtx,
		"tessellate_" + de::toString(getTessPrimitiveTypeShaderName(primitiveType)) + "_passthrough_geometry_no_change",
		"Passthrough geometry shader has no effect",
		primitiveType);
}

inline TestCase* makeIdentityTessellationShaderCase (tcu::TestContext& testCtx, const TessPrimitiveType primitiveType)
{
	return new IdentityTessellationShaderTestCase(
		testCtx,
		"passthrough_tessellation_geometry_shade_" + de::toString(getTessPrimitiveTypeShaderName(primitiveType)) + "_no_change",
		"Passthrough tessellation shader has no effect",
		primitiveType);
}

} // anonymous


//! Ported from dEQP-GLES31.functional.tessellation_geometry_interaction.render.passthrough.*
tcu::TestCaseGroup* createGeometryPassthroughTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "passthrough", "Render various types with either passthrough geometry or tessellation shader"));

	// Passthrough geometry shader
	group->addChild(makeIdentityGeometryShaderCase(testCtx, TESSPRIMITIVETYPE_TRIANGLES));
	group->addChild(makeIdentityGeometryShaderCase(testCtx, TESSPRIMITIVETYPE_QUADS));
	group->addChild(makeIdentityGeometryShaderCase(testCtx, TESSPRIMITIVETYPE_ISOLINES));

	// Passthrough tessellation shader
	group->addChild(makeIdentityTessellationShaderCase(testCtx, TESSPRIMITIVETYPE_TRIANGLES));
	group->addChild(makeIdentityTessellationShaderCase(testCtx, TESSPRIMITIVETYPE_ISOLINES));

	return group.release();
}

} // tessellation
} // vkt
