/*------------------------------------------------------------------------
 * 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 Primitive Discard Tests
 *//*--------------------------------------------------------------------*/

#include "vktTessellationPrimitiveDiscardTests.hpp"
#include "vktTestCaseUtil.hpp"
#include "vktTessellationUtil.hpp"

#include "tcuTestLog.hpp"

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

#include "deUniquePtr.hpp"
#include "deStringUtil.hpp"

#include <string>
#include <vector>

namespace vkt
{
namespace tessellation
{

using namespace vk;

namespace
{

struct CaseDefinition
{
	TessPrimitiveType	primitiveType;
	SpacingMode			spacingMode;
	Winding				winding;
	bool				usePointMode;
	bool				useLessThanOneInnerLevels;
};

bool lessThanOneInnerLevelsDefined (const CaseDefinition& caseDef)
{
	// From Vulkan API specification:
	// >> When tessellating triangles or quads (with/without point mode) with fractional odd spacing, the tessellator
	// >> ***may*** produce interior vertices that are positioned on the edge of the patch if an inner
	// >> tessellation level is less than or equal to one.
	return !((caseDef.primitiveType == vkt::tessellation::TESSPRIMITIVETYPE_QUADS      ||
			  caseDef.primitiveType == vkt::tessellation::TESSPRIMITIVETYPE_TRIANGLES) &&
			 caseDef.spacingMode == vkt::tessellation::SPACINGMODE_FRACTIONAL_ODD);
}

int intPow (int base, int exp)
{
	DE_ASSERT(exp >= 0);
	if (exp == 0)
		return 1;
	else
	{
		const int sub = intPow(base, exp/2);
		if (exp % 2 == 0)
			return sub*sub;
		else
			return sub*sub*base;
	}
}

std::vector<float> genAttributes (bool useLessThanOneInnerLevels)
{
	// Generate input attributes (tessellation levels, and position scale and
	// offset) for a number of primitives. Each primitive has a different
	// combination of tessellatio levels; each level is either a valid
	// value or an "invalid" value (negative or zero, chosen from
	// invalidTessLevelChoices).

	// \note The attributes are generated in such an order that all of the
	//		 valid attribute tuples come before the first invalid one both
	//		 in the result vector, and when scanning the resulting 2d grid
	//		 of primitives is scanned in y-major order. This makes
	//		 verification somewhat simpler.

	static const float	baseTessLevels[6]			= { 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f };
	static const float	invalidTessLevelChoices[]	= { -0.42f, 0.0f };
	const int			numChoices					= 1 + DE_LENGTH_OF_ARRAY(invalidTessLevelChoices);
	float				choices[6][numChoices];
	std::vector<float>	result;

	for (int levelNdx = 0; levelNdx < 6; levelNdx++)
		for (int choiceNdx = 0; choiceNdx < numChoices; choiceNdx++)
			choices[levelNdx][choiceNdx] = (choiceNdx == 0 || !useLessThanOneInnerLevels) ? baseTessLevels[levelNdx] : invalidTessLevelChoices[choiceNdx-1];

	{
		const int	numCols	= intPow(numChoices, 6/2); // sqrt(numChoices**6) == sqrt(number of primitives)
		const int	numRows	= numCols;
		int			index	= 0;
		int			i[6];
		// We could do this with some generic combination-generation function, but meh, it's not that bad.
		for (i[2] = 0; i[2] < numChoices; i[2]++) // First  outer
		for (i[3] = 0; i[3] < numChoices; i[3]++) // Second outer
		for (i[4] = 0; i[4] < numChoices; i[4]++) // Third  outer
		for (i[5] = 0; i[5] < numChoices; i[5]++) // Fourth outer
		for (i[0] = 0; i[0] < numChoices; i[0]++) // First  inner
		for (i[1] = 0; i[1] < numChoices; i[1]++) // Second inner
		{
			for (int j = 0; j < 6; j++)
				result.push_back(choices[j][i[j]]);

			{
				const int col = index % numCols;
				const int row = index / numCols;
				// Position scale.
				result.push_back((float)2.0f / (float)numCols);
				result.push_back((float)2.0f / (float)numRows);
				// Position offset.
				result.push_back((float)col / (float)numCols * 2.0f - 1.0f);
				result.push_back((float)row / (float)numRows * 2.0f - 1.0f);
			}

			index++;
		}
	}

	return result;
}

//! Check that white pixels are found around every non-discarded patch,
//! and that only black pixels are found after the last non-discarded patch.
//! Returns true on successful comparison.
bool verifyResultImage (tcu::TestLog&						log,
						const int							numPrimitives,
						const int							numAttribsPerPrimitive,
						const TessPrimitiveType				primitiveType,
						const std::vector<float>&			attributes,
						const tcu::ConstPixelBufferAccess	pixels)
{
	const tcu::Vec4 black(0.0f, 0.0f, 0.0f, 1.0f);
	const tcu::Vec4 white(1.0f, 1.0f, 1.0f, 1.0f);

	int lastWhitePixelRow								= 0;
	int secondToLastWhitePixelRow						= 0;
	int	lastWhitePixelColumnOnSecondToLastWhitePixelRow	= 0;

	for (int patchNdx = 0; patchNdx < numPrimitives; ++patchNdx)
	{
		const float* const	attr			= &attributes[numAttribsPerPrimitive*patchNdx];
		const bool			validLevels		= !isPatchDiscarded(primitiveType, &attr[2]);

		if (validLevels)
		{
			// Not a discarded patch; check that at least one white pixel is found in its area.

			const float* const	scale		= &attr[6];
			const float* const	offset		= &attr[8];
			const int			x0			= (int)((			offset[0] + 1.0f) * 0.5f * (float)pixels.getWidth()) - 1;
			const int			x1			= (int)((scale[0] + offset[0] + 1.0f) * 0.5f * (float)pixels.getWidth()) + 1;
			const int			y0			= (int)((			offset[1] + 1.0f) * 0.5f * (float)pixels.getHeight()) - 1;
			const int			y1			= (int)((scale[1] + offset[1] + 1.0f) * 0.5f * (float)pixels.getHeight()) + 1;
			bool				pixelOk		= false;

			if (y1 > lastWhitePixelRow)
			{
				secondToLastWhitePixelRow	= lastWhitePixelRow;
				lastWhitePixelRow			= y1;
			}
			lastWhitePixelColumnOnSecondToLastWhitePixelRow = x1;

			for (int y = y0; y <= y1 && !pixelOk; y++)
			for (int x = x0; x <= x1 && !pixelOk; x++)
			{
				if (!de::inBounds(x, 0, pixels.getWidth()) || !de::inBounds(y, 0, pixels.getHeight()))
					continue;

				if (pixels.getPixel(x, y) == white)
					pixelOk = true;
			}

			if (!pixelOk)
			{
				log << tcu::TestLog::Message
					<< "Failure: expected at least one white pixel in the rectangle "
					<< "[x0=" << x0 << ", y0=" << y0 << ", x1=" << x1 << ", y1=" << y1 << "]"
					<< tcu::TestLog::EndMessage
					<< tcu::TestLog::Message
					<< "Note: the rectangle approximately corresponds to the patch with these tessellation levels: "
					<< getTessellationLevelsString(&attr[0], &attr[1])
					<< tcu::TestLog::EndMessage;

				return false;
			}
		}
		else
		{
			// First discarded primitive patch; the remaining are guaranteed to be discarded ones as well.

			for (int y = 0; y < pixels.getHeight(); y++)
			for (int x = 0; x < pixels.getWidth(); x++)
			{
				if (y > lastWhitePixelRow || (y > secondToLastWhitePixelRow && x > lastWhitePixelColumnOnSecondToLastWhitePixelRow))
				{
					if (pixels.getPixel(x, y) != black)
					{
						log << tcu::TestLog::Message
							<< "Failure: expected all pixels to be black in the area "
							<< (lastWhitePixelColumnOnSecondToLastWhitePixelRow < pixels.getWidth()-1
								? std::string() + "y > " + de::toString(lastWhitePixelRow) + " || (y > " + de::toString(secondToLastWhitePixelRow)
												+ " && x > " + de::toString(lastWhitePixelColumnOnSecondToLastWhitePixelRow) + ")"
								: std::string() + "y > " + de::toString(lastWhitePixelRow))
							<< " (they all correspond to patches that should be discarded)"
							<< tcu::TestLog::EndMessage
							<< tcu::TestLog::Message << "Note: pixel " << tcu::IVec2(x, y) << " isn't black" << tcu::TestLog::EndMessage;

						return false;
					}
				}
			}
			break;
		}
	}
	return true;
}

int expectedVertexCount (const int					numPrimitives,
						 const int					numAttribsPerPrimitive,
						 const TessPrimitiveType	primitiveType,
						 const SpacingMode			spacingMode,
						 const std::vector<float>&	attributes)
{
	int count = 0;
	for (int patchNdx = 0; patchNdx < numPrimitives; ++patchNdx)
		count += referenceVertexCount(primitiveType, spacingMode, true, &attributes[numAttribsPerPrimitive*patchNdx+0], &attributes[numAttribsPerPrimitive*patchNdx+2]);
	return count;
}

void initPrograms (vk::SourceCollections& programCollection, const CaseDefinition caseDef)
{
	// Vertex shader
	{
		std::ostringstream src;
		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
			<< "\n"
			<< "layout(location = 0) in  highp float in_v_attr;\n"
			<< "layout(location = 0) out highp float in_tc_attr;\n"
			<< "\n"
			<< "void main (void)\n"
			<< "{\n"
			<< "    in_tc_attr = in_v_attr;\n"
			<< "}\n";

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

	// Tessellation control shader
	{
		std::ostringstream src;
		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
			<< "#extension GL_EXT_tessellation_shader : require\n"
			<< "\n"
			<< "layout(vertices = 1) out;\n"
			<< "\n"
			<< "layout(location = 0) in highp float in_tc_attr[];\n"
			<< "\n"
			<< "layout(location = 0) patch out highp vec2 in_te_positionScale;\n"
			<< "layout(location = 1) patch out highp vec2 in_te_positionOffset;\n"
			<< "\n"
			<< "void main (void)\n"
			<< "{\n"
			<< "    in_te_positionScale  = vec2(in_tc_attr[6], in_tc_attr[7]);\n"
			<< "    in_te_positionOffset = vec2(in_tc_attr[8], in_tc_attr[9]);\n"
			<< "\n"
			<< "    gl_TessLevelInner[0] = in_tc_attr[0];\n"
			<< "    gl_TessLevelInner[1] = in_tc_attr[1];\n"
			<< "\n"
			<< "    gl_TessLevelOuter[0] = in_tc_attr[2];\n"
			<< "    gl_TessLevelOuter[1] = in_tc_attr[3];\n"
			<< "    gl_TessLevelOuter[2] = in_tc_attr[4];\n"
			<< "    gl_TessLevelOuter[3] = in_tc_attr[5];\n"
			<< "}\n";

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

	// Tessellation evaluation shader
	// When using point mode we need two variants of the shader, one for the case where
	// shaderTessellationAndGeometryPointSize is enabled (in which the tessellation evaluation
	// shader needs to write to gl_PointSize for it to be defined) and one for the case where
	// it is disabled, in which we can't write to gl_PointSize but it has a default value
	// of 1.0
	{
		const deUint32	numVariants			= caseDef.usePointMode ? 2 : 1;
		for (deUint32 variant = 0; variant < numVariants; variant++)
		{
			const bool	needPointSizeWrite	= caseDef.usePointMode && variant == 1;

			std::ostringstream src;
			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
				<< "#extension GL_EXT_tessellation_shader : require\n";
			if (needPointSizeWrite)
			{
				src << "#extension GL_EXT_tessellation_point_size : require\n";
			}
			src << "\n"
				<< "layout(" << getTessPrimitiveTypeShaderName(caseDef.primitiveType) << ", "
							 << getSpacingModeShaderName(caseDef.spacingMode) << ", "
							 << getWindingShaderName(caseDef.winding)
							 << (caseDef.usePointMode ? ", point_mode" : "") << ") in;\n"
				<< "\n"
				<< "layout(location = 0) patch in highp vec2 in_te_positionScale;\n"
				<< "layout(location = 1) patch in highp vec2 in_te_positionOffset;\n"
				<< "\n"
				<< "layout(set = 0, binding = 0, std430) coherent restrict buffer Output {\n"
				<< "    int  numInvocations;\n"
				<< "} sb_out;\n"
				<< "\n"
				<< "void main (void)\n"
				<< "{\n"
				<< "    atomicAdd(sb_out.numInvocations, 1);\n"
				<< "\n"
				<< "    gl_Position = vec4(gl_TessCoord.xy*in_te_positionScale + in_te_positionOffset, 0.0, 1.0);\n";
			if (needPointSizeWrite)
			{
				src << "    gl_PointSize = 1.0;\n";
			}
			src << "}\n";

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

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

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

/*--------------------------------------------------------------------*//*!
 * \brief Test that patch is discarded if relevant outer level <= 0.0
 *
 * Draws patches with different combinations of tessellation levels,
 * varying which levels are negative. Verifies by checking that white
 * pixels exist inside the area of valid primitives, and only black pixels
 * exist inside the area of discarded primitives. An additional sanity
 * test is done, checking that the number of primitives written by shader is
 * correct.
 *//*--------------------------------------------------------------------*/
tcu::TestStatus test (Context& context, const CaseDefinition caseDef)
{
	requireFeatures(context.getInstanceInterface(), context.getPhysicalDevice(), FEATURE_TESSELLATION_SHADER | FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS);

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

	const std::vector<float>	attributes				= genAttributes(caseDef.useLessThanOneInnerLevels);
	const int					numAttribsPerPrimitive	= 6 + 2 + 2; // Tess levels, scale, offset.
	const int					numPrimitives			= static_cast<int>(attributes.size() / numAttribsPerPrimitive);
	const int					numExpectedVertices		= expectedVertexCount(numPrimitives, numAttribsPerPrimitive, caseDef.primitiveType, caseDef.spacingMode, attributes);

	// Check the convenience assertion that all discarded patches come after the last non-discarded patch.
	{
		bool discardedPatchEncountered = false;
		for (int patchNdx = 0; patchNdx < numPrimitives; ++patchNdx)
		{
			const bool discard = isPatchDiscarded(caseDef.primitiveType, &attributes[numAttribsPerPrimitive*patchNdx + 2]);
			DE_ASSERT(discard || !discardedPatchEncountered);
			discardedPatchEncountered = discard;
		}
		DE_UNREF(discardedPatchEncountered);
	}

	// Vertex input attributes buffer

	const VkFormat	   vertexFormat		   = VK_FORMAT_R32_SFLOAT;
	const deUint32	   vertexStride		   = tcu::getPixelSize(mapVkFormat(vertexFormat));
	const VkDeviceSize vertexDataSizeBytes = sizeInBytes(attributes);
	const Buffer	   vertexBuffer		   (vk, device, allocator, makeBufferCreateInfo(vertexDataSizeBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible);

	DE_ASSERT(static_cast<int>(attributes.size()) == numPrimitives * numAttribsPerPrimitive);
	DE_ASSERT(sizeof(attributes[0]) == vertexStride);

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

		deMemcpy(alloc.getHostPtr(), &attributes[0], static_cast<std::size_t>(vertexDataSizeBytes));
		flushAlloc(vk, device, alloc);
		// No barrier needed, flushed memory is automatically visible
	}

	// Output buffer: number of invocations

	const VkDeviceSize resultBufferSizeBytes = sizeof(deInt32);
	const Buffer	   resultBuffer			 (vk, device, allocator, makeBufferCreateInfo(resultBufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);

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

		deMemset(alloc.getHostPtr(), 0, static_cast<std::size_t>(resultBufferSizeBytes));
		flushAlloc(vk, device, alloc);
	}

	// Color attachment

	const tcu::IVec2			  renderSize				 = tcu::IVec2(256, 256);
	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

	const VkDeviceSize colorBufferSizeBytes = renderSize.x()*renderSize.y() * tcu::getPixelSize(mapVkFormat(colorFormat));
	const Buffer colorBuffer(vk, device, allocator,
		makeBufferCreateInfo(colorBufferSizeBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible);

	// Descriptors

	const Unique<VkDescriptorSetLayout> descriptorSetLayout(DescriptorSetLayoutBuilder()
		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_TESSELLATION_EVALUATION_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  resultBufferInfo = makeDescriptorBufferInfo(resultBuffer.get(), 0ull, resultBufferSizeBytes);

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

	// 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));
	const bool						needPointSizeWrite	= getPhysicalDeviceFeatures(context.getInstanceInterface(), context.getPhysicalDevice()).shaderTessellationAndGeometryPointSize && caseDef.usePointMode;

	const Unique<VkPipeline> pipeline(GraphicsPipelineBuilder()
		.setRenderSize				  (renderSize)
		.setPatchControlPoints		  (numAttribsPerPrimitive)
		.setVertexInputSingleAttribute(vertexFormat, vertexStride)
		.setShader					  (vk, device, VK_SHADER_STAGE_VERTEX_BIT,					context.getBinaryCollection().get("vert"), DE_NULL)
		.setShader					  (vk, device, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,	context.getBinaryCollection().get("tesc"), DE_NULL)
		.setShader					  (vk, device, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, context.getBinaryCollection().get(needPointSizeWrite ? "tese_psw" : "tese"), DE_NULL)
		.setShader					  (vk, device, VK_SHADER_STAGE_FRAGMENT_BIT,				context.getBinaryCollection().get("frag"), DE_NULL)
		.build						  (vk, device, *pipelineLayout, *renderPass));

	context.getTestContext().getLog()
		<< tcu::TestLog::Message
		<< "Note: rendering " << numPrimitives << " patches; first patches have valid relevant outer levels, "
		<< "but later patches have one or more invalid (i.e. less than or equal to 0.0) relevant outer levels"
		<< tcu::TestLog::EndMessage;

	// Draw commands

	beginCommandBuffer(vk, *cmdBuffer);

	// Change color attachment image layout
	{
		const VkImageMemoryBarrier colorAttachmentLayoutBarrier = makeImageMemoryBarrier(
			(VkAccessFlags)0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
			VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
			*colorAttachmentImage, colorImageSubresourceRange);

		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_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	= tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);

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

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

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

	// Copy render result to a host-visible buffer
	copyImageToBuffer(vk, *cmdBuffer, *colorAttachmentImage, *colorBuffer, renderSize);
	{
		const VkBufferMemoryBarrier shaderWriteBarrier = makeBufferMemoryBarrier(
			VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *resultBuffer, 0ull, resultBufferSizeBytes);

		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
			0u, DE_NULL, 1u, &shaderWriteBarrier, 0u, DE_NULL);
	}

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

	{
		// Log rendered image
		const Allocation&					colorBufferAlloc	= colorBuffer.getAllocation();

		invalidateAlloc(vk, device, colorBufferAlloc);

		const tcu::ConstPixelBufferAccess	imagePixelAccess	(mapVkFormat(colorFormat), renderSize.x(), renderSize.y(), 1, colorBufferAlloc.getHostPtr());
		tcu::TestLog&						log					= context.getTestContext().getLog();

		log << tcu::TestLog::Image("color0", "Rendered image", imagePixelAccess);

		// Verify case result
		const Allocation&					resultAlloc			= resultBuffer.getAllocation();

		invalidateAlloc(vk, device, resultAlloc);

		const deInt32						numResultVertices	= *static_cast<deInt32*>(resultAlloc.getHostPtr());

		if (!lessThanOneInnerLevelsDefined(caseDef) && caseDef.useLessThanOneInnerLevels)
		{
			// Since we cannot explicitly determine whether or not such interior vertices are going to be
			// generated, we will not verify the number of generated vertices for fractional odd + quads/triangles
			// tessellation configurations.
			log << tcu::TestLog::Message
				<< "Note: shader invocations generated " << numResultVertices << " vertices (not verified as number of vertices is implementation-dependent)"
				<< tcu::TestLog::EndMessage;
		}
		else if (numResultVertices < numExpectedVertices)
		{
			log << tcu::TestLog::Message
				<< "Failure: expected " << numExpectedVertices << " vertices from shader invocations, but got only " << numResultVertices
				<< tcu::TestLog::EndMessage;
			return tcu::TestStatus::fail("Wrong number of tessellation coordinates");
		}
		else if (numResultVertices == numExpectedVertices)
		{
			log << tcu::TestLog::Message
				<< "Note: shader invocations generated " << numResultVertices << " vertices"
				<< tcu::TestLog::EndMessage;
		}
		else
		{
			log << tcu::TestLog::Message
				<< "Note: shader invocations generated " << numResultVertices << " vertices (expected " << numExpectedVertices << ", got "
				<< (numResultVertices - numExpectedVertices) << " extra)"
				<< tcu::TestLog::EndMessage;
		}

		return (verifyResultImage(log, numPrimitives, numAttribsPerPrimitive, caseDef.primitiveType, attributes, imagePixelAccess)
				? tcu::TestStatus::pass("OK") : tcu::TestStatus::fail("Image verification failed"));
	}
}

} // anonymous

//! These tests correspond to dEQP-GLES31.functional.tessellation.primitive_discard.*
//! \note Original test used transform feedback (TF) to capture the number of output vertices. The behavior of TF differs significantly from SSBO approach,
//!       especially for non-point_mode rendering. TF returned all coordinates, while SSBO computes the count based on the number of shader invocations
//!       which yields a much smaller number because invocations for duplicate coordinates are often eliminated.
//!       Because of this, the test was changed to:
//!       - always compute the number of expected coordinates as if point_mode was enabled
//!       - not fail if implementation returned more coordinates than expected
tcu::TestCaseGroup* createPrimitiveDiscardTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "primitive_discard", "Test primitive discard with relevant outer tessellation level <= 0.0"));

	for (int primitiveTypeNdx = 0; primitiveTypeNdx < TESSPRIMITIVETYPE_LAST; primitiveTypeNdx++)
	for (int spacingModeNdx = 0; spacingModeNdx < SPACINGMODE_LAST; spacingModeNdx++)
	for (int windingNdx = 0; windingNdx < WINDING_LAST; windingNdx++)
	for (int usePointModeNdx = 0; usePointModeNdx <= 1; usePointModeNdx++)
	for (int lessThanOneInnerLevelsNdx = 0; lessThanOneInnerLevelsNdx <= 1; lessThanOneInnerLevelsNdx++)
	{
		const CaseDefinition caseDef =
		{
			(TessPrimitiveType)primitiveTypeNdx,
			(SpacingMode)spacingModeNdx,
			(Winding)windingNdx,
			(usePointModeNdx != 0),
			(lessThanOneInnerLevelsNdx != 0)
		};

		if (lessThanOneInnerLevelsDefined(caseDef) && !caseDef.useLessThanOneInnerLevels)
			continue; // No point generating a separate case as <= 1 inner level behavior is well-defined

		const std::string caseName = std::string() + getTessPrimitiveTypeShaderName(caseDef.primitiveType)
									 + "_" + getSpacingModeShaderName(caseDef.spacingMode)
									 + "_" + getWindingShaderName(caseDef.winding)
									 + (caseDef.usePointMode ? "_point_mode" : "")
									 + (caseDef.useLessThanOneInnerLevels ? "" : "_valid_levels");

		addFunctionCaseWithPrograms(group.get(), caseName, "", initPrograms, test, caseDef);
	}

	return group.release();
}

} // tessellation
} // vkt
