/*------------------------------------------------------------------------
 * 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 "vkMemUtil.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()));
	}

	// Create command pool and buffer
	{
		const VkCommandPoolCreateInfo cmdPoolParams =
		{
			VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,		// VkStructureType			sType;
			DE_NULL,										// const void*				pNext;
			VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,			// VkCommandPoolCreateFlags	flags;
			queueFamilyIndex,								// deUint32					queueFamilyIndex;
		};
		cmdPool = createCommandPool(vk, device, &cmdPoolParams);

		const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
		{
			VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType			sType;
			DE_NULL,										// const void*				pNext;
			*cmdPool,										// VkCommandPool			commandPool;
			VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// VkCommandBufferLevel		level;
			1u,												// deUint32					bufferCount;
		};
		cmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo);
	}

	// Create fence
	{
		const VkFenceCreateInfo fenceParams =
		{
			VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,	// VkStructureType		sType;
			DE_NULL,								// const void*			pNext;
			0u										// VkFenceCreateFlags	flags;
		};

		fence = createFence(vk, device, &fenceParams);
	}

	// Barriers for copying buffer to image
	const VkBufferMemoryBarrier preBufferBarrier =
	{
		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
		DE_NULL,									// const void*		pNext;
		VK_ACCESS_HOST_WRITE_BIT,					// VkAccessFlags	srcAccessMask;
		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags	dstAccessMask;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
		*buffer,									// VkBuffer			buffer;
		0u,											// VkDeviceSize		offset;
		bufferSize									// VkDeviceSize		size;
	};

	const VkImageMemoryBarrier preImageBarrier =
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
		DE_NULL,									// const void*				pNext;
		0u,											// VkAccessFlags			srcAccessMask;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
		destImage,									// VkImage					image;
		{											// VkImageSubresourceRange	subresourceRange;
			aspectMask,								// VkImageAspect	aspect;
			0u,										// deUint32			baseMipLevel;
			1u,										// deUint32			mipLevels;
			0u,										// deUint32			baseArraySlice;
			1u										// deUint32			arraySize;
		}
	};

	const VkImageMemoryBarrier postImageBarrier =
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
		DE_NULL,									// const void*				pNext;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
		VK_ACCESS_SHADER_READ_BIT,					// VkAccessFlags			dstAccessMask;
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,	// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
		destImage,									// VkImage					image;
		{											// VkImageSubresourceRange	subresourceRange;
			aspectMask,								// VkImageAspect	aspect;
			0u,										// deUint32			baseMipLevel;
			1u,										// deUint32			mipLevels;
			0u,										// deUint32			baseArraySlice;
			1u										// deUint32			arraySize;
		}
	};

	const VkCommandBufferBeginInfo cmdBufferBeginInfo =
	{
		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType					sType;
		DE_NULL,										// const void*						pNext;
		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,	// VkCommandBufferUsageFlags		flags;
		(const VkCommandBufferInheritanceInfo*)DE_NULL,
	};

	// Get copy regions and write buffer data
	const VkBufferImageCopy			copyRegions	=
	{
		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()
		}
	};

	{
		const tcu::PixelBufferAccess	destAccess	(access.getFormat(), access.getSize(), bufferAlloc->getHostPtr());
		tcu::copy(destAccess, access);
		flushMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);
	}

	// Copy buffer to image
	VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
	vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegions);
	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
	VK_CHECK(vk.endCommandBuffer(*cmdBuffer));

	const VkSubmitInfo submitInfo =
	{
		VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType				sType;
		DE_NULL,						// const void*					pNext;
		0u,								// deUint32						waitSemaphoreCount;
		DE_NULL,						// const VkSemaphore*			pWaitSemaphores;
		DE_NULL,						// const VkPipelineStageFlags*	pWaitDstStageMask;
		1u,								// deUint32						commandBufferCount;
		&cmdBuffer.get(),				// const VkCommandBuffer*		pCommandBuffers;
		0u,								// deUint32						signalSemaphoreCount;
		DE_NULL							// const VkSemaphore*			pSignalSemaphores;
	};

	VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
	VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull) /* infinity */));
}

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));
			flushMappedMemoryRange(vk, device, m_allocation->getMemory(), m_allocation->getOffset(), sizeof(emitCount));

			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_GENERAL);
		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);
	flushMappedMemoryRange(vk, device, m_allocation->getMemory(), m_allocation->getOffset(), indexBufferSize);
}

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 (float percent=0.00; percent < 0.30; percent+=0.10)\n"
							"{\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
