/*------------------------------------------------------------------------
 * 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
{
	checkSupportPrimitive(context, m_primitiveType);
}

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
{
	checkSupportPrimitive(context, m_primitiveType);
}

//! 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
