/*------------------------------------------------------------------------
 * 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>

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_TRIANGLE_STRIP_ADJACENCY,
	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,
	TEST_TYPE_QUERY_RESET,
	TEST_TYPE_LAST
};

struct TestParameters
{
	TestType	testType;
	deUint32	bufferSize;
	deUint32	partCount;
	deUint32	streamId;
	deUint32	pointSize;
	deUint32	vertexStride;
};

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			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
								DE_NULL,							// const VkShaderModule								tessellationControlModule
								DE_NULL,							// 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
								0u,									// 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;
}

VkBufferImageCopy makeBufferImageCopy (const VkExtent3D					extent,
									   const VkImageSubresourceLayers	subresourceLayers)
{
	const VkBufferImageCopy copyParams =
	{
		0ull,										//	VkDeviceSize				bufferOffset;
		0u,											//	deUint32					bufferRowLength;
		0u,											//	deUint32					bufferImageHeight;
		subresourceLayers,							//	VkImageSubresourceLayers	imageSubresource;
		makeOffset3D(0, 0, 0),						//	VkOffset3D					imageOffset;
		extent,										//	VkExtent3D					imageExtent;
	};
	return copyParams;
}

inline Move<VkBuffer> makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkBufferCreateInfo& createInfo)
{
	return createBuffer(vk, device, &createInfo);
}

inline Move<VkImage> makeImage (const DeviceInterface& vk, const VkDevice device, const VkImageCreateInfo& createInfo)
{
	return createImage(vk, device, &createInfo);
}

de::MovePtr<Allocation> bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement)
{
	de::MovePtr<Allocation> alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement);
	VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset()));
	return alloc;
}

de::MovePtr<Allocation> bindBuffer (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkBuffer buffer, const MemoryRequirement requirement)
{
	de::MovePtr<Allocation> alloc(allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), requirement));
	VK_CHECK(vk.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset()));
	return alloc;
}

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					();
	deUint32										getNextChunkSize				(const deUint32 usedBytes, const deUint32 bufBytes);
	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.requireDeviceExtension("VK_EXT_transform_feedback"))
	, m_imageExtent2D	(makeExtent2D(IMAGE_SIZE, IMAGE_SIZE))
	, m_parameters		(parameters)
	, m_rnd				(0)
{
	const VkPhysicalDeviceTransformFeedbackFeaturesEXT&		transformFeedbackFeatures	= m_context.getTransformFeedbackFeatures();
	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();

	invalidateMappedMemoryRange(vk, device, bufAlloc->getMemory(), bufAlloc->getOffset(), bufBytes);

	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, 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 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);
	}
	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, 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 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);
		}
	}
	endCommandBuffer(vk, *cmdBuffer);
	submitCommandsAndWait(vk, device, queue, *cmdBuffer);

	verifyTransformFeedbackBuffer(tfBufAllocation, m_parameters.bufferSize);

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

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

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

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

tcu::TestStatus TransformFeedbackTriangleStripWithAdjacencyTestInstance::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();

	DE_ASSERT(m_parameters.partCount >= 6);

	const VkPrimitiveTopology			topology				(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY);
	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, m_imageExtent2D, 0u, DE_NULL, 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 deUint32						numPrimitives			= m_parameters.partCount / 2u - 2u;
	const deUint32						numPoints				= 3u * numPrimitives;
	const VkDeviceSize					bufferSize				= numPoints * 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 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);
	}
	endCommandBuffer(vk, *cmdBuffer);
	submitCommandsAndWait(vk, device, queue, *cmdBuffer);

	verifyTransformFeedbackBuffer(tfBufAllocation, bufferSize);

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

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

	invalidateMappedMemoryRange(vk, device, bufAlloc->getMemory(), bufAlloc->getOffset(), VK_WHOLE_SIZE);

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

	for (deUint32 dataNdx = 0; dataNdx < numPoints; ++dataNdx)
	{
		const deUint32	i			= dataNdx / 3;
		const deUint32	vertexNdx	= dataNdx % 3;
		const bool		even		= (0 == i % 2);
		deUint32		expected;

		if (even)
		{
			const deUint32	vertexNumbers[3] = { 2 * i + 0, 2 * i + 2, 2 * i + 4 };

			expected = vertexNumbers[vertexNdx];
		}
		else
		{
			const deUint32	vertexNumbers[3] = { 2 * i + 0, 2 * i + 4, 2 * i + 2 };

			expected = vertexNumbers[vertexNdx];
		}

		if (tfData[dataNdx] != expected)
			TCU_FAIL(std::string("Failed at item ") + de::toString(dataNdx) + " received:" + de::toString(tfData[dataNdx]) + " expected:" + de::toString(expected));
	}
}

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 deUint32 tfBuffersSupported	= m_transformFeedbackProperties.maxTransformFeedbackBuffers;
	const deUint32 tfBuffersRequired	= m_parameters.partCount;

	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();

	invalidateMappedMemoryRange(vk, device, bufAlloc->getMemory(), bufAlloc->getOffset(), VK_WHOLE_SIZE);

	const deUint32			numPoints	= static_cast<deUint32>(bufBytes / 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, 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 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);
	}
	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.getTransformFeedbackFeatures();
	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();

	invalidateMappedMemoryRange(vk, device, bufAlloc->getMemory(), bufAlloc->getOffset(), bufBytes);

	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, *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 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);
	}
	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.getTransformFeedbackFeatures();
	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, makeBufferCreateInfo(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, *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);
	}
	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, makeBufferCreateInfo(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, makeBufferCreateInfo(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, makeBufferCreateInfo(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, *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);
	}
	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)
{
}

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, 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 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, &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, &tfcBufBindingOffset);
				{
					vk.cmdDrawIndirectByteCountEXT(*cmdBuffer, 1u, 0u, *tfcBuf, 0u, 0u, 4u);
				}
				vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
			}

		}
		endRenderPass(vk, *cmdBuffer);
	}
	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.getTransformFeedbackFeatures();
	const deUint32											streamsSupported			= m_transformFeedbackProperties.maxTransformFeedbackStreams;
	const deUint32											streamsRequired				= m_parameters.streamId + 1;

	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 (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.requireDeviceExtension("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 deUint32						numVerticesInBuffer		= m_parameters.bufferSize / bytesPerVertex;
	const deUint32						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, *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 deUint32						queryCountersNumber		= 1u;
	const deUint32						queryIndex				= 0u;
	const VkQueryPoolCreateInfo			queryPoolCreateInfo		= makeQueryPoolCreateInfo(queryCountersNumber);
	const Unique<VkQueryPool>			queryPool				(createQueryPool(vk, device, &queryPoolCreateInfo));

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

	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, 1u, &*tfBuf, &tfBufBindingOffset, &tfBufBindingSize);

			if (m_parameters.streamId == 0)
				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, numVerticesToWrite, 1u, 0u, 0u);
				}
				vk.cmdEndTransformFeedbackEXT(*cmdBuffer, 0, 0, DE_NULL, DE_NULL);
			}
			if (m_parameters.streamId == 0)
				vk.cmdEndQuery(*cmdBuffer, *queryPool, queryIndex);
			else
				vk.cmdEndQueryIndexedEXT(*cmdBuffer, *queryPool, queryIndex, m_parameters.streamId);
		}
		endRenderPass(vk, *cmdBuffer);
	}
	endCommandBuffer(vk, *cmdBuffer);

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

	{
		const deUint32			queryDataSize			(static_cast<deUint32>(2u * sizeof(deUint32)));
		std::vector<deUint8>	queryData				(queryDataSize, 0u);
		const deUint32*			numPrimitivesWritten	= reinterpret_cast<deUint32*>(&queryData[0]);
		const deUint32*			numPrimitivesNeeded		= numPrimitivesWritten + 1;

		vk.getQueryPoolResults(device, *queryPool, queryIndex, queryCountersNumber, queryDataSize, &queryData[0], queryDataSize, 0u);

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

		const deUint32			queryDataSize			(static_cast<deUint32>(3u * sizeof(deUint32)));
		std::vector<deUint8>	queryData				(queryDataSize, 0u);
		deUint32*			numPrimitivesWritten	= reinterpret_cast<deUint32*>(&queryData[0]);
		deUint32*			numPrimitivesNeeded		= numPrimitivesWritten + 1;
		deUint32*			availabilityState		= numPrimitivesNeeded + 1;

		// Initialize values
		*numPrimitivesNeeded	= 1u;
		*numPrimitivesWritten	= 1u;
		*availabilityState		= 1u;

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

		vk::VkResult res = vk.getQueryPoolResults(device, *queryPool, queryIndex, queryCountersNumber, queryDataSize, &queryData[0], queryDataSize, VK_QUERY_RESULT_WITH_AVAILABILITY_BIT);
		/* From 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 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);

	if (m_parameters.testType == TEST_TYPE_TRIANGLE_STRIP_ADJACENCY)
		return new TransformFeedbackTriangleStripWithAdjacencyTestInstance(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 || m_parameters.testType == TEST_TYPE_QUERY_RESET)
		return new TransformFeedbackQueryTestInstance(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_TRIANGLE_STRIP_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;
	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 (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 || 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
		{
			const deUint32		s	= m_parameters.streamId;
			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(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;
	}

	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];
					const TestParameters	parameters	= { testType, bufferSize, partCount, 0u, 0u, 0u };

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

	{
		const deUint32		bufferCounts[]	= { 6, 8, 10, 12 };
		const TestType		testTypes[]		= { TEST_TYPE_TRIANGLE_STRIP_ADJACENCY };
		const std::string	testTypeNames[]	= { "triangle_strip_with_adjacency"};

		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];
				const TestParameters	parameters	= { testType, 0u, vertexCount, 0u, 0u, 0u };

				group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_" + de::toString(vertexCount)).c_str(), "Triangle Strip With Adjacency Transform Feedback 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]);
			const TestParameters	parameters		= { testType, 0u, 0u, 0u, 0u, vertexStride };

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

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

		group->addChild(new TransformFeedbackTestCase(group->getTestContext(), testName.c_str(), "Rendering test checks backward pipeline dependency", parameters));
	}

	{
		const deUint32		usedStreamId[]			= { 0, 1, 3, 6, 14 };
		const deUint32		vertexCount[]			= { 4, 61, 127, 251, 509 };
		const TestType		testType				= TEST_TYPE_QUERY;
		const std::string	testName				= "query";
		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)
			{
				const deUint32			bytesPerVertex	= static_cast<deUint32>(4 * sizeof(float));
				const deUint32			bufferSize		= bytesPerVertex * vertexCount[vertexCountNdx];
				const TestParameters	parameters		= { testType, bufferSize, 0u, streamId, 0u, 0u };
				const std::string		fullTestName	= testName + "_" + de::toString(streamId) + "_" + de::toString(vertexCount[vertexCountNdx]);

				group->addChild(new TransformFeedbackTestCase(group->getTestContext(), fullTestName.c_str(), "Written primitives query test", parameters));

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

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];
			const TestParameters	parameters	= { testType, 0u, 0u, streamId, pointSize, 0u };

			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 };

			group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_" + de::toString(streamId)).c_str(), "Simultaneous multiple streams 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
