/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2016 The Khronos Group Inc.
 * Copyright (c) 2016 The Android Open Source Project
 *
 * 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 Basic Geometry Shader Tests
 *//*--------------------------------------------------------------------*/

#include "vktGeometryBasicGeometryShaderTests.hpp"
#include "vktGeometryBasicClass.hpp"
#include "vktGeometryTestsUtil.hpp"

#include "gluTextureUtil.hpp"
#include "glwEnums.hpp"
#include "vkDefs.hpp"
#include "vktTestCase.hpp"
#include "vktTestCaseUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkPrograms.hpp"
#include "vkBuilderUtil.hpp"
#include "vkRefUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkCmdUtil.hpp"
#include "tcuTextureUtil.hpp"

#include <string>

using namespace vk;

namespace vkt
{
namespace geometry
{
namespace
{
using tcu::TestStatus;
using tcu::TestContext;
using tcu::TestCaseGroup;
using de::MovePtr;
using std::string;
using std::vector;

enum VaryingSource
{
	READ_ATTRIBUTE = 0,
	READ_UNIFORM,
	READ_TEXTURE,

	READ_LAST
};
enum ShaderInstancingMode
{
	MODE_WITHOUT_INSTANCING = 0,
	MODE_WITH_INSTANCING,

	MODE_LAST
};
enum
{
	EMIT_COUNT_VERTEX_0 = 6,
	EMIT_COUNT_VERTEX_1 = 0,
	EMIT_COUNT_VERTEX_2 = -1,
	EMIT_COUNT_VERTEX_3 = 10,
};
enum VariableTest
{
	TEST_POINT_SIZE = 0,
	TEST_PRIMITIVE_ID_IN,
	TEST_PRIMITIVE_ID,
	TEST_LAST
};

void uploadImage (Context&								context,
				  const tcu::ConstPixelBufferAccess&	access,
				  VkImage								destImage)
{
	const DeviceInterface&			vk					= context.getDeviceInterface();
	const VkDevice					device				= context.getDevice();
	const deUint32					queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
	const VkQueue					queue				= context.getUniversalQueue();
	Allocator&						memAlloc			= context.getDefaultAllocator();
	const VkImageAspectFlags		aspectMask			= VK_IMAGE_ASPECT_COLOR_BIT;
	const deUint32					bufferSize			= access.getWidth() * access.getHeight() * access.getDepth() * access.getFormat().getPixelSize();
	Move<VkBuffer>					buffer;
	de::MovePtr<Allocation>			bufferAlloc;
	Move<VkCommandPool>				cmdPool;
	Move<VkCommandBuffer>			cmdBuffer;
	Move<VkFence>					fence;

	// Create source buffer
	{
		const VkBufferCreateInfo bufferParams =
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
			DE_NULL,									// const void*			pNext;
			0u,											// VkBufferCreateFlags	flags;
			bufferSize,									// VkDeviceSize			size;
			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
			0u,											// deUint32				queueFamilyIndexCount;
			DE_NULL,									// const deUint32*		pQueueFamilyIndices;
		};
		buffer		= createBuffer(vk, device, &bufferParams);
		bufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
		VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
	}

	// Get copy regions and write buffer data
	const VkBufferImageCopy			copyRegion	=
	{
		0u,								// VkDeviceSize				bufferOffset;
		(deUint32)access.getWidth(),	// deUint32					bufferRowLength;
		(deUint32)access.getHeight(),	// deUint32					bufferImageHeight;
		{								// VkImageSubresourceLayers	imageSubresource;
				aspectMask,				// VkImageAspectFlags		aspectMask;
				(deUint32)0u,			// uint32_t					mipLevel;
				(deUint32)0u,			// uint32_t					baseArrayLayer;
				1u						// uint32_t					layerCount;
		},
		{ 0u, 0u, 0u },					// VkOffset3D			imageOffset;
		{								// VkExtent3D			imageExtent;
			(deUint32)access.getWidth(),
			(deUint32)access.getHeight(),
			(deUint32)access.getDepth()
		}
	};

	vector<VkBufferImageCopy>		copyRegions	(1, copyRegion);

	{
		const tcu::PixelBufferAccess	destAccess	(access.getFormat(), access.getSize(), bufferAlloc->getHostPtr());
		tcu::copy(destAccess, access);
		flushAlloc(vk, device, *bufferAlloc);
	}

	// Copy buffer to image
	copyBufferToImage(vk, device, queue, queueFamilyIndex, *buffer, bufferSize, copyRegions, DE_NULL, aspectMask, 1, 1, destImage, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
}

class GeometryOutputCountTestInstance : public GeometryExpanderRenderTestInstance
{
public:
								GeometryOutputCountTestInstance	(Context&					context,
																 const VkPrimitiveTopology	primitiveType,
																 const int					primitiveCount,
																 const char*				name);
	void						genVertexAttribData				(void);
private:
	const int					m_primitiveCount;
};

GeometryOutputCountTestInstance::GeometryOutputCountTestInstance (Context&					context,
																  const VkPrimitiveTopology	primitiveType,
																  const int					primitiveCount,
																  const char*				name)
	: GeometryExpanderRenderTestInstance	(context, primitiveType, name)
	, m_primitiveCount						(primitiveCount)

{
	genVertexAttribData();
}

void GeometryOutputCountTestInstance::genVertexAttribData (void)
{
	m_vertexPosData.resize(m_primitiveCount);
	m_vertexAttrData.resize(m_primitiveCount);

	for (int ndx = 0; ndx < m_primitiveCount; ++ndx)
	{
		m_vertexPosData[ndx] = tcu::Vec4(-1.0f, ((float)ndx) / (float)m_primitiveCount * 2.0f - 1.0f, 0.0f, 1.0f);
		m_vertexAttrData[ndx] = (ndx % 2 == 0) ? tcu::Vec4(1, 1, 1, 1) : tcu::Vec4(1, 0, 0, 1);
	}
	m_numDrawVertices = m_primitiveCount;
}

class VaryingOutputCountTestInstance : public GeometryExpanderRenderTestInstance
{
public:
								VaryingOutputCountTestInstance	(Context&					context,
																 const char*				name,
																 const VkPrimitiveTopology	primitiveType,
																 const VaryingSource		test,
																 const ShaderInstancingMode	mode);
	void						genVertexAttribData				(void);
protected:
	Move<VkPipelineLayout>		createPipelineLayout			(const DeviceInterface& vk, const VkDevice device);
	void						bindDescriptorSets				(const DeviceInterface&		vk,
																 const VkDevice				device,
																 Allocator&					memAlloc,
																 const VkCommandBuffer&		cmdBuffer,
																 const VkPipelineLayout&	pipelineLayout);
private:
	void						genVertexDataWithoutInstancing	(void);
	void						genVertexDataWithInstancing		(void);

	const VaryingSource			m_test;
	const ShaderInstancingMode	m_mode;
	const deInt32				m_maxEmitCount;
	Move<VkDescriptorPool>		m_descriptorPool;
	Move<VkDescriptorSetLayout>	m_descriptorSetLayout;
	Move<VkDescriptorSet>		m_descriptorSet;
	Move<VkBuffer>				m_buffer;
	Move<VkImage>				m_texture;
	Move<VkImageView>			m_imageView;
	Move<VkSampler>				m_sampler;
	de::MovePtr<Allocation>		m_allocation;
};

VaryingOutputCountTestInstance::VaryingOutputCountTestInstance (Context&					context,
																const char*					name,
																const VkPrimitiveTopology	primitiveType,
																const VaryingSource			test,
																const ShaderInstancingMode	mode)
	: GeometryExpanderRenderTestInstance	(context, primitiveType, name)
	, m_test								(test)
	, m_mode								(mode)
	, m_maxEmitCount						(128)
{
	genVertexAttribData ();
}

void VaryingOutputCountTestInstance::genVertexAttribData (void)
{
	if (m_mode == MODE_WITHOUT_INSTANCING)
		genVertexDataWithoutInstancing();
	else if (m_mode == MODE_WITH_INSTANCING)
		genVertexDataWithInstancing();
	else
		DE_ASSERT(false);
}

Move<VkPipelineLayout> VaryingOutputCountTestInstance::createPipelineLayout (const DeviceInterface& vk, const VkDevice device)
{
	if (m_test == READ_UNIFORM)
	{
		m_descriptorSetLayout	=	DescriptorSetLayoutBuilder()
									.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_GEOMETRY_BIT)
									.build(vk, device);
		m_descriptorPool		=	DescriptorPoolBuilder()
									.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
									.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
		m_descriptorSet			=	makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);

		return makePipelineLayout(vk, device, *m_descriptorSetLayout);
	}
	else if (m_test == READ_TEXTURE)
	{
		const tcu::Vec4				data[4]				=
														{
															tcu::Vec4(255, 0, 0, 0),
															tcu::Vec4(0, 255, 0, 0),
															tcu::Vec4(0, 0, 255, 0),
															tcu::Vec4(0, 0, 0, 255)
														};
		const tcu::UVec2			viewportSize		(4, 1);
		const tcu::TextureFormat	texFormat			= glu::mapGLInternalFormat(GL_RGBA8);
		const VkFormat				format				= mapTextureFormat(texFormat);
		const VkImageUsageFlags		imageUsageFlags		= VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
		Allocator&					memAlloc			= m_context.getDefaultAllocator();
		tcu::TextureLevel			texture				(texFormat, static_cast<int>(viewportSize.x()), static_cast<int>(viewportSize.y()));

		// Fill with data
		{
			tcu::PixelBufferAccess access = texture.getAccess();
			for (int x = 0; x < texture.getWidth(); ++x)
				access.setPixel(data[x], x, 0);
		}
		// Create image
		const VkImageCreateInfo			imageParams =
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType;
			DE_NULL,								// const void*				pNext;
			0,										// VkImageCreateFlags		flags;
			VK_IMAGE_TYPE_2D,						// VkImageType				imageType;
			format,									// VkFormat					format;
			{										// VkExtent3D				extent;
					viewportSize.x(),
					viewportSize.y(),
					1u,
			},
			1u,							// deUint32					mipLevels;
			1u,							// deUint32					arrayLayers;
			VK_SAMPLE_COUNT_1_BIT,		// VkSampleCountFlagBits	samples;
			VK_IMAGE_TILING_OPTIMAL,	// VkImageTiling			tiling;
			imageUsageFlags,			// VkImageUsageFlags		usage;
			VK_SHARING_MODE_EXCLUSIVE,	// VkSharingMode			sharingMode;
			0u,							// deUint32					queueFamilyIndexCount;
			DE_NULL,					// const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED	// VkImageLayout			initialLayout;
		};

		m_texture		= createImage(vk, device, &imageParams);
		m_allocation	= memAlloc.allocate(getImageMemoryRequirements(vk, device, *m_texture), MemoryRequirement::Any);
		VK_CHECK(vk.bindImageMemory(device, *m_texture, m_allocation->getMemory(), m_allocation->getOffset()));
		uploadImage(m_context, texture.getAccess(), *m_texture);

		m_descriptorSetLayout	=	DescriptorSetLayoutBuilder()
									.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_GEOMETRY_BIT)
									.build(vk, device);
		m_descriptorPool		=	DescriptorPoolBuilder()
									.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
									.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
		m_descriptorSet			=	makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);

		return makePipelineLayout(vk, device, *m_descriptorSetLayout);
	}
	else
		return makePipelineLayout(vk, device);
}

void VaryingOutputCountTestInstance::bindDescriptorSets (const DeviceInterface& vk, const VkDevice device, Allocator& memAlloc,
														 const VkCommandBuffer& cmdBuffer, const VkPipelineLayout& pipelineLayout)
{
	if (m_test == READ_UNIFORM)
	{
		const deInt32				emitCount[4]		= { 6, 0, m_maxEmitCount, 10 };
		const VkBufferCreateInfo	bufferCreateInfo	= makeBufferCreateInfo(sizeof(emitCount), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
		m_buffer										= createBuffer(vk, device, &bufferCreateInfo);
		m_allocation									= memAlloc.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), MemoryRequirement::HostVisible);

		VK_CHECK(vk.bindBufferMemory(device, *m_buffer, m_allocation->getMemory(), m_allocation->getOffset()));
		{
			deMemcpy(m_allocation->getHostPtr(), &emitCount[0], sizeof(emitCount));
			flushAlloc(vk, device, *m_allocation);

			const VkDescriptorBufferInfo bufferDescriptorInfo = makeDescriptorBufferInfo(*m_buffer, 0ull, sizeof(emitCount));

			DescriptorSetUpdateBuilder()
				.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &bufferDescriptorInfo)
				.update(vk, device);
			vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0u, 1u, &*m_descriptorSet, 0u, DE_NULL);
		}
	}
	else if (m_test == READ_TEXTURE)
	{
		const tcu::TextureFormat	texFormat			= glu::mapGLInternalFormat(GL_RGBA8);
		const VkFormat				format				= mapTextureFormat(texFormat);
		const VkSamplerCreateInfo	samplerParams		=
														{
															VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,		// VkStructureType			sType;
															DE_NULL,									// const void*				pNext;
															0u,											// VkSamplerCreateFlags		flags;
															VK_FILTER_NEAREST,							// VkFilter					magFilter;
															VK_FILTER_NEAREST,							// VkFilter					minFilter;
															VK_SAMPLER_MIPMAP_MODE_NEAREST,				// VkSamplerMipmapMode		mipmapMode;
															VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeU;
															VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeV;
															VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeW;
															0.0f,										// float					mipLodBias;
															VK_FALSE,									// VkBool32					anisotropyEnable;
															1.0f,										// float					maxAnisotropy;
															false,										// VkBool32					compareEnable;
															VK_COMPARE_OP_NEVER,						// VkCompareOp				compareOp;
															0.0f,										// float					minLod;
															0.0f,										// float					maxLod;
															VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,	// VkBorderColor			borderColor;
															false										// VkBool32					unnormalizedCoordinates;
														};
		m_sampler										= createSampler(vk, device, &samplerParams);
		const VkImageViewCreateInfo	viewParams			=
														{
															VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType;
															NULL,										// const voide*				pNext;
															0u,											// VkImageViewCreateFlags	flags;
															*m_texture,									// VkImage					image;
															VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType;
															format,										// VkFormat					format;
															makeComponentMappingRGBA(),					// VkChannelMapping			channels;
															{
																VK_IMAGE_ASPECT_COLOR_BIT,				// VkImageAspectFlags	aspectMask;
																0u,										// deUint32				baseMipLevel;
																1u,										// deUint32				mipLevels;
																0,										// deUint32				baseArraySlice;
																1u										// deUint32				arraySize;
															},											// VkImageSubresourceRange	subresourceRange;
														};
		m_imageView										= createImageView(vk, device, &viewParams);
		const VkDescriptorImageInfo descriptorImageInfo = makeDescriptorImageInfo (*m_sampler, *m_imageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
		DescriptorSetUpdateBuilder()
			.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorImageInfo)
			.update(vk, device);
		vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0u, 1u, &*m_descriptorSet, 0u, DE_NULL);
	}
}

void VaryingOutputCountTestInstance::genVertexDataWithoutInstancing (void)
{
	m_numDrawVertices = 4;
	m_vertexPosData.resize(m_numDrawVertices);
	m_vertexAttrData.resize(m_numDrawVertices);

	m_vertexPosData[0] = tcu::Vec4( 0.5f,  0.0f, 0.0f, 1.0f);
	m_vertexPosData[1] = tcu::Vec4( 0.0f,  0.5f, 0.0f, 1.0f);
	m_vertexPosData[2] = tcu::Vec4(-0.7f, -0.1f, 0.0f, 1.0f);
	m_vertexPosData[3] = tcu::Vec4(-0.1f, -0.7f, 0.0f, 1.0f);

	if (m_test == READ_ATTRIBUTE)
	{
		m_vertexAttrData[0] = tcu::Vec4(((EMIT_COUNT_VERTEX_0 == -1) ? ((float)m_maxEmitCount) : ((float)EMIT_COUNT_VERTEX_0)), 0.0f, 0.0f, 0.0f);
		m_vertexAttrData[1] = tcu::Vec4(((EMIT_COUNT_VERTEX_1 == -1) ? ((float)m_maxEmitCount) : ((float)EMIT_COUNT_VERTEX_1)), 0.0f, 0.0f, 0.0f);
		m_vertexAttrData[2] = tcu::Vec4(((EMIT_COUNT_VERTEX_2 == -1) ? ((float)m_maxEmitCount) : ((float)EMIT_COUNT_VERTEX_2)), 0.0f, 0.0f, 0.0f);
		m_vertexAttrData[3] = tcu::Vec4(((EMIT_COUNT_VERTEX_3 == -1) ? ((float)m_maxEmitCount) : ((float)EMIT_COUNT_VERTEX_3)), 0.0f, 0.0f, 0.0f);
	}
	else
	{
		m_vertexAttrData[0] = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
		m_vertexAttrData[1] = tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f);
		m_vertexAttrData[2] = tcu::Vec4(2.0f, 0.0f, 0.0f, 0.0f);
		m_vertexAttrData[3] = tcu::Vec4(3.0f, 0.0f, 0.0f, 0.0f);
	}
}

void VaryingOutputCountTestInstance::genVertexDataWithInstancing (void)
{
	m_numDrawVertices = 1;
	m_vertexPosData.resize(m_numDrawVertices);
	m_vertexAttrData.resize(m_numDrawVertices);

	m_vertexPosData[0] = tcu::Vec4(0.0f,  0.0f, 0.0f, 1.0f);

	if (m_test == READ_ATTRIBUTE)
	{
		const int emitCounts[] =
		{
			(EMIT_COUNT_VERTEX_0 == -1) ? (m_maxEmitCount) : (EMIT_COUNT_VERTEX_0),
			(EMIT_COUNT_VERTEX_1 == -1) ? (m_maxEmitCount) : (EMIT_COUNT_VERTEX_1),
			(EMIT_COUNT_VERTEX_2 == -1) ? (m_maxEmitCount) : (EMIT_COUNT_VERTEX_2),
			(EMIT_COUNT_VERTEX_3 == -1) ? (m_maxEmitCount) : (EMIT_COUNT_VERTEX_3),
		};

		m_vertexAttrData[0] = tcu::Vec4((float)emitCounts[0], (float)emitCounts[1], (float)emitCounts[2], (float)emitCounts[3]);
	}
	else
	{
		// not used
		m_vertexAttrData[0] = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
	}
}

class BuiltinVariableRenderTestInstance: public GeometryExpanderRenderTestInstance
{
public:
			BuiltinVariableRenderTestInstance	(Context&				context,
												 const char*			name,
												 const VariableTest		test,
												 const bool				indicesTest);
	void	genVertexAttribData					(void);
	void	createIndicesBuffer					(void);

protected:
	void	drawCommand							(const VkCommandBuffer&	cmdBuffer);

private:
	const bool				m_indicesTest;
	std::vector<deUint16>	m_indices;
	Move<vk::VkBuffer>		m_indicesBuffer;
	MovePtr<Allocation>		m_allocation;
};

BuiltinVariableRenderTestInstance::BuiltinVariableRenderTestInstance (Context& context, const char* name, const VariableTest test, const bool indicesTest)
	: GeometryExpanderRenderTestInstance	(context, (test == TEST_PRIMITIVE_ID_IN) ? VK_PRIMITIVE_TOPOLOGY_LINE_STRIP : VK_PRIMITIVE_TOPOLOGY_POINT_LIST, name)
	, m_indicesTest							(indicesTest)
{
	genVertexAttribData();
}

void BuiltinVariableRenderTestInstance::genVertexAttribData (void)
{
	m_numDrawVertices = 5;

	m_vertexPosData.resize(m_numDrawVertices);
	m_vertexPosData[0] = tcu::Vec4( 0.5f,  0.0f, 0.0f, 1.0f);
	m_vertexPosData[1] = tcu::Vec4( 0.0f,  0.5f, 0.0f, 1.0f);
	m_vertexPosData[2] = tcu::Vec4(-0.7f, -0.1f, 0.0f, 1.0f);
	m_vertexPosData[3] = tcu::Vec4(-0.1f, -0.7f, 0.0f, 1.0f);
	m_vertexPosData[4] = tcu::Vec4( 0.5f,  0.0f, 0.0f, 1.0f);

	m_vertexAttrData.resize(m_numDrawVertices);
	m_vertexAttrData[0] = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
	m_vertexAttrData[1] = tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f);
	m_vertexAttrData[2] = tcu::Vec4(2.0f, 0.0f, 0.0f, 0.0f);
	m_vertexAttrData[3] = tcu::Vec4(3.0f, 0.0f, 0.0f, 0.0f);
	m_vertexAttrData[4] = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);

	if (m_indicesTest)
	{
		// Only used by primitive ID restart test
		m_indices.resize(m_numDrawVertices);
		m_indices[0] = 1;
		m_indices[1] = 4;
		m_indices[2] = 0xFFFF; // restart
		m_indices[3] = 2;
		m_indices[4] = 1;
		createIndicesBuffer();
	}
}

void BuiltinVariableRenderTestInstance::createIndicesBuffer (void)
{
	// Create vertex indices buffer
	const DeviceInterface&			vk					= m_context.getDeviceInterface();
	const VkDevice					device				= m_context.getDevice();
	Allocator&						memAlloc			= m_context.getDefaultAllocator();
	const VkDeviceSize				indexBufferSize		= m_indices.size() * sizeof(deUint16);
	const VkBufferCreateInfo		indexBufferParams	=
														{
															VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
															DE_NULL,								// const void*			pNext;
															0u,										// VkBufferCreateFlags	flags;
															indexBufferSize,						// VkDeviceSize			size;
															VK_BUFFER_USAGE_INDEX_BUFFER_BIT,		// VkBufferUsageFlags	usage;
															VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
															0u,										// deUint32				queueFamilyCount;
															DE_NULL									// const deUint32*		pQueueFamilyIndices;
														};

	m_indicesBuffer = createBuffer(vk, device, &indexBufferParams);
	m_allocation = memAlloc.allocate(getBufferMemoryRequirements(vk, device, *m_indicesBuffer), MemoryRequirement::HostVisible);
	VK_CHECK(vk.bindBufferMemory(device, *m_indicesBuffer, m_allocation->getMemory(), m_allocation->getOffset()));
	// Load indices into buffer
	deMemcpy(m_allocation->getHostPtr(), &m_indices[0], (size_t)indexBufferSize);
	flushAlloc(vk, device, *m_allocation);
}

void BuiltinVariableRenderTestInstance::drawCommand (const VkCommandBuffer&	cmdBuffer)
{
	const DeviceInterface&	vk = m_context.getDeviceInterface();
	if (m_indicesTest)
	{
		vk.cmdBindIndexBuffer(cmdBuffer, *m_indicesBuffer, 0, VK_INDEX_TYPE_UINT16);
		vk.cmdDrawIndexed(cmdBuffer, static_cast<deUint32>(m_indices.size()), 1, 0, 0, 0);
	}
	else
		vk.cmdDraw(cmdBuffer, static_cast<deUint32>(m_numDrawVertices), 1u, 0u, 0u);
}

class GeometryOutputCountTest : public TestCase
{
public:
							GeometryOutputCountTest	(TestContext&		testCtx,
													 const char*		name,
													 const char*		description,
													 const vector<int>	pattern);

	void					initPrograms			(SourceCollections&			sourceCollections) const;
	virtual TestInstance*	createInstance			(Context&					context) const;

protected:
	const vector<int> m_pattern;
};

GeometryOutputCountTest::GeometryOutputCountTest (TestContext& testCtx, const char* name, const char* description, const vector<int> pattern)
	: TestCase	(testCtx, name, description)
	, m_pattern	(pattern)
{

}

void GeometryOutputCountTest::initPrograms (SourceCollections& sourceCollections) const
{
	{
		std::ostringstream src;
		src	<< "#version 310 es\n"
			<<"layout(location = 0) in highp vec4 a_position;\n"
			<<"layout(location = 1) in highp vec4 a_color;\n"
			<<"layout(location = 0) out highp vec4 v_geom_FragColor;\n"
			<<"void main (void)\n"
			<<"{\n"
			<<"	gl_Position = a_position;\n"
			<<"	v_geom_FragColor = a_color;\n"
			<<"}\n";
		sourceCollections.glslSources.add("vertex") << glu::VertexSource(src.str());
	}

	{
		const int max_vertices = m_pattern.size() == 2 ? std::max(m_pattern[0], m_pattern[1]) : m_pattern[0];

		std::ostringstream src;
		src	<< "#version 310 es\n"
			<< "#extension GL_EXT_geometry_shader : require\n"
			<< "#extension GL_OES_texture_storage_multisample_2d_array : require\n"
			<< "layout(points) in;\n"
			<< "layout(triangle_strip, max_vertices = " << max_vertices << ") out;\n"
			<< "layout(location = 0) in highp vec4 v_geom_FragColor[];\n"
			<< "layout(location = 0) out highp vec4 v_frag_FragColor;\n"
			<< "void main (void)\n"
			<< "{\n"
			<< "	const highp float rowHeight = 2.0 / float(" << m_pattern.size() << ");\n"
			<< "	const highp float colWidth = 2.0 / float(" << max_vertices << ");\n";

		if (m_pattern.size() == 2)
			src	<< "	highp int emitCount = (gl_PrimitiveIDIn == 0) ? (" << m_pattern[0] << ") : (" << m_pattern[1] << ");\n";
		else
			src	<< "	highp int emitCount = " << m_pattern[0] << ";\n";
		src	<< "	for (highp int ndx = 0; ndx < emitCount / 2; ndx++)\n"
			<< "	{\n"
			<< "		gl_Position = gl_in[0].gl_Position + vec4(float(ndx) * 2.0 * colWidth, 0.0, 0.0, 0.0);\n"
			<< "		v_frag_FragColor = v_geom_FragColor[0];\n"
			<< "		EmitVertex();\n"

			<< "		gl_Position = gl_in[0].gl_Position + vec4(float(ndx) * 2.0 * colWidth, rowHeight, 0.0, 0.0);\n"
			<< "		v_frag_FragColor = v_geom_FragColor[0];\n"
			<< "		EmitVertex();\n"

			<< "	}\n"
			<< "}\n";
		sourceCollections.glslSources.add("geometry") << glu::GeometrySource(src.str());
	}

	{
		std::ostringstream src;
		src	<< "#version 310 es\n"
			<<"layout(location = 0) out mediump vec4 fragColor;\n"
			<<"layout(location = 0) in highp vec4 v_frag_FragColor;\n"
			<<"void main (void)\n"
			<<"{\n"
			<<"	fragColor = v_frag_FragColor;\n"
			<<"}\n";
		sourceCollections.glslSources.add("fragment") << glu::FragmentSource(src.str());
	}
}

TestInstance* GeometryOutputCountTest::createInstance (Context& context) const
{
	return new GeometryOutputCountTestInstance (context, VK_PRIMITIVE_TOPOLOGY_POINT_LIST, static_cast<int>(m_pattern.size()), getName());
}

class VaryingOutputCountCase : public TestCase
{
public:
							VaryingOutputCountCase	(TestContext&				testCtx,
													 const char*				name,
													 const char*				description,
													 const VaryingSource		test,
													 const ShaderInstancingMode	mode);
	void					initPrograms			(SourceCollections&			sourceCollections) const;
	virtual TestInstance*	createInstance			(Context&					context) const;
protected:
	const VaryingSource			m_test;
	const ShaderInstancingMode	m_mode;
};

VaryingOutputCountCase::VaryingOutputCountCase (TestContext& testCtx, const char* name, const char* description, const VaryingSource test, const ShaderInstancingMode mode)
	: TestCase	(testCtx, name, description)
	, m_test	(test)
	, m_mode	(mode)
{
}

void VaryingOutputCountCase::initPrograms (SourceCollections& sourceCollections) const
{
	{
		std::ostringstream src;
		switch(m_test)
		{
			case READ_ATTRIBUTE:
			case READ_TEXTURE:
				src	<< "#version 310 es\n"
					<< "layout(location = 0) in highp vec4 a_position;\n"
					<< "layout(location = 1) in highp vec4 a_emitCount;\n"
					<< "layout(location = 0) out highp vec4 v_geom_emitCount;\n"
					<< "void main (void)\n"
					<< "{\n"
					<< "	gl_Position = a_position;\n"
					<< "	v_geom_emitCount = a_emitCount;\n"
					<< "}\n";
				break;
			case READ_UNIFORM:
				src	<< "#version 310 es\n"
					<< "layout(location = 0) in highp vec4 a_position;\n"
					<< "layout(location = 1) in highp vec4 a_vertexNdx;\n"
					<< "layout(location = 0) out highp vec4 v_geom_vertexNdx;\n"
					<< "void main (void)\n"
					<< "{\n"
					<< "	gl_Position = a_position;\n"
					<< "	v_geom_vertexNdx = a_vertexNdx;\n"
					<< "}\n";
				break;
			default:
				DE_ASSERT(0);
				break;
		}
		sourceCollections.glslSources.add("vertex") << glu::VertexSource(src.str());
	}

	{
		const bool instanced = MODE_WITH_INSTANCING == m_mode;
		std::ostringstream src;
		src	<< "#version 310 es\n"
			<< "#extension GL_EXT_geometry_shader : require\n"
			<< "#extension GL_OES_texture_storage_multisample_2d_array : require\n";
		if (instanced)
			src	<< "layout(points, invocations=4) in;\n";
		else
			src	<< "layout(points) in;\n";

		switch(m_test)
		{
			case READ_ATTRIBUTE:
				src	<< "layout(triangle_strip, max_vertices = 128) out;\n"
					<< "layout(location = 0) in highp vec4 v_geom_emitCount[];\n"
					<< "layout(location = 0) out highp vec4 v_frag_FragColor;\n"
					<< "void main (void)\n"
					<< "{\n"
					<< "	highp vec4 attrEmitCounts = v_geom_emitCount[0];\n"
					<< "	mediump int emitCount = int(attrEmitCounts[" << ((instanced) ? ("gl_InvocationID") : ("0")) << "]);\n"
					<< "	highp vec4 color = vec4((emitCount < 10) ? (0.0) : (1.0), (emitCount > 10) ? (0.0) : (1.0), 1.0, 1.0);\n"
					<< "	highp vec4 basePos = " << ((instanced) ? ("gl_in[0].gl_Position + 0.5 * vec4(cos(float(gl_InvocationID)), sin(float(gl_InvocationID)), 0.0, 0.0)") : ("gl_in[0].gl_Position")) << ";\n"
					<< "	for (mediump int i = 0; i < emitCount / 2; i++)\n"
					<< "	{\n"
					<< "		highp float angle = (float(i) + 0.5) / float(emitCount / 2) * 3.142;\n"
					<< "		gl_Position = basePos + vec4(cos(angle),  sin(angle), 0.0, 0.0) * 0.15;\n"
					<< "		v_frag_FragColor = color;\n"
					<< "		EmitVertex();\n"
					<< "		gl_Position = basePos + vec4(cos(angle), -sin(angle), 0.0, 0.0) * 0.15;\n"
					<< "		v_frag_FragColor = color;\n"
					<< "		EmitVertex();\n"
					<< "	}\n"
					<<"}\n";
				break;
			case READ_UNIFORM:
				src	<< "layout(triangle_strip, max_vertices = 128) out;\n"
					<< "layout(location = 0) in highp vec4 v_geom_vertexNdx[];\n"
					<< "layout(binding = 0) readonly uniform Input {\n"
					<< "	ivec4 u_emitCount;\n"
					<< "} emit;\n"
					<< "layout(location = 0) out highp vec4 v_frag_FragColor;\n"
					<< "void main (void)\n"
					<< "{\n"
					<< "	mediump int primitiveNdx = " << ((instanced) ? ("gl_InvocationID") : ("int(v_geom_vertexNdx[0].x)")) << ";\n"
					<< "	mediump int emitCount = emit.u_emitCount[primitiveNdx];\n"
					<< "\n"
					<< "	const highp vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
					<< "	const highp vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
					<< "	const highp vec4 blue = vec4(0.0, 0.0, 1.0, 1.0);\n"
					<< "	const highp vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n"
					<< "	const highp vec4 colors[4] = vec4[4](red, green, blue, yellow);\n"
					<< "	highp vec4 color = colors[int(primitiveNdx)];\n"
					<< "\n"
					<< "	highp vec4 basePos = " << ((instanced) ? ("gl_in[0].gl_Position + 0.5 * vec4(cos(float(gl_InvocationID)), sin(float(gl_InvocationID)), 0.0, 0.0)") : ("gl_in[0].gl_Position")) << ";\n"
					<< "	for (mediump int i = 0; i < emitCount / 2; i++)\n"
					<< "	{\n"
					<< "		highp float angle = (float(i) + 0.5) / float(emitCount / 2) * 3.142;\n"
					<< "		gl_Position = basePos + vec4(cos(angle),  sin(angle), 0.0, 0.0) * 0.15;\n"
					<< "		v_frag_FragColor = color;\n"
					<< "		EmitVertex();\n"
					<< "		gl_Position = basePos + vec4(cos(angle), -sin(angle), 0.0, 0.0) * 0.15;\n"
					<< "		v_frag_FragColor = color;\n"
					<< "		EmitVertex();\n"
					<< "	}\n"
					<<"}\n";
				break;
			case READ_TEXTURE:
				src	<< "layout(triangle_strip, max_vertices = 128) out;\n"
					<< "layout(location = 0) in highp vec4 v_geom_vertexNdx[];\n"
					<< "layout(binding = 0) uniform highp sampler2D u_sampler;\n"
					<< "layout(location = 0) out highp vec4 v_frag_FragColor;\n"
					<< "void main (void)\n"
					<< "{\n"
					<< "	highp float primitiveNdx = " << ((instanced) ? ("float(gl_InvocationID)") : ("v_geom_vertexNdx[0].x")) << ";\n"
					<< "	highp vec2 texCoord = vec2(1.0 / 8.0 + primitiveNdx / 4.0, 0.5);\n"
					<< "	highp vec4 texColor = texture(u_sampler, texCoord);\n"
					<< "	mediump int emitCount = 0;\n"
					<< "	if (texColor.x > 0.0)\n"
					<< "		emitCount += 6;\n"
					<< "	if (texColor.y > 0.0)\n"
					<< "		emitCount += 0;\n"
					<< "	if (texColor.z > 0.0)\n"
					<< "		emitCount += 128;\n"
					<< "	if (texColor.w > 0.0)\n"
					<< "		emitCount += 10;\n"
					<< "	const highp vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
					<< "	const highp vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
					<< "	const highp vec4 blue = vec4(0.0, 0.0, 1.0, 1.0);\n"
					<< "	const highp vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n"
					<< "	const highp vec4 colors[4] = vec4[4](red, green, blue, yellow);\n"
					<< "	highp vec4 color = colors[int(primitiveNdx)];\n"
					<< "	highp vec4 basePos = "<< ((instanced) ? ("gl_in[0].gl_Position + 0.5 * vec4(cos(float(gl_InvocationID)), sin(float(gl_InvocationID)), 0.0, 0.0)") : ("gl_in[0].gl_Position")) << ";\n"
					<< "	for (mediump int i = 0; i < emitCount / 2; i++)\n"
					<< "	{\n"
					<< "		highp float angle = (float(i) + 0.5) / float(emitCount / 2) * 3.142;\n"
					<< "		gl_Position = basePos + vec4(cos(angle),  sin(angle), 0.0, 0.0) * 0.15;\n"
					<< "		v_frag_FragColor = color;\n"
					<< "		EmitVertex();\n"
					<< "		gl_Position = basePos + vec4(cos(angle), -sin(angle), 0.0, 0.0) * 0.15;\n"
					<< "		v_frag_FragColor = color;\n"
					<< "		EmitVertex();\n"
					<< "	}\n"
					<<"}\n";
				break;
			default:
				DE_ASSERT(0);
				break;
		}
		sourceCollections.glslSources.add("geometry") << glu::GeometrySource(src.str());
	}

	{
		std::ostringstream src;
		src	<< "#version 310 es\n"
			<< "layout(location = 0) out mediump vec4 fragColor;\n"
			<< "layout(location = 0) in highp vec4 v_frag_FragColor;\n"
			<< "void main (void)\n"
			<< "{\n"
			<< "	fragColor = v_frag_FragColor;\n"
			<< "}\n";
		sourceCollections.glslSources.add("fragment") << glu::FragmentSource(src.str());
	}
}

TestInstance* VaryingOutputCountCase::createInstance (Context& context) const
{
	return new VaryingOutputCountTestInstance (context, getName(), VK_PRIMITIVE_TOPOLOGY_POINT_LIST, m_test, m_mode);
}

class BuiltinVariableRenderTest : public TestCase
{
public:
							BuiltinVariableRenderTest	(TestContext&		testCtx,
														const char*			name,
														const char*			desc,
														const VariableTest	test,
														const bool			flag = false);
	void					initPrograms				(SourceCollections&	sourceCollections) const;
	virtual TestInstance*	createInstance				(Context&			context) const;
protected:
	const VariableTest	m_test;
	const bool			m_flag;
};

BuiltinVariableRenderTest::BuiltinVariableRenderTest (TestContext& testCtx, const char* name, const char* description, const VariableTest test, const bool flag)
	: TestCase	(testCtx, name, description)
	, m_test	(test)
	, m_flag	(flag)
{
}

void BuiltinVariableRenderTest::initPrograms (SourceCollections& sourceCollections) const
{
	{
		std::ostringstream src;
		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
			<< "out gl_PerVertex\n"
			<<" {\n"
			<< "	vec4 gl_Position;\n"
			<< "	float gl_PointSize;\n"
			<< "};\n"
			<< "layout(location = 0) in vec4 a_position;\n";
		switch(m_test)
		{
			case TEST_POINT_SIZE:
				src	<< "layout(location = 1) in vec4 a_pointSize;\n"
					<< "layout(location = 0) out vec4 v_geom_pointSize;\n"
					<< "void main (void)\n"
					<< "{\n"
					<< "	gl_Position = a_position;\n"
					<< "	gl_PointSize = 1.0;\n"
					<< "	v_geom_pointSize = a_pointSize;\n"
					<< "}\n";
				break;
			case TEST_PRIMITIVE_ID_IN:
				src	<< "void main (void)\n"
					<< "{\n"
					<< "	gl_Position = a_position;\n"
					<< "}\n";
				break;
			case TEST_PRIMITIVE_ID:
				src	<< "layout(location = 1) in vec4 a_primitiveID;\n"
					<< "layout(location = 0) out vec4 v_geom_primitiveID;\n"
					<< "void main (void)\n"
					<< "{\n"
					<< "	gl_Position = a_position;\n"
					<< "	v_geom_primitiveID = a_primitiveID;\n"
					<< "}\n";
				break;
			default:
				DE_ASSERT(0);
				break;
		}
		sourceCollections.glslSources.add("vertex") << glu::VertexSource(src.str());
	}

	{
		std::ostringstream src;
		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
			<< "in gl_PerVertex\n"
			<<"{\n"
			<< "	vec4 gl_Position;\n"
			<< "	float gl_PointSize;\n"
			<< "} gl_in[];\n"
			<< "out gl_PerVertex\n"
			<<"{\n"
			<< "	vec4 gl_Position;\n"
			<< "	float gl_PointSize;\n"
			<< "};\n";
		switch(m_test)
		{
			case TEST_POINT_SIZE:
				src	<< "#extension GL_EXT_geometry_point_size : require\n"
					<< "layout(points) in;\n"
					<< "layout(points, max_vertices = 1) out;\n"
					<< "layout(location = 0) in vec4 v_geom_pointSize[];\n"
					<< "layout(location = 0) out vec4 v_frag_FragColor;\n"
					<< "void main (void)\n"
					<< "{\n"
					<< "	gl_Position = gl_in[0].gl_Position;\n"
					<< "	gl_PointSize = v_geom_pointSize[0].x + 1.0;\n"
					<< "	v_frag_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
					<< "	EmitVertex();\n"
					<< "}\n";
				break;
			case TEST_PRIMITIVE_ID_IN:
				src	<< "layout(lines) in;\n"
					<< "layout(triangle_strip, max_vertices = 10) out;\n"
					<< "layout(location = 0) out vec4 v_frag_FragColor;\n"
					<< "void main (void)\n"
					<< "{\n"
					<< "	const vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
					<< "	const vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
					<< "	const vec4 blue = vec4(0.0, 0.0, 1.0, 1.0);\n"
					<< "	const vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n"
					<< "	const vec4 colors[4] = vec4[4](red, green, blue, yellow);\n"
					<< "	for (int counter = 0; counter < 3; ++counter)\n"
					<< "	{\n"
					<< "		float percent = 0.1 * counter;\n"
					<< "		gl_Position = gl_in[0].gl_Position * vec4(1.0 + percent, 1.0 + percent, 1.0, 1.0);\n"
					<< "		v_frag_FragColor = colors[gl_PrimitiveIDIn % 4];\n"
					<< "		EmitVertex();\n"
					<< "		gl_Position = gl_in[1].gl_Position * vec4(1.0 + percent, 1.0 + percent, 1.0, 1.0);\n"
					<< "		v_frag_FragColor = colors[gl_PrimitiveIDIn % 4];\n"
					<< "		EmitVertex();\n"
					<< "	}\n"
					<< "}\n";
				break;
			case TEST_PRIMITIVE_ID:
				src	<< "layout(points, invocations=1) in;\n"
					<< "layout(triangle_strip, max_vertices = 3) out;\n"
					<< "layout(location = 0) in vec4 v_geom_primitiveID[];\n"
					<< "void main (void)\n"
					<< "{\n"
					<< "	gl_Position = gl_in[0].gl_Position + vec4(0.05, 0.0, 0.0, 0.0);\n"
					<< "	gl_PrimitiveID = int(floor(v_geom_primitiveID[0].x)) + 3;\n"
					<< "	EmitVertex();\n"
					<< "	gl_Position = gl_in[0].gl_Position - vec4(0.05, 0.0, 0.0, 0.0);\n"
					<< "	gl_PrimitiveID = int(floor(v_geom_primitiveID[0].x)) + 3;\n"
					<< "	EmitVertex();\n"
					<< "	gl_Position = gl_in[0].gl_Position + vec4(0.0, 0.05, 0.0, 0.0);\n"
					<< "	gl_PrimitiveID = int(floor(v_geom_primitiveID[0].x)) + 3;\n"
					<< "	EmitVertex();\n"
					<< "}\n";
				break;
			default:
				DE_ASSERT(0);
				break;
		}
		sourceCollections.glslSources.add("geometry") << glu::GeometrySource(src.str());
	}

	{
		std::ostringstream src;
		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n";
		switch(m_test)
		{
			case TEST_POINT_SIZE:
				src	<< "layout(location = 0) out vec4 fragColor;\n"
					<< "layout(location = 0) in vec4 v_frag_FragColor;\n"
					<< "void main (void)\n"
					<< "{\n"
					<< "	fragColor = v_frag_FragColor;\n"
					<< "}\n";
				break;
			case TEST_PRIMITIVE_ID_IN:
				src	<< "layout(location = 0) out vec4 fragColor;\n"
					<< "layout(location = 0) in vec4 v_frag_FragColor;\n"
					<< "void main (void)\n"
					<< "{\n"
					<< "	fragColor = v_frag_FragColor;\n"
					<< "}\n";
				break;
			case TEST_PRIMITIVE_ID:
				src	<< "layout(location = 0) out vec4 fragColor;\n"
					<< "void main (void)\n"
					<< "{\n"
					<< "	const vec4 red			= vec4(1.0, 0.0, 0.0, 1.0);\n"
					<< "	const vec4 green		= vec4(0.0, 1.0, 0.0, 1.0);\n"
					<< "	const vec4 blue			= vec4(0.0, 0.0, 1.0, 1.0);\n"
					<< "	const vec4 yellow		= vec4(1.0, 1.0, 0.0, 1.0);\n"
					<< "	const vec4 colors[4]	= vec4[4](yellow, red, green, blue);\n"
					<< "	fragColor = colors[gl_PrimitiveID % 4];\n"
					<< "}\n";
				break;
			default:
				DE_ASSERT(0);
				break;
		}
		sourceCollections.glslSources.add("fragment") << glu::FragmentSource(src.str());
	}
}

TestInstance* BuiltinVariableRenderTest::createInstance (Context& context) const
{
	if (m_test == TEST_POINT_SIZE && !checkPointSize(context.getInstanceInterface(), context.getPhysicalDevice()))
			TCU_THROW(NotSupportedError, "Missing feature: pointSize");
	return new BuiltinVariableRenderTestInstance(context, getName(), m_test, m_flag);
}

inline vector<int> createPattern (int count)
{
	vector<int>	pattern;
	pattern.push_back(count);
	return pattern;
}

inline vector<int> createPattern (int count0, int count1)
{
	vector<int>	pattern;
	pattern.push_back(count0);
	pattern.push_back(count1);
	return pattern;
}

} // anonymous

TestCaseGroup* createBasicGeometryShaderTests (TestContext& testCtx)
{
	MovePtr<TestCaseGroup> basicGroup	(new tcu::TestCaseGroup(testCtx, "basic", "Basic tests."));

	basicGroup->addChild(new GeometryOutputCountTest	(testCtx,	"output_10",				"Output 10 vertices",								createPattern(10)));
	basicGroup->addChild(new GeometryOutputCountTest	(testCtx,	"output_128",				"Output 128 vertices",								createPattern(128)));
	basicGroup->addChild(new GeometryOutputCountTest	(testCtx,	"output_10_and_100",		"Output 10 and 100 vertices in two invocations",	createPattern(10, 100)));
	basicGroup->addChild(new GeometryOutputCountTest	(testCtx,	"output_100_and_10",		"Output 100 and 10 vertices in two invocations",	createPattern(100, 10)));
	basicGroup->addChild(new GeometryOutputCountTest	(testCtx,	"output_0_and_128",			"Output 0 and 128 vertices in two invocations",		createPattern(0, 128)));
	basicGroup->addChild(new GeometryOutputCountTest	(testCtx,	"output_128_and_0",			"Output 128 and 0 vertices in two invocations",		createPattern(128, 0)));

	basicGroup->addChild(new VaryingOutputCountCase		(testCtx,	"output_vary_by_attribute",				"Output varying number of vertices",	READ_ATTRIBUTE,	MODE_WITHOUT_INSTANCING));
	basicGroup->addChild(new VaryingOutputCountCase		(testCtx,	"output_vary_by_uniform",				"Output varying number of vertices",	READ_UNIFORM,	MODE_WITHOUT_INSTANCING));
	basicGroup->addChild(new VaryingOutputCountCase		(testCtx,	"output_vary_by_texture",				"Output varying number of vertices",	READ_TEXTURE,	MODE_WITHOUT_INSTANCING));
	basicGroup->addChild(new VaryingOutputCountCase		(testCtx,	"output_vary_by_attribute_instancing",	"Output varying number of vertices",	READ_ATTRIBUTE,	MODE_WITH_INSTANCING));
	basicGroup->addChild(new VaryingOutputCountCase		(testCtx,	"output_vary_by_uniform_instancing",	"Output varying number of vertices",	READ_UNIFORM,	MODE_WITH_INSTANCING));
	basicGroup->addChild(new VaryingOutputCountCase		(testCtx,	"output_vary_by_texture_instancing",	"Output varying number of vertices",	READ_TEXTURE,	MODE_WITH_INSTANCING));

	basicGroup->addChild(new BuiltinVariableRenderTest	(testCtx,	"point_size",					"test gl_PointSize",								TEST_POINT_SIZE));
	basicGroup->addChild(new BuiltinVariableRenderTest	(testCtx,	"primitive_id_in",				"test gl_PrimitiveIDIn",							TEST_PRIMITIVE_ID_IN));
	basicGroup->addChild(new BuiltinVariableRenderTest	(testCtx,	"primitive_id_in_restarted",	"test gl_PrimitiveIDIn with primitive restart",		TEST_PRIMITIVE_ID_IN, true));
	basicGroup->addChild(new BuiltinVariableRenderTest	(testCtx,	"primitive_id",					"test gl_PrimitiveID",								TEST_PRIMITIVE_ID));

	return basicGroup.release();
}

} // geometry
} // vkt
