/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2018 The Khronos Group Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Vulkan Transform Feedback Simple Tests
 *//*--------------------------------------------------------------------*/

#include "vktTransformFeedbackSimpleTests.hpp"
#include "vktTestGroupUtil.hpp"
#include "vktTestCase.hpp"

#include "vkBuilderUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkObjUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkRefUtil.hpp"
#include "vkTypeUtil.hpp"

#include "deUniquePtr.hpp"
#include "deRandom.hpp"

#include "tcuTextureUtil.hpp"
#include "tcuVectorUtil.hpp"
#include "tcuImageCompare.hpp"
#include "tcuRGBA.hpp"

#include <iostream>
#include <functional>
#include <set>
#include <algorithm>

namespace vkt
{
namespace TransformFeedback
{
namespace
{
using namespace vk;
using de::MovePtr;
using de::UniquePtr;
using de::SharedPtr;

#define VALIDATE_MINIMUM(A,B) if ((A) < (B)) TCU_FAIL(#A "==" + de::toString(A) + " which is less than required by specification (" + de::toString(B) + ")")
#define VALIDATE_BOOL(A) if (! ( (A) == VK_TRUE || (A) == VK_FALSE) ) TCU_FAIL(#A " expected to be VK_TRUE or VK_FALSE. Received " + de::toString((deUint64)(A)))

enum TestType
{
	TEST_TYPE_BASIC,
	TEST_TYPE_RESUME,
	TEST_TYPE_STREAMS,
	TEST_TYPE_XFB_POINTSIZE,
	TEST_TYPE_XFB_CLIPDISTANCE,
	TEST_TYPE_XFB_CULLDISTANCE,
	TEST_TYPE_XFB_CLIP_AND_CULL,
	TEST_TYPE_LINE_LIST,
	TEST_TYPE_LINE_STRIP,
	TEST_TYPE_TRIANGLE_LIST,
	TEST_TYPE_TRIANGLE_STRIP,
	TEST_TYPE_TRIANGLE_FAN,
	TEST_TYPE_LINE_LIST_ADJACENCY,
	TEST_TYPE_LINE_STRIP_ADJACENCY,
	TEST_TYPE_TRIANGLE_STRIP_ADJACENCY,
	TEST_TYPE_TRIANGLE_LIST_ADJACENCY,
	TEST_TYPE_PATCH_LIST,
	TEST_TYPE_STREAMS_POINTSIZE,
	TEST_TYPE_STREAMS_CLIPDISTANCE,
	TEST_TYPE_STREAMS_CULLDISTANCE,
	TEST_TYPE_MULTISTREAMS,
	TEST_TYPE_DRAW_INDIRECT,
	TEST_TYPE_BACKWARD_DEPENDENCY,
	TEST_TYPE_QUERY_GET,
	TEST_TYPE_QUERY_COPY,
	TEST_TYPE_QUERY_RESET,
	TEST_TYPE_MULTIQUERY,
	TEST_TYPE_LAST
};

enum StreamId0Mode
{
	STREAM_ID_0_NORMAL					= 0,
	STREAM_ID_0_BEGIN_QUERY_INDEXED		= 1,
	STREAM_ID_0_END_QUERY_INDEXED		= 2,
};

struct TestParameters
{
	TestType		testType;
	deUint32		bufferSize;
	deUint32		partCount;
	deUint32		streamId;
	deUint32		pointSize;
	deUint32		vertexStride;
	StreamId0Mode	streamId0Mode;
	bool			query64bits;
	bool			noOffsetArray;
};

struct TransformFeedbackQuery
{
	deUint32	written;
	deUint32	attempts;
};

const deUint32 MINIMUM_TF_BUFFER_SIZE	= (1<<27);
const deUint32 IMAGE_SIZE				= 64u;

template<typename T>
inline SharedPtr<Unique<T> > makeSharedPtr(Move<T> move)
{
	return SharedPtr<Unique<T> >(new Unique<T>(move));
}

Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface&		vk,
										   const VkDevice				device)
{
	const VkPushConstantRange			pushConstantRanges			=
	{
		VK_SHADER_STAGE_VERTEX_BIT,						//  VkShaderStageFlags				stageFlags;
		0u,												//  deUint32						offset;
		sizeof(deUint32)								//  deUint32						size;
	};
	const VkPipelineLayoutCreateInfo	pipelineLayoutCreateInfo	=
	{
		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	//  VkStructureType					sType;
		DE_NULL,										//  const void*						pNext;
		(VkPipelineLayoutCreateFlags)0,					//  VkPipelineLayoutCreateFlags		flags;
		0u,												//  deUint32						setLayoutCount;
		DE_NULL,										//  const VkDescriptorSetLayout*	pSetLayouts;
		1u,												//  deUint32						pushConstantRangeCount;
		&pushConstantRanges,							//  const VkPushConstantRange*		pPushConstantRanges;
	};
	return createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
}

Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&		vk,
									   const VkDevice				device,
									   const VkPipelineLayout		pipelineLayout,
									   const VkRenderPass			renderPass,
									   const VkShaderModule			vertexModule,
									   const VkShaderModule			tessellationControlModule,
									   const VkShaderModule			tessellationEvalModule,
									   const VkShaderModule			geometryModule,
									   const VkShaderModule			fragmendModule,
									   const VkExtent2D				renderSize,
									   const deUint32				subpass,
									   const deUint32*				rasterizationStreamPtr	= DE_NULL,
									   const VkPrimitiveTopology	topology				= VK_PRIMITIVE_TOPOLOGY_POINT_LIST,
									   const bool					inputVertices			= false)
{
	const std::vector<VkViewport>							viewports								(1, makeViewport(renderSize));
	const std::vector<VkRect2D>								scissors								(1, makeRect2D(renderSize));
	const VkPipelineVertexInputStateCreateInfo				vertexInputStateCreateInfo			=
	{
		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,									//  VkStructureType									sType
		DE_NULL,																					//  const void*										pNext
		(VkPipelineVertexInputStateCreateFlags)0,													//  VkPipelineVertexInputStateCreateFlags			flags
		0u,																							//  deUint32										vertexBindingDescriptionCount
		DE_NULL,																					//  const VkVertexInputBindingDescription*			pVertexBindingDescriptions
		0u,																							//  deUint32										vertexAttributeDescriptionCount
		DE_NULL,																					//  const VkVertexInputAttributeDescription*		pVertexAttributeDescriptions
	};
	const VkPipelineVertexInputStateCreateInfo*				vertexInputStateCreateInfoPtr		= (inputVertices) ? DE_NULL : &vertexInputStateCreateInfo;
	const VkBool32											disableRasterization				= (fragmendModule == DE_NULL);
	const deUint32											rasterizationStream					= (rasterizationStreamPtr == DE_NULL) ? 0 : *rasterizationStreamPtr;
	const VkPipelineRasterizationStateStreamCreateInfoEXT	rasterizationStateStreamCreateInfo	=
	{
		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT,						//  VkStructureType										sType;
		DE_NULL,																					//  const void*											pNext;
		0,																							//  VkPipelineRasterizationStateStreamCreateFlagsEXT	flags;
		rasterizationStream																			//  deUint32											rasterizationStream;
	};
	const VkPipelineRasterizationStateCreateInfo			rasterizationStateCreateInfo		=
	{
		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,									//  VkStructureType							sType;
		&rasterizationStateStreamCreateInfo,														//  const void*								pNext;
		0u,																							//  VkPipelineRasterizationStateCreateFlags	flags;
		VK_FALSE,																					//  VkBool32								depthClampEnable;
		disableRasterization,																		//  VkBool32								rasterizerDiscardEnable;
		VK_POLYGON_MODE_FILL,																		//  VkPolygonMode							polygonMode;
		VK_CULL_MODE_NONE,																			//  VkCullModeFlags							cullMode;
		VK_FRONT_FACE_COUNTER_CLOCKWISE,															//  VkFrontFace								frontFace;
		VK_FALSE,																					//  VkBool32								depthBiasEnable;
		0.0f,																						//  float									depthBiasConstantFactor;
		0.0f,																						//  float									depthBiasClamp;
		0.0f,																						//  float									depthBiasSlopeFactor;
		1.0f																						//  float									lineWidth;
	};
	const VkPipelineRasterizationStateCreateInfo*			rasterizationStateCreateInfoPtr		= (rasterizationStreamPtr == DE_NULL) ? DE_NULL : &rasterizationStateCreateInfo;

	return makeGraphicsPipeline(vk,											// const DeviceInterface&							vk
								device,										// const VkDevice									device
								pipelineLayout,								// const VkPipelineLayout							pipelineLayout
								vertexModule,								// const VkShaderModule								vertexShaderModule
								tessellationControlModule,					// const VkShaderModule								tessellationControlModule
								tessellationEvalModule,						// const VkShaderModule								tessellationEvalModule
								geometryModule,								// const VkShaderModule								geometryShaderModule
								fragmendModule,								// const VkShaderModule								fragmentShaderModule
								renderPass,									// const VkRenderPass								renderPass
								viewports,									// const std::vector<VkViewport>&					viewports
								scissors,									// const std::vector<VkRect2D>&						scissors
								topology,									// const VkPrimitiveTopology						topology
								subpass,									// const deUint32									subpass
								(tessellationEvalModule != DE_NULL) * 3u,	// const deUint32									patchControlPoints
								vertexInputStateCreateInfoPtr,				// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
								rasterizationStateCreateInfoPtr);			// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
}

VkImageCreateInfo makeImageCreateInfo (const VkImageCreateFlags flags, const VkImageType type, const VkFormat format, const VkExtent2D size, const deUint32 numLayers, const VkImageUsageFlags usage)
{
	const VkExtent3D		extent		= { size.width, size.height, 1u };
	const VkImageCreateInfo imageParams =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType			sType;
		DE_NULL,										// const void*				pNext;
		flags,											// VkImageCreateFlags		flags;
		type,											// VkImageType				imageType;
		format,											// VkFormat					format;
		extent,											// VkExtent3D				extent;
		1u,												// deUint32					mipLevels;
		numLayers,										// deUint32					arrayLayers;
		VK_SAMPLE_COUNT_1_BIT,							// VkSampleCountFlagBits	samples;
		VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling;
		usage,											// VkImageUsageFlags		usage;
		VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
		0u,												// deUint32					queueFamilyIndexCount;
		DE_NULL,										// const deUint32*			pQueueFamilyIndices;
		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			initialLayout;
	};
	return imageParams;
}

Move<VkRenderPass> makeRenderPass (const DeviceInterface&		vk,
								   const VkDevice				device)
{
	std::vector<VkSubpassDescription>	subpassDescriptions;
	std::vector<VkSubpassDependency>	subpassDependencies;

	const VkSubpassDescription	description	=
	{
		(VkSubpassDescriptionFlags)0,		//  VkSubpassDescriptionFlags		flags;
		VK_PIPELINE_BIND_POINT_GRAPHICS,	//  VkPipelineBindPoint				pipelineBindPoint;
		0u,									//  deUint32						inputAttachmentCount;
		DE_NULL,							//  const VkAttachmentReference*	pInputAttachments;
		0u,									//  deUint32						colorAttachmentCount;
		DE_NULL,							//  const VkAttachmentReference*	pColorAttachments;
		DE_NULL,							//  const VkAttachmentReference*	pResolveAttachments;
		DE_NULL,							//  const VkAttachmentReference*	pDepthStencilAttachment;
		0,									//  deUint32						preserveAttachmentCount;
		DE_NULL								//  const deUint32*					pPreserveAttachments;
	};
	subpassDescriptions.push_back(description);

	const VkSubpassDependency	dependency	=
	{
		0u,													//  deUint32				srcSubpass;
		0u,													//  deUint32				dstSubpass;
		VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT,		//  VkPipelineStageFlags	srcStageMask;
		VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,				//  VkPipelineStageFlags	dstStageMask;
		VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT,	//  VkAccessFlags			srcAccessMask;
		VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT,	//  VkAccessFlags			dstAccessMask;
		0u													//  VkDependencyFlags		dependencyFlags;
	};
	subpassDependencies.push_back(dependency);

	const VkRenderPassCreateInfo renderPassInfo =
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,							//  VkStructureType					sType;
		DE_NULL,															//  const void*						pNext;
		static_cast<VkRenderPassCreateFlags>(0u),							//  VkRenderPassCreateFlags			flags;
		0u,																	//  deUint32						attachmentCount;
		DE_NULL,															//  const VkAttachmentDescription*	pAttachments;
		static_cast<deUint32>(subpassDescriptions.size()),					//  deUint32						subpassCount;
		&subpassDescriptions[0],											//  const VkSubpassDescription*		pSubpasses;
		static_cast<deUint32>(subpassDependencies.size()),					//  deUint32						dependencyCount;
		subpassDependencies.size() > 0 ? &subpassDependencies[0] : DE_NULL	//  const VkSubpassDependency*		pDependencies;
	};

	return createRenderPass(vk, device, &renderPassInfo);
}

VkImageMemoryBarrier makeImageMemoryBarrier	(const VkAccessFlags			srcAccessMask,
											 const VkAccessFlags			dstAccessMask,
											 const VkImageLayout			oldLayout,
											 const VkImageLayout			newLayout,
											 const VkImage					image,
											 const VkImageSubresourceRange	subresourceRange)
{
	const VkImageMemoryBarrier barrier =
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
		DE_NULL,										// const void*				pNext;
		srcAccessMask,									// VkAccessFlags			outputMask;
		dstAccessMask,									// VkAccessFlags			inputMask;
		oldLayout,										// VkImageLayout			oldLayout;
		newLayout,										// VkImageLayout			newLayout;
		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,						// deUint32					destQueueFamilyIndex;
		image,											// VkImage					image;
		subresourceRange,								// VkImageSubresourceRange	subresourceRange;
	};
	return barrier;
}

VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags	srcAccessMask,
											   const VkAccessFlags	dstAccessMask,
											   const VkBuffer		buffer,
											   const VkDeviceSize	offset,
											   const VkDeviceSize	bufferSizeBytes)
{
	const VkBufferMemoryBarrier barrier =
	{
		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	//  VkStructureType	sType;
		DE_NULL,									//  const void*		pNext;
		srcAccessMask,								//  VkAccessFlags	srcAccessMask;
		dstAccessMask,								//  VkAccessFlags	dstAccessMask;
		VK_QUEUE_FAMILY_IGNORED,					//  deUint32		srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					//  deUint32		destQueueFamilyIndex;
		buffer,										//  VkBuffer		buffer;
		offset,										//  VkDeviceSize	offset;
		bufferSizeBytes,							//  VkDeviceSize	size;
	};
	return barrier;
}

VkMemoryBarrier makeMemoryBarrier (const VkAccessFlags	srcAccessMask,
								   const VkAccessFlags	dstAccessMask)
{
	const VkMemoryBarrier barrier =
	{
		VK_STRUCTURE_TYPE_MEMORY_BARRIER,	// VkStructureType			sType;
		DE_NULL,							// const void*				pNext;
		srcAccessMask,						// VkAccessFlags			outputMask;
		dstAccessMask,						// VkAccessFlags			inputMask;
	};
	return barrier;
}

VkQueryPoolCreateInfo makeQueryPoolCreateInfo (const deUint32 queryCountersNumber)
{
	const VkQueryPoolCreateInfo			queryPoolCreateInfo		=
	{
		VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,		//  VkStructureType					sType;
		DE_NULL,										//  const void*						pNext;
		(VkQueryPoolCreateFlags)0,						//  VkQueryPoolCreateFlags			flags;
		VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT,	//  VkQueryType						queryType;
		queryCountersNumber,							//  deUint32						queryCount;
		0u,												//  VkQueryPipelineStatisticFlags	pipelineStatistics;
	};

	return queryPoolCreateInfo;
}

void fillBuffer (const DeviceInterface& vk, const VkDevice device, Allocation& bufferAlloc, VkDeviceSize bufferSize, const void* data, const VkDeviceSize dataSize)
{
	const VkMappedMemoryRange	memRange		=
	{
		VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,	//  VkStructureType	sType;
		DE_NULL,								//  const void*		pNext;
		bufferAlloc.getMemory(),				//  VkDeviceMemory	memory;
		bufferAlloc.getOffset(),				//  VkDeviceSize	offset;
		VK_WHOLE_SIZE							//  VkDeviceSize	size;
	};
	std::vector<deUint8>		dataVec			(static_cast<deUint32>(bufferSize), 0u);

	DE_ASSERT(bufferSize >= dataSize);

	deMemcpy(&dataVec[0], data, static_cast<deUint32>(dataSize));

	deMemcpy(bufferAlloc.getHostPtr(), &dataVec[0], dataVec.size());
	VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &memRange));
}

class TransformFeedbackTestInstance : public TestInstance
{
public:
													TransformFeedbackTestInstance	(Context& context, const TestParameters& parameters);
protected:
	void											validateLimits					();
	std::vector<VkDeviceSize>						generateSizesList				(const size_t bufBytes, const size_t chunkCount);
	std::vector<VkDeviceSize>						generateOffsetsList				(const std::vector<VkDeviceSize>& sizesList);
	void											verifyTransformFeedbackBuffer	(const MovePtr<Allocation>& bufAlloc,
																					 const deUint32 bufBytes);

	const bool										m_extensions;
	const VkExtent2D								m_imageExtent2D;
	const TestParameters							m_parameters;
	VkPhysicalDeviceTransformFeedbackPropertiesEXT	m_transformFeedbackProperties;
	de::Random										m_rnd;
};

TransformFeedbackTestInstance::TransformFeedbackTestInstance (Context& context, const TestParameters& parameters)
	: TestInstance		(context)
	, m_extensions		(context.requireDeviceFunctionality("VK_EXT_transform_feedback"))
	, m_imageExtent2D	(makeExtent2D(IMAGE_SIZE, IMAGE_SIZE))
	, m_parameters		(parameters)
	, m_rnd				(0)
{
	const VkPhysicalDeviceTransformFeedbackFeaturesEXT&		transformFeedbackFeatures	= m_context.getTransformFeedbackFeaturesEXT();
	VkPhysicalDeviceProperties2								deviceProperties2;

	if (transformFeedbackFeatures.transformFeedback == DE_FALSE)
		TCU_THROW(NotSupportedError, "transformFeedback feature is not supported");

	deMemset(&deviceProperties2, 0, sizeof(deviceProperties2));
	deMemset(&m_transformFeedbackProperties, 0, sizeof(m_transformFeedbackProperties));

	deviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
	deviceProperties2.pNext = &m_transformFeedbackProperties;

	m_transformFeedbackProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT;
	m_transformFeedbackProperties.pNext = DE_NULL;

	context.getInstanceInterface().getPhysicalDeviceProperties2(context.getPhysicalDevice(), &deviceProperties2);

	validateLimits();
}

void TransformFeedbackTestInstance::validateLimits ()
{
	VALIDATE_MINIMUM(m_transformFeedbackProperties.maxTransformFeedbackBuffers, 1);
	VALIDATE_MINIMUM(m_transformFeedbackProperties.maxTransformFeedbackBufferSize, MINIMUM_TF_BUFFER_SIZE);
	VALIDATE_MINIMUM(m_transformFeedbackProperties.maxTransformFeedbackStreamDataSize, 512);
	VALIDATE_MINIMUM(m_transformFeedbackProperties.maxTransformFeedbackBufferDataSize, 512);
	VALIDATE_MINIMUM(m_transformFeedbackProperties.maxTransformFeedbackBufferDataStride, 512);

	VALIDATE_BOOL(m_transformFeedbackProperties.transformFeedbackQueries);
	VALIDATE_BOOL(m_transformFeedbackProperties.transformFeedbackStreamsLinesTriangles);
	VALIDATE_BOOL(m_transformFeedbackProperties.transformFeedbackRasterizationStreamSelect);
	VALIDATE_BOOL(m_transformFeedbackProperties.transformFeedbackDraw);
}

std::vector<VkDeviceSize> TransformFeedbackTestInstance::generateSizesList (const size_t bufBytes, const size_t chunkCount)
{
	const int					minChunkSlot	= static_cast<int>(1);
	const int					maxChunkSlot	= static_cast<int>(bufBytes / sizeof(deUint32));
	int							prevOffsetSlot	= 0;
	std::map<int, bool>			offsetsSet;
	std::vector<VkDeviceSize>	result;

	DE_ASSERT(bufBytes <= MINIMUM_TF_BUFFER_SIZE);
	DE_ASSERT(bufBytes % sizeof(deUint32) == 0);
	DE_ASSERT(minChunkSlot <= maxChunkSlot);
	DE_ASSERT(chunkCount > 0);
	// To be effective this algorithm requires that chunkCount is much less than amount of chunks possible
	DE_ASSERT(8 * chunkCount <= static_cast<size_t>(maxChunkSlot));

	offsetsSet[0] = true;

	// Create a list of unique offsets first
	for (size_t chunkNdx = 1; chunkNdx < chunkCount; ++chunkNdx)
	{
		int chunkSlot;

		do
		{
			chunkSlot = m_rnd.getInt(minChunkSlot, maxChunkSlot - 1);
		} while (offsetsSet.find(chunkSlot) != offsetsSet.end());

		offsetsSet[chunkSlot] = true;
	}
	offsetsSet[maxChunkSlot] = true;

	// Calculate sizes of offsets list
	result.reserve(chunkCount);
	for (std::map<int, bool>::iterator mapIt = offsetsSet.begin(); mapIt != offsetsSet.end(); ++mapIt)
	{
		const int offsetSlot = mapIt->first;

		if (offsetSlot == 0)
			continue;

		DE_ASSERT(prevOffsetSlot < offsetSlot && offsetSlot > 0);

		result.push_back(static_cast<VkDeviceSize>(static_cast<size_t>(offsetSlot - prevOffsetSlot) * sizeof(deUint32)));

		prevOffsetSlot = offsetSlot;
	}

	DE_ASSERT(result.size() == chunkCount);

	return result;
}

std::vector<VkDeviceSize> TransformFeedbackTestInstance::generateOffsetsList (const std::vector<VkDeviceSize>& sizesList)
{
	VkDeviceSize				offset	= 0ull;
	std::vector<VkDeviceSize>	result;

	result.reserve(sizesList.size());

	for (size_t chunkNdx = 0; chunkNdx < sizesList.size(); ++chunkNdx)
	{
		result.push_back(offset);

		offset += sizesList[chunkNdx];
	}

	DE_ASSERT(sizesList.size() == result.size());

	return result;
}

void TransformFeedbackTestInstance::verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc,
																   const deUint32 bufBytes)
{
	const DeviceInterface&	vk			= m_context.getDeviceInterface();
	const VkDevice			device		= m_context.getDevice();

	invalidateAlloc(vk, device, *bufAlloc);

	const deUint32			numPoints	= static_cast<deUint32>(bufBytes / sizeof(deUint32));
	const deUint32*			tfData		= (deUint32*)bufAlloc->getHostPtr();

	for (deUint32 i = 0; i < numPoints; ++i)
		if (tfData[i] != i)
			TCU_FAIL(std::string("Failed at item ") + de::toString(i) + " received:" + de::toString(tfData[i]) + " expected:" + de::toString(i));
}

class TransformFeedbackBasicTestInstance : public TransformFeedbackTestInstance
{
public:
						TransformFeedbackBasicTestInstance	(Context& context, const TestParameters& parameters);

protected:
	tcu::TestStatus		iterate								(void);
};

TransformFeedbackBasicTestInstance::TransformFeedbackBasicTestInstance (Context& context, const TestParameters& parameters)
	: TransformFeedbackTestInstance	(context, parameters)
{
}

tcu::TestStatus TransformFeedbackBasicTestInstance::iterate (void)
{
	const DeviceInterface&				vk						= m_context.getDeviceInterface();
	const VkDevice						device					= m_context.getDevice();
	const deUint32						queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
	const VkQueue						queue					= m_context.getUniversalQueue();
	Allocator&							allocator				= m_context.getDefaultAllocator();

	const Unique<VkShaderModule>		vertexModule			(createShaderModule						(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
	const Unique<VkRenderPass>			renderPass				(makeRenderPass							(vk, device, VK_FORMAT_UNDEFINED));
	const Unique<VkFramebuffer>			framebuffer				(makeFramebuffer						(vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
	const Unique<VkPipelineLayout>		pipelineLayout			(TransformFeedback::makePipelineLayout	(vk, device));
	const Unique<VkPipeline>			pipeline				(makeGraphicsPipeline					(vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
	const Unique<VkCommandPool>			cmdPool					(createCommandPool						(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>		cmdBuffer				(allocateCommandBuffer					(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	const VkBufferCreateInfo			tfBufCreateInfo			= makeBufferCreateInfo(m_parameters.bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
	const Move<VkBuffer>				tfBuf					= createBuffer(vk, device, &tfBufCreateInfo);
	const MovePtr<Allocation>			tfBufAllocation			= allocator.allocate(getBufferMemoryRequirements(vk, device, *tfBuf), MemoryRequirement::HostVisible);
	const VkMemoryBarrier				tfMemoryBarrier			= makeMemoryBarrier(VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, VK_ACCESS_HOST_READ_BIT);
	const std::vector<VkDeviceSize>		tfBufBindingSizes		= generateSizesList(m_parameters.bufferSize, m_parameters.partCount);
	const std::vector<VkDeviceSize>		tfBufBindingOffsets		= generateOffsetsList(tfBufBindingSizes);

	VK_CHECK(vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset()));

	beginCommandBuffer(vk, *cmdBuffer);
	{
		beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D));
		{
			vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);

			for (deUint32 drawNdx = 0; drawNdx < m_parameters.partCount; ++drawNdx)
			{
				const deUint32	startValue	= static_cast<deUint32>(tfBufBindingOffsets[drawNdx] / sizeof(deUint32));
				const deUint32	numPoints	= static_cast<deUint32>(tfBufBindingSizes[drawNdx] / sizeof(deUint32));

				vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0, 1, &*tfBuf, &tfBufBindingOffsets[drawNdx], &tfBufBindingSizes[drawNdx]);

				vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0u, sizeof(startValue), &startValue);

				vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
				{
					vk.cmdDraw(*cmdBuffer, numPoints, 1u, 0u, 0u);
				}
				vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
			}
		}
		endRenderPass(vk, *cmdBuffer);

		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &tfMemoryBarrier, 0u, DE_NULL, 0u, DE_NULL);
	}
	endCommandBuffer(vk, *cmdBuffer);
	submitCommandsAndWait(vk, device, queue, *cmdBuffer);

	verifyTransformFeedbackBuffer(tfBufAllocation, m_parameters.bufferSize);

	return tcu::TestStatus::pass("Pass");
}

class TransformFeedbackResumeTestInstance : public TransformFeedbackTestInstance
{
public:
						TransformFeedbackResumeTestInstance	(Context& context, const TestParameters& parameters);

protected:
	tcu::TestStatus		iterate								(void);
};

TransformFeedbackResumeTestInstance::TransformFeedbackResumeTestInstance (Context& context, const TestParameters& parameters)
	: TransformFeedbackTestInstance	(context, parameters)
{
}

tcu::TestStatus TransformFeedbackResumeTestInstance::iterate (void)
{
	const DeviceInterface&					vk						= m_context.getDeviceInterface();
	const VkDevice							device					= m_context.getDevice();
	const deUint32							queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
	const VkQueue							queue					= m_context.getUniversalQueue();
	Allocator&								allocator				= m_context.getDefaultAllocator();

	const Unique<VkShaderModule>			vertexModule			(createShaderModule						(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
	const Unique<VkRenderPass>				renderPass				(makeRenderPass							(vk, device, VK_FORMAT_UNDEFINED));
	const Unique<VkFramebuffer>				framebuffer				(makeFramebuffer						(vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
	const Unique<VkPipelineLayout>			pipelineLayout			(TransformFeedback::makePipelineLayout	(vk, device));
	const Unique<VkPipeline>				pipeline				(makeGraphicsPipeline					(vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, DE_NULL, DE_NULL, m_imageExtent2D, 0u));

	const Unique<VkCommandPool>				cmdPool					(createCommandPool						(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>			cmdBuffer				(allocateCommandBuffer					(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	const VkBufferCreateInfo				tfBufCreateInfo			= makeBufferCreateInfo(m_parameters.bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
	const Move<VkBuffer>					tfBuf					= createBuffer(vk, device, &tfBufCreateInfo);
	const MovePtr<Allocation>				tfBufAllocation			= allocator.allocate(getBufferMemoryRequirements(vk, device, *tfBuf), MemoryRequirement::HostVisible);
	const VkMemoryBarrier					tfMemoryBarrier			= makeMemoryBarrier(VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, VK_ACCESS_HOST_READ_BIT);
	const std::vector<VkDeviceSize>			tfBufBindingSizes		= std::vector<VkDeviceSize>(1, m_parameters.bufferSize);
	const std::vector<VkDeviceSize>			tfBufBindingOffsets		= std::vector<VkDeviceSize>(1, 0ull);

	const size_t							tfcBufSize				= 16 * sizeof(deUint32) * m_parameters.partCount;
	const VkBufferCreateInfo				tfcBufCreateInfo		= makeBufferCreateInfo(tfcBufSize, VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT);
	const Move<VkBuffer>					tfcBuf					= createBuffer(vk, device, &tfcBufCreateInfo);
	const MovePtr<Allocation>				tfcBufAllocation		= allocator.allocate(getBufferMemoryRequirements(vk, device, *tfcBuf), MemoryRequirement::Any);
	const std::vector<VkDeviceSize>			tfcBufBindingOffsets	= generateOffsetsList(generateSizesList(tfcBufSize, m_parameters.partCount));
	const VkBufferMemoryBarrier				tfcBufBarrier			= makeBufferMemoryBarrier(VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT, VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT, *tfcBuf, 0ull, VK_WHOLE_SIZE);

	const std::vector<VkDeviceSize>			chunkSizesList			= generateSizesList(m_parameters.bufferSize, m_parameters.partCount);
	const std::vector<VkDeviceSize>			chunkOffsetsList		= generateOffsetsList(chunkSizesList);

	DE_ASSERT(tfBufBindingSizes.size() == 1);
	DE_ASSERT(tfBufBindingOffsets.size() == 1);

	VK_CHECK(vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset()));
	VK_CHECK(vk.bindBufferMemory(device, *tfcBuf, tfcBufAllocation->getMemory(), tfcBufAllocation->getOffset()));

	beginCommandBuffer(vk, *cmdBuffer);
	{
		for (size_t drawNdx = 0; drawNdx < m_parameters.partCount; ++drawNdx)
		{
			const deUint32	startValue = static_cast<deUint32>(chunkOffsetsList[drawNdx] / sizeof(deUint32));
			const deUint32	numPoints = static_cast<deUint32>(chunkSizesList[drawNdx] / sizeof(deUint32));
			const deUint32	countBuffersCount = (drawNdx == 0) ? 0 : 1;

			beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D));
			{

				vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);

				vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0, 1, &*tfBuf, &tfBufBindingOffsets[0], &tfBufBindingSizes[0]);

				vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0u, sizeof(startValue), &startValue);

				vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, countBuffersCount, (drawNdx == 0) ? DE_NULL : &*tfcBuf, (drawNdx == 0) ? DE_NULL : &tfcBufBindingOffsets[drawNdx - 1]);
				{
					vk.cmdDraw(*cmdBuffer, numPoints, 1u, 0u, 0u);
				}
				vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 1, &*tfcBuf, &tfcBufBindingOffsets[drawNdx]);
			}
			endRenderPass(vk, *cmdBuffer);

			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, 0u, 0u, DE_NULL, 1u, &tfcBufBarrier, 0u, DE_NULL);
		}

		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &tfMemoryBarrier, 0u, DE_NULL, 0u, DE_NULL);
	}
	endCommandBuffer(vk, *cmdBuffer);
	submitCommandsAndWait(vk, device, queue, *cmdBuffer);

	verifyTransformFeedbackBuffer(tfBufAllocation, m_parameters.bufferSize);

	return tcu::TestStatus::pass("Pass");
}

class TransformFeedbackWindingOrderTestInstance : public TransformFeedbackTestInstance
{
public:
	TransformFeedbackWindingOrderTestInstance(Context& context, const TestParameters& parameters);

protected:
	struct TopologyParameters
	{
		VkPrimitiveTopology topology;

		// number of vertex in primitive; 2 for line, 3 for triangle
		deUint32 vertexPerPrimitive;

		// pointer to function calculating number of points that
		// will be generated for given part count
		std::function<deUint32(deUint32)> getNumGeneratedPoints;

		// pointer to function generating expected values; parameter is
		// primitive index, result array with expected data for primitive vertex
		std::function<std::vector<deUint32>(deUint32)> getExpectedValuesForPrimitive;
	};
	typedef const std::map<TestType, TopologyParameters> TopologyParametersMap;

protected:
	const TopologyParametersMap&	getTopologyParametersMap					(void);
	tcu::TestStatus					iterate										(void);
	void							verifyTransformFeedbackBuffer				(const MovePtr<Allocation>& bufAlloc,
																				 const deUint32 bufBytes);

private:
	TopologyParameters				m_tParameters;
	const bool						m_requiresTesselationStage;
};

TransformFeedbackWindingOrderTestInstance::TransformFeedbackWindingOrderTestInstance(Context& context, const TestParameters& parameters)
	: TransformFeedbackTestInstance	(context, parameters)
	, m_requiresTesselationStage(parameters.testType == TEST_TYPE_PATCH_LIST)
{
	if (m_requiresTesselationStage && !context.getDeviceFeatures().tessellationShader)
		throw tcu::NotSupportedError("Tessellation shader not supported");

	TopologyParametersMap topologyParametersMap = getTopologyParametersMap();
	DE_ASSERT(topologyParametersMap.find(parameters.testType) != topologyParametersMap.end());
	m_tParameters = topologyParametersMap.at(parameters.testType);
}

const TransformFeedbackWindingOrderTestInstance::TopologyParametersMap& TransformFeedbackWindingOrderTestInstance::getTopologyParametersMap(void)
{
	static const TopologyParametersMap topologyParametersMap =
	{
		{
			TEST_TYPE_LINE_LIST,
			{
				VK_PRIMITIVE_TOPOLOGY_LINE_LIST,
				2u,
				[](deUint32 partCount)	{	return partCount;	},
				[](deUint32 i)			{	return std::vector<deUint32>{ 2 * i, 2 * i + 1u };	}
			}
		},
		{
			TEST_TYPE_LINE_STRIP,
			{
				VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
				2u,
				[](deUint32 partCount)	{	return 2u * (partCount - 1);	},
				[](deUint32 i)			{	return std::vector<deUint32>{ i, i + 1u };	}
			}
		},
		{
			TEST_TYPE_TRIANGLE_LIST,
			{
				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
				3u,
				[](deUint32 partCount)	{	return partCount;	},
				[](deUint32 i)			{	return std::vector<deUint32>{ 3 * i, 3 * i + 1u, 3 * i + 2u };	}
			}
		},
		{
			TEST_TYPE_TRIANGLE_STRIP,
			{
				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
				3u,
				[](deUint32 partCount)	{	return 3u * (partCount - 2);	},
				[](deUint32 i)
				{
					const deUint32	iMod2 = i % 2;
					return std::vector<deUint32>{ i, i + 1 + iMod2, i + 2 - iMod2 };
				}
			}
		},
		{
			TEST_TYPE_TRIANGLE_FAN,
			{
				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,
				3u,
				[](deUint32 partCount)	{	return partCount;	},
				[](deUint32 i)			{	return std::vector<deUint32>{ i + 1, i + 2, 0 };	}
			}
		},
		{
			TEST_TYPE_LINE_LIST_ADJACENCY,
			{
				VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY,
				2u,
				[](deUint32 partCount)	{	return partCount / 4u;	},		// note: this cant be replaced with partCount / 2 as for partCount=6 we will get 3 instead of 2
				[](deUint32 i)			{	return std::vector<deUint32>{ i + 1u, i + 2u };	}
			}
		},
		{
			TEST_TYPE_LINE_STRIP_ADJACENCY,
			{
				VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY,
				2u,
				[](deUint32 partCount)	{	return 2u * (partCount - 3u);	},
				[](deUint32 i)			{	return std::vector<deUint32>{ i + 1u, i + 2u };	}
			}
		},
		{
			TEST_TYPE_TRIANGLE_LIST_ADJACENCY,
			{
				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY,
				3u,
				[](deUint32 partCount)	{	return partCount / 2u;	},
				[](deUint32 i)			{	return std::vector<deUint32>{ 6 * i, 6 * i + 2u, 6 * i + 4u	};	}
			}
		},
		{
			TEST_TYPE_TRIANGLE_STRIP_ADJACENCY,
			{
				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY,
				3u,
				[](deUint32 partCount)	{	return 3u * (partCount / 2u - 2u);	},
				[](deUint32 i)
				{
					const bool even = (0 == i % 2);
					if (even)
						return std::vector<deUint32>{ 2 * i + 0, 2 * i + 2, 2 * i + 4 };
					return std::vector<deUint32>{ 2 * i + 0, 2 * i + 4, 2 * i + 2 };
				}
			}
		},
		{
			TEST_TYPE_PATCH_LIST,
			{
				VK_PRIMITIVE_TOPOLOGY_PATCH_LIST,
				9u,
				[](deUint32 partCount)	{	return partCount * 3u;	},
				[](deUint32 i)
				{
					// we cant generate vertex numbers in tesselation evaluation shader;
					// check if patch index is correct for every 9 generated vertex
					return std::vector<deUint32>(9, i);
				}
			}
		}
	};

	return topologyParametersMap;
}

tcu::TestStatus TransformFeedbackWindingOrderTestInstance::iterate (void)
{
	DE_ASSERT(m_parameters.partCount >= 6);

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

	const Move<VkShaderModule>		vertexModule(createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
	Move<VkShaderModule>			tescModule;
	Move<VkShaderModule>			teseModule;
	if (m_requiresTesselationStage)
	{
		tescModule = createShaderModule(vk, device, m_context.getBinaryCollection().get("tesc"), 0u);
		teseModule = createShaderModule(vk, device, m_context.getBinaryCollection().get("tese"), 0u);
	}

	const Unique<VkRenderPass>		renderPass			(makeRenderPass							(vk, device, VK_FORMAT_UNDEFINED));
	const Unique<VkFramebuffer>		framebuffer			(makeFramebuffer						(vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
	const Unique<VkPipelineLayout>	pipelineLayout		(TransformFeedback::makePipelineLayout	(vk, device));
	const Unique<VkPipeline>		pipeline			(makeGraphicsPipeline					(vk, device, *pipelineLayout, *renderPass,
																								 *vertexModule,
																								 m_requiresTesselationStage ? *tescModule : DE_NULL,
																								 m_requiresTesselationStage ? *teseModule : DE_NULL,
																								 DE_NULL,
																								 DE_NULL,
																								 m_imageExtent2D, 0u, DE_NULL, m_tParameters.topology));
	const Unique<VkCommandPool>		cmdPool				(createCommandPool						(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>	cmdBuffer			(allocateCommandBuffer					(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
	const VkDeviceSize				bufferSize			= m_tParameters.getNumGeneratedPoints	(m_parameters.partCount) * sizeof(deUint32);
	const VkBufferCreateInfo		tfBufCreateInfo		= makeBufferCreateInfo					(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
	const Move<VkBuffer>			tfBuf				= createBuffer							(vk, device, &tfBufCreateInfo);
	const MovePtr<Allocation>		tfBufAllocation		= allocator.allocate					(getBufferMemoryRequirements(vk, device, *tfBuf), MemoryRequirement::HostVisible);
	const VkMemoryBarrier			tfMemoryBarrier		= makeMemoryBarrier						(VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, VK_ACCESS_HOST_READ_BIT);
	const VkDeviceSize				tfBufBindingSize	= bufferSize;
	const VkDeviceSize				tfBufBindingOffset	= 0u;
	const deUint32					startValue			= 0u;

	VK_CHECK(vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset()));

	beginCommandBuffer(vk, *cmdBuffer);
	{
		beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D));
		{
			vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);

			vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0, 1, &*tfBuf, &tfBufBindingOffset, &tfBufBindingSize);

			vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0u, sizeof(startValue), &startValue);

			vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
			{
				vk.cmdDraw(*cmdBuffer, m_parameters.partCount, 1u, 0u, 0u);
			}
			vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
		}
		endRenderPass(vk, *cmdBuffer);

		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &tfMemoryBarrier, 0u, DE_NULL, 0u, DE_NULL);
	}
	endCommandBuffer(vk, *cmdBuffer);
	submitCommandsAndWait(vk, device, queue, *cmdBuffer);

	verifyTransformFeedbackBuffer(tfBufAllocation, static_cast<deUint32>(bufferSize));

	return tcu::TestStatus::pass("Pass");
}

void TransformFeedbackWindingOrderTestInstance::verifyTransformFeedbackBuffer(const MovePtr<Allocation>& bufAlloc,
																			  const deUint32 bufBytes)
{
	const DeviceInterface&	vk		= m_context.getDeviceInterface();
	const VkDevice			device	= m_context.getDevice();

	invalidateAlloc(vk, device, *bufAlloc);

	const deUint32	numPoints			= static_cast<deUint32>(bufBytes / sizeof(deUint32));
	const deUint32	vertexPerPrimitive	= m_tParameters.vertexPerPrimitive;
	const deUint32	numPrimitives		= numPoints / vertexPerPrimitive;
	const deUint32*	tfData				= (deUint32*)bufAlloc->getHostPtr();

	for (deUint32 primitiveIndex = 0; primitiveIndex < numPrimitives; ++primitiveIndex)
	{
		const deUint32*			tfDataForPrimitive			= &tfData[primitiveIndex * vertexPerPrimitive];
		std::vector<deUint32>	expectedDataForPrimitive	= m_tParameters.getExpectedValuesForPrimitive(primitiveIndex);

		// For multi - vertex primitives, all values for a given vertex are written before writing values for any other vertex.
		// Implementations may write out any vertex within the primitive first, but all subsequent vertices for that primitive
		// must be written out in a consistent winding order
		bool correctWinding = true;
		for (deUint32 combinationIndex = 0; combinationIndex < vertexPerPrimitive; combinationIndex++)
		{
			correctWinding = true;
			for (deUint32 vertexIndex = 0; vertexIndex < vertexPerPrimitive; vertexIndex++)
			{
				correctWinding &= (tfDataForPrimitive[vertexIndex] == expectedDataForPrimitive[(combinationIndex + vertexIndex) % vertexPerPrimitive]);

				// if data for this vertex is not correct then there
				// is no need to check other, go to next combination
				if (!correctWinding)
					break;
			}

			// no need to check other combinations, we found correct one
			if (correctWinding)
				break;
		}

		if (!correctWinding)
		{
			std::stringstream message;
			message << "Failed at primitive " << primitiveIndex << " received: [";
			for (deUint32 vertexIndex = 0; vertexIndex < vertexPerPrimitive; vertexIndex++)
				message << de::toString(tfDataForPrimitive[vertexIndex]) << " ";
			message << "] expected: [";
			for (deUint32 vertexIndex = 0; vertexIndex < vertexPerPrimitive; vertexIndex++)
				message << de::toString(expectedDataForPrimitive[vertexIndex]) << " ";
			message << "]";
			TCU_FAIL(message.str());
		}
	}
}

class TransformFeedbackBuiltinTestInstance : public TransformFeedbackTestInstance
{
public:
						TransformFeedbackBuiltinTestInstance	(Context& context, const TestParameters& parameters);

protected:
	tcu::TestStatus		iterate									(void);
	void				verifyTransformFeedbackBuffer			(const MovePtr<Allocation>& bufAlloc, const VkDeviceSize offset, const deUint32 bufBytes);
};

TransformFeedbackBuiltinTestInstance::TransformFeedbackBuiltinTestInstance (Context& context, const TestParameters& parameters)
	: TransformFeedbackTestInstance	(context, parameters)
{
	const InstanceInterface&		vki			= m_context.getInstanceInterface();
	const VkPhysicalDevice			physDevice	= m_context.getPhysicalDevice();
	const VkPhysicalDeviceFeatures	features	= getPhysicalDeviceFeatures(vki, physDevice);

	const deUint32 tfBuffersSupported	= m_transformFeedbackProperties.maxTransformFeedbackBuffers;
	const deUint32 tfBuffersRequired	= m_parameters.partCount;

	if ((m_parameters.testType == TEST_TYPE_XFB_CLIPDISTANCE || m_parameters.testType == TEST_TYPE_XFB_CLIP_AND_CULL) && !features.shaderClipDistance)
		TCU_THROW(NotSupportedError, std::string("shaderClipDistance feature is not supported"));
	if ((m_parameters.testType == TEST_TYPE_XFB_CULLDISTANCE || m_parameters.testType == TEST_TYPE_XFB_CLIP_AND_CULL) && !features.shaderCullDistance)
		TCU_THROW(NotSupportedError, std::string("shaderCullDistance feature is not supported"));
	if (tfBuffersSupported < tfBuffersRequired)
		TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackBuffers=" + de::toString(tfBuffersSupported) + ", while test requires " + de::toString(tfBuffersRequired)).c_str());
}

void TransformFeedbackBuiltinTestInstance::verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc, const VkDeviceSize offset, const deUint32 bufBytes)
{
	const DeviceInterface&	vk			= m_context.getDeviceInterface();
	const VkDevice			device		= m_context.getDevice();

	invalidateAlloc(vk, device, *bufAlloc);

	const deUint32			numPoints	= bufBytes / static_cast<deUint32>(sizeof(float));
	const deUint8*			tfDataBytes	= (deUint8*)bufAlloc->getHostPtr();
	const float*			tfData		= (float*)&tfDataBytes[offset];

	for (deUint32 i = 0; i < numPoints; ++i)
	{
		const deUint32	divisor		= 32768u;
		const float		epsilon		= 1.0f / float(divisor);
		const float		expected	= float(i) / float(divisor);

		if (deAbs(tfData[i] - expected) > epsilon)
			TCU_FAIL(std::string("Failed at item ") + de::toString(i) + " received:" + de::toString(tfData[i]) + " expected:" + de::toString(expected));
	}
}

tcu::TestStatus TransformFeedbackBuiltinTestInstance::iterate (void)
{
	const DeviceInterface&				vk						= m_context.getDeviceInterface();
	const VkDevice						device					= m_context.getDevice();
	const deUint32						queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
	const VkQueue						queue					= m_context.getUniversalQueue();
	Allocator&							allocator				= m_context.getDefaultAllocator();

	const Unique<VkShaderModule>		vertexModule			(createShaderModule						(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
	const Unique<VkRenderPass>			renderPass				(makeRenderPass							(vk, device, VK_FORMAT_UNDEFINED));
	const Unique<VkFramebuffer>			framebuffer				(makeFramebuffer						(vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
	const Unique<VkPipelineLayout>		pipelineLayout			(TransformFeedback::makePipelineLayout	(vk, device));
	const Unique<VkPipeline>			pipeline				(makeGraphicsPipeline					(vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
	const Unique<VkCommandPool>			cmdPool					(createCommandPool						(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>		cmdBuffer				(allocateCommandBuffer					(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	const VkDeviceSize					tfBufSize				= m_parameters.bufferSize * m_parameters.partCount;
	const VkBufferCreateInfo			tfBufCreateInfo			= makeBufferCreateInfo(tfBufSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
	const Move<VkBuffer>				tfBuf					= createBuffer(vk, device, &tfBufCreateInfo);
	const std::vector<VkBuffer>			tfBufArray				= std::vector<VkBuffer>(m_parameters.partCount, *tfBuf);
	const MovePtr<Allocation>			tfBufAllocation			= allocator.allocate(getBufferMemoryRequirements(vk, device, *tfBuf), MemoryRequirement::HostVisible);
	const VkMemoryBarrier				tfMemoryBarrier			= makeMemoryBarrier(VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, VK_ACCESS_HOST_READ_BIT);
	const std::vector<VkDeviceSize>		tfBufBindingSizes		= std::vector<VkDeviceSize>(m_parameters.partCount, m_parameters.bufferSize);
	const std::vector<VkDeviceSize>		tfBufBindingOffsets		= generateOffsetsList(tfBufBindingSizes);
	const deUint32						perVertexDataSize		= (m_parameters.testType == TEST_TYPE_XFB_POINTSIZE)    ? static_cast<deUint32>(sizeof(float))
																: (m_parameters.testType == TEST_TYPE_XFB_CLIPDISTANCE) ? static_cast<deUint32>(8u * sizeof(float))
																: (m_parameters.testType == TEST_TYPE_XFB_CULLDISTANCE) ? static_cast<deUint32>(8u * sizeof(float))
																: (m_parameters.testType == TEST_TYPE_XFB_CLIP_AND_CULL) ? static_cast<deUint32>(6u * sizeof(float))
																: 0u;
	const deUint32						numPoints				= m_parameters.bufferSize / perVertexDataSize;

	VK_CHECK(vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset()));

	beginCommandBuffer(vk, *cmdBuffer);
	{
		beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D));
		{
			vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);

			vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0, m_parameters.partCount, &tfBufArray[0], &tfBufBindingOffsets[0], &tfBufBindingSizes[0]);

			vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
			{
				vk.cmdDraw(*cmdBuffer, numPoints, 1u, 0u, 0u);
			}
			vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
		}
		endRenderPass(vk, *cmdBuffer);

		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &tfMemoryBarrier, 0u, DE_NULL, 0u, DE_NULL);
	}
	endCommandBuffer(vk, *cmdBuffer);
	submitCommandsAndWait(vk, device, queue, *cmdBuffer);

	verifyTransformFeedbackBuffer(tfBufAllocation, tfBufBindingOffsets[m_parameters.partCount - 1], numPoints * perVertexDataSize);

	return tcu::TestStatus::pass("Pass");
}

class TransformFeedbackMultistreamTestInstance : public TransformFeedbackTestInstance
{
public:
								TransformFeedbackMultistreamTestInstance	(Context& context, const TestParameters& parameters);

protected:
	std::vector<VkDeviceSize>	generateSizesList							(const size_t bufBytes, const size_t chunkCount);
	void						verifyTransformFeedbackBuffer				(const MovePtr<Allocation>& bufAlloc, const deUint32 bufBytes);
	tcu::TestStatus				iterate										(void);
};

TransformFeedbackMultistreamTestInstance::TransformFeedbackMultistreamTestInstance (Context& context, const TestParameters& parameters)
	: TransformFeedbackTestInstance	(context, parameters)
{
	const InstanceInterface&								vki							= m_context.getInstanceInterface();
	const VkPhysicalDevice									physDevice					= m_context.getPhysicalDevice();
	const VkPhysicalDeviceFeatures							features					= getPhysicalDeviceFeatures(vki, physDevice);
	const VkPhysicalDeviceTransformFeedbackFeaturesEXT&		transformFeedbackFeatures	= m_context.getTransformFeedbackFeaturesEXT();
	const deUint32											streamsSupported			= m_transformFeedbackProperties.maxTransformFeedbackStreams;
	const deUint32											streamsRequired				= m_parameters.streamId + 1;
	const deUint32											tfBuffersSupported			= m_transformFeedbackProperties.maxTransformFeedbackBuffers;
	const deUint32											tfBuffersRequired			= m_parameters.partCount;
	const deUint32											bytesPerVertex				= m_parameters.bufferSize / m_parameters.partCount;
	const deUint32											tfStreamDataSizeSupported	= m_transformFeedbackProperties.maxTransformFeedbackStreamDataSize;
	const deUint32											tfBufferDataSizeSupported	= m_transformFeedbackProperties.maxTransformFeedbackBufferDataSize;
	const deUint32											tfBufferDataStrideSupported	= m_transformFeedbackProperties.maxTransformFeedbackBufferDataStride;

	DE_ASSERT(m_parameters.partCount == 2u);

	if (!features.geometryShader)
		TCU_THROW(NotSupportedError, "Missing feature: geometryShader");

	if (transformFeedbackFeatures.geometryStreams == DE_FALSE)
		TCU_THROW(NotSupportedError, "geometryStreams feature is not supported");

	if (streamsSupported < streamsRequired)
		TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackStreams=" + de::toString(streamsSupported) + ", while test requires " + de::toString(streamsRequired)).c_str());

	if (tfBuffersSupported < tfBuffersRequired)
		TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackBuffers=" + de::toString(tfBuffersSupported) + ", while test requires " + de::toString(tfBuffersRequired)).c_str());

	if (tfStreamDataSizeSupported < bytesPerVertex)
		TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackStreamDataSize=" + de::toString(tfStreamDataSizeSupported) + ", while test requires " + de::toString(bytesPerVertex)).c_str());

	if (tfBufferDataSizeSupported < bytesPerVertex)
		TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackBufferDataSize=" + de::toString(tfBufferDataSizeSupported) + ", while test requires " + de::toString(bytesPerVertex)).c_str());

	if (tfBufferDataStrideSupported < bytesPerVertex)
		TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackBufferDataStride=" + de::toString(tfBufferDataStrideSupported) + ", while test requires " + de::toString(bytesPerVertex)).c_str());
}

std::vector<VkDeviceSize> TransformFeedbackMultistreamTestInstance::generateSizesList (const size_t bufBytes, const size_t chunkCount)
{
	const VkDeviceSize			chunkSize	= bufBytes / chunkCount;
	std::vector<VkDeviceSize>	result		(chunkCount, chunkSize);

	DE_ASSERT(chunkSize * chunkCount == bufBytes);
	DE_ASSERT(bufBytes <= MINIMUM_TF_BUFFER_SIZE);
	DE_ASSERT(bufBytes % sizeof(deUint32) == 0);
	DE_ASSERT(chunkCount > 0);
	DE_ASSERT(result.size() == chunkCount);

	return result;
}

void TransformFeedbackMultistreamTestInstance::verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc, const deUint32 bufBytes)
{
	const DeviceInterface&	vk			= m_context.getDeviceInterface();
	const VkDevice			device		= m_context.getDevice();

	invalidateAlloc(vk, device, *bufAlloc);

	const deUint32			numPoints	= static_cast<deUint32>(bufBytes / sizeof(deUint32));
	const float*			tfData		= (float*)bufAlloc->getHostPtr();

	for (deUint32 i = 0; i < numPoints; ++i)
		if (tfData[i] != float(i))
			TCU_FAIL(std::string("Failed at item ") + de::toString(float(i)) + " received:" + de::toString(tfData[i]) + " expected:" + de::toString(i));
}

tcu::TestStatus TransformFeedbackMultistreamTestInstance::iterate (void)
{
	const DeviceInterface&				vk						= m_context.getDeviceInterface();
	const VkDevice						device					= m_context.getDevice();
	const deUint32						queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
	const VkQueue						queue					= m_context.getUniversalQueue();
	Allocator&							allocator				= m_context.getDefaultAllocator();

	const Unique<VkRenderPass>			renderPass				(makeRenderPass							(vk, device, VK_FORMAT_UNDEFINED));

	const Unique<VkShaderModule>		vertexModule			(createShaderModule						(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
	const Unique<VkShaderModule>		geomModule				(createShaderModule						(vk, device, m_context.getBinaryCollection().get("geom"), 0u));

	const Unique<VkFramebuffer>			framebuffer				(makeFramebuffer						(vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
	const Unique<VkPipelineLayout>		pipelineLayout			(TransformFeedback::makePipelineLayout	(vk, device));
	const Unique<VkPipeline>			pipeline				(makeGraphicsPipeline					(vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, *geomModule, DE_NULL, m_imageExtent2D, 0u));
	const Unique<VkCommandPool>			cmdPool					(createCommandPool						(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>		cmdBuffer				(allocateCommandBuffer					(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	const VkBufferCreateInfo			tfBufCreateInfo			= makeBufferCreateInfo(m_parameters.bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
	const Move<VkBuffer>				tfBuf					= createBuffer(vk, device, &tfBufCreateInfo);
	const std::vector<VkBuffer>			tfBufArray				= std::vector<VkBuffer>(m_parameters.partCount, *tfBuf);
	const MovePtr<Allocation>			tfBufAllocation			= allocator.allocate(getBufferMemoryRequirements(vk, device, *tfBuf), MemoryRequirement::HostVisible);
	const VkMemoryBarrier				tfMemoryBarrier			= makeMemoryBarrier(VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, VK_ACCESS_HOST_READ_BIT);
	const std::vector<VkDeviceSize>		tfBufBindingSizes		= generateSizesList(m_parameters.bufferSize, m_parameters.partCount);
	const std::vector<VkDeviceSize>		tfBufBindingOffsets		= generateOffsetsList(tfBufBindingSizes);

	VK_CHECK(vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset()));

	beginCommandBuffer(vk, *cmdBuffer);
	{
		beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D));
		{
			vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);

			vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0u, m_parameters.partCount, &tfBufArray[0], &tfBufBindingOffsets[0], &tfBufBindingSizes[0]);

			vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
			{
				vk.cmdDraw(*cmdBuffer, 1u, 1u, 0u, 0u);
			}
			vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
		}
		endRenderPass(vk, *cmdBuffer);

		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &tfMemoryBarrier, 0u, DE_NULL, 0u, DE_NULL);
	}
	endCommandBuffer(vk, *cmdBuffer);
	submitCommandsAndWait(vk, device, queue, *cmdBuffer);

	verifyTransformFeedbackBuffer(tfBufAllocation, m_parameters.bufferSize);

	return tcu::TestStatus::pass("Pass");
}

class TransformFeedbackStreamsTestInstance : public TransformFeedbackTestInstance
{
public:
						TransformFeedbackStreamsTestInstance	(Context& context, const TestParameters& parameters);

protected:
	tcu::TestStatus		iterate									(void);
	bool				verifyImage								(const VkFormat imageFormat, const VkExtent2D& size, const void* resultData);
};

TransformFeedbackStreamsTestInstance::TransformFeedbackStreamsTestInstance (Context& context, const TestParameters& parameters)
	: TransformFeedbackTestInstance	(context, parameters)
{
	const InstanceInterface&								vki							= m_context.getInstanceInterface();
	const VkPhysicalDevice									physDevice					= m_context.getPhysicalDevice();
	const VkPhysicalDeviceFeatures							features					= getPhysicalDeviceFeatures(vki, physDevice);
	const VkPhysicalDeviceTransformFeedbackFeaturesEXT&		transformFeedbackFeatures	= m_context.getTransformFeedbackFeaturesEXT();
	const deUint32											streamsSupported			= m_transformFeedbackProperties.maxTransformFeedbackStreams;
	const deUint32											streamsRequired				= m_parameters.streamId + 1;
	const bool												geomPointSizeRequired		= m_parameters.testType == TEST_TYPE_STREAMS_POINTSIZE;

	if (!features.geometryShader)
		TCU_THROW(NotSupportedError, "Missing feature: geometryShader");

	if (transformFeedbackFeatures.geometryStreams == DE_FALSE)
		TCU_THROW(NotSupportedError, "geometryStreams feature is not supported");

	if (m_transformFeedbackProperties.transformFeedbackRasterizationStreamSelect == DE_FALSE)
		TCU_THROW(NotSupportedError, "transformFeedbackRasterizationStreamSelect feature is not supported");

	if (streamsSupported < streamsRequired)
		TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackStreams=" + de::toString(streamsSupported) + ", while test requires " + de::toString(streamsRequired)).c_str());

	if (geomPointSizeRequired && !features.shaderTessellationAndGeometryPointSize)
		TCU_THROW(NotSupportedError, "shaderTessellationAndGeometryPointSize feature is not supported");
}

bool TransformFeedbackStreamsTestInstance::verifyImage (const VkFormat imageFormat, const VkExtent2D& size, const void* resultData)
{
	const tcu::RGBA				magentaRGBA		(tcu::RGBA(0xFF, 0x00, 0xFF, 0xFF));
	const tcu::Vec4				magenta			(magentaRGBA.toVec());
	const tcu::Vec4				black			(tcu::RGBA::black().toVec());
	const tcu::TextureFormat	textureFormat	(mapVkFormat(imageFormat));
	const int					dataSize		(size.width * size.height * textureFormat.getPixelSize());
	tcu::TextureLevel			referenceImage	(textureFormat, size.width, size.height);
	tcu::PixelBufferAccess		referenceAccess	(referenceImage.getAccess());

	// Generate reference image
	if (m_parameters.testType == TEST_TYPE_STREAMS)
	{
		for (int y = 0; y < referenceImage.getHeight(); ++y)
		{
			const tcu::Vec4&	validColor = y < referenceImage.getHeight() / 2 ? black : magenta;

			for (int x = 0; x < referenceImage.getWidth(); ++x)
				referenceAccess.setPixel(validColor, x, y);
		}
	}

	if (m_parameters.testType == TEST_TYPE_STREAMS_CLIPDISTANCE || m_parameters.testType == TEST_TYPE_STREAMS_CULLDISTANCE)
	{
		for (int y = 0; y < referenceImage.getHeight(); ++y)
			for (int x = 0; x < referenceImage.getWidth(); ++x)
			{
				const tcu::Vec4&	validColor	= (y >= referenceImage.getHeight() / 2) && (x >= referenceImage.getWidth() / 2) ? magenta : black;

				referenceAccess.setPixel(validColor, x, y);
			}
	}

	if (m_parameters.testType == TEST_TYPE_STREAMS_POINTSIZE)
	{
		const int			pointSize	= static_cast<int>(m_parameters.pointSize);
		const tcu::Vec4&	validColor	= black;

		for (int y = 0; y < referenceImage.getHeight(); ++y)
			for (int x = 0; x < referenceImage.getWidth(); ++x)
				referenceAccess.setPixel(validColor, x, y);

		referenceAccess.setPixel(magenta, (1 + referenceImage.getWidth()) / 4 - 1, (referenceImage.getHeight() * 3) / 4 - 1);

		for (int y = 0; y < pointSize; ++y)
			for (int x = 0; x < pointSize; ++x)
				referenceAccess.setPixel(magenta, x + (referenceImage.getWidth() * 3) / 4 - 1, y + (referenceImage.getHeight() * 3) / 4 - 1);
	}

	if (deMemCmp(resultData, referenceAccess.getDataPtr(), dataSize) != 0)
	{
		const tcu::ConstPixelBufferAccess	resultImage	(textureFormat, size.width, size.height, 1, resultData);
		bool								ok;

		ok = tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Image comparison", "", referenceAccess, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT);

		return ok;
	}

	return true;
}

tcu::TestStatus TransformFeedbackStreamsTestInstance::iterate (void)
{
	const DeviceInterface&				vk					= m_context.getDeviceInterface();
	const VkDevice						device				= m_context.getDevice();
	const deUint32						queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
	const VkQueue						queue				= m_context.getUniversalQueue();
	Allocator&							allocator			= m_context.getDefaultAllocator();

	const Unique<VkRenderPass>			renderPass			(makeRenderPass			(vk, device, VK_FORMAT_R8G8B8A8_UNORM));

	const Unique<VkShaderModule>		vertModule			(createShaderModule		(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
	const Unique<VkShaderModule>		geomModule			(createShaderModule		(vk, device, m_context.getBinaryCollection().get("geom"), 0u));
	const Unique<VkShaderModule>		fragModule			(createShaderModule		(vk, device, m_context.getBinaryCollection().get("frag"), 0u));

	const VkFormat						colorFormat			= VK_FORMAT_R8G8B8A8_UNORM;
	const VkImageUsageFlags				imageUsageFlags		= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
	const tcu::RGBA						clearColor			(tcu::RGBA::black());
	const VkImageSubresourceRange		colorSubresRange	(makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
	const VkDeviceSize					colorBufferSize		(m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat)));
	const Unique<VkImage>				colorImage			(makeImage								(vk, device, makeImageCreateInfo(0u, VK_IMAGE_TYPE_2D, colorFormat, m_imageExtent2D, 1u, imageUsageFlags)));
	const UniquePtr<Allocation>			colorImageAlloc		(bindImage								(vk, device, allocator, *colorImage, MemoryRequirement::Any));
	const Unique<VkImageView>			colorAttachment		(makeImageView							(vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
	const Unique<VkBuffer>				colorBuffer			(makeBuffer								(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
	const UniquePtr<Allocation>			colorBufferAlloc	(bindBuffer								(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));

	const Unique<VkFramebuffer>			framebuffer			(makeFramebuffer						(vk, device, *renderPass, *colorAttachment, m_imageExtent2D.width, m_imageExtent2D.height));
	const Unique<VkPipelineLayout>		pipelineLayout		(TransformFeedback::makePipelineLayout	(vk, device));
	const Unique<VkPipeline>			pipeline			(makeGraphicsPipeline					(vk, device, *pipelineLayout, *renderPass, *vertModule, DE_NULL, DE_NULL, *geomModule, *fragModule, m_imageExtent2D, 0u, &m_parameters.streamId));
	const Unique<VkCommandPool>			cmdPool				(createCommandPool						(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>		cmdBuffer			(allocateCommandBuffer					(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	const VkImageMemoryBarrier			preCopyBarrier		= makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
																					 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
																					 *colorImage, colorSubresRange);
	const VkBufferImageCopy				region				= makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
																				  makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
	const VkBufferMemoryBarrier			postCopyBarrier		= makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, VK_WHOLE_SIZE);

	beginCommandBuffer(vk, *cmdBuffer);
	{
		beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor.toVec());
		{
			vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);

			vk.cmdDraw(*cmdBuffer, 2u, 1u, 0u, 0u);
		}
		endRenderPass(vk, *cmdBuffer);

		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
		vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, &region);
		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);

		invalidateAlloc(vk, device, *colorBufferAlloc);
	}
	endCommandBuffer(vk, *cmdBuffer);
	submitCommandsAndWait(vk, device, queue, *cmdBuffer);

	if (!verifyImage(colorFormat, m_imageExtent2D, colorBufferAlloc->getHostPtr()))
		return tcu::TestStatus::fail("Fail");

	return tcu::TestStatus::pass("Pass");
}

class TransformFeedbackIndirectDrawTestInstance : public TransformFeedbackTestInstance
{
public:
						TransformFeedbackIndirectDrawTestInstance	(Context& context, const TestParameters& parameters);

protected:
	tcu::TestStatus		iterate										(void);
	bool				verifyImage									(const VkFormat imageFormat, const VkExtent2D& size, const void* resultData);
};

TransformFeedbackIndirectDrawTestInstance::TransformFeedbackIndirectDrawTestInstance (Context& context, const TestParameters& parameters)
	: TransformFeedbackTestInstance	(context, parameters)
{
	const InstanceInterface&		vki							= m_context.getInstanceInterface();
	const VkPhysicalDevice			physDevice					= m_context.getPhysicalDevice();
	const VkPhysicalDeviceLimits	limits						= getPhysicalDeviceProperties(vki, physDevice).limits;
	const deUint32					tfBufferDataSizeSupported	= m_transformFeedbackProperties.maxTransformFeedbackBufferDataSize;
	const deUint32					tfBufferDataStrideSupported	= m_transformFeedbackProperties.maxTransformFeedbackBufferDataStride;

	if (m_transformFeedbackProperties.transformFeedbackDraw == DE_FALSE)
		TCU_THROW(NotSupportedError, "transformFeedbackDraw feature is not supported");

	if (limits.maxVertexInputBindingStride < m_parameters.vertexStride)
		TCU_THROW(NotSupportedError, std::string("maxVertexInputBindingStride=" + de::toString(limits.maxVertexInputBindingStride) + ", while test requires " + de::toString(m_parameters.vertexStride)).c_str());

	if (tfBufferDataSizeSupported < m_parameters.vertexStride)
		TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackBufferDataSize=" + de::toString(tfBufferDataSizeSupported) + ", while test requires " + de::toString(m_parameters.vertexStride)).c_str());

	if (tfBufferDataStrideSupported < m_parameters.vertexStride)
		TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackBufferDataStride=" + de::toString(tfBufferDataStrideSupported) + ", while test requires " + de::toString(m_parameters.vertexStride)).c_str());
}

bool TransformFeedbackIndirectDrawTestInstance::verifyImage (const VkFormat imageFormat, const VkExtent2D& size, const void* resultData)
{
	const tcu::Vec4				white			(tcu::RGBA::white().toVec());
	const tcu::TextureFormat	textureFormat	(mapVkFormat(imageFormat));
	const int					dataSize		(size.width * size.height * textureFormat.getPixelSize());
	tcu::TextureLevel			referenceImage	(textureFormat, size.width, size.height);
	tcu::PixelBufferAccess		referenceAccess	(referenceImage.getAccess());

	// Generate reference image
	for (int y = 0; y < referenceImage.getHeight(); ++y)
		for (int x = 0; x < referenceImage.getWidth(); ++x)
			referenceAccess.setPixel(white, x, y);

	if (deMemCmp(resultData, referenceAccess.getDataPtr(), dataSize) != 0)
	{
		const tcu::ConstPixelBufferAccess	resultImage	(textureFormat, size.width, size.height, 1, resultData);
		bool								ok;

		ok = tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Image comparison", "", referenceAccess, resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT);

		return ok;
	}

	return true;
}

tcu::TestStatus TransformFeedbackIndirectDrawTestInstance::iterate (void)
{
	const DeviceInterface&				vk					= m_context.getDeviceInterface();
	const VkDevice						device				= m_context.getDevice();
	const deUint32						queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
	const VkQueue						queue				= m_context.getUniversalQueue();
	Allocator&							allocator			= m_context.getDefaultAllocator();

	const Unique<VkRenderPass>			renderPass			(makeRenderPass			(vk, device, VK_FORMAT_R8G8B8A8_UNORM));

	const Unique<VkShaderModule>		vertModule			(createShaderModule		(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
	const Unique<VkShaderModule>		fragModule			(createShaderModule		(vk, device, m_context.getBinaryCollection().get("frag"), 0u));

	const VkFormat						colorFormat			= VK_FORMAT_R8G8B8A8_UNORM;
	const VkImageUsageFlags				imageUsageFlags		= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
	const tcu::RGBA						clearColor			(tcu::RGBA::black());
	const VkImageSubresourceRange		colorSubresRange	(makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
	const VkDeviceSize					colorBufferSize		(m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat)));
	const Unique<VkImage>				colorImage			(makeImage				(vk, device, makeImageCreateInfo(0u, VK_IMAGE_TYPE_2D, colorFormat, m_imageExtent2D, 1u, imageUsageFlags)));
	const UniquePtr<Allocation>			colorImageAlloc		(bindImage				(vk, device, allocator, *colorImage, MemoryRequirement::Any));
	const Unique<VkImageView>			colorAttachment		(makeImageView			(vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
	const Unique<VkBuffer>				colorBuffer			(makeBuffer				(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
	const UniquePtr<Allocation>			colorBufferAlloc	(bindBuffer				(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));

	const deUint32						vertexCount			= 6u;
	const VkDeviceSize					vertexBufferSize	= vertexCount * m_parameters.vertexStride;
	const VkBufferUsageFlags			vertexBufferUsage	= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
	const Unique<VkBuffer>				vertexBuffer		(makeBuffer				(vk, device, vertexBufferSize, vertexBufferUsage));
	const UniquePtr<Allocation>			vertexBufferAlloc	(bindBuffer				(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
	const VkDeviceSize					vertexBufferOffset	(0u);
	const float							vertexBufferVals[]	=
																{
																	-1.0f, -1.0f, 0.0f, 1.0f,
																	-1.0f, +1.0f, 0.0f, 1.0f,
																	+1.0f, -1.0f, 0.0f, 1.0f,
																	-1.0f, +1.0f, 0.0f, 1.0f,
																	+1.0f, -1.0f, 0.0f, 1.0f,
																	+1.0f, +1.0f, 0.0f, 1.0f,
																};

	const deUint32						counterBufferValue	= m_parameters.vertexStride * vertexCount;
	const VkDeviceSize					counterBufferSize	= sizeof(counterBufferValue);
	const VkBufferUsageFlags			counterBufferUsage	= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
	const Unique<VkBuffer>				counterBuffer		(makeBuffer								(vk, device, counterBufferSize, counterBufferUsage));
	const UniquePtr<Allocation>			counterBufferAlloc	(bindBuffer								(vk, device, allocator, *counterBuffer, MemoryRequirement::HostVisible));

	const Unique<VkFramebuffer>			framebuffer			(makeFramebuffer						(vk, device, *renderPass, *colorAttachment, m_imageExtent2D.width, m_imageExtent2D.height));
	const Unique<VkPipelineLayout>		pipelineLayout		(TransformFeedback::makePipelineLayout	(vk, device));
	const Unique<VkPipeline>			pipeline			(makeGraphicsPipeline					(vk, device, *pipelineLayout, *renderPass, *vertModule, DE_NULL, DE_NULL, DE_NULL, *fragModule, m_imageExtent2D, 0u, DE_NULL, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, true));
	const Unique<VkCommandPool>			cmdPool				(createCommandPool						(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>		cmdBuffer			(allocateCommandBuffer					(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	const VkImageMemoryBarrier			preCopyBarrier		= makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
																					 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
																					 *colorImage, colorSubresRange);
	const VkBufferImageCopy				region				= makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
																				  makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
	const VkBufferMemoryBarrier			postCopyBarrier		= makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, VK_WHOLE_SIZE);

	fillBuffer(vk, device, *counterBufferAlloc, counterBufferSize, &counterBufferValue, counterBufferSize);
	fillBuffer(vk, device, *vertexBufferAlloc, vertexBufferSize, vertexBufferVals, sizeof(vertexBufferVals));

	beginCommandBuffer(vk, *cmdBuffer);
	{
		beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor.toVec());
		{
			vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);

			vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);

			vk.cmdDrawIndirectByteCountEXT(*cmdBuffer, 1u, 0u, *counterBuffer, 0u, 0u, m_parameters.vertexStride);
		}
		endRenderPass(vk, *cmdBuffer);

		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
		vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, &region);
		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);

		invalidateAlloc(vk, device, *colorBufferAlloc);
	}
	endCommandBuffer(vk, *cmdBuffer);
	submitCommandsAndWait(vk, device, queue, *cmdBuffer);

	if (!verifyImage(colorFormat, m_imageExtent2D, colorBufferAlloc->getHostPtr()))
		return tcu::TestStatus::fail("Fail");

	return tcu::TestStatus::pass("Pass");
}

class TransformFeedbackBackwardDependencyTestInstance : public TransformFeedbackTestInstance
{
public:
								TransformFeedbackBackwardDependencyTestInstance	(Context& context, const TestParameters& parameters);

protected:
	tcu::TestStatus				iterate											(void);
	std::vector<VkDeviceSize>	generateSizesList								(const size_t bufBytes, const size_t chunkCount);
};

TransformFeedbackBackwardDependencyTestInstance::TransformFeedbackBackwardDependencyTestInstance (Context& context, const TestParameters& parameters)
	: TransformFeedbackTestInstance	(context, parameters)
{
	if (m_transformFeedbackProperties.transformFeedbackDraw == DE_FALSE)
		TCU_THROW(NotSupportedError, "transformFeedbackDraw feature is not supported");
}

std::vector<VkDeviceSize> TransformFeedbackBackwardDependencyTestInstance::generateSizesList (const size_t bufBytes, const size_t chunkCount)
{
	const VkDeviceSize			chunkSize	= bufBytes / chunkCount;
	std::vector<VkDeviceSize>	result		(chunkCount, chunkSize);

	DE_ASSERT(chunkSize * chunkCount == bufBytes);
	DE_ASSERT(bufBytes <= MINIMUM_TF_BUFFER_SIZE);
	DE_ASSERT(bufBytes % sizeof(deUint32) == 0);
	DE_ASSERT(chunkCount > 0);
	DE_ASSERT(result.size() == chunkCount);

	return result;
}

tcu::TestStatus TransformFeedbackBackwardDependencyTestInstance::iterate (void)
{
	const DeviceInterface&				vk					= m_context.getDeviceInterface();
	const VkDevice						device				= m_context.getDevice();
	const deUint32						queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
	const VkQueue						queue				= m_context.getUniversalQueue();
	Allocator&							allocator			= m_context.getDefaultAllocator();

	const Unique<VkShaderModule>		vertexModule		(createShaderModule						(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
	const Unique<VkRenderPass>			renderPass			(TransformFeedback::makeRenderPass		(vk, device));
	const Unique<VkFramebuffer>			framebuffer			(makeFramebuffer						(vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
	const Unique<VkPipelineLayout>		pipelineLayout		(TransformFeedback::makePipelineLayout	(vk, device));
	const Unique<VkPipeline>			pipeline			(makeGraphicsPipeline					(vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
	const Unique<VkCommandPool>			cmdPool				(createCommandPool						(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>		cmdBuffer			(allocateCommandBuffer					(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	const VkBufferCreateInfo			tfBufCreateInfo		= makeBufferCreateInfo(m_parameters.bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
	const Move<VkBuffer>				tfBuf				= createBuffer(vk, device, &tfBufCreateInfo);
	const MovePtr<Allocation>			tfBufAllocation		= allocator.allocate(getBufferMemoryRequirements(vk, device, *tfBuf), MemoryRequirement::HostVisible);
	const VkMemoryBarrier				tfMemoryBarrier		= makeMemoryBarrier(VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, VK_ACCESS_HOST_READ_BIT);
	const VkDeviceSize					tfBufBindingSize	= m_parameters.bufferSize;
	const VkDeviceSize					tfBufBindingOffset	= 0ull;

	const size_t						tfcBufSize			= sizeof(deUint32);
	const VkBufferCreateInfo			tfcBufCreateInfo	= makeBufferCreateInfo(tfcBufSize, VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
	const Move<VkBuffer>				tfcBuf				= createBuffer(vk, device, &tfcBufCreateInfo);
	const MovePtr<Allocation>			tfcBufAllocation	= allocator.allocate(getBufferMemoryRequirements(vk, device, *tfcBuf), MemoryRequirement::Any);
	const VkDeviceSize					tfcBufBindingOffset	= 0ull;
	const VkMemoryBarrier				tfcMemoryBarrier	= makeMemoryBarrier(VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT, VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT);

	const std::vector<VkDeviceSize>		chunkSizesList		= generateSizesList(m_parameters.bufferSize, m_parameters.partCount);
	const std::vector<VkDeviceSize>		chunkOffsetsList	= generateOffsetsList(chunkSizesList);

	VK_CHECK(vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset()));
	VK_CHECK(vk.bindBufferMemory(device, *tfcBuf, tfcBufAllocation->getMemory(), tfcBufAllocation->getOffset()));

	DE_ASSERT(m_parameters.partCount == 2u);

	beginCommandBuffer(vk, *cmdBuffer);
	{
		beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D));
		{
			vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);

			vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0, 1, &*tfBuf, &tfBufBindingOffset, &tfBufBindingSize);

			{
				const deUint32	startValue	= static_cast<deUint32>(chunkOffsetsList[0] / sizeof(deUint32));
				const deUint32	numPoints	= static_cast<deUint32>(chunkSizesList[0] / sizeof(deUint32));

				vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0u, sizeof(startValue), &startValue);

				vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
				{
					vk.cmdDraw(*cmdBuffer, numPoints, 1u, 0u, 0u);
				}
				vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 1, &*tfcBuf, m_parameters.noOffsetArray ? DE_NULL : &tfcBufBindingOffset);
			}

			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, 0u, 1u, &tfcMemoryBarrier, 0u, DE_NULL, DE_NULL, 0u);

			{
				const deUint32	startValue	= static_cast<deUint32>(chunkOffsetsList[1] / sizeof(deUint32));

				vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0u, sizeof(startValue), &startValue);

				vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 1, &*tfcBuf, m_parameters.noOffsetArray ? DE_NULL : &tfcBufBindingOffset);
				{
					vk.cmdDrawIndirectByteCountEXT(*cmdBuffer, 1u, 0u, *tfcBuf, 0u, 0u, 4u);
				}
				vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
			}

		}
		endRenderPass(vk, *cmdBuffer);

		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &tfMemoryBarrier, 0u, DE_NULL, 0u, DE_NULL);
	}
	endCommandBuffer(vk, *cmdBuffer);
	submitCommandsAndWait(vk, device, queue, *cmdBuffer);

	verifyTransformFeedbackBuffer(tfBufAllocation, m_parameters.bufferSize);

	return tcu::TestStatus::pass("Pass");
}


class TransformFeedbackQueryTestInstance : public TransformFeedbackTestInstance
{
public:
						TransformFeedbackQueryTestInstance	(Context& context, const TestParameters& parameters);

protected:
	tcu::TestStatus		iterate								(void);
};

TransformFeedbackQueryTestInstance::TransformFeedbackQueryTestInstance (Context& context, const TestParameters& parameters)
	: TransformFeedbackTestInstance	(context, parameters)
{
	const InstanceInterface&								vki							= m_context.getInstanceInterface();
	const VkPhysicalDevice									physDevice					= m_context.getPhysicalDevice();
	const VkPhysicalDeviceFeatures							features					= getPhysicalDeviceFeatures(vki, physDevice);
	const VkPhysicalDeviceTransformFeedbackFeaturesEXT&		transformFeedbackFeatures	= m_context.getTransformFeedbackFeaturesEXT();
	const deUint32											streamsSupported			= m_transformFeedbackProperties.maxTransformFeedbackStreams;
	const deUint32											streamsRequired				= m_parameters.streamId + 1;

	if (!features.geometryShader)
		TCU_THROW(NotSupportedError, "Missing feature: geometryShader");

	if (streamsRequired > 1 && transformFeedbackFeatures.geometryStreams == DE_FALSE)
		TCU_THROW(NotSupportedError, "geometryStreams feature is not supported");

	if (streamsSupported < streamsRequired)
		TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackStreams=" + de::toString(streamsSupported) + ", while test requires " + de::toString(streamsRequired)).c_str());

	if (m_transformFeedbackProperties.transformFeedbackQueries == DE_FALSE)
		TCU_THROW(NotSupportedError, "transformFeedbackQueries feature is not supported");

	if (m_parameters.testType == TEST_TYPE_QUERY_RESET)
	{
		// Check VK_EXT_host_query_reset is supported
		m_context.requireDeviceFunctionality("VK_EXT_host_query_reset");
		if(m_context.getHostQueryResetFeatures().hostQueryReset == VK_FALSE)
			throw tcu::NotSupportedError(std::string("Implementation doesn't support resetting queries from the host").c_str());
	}
}

tcu::TestStatus TransformFeedbackQueryTestInstance::iterate (void)
{
	const DeviceInterface&				vk						= m_context.getDeviceInterface();
	const VkDevice						device					= m_context.getDevice();
	const deUint32						queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
	const VkQueue						queue					= m_context.getUniversalQueue();
	Allocator&							allocator				= m_context.getDefaultAllocator();

	const deUint32						overflowVertices		= 3u;
	const deUint32						bytesPerVertex			= static_cast<deUint32>(4 * sizeof(float));
	const deUint64						numVerticesInBuffer		= m_parameters.bufferSize / bytesPerVertex;
	const deUint64						numVerticesToWrite		= numVerticesInBuffer + overflowVertices;
	const Unique<VkRenderPass>			renderPass				(makeRenderPass							(vk, device, VK_FORMAT_UNDEFINED));

	const Unique<VkShaderModule>		vertModule				(createShaderModule						(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
	const Unique<VkShaderModule>		geomModule				(createShaderModule						(vk, device, m_context.getBinaryCollection().get("geom"), 0u));

	const Unique<VkFramebuffer>			framebuffer				(makeFramebuffer						(vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
	const Unique<VkPipelineLayout>		pipelineLayout			(TransformFeedback::makePipelineLayout	(vk, device));
	const Unique<VkPipeline>			pipeline				(makeGraphicsPipeline					(vk, device, *pipelineLayout, *renderPass, *vertModule, DE_NULL, DE_NULL, *geomModule, DE_NULL, m_imageExtent2D, 0u));
	const Unique<VkCommandPool>			cmdPool					(createCommandPool						(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>		cmdBuffer				(allocateCommandBuffer					(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	const VkBufferCreateInfo			tfBufCreateInfo			= makeBufferCreateInfo(m_parameters.bufferSize, VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
	const Move<VkBuffer>				tfBuf					= createBuffer(vk, device, &tfBufCreateInfo);
	const MovePtr<Allocation>			tfBufAllocation			= bindBuffer(vk, device, allocator, *tfBuf, MemoryRequirement::HostVisible);
	const VkDeviceSize					tfBufBindingSize		= m_parameters.bufferSize;
	const VkDeviceSize					tfBufBindingOffset		= 0ull;

	const size_t						queryResultWidth		= (m_parameters.query64bits ? sizeof(deUint64) : sizeof(deUint32));
	const vk::VkQueryControlFlags		queryExtraFlags			= (m_parameters.query64bits ? vk::VK_QUERY_RESULT_64_BIT : 0);
	const deUint32						queryCountersNumber		= 1u;
	const deUint32						queryIndex				= 0u;
	constexpr deUint32					queryResultElements		= 2u;
	const deUint32						queryDataSize			= static_cast<deUint32>(queryResultElements * queryResultWidth);
	const VkQueryPoolCreateInfo			queryPoolCreateInfo		= makeQueryPoolCreateInfo(queryCountersNumber);
	const Unique<VkQueryPool>			queryPool				(createQueryPool(vk, device, &queryPoolCreateInfo));

	Move<VkBuffer>						queryPoolResultsBuffer;
	de::MovePtr<Allocation>				queryPoolResultsBufferAlloc;

	DE_ASSERT(numVerticesInBuffer * bytesPerVertex == m_parameters.bufferSize);

	if (m_parameters.testType == TEST_TYPE_QUERY_COPY)
	{
		const VkBufferCreateInfo bufferParams =
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,       // VkStructureType      sType;
			DE_NULL,                                    // const void*          pNext;
			0u,                                         // VkBufferCreateFlags  flags;
			queryDataSize,                              // VkDeviceSize         size;
			VK_BUFFER_USAGE_TRANSFER_DST_BIT,           // VkBufferUsageFlags   usage;
			VK_SHARING_MODE_EXCLUSIVE,                  // VkSharingMode        sharingMode;
			1u,                                         // deUint32             queueFamilyCount;
			&queueFamilyIndex                           // const deUint32*      pQueueFamilyIndices;
		};

		queryPoolResultsBuffer = createBuffer(vk, device, &bufferParams);
		queryPoolResultsBufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *queryPoolResultsBuffer), MemoryRequirement::HostVisible);

		VK_CHECK(vk.bindBufferMemory(device, *queryPoolResultsBuffer, queryPoolResultsBufferAlloc->getMemory(), queryPoolResultsBufferAlloc->getOffset()));
	}

	beginCommandBuffer(vk, *cmdBuffer);
	{
		if (m_parameters.testType != TEST_TYPE_QUERY_RESET)
			vk.cmdResetQueryPool(*cmdBuffer, *queryPool, queryIndex, queryCountersNumber);

		beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D));
		{
			vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);

			vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0u, 1u, &*tfBuf, &tfBufBindingOffset, &tfBufBindingSize);

			if (m_parameters.streamId == 0 && m_parameters.streamId0Mode != STREAM_ID_0_BEGIN_QUERY_INDEXED)
				vk.cmdBeginQuery(*cmdBuffer, *queryPool, queryIndex, 0u);
			else
				vk.cmdBeginQueryIndexedEXT(*cmdBuffer, *queryPool, queryIndex, 0u, m_parameters.streamId);
			{
				vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
				{
					vk.cmdDraw(*cmdBuffer, static_cast<deUint32>(numVerticesToWrite), 1u, 0u, 0u);
				}
				vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
			}
			if (m_parameters.streamId == 0 && m_parameters.streamId0Mode != STREAM_ID_0_END_QUERY_INDEXED)
				vk.cmdEndQuery(*cmdBuffer, *queryPool, queryIndex);
			else
				vk.cmdEndQueryIndexedEXT(*cmdBuffer, *queryPool, queryIndex, m_parameters.streamId);
		}
		endRenderPass(vk, *cmdBuffer);

		if (m_parameters.testType == TEST_TYPE_QUERY_COPY)
		{
			vk.cmdCopyQueryPoolResults(*cmdBuffer, *queryPool, queryIndex, queryCountersNumber, *queryPoolResultsBuffer, 0u, queryDataSize, (vk::VK_QUERY_RESULT_WAIT_BIT | queryExtraFlags));

			const VkBufferMemoryBarrier bufferBarrier =
			{
				VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
				DE_NULL,									// const void*		pNext;
				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
				VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
				VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
				VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
				*queryPoolResultsBuffer,					// VkBuffer			buffer;
				0ull,										// VkDeviceSize		offset;
				VK_WHOLE_SIZE								// VkDeviceSize		size;
			};
			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
		}

	}
	endCommandBuffer(vk, *cmdBuffer);

	if (m_parameters.testType == TEST_TYPE_QUERY_RESET)
		vk.resetQueryPool(device, *queryPool, queryIndex, queryCountersNumber);
	submitCommandsAndWait(vk, device, queue, *cmdBuffer);

	{
		union Results {
			deUint32	elements32[queryResultElements];
			deUint64	elements64[queryResultElements];
		};

		std::vector<deUint8>	queryData		(queryDataSize, 0u);
		const Results*			queryResults	= reinterpret_cast<Results*>(queryData.data());

		if (m_parameters.testType != TEST_TYPE_QUERY_COPY)
		{
			vk.getQueryPoolResults(device, *queryPool, queryIndex, queryCountersNumber, queryDataSize, queryData.data(), queryDataSize, (vk::VK_QUERY_RESULT_WAIT_BIT | queryExtraFlags));
		}
		else
		{
			invalidateAlloc(vk, device, *queryPoolResultsBufferAlloc);
			deMemcpy(queryData.data(), queryPoolResultsBufferAlloc->getHostPtr(), queryData.size());
		}

		const deUint64	numPrimitivesWritten	= (m_parameters.query64bits ? queryResults->elements64[0] : queryResults->elements32[0]);
		const deUint64	numPrimitivesNeeded		= (m_parameters.query64bits ? queryResults->elements64[1] : queryResults->elements32[1]);

		if (numPrimitivesWritten != numVerticesInBuffer)
			return tcu::TestStatus::fail("numPrimitivesWritten=" + de::toString(numPrimitivesWritten) + " while expected " + de::toString(numVerticesInBuffer));

		if (numPrimitivesNeeded != numVerticesToWrite)
			return tcu::TestStatus::fail("numPrimitivesNeeded=" + de::toString(numPrimitivesNeeded) + " while expected " + de::toString(numVerticesToWrite));
	}

	if (m_parameters.testType == TEST_TYPE_QUERY_RESET)
	{
		constexpr deUint32		queryResetElements		= queryResultElements + 1; // For the availability bit.

		union Results {
			deUint32	elements32[queryResetElements];
			deUint64	elements64[queryResetElements];
		};

		const deUint32			queryDataAvailSize		(static_cast<deUint32>(queryResetElements * queryResultWidth));
		std::vector<deUint8>	queryData				(queryDataAvailSize, 0u);
		Results*				queryResults			= reinterpret_cast<Results*>(queryData.data());

		// Initialize values
		if (m_parameters.query64bits)
		{
			queryResults->elements64[0] = 1u;	// numPrimitivesWritten
			queryResults->elements64[1] = 1u;	// numPrimitivesNeeded
			queryResults->elements64[2] = 1u;	// Availability bit
		}
		else
		{
			queryResults->elements32[0] = 1u;	// numPrimitivesWritten
			queryResults->elements32[1] = 1u;	// numPrimitivesNeeded
			queryResults->elements32[2] = 1u;	// Availability bit
		}

		vk.resetQueryPool(device, *queryPool, queryIndex, queryCountersNumber);

		vk::VkResult	res						= vk.getQueryPoolResults(device, *queryPool, queryIndex, queryCountersNumber, queryDataAvailSize, queryData.data(), queryDataAvailSize, (vk::VK_QUERY_RESULT_WITH_AVAILABILITY_BIT | queryExtraFlags));
		const deUint64	numPrimitivesWritten	= (m_parameters.query64bits ? queryResults->elements64[0] : queryResults->elements32[0]);
		const deUint64	numPrimitivesNeeded		= (m_parameters.query64bits ? queryResults->elements64[1] : queryResults->elements32[1]);
		const deUint64	availabilityState		= (m_parameters.query64bits ? queryResults->elements64[2] : queryResults->elements32[2]);

		/* From the Vulkan spec:
			*
			* If VK_QUERY_RESULT_WAIT_BIT and VK_QUERY_RESULT_PARTIAL_BIT are both not set then no result values are written to pData
			* for queries that are in the unavailable state at the time of the call, and vkGetQueryPoolResults returns VK_NOT_READY.
			* However, availability state is still written to pData for those queries if VK_QUERY_RESULT_WITH_AVAILABILITY_BIT is set.
			*/
		if (res != vk::VK_NOT_READY || availabilityState != 0u)
			return tcu::TestStatus::fail("QueryPoolResults incorrect reset");
	    if (numPrimitivesWritten != 1u || numPrimitivesNeeded != 1u)
			return tcu::TestStatus::fail("QueryPoolResults data was modified");

	}

	return tcu::TestStatus::pass("Pass");
}

class TransformFeedbackMultiQueryTestInstance : public TransformFeedbackTestInstance
{
public:
								TransformFeedbackMultiQueryTestInstance	(Context& context, const TestParameters& parameters);

protected:
	std::vector<VkDeviceSize>	generateSizesList							(const size_t bufBytes, const size_t chunkCount);
	void						verifyTransformFeedbackBuffer				(const MovePtr<Allocation>& bufAlloc, const deUint32 bufBytes, const deUint32 bufOffset, const float expected);
	tcu::TestStatus				iterate										(void);
};

TransformFeedbackMultiQueryTestInstance::TransformFeedbackMultiQueryTestInstance (Context& context, const TestParameters& parameters)
	: TransformFeedbackTestInstance	(context, parameters)
{
	const InstanceInterface&								vki							= m_context.getInstanceInterface();
	const VkPhysicalDevice									physDevice					= m_context.getPhysicalDevice();
	const VkPhysicalDeviceFeatures							features					= getPhysicalDeviceFeatures(vki, physDevice);
	const VkPhysicalDeviceTransformFeedbackFeaturesEXT&		transformFeedbackFeatures	= m_context.getTransformFeedbackFeaturesEXT();
	const deUint32											streamsSupported			= m_transformFeedbackProperties.maxTransformFeedbackStreams;
	const deUint32											streamsRequired				= m_parameters.streamId + 1;
	const deUint32											tfBuffersSupported			= m_transformFeedbackProperties.maxTransformFeedbackBuffers;
	const deUint32											tfBuffersRequired			= m_parameters.partCount;
	const deUint32											bytesPerVertex				= m_parameters.bufferSize / m_parameters.partCount;
	const deUint32											tfStreamDataSizeSupported	= m_transformFeedbackProperties.maxTransformFeedbackStreamDataSize;
	const deUint32											tfBufferDataSizeSupported	= m_transformFeedbackProperties.maxTransformFeedbackBufferDataSize;
	const deUint32											tfBufferDataStrideSupported	= m_transformFeedbackProperties.maxTransformFeedbackBufferDataStride;

	DE_ASSERT(m_parameters.partCount == 2u);

	if (!features.geometryShader)
		TCU_THROW(NotSupportedError, "Missing feature: geometryShader");

	if (transformFeedbackFeatures.geometryStreams == DE_FALSE)
		TCU_THROW(NotSupportedError, "geometryStreams feature is not supported");

	if (streamsSupported < streamsRequired)
		TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackStreams=" + de::toString(streamsSupported) + ", while test requires " + de::toString(streamsRequired)).c_str());

	if (tfBuffersSupported < tfBuffersRequired)
		TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackBuffers=" + de::toString(tfBuffersSupported) + ", while test requires " + de::toString(tfBuffersRequired)).c_str());

	if (tfStreamDataSizeSupported < bytesPerVertex)
		TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackStreamDataSize=" + de::toString(tfStreamDataSizeSupported) + ", while test requires " + de::toString(bytesPerVertex)).c_str());

	if (tfBufferDataSizeSupported < bytesPerVertex)
		TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackBufferDataSize=" + de::toString(tfBufferDataSizeSupported) + ", while test requires " + de::toString(bytesPerVertex)).c_str());

	if (tfBufferDataStrideSupported < bytesPerVertex)
		TCU_THROW(NotSupportedError, std::string("maxTransformFeedbackBufferDataStride=" + de::toString(tfBufferDataStrideSupported) + ", while test requires " + de::toString(bytesPerVertex)).c_str());

	if (m_transformFeedbackProperties.transformFeedbackQueries == DE_FALSE)
		TCU_THROW(NotSupportedError, "transformFeedbackQueries feature is not supported");
}

std::vector<VkDeviceSize> TransformFeedbackMultiQueryTestInstance::generateSizesList (const size_t bufBytes, const size_t chunkCount)
{
	const VkDeviceSize			chunkSize	= bufBytes / chunkCount;
	std::vector<VkDeviceSize>	result		(chunkCount, chunkSize);

	DE_ASSERT(chunkSize * chunkCount == bufBytes);
	DE_ASSERT(bufBytes <= MINIMUM_TF_BUFFER_SIZE);
	DE_ASSERT(bufBytes % sizeof(deUint32) == 0);
	DE_ASSERT(chunkCount > 0);
	DE_ASSERT(result.size() == chunkCount);

	return result;
}

void TransformFeedbackMultiQueryTestInstance::verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc, const deUint32 bufBytes, const deUint32 bufOffset, const float expected)
{
	const DeviceInterface&	vk			= m_context.getDeviceInterface();
	const VkDevice			device		= m_context.getDevice();

	invalidateAlloc(vk, device, *bufAlloc);

	const deUint32			numPoints	= bufBytes / static_cast<deUint32>(sizeof(float));
	const deUint8*			tfDataRaw	= reinterpret_cast<const deUint8*>(bufAlloc->getHostPtr());
	const float*			tfData		= reinterpret_cast<const float*>(&tfDataRaw[bufOffset]);

	for (deUint32 i = 0; i < numPoints; ++i)
		if (tfData[i] != expected)
			TCU_FAIL(std::string("Failed at item ") + de::toString(i) + " received:" + de::toString(tfData[i]) + " expected:" + de::toString(expected));
}

tcu::TestStatus TransformFeedbackMultiQueryTestInstance::iterate (void)
{
	const DeviceInterface&						vk							= m_context.getDeviceInterface();
	const VkDevice								device						= m_context.getDevice();
	const deUint32								queueFamilyIndex			= m_context.getUniversalQueueFamilyIndex();
	const std::vector<deUint32>					queueFamilyIndices			= { queueFamilyIndex };
	const VkQueue								queue						= m_context.getUniversalQueue();
	Allocator&									allocator					= m_context.getDefaultAllocator();

	const Unique<VkRenderPass>					renderPass					(makeRenderPass							(vk, device, VK_FORMAT_UNDEFINED));

	const Unique<VkShaderModule>				vertModule					(createShaderModule						(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
	const Unique<VkShaderModule>				geomModule					(createShaderModule						(vk, device, m_context.getBinaryCollection().get("geom"), 0u));

	const Unique<VkFramebuffer>					framebuffer					(makeFramebuffer						(vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
	const Unique<VkPipelineLayout>				pipelineLayout				(TransformFeedback::makePipelineLayout	(vk, device));
	const Unique<VkPipeline>					pipeline					(makeGraphicsPipeline					(vk, device, *pipelineLayout, *renderPass, *vertModule, DE_NULL, DE_NULL, *geomModule, DE_NULL, m_imageExtent2D, 0u));
	const Unique<VkCommandPool>					cmdPool						(createCommandPool						(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>				cmdBuffer					(allocateCommandBuffer					(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	const VkBufferCreateInfo					tfBufCreateInfo				= makeBufferCreateInfo(m_parameters.bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
	const Move<VkBuffer>						tfBuf						= createBuffer(vk, device, &tfBufCreateInfo);
	const std::vector<VkBuffer>					tfBufArray					= std::vector<VkBuffer>(m_parameters.partCount, *tfBuf);
	const MovePtr<Allocation>					tfBufAllocation				= allocator.allocate(getBufferMemoryRequirements(vk, device, *tfBuf), MemoryRequirement::HostVisible);
	const VkMemoryBarrier						tfMemoryBarrier				= makeMemoryBarrier(VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, VK_ACCESS_HOST_READ_BIT);
	const std::vector<VkDeviceSize>				tfBufBindingSizes			= generateSizesList(m_parameters.bufferSize, m_parameters.partCount);
	const std::vector<VkDeviceSize>				tfBufBindingOffsets			= generateOffsetsList(tfBufBindingSizes);
	const std::vector<float>					tfBufExpectedValues			= { 0.5f, 0.5f + float(m_parameters.streamId) };
	const deUint32								maxBufferSizeBytes			= static_cast<deUint32>(*std::max_element(tfBufBindingSizes.begin(), tfBufBindingSizes.end()));
	const deUint32								bytesPerVertex				= static_cast<deUint32>(4 * sizeof(float));
	const deUint32								numVerticesInBuffer			= maxBufferSizeBytes / bytesPerVertex;
	const deUint32								numDrawVertices				= numVerticesInBuffer / 2;

	const deUint32								queryIndex					= 0u;
	const deUint32								queryCountersNumber			= 2u;
	const deUint32								queryStride					= sizeof(TransformFeedbackQuery);
	const deUint32								queryDataSize				= queryCountersNumber * queryStride;
	const VkQueryPoolCreateInfo					queryPoolCreateInfo			= makeQueryPoolCreateInfo(queryCountersNumber);
	const Unique<VkQueryPool>					queryPool					(createQueryPool(vk, device, &queryPoolCreateInfo));
	const deUint32								queryInvalidCounterValue	= 999999u;
	std::vector<TransformFeedbackQuery>			queryResultData				(queryCountersNumber, TransformFeedbackQuery{ queryInvalidCounterValue, queryInvalidCounterValue });
	const std::vector<TransformFeedbackQuery>	queryExpectedData			({ TransformFeedbackQuery{ numVerticesInBuffer, 3 * numDrawVertices }, TransformFeedbackQuery{ numDrawVertices, numDrawVertices } });

	const VkBufferCreateInfo					queryBufferCreateInfo		= makeBufferCreateInfo(queryDataSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, queueFamilyIndices);
	const Move<VkBuffer>						queryPoolResultsBuffer		= createBuffer(vk, device, &queryBufferCreateInfo);
	const MovePtr<Allocation>					queryPoolResultsBufferAlloc	= allocator.allocate(getBufferMemoryRequirements(vk, device, *queryPoolResultsBuffer), MemoryRequirement::HostVisible);

	DE_ASSERT(queryCountersNumber == queryExpectedData.size());

	VK_CHECK(vk.bindBufferMemory(device, *queryPoolResultsBuffer, queryPoolResultsBufferAlloc->getMemory(), queryPoolResultsBufferAlloc->getOffset()));

	VK_CHECK(vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset()));

	beginCommandBuffer(vk, *cmdBuffer);
	{
		vk.cmdResetQueryPool(*cmdBuffer, *queryPool, queryIndex, queryCountersNumber);

		beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D));
		{
			vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);

			vk.cmdBindTransformFeedbackBuffersEXT(*cmdBuffer, 0u, m_parameters.partCount, &tfBufArray[0], &tfBufBindingOffsets[0], &tfBufBindingSizes[0]);

			vk.cmdBeginQueryIndexedEXT(*cmdBuffer, *queryPool, queryIndex + 0, 0u, 0u);
			vk.cmdBeginQueryIndexedEXT(*cmdBuffer, *queryPool, queryIndex + 1, 0u, m_parameters.streamId);
			{
				vk.cmdBeginTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
				{
					vk.cmdDraw(*cmdBuffer, numDrawVertices, 1u, 0u, 0u);
				}
				vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
			}
			vk.cmdEndQueryIndexedEXT(*cmdBuffer, *queryPool, queryIndex + 1, m_parameters.streamId);
			vk.cmdEndQueryIndexedEXT(*cmdBuffer, *queryPool, queryIndex + 0, 0);
		}
		endRenderPass(vk, *cmdBuffer);

		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &tfMemoryBarrier, 0u, DE_NULL, 0u, DE_NULL);
	}
	endCommandBuffer(vk, *cmdBuffer);
	submitCommandsAndWait(vk, device, queue, *cmdBuffer);

	vk.getQueryPoolResults(device, *queryPool, queryIndex, queryCountersNumber, queryDataSize, queryResultData.data(), queryStride, (vk::VK_QUERY_RESULT_WAIT_BIT));

	DE_ASSERT(queryResultData.size() == queryCountersNumber && queryExpectedData.size() == queryCountersNumber);
	DE_ASSERT(queryCountersNumber > 0);

	for (size_t counterNdx = 0; counterNdx < queryCountersNumber; ++counterNdx)
	{
		const TransformFeedbackQuery&	result		= queryResultData[counterNdx];
		const TransformFeedbackQuery&	expected	= queryExpectedData[counterNdx];

		DE_ASSERT(expected.written != queryInvalidCounterValue);
		DE_ASSERT(expected.attempts != queryInvalidCounterValue);

		if (result.written == queryInvalidCounterValue || result.attempts == queryInvalidCounterValue)
			return tcu::TestStatus::fail("Query counters read failed");

		if (result.written != expected.written)
		{
			const std::string	comment	= "At counter " + de::toString(counterNdx) + " vertices written " + de::toString(result.written) + ", while expected " + de::toString(expected.written);

			return tcu::TestStatus::fail(comment.c_str());
		}


		if (result.attempts != expected.attempts)
		{
			const std::string	comment = "At counter " + de::toString(counterNdx) + " attempts committed " + de::toString(result.attempts) + ", while expected " + de::toString(expected.attempts);

			return tcu::TestStatus::fail(comment.c_str());
		}

		verifyTransformFeedbackBuffer(tfBufAllocation, bytesPerVertex * expected.written, static_cast<deUint32>(tfBufBindingOffsets[counterNdx]), tfBufExpectedValues[counterNdx]);
	}

	return tcu::TestStatus::pass("Pass");
}


class TransformFeedbackTestCase : public vkt::TestCase
{
public:
						TransformFeedbackTestCase	(tcu::TestContext &context, const char *name, const char *description, const TestParameters& parameters);

protected:
	vkt::TestInstance*	createInstance				(vkt::Context& context) const;
	void				initPrograms				(SourceCollections& programCollection) const;

	TestParameters		m_parameters;
};

TransformFeedbackTestCase::TransformFeedbackTestCase (tcu::TestContext &context, const char *name, const char *description, const TestParameters& parameters)
	: TestCase		(context, name, description)
	, m_parameters	(parameters)
{
}

vkt::TestInstance*	TransformFeedbackTestCase::createInstance (vkt::Context& context) const
{
	if (m_parameters.testType == TEST_TYPE_BASIC)
		return new TransformFeedbackBasicTestInstance(context, m_parameters);

	if (m_parameters.testType == TEST_TYPE_RESUME)
		return new TransformFeedbackResumeTestInstance(context, m_parameters);

	if (m_parameters.testType == TEST_TYPE_XFB_POINTSIZE)
		return new TransformFeedbackBuiltinTestInstance(context, m_parameters);

	if (m_parameters.testType == TEST_TYPE_XFB_CLIPDISTANCE)
		return new TransformFeedbackBuiltinTestInstance(context, m_parameters);

	if (m_parameters.testType == TEST_TYPE_XFB_CULLDISTANCE)
		return new TransformFeedbackBuiltinTestInstance(context, m_parameters);

	if (m_parameters.testType == TEST_TYPE_XFB_CLIP_AND_CULL)
		return new TransformFeedbackBuiltinTestInstance(context, m_parameters);

	static const std::set<TestType> windingTests =
	{
		TEST_TYPE_LINE_LIST,
		TEST_TYPE_LINE_STRIP,
		TEST_TYPE_TRIANGLE_LIST,
		TEST_TYPE_TRIANGLE_STRIP,
		TEST_TYPE_TRIANGLE_FAN,
		TEST_TYPE_LINE_LIST_ADJACENCY,
		TEST_TYPE_LINE_STRIP_ADJACENCY,
		TEST_TYPE_TRIANGLE_STRIP_ADJACENCY,
		TEST_TYPE_TRIANGLE_LIST_ADJACENCY,
		TEST_TYPE_PATCH_LIST
	};
	if (windingTests.count(m_parameters.testType))
		return new TransformFeedbackWindingOrderTestInstance(context, m_parameters);

	if (m_parameters.testType == TEST_TYPE_STREAMS)
		return new TransformFeedbackStreamsTestInstance(context, m_parameters);

	if (m_parameters.testType == TEST_TYPE_STREAMS_POINTSIZE)
		return new TransformFeedbackStreamsTestInstance(context, m_parameters);

	if (m_parameters.testType == TEST_TYPE_STREAMS_CLIPDISTANCE)
		return new TransformFeedbackStreamsTestInstance(context, m_parameters);

	if (m_parameters.testType == TEST_TYPE_STREAMS_CULLDISTANCE)
		return new TransformFeedbackStreamsTestInstance(context, m_parameters);

	if (m_parameters.testType == TEST_TYPE_MULTISTREAMS)
		return new TransformFeedbackMultistreamTestInstance(context, m_parameters);

	if (m_parameters.testType == TEST_TYPE_DRAW_INDIRECT)
		return new TransformFeedbackIndirectDrawTestInstance(context, m_parameters);

	if (m_parameters.testType == TEST_TYPE_BACKWARD_DEPENDENCY)
		return new TransformFeedbackBackwardDependencyTestInstance(context, m_parameters);

	if (m_parameters.testType == TEST_TYPE_QUERY_GET	||
		m_parameters.testType == TEST_TYPE_QUERY_COPY	||
	    m_parameters.testType == TEST_TYPE_QUERY_RESET)
		return new TransformFeedbackQueryTestInstance(context, m_parameters);

	if (m_parameters.testType == TEST_TYPE_MULTIQUERY)
		return new TransformFeedbackMultiQueryTestInstance(context, m_parameters);

	TCU_THROW(InternalError, "Specified test type not found");
}

void TransformFeedbackTestCase::initPrograms (SourceCollections& programCollection) const
{
	const bool vertexShaderOnly		=  m_parameters.testType == TEST_TYPE_BASIC
									|| m_parameters.testType == TEST_TYPE_RESUME
									|| m_parameters.testType == TEST_TYPE_BACKWARD_DEPENDENCY
									|| m_parameters.testType == TEST_TYPE_LINE_LIST
									|| m_parameters.testType == TEST_TYPE_LINE_STRIP
									|| m_parameters.testType == TEST_TYPE_TRIANGLE_LIST
									|| m_parameters.testType == TEST_TYPE_TRIANGLE_STRIP
									|| m_parameters.testType == TEST_TYPE_TRIANGLE_FAN
									|| m_parameters.testType == TEST_TYPE_LINE_LIST_ADJACENCY
									|| m_parameters.testType == TEST_TYPE_LINE_STRIP_ADJACENCY
									|| m_parameters.testType == TEST_TYPE_TRIANGLE_STRIP_ADJACENCY
									|| m_parameters.testType == TEST_TYPE_TRIANGLE_LIST_ADJACENCY;
	const bool requiresFullPipeline	=  m_parameters.testType == TEST_TYPE_STREAMS
									|| m_parameters.testType == TEST_TYPE_STREAMS_POINTSIZE
									|| m_parameters.testType == TEST_TYPE_STREAMS_CULLDISTANCE
									|| m_parameters.testType == TEST_TYPE_STREAMS_CLIPDISTANCE
									|| m_parameters.testType == TEST_TYPE_PATCH_LIST;
	const bool xfbBuiltinPipeline	=  m_parameters.testType == TEST_TYPE_XFB_POINTSIZE
									|| m_parameters.testType == TEST_TYPE_XFB_CLIPDISTANCE
									|| m_parameters.testType == TEST_TYPE_XFB_CULLDISTANCE
									|| m_parameters.testType == TEST_TYPE_XFB_CLIP_AND_CULL;

	if (vertexShaderOnly)
	{
		// Vertex shader
		{
			std::ostringstream src;
			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
				<< "\n"
				<< "layout(push_constant) uniform pushConstants\n"
				<< "{\n"
				<< "    uint start;\n"
				<< "} uInput;\n"
				<< "\n"
				<< "layout(xfb_buffer = 0, xfb_offset = 0, xfb_stride = 4, location = 0) out uint idx_out;\n"
				<< "\n"
				<< "void main(void)\n"
				<< "{\n"
				<< "    idx_out = uInput.start + gl_VertexIndex;\n"
				<< "}\n";

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

		return;
	}

	if (m_parameters.testType == TEST_TYPE_PATCH_LIST)
	{
		// Vertex shader
		{
			std::ostringstream src;
			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
				<< "layout(push_constant) uniform pushConstants\n"
				<< "{\n"
				<< "    uint start;\n"
				<< "} uInput;\n"
				<< "void main(void)\n"
				<< "{\n"
				<< "}\n";
			programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
		}

		// Tesselation control shader
		{
			std::ostringstream src;
			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
				<< "layout(vertices = 3) out;\n"
				<< "void main (void)\n"
				<< "{\n"
				<< "    gl_TessLevelInner[0] = 2.0;\n" // generate three triangles out of each patch
				<< "    gl_TessLevelOuter[0] = 1.0;\n"
				<< "    gl_TessLevelOuter[1] = 1.0;\n"
				<< "    gl_TessLevelOuter[2] = 1.0;\n"
				<< "}\n";
			programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str());
		}

		// Tessellation evaluation shader
		{
			std::ostringstream src;
			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
				<< "layout(triangles, ccw) in;\n"
				<< "layout(xfb_buffer = 0, xfb_offset = 0, xfb_stride = 4, location = 0) out uint idx_out;\n"
				<< "\n"
				<< "void main (void)\n"
				<< "{\n"
				<< "    idx_out = gl_PrimitiveID;\n" // all vertex generated from patch will have its id
				<< "}\n";
			programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str());
		}

		return;
	}

	if (xfbBuiltinPipeline)
	{
		const std::string	outputBuiltIn		= (m_parameters.testType == TEST_TYPE_XFB_POINTSIZE)     ? "float gl_PointSize;\n"
												: (m_parameters.testType == TEST_TYPE_XFB_CLIPDISTANCE)  ? "float gl_ClipDistance[8];\n"
												: (m_parameters.testType == TEST_TYPE_XFB_CULLDISTANCE)  ? "float gl_CullDistance[8];\n"
												: (m_parameters.testType == TEST_TYPE_XFB_CLIP_AND_CULL) ? "float gl_CullDistance[5];\nfloat gl_ClipDistance[1];\n"
												: "";
		const std::string	operationBuiltIn	= (m_parameters.testType == TEST_TYPE_XFB_POINTSIZE)     ? "gl_PointSize = float(gl_VertexIndex) / 32768.0f;"
												: (m_parameters.testType == TEST_TYPE_XFB_CLIPDISTANCE)  ? "for (int i=0; i<8; i++) gl_ClipDistance[i] = float(8 * gl_VertexIndex + i) / 32768.0f;"
												: (m_parameters.testType == TEST_TYPE_XFB_CULLDISTANCE)  ? "for (int i=0; i<8; i++) gl_CullDistance[i] = float(8 * gl_VertexIndex + i) / 32768.0f;"
												: (m_parameters.testType == TEST_TYPE_XFB_CLIP_AND_CULL) ? "for (int i=0; i<5; i++) gl_CullDistance[i] = float(6 * gl_VertexIndex + i) / 32768.0f;\n"
																										   "gl_ClipDistance[0] = float(6 * gl_VertexIndex + 5) / 32768.0f;\n"
												: "";

		// Vertex shader
		{
			std::ostringstream src;
			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
				<< "\n"
				<< "layout(xfb_buffer = " << m_parameters.partCount - 1 << ", xfb_offset = 0) out gl_PerVertex\n"
				<< "{\n"
				<< outputBuiltIn
				<< "};\n"
				<< "\n"
				<< "void main(void)\n"
				<< "{\n"
				<< operationBuiltIn
				<< "}\n";

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

		return;
	}

	if (m_parameters.testType == TEST_TYPE_MULTISTREAMS)
	{
		// vertex shader
		{
			std::ostringstream src;
			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
				<< "\n"
				<< "void main(void)\n"
				<< "{\n"
				<< "}\n";

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

		// geometry shader
		{
			const deUint32		s	= m_parameters.streamId;
			std::ostringstream	src;

			DE_ASSERT(s != 0);

			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
				<< "\n"
				<< "layout(points) in;\n"
				<< "\n"
				<< "layout(points, max_vertices = 32) out;\n"
				<< "layout(stream = " << 0 << ", xfb_buffer = 0, xfb_offset = 0, xfb_stride = 16, location = 0) out vec4 out0;\n"
				<< "layout(stream = " << s << ", xfb_buffer = 1, xfb_offset = 0, xfb_stride = 16, location = 1) out vec4 out1;\n"
				<< "\n"
				<< "const int counts[] = int[](1, 1, 2, 4, 8);\n"
				<< "\n"
				<< "void main(void)\n"
				<< "{\n"
				<< "    int c0 = 0;\n"
				<< "    int c1 = 0;\n"
				<< "\n"
				<< "    // Start 1st buffer from point where 0th buffer ended\n"
				<< "    for (int i = 0; i < counts.length(); i++)\n"
				<< "        c1 = c1 + 4 * counts[i];\n"
				<< "\n"
				<< "    for (int i = 0; i < counts.length(); i++)\n"
				<< "    {\n"
				<< "        const int n0 = counts[i];\n"
				<< "        const int n1 = counts[counts.length() - 1 - i];\n"
				<< "\n"
				<< "        for (int j = 0; j < n0; j++)\n"
				<< "        {\n"
				<< "            out0 = vec4(ivec4(c0, c0 + 1, c0 + 2, c0 + 3));\n"
				<< "            c0 = c0 + 4;\n"
				<< "            EmitStreamVertex(0);\n"
				<< "            EndStreamPrimitive(0);\n"
				<< "        }\n"
				<< "\n"
				<< "        for (int j = 0; j < n1; j++)\n"
				<< "        {\n"
				<< "            out1 = vec4(ivec4(c1, c1 + 1, c1 + 2, c1 + 3));\n"
				<< "            c1 = c1 + 4;\n"
				<< "            EmitStreamVertex(" << s << ");\n"
				<< "            EndStreamPrimitive(" << s << ");\n"
				<< "        }\n"
				<< "    }\n"
				<< "}\n";

			programCollection.glslSources.add("geom") << glu::GeometrySource(src.str());
		}

		return;
	}

	if (requiresFullPipeline)
	{
		// vertex shader
		{
			std::ostringstream src;
			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
				<< "\n"
				<< "void main(void)\n"
				<< "{\n"
				<< "}\n";

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

		// geometry shader
		{
			const deUint32		s					= m_parameters.streamId;
			const bool			requirePoints		= (m_parameters.testType == TEST_TYPE_STREAMS_POINTSIZE || m_parameters.testType == TEST_TYPE_MULTISTREAMS);
			const std::string	outputPrimitiveType	= requirePoints ? "points" : "triangle_strip";
			const std::string	outputBuiltIn		= (m_parameters.testType == TEST_TYPE_STREAMS_POINTSIZE)    ? "    float gl_PointSize;\n"
													: (m_parameters.testType == TEST_TYPE_STREAMS_CLIPDISTANCE) ? "    float gl_ClipDistance[];\n"
													: (m_parameters.testType == TEST_TYPE_STREAMS_CULLDISTANCE) ? "    float gl_CullDistance[];\n"
													: "";
			std::ostringstream	src;

			DE_ASSERT(s != 0);

			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
				<< "\n"
				<< "layout(points) in;\n"
				<< "layout(" << outputPrimitiveType << ", max_vertices = 16) out;\n"
				<< "layout(stream = " << s << ") out;\n"
				<< "layout(location = 0) out vec4 color;\n"
				<< "\n"
				<< "layout(stream = " << s << ") out gl_PerVertex\n"
				<< "{\n"
				<< "    vec4 gl_Position;\n"
				<< outputBuiltIn
				<< "};\n"
				<< "\n"
				<< "void main(void)\n"
				<< "{\n"
				<< "    // Color constants\n"
				<< "    vec4 g = vec4(0.0, 1.0, 0.0, 1.0);\n"
				<< "    vec4 m = vec4(1.0, 0.0, 1.0, 1.0);\n"
				<< "    // Coordinate constants: leftmost column\n"
				<< "    vec4 a = vec4(-1.0,-1.0, 0.0, 1.0);\n"
				<< "    vec4 b = vec4(-1.0, 0.0, 0.0, 1.0);\n"
				<< "    vec4 c = vec4(-1.0, 1.0, 0.0, 1.0);\n"
				<< "    // Coordinate constants: middle column\n"
				<< "    vec4 i = vec4( 0.0,-1.0, 0.0, 1.0);\n"
				<< "    vec4 j = vec4( 0.0, 0.0, 0.0, 1.0);\n"
				<< "    vec4 k = vec4( 0.0, 1.0, 0.0, 1.0);\n"
				<< "    // Coordinate constants: rightmost column\n"
				<< "    vec4 x = vec4( 1.0,-1.0, 0.0, 1.0);\n"
				<< "    vec4 y = vec4( 1.0, 0.0, 0.0, 1.0);\n"
				<< "    vec4 z = vec4( 1.0, 1.0, 0.0, 1.0);\n"
				<< "\n";

			if (m_parameters.testType == TEST_TYPE_STREAMS)
			{
				src << "    if (gl_PrimitiveIDIn == 0)\n"
					<< "    {\n"
					<< "        color = m; gl_Position = b; EmitStreamVertex(" << s << ");\n"
					<< "        color = m; gl_Position = y; EmitStreamVertex(" << s << ");\n"
					<< "        color = m; gl_Position = c; EmitStreamVertex(" << s << ");\n"
					<< "        EndStreamPrimitive(" << s << ");\n"
					<< "    }\n"
					<< "    else\n"
					<< "    {\n"
					<< "        color = m; gl_Position = y; EmitStreamVertex(" << s << ");\n"
					<< "        color = m; gl_Position = c; EmitStreamVertex(" << s << ");\n"
					<< "        color = m; gl_Position = z; EmitStreamVertex(" << s << ");\n"
					<< "        EndStreamPrimitive(" << s << ");\n"
					<< "    }\n";
			}

			if (m_parameters.testType == TEST_TYPE_STREAMS_POINTSIZE)
			{
				const std::string	pointSize	= "gl_PointSize = " + de::toString(m_parameters.pointSize) + ".0f";

				src << "    if (gl_PrimitiveIDIn == 0)\n"
					<< "    {\n"
					<< "        color = g; gl_Position = (a + j) / 2.0f; gl_PointSize = 1.0f; EmitStreamVertex(0);\n"
					<< "        EndStreamPrimitive(0);\n"
					<< "        color = m; gl_Position = (b + k) / 2.0f; gl_PointSize = 1.0f; EmitStreamVertex(" << s << ");\n"
					<< "        EndStreamPrimitive(" << s << ");\n"
					<< "    }\n"
					<< "    else\n"
					<< "    {\n"
					<< "        color = g; gl_Position = (j + x) / 2.0f; " << pointSize << "; EmitStreamVertex(0);\n"
					<< "        EndStreamPrimitive(0);\n"
					<< "        color = m; gl_Position = (k + y) / 2.0f; " << pointSize << "; EmitStreamVertex(" << s << ");\n"
					<< "        EndStreamPrimitive(" << s << ");\n"
					<< "    }\n";
			}

			if (m_parameters.testType == TEST_TYPE_STREAMS_CLIPDISTANCE)
			{
				src << "    if (gl_PrimitiveIDIn == 0)\n"
					<< "    {\n"
					<< "        color = m; gl_Position = b; gl_ClipDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
					<< "        color = m; gl_Position = c; gl_ClipDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
					<< "        color = m; gl_Position = y; gl_ClipDistance[0] =  1.0; EmitStreamVertex(" << s << ");\n"
					<< "        EndStreamPrimitive(" << s << ");\n"
					<< "    }\n"
					<< "    else\n"
					<< "    {\n"
					<< "        color = m; gl_Position = y; gl_ClipDistance[0] =  1.0; EmitStreamVertex(" << s << ");\n"
					<< "        color = m; gl_Position = c; gl_ClipDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
					<< "        color = m; gl_Position = z; gl_ClipDistance[0] =  1.0; EmitStreamVertex(" << s << ");\n"
					<< "        EndStreamPrimitive(" << s << ");\n"
					<< "    }\n";
			}

			if (m_parameters.testType == TEST_TYPE_STREAMS_CULLDISTANCE)
			{
				src << "    if (gl_PrimitiveIDIn == 0)\n"
					<< "    {\n"
					<< "        color = m; gl_Position = b; gl_CullDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
					<< "        color = m; gl_Position = c; gl_CullDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
					<< "        color = m; gl_Position = j; gl_CullDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
					<< "        EndStreamPrimitive(" << s << ");\n"
					<< "        color = m; gl_Position = j; gl_CullDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
					<< "        color = m; gl_Position = c; gl_CullDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
					<< "        color = m; gl_Position = k; gl_CullDistance[0] = -1.0; EmitStreamVertex(" << s << ");\n"
					<< "        EndStreamPrimitive(" << s << ");\n"
					<< "    }\n"
					<< "    else\n"
					<< "    {\n"
					<< "        color = m; gl_Position = j; gl_CullDistance[0] =  1.0; EmitStreamVertex(" << s << ");\n"
					<< "        color = m; gl_Position = k; gl_CullDistance[0] =  1.0; EmitStreamVertex(" << s << ");\n"
					<< "        color = m; gl_Position = y; gl_CullDistance[0] =  1.0; EmitStreamVertex(" << s << ");\n"
					<< "        EndStreamPrimitive(" << s << ");\n"
					<< "        color = m; gl_Position = y; gl_CullDistance[0] =  1.0; EmitStreamVertex(" << s << ");\n"
					<< "        color = m; gl_Position = k; gl_CullDistance[0] =  1.0; EmitStreamVertex(" << s << ");\n"
					<< "        color = m; gl_Position = z; gl_CullDistance[0] =  1.0; EmitStreamVertex(" << s << ");\n"
					<< "        EndStreamPrimitive(" << s << ");\n"
					<< "    }\n";
			}

			src << "}\n";

			programCollection.glslSources.add("geom") << glu::GeometrySource(src.str());
		}

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

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

		return;
	}

	if (m_parameters.testType == TEST_TYPE_DRAW_INDIRECT)
	{
		// vertex shader
		{
			std::ostringstream src;
			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
				<< "\n"
				<< "layout(location = 0) in vec4 in_position;\n"
				<< "\n"
				<< "void main(void)\n"
				<< "{\n"
				<< "    gl_Position = in_position;\n"
				<< "}\n";

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

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

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

		return;
	}

	if (m_parameters.testType == TEST_TYPE_QUERY_GET	||
		m_parameters.testType == TEST_TYPE_QUERY_COPY	||
		m_parameters.testType == TEST_TYPE_QUERY_RESET)
	{
		// Vertex shader
		{
			std::ostringstream src;
			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
				<< "\n"
				<< "layout(location = 0) out vec4 out0;\n"
				<< "\n"
				<< "void main(void)\n"
				<< "{\n"
				<< "    float n = 4.0 * float(gl_VertexIndex);\n"
				<< "    out0 = vec4(n + 0.0, n + 1.0, n + 2.0, n + 3.0);\n"
				<< "}\n";

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

		// geometry shader
		if (m_parameters.streamId == 0)
		{
			std::ostringstream	src;

			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
				<< "\n"
				<< "layout(points) in;\n"
				<< "layout(location = 0) in vec4 in0[];\n"
				<< "\n"
				<< "layout(points, max_vertices = 1) out;\n"
				<< "layout(xfb_buffer = 0, xfb_offset = 0, xfb_stride = 16, location = 0) out vec4 out0;\n"
				<< "\n"
				<< "void main(void)\n"
				<< "{\n"
				<< "    out0 = in0[0];\n"
				<< "    EmitVertex();\n"
				<< "    EndPrimitive();\n"
				<< "}\n";

			programCollection.glslSources.add("geom") << glu::GeometrySource(src.str());
		}
		else
		{
			const deUint32		s	= m_parameters.streamId;
			std::ostringstream	src;

			if (m_parameters.testType == TEST_TYPE_QUERY_GET)
			{
				// The SPIR-V program below is roughly equivalent to the following GLSL code:
				//
				// #version 450
				// #extension GL_ARB_enhanced_layouts : require
				//
				// layout(points) in;
				// layout(location = 0) in vec4 in0[];
				//
				// layout(points, max_vertices = 1) out;
				// layout(location=0, stream=1, xfb_buffer=0, xfb_stride=16) out OutBlock {
				//     layout(xfb_offset=0, location=0) vec4 out0;
				// } outBlock;
				//
				// void main(void)
				// {
				//     outBlock.out0 = in0[0];
				//     EmitStreamVertex(1);
				//     EndStreamPrimitive(1);
				// }
				//
				// However, the stream number has been parametrized and the code generated by glslang has been tuned to move the
				// Stream, XfbBuffer and XfbStride decorations to the structure member instead of the block. This allows us to test
				// transform feedback decorations on structure members as part of these basic tests.
				src	<< "; SPIR-V\n"
					<< "; Version: 1.0\n"
					<< "; Generator: Khronos Glslang Reference Front End; 8\n"
					<< "; Bound: 24\n"
					<< "; Schema: 0\n"
					<< "               OpCapability Geometry\n"
					<< "               OpCapability TransformFeedback\n"
					<< "               OpCapability GeometryStreams\n"
					<< "          %1 = OpExtInstImport \"GLSL.std.450\"\n"
					<< "               OpMemoryModel Logical GLSL450\n"
					<< "               OpEntryPoint Geometry %main \"main\" %outBlock %in0\n"
					<< "               OpExecutionMode %main Xfb\n"
					<< "               OpExecutionMode %main InputPoints\n"
					<< "               OpExecutionMode %main Invocations 1\n"
					<< "               OpExecutionMode %main OutputPoints\n"
					<< "               OpExecutionMode %main OutputVertices 1\n"
					<< "               OpSource GLSL 450\n"
					<< "               OpSourceExtension \"GL_ARB_enhanced_layouts\"\n"
					<< "               OpName %main \"main\"\n"
					<< "               OpName %OutBlock \"OutBlock\"\n"
					<< "               OpMemberName %OutBlock 0 \"out0\"\n"
					<< "               OpName %outBlock \"outBlock\"\n"
					<< "               OpName %in0 \"in0\"\n"
					<< "               OpMemberDecorate %OutBlock 0 Location 0\n"
					<< "               OpMemberDecorate %OutBlock 0 Offset 0\n"
					// These Stream, XfbBuffer and XfbStride decorations have been moved to the struct member.
					<< "               OpMemberDecorate %OutBlock 0 Stream " << s << "\n"
					<< "               OpMemberDecorate %OutBlock 0 XfbBuffer 0\n"
					<< "               OpMemberDecorate %OutBlock 0 XfbStride 16\n"
					<< "               OpDecorate %OutBlock Block\n"
					// The decorations mentioned above were using OpDecorate and assigned to %outBlock itself here.
					<< "               OpDecorate %in0 Location 0\n"
					<< "       %void = OpTypeVoid\n"
					<< "          %3 = OpTypeFunction %void\n"
					<< "      %float = OpTypeFloat 32\n"
					<< "    %v4float = OpTypeVector %float 4\n"
					<< "   %OutBlock = OpTypeStruct %v4float\n"
					<< "%_ptr_Output_OutBlock = OpTypePointer Output %OutBlock\n"
					<< "   %outBlock = OpVariable %_ptr_Output_OutBlock Output\n"
					<< "        %int = OpTypeInt 32 1\n"
					<< "      %int_0 = OpConstant %int 0\n"
					<< "       %uint = OpTypeInt 32 0\n"
					<< "     %uint_1 = OpConstant %uint 1\n"
					<< "%_arr_v4float_uint_1 = OpTypeArray %v4float %uint_1\n"
					<< "%_ptr_Input__arr_v4float_uint_1 = OpTypePointer Input %_arr_v4float_uint_1\n"
					<< "        %in0 = OpVariable %_ptr_Input__arr_v4float_uint_1 Input\n"
					<< "%_ptr_Input_v4float = OpTypePointer Input %v4float\n"
					<< "%_ptr_Output_v4float = OpTypePointer Output %v4float\n"
					<< "  %streamNum = OpConstant %int " << s << "\n"
					<< "       %main = OpFunction %void None %3\n"
					<< "          %5 = OpLabel\n"
					<< "         %19 = OpAccessChain %_ptr_Input_v4float %in0 %int_0\n"
					<< "         %20 = OpLoad %v4float %19\n"
					<< "         %22 = OpAccessChain %_ptr_Output_v4float %outBlock %int_0\n"
					<< "               OpStore %22 %20\n"
					<< "               OpEmitStreamVertex %streamNum\n"
					<< "               OpEndStreamPrimitive %streamNum\n"
					<< "               OpReturn\n"
					<< "               OpFunctionEnd\n"
					;

				programCollection.spirvAsmSources.add("geom") << src.str();
			}
			else
			{
				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
					<< "\n"
					<< "layout(points) in;\n"
					<< "layout(location = 0) in vec4 in0[];\n"
					<< "\n"
					<< "layout(points, max_vertices = 1) out;\n"
					<< "layout(stream = " << s << ", xfb_buffer = 0, xfb_offset = 0, xfb_stride = 16, location = 0) out vec4 out0;\n"
					<< "\n"
					<< "void main(void)\n"
					<< "{\n"
					<< "    out0 = in0[0];\n"
					<< "    EmitStreamVertex(" << s << ");\n"
					<< "    EndStreamPrimitive(" << s << ");\n"
					<< "}\n";

				programCollection.glslSources.add("geom") << glu::GeometrySource(src.str());
			}
		}

		return;
	}

	if (m_parameters.testType == TEST_TYPE_MULTIQUERY)
	{
		// vertex shader
		{
			std::ostringstream src;
			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
				<< "\n"
				<< "layout(location = 0) out ivec4 out0;\n"
				<< "\n"
				<< "void main(void)\n"
				<< "{\n"
				<< "    out0 = ivec4(gl_VertexIndex);\n"
				<< "}\n";

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

		// geometry shader
		{
			const deUint32		s	= m_parameters.streamId;
			std::ostringstream	src;

			DE_ASSERT(s != 0);

			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
				<< "\n"
				<< "layout(points) in;\n"
				<< "\n"
				<< "layout(points, max_vertices = 4) out;\n"
				<< "\n"
				<< "layout(stream = " << 0 << ", xfb_buffer = 0, xfb_offset = 0, xfb_stride = 16, location = 0) out vec4 out0;\n"
				<< "layout(stream = " << s << ", xfb_buffer = 1, xfb_offset = 0, xfb_stride = 16, location = 1) out vec4 out1;\n"
				<< "\n"
				<< "void main(void)\n"
				<< "{\n"
				<< "    const int   n0 = 3;\n"
				<< "    const int   n1 = 1;\n"
				<< "    const float c0 = 0.5f;\n"
				<< "    const float c1 = 0.5f + float(" << s << ");\n"
				<< "\n"
				<< "    for (int j = 0; j < n0; j++)\n"
				<< "    {\n"
				<< "        out0 = vec4(c0);\n"
				<< "        EmitStreamVertex(0);\n"
				<< "        EndStreamPrimitive(0);\n"
				<< "    }\n"
				<< "\n"
				<< "    for (int j = 0; j < n1; j++)\n"
				<< "    {\n"
				<< "        out1 = vec4(c1);\n"
				<< "        EmitStreamVertex(" << s << ");\n"
				<< "        EndStreamPrimitive(" << s << ");\n"
				<< "    }\n"
				<< "}\n";

			programCollection.glslSources.add("geom") << glu::GeometrySource(src.str());
		}

		return;
	}

	DE_ASSERT(0 && "Unknown test");
}

void createTransformFeedbackSimpleTests (tcu::TestCaseGroup* group)
{
	{
		const deUint32		bufferCounts[]	= { 1, 2, 4, 8 };
		const deUint32		bufferSizes[]	= { 256, 512, 128*1024 };
		const TestType		testTypes[]		= { TEST_TYPE_BASIC, TEST_TYPE_RESUME, TEST_TYPE_XFB_POINTSIZE, TEST_TYPE_XFB_CLIPDISTANCE, TEST_TYPE_XFB_CULLDISTANCE, TEST_TYPE_XFB_CLIP_AND_CULL };
		const std::string	testTypeNames[]	= { "basic",         "resume",         "xfb_pointsize",         "xfb_clipdistance",         "xfb_culldistance",         "xfb_clip_and_cull"         };

		for (deUint32 testTypesNdx = 0; testTypesNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypesNdx)
		{
			const TestType		testType	= testTypes[testTypesNdx];
			const std::string	testName	= testTypeNames[testTypesNdx];

			for (deUint32 bufferCountsNdx = 0; bufferCountsNdx < DE_LENGTH_OF_ARRAY(bufferCounts); ++bufferCountsNdx)
			{
				const deUint32	partCount	= bufferCounts[bufferCountsNdx];

				for (deUint32 bufferSizesNdx = 0; bufferSizesNdx < DE_LENGTH_OF_ARRAY(bufferSizes); ++bufferSizesNdx)
				{
					const deUint32	bufferSize	= bufferSizes[bufferSizesNdx];
					TestParameters	parameters	= { testType, bufferSize, partCount, 0u, 0u, 0u, STREAM_ID_0_NORMAL, false, false };

					group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_" + de::toString(partCount) + "_" + de::toString(bufferSize)).c_str(), "Simple Transform Feedback test", parameters));
					parameters.streamId0Mode = STREAM_ID_0_BEGIN_QUERY_INDEXED;
					group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_beginqueryindexed_streamid_0_" + de::toString(partCount) + "_" + de::toString(bufferSize)).c_str(), "Simple Transform Feedback test", parameters));
					parameters.streamId0Mode = STREAM_ID_0_END_QUERY_INDEXED;
					group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_endqueryindexed_streamid_0_" + de::toString(partCount) + "_" + de::toString(bufferSize)).c_str(), "Simple Transform Feedback test", parameters));
				}
			}
		}
	}

	{
		const deUint32		bufferCounts[]	= { 6, 8, 10, 12 };
		const TestType		testTypes[]		=
		{
			// note: no need to test POINT_LIST as is tested in many tests
			TEST_TYPE_LINE_LIST,
			TEST_TYPE_LINE_STRIP,
			TEST_TYPE_TRIANGLE_LIST,
			TEST_TYPE_TRIANGLE_STRIP,
			TEST_TYPE_TRIANGLE_FAN,
			TEST_TYPE_LINE_LIST_ADJACENCY,
			TEST_TYPE_LINE_STRIP_ADJACENCY,
			TEST_TYPE_TRIANGLE_STRIP_ADJACENCY,
			TEST_TYPE_TRIANGLE_LIST_ADJACENCY,
			TEST_TYPE_PATCH_LIST
		};
		const std::string	testTypeNames[]	=
		{
			"winding_line_list",
			"winding_line_strip",
			"winding_triangle_list",
			"winding_triangle_strip",
			"winding_triangle_fan",
			"winding_line_list_with_adjacency",
			"winding_line_strip_with_adjacency",
			"winding_triangle_strip_with_adjacency",
			"winding_triangle_list_with_adjacency",
			"winding_patch_list"
		};

		for (deUint32 testTypesNdx = 0; testTypesNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypesNdx)
		{
			const TestType		testType	= testTypes[testTypesNdx];
			const std::string	testName	= testTypeNames[testTypesNdx];

			for (deUint32 bufferCountsNdx = 0; bufferCountsNdx < DE_LENGTH_OF_ARRAY(bufferCounts); ++bufferCountsNdx)
			{
				const deUint32	vertexCount	= bufferCounts[bufferCountsNdx];
				TestParameters	parameters	= { testType, 0u, vertexCount, 0u, 0u, 0u, STREAM_ID_0_NORMAL, false, false };

				group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_" + de::toString(vertexCount)).c_str(), "Topology winding test", parameters));
			}
		}
	}

	{
		const deUint32		vertexStrides[]	= { 4, 61, 127, 251, 509 };
		const TestType		testType		= TEST_TYPE_DRAW_INDIRECT;
		const std::string	testName		= "draw_indirect";

		for (deUint32 vertexStridesNdx = 0; vertexStridesNdx < DE_LENGTH_OF_ARRAY(vertexStrides); ++vertexStridesNdx)
		{
			const deUint32	vertexStride	= static_cast<deUint32>(sizeof(deUint32) * vertexStrides[vertexStridesNdx]);
			TestParameters	parameters		= { testType, 0u, 0u, 0u, 0u, vertexStride, STREAM_ID_0_NORMAL, false, false };

			group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_" + de::toString(vertexStride)).c_str(), "Rendering tests with various strides", parameters));
			parameters.streamId0Mode = STREAM_ID_0_BEGIN_QUERY_INDEXED;
			group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_beginqueryindexed_streamid_0_" + de::toString(vertexStride)).c_str(), "Rendering tests with various strides", parameters));
			parameters.streamId0Mode = STREAM_ID_0_END_QUERY_INDEXED;
			group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_endqueryindexed_streamid_0_" + de::toString(vertexStride)).c_str(), "Rendering tests with various strides", parameters));
		}
	}

	{
		const TestType		testType	= TEST_TYPE_BACKWARD_DEPENDENCY;
		const std::string	testName	= "backward_dependency";
		TestParameters		parameters	= { testType, 512u, 2u, 0u, 0u, 0u, STREAM_ID_0_NORMAL, false, false };

		group->addChild(new TransformFeedbackTestCase(group->getTestContext(), testName.c_str(), "Rendering test checks backward pipeline dependency", parameters));
		parameters.streamId0Mode = STREAM_ID_0_BEGIN_QUERY_INDEXED;
		group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_beginqueryindexed_streamid_0").c_str(), "Rendering test checks backward pipeline dependency", parameters));
		parameters.streamId0Mode = STREAM_ID_0_END_QUERY_INDEXED;
		group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_endqueryindexed_streamid_0").c_str(), "Rendering test checks backward pipeline dependency", parameters));

		parameters.noOffsetArray = true;
		group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_no_offset_array").c_str(), "Rendering test checks backward pipeline dependency (using NULL for offset array)", parameters));
	}

	{
		const deUint32		usedStreamId[]			= { 0, 1, 3, 6, 14 };
		const deUint32		vertexCount[]			= { 4, 61, 127, 251, 509 };
		const TestType		testType				= TEST_TYPE_QUERY_GET;
		const std::string	testName				= "query";
		const TestType		testTypeCopy			= TEST_TYPE_QUERY_COPY;
		const std::string	testNameCopy			= "query_copy";
		const TestType		testTypeHostQueryReset	= TEST_TYPE_QUERY_RESET;
		const std::string	testNameHostQueryReset	= "host_query_reset";

		for (deUint32 streamCountsNdx = 0; streamCountsNdx < DE_LENGTH_OF_ARRAY(usedStreamId); ++streamCountsNdx)
		{
			const deUint32	streamId	= usedStreamId[streamCountsNdx];

			for (deUint32 vertexCountNdx = 0; vertexCountNdx < DE_LENGTH_OF_ARRAY(vertexCount); ++vertexCountNdx)
			{
				for (deUint32 i = 0; i < 2; ++i)
				{
					const bool				query64Bits		= (i == 1);
					const std::string		widthStr		= (query64Bits ? "_64bits" : "_32bits");

					const deUint32			bytesPerVertex	= static_cast<deUint32>(4 * sizeof(float));
					const deUint32			bufferSize		= bytesPerVertex * vertexCount[vertexCountNdx];
					TestParameters			parameters		= { testType, bufferSize, 0u, streamId, 0u, 0u, STREAM_ID_0_NORMAL, query64Bits, false };
					const std::string		fullTestName	= testName + "_" + de::toString(streamId) + "_" + de::toString(vertexCount[vertexCountNdx]) + widthStr;
					group->addChild(new TransformFeedbackTestCase(group->getTestContext(), fullTestName.c_str(), "Written primitives query test", parameters));

					const TestParameters	parametersCopy		= { testTypeCopy, bufferSize, 0u, streamId, 0u, 0u, STREAM_ID_0_NORMAL, query64Bits, false };
					const std::string		fullTestNameCopy	= testNameCopy + "_" + de::toString(streamId) + "_" + de::toString(vertexCount[vertexCountNdx]) + widthStr;
					group->addChild(new TransformFeedbackTestCase(group->getTestContext(), fullTestNameCopy.c_str(), "Written primitives query test", parametersCopy));

					const TestParameters	parametersHostQueryReset	= { testTypeHostQueryReset, bufferSize, 0u, streamId, 0u, 0u, STREAM_ID_0_NORMAL, query64Bits, false };
					const std::string		fullTestNameHostQueryReset	= testNameHostQueryReset + "_" + de::toString(streamId) + "_" + de::toString(vertexCount[vertexCountNdx]) + widthStr;
					group->addChild(new TransformFeedbackTestCase(group->getTestContext(), fullTestNameHostQueryReset.c_str(), "Written primitives query test", parametersHostQueryReset));

					if (streamId == 0)
					{
						std::string	testNameStream0 = fullTestName;
						testNameStream0 += "_beginqueryindexed_streamid_0";
						parameters.streamId0Mode = STREAM_ID_0_BEGIN_QUERY_INDEXED;
						group->addChild(new TransformFeedbackTestCase(group->getTestContext(), testNameStream0.c_str(), "Written primitives query test", parameters));
						testNameStream0 = fullTestName;
						testNameStream0 += "_endqueryindexed_streamid_0";
						parameters.streamId0Mode = STREAM_ID_0_END_QUERY_INDEXED;
						group->addChild(new TransformFeedbackTestCase(group->getTestContext(), testNameStream0.c_str(), "Written primitives query test", parameters));
					}
				}
			}
		}
	}
}

void createTransformFeedbackStreamsSimpleTests (tcu::TestCaseGroup* group)
{
	const deUint32		usedStreamId[]		= { 1, 3, 6, 14 };
	const TestType		testTypes[]			= { TEST_TYPE_STREAMS, TEST_TYPE_STREAMS_POINTSIZE, TEST_TYPE_STREAMS_CLIPDISTANCE, TEST_TYPE_STREAMS_CULLDISTANCE };
	const std::string	testTypeNames[]		= { "streams",         "streams_pointsize",         "streams_clipdistance",         "streams_culldistance"         };

	for (deUint32 testTypesNdx = 0; testTypesNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypesNdx)
	{
		const TestType		testType	= testTypes[testTypesNdx];
		const std::string	testName	= testTypeNames[testTypesNdx];
		const deUint32		pointSize	= (testType == TEST_TYPE_STREAMS_POINTSIZE) ? 2u : 0u;

		for (deUint32 streamCountsNdx = 0; streamCountsNdx < DE_LENGTH_OF_ARRAY(usedStreamId); ++streamCountsNdx)
		{
			const deUint32	streamId	= usedStreamId[streamCountsNdx];
			TestParameters	parameters	= { testType, 0u, 0u, streamId, pointSize, 0u, STREAM_ID_0_NORMAL, false, false };

			group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_" + de::toString(streamId)).c_str(), "Streams usage test", parameters));
		}
	}

	{
		const TestType		testType	= TEST_TYPE_MULTISTREAMS;
		const std::string	testName	= "multistreams";

		for (deUint32 bufferCountsNdx = 0; bufferCountsNdx < DE_LENGTH_OF_ARRAY(usedStreamId); ++bufferCountsNdx)
		{
			const deUint32			streamId			= usedStreamId[bufferCountsNdx];
			const deUint32			streamsUsed			= 2u;
			const deUint32			maxBytesPerVertex	= 256u;
			const TestParameters	parameters			= { testType, maxBytesPerVertex * streamsUsed, streamsUsed, streamId, 0u, 0u, STREAM_ID_0_NORMAL, false, false };

			group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_" + de::toString(streamId)).c_str(), "Simultaneous multiple streams usage test", parameters));
		}
	}

	{
		const TestType		testType	= TEST_TYPE_MULTIQUERY;
		const std::string	testName	= "multiquery";

		for (deUint32 bufferCountsNdx = 0; bufferCountsNdx < DE_LENGTH_OF_ARRAY(usedStreamId); ++bufferCountsNdx)
		{
			const deUint32			streamId			= usedStreamId[bufferCountsNdx];
			const deUint32			streamsUsed			= 2u;
			const deUint32			maxBytesPerVertex	= 256u;
			const TestParameters	parameters			= { testType, maxBytesPerVertex * streamsUsed, streamsUsed, streamId, 0u, 0u, STREAM_ID_0_NORMAL, false, false };

			group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_" + de::toString(streamId)).c_str(), "Simultaneous multiple queries usage test", parameters));
		}
	}
}

void createTransformFeedbackAndStreamsSimpleTests (tcu::TestCaseGroup* group)
{
	createTransformFeedbackSimpleTests(group);
	createTransformFeedbackStreamsSimpleTests(group);
}
} // anonymous

tcu::TestCaseGroup* createTransformFeedbackSimpleTests (tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "simple", "Transform Feedback Simple tests", createTransformFeedbackAndStreamsSimpleTests);
}

} // TransformFeedback
} // vkt
