/*------------------------------------------------------------------------
 * 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 "vkObjUtil.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;
	virtual void			checkSupport			(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::checkSupport (Context& context) const
{
	context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
}

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"
			<< "out gl_PerVertex\n"
			<< "{\n"
			<< "	vec4 gl_Position;\n"
			<< "};\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;
	virtual void			checkSupport			(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::checkSupport (Context& context) const
{
	context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
}

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"
					<< "out gl_PerVertex\n"
					<< "{\n"
					<< "	vec4 gl_Position;\n"
					<< "};\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"
					<< "out gl_PerVertex\n"
					<< "{\n"
					<< "	vec4 gl_Position;\n"
					<< "};\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"
					<< "out gl_PerVertex\n"
					<< "{\n"
					<< "	vec4 gl_Position;\n"
					<< "};\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;
	virtual void			checkSupport				(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::checkSupport (Context& context) const
{
	context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);

	if (m_test == TEST_POINT_SIZE)
		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE);
}


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
{
	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
