/*-------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2018 Google Inc.
 * 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 Tests for subpass dependency
 *//*--------------------------------------------------------------------*/

#include "vktRenderPassSubpassDependencyTests.hpp"
#include "vktRenderPassTestsUtil.hpp"

#include "vktTestCaseUtil.hpp"
#include "vktTestGroupUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkRefUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"
#include "vkBuilderUtil.hpp"

#include "tcuImageCompare.hpp"
#include "tcuResultCollector.hpp"
#include "tcuTestLog.hpp"
#include "tcuTextureUtil.hpp"

#include "rrRenderer.hpp"
#include "deRandom.hpp"
#include "deMath.h"

using namespace vk;

using tcu::UVec4;
using tcu::Vec2;
using tcu::UVec2;
using tcu::Vec4;

using tcu::ConstPixelBufferAccess;
using tcu::PixelBufferAccess;

using tcu::TestLog;

using std::string;
using std::vector;
using de::SharedPtr;

typedef de::SharedPtr<Unique<VkImage> >					SharedPtrVkImage;
typedef de::SharedPtr<Unique<VkImageView> >				SharedPtrVkImageView;
typedef de::SharedPtr<Unique<VkPipeline> >				SharedPtrVkPipeline;
typedef de::SharedPtr<Unique<VkSampler> >				SharedPtrVkSampler;
typedef de::SharedPtr<Unique<VkRenderPass> >			SharedPtrVkRenderPass;
typedef de::SharedPtr<Unique<VkFramebuffer> >			SharedPtrVkFramebuffer;
typedef de::SharedPtr<Unique<VkDescriptorPool> >		SharedPtrVkDescriptorPool;
typedef de::SharedPtr<Unique<VkDescriptorSetLayout> >	SharedPtrVkDescriptorLayout;
typedef de::SharedPtr<Unique<VkDescriptorSet> >			SharedPtrVkDescriptorSet;
typedef de::SharedPtr<Unique<VkPipelineLayout> >		SharedPtrVkPipelineLayout;
typedef de::SharedPtr<Unique<VkPipeline> >				SharedPtrVkPipeline;

namespace vkt
{
namespace
{
using namespace renderpass;

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

tcu::TextureLevel getRepresentableDepthChannel (const ConstPixelBufferAccess& access)
{
	tcu::TextureLevel depthChannel (mapVkFormat(VK_FORMAT_R8G8B8_UNORM), access.getWidth(), access.getHeight());

	for (int y = 0; y < access.getHeight(); y++)
	for (int x = 0; x < access.getWidth(); x++)
		depthChannel.getAccess().setPixel(tcu::Vec4(access.getPixDepth(x, y)), x, y);

	return depthChannel;
}

bool verifyDepth (Context&						context,
				  const ConstPixelBufferAccess&	reference,
				  const ConstPixelBufferAccess&	result,
				  const float					threshold)
{
	tcu::TestLog& log (context.getTestContext().getLog());

	return tcu::floatThresholdCompare(log,										// log
									  "Depth channel",							// imageSetName
									  "Depth compare",							// imageSetDesc
									  getRepresentableDepthChannel(reference),	// reference
									  getRepresentableDepthChannel(result),		// result
									  Vec4(threshold),							// threshold
									  tcu::COMPARE_LOG_RESULT);					// logMode
}

bool verifyStencil (Context&						context,
					const ConstPixelBufferAccess&	reference,
					const ConstPixelBufferAccess&	result)
{
	tcu::TextureLevel	stencilErrorImage	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight());
	tcu::TestLog&		log					(context.getTestContext().getLog());
	bool				stencilOk			(DE_TRUE);

	for (int y = 0; y < result.getHeight(); y++)
	for (int x = 0; x < result.getWidth(); x++)
	{
		if (result.getPixStencil(x, y) != reference.getPixStencil(x, y))
		{
			stencilErrorImage.getAccess().setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
			stencilOk = DE_FALSE;
		}
		else
			stencilErrorImage.getAccess().setPixel(Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
	}

	log << tcu::TestLog::ImageSet("Stencil compare", "Stencil compare")
		<< tcu::TestLog::Image("Result stencil channel", "Result stencil channel", result)
		<< tcu::TestLog::Image("Reference stencil channel", "Reference stencil channel", reference);

	if (!stencilOk)
		log << tcu::TestLog::Image("Stencil error mask", "Stencil error mask", stencilErrorImage);

	log << tcu::TestLog::EndImageSet;

	return stencilOk;
}

// Reference renderer shaders
class DepthVertShader : public rr::VertexShader
{
public:
	DepthVertShader (void)
	: rr::VertexShader (1, 1)
	{
		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
		m_outputs[0].type	= rr::GENERICVECTYPE_FLOAT;
	}

	void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
	{
		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
		{
			packets[packetNdx]->position	= rr::readVertexAttribFloat(inputs[0],
																		packets[packetNdx]->instanceNdx,
																		packets[packetNdx]->vertexNdx);

			packets[packetNdx]->outputs[0]	= rr::readVertexAttribFloat(inputs[0],
																		packets[packetNdx]->instanceNdx,
																		packets[packetNdx]->vertexNdx);
		}
	}
};

class DepthFragShader : public rr::FragmentShader
{
public:
	DepthFragShader (void)
	: rr::FragmentShader(1, 1)
	{
		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
		m_outputs[0].type	= rr::GENERICVECTYPE_FLOAT;
	}

	void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
	{
		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
		{
			rr::FragmentPacket& packet = packets[packetNdx];
			for (deUint32 fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx)
			{
				const tcu::Vec4 vtxPosition = rr::readVarying<float>(packet, context, 0, fragNdx);

				rr::writeFragmentDepth(context, packetNdx, fragNdx, 0, vtxPosition.z());
			}
		}
	}
};

class SelfDependencyBackwardsVertShader : public rr::VertexShader
{
public:
	SelfDependencyBackwardsVertShader (void)
	: rr::VertexShader (1, 0)
	{
		m_inputs[0].type	= rr::GENERICVECTYPE_FLOAT;
	}

	void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
	{
		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
		{
			packets[packetNdx]->position	= rr::readVertexAttribFloat(inputs[0],
																		packets[packetNdx]->instanceNdx,
																		packets[packetNdx]->vertexNdx);
		}
	}
};

class SelfDependencyBackwardsFragShader : public rr::FragmentShader
{
public:
	SelfDependencyBackwardsFragShader (void)
	: rr::FragmentShader(0, 1)
	{
		m_outputs[0].type	= rr::GENERICVECTYPE_FLOAT;
	}

	void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
	{
		DE_UNREF(packets);

		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
			for (deUint32 fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx)
				rr::writeFragmentOutput<tcu::Vec4>(context, packetNdx, fragNdx, 0, tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
	}
};

de::MovePtr<Allocation> createBufferMemory (const DeviceInterface&	vk,
											VkDevice				device,
											Allocator&				allocator,
											VkBuffer				buffer)
{
	de::MovePtr<Allocation> allocation (allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), MemoryRequirement::HostVisible));

	VK_CHECK(vk.bindBufferMemory(device, buffer, allocation->getMemory(), allocation->getOffset()));

	return allocation;
}

Move<VkImageView> createImageView (const DeviceInterface&	vk,
								   VkDevice					device,
								   VkImageViewCreateFlags	flags,
								   VkImage					image,
								   VkImageViewType			viewType,
								   VkFormat					format,
								   VkComponentMapping		components,
								   VkImageSubresourceRange	subresourceRange)
{
	const VkImageViewCreateInfo pCreateInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType
		DE_NULL,									// const void*				pNext
		flags,										// VkImageViewCreateFlags	flags
		image,										// VkImage					image
		viewType,									// VkImageViewType			viewType
		format,										// VkFormat					format
		components,									// VkComponentMapping		components
		subresourceRange,							// VkImageSubresourceRange	subresourceRange
	};

	return createImageView(vk, device, &pCreateInfo);
}

vector<SharedPtrVkImageView> createImageViews (const DeviceInterface&	vkd,
											   VkDevice					device,
											   vector<SharedPtrVkImage>	images,
											   VkFormat					format,
											   VkImageAspectFlags		aspect)
{
	vector<SharedPtrVkImageView> imageViews;

	for (size_t imageViewNdx = 0; imageViewNdx < images.size(); imageViewNdx++)
	{
		const VkImageSubresourceRange range =
		{
			aspect,	// VkImageAspectFlags	aspectMask
			0u,		// uint32_t				baseMipLevel
			1u,		// uint32_t				levelCount
			0u,		// uint32_t				baseArrayLayer
			1u		// uint32_t				layerCount
		};

		imageViews.push_back(makeSharedPtr(createImageView(vkd, device, 0u, **images[imageViewNdx], VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range)));
	}

	return imageViews;
}

Move<VkBuffer> createBuffer (const DeviceInterface&	vkd,
							 VkDevice				device,
							 VkFormat				format,
							 deUint32				width,
							 deUint32				height)
{
	const VkBufferUsageFlags	bufferUsage	(VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
	const VkDeviceSize			pixelSize	= mapVkFormat(format).getPixelSize();
	const VkBufferCreateInfo	createInfo	=
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType
		DE_NULL,								// const void*			pNext
		0u,										// VkBufferCreateFlags	flags
		width * height * pixelSize,				// VkDeviceSize			size
		bufferUsage,							// VkBufferUsageFlags	usage
		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode
		0u,										// uint32_t				queueFamilyIndexCount
		DE_NULL									// const uint32_t*		pQueueFamilyIndices
	};

	return createBuffer(vkd, device, &createInfo);
}

vector<SharedPtrVkDescriptorLayout> createDescriptorSetLayouts (const DeviceInterface&		vkd,
																VkDevice					device,
																vector<SharedPtrVkSampler>&	samplers)
{
	vector<SharedPtrVkDescriptorLayout> layouts;

	for (size_t layoutNdx = 0; layoutNdx < samplers.size(); layoutNdx++)
	{
		const VkDescriptorSetLayoutBinding		bindings	=
		{
				0u,											// uint32_t				binding
				VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	// VkDescriptorType		descriptorType
				1u,											// uint32_t				descriptorCount
				VK_SHADER_STAGE_FRAGMENT_BIT,				// VkShaderStageFlags	stageFlags
				&**samplers[layoutNdx]						// const VkSampler*		pImmutableSamplers
		};

		const VkDescriptorSetLayoutCreateInfo	createInfo	=
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType						sType
			DE_NULL,												// const void*							pNext
			0u,														// VkDescriptorSetLayoutCreateFlags		flags
			1u,														// uint32_t								bindingCount
			&bindings												// const VkDescriptorSetLayoutBinding*	pBindings
		};

		layouts.push_back(makeSharedPtr(createDescriptorSetLayout(vkd, device, &createInfo)));
	}

	return layouts;
}

vector<SharedPtrVkDescriptorPool> createDescriptorPools (const DeviceInterface&					vkd,
														 VkDevice								device,
														 vector<SharedPtrVkDescriptorLayout>&	layouts,
														 VkDescriptorType						type)
{
	vector<SharedPtrVkDescriptorPool> descriptorPools;

	for (size_t poolNdx = 0; poolNdx < layouts.size(); poolNdx++)
	{
		const VkDescriptorPoolSize			size		=
		{
			type,	// VkDescriptorType		type
			1u		// uint32_t				descriptorCount
		};

		const VkDescriptorPoolCreateInfo	createInfo	=
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,		// VkStructureType				sType
			DE_NULL,											// const void*					pNext
			VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,	// VkDescriptorPoolCreateFlags	flags
			1u,													// uint32_t						maxSets
			1u,													// uint32_t						poolSizeCount
			&size												// const VkDescriptorPoolSize*	pPoolSizes
		};

		descriptorPools.push_back(makeSharedPtr(createDescriptorPool(vkd, device, &createInfo)));
	}

	return descriptorPools;
}

struct ExternalTestConfig
{
	ExternalTestConfig	(VkFormat				format_,
						 UVec2					imageSize_,
						 vector<RenderPass>		renderPasses_,
						 RenderPassType			renderPassType_,
						 SynchronizationType	synchronizationType_,
						 deUint32				blurKernel_ = 4)
		: format				(format_)
		, imageSize				(imageSize_)
		, renderPasses			(renderPasses_)
		, renderPassType		(renderPassType_)
		, synchronizationType	(synchronizationType_)
		, blurKernel			(blurKernel_)
	{
	}

	VkFormat			format;
	UVec2				imageSize;
	vector<RenderPass>	renderPasses;
	RenderPassType		renderPassType;
	SynchronizationType	synchronizationType;
	deUint32			blurKernel;
};

class ExternalDependencyTestInstance : public TestInstance
{
public:
											ExternalDependencyTestInstance	(Context& context, ExternalTestConfig testConfig);
											~ExternalDependencyTestInstance	(void);

	vector<SharedPtrVkImage>				createAndAllocateImages			(const DeviceInterface&					vk,
																			 VkDevice								device,
																			 Allocator&								allocator,
																			 vector<de::SharedPtr<Allocation> >&	imageMemories,
																			 deUint32								universalQueueFamilyIndex,
																			 VkFormat								format,
																			 deUint32								width,
																			 deUint32								height,
																			 vector<RenderPass>						renderPasses);

	vector<SharedPtrVkSampler>				createSamplers					(const DeviceInterface&					vkd,
																			 const VkDevice							device,
																			 vector<RenderPass>&					renderPasses);

	vector<SharedPtrVkRenderPass>			createRenderPasses				(const DeviceInterface&					vkd,
																			 VkDevice								device,
																			 vector<RenderPass>						renderPassInfos,
																			 const RenderPassType					renderPassType,
																			 const SynchronizationType				synchronizationType);

	vector<SharedPtrVkFramebuffer>			createFramebuffers				(const DeviceInterface&					vkd,
																			 VkDevice								device,
																			 vector<SharedPtrVkRenderPass>&			renderPasses,
																			 vector<SharedPtrVkImageView>&			dstImageViews,
																			 deUint32								width,
																			 deUint32								height);

	vector<SharedPtrVkPipelineLayout>		createRenderPipelineLayouts		(const DeviceInterface&					vkd,
																			 VkDevice								device,
																			 vector<SharedPtrVkRenderPass>&			renderPasses,
																			 vector<SharedPtrVkDescriptorLayout>&	descriptorSetLayouts);

	vector<SharedPtrVkPipeline>				createRenderPipelines			(const DeviceInterface&					vkd,
																			 VkDevice								device,
																			 vector<SharedPtrVkRenderPass>&			renderPasses,
																			 vector<SharedPtrVkPipelineLayout>&		pipelineLayouts,
																			 const BinaryCollection&				binaryCollection,
																			 deUint32								width,
																			 deUint32								height);

	vector<SharedPtrVkDescriptorSet>		createDescriptorSets			(const DeviceInterface&					vkd,
																			 VkDevice								device,
																			 vector<SharedPtrVkDescriptorPool>&		pools,
																			 vector<SharedPtrVkDescriptorLayout>&	layouts,
																			 vector<SharedPtrVkImageView>&			imageViews,
																			 vector<SharedPtrVkSampler>&			samplers);

	tcu::TestStatus							iterate							(void);

	template<typename RenderpassSubpass>
	tcu::TestStatus							iterateInternal					(void);

private:
	const bool								m_renderPass2Supported;
	const bool								m_synchronization2Supported;
	const RenderPassType					m_renderPassType;

	const deUint32							m_width;
	const deUint32							m_height;
	const deUint32							m_blurKernel;
	const VkFormat							m_format;

	vector<de::SharedPtr<Allocation> >		m_imageMemories;
	vector<SharedPtrVkImage>				m_images;
	vector<SharedPtrVkImageView>			m_imageViews;
	vector<SharedPtrVkSampler>				m_samplers;

	const Unique<VkBuffer>					m_dstBuffer;
	const de::UniquePtr<Allocation>			m_dstBufferMemory;

	vector<SharedPtrVkRenderPass>			m_renderPasses;
	vector<SharedPtrVkFramebuffer>			m_framebuffers;

	vector<SharedPtrVkDescriptorLayout>		m_subpassDescriptorSetLayouts;
	vector<SharedPtrVkDescriptorPool>		m_subpassDescriptorPools;
	vector<SharedPtrVkDescriptorSet>		m_subpassDescriptorSets;

	vector<SharedPtrVkPipelineLayout>		m_renderPipelineLayouts;
	vector<SharedPtrVkPipeline>				m_renderPipelines;

	const Unique<VkCommandPool>				m_commandPool;
	tcu::ResultCollector					m_resultCollector;
};

ExternalDependencyTestInstance::ExternalDependencyTestInstance (Context& context, ExternalTestConfig testConfig)
	: TestInstance					(context)
	, m_renderPass2Supported		((testConfig.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
	, m_synchronization2Supported	((testConfig.synchronizationType == SYNCHRONIZATION_TYPE_SYNCHRONIZATION2) && context.requireDeviceFunctionality("VK_KHR_synchronization2"))
	, m_renderPassType				(testConfig.renderPassType)
	, m_width						(testConfig.imageSize.x())
	, m_height						(testConfig.imageSize.y())
	, m_blurKernel					(testConfig.blurKernel)
	, m_format						(testConfig.format)
	, m_images						(createAndAllocateImages(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_imageMemories, context.getUniversalQueueFamilyIndex(), m_format, m_width, m_height, testConfig.renderPasses))
	, m_imageViews					(createImageViews(context.getDeviceInterface(), context.getDevice(), m_images, m_format, VK_IMAGE_ASPECT_COLOR_BIT))
	, m_samplers					(createSamplers(context.getDeviceInterface(), context.getDevice(), testConfig.renderPasses))
	, m_dstBuffer					(createBuffer(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height))
	, m_dstBufferMemory				(createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_dstBuffer))
	, m_renderPasses				(createRenderPasses(context.getDeviceInterface(), context.getDevice(), testConfig.renderPasses, testConfig.renderPassType, testConfig.synchronizationType))
	, m_framebuffers				(createFramebuffers(context.getDeviceInterface(), context.getDevice(), m_renderPasses, m_imageViews, m_width, m_height))
	, m_subpassDescriptorSetLayouts	(createDescriptorSetLayouts(context.getDeviceInterface(), context.getDevice(), m_samplers))
	, m_subpassDescriptorPools		(createDescriptorPools(context.getDeviceInterface(), context.getDevice(), m_subpassDescriptorSetLayouts, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER))
	, m_subpassDescriptorSets		(createDescriptorSets(context.getDeviceInterface(), context.getDevice(), m_subpassDescriptorPools, m_subpassDescriptorSetLayouts, m_imageViews, m_samplers))
	, m_renderPipelineLayouts		(createRenderPipelineLayouts(context.getDeviceInterface(), context.getDevice(), m_renderPasses, m_subpassDescriptorSetLayouts))
	, m_renderPipelines				(createRenderPipelines(context.getDeviceInterface(), context.getDevice(), m_renderPasses, m_renderPipelineLayouts, context.getBinaryCollection(), m_width, m_height))
	, m_commandPool					(createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
{
}

ExternalDependencyTestInstance::~ExternalDependencyTestInstance (void)
{
}

vector<SharedPtrVkImage> ExternalDependencyTestInstance::createAndAllocateImages (const DeviceInterface&				vk,
																				  VkDevice								device,
																				  Allocator&							allocator,
																				  vector<de::SharedPtr<Allocation> >&	imageMemories,
																				  deUint32								universalQueueFamilyIndex,
																				  VkFormat								format,
																				  deUint32								width,
																				  deUint32								height,
																				  vector<RenderPass>					renderPasses)
{
	vector<SharedPtrVkImage> images;

	for (size_t imageNdx = 0; imageNdx < renderPasses.size(); imageNdx++)
	{
		const VkExtent3D		imageExtent		=
		{
			width,		// uint32_t		width
			height,		// uint32_t		height
			1u			// uint32_t		depth
		};

		const VkImageCreateInfo	imageCreateInfo	=
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
			DE_NULL,								// const void*				pNext
			0u,										// VkImageCreateFlags		flags
			VK_IMAGE_TYPE_2D,						// VkImageType				imageType
			format,									// VkFormat					format
			imageExtent,							// VkExtent3D				extent
			1u,										// uint32_t					mipLevels
			1u,										// uint32_t					arrayLayers
			VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
				| VK_IMAGE_USAGE_SAMPLED_BIT
				| VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
			1u,										// uint32_t					queueFamilyIndexCount
			&universalQueueFamilyIndex,				// const uint32_t*			pQueueFamilyIndices
			VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
		};

		images.push_back(makeSharedPtr(vk::createImage(vk, device, &imageCreateInfo, DE_NULL)));
		imageMemories.push_back((de::SharedPtr<Allocation>)allocator.allocate(getImageMemoryRequirements(vk, device, **images[imageNdx]), MemoryRequirement::Any).release());
		VK_CHECK(vk.bindImageMemory(device, **images[imageNdx], imageMemories[imageNdx]->getMemory(), imageMemories[imageNdx]->getOffset()));
	}

	return images;
}

vector<SharedPtrVkSampler> ExternalDependencyTestInstance::createSamplers (const DeviceInterface&	vkd,
																		   const VkDevice			device,
																		   vector<RenderPass>&		renderPasses)
{
	vector<SharedPtrVkSampler> samplers;

	for (size_t samplerNdx = 0; samplerNdx < renderPasses.size() - 1; samplerNdx++)
	{
		const VkSamplerCreateInfo samplerInfo =
		{
			VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,		// VkStructureType			sType
			DE_NULL,									// const void*				pNext
			0u,											// VkSamplerCreateFlags		flags
			VK_FILTER_NEAREST,							// VkFilter					magFilter
			VK_FILTER_NEAREST,							// VkFilter					minFilter
			VK_SAMPLER_MIPMAP_MODE_NEAREST,				// VkSamplerMipmapMode		mipmapMode
			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeU
			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeV
			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeW
			0.0f,										// float					mipLodBias
			VK_FALSE,									// VkBool32					anisotropyEnable
			1.0f,										// float					maxAnisotropy
			VK_FALSE,									// VkBool32					compareEnable
			VK_COMPARE_OP_ALWAYS,						// VkCompareOp				compareOp
			0.0f,										// float					minLod
			0.0f,										// float					maxLod
			VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,	// VkBorderColor			borderColor
			VK_FALSE,									// VkBool32					unnormalizedCoordinates
		};

		samplers.push_back(makeSharedPtr(createSampler(vkd, device, &samplerInfo)));
	}

	return samplers;
}

vector<SharedPtrVkRenderPass> ExternalDependencyTestInstance::createRenderPasses (const DeviceInterface&	vkd,
																				  VkDevice					device,
																				  vector<RenderPass>		renderPassInfos,
																				  const RenderPassType		renderPassType,
																				  const SynchronizationType	synchronizationType)
{
	vector<SharedPtrVkRenderPass> renderPasses;
	renderPasses.reserve(renderPassInfos.size());

	for (const auto& renderPassInfo : renderPassInfos)
		renderPasses.push_back(makeSharedPtr(createRenderPass(vkd, device, renderPassInfo, renderPassType, synchronizationType)));

	return renderPasses;
}

vector<SharedPtrVkFramebuffer> ExternalDependencyTestInstance::createFramebuffers (const DeviceInterface&			vkd,
																				   VkDevice							device,
																				   vector<SharedPtrVkRenderPass>&	renderPasses,
																				   vector<SharedPtrVkImageView>&	dstImageViews,
																				   deUint32							width,
																				   deUint32							height)
{
	vector<SharedPtrVkFramebuffer> framebuffers;

	for (size_t renderPassNdx = 0; renderPassNdx < renderPasses.size(); renderPassNdx++)
	{
		VkRenderPass renderPass (**renderPasses[renderPassNdx]);

		const VkFramebufferCreateInfo createInfo =
		{
			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType
			DE_NULL,									// const void*				pNext
			0u,											// VkFramebufferCreateFlags	flags
			renderPass,									// VkRenderPass				renderPass
			1u,											// uint32_t					attachmentCount
			&**dstImageViews[renderPassNdx],			// const VkImageView*		pAttachments
			width,										// uint32_t					width
			height,										// uint32_t					height
			1u											// uint32_t					layers
		};

		framebuffers.push_back(makeSharedPtr(createFramebuffer(vkd, device, &createInfo)));
	}

	return framebuffers;
}

vector<SharedPtrVkDescriptorSet> ExternalDependencyTestInstance::createDescriptorSets (const DeviceInterface&				vkd,
																					   VkDevice								device,
																					   vector<SharedPtrVkDescriptorPool>&	pools,
																					   vector<SharedPtrVkDescriptorLayout>&	layouts,
																					   vector<SharedPtrVkImageView>&		imageViews,
																					   vector<SharedPtrVkSampler>&			samplers)
{
	vector<SharedPtrVkDescriptorSet> descriptorSets;

	for (size_t setNdx = 0; setNdx < layouts.size(); setNdx++)
	{
		const VkDescriptorSetAllocateInfo allocateInfo =
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,	// VkStructureType					sType
			DE_NULL,										// const void*						pNext
			**pools[setNdx],								// VkDescriptorPool					descriptorPool
			1u,												// uint32_t							descriptorSetCount
			&**layouts[setNdx]								// const VkDescriptorSetLayout*		pSetLayouts
		};

		descriptorSets.push_back(makeSharedPtr(allocateDescriptorSet(vkd, device, &allocateInfo)));

		{
			const VkDescriptorImageInfo	imageInfo	=
			{
				**samplers[setNdx],							// VkSampler		sampler
				**imageViews[setNdx],						// VkImageView		imageView
				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL	// VkImageLayout	imageLayout
			};

			const VkWriteDescriptorSet	write		=
			{
				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,		// VkStructureType					sType
				DE_NULL,									// const void*						pNext
				**descriptorSets[setNdx],					// VkDescriptorSet					dstSet
				0u,											// uint32_t							dstBinding
				0u,											// uint32_t							dstArrayElement
				1u,											// uint32_t							descriptorCount
				VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	// VkDescriptorType					descriptorType
				&imageInfo,									// const VkDescriptorImageInfo*		pImageInfo
				DE_NULL,									// const VkDescriptorBufferInfo*	pBufferInfo
				DE_NULL										// const VkBufferView*				pTexelBufferView
			};

			vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
		}
	}

	return descriptorSets;
}

vector<SharedPtrVkPipelineLayout> ExternalDependencyTestInstance::createRenderPipelineLayouts (const DeviceInterface&				vkd,
																							   VkDevice								device,
																							   vector<SharedPtrVkRenderPass>&		renderPasses,
																							   vector<SharedPtrVkDescriptorLayout>&	descriptorSetLayouts)
{
	vector<SharedPtrVkPipelineLayout> pipelineLayouts;

	for (size_t renderPassNdx = 0; renderPassNdx < renderPasses.size(); renderPassNdx++)
	{
		const VkPipelineLayoutCreateInfo createInfo =
		{
			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,								// VkStructureType				sType
			DE_NULL,																	// const void*					pNext
			(vk::VkPipelineLayoutCreateFlags)0,											// VkPipelineLayoutCreateFlags	flags
			renderPassNdx > 0 ? 1u : 0u,												// deUint32						setLayoutCount
			renderPassNdx > 0 ? &**descriptorSetLayouts[renderPassNdx - 1] : DE_NULL,	// const VkDescriptorSetLayout*	pSetLayouts
			0u,																			// deUint32						pushConstantRangeCount
			DE_NULL																		// const VkPushConstantRange*	pPushConstantRanges
		};

		pipelineLayouts.push_back(makeSharedPtr(createPipelineLayout(vkd, device, &createInfo)));
	}

	return pipelineLayouts;
}

vector<SharedPtrVkPipeline> ExternalDependencyTestInstance::createRenderPipelines (const DeviceInterface&				vkd,
																				   VkDevice								device,
																				   vector<SharedPtrVkRenderPass>&		renderPasses,
																				   vector<SharedPtrVkPipelineLayout>&	pipelineLayouts,
																				   const BinaryCollection&				binaryCollection,
																				   deUint32								width,
																				   deUint32								height)
{
	vector<SharedPtrVkPipeline> pipelines;

	for (size_t renderPassNdx = 0; renderPassNdx < renderPasses.size(); renderPassNdx++)
	{
		const Unique<VkShaderModule>					vertexShaderModule		(createShaderModule(vkd, device, binaryCollection.get("quad-vert-" + de::toString(renderPassNdx)), 0u));
		const Unique<VkShaderModule>					fragmentShaderModule	(createShaderModule(vkd, device, binaryCollection.get("quad-frag-" + de::toString(renderPassNdx)), 0u));

		const VkPipelineVertexInputStateCreateInfo		vertexInputState		=
		{
			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType
			DE_NULL,													// const void*								pNext
			(VkPipelineVertexInputStateCreateFlags)0u,					// VkPipelineVertexInputStateCreateFlags	flags
			0u,															// uint32_t									vertexBindingDescriptionCount
			DE_NULL,													// const VkVertexInputBindingDescription*	pVertexBindingDescriptions
			0u,															// uint32_t									vertexAttributeDescriptionCount
			DE_NULL														// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions
		};

		const std::vector<VkViewport>					viewports				(1, makeViewport(tcu::UVec2(width, height)));
		const std::vector<VkRect2D>						scissors				(1, makeRect2D(tcu::UVec2(width, height)));
		const VkRenderPass								renderPass				(**renderPasses[renderPassNdx]);
		const VkPipelineLayout							layout					(**pipelineLayouts[renderPassNdx]);

		pipelines.push_back(makeSharedPtr(makeGraphicsPipeline(vkd,									// const DeviceInterface&						vk
															   device,								// const VkDevice								device
															   layout,								// const VkPipelineLayout						pipelineLayout
															   *vertexShaderModule,					// const VkShaderModule							vertexShaderModule
															   DE_NULL,								// const VkShaderModule							tessellationControlShaderModule
															   DE_NULL,								// const VkShaderModule							tessellationEvalShaderModule
															   DE_NULL,								// const VkShaderModule							geometryShaderModule
															   *fragmentShaderModule,				// const VkShaderModule							fragmentShaderModule
															   renderPass,							// const VkRenderPass							renderPass
															   viewports,							// const std::vector<VkViewport>&				viewports
															   scissors,							// const std::vector<VkRect2D>&					scissors
															   VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology					topology
															   0u,									// const deUint32								subpass
															   0u,									// const deUint32								patchControlPoints
															   &vertexInputState)));				// const VkPipelineVertexInputStateCreateInfo*	vertexInputStateCreateInfo
	}

	return pipelines;
}

tcu::TestStatus ExternalDependencyTestInstance::iterate (void)
{
	switch (m_renderPassType)
	{
		case RENDERPASS_TYPE_LEGACY:
			return iterateInternal<RenderpassSubpass1>();
		case RENDERPASS_TYPE_RENDERPASS2:
			return iterateInternal<RenderpassSubpass2>();
		default:
			TCU_THROW(InternalError, "Impossible");
	}
}

template<typename RenderpassSubpass>
tcu::TestStatus ExternalDependencyTestInstance::iterateInternal (void)
{
	const DeviceInterface&								vkd					(m_context.getDeviceInterface());
	const Unique<VkCommandBuffer>						commandBuffer		(allocateCommandBuffer(vkd, m_context.getDevice(), *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
	const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo	(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo		(DE_NULL);

	beginCommandBuffer(vkd, *commandBuffer);

	for (size_t renderPassNdx = 0; renderPassNdx < m_renderPasses.size(); renderPassNdx++)
	{
		// Begin render pass
		{
			VkRect2D renderArea =
			{
				{ 0u, 0u },				// VkOffset2D	offset
				{ m_width, m_height }	// VkExtent2D	extent
			};

			const VkRenderPassBeginInfo beginInfo =
			{
				VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType
				DE_NULL,									// const void*			pNext
				**m_renderPasses[renderPassNdx],			// VkRenderPass			renderPass
				**m_framebuffers[renderPassNdx],			// VkFramebuffer		framebuffer
				renderArea,									// VkRect2D				renderArea
				0u,											// uint32_t				clearValueCount
				DE_NULL										// const VkClearValue*	pClearValues
			};

			RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
		}

		vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_renderPipelines[renderPassNdx]);

		// Use results from the previous pass as input texture
		if (renderPassNdx > 0)
			vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_renderPipelineLayouts[renderPassNdx], 0, 1, &**m_subpassDescriptorSets[renderPassNdx - 1], 0, DE_NULL);

		vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);

		RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
	}

	// Memory barrier between rendering and copy
	{
		VkImageSubresourceRange		imageSubresourceRange	=
		{
			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask
			0u,							// uint32_t				baseMipLevel
			1u,							// uint32_t				levelCount
			0u,							// uint32_t				baseArrayLayer
			1u							// uint32_t				layerCount
		};

		const VkImageMemoryBarrier	barrier					=
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType
			DE_NULL,									// const void*				pNext
			0,											// VkAccessFlags			srcAccessMask
			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask
			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,	// VkImageLayout			oldLayout
			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout
			VK_QUEUE_FAMILY_IGNORED,					// uint32_t					srcQueueFamilyIndex
			VK_QUEUE_FAMILY_IGNORED,					// uint32_t					dstQueueFamilyIndex
			**m_images[m_renderPasses.size() - 1],		// VkImage					image
			imageSubresourceRange						// VkImageSubresourceRange	subresourceRange
		};
		// Since the implicit 'end' subpass dependency has VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT in its dstStageMask,
		// we can't form an execution dependency chain with a specific pipeline stage. The cases that provide an explict
		// 'end' subpass dependency could use a specific pipline stage, but there isn't a way to distinguish between the
		// implicit and explicit cases here.
		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
	}

	// Copy image memory to buffer
	{
		const VkImageSubresourceLayers imageSubresourceLayers =
		{
			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask
			0u,							// deUint32				mipLevel
			0u,							// deUint32				baseArrayLayer
			1u							// deUint32				layerCount
		};

		const VkBufferImageCopy region =
		{
			0u,							// VkDeviceSize				bufferOffset
			0u,							// uint32_t					bufferRowLength
			0u,							// uint32_t					bufferImageHeight
			imageSubresourceLayers,		// VkImageSubresourceLayers	imageSubresource
			{ 0u, 0u, 0u },				// VkOffset3D				imageOffset
			{ m_width, m_height, 1u }	// VkExtent3D				imageExtent
		};

		vkd.cmdCopyImageToBuffer(*commandBuffer, **m_images[m_renderPasses.size() - 1], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_dstBuffer, 1u, &region);
	}

	// Memory barrier between copy and host access
	{
		const VkBufferMemoryBarrier barrier =
		{
			VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType
			DE_NULL,									// const void*		pNext
			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask
			VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask
			VK_QUEUE_FAMILY_IGNORED,					// uint32_t			srcQueueFamilyIndex
			VK_QUEUE_FAMILY_IGNORED,					// uint32_t			dstQueueFamilyIndex
			*m_dstBuffer,								// VkBuffer			buffer
			0u,											// VkDeviceSize		offset
			VK_WHOLE_SIZE								// VkDeviceSize		size
		};

		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
	}

	endCommandBuffer(vkd, *commandBuffer);
	submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
	invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_dstBufferMemory->getMemory(), m_dstBufferMemory->getOffset(), VK_WHOLE_SIZE);

	{
		const tcu::TextureFormat			format		(mapVkFormat(m_format));
		const void* const					ptr			(m_dstBufferMemory->getHostPtr());
		const tcu::ConstPixelBufferAccess	access		(format, m_width, m_height, 1, ptr);
		tcu::TextureLevel					reference	(format, m_width, m_height);
		tcu::TextureLevel					textureA	(format, m_width, m_height);
		tcu::TextureLevel					textureB	(format, m_width, m_height);

		for (deUint32 renderPassNdx = 0; renderPassNdx < m_renderPasses.size(); renderPassNdx++)
		{
			// First pass renders four quads of different color, which will be blurred in the following passes
			if (renderPassNdx == 0)
			{
				for (deUint32 y = 0; y < m_height; y++)
				for (deUint32 x = 0; x < m_width; x++)
				{
					if (x <= (m_width - 1) / 2 && y <= (m_height - 1) / 2)
						textureA.getAccess().setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
					else if (x > (m_width - 1) / 2 && y <= (m_height - 1) / 2)
						textureA.getAccess().setPixel(Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
					else if (x <= (m_width - 1) / 2 && y > (m_height - 1) / 2)
						textureA.getAccess().setPixel(Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
					else
						textureA.getAccess().setPixel(Vec4(0.0f, 0.0f, 0.0f, 1.0f), x, y);
				}
			}
			// Blur previous pass
			else
			{
				for (deUint32 y = 0; y < m_height; y++)
				for (deUint32 x = 0; x < m_width; x++)
				{
					Vec4 blurColor (Vec4(0.0));

					for (deUint32 sampleNdx = 0; sampleNdx < (m_blurKernel + 1); sampleNdx++)
					{
						if (renderPassNdx % 2 == 0)
						{
							// Do a horizontal blur
							blurColor += 0.12f * textureB.getAccess().getPixel(deClamp32((deInt32)x - (m_blurKernel / 2) + sampleNdx, 0u, m_width - 1u), y);
						}
						else
						{
							// Do a vertical blur
							blurColor += 0.12f * textureA.getAccess().getPixel(x, deClamp32((deInt32)y - (m_blurKernel / 2) + sampleNdx, 0u, m_height - 1u));
						}
					}

					renderPassNdx % 2 == 0 ? textureA.getAccess().setPixel(blurColor, x, y) : textureB.getAccess().setPixel(blurColor, x, y);
				}
			}
		}

		reference = m_renderPasses.size() % 2 == 0 ? textureB : textureA;

		{
			// Allow error of 4 times the minimum presentable difference
			const Vec4 threshold (4.0f * 1.0f / ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>()) - 1u).cast<float>());

			if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "", "", reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
				m_resultCollector.fail("Compare failed.");
		}
	}

	return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
}

struct SubpassTestConfig
{
		SubpassTestConfig	(VkFormat		format_,
							 UVec2			imageSize_,
							 RenderPass		renderPass_,
							 RenderPassType	renderPassType_)
		: format			(format_)
		, imageSize			(imageSize_)
		, renderPass		(renderPass_)
		, renderPassType	(renderPassType_)
	{
	}

	VkFormat			format;
	UVec2				imageSize;
	RenderPass			renderPass;
	RenderPassType		renderPassType;
};

class SubpassDependencyTestInstance : public TestInstance
{
public:
										SubpassDependencyTestInstance	(Context&								context,
																		 SubpassTestConfig						testConfig);

										~SubpassDependencyTestInstance	(void);

	vector<SharedPtrVkImage>			createAndAllocateImages			(const DeviceInterface&					vk,
																		 VkDevice								device,
																		 Allocator&								allocator,
																		 vector<de::SharedPtr<Allocation> >&	imageMemories,
																		 deUint32								universalQueueFamilyIndex,
																		 RenderPass								renderPassInfo,
																		 VkFormat								format,
																		 deUint32								width,
																		 deUint32								height);

	vector<SharedPtrVkPipelineLayout>	createRenderPipelineLayouts		(const DeviceInterface&					vkd,
																		 VkDevice								device,
																		 RenderPass								renderPassInfo,
																		 vector<SharedPtrVkDescriptorLayout>	descriptorSetLayouts);

	vector<SharedPtrVkPipeline>			createRenderPipelines			(const DeviceInterface&					vkd,
																		 VkDevice								device,
																		 RenderPass								renderPassInfo,
																		 VkRenderPass							renderPass,
																		 vector<SharedPtrVkPipelineLayout>&		pipelineLayouts,
																		 const BinaryCollection&				binaryCollection,
																		 VkFormat								format,
																		 deUint32								width,
																		 deUint32								height);

	Move<VkFramebuffer>					createFramebuffer				(const DeviceInterface&					vkd,
																		 VkDevice								device,
																		 RenderPass								renderPassInfo,
																		 VkRenderPass							renderPass,
																		 vector<SharedPtrVkImageView>&			dstImageViews,
																		 deUint32								width,
																		 deUint32								height);

	vector<SharedPtrVkDescriptorLayout>	createDescriptorSetLayouts		(const DeviceInterface&					vkd,
																		 VkDevice								device,
																		 RenderPass								renderPassInfo);

	vector<SharedPtrVkDescriptorSet>	createDescriptorSets			(const DeviceInterface&					vkd,
																		 VkDevice								device,
																		 VkFormat								format,
																		 vector<SharedPtrVkDescriptorPool>&		pools,
																		 vector<SharedPtrVkDescriptorLayout>&	layouts,
																		 vector<SharedPtrVkImageView>&			imageViews);

	tcu::TestStatus						iterate							(void);

	template<typename RenderpassSubpass>
	tcu::TestStatus						iterateInternal					(void);

private:
	const bool							m_extensionSupported;
	const RenderPass					m_renderPassInfo;
	const RenderPassType				m_renderPassType;

	const deUint32						m_width;
	const deUint32						m_height;
	const VkFormat						m_format;

	vector<de::SharedPtr<Allocation> >	m_imageMemories;
	vector<SharedPtrVkImage>			m_images;
	vector<SharedPtrVkImageView>		m_imageViews;

	const Unique<VkBuffer>				m_primaryBuffer;
	const Unique<VkBuffer>				m_secondaryBuffer;
	const de::UniquePtr<Allocation>		m_primaryBufferMemory;
	const de::UniquePtr<Allocation>		m_secondaryBufferMemory;

	const Unique<VkRenderPass>			m_renderPass;
	const Unique<VkFramebuffer>			m_framebuffer;

	vector<SharedPtrVkDescriptorLayout>	m_subpassDescriptorSetLayouts;
	vector<SharedPtrVkDescriptorPool>	m_subpassDescriptorPools;
	vector<SharedPtrVkDescriptorSet>	m_subpassDescriptorSets;

	vector<SharedPtrVkPipelineLayout>	m_renderPipelineLayouts;
	vector<SharedPtrVkPipeline>			m_renderPipelines;

	const Unique<VkCommandPool>			m_commandPool;
	tcu::ResultCollector				m_resultCollector;
};

SubpassDependencyTestInstance::SubpassDependencyTestInstance (Context& context, SubpassTestConfig testConfig)
	: TestInstance					(context)
	, m_extensionSupported			((testConfig.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
	, m_renderPassInfo				(testConfig.renderPass)
	, m_renderPassType				(testConfig.renderPassType)
	, m_width						(testConfig.imageSize.x())
	, m_height						(testConfig.imageSize.y())
	, m_format						(testConfig.format)
	, m_images						(createAndAllocateImages(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_imageMemories, context.getUniversalQueueFamilyIndex(), m_renderPassInfo, m_format, m_width, m_height))
	, m_imageViews					(createImageViews(context.getDeviceInterface(), context.getDevice(), m_images, m_format, isDepthStencilFormat(m_format) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT))
	, m_primaryBuffer				(createBuffer(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height))
	, m_secondaryBuffer				(createBuffer(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height))
	, m_primaryBufferMemory			(createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_primaryBuffer))
	, m_secondaryBufferMemory		(createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_secondaryBuffer))
	, m_renderPass					(createRenderPass(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo, testConfig.renderPassType))
	, m_framebuffer					(createFramebuffer(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo, *m_renderPass, m_imageViews, m_width, m_height))
	, m_subpassDescriptorSetLayouts	(createDescriptorSetLayouts(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo))
	, m_subpassDescriptorPools		(createDescriptorPools(context.getDeviceInterface(), context.getDevice(), m_subpassDescriptorSetLayouts, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT))
	, m_subpassDescriptorSets		(createDescriptorSets(context.getDeviceInterface(), context.getDevice(), m_format, m_subpassDescriptorPools, m_subpassDescriptorSetLayouts, m_imageViews))
	, m_renderPipelineLayouts		(createRenderPipelineLayouts(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo, m_subpassDescriptorSetLayouts))
	, m_renderPipelines				(createRenderPipelines(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo, *m_renderPass, m_renderPipelineLayouts, context.getBinaryCollection(), m_format, m_width, m_height))
	, m_commandPool					(createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
{
}

SubpassDependencyTestInstance::~SubpassDependencyTestInstance (void)
{
}

vector<SharedPtrVkImage> SubpassDependencyTestInstance::createAndAllocateImages (const DeviceInterface&					vk,
																				 VkDevice								device,
																				 Allocator&								allocator,
																				 vector<de::SharedPtr<Allocation> >&	imageMemories,
																				 deUint32								universalQueueFamilyIndex,
																				 RenderPass								renderPassInfo,
																				 VkFormat								format,
																				 deUint32								width,
																				 deUint32								height)
{
	// Verify format support
	{
		const VkFormatFeatureFlags	flags		= isDepthStencilFormat(m_format) ? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
		const VkFormatProperties	properties	= vk::getPhysicalDeviceFormatProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), format);

		if ((properties.optimalTilingFeatures & flags) != flags)
			TCU_THROW(NotSupportedError, "Format not supported");
	}

	vector<SharedPtrVkImage> images;

	for (size_t imageNdx = 0; imageNdx < renderPassInfo.getAttachments().size(); imageNdx++)
	{
		const VkExtent3D		imageExtent		=
		{
			width,		// uint32_t	width
			height,		// uint32_t	height
			1u			// uint32_t	depth
		};

		VkImageUsageFlags		usage			= ((isDepthStencilFormat(format)
													? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
													: VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
													| VK_IMAGE_USAGE_TRANSFER_SRC_BIT
													| VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);

		const VkImageCreateInfo	imageCreateInfo	=
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
			DE_NULL,								// const void*				pNext
			0u,										// VkImageCreateFlags		flags
			VK_IMAGE_TYPE_2D,						// VkImageType				imageType
			format,									// VkFormat					format
			imageExtent,							// VkExtent3D				extent
			1u,										// uint32_t					mipLevels
			1u,										// uint32_t					arrayLayers
			VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
			usage,									// VkImageUsageFlags		usage
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
			1u,										// uint32_t					queueFamilyIndexCount
			&universalQueueFamilyIndex,				// const uint32_t*			pQueueFamilyIndices
			VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
		};

		images.push_back(makeSharedPtr(vk::createImage(vk, device, &imageCreateInfo, DE_NULL)));
		imageMemories.push_back((de::SharedPtr<Allocation>)allocator.allocate(getImageMemoryRequirements(vk, device, **images[imageNdx]), MemoryRequirement::Any).release());
		VK_CHECK(vk.bindImageMemory(device, **images[imageNdx], imageMemories[imageNdx]->getMemory(), imageMemories[imageNdx]->getOffset()));
	}

	return images;
}

vector<SharedPtrVkPipelineLayout> SubpassDependencyTestInstance::createRenderPipelineLayouts (const DeviceInterface&				vkd,
																							  VkDevice								device,
																							  RenderPass							renderPassInfo,
																							  vector<SharedPtrVkDescriptorLayout>	descriptorSetLayouts)
{
	vector<SharedPtrVkPipelineLayout>	pipelineLayouts;
	vector<VkDescriptorSetLayout>		descriptorSetLayoutHandles;
	const size_t						descriptorSetLayoutCount	= descriptorSetLayouts.size();

	for (size_t descriptorSetLayoutNdx = 0; descriptorSetLayoutNdx < descriptorSetLayoutCount; descriptorSetLayoutNdx++)
		descriptorSetLayoutHandles.push_back(**descriptorSetLayouts.at(descriptorSetLayoutNdx));

	for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
	{
		const VkPipelineLayoutCreateInfo createInfo =
		{
			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType
			DE_NULL,										// const void*					pNext
			(vk::VkPipelineLayoutCreateFlags)0,				// VkPipelineLayoutCreateFlags	flags
			(deUint32)descriptorSetLayoutCount,				// deUint32						setLayoutCount
			descriptorSetLayoutHandles.data(),				// const VkDescriptorSetLayout*	pSetLayouts
			0u,												// deUint32						pushConstantRangeCount
			DE_NULL											// const VkPushConstantRange*	pPushConstantRanges
		};

		pipelineLayouts.push_back(makeSharedPtr(createPipelineLayout(vkd, device, &createInfo)));
	}

	return pipelineLayouts;
}

vector<SharedPtrVkPipeline> SubpassDependencyTestInstance::createRenderPipelines (const DeviceInterface&				vkd,
																				  VkDevice								device,
																				  RenderPass							renderPassInfo,
																				  VkRenderPass							renderPass,
																				  vector<SharedPtrVkPipelineLayout>&	pipelineLayouts,
																				  const BinaryCollection&				binaryCollection,
																				  VkFormat								format,
																				  deUint32								width,
																				  deUint32								height)
{
	vector<SharedPtrVkPipeline> pipelines;

	for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
	{
		const Unique<VkShaderModule>				vertexShaderModule			(createShaderModule(vkd, device, binaryCollection.get("subpass-vert-" + de::toString(subpassNdx)), 0u));
		const Unique<VkShaderModule>				fragmentShaderModule		(createShaderModule(vkd, device, binaryCollection.get("subpass-frag-" + de::toString(subpassNdx)), 0u));

		const VkVertexInputBindingDescription		vertexBinding0				=
		{
			0u,							// deUint32					binding;
			sizeof(Vec4),				// deUint32					strideInBytes;
			VK_VERTEX_INPUT_RATE_VERTEX	// VkVertexInputStepRate	stepRate;
		};

		VkVertexInputAttributeDescription			attr0						=
		{
			0u,								// deUint32	location;
			0u,								// deUint32	binding;
			VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat	format;
			0u								// deUint32	offsetInBytes;
		};

		const VkPipelineVertexInputStateCreateInfo	vertexInputState			=
		{
			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType
			DE_NULL,													// const void*								pNext
			(VkPipelineVertexInputStateCreateFlags)0u,					// VkPipelineVertexInputStateCreateFlags	flags
			1u,															// uint32_t									vertexBindingDescriptionCount
			&vertexBinding0,											// const VkVertexInputBindingDescription*	pVertexBindingDescriptions
			1u,															// uint32_t									vertexAttributeDescriptionCount
			&attr0														// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions
		};

		const VkStencilOpState						stencilOpState				=
		{
			VK_STENCIL_OP_KEEP,		// stencilFailOp
			VK_STENCIL_OP_KEEP,		// stencilPassOp
			VK_STENCIL_OP_KEEP,		// stencilDepthFailOp
			VK_COMPARE_OP_ALWAYS,	// stencilCompareOp
			0x0u,					// stencilCompareMask
			0x0u,					// stencilWriteMask
			0u						// stencilReference
		};

		const VkPipelineDepthStencilStateCreateInfo	depthStencilStateCreateInfo	=
		{
			VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType
			DE_NULL,													// const void*								pNext
			0u,															// VkPipelineDepthStencilStateCreateFlags	flags
			VK_TRUE,													// VkBool32									depthTestEnable
			VK_TRUE,													// VkBool32									depthWriteEnable
			VK_COMPARE_OP_LESS_OR_EQUAL,								// VkCompareOp								depthCompareOp
			VK_FALSE,													// VkBool32									depthBoundsTestEnable
			VK_TRUE,													// VkBool32									stencilTestEnable
			stencilOpState,												// VkStencilOpState							front
			stencilOpState,												// VkStencilOpState							back
			0.0f,														// float									minDepthBounds
			1.0f,														// float									maxDepthBounds
		};

		const std::vector<VkViewport>				viewports					(1, makeViewport(tcu::UVec2(width, height)));
		const std::vector<VkRect2D>					scissors					(1, makeRect2D(tcu::UVec2(width, height)));
		const VkPipelineLayout						layout						(**pipelineLayouts[subpassNdx]);
		const VkPipelineDepthStencilStateCreateInfo	depthStencilCreateInfo		(isDepthStencilFormat(format)
																					? depthStencilStateCreateInfo
																					: VkPipelineDepthStencilStateCreateInfo());

		pipelines.push_back(makeSharedPtr(makeGraphicsPipeline(vkd,									// const DeviceInterface&							vk
															   device,								// const VkDevice									device
															   layout,								// const VkPipelineLayout							pipelineLayout
															   *vertexShaderModule,					// const VkShaderModule								vertexShaderModule
															   DE_NULL,								// const VkShaderModule								tessellationControlShaderModule
															   DE_NULL,								// const VkShaderModule								tessellationEvalShaderModule
															   DE_NULL,								// const VkShaderModule								geometryShaderModule
															   *fragmentShaderModule,				// const VkShaderModule								fragmentShaderModule
															   renderPass,							// const VkRenderPass								renderPass
															   viewports,							// const std::vector<VkViewport>&					viewports
															   scissors,							// const std::vector<VkRect2D>&						scissors
															   VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology						topology
															   (deUint32)subpassNdx,				// const deUint32									subpass
															   0u,									// const deUint32									patchControlPoints
															   &vertexInputState,					// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
															   DE_NULL,								// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
															   DE_NULL,								// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
															   &depthStencilCreateInfo,				// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
															   DE_NULL)));							// const VkPipelineDynamicStateCreateInfo*			pDynamicState
	}

	return pipelines;
}

Move<VkFramebuffer> SubpassDependencyTestInstance::createFramebuffer (const DeviceInterface&		vkd,
																	  VkDevice						device,
																	  RenderPass					renderPassInfo,
																	  VkRenderPass					renderPass,
																	  vector<SharedPtrVkImageView>&	dstImageViews,
																	  deUint32						width,
																	  deUint32						height)
{
	const size_t		attachmentCount		(renderPassInfo.getAttachments().size());
	vector<VkImageView>	attachmentHandles;

	for (deUint32 attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
		attachmentHandles.push_back(**dstImageViews.at(attachmentNdx));

	const VkFramebufferCreateInfo createInfo =
	{
		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType
		DE_NULL,									// const void*				pNext
		0u,											// VkFramebufferCreateFlags	flags
		renderPass,									// VkRenderPass				renderPass
		(deUint32)attachmentCount,					// uint32_t					attachmentCount
		attachmentHandles.data(),					// const VkImageView*		pAttachments
		width,										// uint32_t					width
		height,										// uint32_t					height
		1u											// uint32_t					layers
	};

	return vk::createFramebuffer(vkd, device, &createInfo);
}

vector<SharedPtrVkDescriptorLayout> SubpassDependencyTestInstance::createDescriptorSetLayouts (const DeviceInterface&	vkd,
																							   VkDevice					device,
																							   RenderPass				renderPassInfo)
{
	vector<SharedPtrVkDescriptorLayout> layouts;

	size_t attachmentCount = renderPassInfo.getAttachments().size();

	for (size_t layoutNdx = 0; layoutNdx < attachmentCount - 1; layoutNdx++)
	{
		const VkDescriptorSetLayoutBinding		bindings	=
		{
				0u,										// uint32_t				binding
				VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,	// VkDescriptorType		descriptorType
				1u,										// uint32_t				descriptorCount
				VK_SHADER_STAGE_FRAGMENT_BIT,			// VkShaderStageFlags	stageFlags
				DE_NULL									// const VkSampler*		pImmutableSamplers
		};

		const VkDescriptorSetLayoutCreateInfo	createInfo	=
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType						sType
			DE_NULL,												// const void*							pNext
			0u,														// VkDescriptorSetLayoutCreateFlags		flags
			1u,														// uint32_t								bindingCount
			&bindings												// const VkDescriptorSetLayoutBinding*	pBindings
		};

		layouts.push_back(makeSharedPtr(createDescriptorSetLayout(vkd, device, &createInfo)));
	}

	return layouts;
}

vector<SharedPtrVkDescriptorSet> SubpassDependencyTestInstance::createDescriptorSets (const DeviceInterface&				vkd,
																					  VkDevice								device,
																					  VkFormat								format,
																					  vector<SharedPtrVkDescriptorPool>&	pools,
																					  vector<SharedPtrVkDescriptorLayout>&	layouts,
																					  vector<SharedPtrVkImageView>&			imageViews)
{
	vector<SharedPtrVkDescriptorSet> descriptorSets;

	for (size_t setNdx = 0; setNdx < layouts.size(); setNdx++)
	{
		const VkDescriptorSetAllocateInfo allocateInfo =
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,	// VkStructureType				sType
			DE_NULL,										// const void*					pNext
			**pools[setNdx],								// VkDescriptorPool				descriptorPool
			1u,												// uint32_t						descriptorSetCount
			&**layouts[setNdx]								// const VkDescriptorSetLayout*	pSetLayouts
		};

		descriptorSets.push_back(makeSharedPtr(allocateDescriptorSet(vkd, device, &allocateInfo)));

		{
			VkImageLayout imageLayout				= isDepthStencilFormat(format)
														? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
														: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;

			const VkDescriptorImageInfo	imageInfo	=
			{
				DE_NULL,				// VkSampler		sampler
				**imageViews[setNdx],	// VkImageView		imageView
				imageLayout				// VkImageLayout	imageLayout
			};

			const VkWriteDescriptorSet	write		=
			{
				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType
				DE_NULL,								// const void*						pNext
				**descriptorSets[setNdx],				// VkDescriptorSet					dstSet
				0u,										// uint32_t							dstBinding
				0u,										// uint32_t							dstArrayElement
				1u,										// uint32_t							descriptorCount
				VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,	// VkDescriptorType					descriptorType
				&imageInfo,								// const VkDescriptorImageInfo*		pImageInfo
				DE_NULL,								// const VkDescriptorBufferInfo*	pBufferInfo
				DE_NULL									// const VkBufferView*				pTexelBufferView
			};

			vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
		}
	}

	return descriptorSets;
}

tcu::TestStatus SubpassDependencyTestInstance::iterate (void)
{
	switch (m_renderPassType)
	{
		case RENDERPASS_TYPE_LEGACY:
			return iterateInternal<RenderpassSubpass1>();
		case RENDERPASS_TYPE_RENDERPASS2:
			return iterateInternal<RenderpassSubpass2>();
		default:
			TCU_THROW(InternalError, "Impossible");
	}
}

template<typename RenderpassSubpass>
tcu::TestStatus SubpassDependencyTestInstance::iterateInternal (void)
{
	de::Random											rand					(5);
	const DeviceInterface&								vkd						(m_context.getDeviceInterface());
	const Unique<VkCommandBuffer>						commandBuffer			(allocateCommandBuffer(vkd, m_context.getDevice(), *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
	const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo		(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo			(DE_NULL);
	const size_t										attachmentCount			(m_renderPassInfo.getAttachments().size());
	const size_t										subpassCount			(m_renderPassInfo.getSubpasses().size());
	vector<VkClearValue>								clearValues;
	vector<Vec4>										vertexData;

	beginCommandBuffer(vkd, *commandBuffer);

	// Transition stencil aspects to the final layout directly.
	if (isDepthStencilFormat(m_format))
	{
		const VkImageSubresourceRange imageSubresourceRange =
		{
			VK_IMAGE_ASPECT_STENCIL_BIT,	// VkImageAspectFlags	aspectMask
			0u,								// uint32_t				baseMipLevel
			1u,								// uint32_t				levelCount
			0u,								// uint32_t				baseArrayLayer
			1u								// uint32_t				layerCount
		};

		VkImageMemoryBarrier barrier =
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType			sType
			DE_NULL,											// const void*				pNext
			0u,													// VkAccessFlags			srcAccessMask
			VK_ACCESS_TRANSFER_READ_BIT,						// VkAccessFlags			dstAccessMask
			VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout			oldLayout
			VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,	// VkImageLayout			newLayout
			VK_QUEUE_FAMILY_IGNORED,							// uint32_t					srcQueueFamilyIndex
			VK_QUEUE_FAMILY_IGNORED,							// uint32_t					dstQueueFamilyIndex
			DE_NULL,											// VkImage					image
			imageSubresourceRange								// VkImageSubresourceRange	subresourceRange
		};

		for (deUint32 attachmentNdx = 0; attachmentNdx < attachmentCount; ++attachmentNdx)
		{
			barrier.image = **m_images[attachmentNdx];
			vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
		}
	}

	// Begin render pass
	{
		VkRect2D					renderArea			=
		{
			{ 0u, 0u },				// VkOffset2D	offset
			{ m_width, m_height }	// VkExtent2D	extent
		};

		for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
			clearValues.push_back(isDepthStencilFormat(m_format) ? makeClearValueDepthStencil(1.0f, 255u) : makeClearValueColor(Vec4(1.0f, 0.0f, 0.0f, 1.0f)));

		const VkRenderPassBeginInfo	beginInfo			=
		{
			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType
			DE_NULL,									// const void*			pNext
			*m_renderPass,								// VkRenderPass			renderPass
			*m_framebuffer,								// VkFramebuffer		framebuffer
			renderArea,									// VkRect2D				renderArea
			(deUint32)attachmentCount,					// uint32_t				clearValueCount
			clearValues.data()							// const VkClearValue*	pClearValues
		};

		RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
	}

	// Generate vertices for 128 triangles with pseudorandom positions and depths values
	for (int primitiveNdx = 0; primitiveNdx < 128; primitiveNdx++)
	{
		float primitiveDepth = rand.getFloat();

		for (int vertexNdx = 0; vertexNdx < 3; vertexNdx++)
		{
			float x = 2.0f * rand.getFloat() - 1.0f;
			float y = 2.0f * rand.getFloat() - 1.0f;

			vertexData.push_back(Vec4(x, y, primitiveDepth, 1.0f));
		}
	}

	const size_t										singleVertexDataSize	= sizeof(Vec4);
	const size_t										vertexCount				= vertexData.size();
	const size_t										vertexDataSize			= vertexCount * singleVertexDataSize;
	const deUint32										queueFamilyIndices		= m_context.getUniversalQueueFamilyIndex();

	const VkBufferCreateInfo							vertexBufferParams		=
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	//	VkStructureType		sType;
		DE_NULL,								//	const void*			pNext;
		0u,										//	VkBufferCreateFlags	flags;
		(VkDeviceSize)vertexDataSize,			//	VkDeviceSize		size;
		VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		//	VkBufferUsageFlags	usage;
		VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode		sharingMode;
		1u,										//	deUint32			queueFamilyCount;
		&queueFamilyIndices,					//	const deUint32*		pQueueFamilyIndices;
	};

	const Unique<VkBuffer>								vertexBuffer			(createBuffer(vkd, m_context.getDevice(), &vertexBufferParams));
	const de::UniquePtr<Allocation>						vertexBufferMemory		(m_context.getDefaultAllocator().allocate(getBufferMemoryRequirements(vkd, m_context.getDevice(), *vertexBuffer), MemoryRequirement::HostVisible));

	VK_CHECK(vkd.bindBufferMemory(m_context.getDevice(), *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));

	const VkDeviceSize bindingOffset = 0;
	vkd.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer.get(), &bindingOffset);

	for (size_t subpassNdx = 0; subpassNdx < subpassCount; subpassNdx++)
	{
		if (subpassNdx > 0)
		{
			RenderpassSubpass::cmdNextSubpass(vkd, *commandBuffer, &subpassBeginInfo, &subpassEndInfo);
			vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_renderPipelineLayouts[subpassNdx], 0, 1, &**m_subpassDescriptorSets[subpassNdx - 1], 0, DE_NULL);
		}

		vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_renderPipelines[subpassNdx]);

		if (subpassNdx == 0)
		{
			// Upload vertex data
			{
				void* vertexBufPtr = vertexBufferMemory->getHostPtr();
				deMemcpy(vertexBufPtr, vertexData.data(), vertexDataSize);
				flushAlloc(vkd, m_context.getDevice(), *vertexBufferMemory);
			}

			vkd.cmdDraw(*commandBuffer, (deUint32)vertexData.size(), 1u, 0u, 0u);
		}
		else
			vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
	}

	RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);

	// Memory barrier between rendering and copy
	{
		const VkImageAspectFlags	imageAspectFlags		= isDepthStencilFormat(m_format)
																? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
		const VkAccessFlags			srcAccessMask			= isDepthStencilFormat(m_format)
																? VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT : VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
		const VkImageLayout			oldLayout				= isDepthStencilFormat(m_format)
																? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
		const VkPipelineStageFlags	srcStageMask			= isDepthStencilFormat(m_format)
																? VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT : VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;

		VkImageSubresourceRange		imageSubresourceRange	=
		{
			imageAspectFlags,	// VkImageAspectFlags	aspectMask
			0u,					// uint32_t				baseMipLevel
			1u,					// uint32_t				levelCount
			0u,					// uint32_t				baseArrayLayer
			1u					// uint32_t				layerCount
		};

		const VkImageMemoryBarrier	barrier					=
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType
			DE_NULL,								// const void*				pNext
			srcAccessMask,							// VkAccessFlags			srcAccessMask
			VK_ACCESS_TRANSFER_READ_BIT,			// VkAccessFlags			dstAccessMask
			oldLayout,								// VkImageLayout			oldLayout
			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,	// VkImageLayout			newLayout
			VK_QUEUE_FAMILY_IGNORED,				// uint32_t					srcQueueFamilyIndex
			VK_QUEUE_FAMILY_IGNORED,				// uint32_t					dstQueueFamilyIndex
			**m_images[attachmentCount - 1],		// VkImage					image
			imageSubresourceRange					// VkImageSubresourceRange	subresourceRange
		};

		vkd.cmdPipelineBarrier(*commandBuffer, srcStageMask, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
	}

	// Copy image memory to buffer
	{
		if (isDepthStencilFormat(m_format))
		{
			// Copy depth
			const VkImageSubresourceLayers subresourceLayersDepth	=
			{
				VK_IMAGE_ASPECT_DEPTH_BIT,	// VkImageAspectFlags	aspectMask
				0u,							// deUint32				mipLevel
				0u,							// deUint32				baseArrayLayer
				1u							// deUint32				layerCount
			};

			const VkBufferImageCopy			regionDepth				=
			{
				0u,							// VkDeviceSize				bufferOffset
				0u,							// uint32_t					bufferRowLength
				0u,							// uint32_t					bufferImageHeight
				subresourceLayersDepth,		// VkImageSubresourceLayers	imageSubresource
				{ 0u, 0u, 0u },				// VkOffset3D				imageOffset
				{ m_width, m_height, 1u }	// VkExtent3D				imageExtent
			};

			vkd.cmdCopyImageToBuffer(*commandBuffer, **m_images[attachmentCount - 1], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_primaryBuffer, 1u, &regionDepth);

			// Copy stencil
			const VkImageSubresourceLayers subresourceLayersStencil	=
			{
				VK_IMAGE_ASPECT_STENCIL_BIT,	// VkImageAspectFlags	aspectMask
				0u,								// deUint32				mipLevel
				0u,								// deUint32				baseArrayLayer
				1u								// deUint32				layerCount
			};

			const VkBufferImageCopy			regionStencil			=
			{
				0u,							// VkDeviceSize				bufferOffset
				0u,							// uint32_t					bufferRowLength
				0u,							// uint32_t					bufferImageHeight
				subresourceLayersStencil,	// VkImageSubresourceLayers	imageSubresource
				{ 0u, 0u, 0u },				// VkOffset3D				imageOffset
				{ m_width, m_height, 1u }	// VkExtent3D				imageExtent
			};

			vkd.cmdCopyImageToBuffer(*commandBuffer, **m_images[attachmentCount - 1], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_secondaryBuffer, 1u, &regionStencil);
		}
		else
		{
			// Copy color
			const VkImageSubresourceLayers imageSubresourceLayers	=
			{
				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask
				0u,							// deUint32				mipLevel
				0u,							// deUint32				baseArrayLayer
				1u							// deUint32				layerCount
			};

			const VkBufferImageCopy			region					=
			{
				0u,							// VkDeviceSize				bufferOffset
				0u,							// uint32_t					bufferRowLength
				0u,							// uint32_t					bufferImageHeight
				imageSubresourceLayers,		// VkImageSubresourceLayers	imageSubresource
				{ 0u, 0u, 0u },				// VkOffset3D				imageOffset
				{ m_width, m_height, 1u }	// VkExtent3D				imageExtent
			};

			vkd.cmdCopyImageToBuffer(*commandBuffer, **m_images[attachmentCount - 1], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_primaryBuffer, 1u, &region);
		}
	}

	// Memory barrier between copy and host access
	{
		const VkBufferMemoryBarrier barrier		=
		{
			VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType
			DE_NULL,									// const void*		pNext
			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask
			VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask
			VK_QUEUE_FAMILY_IGNORED,					// uint32_t			srcQueueFamilyIndex
			VK_QUEUE_FAMILY_IGNORED,					// uint32_t			dstQueueFamilyIndex
			*m_primaryBuffer,							// VkBuffer			buffer
			0u,											// VkDeviceSize		offset
			VK_WHOLE_SIZE								// VkDeviceSize		size
		};

		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);

		if (isDepthStencilFormat(m_format))
		{
			const VkBufferMemoryBarrier stencilBarrier =
			{
				VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType
				DE_NULL,									// const void*		pNext
				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask
				VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask
				VK_QUEUE_FAMILY_IGNORED,					// uint32_t			srcQueueFamilyIndex
				VK_QUEUE_FAMILY_IGNORED,					// uint32_t			dstQueueFamilyIndex
				*m_secondaryBuffer,							// VkBuffer			buffer
				0u,											// VkDeviceSize		offset
				VK_WHOLE_SIZE								// VkDeviceSize		size
			};

			vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &stencilBarrier, 0u, DE_NULL);
		}
	}

	endCommandBuffer(vkd, *commandBuffer);
	submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
	invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_primaryBufferMemory->getMemory(), m_primaryBufferMemory->getOffset(), VK_WHOLE_SIZE);
	invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_secondaryBufferMemory->getMemory(), m_secondaryBufferMemory->getOffset(), VK_WHOLE_SIZE);

	// Verify result
	{
		const tcu::TextureFormat format (mapVkFormat(m_format));

		if (isDepthStencilFormat(m_format))
		{
			const void* const					ptrDepth				(m_primaryBufferMemory->getHostPtr());
			const void* const					ptrStencil				(m_secondaryBufferMemory->getHostPtr());
			tcu::TextureLevel					reference				(format, m_width, m_height);
			tcu::TextureLevel					colorBuffer				(mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM), m_width, m_height);
			const tcu::ConstPixelBufferAccess	resultDepthAccess		(getDepthCopyFormat(m_format), m_width, m_height, 1, ptrDepth);
			const tcu::ConstPixelBufferAccess	resultStencilAccess		(getStencilCopyFormat(m_format), m_width, m_height, 1, ptrStencil);
			const PixelBufferAccess				referenceDepthAccess	(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_DEPTH));
			const PixelBufferAccess				referenceStencilAccess	(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_STENCIL));

			tcu::clearDepth(referenceDepthAccess, 1.0f);
			tcu::clearStencil(referenceStencilAccess, 255);

			// Setup and run reference renderer
			{
				const DepthVertShader					vertShader;
				const DepthFragShader					fragShader;
				const rr::Renderer						renderer;
				const rr::Program						program				(&vertShader, &fragShader);
				const rr::MultisamplePixelBufferAccess	depthBuffer			(rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(referenceDepthAccess));
				const rr::MultisamplePixelBufferAccess	colorBufferAccess	(rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(colorBuffer.getAccess()));
				const rr::RenderTarget					renderTarget		(rr::MultisamplePixelBufferAccess(colorBufferAccess), depthBuffer, rr::MultisamplePixelBufferAccess());
				const rr::PrimitiveType					primitiveType		(rr::PRIMITIVETYPE_TRIANGLES);
				const rr::PrimitiveList					primitiveList		(rr::PrimitiveList(primitiveType, (deUint32)vertexData.size(), 0));
				rr::RenderState							renderState			((rr::ViewportState(depthBuffer)), m_context.getDeviceProperties().limits.subPixelPrecisionBits);

				const rr::VertexAttrib vertices			= rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &vertexData[0]);

				renderState.fragOps.depthTestEnabled	= DE_TRUE;
				renderState.fragOps.depthFunc			= rr::TESTFUNC_LEQUAL;

				renderer.draw(rr::DrawCommand(renderState,
											  renderTarget,
											  program,
											  1u,
											  &vertices,
											  primitiveList));
			}

			for (size_t subpassNdx = 0; subpassNdx < subpassCount - 1; subpassNdx++)
			{
				for (int y = 0; y < reference.getHeight(); y++)
				for (int x = 0; x < reference.getWidth(); x++)
					reference.getAccess().setPixDepth(reference.getAccess().getPixDepth(x, y) - 0.02f, x, y);
			}

			// Threshold size of subpass count multiplied by the minimum representable difference is allowed for depth compare
			const float							depthThreshold			((float)subpassCount * (1.0f / ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(
																			resultDepthAccess.getFormat()).cast<deUint32>()) - 1u).cast<float>().x()));

			if (!verifyDepth(m_context, reference.getAccess(), resultDepthAccess, depthThreshold))
				m_resultCollector.fail("Depth compare failed.");

			if (!verifyStencil(m_context, referenceStencilAccess, resultStencilAccess))
				m_resultCollector.fail("Stencil compare failed.");
		}
		else
			DE_FATAL("Not implemented");
	}

	return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
}

struct SubpassSelfDependencyBackwardsTestConfig
{
		SubpassSelfDependencyBackwardsTestConfig	(VkFormat		format_,
													 UVec2			imageSize_,
													 RenderPassType	renderPassType_)
		: format			(format_)
		, imageSize			(imageSize_)
		, renderPassType	(renderPassType_)
	{
	}

	VkFormat		format;
	UVec2			imageSize;
	RenderPassType	renderPassType;
};

class SubpassSelfDependencyBackwardsTestInstance : public TestInstance
{
public:
							SubpassSelfDependencyBackwardsTestInstance	(Context&									context,
																		 SubpassSelfDependencyBackwardsTestConfig	testConfig);

							~SubpassSelfDependencyBackwardsTestInstance	(void);

	tcu::TestStatus			iterate										(void);

	template<typename RenderpassSubpass>
	tcu::TestStatus			iterateInternal								(void);

private:
	const bool				m_extensionSupported;
	const bool				m_featuresSupported;
	const RenderPassType	m_renderPassType;

	const deUint32			m_width;
	const deUint32			m_height;
	const VkFormat			m_format;
	tcu::ResultCollector	m_resultCollector;
};

SubpassSelfDependencyBackwardsTestInstance::SubpassSelfDependencyBackwardsTestInstance (Context& context, SubpassSelfDependencyBackwardsTestConfig testConfig)
	: TestInstance			(context)
	, m_extensionSupported	((testConfig.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
	, m_featuresSupported	(context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER))
	, m_renderPassType		(testConfig.renderPassType)
	, m_width				(testConfig.imageSize.x())
	, m_height				(testConfig.imageSize.y())
	, m_format				(testConfig.format)
{
}

SubpassSelfDependencyBackwardsTestInstance::~SubpassSelfDependencyBackwardsTestInstance (void)
{
}

tcu::TestStatus SubpassSelfDependencyBackwardsTestInstance::iterate (void)
{
	switch (m_renderPassType)
	{
		case RENDERPASS_TYPE_LEGACY:
			return iterateInternal<RenderpassSubpass1>();
		case RENDERPASS_TYPE_RENDERPASS2:
			return iterateInternal<RenderpassSubpass2>();
		default:
			TCU_THROW(InternalError, "Impossible");
	}
}

template<typename RenderpassSubpass>
tcu::TestStatus SubpassSelfDependencyBackwardsTestInstance::iterateInternal (void)
{
	de::Random											rand					(5);
	const DeviceInterface&								vkd						(m_context.getDeviceInterface());
	const VkDevice										device					= m_context.getDevice();
	const deUint32										queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
	const Unique<VkCommandPool>							commandPool				(createCommandPool(vkd, m_context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>						commandBuffer			(allocateCommandBuffer(vkd, m_context.getDevice(), *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
	const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo		(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo			(DE_NULL);
	vector<Vec4>										vertexData;
	Move<VkImage>										outputImage;
	de::MovePtr<Allocation>								outputImageAllocation;
	Move<VkImageView>									outputImageView;
	Move<VkPipelineLayout>								pipelineLayout;
	Move<VkPipeline>									renderPipeline;
	Move<VkFramebuffer>									framebuffer;
	Move<VkRenderPass>									renderPass;
	Move<VkBuffer>										indirectBuffer;
	de::MovePtr<Allocation>								indirectBufferMemory;
	Move<VkBuffer>										resultBuffer;
	de::MovePtr<Allocation>								resultBufferMemory;
	const VkDeviceSize									indirectBufferSize		= 4 * sizeof(deUint32);
	Move<VkBuffer>										vertexBuffer;
	de::MovePtr<Allocation>								vertexBufferMemory;

	// Create output image.
	{
		const VkExtent3D		imageExtent		=
		{
			m_width,	// uint32_t	width
			m_height,	// uint32_t	height
			1u			// uint32_t	depth
		};

		VkImageUsageFlags		usage			= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;

		const VkImageCreateInfo	imageCreateInfo	=
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
			DE_NULL,								// const void*				pNext
			0u,										// VkImageCreateFlags		flags
			VK_IMAGE_TYPE_2D,						// VkImageType				imageType
			m_format,								// VkFormat					format
			imageExtent,							// VkExtent3D				extent
			1u,										// uint32_t					mipLevels
			1u,										// uint32_t					arrayLayers
			VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
			usage,									// VkImageUsageFlags		usage
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
			1u,										// uint32_t					queueFamilyIndexCount
			&queueFamilyIndex,						// const uint32_t*			pQueueFamilyIndices
			VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
		};

		outputImage = createImage(vkd, device, &imageCreateInfo, DE_NULL);
		outputImageAllocation = m_context.getDefaultAllocator().allocate(getImageMemoryRequirements(vkd, device, *outputImage), MemoryRequirement::Any);
		VK_CHECK(vkd.bindImageMemory(device, *outputImage, outputImageAllocation->getMemory(), outputImageAllocation->getOffset()));
	}

	// Create indirect buffer and initialize.
	{
		const VkBufferUsageFlags	bufferUsage	(VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
		const VkBufferCreateInfo	bufferCreateInfo	=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType
			DE_NULL,								// const void*			pNext
			0u,										// VkBufferCreateFlags	flags
			indirectBufferSize,						// VkDeviceSize			size
			bufferUsage,							// VkBufferUsageFlags	usage
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode
			0u,										// uint32_t				queueFamilyIndexCount
			DE_NULL									// const uint32_t*		pQueueFamilyIndices
		};

		indirectBuffer			= createBuffer(vkd, device, &bufferCreateInfo);
		indirectBufferMemory	= createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *indirectBuffer);

		VkDrawIndirectCommand	drawIndirectCommand	=
		{
			64u,	// deUint32	vertexCount
			1u,		// deUint32	instanceCount
			0u,		// deUint32	firstVertex
			0u,		// deUint32	firstInstance
		};

		deMemcpy(indirectBufferMemory->getHostPtr(), (void*)&drawIndirectCommand, sizeof(VkDrawIndirectCommand));
		flushAlloc(vkd, device, *indirectBufferMemory);
	}

	// Create result buffer.
	{
		resultBuffer		= createBuffer(vkd, device, m_format, m_width, m_height);
		resultBufferMemory	= createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *resultBuffer);
	}

	// Create descriptor set layout.
	Unique<VkDescriptorSetLayout>	descriptorSetLayout	(DescriptorSetLayoutBuilder()
			.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_GEOMETRY_BIT)
			.build(vkd, device));
	// Create descriptor pool.
	Unique<VkDescriptorPool>		descriptorPool		(DescriptorPoolBuilder()
			.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u)
			.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
	// Create descriptor set.
	Unique<VkDescriptorSet>			descriptorSet		(makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout));

	// Update descriptor set information.
	{
		VkDescriptorBufferInfo descIndirectBuffer = makeDescriptorBufferInfo(*indirectBuffer, 0, indirectBufferSize);

		DescriptorSetUpdateBuilder()
			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descIndirectBuffer)
			.update(vkd, device);
	}

	// Create render pipeline layout.
	{
		const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
		{
			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType
			DE_NULL,										// const void*					pNext
			(vk::VkPipelineLayoutCreateFlags)0,				// VkPipelineLayoutCreateFlags	flags
			1u,												// deUint32						setLayoutCount
			&*descriptorSetLayout,							// const VkDescriptorSetLayout*	pSetLayouts
			0u,												// deUint32						pushConstantRangeCount
			DE_NULL											// const VkPushConstantRange*	pPushConstantRanges
		};

		pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);
	}

	// Create render pass.
	{
		vector<Attachment>			attachments;
		vector<AttachmentReference>	colorAttachmentReferences;

		attachments.push_back(Attachment(m_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
		colorAttachmentReferences.push_back(AttachmentReference(0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));

		const vector<Subpass>		subpasses	(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<deUint32>()));
		vector<SubpassDependency>	deps;

		deps.push_back(SubpassDependency(0u,									// deUint32				srcPass
										 0u,									// deUint32				dstPass
										 VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT,	// VkPipelineStageFlags	srcStageMask
										 VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,	// VkPipelineStageFlags	dstStageMask
										 VK_ACCESS_SHADER_WRITE_BIT,			// VkAccessFlags		srcAccessMask
										 VK_ACCESS_INDIRECT_COMMAND_READ_BIT,	// VkAccessFlags		dstAccessMask
										 0));									// VkDependencyFlags	flags

		renderPass = createRenderPass(vkd, device, RenderPass(attachments, subpasses, deps), m_renderPassType);
	}

	// Create render pipeline.
	{
		const Unique<VkShaderModule>				vertexShaderModule			(createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u));
		const Unique<VkShaderModule>				geometryShaderModule		(createShaderModule(vkd, device, m_context.getBinaryCollection().get("geom"), 0u));
		const Unique<VkShaderModule>				fragmentShaderModule		(createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u));

		const VkVertexInputBindingDescription		vertexBinding0				=
		{
			0u,							// deUint32					binding;
			sizeof(Vec4),				// deUint32					strideInBytes;
			VK_VERTEX_INPUT_RATE_VERTEX	// VkVertexInputStepRate	stepRate;
		};

		VkVertexInputAttributeDescription			attr0						=
		{
			0u,								// deUint32	location;
			0u,								// deUint32	binding;
			VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat	format;
			0u								// deUint32	offsetInBytes;
		};

		const VkPipelineVertexInputStateCreateInfo	vertexInputState			=
		{
			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType
			DE_NULL,													// const void*								pNext
			(VkPipelineVertexInputStateCreateFlags)0u,					// VkPipelineVertexInputStateCreateFlags	flags
			1u,															// uint32_t									vertexBindingDescriptionCount
			&vertexBinding0,											// const VkVertexInputBindingDescription*	pVertexBindingDescriptions
			1u,															// uint32_t									vertexAttributeDescriptionCount
			&attr0														// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions
		};

		const std::vector<VkViewport>				viewports					(1, makeViewport(tcu::UVec2(m_width, m_height)));
		const std::vector<VkRect2D>					scissors					(1, makeRect2D(tcu::UVec2(m_width, m_height)));

		renderPipeline = makeGraphicsPipeline(vkd,	// const DeviceInterface&						vk
				device,								// const VkDevice								device
				*pipelineLayout,					// const VkPipelineLayout						pipelineLayout
				*vertexShaderModule,				// const VkShaderModule							vertexShaderModule
				DE_NULL,							// const VkShaderModule							tessellationControlShaderModule
				DE_NULL,							// const VkShaderModule							tessellationEvalShaderModule
				*geometryShaderModule,				// const VkShaderModule							geometryShaderModule
				*fragmentShaderModule,				// const VkShaderModule							fragmentShaderModule
				*renderPass,						// const VkRenderPass							renderPass
				viewports,							// const std::vector<VkViewport>&				viewports
				scissors,							// const std::vector<VkRect2D>&					scissors
				VK_PRIMITIVE_TOPOLOGY_POINT_LIST,	// const VkPrimitiveTopology					topology
				0u,									// const deUint32								subpass
				0u,									// const deUint32								patchControlPoints
				&vertexInputState);					// const VkPipelineVertexInputStateCreateInfo*	vertexInputStateCreateInfo
	}

	// Create framebuffer.
	{
		const VkImageViewCreateInfo imageViewCreateInfo =
		{
			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType
			DE_NULL,									// const void*				pNext
			0u,											// VkImageViewCreateFlags	flags
			*outputImage,								// VkImage					image
			VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType
			m_format,									// VkFormat					format
			makeComponentMappingRGBA(),					// VkComponentMapping		components
			{											// VkImageSubresourceRange	subresourceRange
				VK_IMAGE_ASPECT_COLOR_BIT,
				0u,
				1u,
				0u,
				1u
			}
		};
		outputImageView	= createImageView(vkd, device, &imageViewCreateInfo);

		const VkFramebufferCreateInfo framebufferCreateInfo =
		{
			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType
			DE_NULL,									// const void*				pNext
			0u,											// VkFramebufferCreateFlags	flags
			*renderPass,								// VkRenderPass				renderPass
			1u,											// uint32_t					attachmentCount
			&*outputImageView,							// const VkImageView*		pAttachments
			m_width,									// uint32_t					width
			m_height,									// uint32_t					height
			1u											// uint32_t					layers
		};

		framebuffer = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
	}

	// Generate random point locations (pixel centered to make reference comparison easier).
	for (int primitiveNdx = 0; primitiveNdx < 128; primitiveNdx++)
	{
		vertexData.push_back(Vec4((float)((rand.getUint32() % m_width) * 2) / (float)m_width - 1.0f,
				(float)((rand.getUint32() % m_height) * 2) / (float)m_height - 1.0f,
				1.0f, 1.0f));
	}

	// Upload vertex data.
	{
		const size_t				vertexDataSize		= vertexData.size() * sizeof(Vec4);

		const VkBufferCreateInfo	vertexBufferParams	=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	//	VkStructureType		sType;
			DE_NULL,								//	const void*			pNext;
			0u,										//	VkBufferCreateFlags	flags;
			(VkDeviceSize)vertexDataSize,			//	VkDeviceSize		size;
			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		//	VkBufferUsageFlags	usage;
			VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode		sharingMode;
			1u,										//	deUint32			queueFamilyCount;
			&queueFamilyIndex,						//	const deUint32*		pQueueFamilyIndices;
		};

		vertexBuffer		= createBuffer(vkd, m_context.getDevice(), &vertexBufferParams);
		vertexBufferMemory	= createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *vertexBuffer);

		deMemcpy(vertexBufferMemory->getHostPtr(), vertexData.data(), vertexDataSize);
		flushAlloc(vkd, device, *vertexBufferMemory);
	}

	beginCommandBuffer(vkd, *commandBuffer);
	vkd.cmdBindPipeline(*commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *renderPipeline);
	vkd.cmdBindDescriptorSets(*commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);

	// Begin render pass.
	{
		VkRect2D					renderArea	=
		{
			{ 0u, 0u },				// VkOffset2D	offset
			{ m_width, m_height }	// VkExtent2D	extent
		};

		VkClearValue				clearValue	= makeClearValueColor(Vec4(0.0f, 1.0f, 0.0f, 1.0f));

		const VkRenderPassBeginInfo	beginInfo	=
		{
			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType
			DE_NULL,									// const void*			pNext
			*renderPass,								// VkRenderPass			renderPass
			*framebuffer,								// VkFramebuffer		framebuffer
			renderArea,									// VkRect2D				renderArea
			1u,											// uint32_t				clearValueCount
			&clearValue									// const VkClearValue*	pClearValues
		};

		RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
	}

	const VkDeviceSize bindingOffset = 0;
	vkd.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer.get(), &bindingOffset);

	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *renderPipeline);

	// The first indirect draw: Draw the first 64 items.
	vkd.cmdDrawIndirect(*commandBuffer, *indirectBuffer, 0u, 1u, 0u);

	// Barrier for indirect buffer.
	{
		const VkMemoryBarrier barrier =
		{
			VK_STRUCTURE_TYPE_MEMORY_BARRIER,	// VkStructureType	sType
			DE_NULL,							// const void*		pNext
			VK_ACCESS_SHADER_WRITE_BIT,			// VkAccessFlags	srcAccessMask
			VK_ACCESS_INDIRECT_COMMAND_READ_BIT	// VkAccessFlags	dstAccessMask
		};

		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, 0u, 1u, &barrier, 0u, DE_NULL, 0u, DE_NULL);
	}

	// The second indirect draw: Draw the last 64 items.
	vkd.cmdDrawIndirect(*commandBuffer, *indirectBuffer, 0u, 1u, 0u);

	RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);

	// Copy results to a buffer.
	copyImageToBuffer(vkd, *commandBuffer, *outputImage, *resultBuffer, tcu::IVec2(m_width, m_height));

	endCommandBuffer(vkd, *commandBuffer);
	submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
	invalidateMappedMemoryRange(vkd, m_context.getDevice(), resultBufferMemory->getMemory(), resultBufferMemory->getOffset(), VK_WHOLE_SIZE);

	// Verify result.
	{
		const tcu::TextureFormat format (mapVkFormat(m_format));

		const void* const					ptrResult		(resultBufferMemory->getHostPtr());
		tcu::TextureLevel					reference		(format, m_width, m_height);
		const tcu::ConstPixelBufferAccess	resultAccess	(format, m_width, m_height, 1, ptrResult);
		const PixelBufferAccess				referenceAccess	(reference.getAccess());


		// Setup and run reference renderer.
		{
			vector<Vec4>							triangles;
			const float								offset			= 0.03f;

			// Convert points into triangles to have quads similar to what GPU is producing from geometry shader.
			for (size_t vtxIdx = 0; vtxIdx < vertexData.size(); vtxIdx++)
			{
				triangles.push_back(vertexData[vtxIdx] + tcu::Vec4(-offset, offset, 0.0f, 0.0f));
				triangles.push_back(vertexData[vtxIdx] + tcu::Vec4(-offset, -offset, 0.0f, 0.0f));
				triangles.push_back(vertexData[vtxIdx] + tcu::Vec4(offset, offset, 0.0f, 0.0f));

				triangles.push_back(vertexData[vtxIdx] + tcu::Vec4(-offset, -offset, 0.0f, 0.0f));
				triangles.push_back(vertexData[vtxIdx] + tcu::Vec4(offset, offset, 0.0f, 0.0f));
				triangles.push_back(vertexData[vtxIdx] + tcu::Vec4(offset, -offset, 0.0f, 0.0f));
			}

			const SelfDependencyBackwardsVertShader	vertShader;
			const SelfDependencyBackwardsFragShader	fragShader;
			const rr::Renderer						renderer;
			const rr::Program						program			(&vertShader, &fragShader);
			const rr::MultisamplePixelBufferAccess	msAccess		(rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(referenceAccess));
			const rr::RenderTarget					renderTarget	(msAccess);
			const rr::PrimitiveType					primitiveType	(rr::PRIMITIVETYPE_TRIANGLES);
			const rr::PrimitiveList					primitiveList	(rr::PrimitiveList(primitiveType, (deUint32)triangles.size(), 0));
			const rr::ViewportState					viewportState	(msAccess);
			const rr::RenderState					renderState		(viewportState, m_context.getDeviceProperties().limits.subPixelPrecisionBits);
			const rr::VertexAttrib					vertices		= rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &triangles[0]);

			tcu::clear(referenceAccess, tcu::UVec4(0, 255, 0, 255));
			renderer.draw(rr::DrawCommand(renderState, renderTarget, program, 1u, &vertices, primitiveList));
		}

		if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(),	// log
										"Color buffer",							// imageSetName
										"",										// imageSetDesc
										referenceAccess,						// reference
										resultAccess,							// result
										Vec4(0.01f),							// threshold
										tcu::COMPARE_LOG_RESULT))				// logMode
		{
			m_resultCollector.fail("Image compare failed.");
		}
	}

	return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
}

struct SeparateChannelsTestConfig
{
		SeparateChannelsTestConfig	(VkFormat		format_,
									 RenderPassType	renderPassType_)
		: format			(format_)
		, renderPassType	(renderPassType_)
	{
	}

	VkFormat		format;
	RenderPassType	renderPassType;
};

class SeparateChannelsTestInstance : public TestInstance
{
public:
							SeparateChannelsTestInstance	(Context&					context,
															 SeparateChannelsTestConfig	testConfig);

							~SeparateChannelsTestInstance	(void);

	tcu::TestStatus			iterate							(void);

	template<typename RenderpassSubpass>
	tcu::TestStatus			iterateInternal					(void);

private:
	const bool				m_extensionSupported;
	const RenderPassType	m_renderPassType;

	const deUint32			m_width;
	const deUint32			m_height;
	const VkFormat			m_format;
	tcu::ResultCollector	m_resultCollector;
};

SeparateChannelsTestInstance::SeparateChannelsTestInstance (Context& context, SeparateChannelsTestConfig testConfig)
	: TestInstance			(context)
	, m_extensionSupported	((testConfig.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
	, m_renderPassType		(testConfig.renderPassType)
	, m_width				(256u)
	, m_height				(256u)
	, m_format				(testConfig.format)
{
}

SeparateChannelsTestInstance::~SeparateChannelsTestInstance (void)
{
}

tcu::TestStatus SeparateChannelsTestInstance::iterate (void)
{
	switch (m_renderPassType)
	{
		case RENDERPASS_TYPE_LEGACY:
			return iterateInternal<RenderpassSubpass1>();
		case RENDERPASS_TYPE_RENDERPASS2:
			return iterateInternal<RenderpassSubpass2>();
		default:
			TCU_THROW(InternalError, "Impossible");
	}
}

template<typename RenderpassSubpass>
tcu::TestStatus SeparateChannelsTestInstance::iterateInternal (void)
{
	const DeviceInterface&								vkd						(m_context.getDeviceInterface());
	const VkDevice										device					= m_context.getDevice();
	const VkQueue										queue					= m_context.getUniversalQueue();
	const deUint32										queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
	const Unique<VkCommandPool>							commandPool				(createCommandPool(vkd, m_context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>						commandBuffer			(allocateCommandBuffer(vkd, m_context.getDevice(), *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
	const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo		(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo			(DE_NULL);
	const bool											isDSFormat				= isDepthStencilFormat(m_format);
	const VkFormat										colorFormat				= isDSFormat ? VK_FORMAT_R8G8B8A8_UNORM : m_format;
	const tcu::Vec4										colorInitValues[2]		= { tcu::Vec4(0.2f, 0.4f, 0.1f, 1.0f), tcu::Vec4(0.5f, 0.4f, 0.7f, 1.0f) };
	const float											depthInitValues[2]		= { 0.3f, 0.7f };
	const deUint32										stencilInitValues[2]	= { 2u, 100u };
	const deUint32										stencilRefValue			= 200u;
	const deUint32										tileSize				= 32u;
	vector<Vec4>										vertexData;
	Move<VkImage>										colorImage;
	de::MovePtr<Allocation>								colorImageAllocation;
	// When testing color formats the same attachment is used as input and output. This requires general layout to be used.
	const VkImageLayout									colorImageLayout		= isDSFormat ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL;
	Move<VkImage>										dsImage;
	de::MovePtr<Allocation>								dsImageAllocation;
	Move<VkImageView>									outputImageView;
	Move<VkImageView>									inputImageView;
	Move<VkImageView>									dsImageView;
	Move<VkPipelineLayout>								pipelineLayout;
	Move<VkPipeline>									renderPipeline;
	Move<VkFramebuffer>									framebuffer;
	Move<VkRenderPass>									renderPass;
	Move<VkBuffer>										resultBuffer0;
	de::MovePtr<Allocation>								resultBuffer0Memory;
	Move<VkBuffer>										resultBuffer1;
	de::MovePtr<Allocation>								resultBuffer1Memory;
	Move<VkBuffer>										vertexBuffer;
	de::MovePtr<Allocation>								vertexBufferMemory;

	const VkExtent3D		imageExtent		=
	{
		m_width,	// deUint32	width
		m_height,	// deUint32	height
		1u			// deUint32	depth
	};

	// Create image used for both input and output in case of color test, and as a color output in depth/stencil test.
	{
		VkImageUsageFlags		usage			= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;

		const VkImageCreateInfo	imageCreateInfo	=
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
			DE_NULL,								// const void*				pNext
			0u,										// VkImageCreateFlags		flags
			VK_IMAGE_TYPE_2D,						// VkImageType				imageType
			colorFormat,							// VkFormat					format
			imageExtent,							// VkExtent3D				extent
			1u,										// uint32_t					mipLevels
			1u,										// uint32_t					arrayLayers
			VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
			usage,									// VkImageUsageFlags		usage
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
			1u,										// uint32_t					queueFamilyIndexCount
			&queueFamilyIndex,						// const uint32_t*			pQueueFamilyIndices
			VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
		};

		checkImageSupport(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), imageCreateInfo);

		colorImage = createImage(vkd, device, &imageCreateInfo, DE_NULL);
		colorImageAllocation = m_context.getDefaultAllocator().allocate(getImageMemoryRequirements(vkd, device, *colorImage), MemoryRequirement::Any);
		VK_CHECK(vkd.bindImageMemory(device, *colorImage, colorImageAllocation->getMemory(), colorImageAllocation->getOffset()));
	}

	// Create depth/stencil image
	if (isDSFormat)
	{
		VkImageUsageFlags		usage			= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;

		const VkImageCreateInfo	imageCreateInfo	=
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
			DE_NULL,								// const void*				pNext
			0u,										// VkImageCreateFlags		flags
			VK_IMAGE_TYPE_2D,						// VkImageType				imageType
			m_format,								// VkFormat					format
			imageExtent,							// VkExtent3D				extent
			1u,										// uint32_t					mipLevels
			1u,										// uint32_t					arrayLayers
			VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
			usage,									// VkImageUsageFlags		usage
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
			1u,										// uint32_t					queueFamilyIndexCount
			&queueFamilyIndex,						// const uint32_t*			pQueueFamilyIndices
			VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
		};

		checkImageSupport(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), imageCreateInfo);

		dsImage = createImage(vkd, device, &imageCreateInfo, DE_NULL);
		dsImageAllocation = m_context.getDefaultAllocator().allocate(getImageMemoryRequirements(vkd, device, *dsImage), MemoryRequirement::Any);
		VK_CHECK(vkd.bindImageMemory(device, *dsImage, dsImageAllocation->getMemory(), dsImageAllocation->getOffset()));

		// Initialize depth / stencil image
		initDepthStencilImageChessboardPattern(vkd, device, queue, queueFamilyIndex, m_context.getDefaultAllocator(), *dsImage, m_format, depthInitValues[0], depthInitValues[1], stencilInitValues[0], stencilInitValues[1], m_width, m_height, tileSize, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
	}

	// Initialize color image
	initColorImageChessboardPattern(vkd, device, queue, queueFamilyIndex, m_context.getDefaultAllocator(), *colorImage, colorFormat, colorInitValues[0], colorInitValues[1], m_width, m_height, tileSize, VK_IMAGE_LAYOUT_UNDEFINED, colorImageLayout, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);

	// Create color image views
	{
		const VkImageViewCreateInfo imageViewCreateInfo =
		{
			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType
			DE_NULL,									// const void*				pNext
			0u,											// VkImageViewCreateFlags	flags
			*colorImage,								// VkImage					image
			VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType
			colorFormat,								// VkFormat					format
			makeComponentMappingRGBA(),					// VkComponentMapping		components
			{											// VkImageSubresourceRange	subresourceRange
				VK_IMAGE_ASPECT_COLOR_BIT,
				0u,
				1u,
				0u,
				1u
			}
		};

		if (!isDSFormat) inputImageView	= createImageView(vkd, device, &imageViewCreateInfo);
		outputImageView	= createImageView(vkd, device, &imageViewCreateInfo);
	}

	// Create depth/stencil image view
	if (isDSFormat)
	{
		const VkImageViewCreateInfo imageViewCreateInfo =
		{
			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType
			DE_NULL,									// const void*				pNext
			0u,											// VkImageViewCreateFlags	flags
			*dsImage,									// VkImage					image
			VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType
			m_format,									// VkFormat					format
			makeComponentMappingRGBA(),					// VkComponentMapping		components
			{											// VkImageSubresourceRange	subresourceRange
				VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
				0u,
				1u,
				0u,
				1u
			}
		};

		dsImageView	= createImageView(vkd, device, &imageViewCreateInfo);
	}

	// Create result buffers.
	{
		resultBuffer0		= createBuffer(vkd, device, m_format, m_width, m_height);
		resultBuffer0Memory	= createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *resultBuffer0);
		resultBuffer1		= createBuffer(vkd, device, m_format, m_width, m_height);
		resultBuffer1Memory	= createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *resultBuffer1);
	}

	// Create descriptor set layout.
	Unique<VkDescriptorSetLayout>	descriptorSetLayout	(DescriptorSetLayoutBuilder()
			.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT)
			.build(vkd, device));
	// Create descriptor pool.
	Unique<VkDescriptorPool>		descriptorPool		(DescriptorPoolBuilder()
			.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u)
			.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
	// Create descriptor set.
	Unique<VkDescriptorSet>			descriptorSet		(makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout));

	// Update descriptor set information.
	if (!isDSFormat)
	{
		VkDescriptorImageInfo descInputAttachment = makeDescriptorImageInfo(DE_NULL, *inputImageView, VK_IMAGE_LAYOUT_GENERAL);

		DescriptorSetUpdateBuilder()
			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descInputAttachment)
			.update(vkd, device);
	}

	// Create render pipeline layout.
	{
		const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
		{
			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType
			DE_NULL,										// const void*					pNext
			(vk::VkPipelineLayoutCreateFlags)0,				// VkPipelineLayoutCreateFlags	flags
			1u,												// deUint32						setLayoutCount
			&*descriptorSetLayout,							// const VkDescriptorSetLayout*	pSetLayouts
			0u,												// deUint32						pushConstantRangeCount
			DE_NULL											// const VkPushConstantRange*	pPushConstantRanges
		};

		pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);
	}

	// Create render pass.
	{
		vector<Attachment>			attachments;
		vector<AttachmentReference>	colorAttachmentReferences;
		vector<AttachmentReference>	inputAttachmentReferences;
		AttachmentReference			dsAttachmentReference		(1u, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);

		const VkImageAspectFlags	inputAttachmentAspectMask	((m_renderPassType == RENDERPASS_TYPE_RENDERPASS2)
																? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT)
																: static_cast<VkImageAspectFlags>(0));

		attachments.push_back(Attachment(colorFormat, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, colorImageLayout, colorImageLayout));
		colorAttachmentReferences.push_back(AttachmentReference(0u, colorImageLayout));

		if (isDSFormat)
		{
			attachments.push_back(Attachment(m_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
		}
		else
		{
			attachments.push_back(Attachment(colorFormat, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL));
			inputAttachmentReferences.push_back(AttachmentReference(1u, VK_IMAGE_LAYOUT_GENERAL, inputAttachmentAspectMask));
		}

		const vector<Subpass>		subpasses	(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, inputAttachmentReferences, colorAttachmentReferences, vector<AttachmentReference>(), isDSFormat ? dsAttachmentReference : AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<deUint32>()));

		renderPass = createRenderPass(vkd, device, RenderPass(attachments, subpasses, vector<SubpassDependency>()), m_renderPassType);
	}

	// Create render pipeline.
	{
		const Unique<VkShaderModule>				vertexShaderModule			(createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u));
		const Unique<VkShaderModule>				fragmentShaderModule		(createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u));

		const VkVertexInputBindingDescription		vertexBinding0				=
		{
			0u,							// deUint32					binding
			sizeof(Vec4),				// deUint32					strideInBytes
			VK_VERTEX_INPUT_RATE_VERTEX	// VkVertexInputStepRate	stepRate
		};

		const VkVertexInputAttributeDescription		attr0						=
		{
			0u,								// deUint32	location
			0u,								// deUint32	binding
			VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat	format
			0u								// deUint32	offsetInBytes
		};

		const VkPipelineVertexInputStateCreateInfo	vertexInputState			=
		{
			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType
			DE_NULL,													// const void*								pNext
			(VkPipelineVertexInputStateCreateFlags)0u,					// VkPipelineVertexInputStateCreateFlags	flags
			1u,															// deUint32									vertexBindingDescriptionCount
			&vertexBinding0,											// const VkVertexInputBindingDescription*	pVertexBindingDescriptions
			1u,															// deUint32									vertexAttributeDescriptionCount
			&attr0														// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions
		};

		// Use write mask to enable only B and A channels to prevent self dependency (reads are done for channels R and G).
		const VkPipelineColorBlendAttachmentState	colorBlendAttachmentState	=
		{
			VK_FALSE,					// VkBool32					blendEnable
			VK_BLEND_FACTOR_ZERO,		// VkBlendFactor			srcColorBlendFactor
			VK_BLEND_FACTOR_ZERO,		// VkBlendFactor			dstColorBlendFactor
			VK_BLEND_OP_ADD,			// VkBlendOp				colorBlendOp
			VK_BLEND_FACTOR_ZERO,		// VkBlendFactor			srcAlphaBlendFactor
			VK_BLEND_FACTOR_ZERO,		// VkBlendFactor			dstAlphaBlendFactor
			VK_BLEND_OP_ADD,			// VkBlendOp				alphaBlendOp
			VK_COLOR_COMPONENT_B_BIT
			| VK_COLOR_COMPONENT_A_BIT	// VkColorComponentFlags	colorWriteMask
		};

		const VkPipelineColorBlendStateCreateInfo	colorBlendState				=
		{
			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType
			DE_NULL,													// const void*									pNext
			0u,															// VkPipelineColorBlendStateCreateFlags			flags
			VK_FALSE,													// VkBool32										logicOpEnable
			VK_LOGIC_OP_CLEAR,											// VkLogicOp									logicOp
			1u,															// deUint32										attachmentCount
			&colorBlendAttachmentState,									// const VkPipelineColorBlendAttachmentState*	pAttachments
			{ 0.0f, 0.0f, 0.0f, 0.0f }									// float										blendConstants[4]
		};

		const VkStencilOpState						stencilOpState				=
		{
			VK_STENCIL_OP_REPLACE,	// VkStencilOp	failOp
			VK_STENCIL_OP_REPLACE,	// VkStencilOp	passOp
			VK_STENCIL_OP_ZERO,		// VkStencilOp	depthFailOp
			VK_COMPARE_OP_ALWAYS,	// VkCompareOp	compareOp
			0xff,					// deUint32		compareMask
			0xff,					// deUint32		writeMask
			stencilRefValue			// deUint32		reference
		};

		const VkPipelineDepthStencilStateCreateInfo	depthStencilState			=
		{
			VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType
			DE_NULL,													// const void*								pNext
			0u,															// VkPipelineDepthStencilStateCreateFlags	flags
			VK_TRUE,													// VkBool32									depthTestEnable
			VK_FALSE,													// VkBool32									depthWriteEnable
			VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp
			VK_FALSE,													// VkBool32									depthBoundsTestEnable
			VK_TRUE,													// VkBool32									stencilTestEnable
			stencilOpState,												// VkStencilOpState							front
			stencilOpState,												// VkStencilOpState							back
			0.0f,														// float									minDepthBounds
			1.0f														// float									maxDepthBounds
		};

		const std::vector<VkViewport>				viewports					(1, makeViewport(tcu::UVec2(m_width, m_height)));
		const std::vector<VkRect2D>					scissors					(1, makeRect2D(tcu::UVec2(m_width, m_height)));

		renderPipeline = makeGraphicsPipeline(vkd,			// const DeviceInterface&							vk
				device,										// const VkDevice									device
				*pipelineLayout,							// const VkPipelineLayout							pipelineLayout
				*vertexShaderModule,						// const VkShaderModule								vertexShaderModule
				DE_NULL,									// const VkShaderModule								tessellationControlShaderModule
				DE_NULL,									// const VkShaderModule								tessellationEvalShaderModule
				DE_NULL,									// const VkShaderModule								geometryShaderModule
				*fragmentShaderModule,						// const VkShaderModule								fragmentShaderModule
				*renderPass,								// const VkRenderPass								renderPass
				viewports,									// const std::vector<VkViewport>&					viewports
				scissors,									// const std::vector<VkRect2D>&						scissors
				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,		// const VkPrimitiveTopology						topology
				0u,											// const deUint32									subpass
				0u,											// const deUint32									patchControlPoints
				&vertexInputState,							// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
				DE_NULL,									// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
				DE_NULL,									// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
				isDSFormat ? &depthStencilState : DE_NULL,	// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
				isDSFormat ? DE_NULL : &colorBlendState);	// const VkPipelineColorBlendStateCreateInfo*		colorBlendStateCreateInfo
	}

	// Create framebuffer.
	{
		const VkImageView				attachments[]			=
		{
			*outputImageView,
			isDSFormat ? *dsImageView : *inputImageView
		};

		const VkFramebufferCreateInfo	framebufferCreateInfo	=
		{
			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType
			DE_NULL,									// const void*				pNext
			0u,											// VkFramebufferCreateFlags	flags
			*renderPass,								// VkRenderPass				renderPass
			2u,											// uint32_t					attachmentCount
			attachments,								// const VkImageView*		pAttachments
			m_width,									// uint32_t					width
			m_height,									// uint32_t					height
			1u											// uint32_t					layers
		};

		framebuffer = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
	}

	// Generate quad vertices
	{
		const tcu::Vec4	lowerLeftVertex		(-1.0f, -1.0f, 0.5f, 1.0f);
		const tcu::Vec4	lowerRightVertex	(1.0f, -1.0f, 0.5f, 1.0f);
		const tcu::Vec4	upperLeftVertex		(-1.0f, 1.0f, 0.5f, 1.0f);
		const tcu::Vec4	upperRightVertex	(1.0f, 1.0f, 0.5f, 1.0f);

		vertexData.push_back(lowerLeftVertex);
		vertexData.push_back(upperLeftVertex);
		vertexData.push_back(lowerRightVertex);
		vertexData.push_back(upperRightVertex);
	}

	// Upload vertex data.
	{
		const size_t				vertexDataSize		= vertexData.size() * sizeof(Vec4);

		const VkBufferCreateInfo	vertexBufferParams	=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	//	VkStructureType		sType
			DE_NULL,								//	const void*			pNext
			0u,										//	VkBufferCreateFlags	flags
			(VkDeviceSize)vertexDataSize,			//	VkDeviceSize		size
			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		//	VkBufferUsageFlags	usage
			VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode		sharingMode
			1u,										//	deUint32			queueFamilyCount
			&queueFamilyIndex,						//	const deUint32*		pQueueFamilyIndices
		};

		vertexBuffer		= createBuffer(vkd, m_context.getDevice(), &vertexBufferParams);
		vertexBufferMemory	= createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *vertexBuffer);

		deMemcpy(vertexBufferMemory->getHostPtr(), vertexData.data(), vertexDataSize);
		flushAlloc(vkd, device, *vertexBufferMemory);
	}

	beginCommandBuffer(vkd, *commandBuffer);
	vkd.cmdBindPipeline(*commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *renderPipeline);

	if (!isDSFormat)
		vkd.cmdBindDescriptorSets(*commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);

	// Begin render pass.
	{
		VkRect2D					renderArea	=
		{
			{ 0u, 0u },				// VkOffset2D	offset
			{ m_width, m_height }	// VkExtent2D	extent
		};

		const VkRenderPassBeginInfo	beginInfo	=
		{
			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType
			DE_NULL,									// const void*			pNext
			*renderPass,								// VkRenderPass			renderPass
			*framebuffer,								// VkFramebuffer		framebuffer
			renderArea,									// VkRect2D				renderArea
			0u,											// uint32_t				clearValueCount
			DE_NULL										// const VkClearValue*	pClearValues
		};

		RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
	}

	const VkDeviceSize bindingOffset = 0;

	vkd.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *renderPipeline);
	vkd.cmdDraw(*commandBuffer, 4u, 1u, 0u, 0u);
	RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);

	// Copy results to a buffer.
	if (isDSFormat)
	{
		copyDepthStencilImageToBuffers(vkd, *commandBuffer, *dsImage, *resultBuffer0, *resultBuffer1, tcu::IVec2(m_width, m_height), VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
	}
	else
	{
		copyImageToBuffer(vkd, *commandBuffer, *colorImage, *resultBuffer0, tcu::IVec2(m_width, m_height), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
	}

	endCommandBuffer(vkd, *commandBuffer);
	submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
	invalidateMappedMemoryRange(vkd, m_context.getDevice(), resultBuffer0Memory->getMemory(), resultBuffer0Memory->getOffset(), VK_WHOLE_SIZE);
	invalidateMappedMemoryRange(vkd, m_context.getDevice(), resultBuffer1Memory->getMemory(), resultBuffer1Memory->getOffset(), VK_WHOLE_SIZE);

	// Verify result.
	{
		const tcu::TextureFormat	format		(mapVkFormat(m_format));
		tcu::TextureLevel			reference	(format, m_width, m_height);

		if (isDSFormat)
		{
			const void* const					ptrDepth				(resultBuffer0Memory->getHostPtr());
			const void* const					ptrStencil				(resultBuffer1Memory->getHostPtr());
			const tcu::ConstPixelBufferAccess	resultDepthAccess		(getDepthCopyFormat(m_format), m_width, m_height, 1, ptrDepth);
			const tcu::ConstPixelBufferAccess	resultStencilAccess		(getStencilCopyFormat(m_format), m_width, m_height, 1, ptrStencil);
			const PixelBufferAccess				referenceDepthAccess	(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_DEPTH));
			const PixelBufferAccess				referenceStencilAccess	(tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_STENCIL));
			const float							depthThreshold			(1.0f / ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(resultDepthAccess.getFormat()).cast<deUint32>()) - 1u).cast<float>().x());

			for (deUint32 x = 0; x < m_width; x++)
				for (deUint32 y = 0; y < m_height; y++)
				{
					float depthValue = ((x / tileSize) % 2 != (y / tileSize) % 2) ? depthInitValues[0] : depthInitValues[1];
					referenceDepthAccess.setPixDepth(depthValue, x, y, 0);
					referenceStencilAccess.setPixel(tcu::IVec4(0.5f < depthValue ? stencilRefValue : 0), x, y, 0);
				}

			if (!verifyDepth(m_context, reference.getAccess(), resultDepthAccess, depthThreshold))
				m_resultCollector.fail("Depth compare failed.");

			if (!verifyStencil(m_context, referenceStencilAccess, resultStencilAccess))
				m_resultCollector.fail("Stencil compare failed.");
		}
		else
		{
			const void* const					ptrResult		(resultBuffer0Memory->getHostPtr());
			const tcu::ConstPixelBufferAccess	resultAccess	(format, m_width, m_height, 1, ptrResult);
			const PixelBufferAccess				referenceAccess	(reference.getAccess());

			for (deUint32 x = 0; x < m_width; x++)
				for (deUint32 y = 0; y < m_height; y++)
				{
					const tcu::Vec4	initValue	= ((x / tileSize) % 2 != (y / tileSize) % 2) ? colorInitValues[0] : colorInitValues[1];
					const tcu::Vec4	refValue	= tcu::Vec4(initValue.x(), initValue.y(), initValue.x() + initValue.y(), 1.0f);

					referenceAccess.setPixel(refValue, x, y, 0);
				}

			if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(),	// log
											"Rendered result",						// imageSetName
											"",										// imageSetDesc
											referenceAccess,						// reference
											resultAccess,							// result
											Vec4(0.01f),							// threshold
											tcu::COMPARE_LOG_RESULT))				// logMode
			{
				m_resultCollector.fail("Image compare failed.");
			}
		}

	}

	return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
}

struct SingleAttachmentTestConfig
{
		SingleAttachmentTestConfig	(VkFormat		format_,
									 RenderPassType	renderPassType_)
		: format			(format_)
		, renderPassType	(renderPassType_)
	{
	}

	VkFormat		format;
	RenderPassType	renderPassType;
};

class SingleAttachmentTestInstance : public TestInstance
{
public:
							SingleAttachmentTestInstance	(Context&					context,
															 SingleAttachmentTestConfig	testConfig);

							~SingleAttachmentTestInstance	(void);

	tcu::TestStatus			iterate							(void);

	template<typename RenderpassSubpass>
	tcu::TestStatus			iterateInternal					(void);

private:
	const bool				m_extensionSupported;
	const RenderPassType	m_renderPassType;

	const deUint32			m_width;
	const deUint32			m_height;
	const VkFormat			m_format;
	tcu::ResultCollector	m_resultCollector;
};

SingleAttachmentTestInstance::SingleAttachmentTestInstance (Context& context, SingleAttachmentTestConfig testConfig)
	: TestInstance			(context)
	, m_extensionSupported	((testConfig.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
	, m_renderPassType		(testConfig.renderPassType)
	, m_width				(256u)
	, m_height				(256u)
	, m_format				(testConfig.format)
{
}

SingleAttachmentTestInstance::~SingleAttachmentTestInstance (void)
{
}

tcu::TestStatus SingleAttachmentTestInstance::iterate (void)
{
	switch (m_renderPassType)
	{
		case RENDERPASS_TYPE_LEGACY:
			return iterateInternal<RenderpassSubpass1>();
		case RENDERPASS_TYPE_RENDERPASS2:
			return iterateInternal<RenderpassSubpass2>();
		default:
			TCU_THROW(InternalError, "Impossible");
	}
}

template<typename RenderpassSubpass>
tcu::TestStatus SingleAttachmentTestInstance::iterateInternal (void)
{
	const DeviceInterface&								vkd					(m_context.getDeviceInterface());
	const VkDevice										device				= m_context.getDevice();
	const VkQueue										queue				= m_context.getUniversalQueue();
	const deUint32										queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
	const Unique<VkCommandPool>							commandPool			(createCommandPool(vkd, m_context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex));
	const Unique<VkCommandBuffer>						commandBuffer		(allocateCommandBuffer(vkd, m_context.getDevice(), *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
	const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo	(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo		(DE_NULL);
	const tcu::Vec4										colorInitValues[2]	= { tcu::Vec4(0.2f, 0.4f, 0.1f, 1.0f), tcu::Vec4(0.5f, 0.4f, 0.7f, 1.0f) };
	const VkExtent3D									imageExtent			= { m_width, m_height, 1u };
	vector<Vec4>										vertexData;
	Move<VkImage>										colorImage;
	Move<VkImage>										resultImage;
	de::MovePtr<Allocation>								colorImageAllocation;
	de::MovePtr<Allocation>								resultImageAllocation;
	Move<VkImageView>									imageViewInput;
	Move<VkImageView>									imageViewResult;
	Move<VkPipelineLayout>								pipelineLayoutInput;
	Move<VkPipelineLayout>								pipelineLayoutImageSampler;
	Move<VkPipeline>									pipelineSolidColor;
	Move<VkPipeline>									pipelineInputAtt;
	Move<VkPipeline>									pipelineImageSampler;
	Move<VkFramebuffer>									framebuffer1;
	Move<VkFramebuffer>									framebuffer0;
	Move<VkRenderPass>									renderPass0;
	Move<VkRenderPass>									renderPass1;
	Move<VkBuffer>										resultBuffer;
	de::MovePtr<Allocation>								resultBufferMemory;
	Move<VkBuffer>										vertexBuffer;
	de::MovePtr<Allocation>								vertexBufferMemory;
	Move<VkSampler>										sampler;

	// Create image used for both input and output.
	{
		VkImageUsageFlags		usage			= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
												  | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT
												  | VK_IMAGE_USAGE_SAMPLED_BIT;

		const VkImageCreateInfo	imageCreateInfo	=
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
			DE_NULL,								// const void*				pNext
			0u,										// VkImageCreateFlags		flags
			VK_IMAGE_TYPE_2D,						// VkImageType				imageType
			m_format,								// VkFormat					format
			imageExtent,							// VkExtent3D				extent
			1u,										// uint32_t					mipLevels
			1u,										// uint32_t					arrayLayers
			VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
			usage,									// VkImageUsageFlags		usage
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
			1u,										// uint32_t					queueFamilyIndexCount
			&queueFamilyIndex,						// const uint32_t*			pQueueFamilyIndices
			VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
		};

		checkImageSupport(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), imageCreateInfo);

		colorImage = createImage(vkd, device, &imageCreateInfo, DE_NULL);
		colorImageAllocation = m_context.getDefaultAllocator().allocate(getImageMemoryRequirements(vkd, device, *colorImage), MemoryRequirement::Any);
		VK_CHECK(vkd.bindImageMemory(device, *colorImage, colorImageAllocation->getMemory(), colorImageAllocation->getOffset()));
	}

	// Create image used for final result.
	{
		VkImageUsageFlags		usage			= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;

		const VkImageCreateInfo	imageCreateInfo	=
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
			DE_NULL,								// const void*				pNext
			0u,										// VkImageCreateFlags		flags
			VK_IMAGE_TYPE_2D,						// VkImageType				imageType
			m_format,								// VkFormat					format
			imageExtent,							// VkExtent3D				extent
			1u,										// uint32_t					mipLevels
			1u,										// uint32_t					arrayLayers
			VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling
			usage,									// VkImageUsageFlags		usage
			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode
			1u,										// uint32_t					queueFamilyIndexCount
			&queueFamilyIndex,						// const uint32_t*			pQueueFamilyIndices
			VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout
		};

		checkImageSupport(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), imageCreateInfo);

		resultImage = createImage(vkd, device, &imageCreateInfo, DE_NULL);
		resultImageAllocation = m_context.getDefaultAllocator().allocate(getImageMemoryRequirements(vkd, device, *resultImage), MemoryRequirement::Any);
		VK_CHECK(vkd.bindImageMemory(device, *resultImage, resultImageAllocation->getMemory(), resultImageAllocation->getOffset()));
	}

	// Initialize color image. This is expected to be cleared later.
	initColorImageChessboardPattern(vkd, device, queue, queueFamilyIndex, m_context.getDefaultAllocator(), *colorImage, m_format, colorInitValues[0], colorInitValues[1], m_width, m_height, 32u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
	// Initialize result image. This will be overwritten later.
	initColorImageChessboardPattern(vkd, device, queue, queueFamilyIndex, m_context.getDefaultAllocator(), *resultImage, m_format, colorInitValues[0], colorInitValues[1], m_width, m_height, 32u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);

	// Create image views.
	{
		const VkImageViewCreateInfo imageViewCreateInfo =
		{
			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType
			DE_NULL,									// const void*				pNext
			0u,											// VkImageViewCreateFlags	flags
			*colorImage,								// VkImage					image
			VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType
			m_format,									// VkFormat					format
			makeComponentMappingRGBA(),					// VkComponentMapping		components
			{											// VkImageSubresourceRange	subresourceRange
				VK_IMAGE_ASPECT_COLOR_BIT,
				0u,
				1u,
				0u,
				1u
			}
		};

		imageViewInput = createImageView(vkd, device, &imageViewCreateInfo);
	}

	{
		const VkImageViewCreateInfo imageViewCreateInfo =
		{
			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType
			DE_NULL,									// const void*				pNext
			0u,											// VkImageViewCreateFlags	flags
			*resultImage,								// VkImage					image
			VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType
			m_format,									// VkFormat					format
			makeComponentMappingRGBA(),					// VkComponentMapping		components
			{											// VkImageSubresourceRange	subresourceRange
				VK_IMAGE_ASPECT_COLOR_BIT,
				0u,
				1u,
				0u,
				1u
			}
		};

		imageViewResult = createImageView(vkd, device, &imageViewCreateInfo);
	}

	// Create result buffer.
	{
		resultBuffer		= createBuffer(vkd, device, m_format, m_width, m_height);
		resultBufferMemory	= createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *resultBuffer);
	}

	// Create sampler.
	{
		const VkSamplerCreateInfo samplerInfo =
		{
			VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,		// VkStructureType			sType
			DE_NULL,									// const void*				pNext
			0u,											// VkSamplerCreateFlags		flags
			VK_FILTER_NEAREST,							// VkFilter					magFilter
			VK_FILTER_NEAREST,							// VkFilter					minFilter
			VK_SAMPLER_MIPMAP_MODE_NEAREST,				// VkSamplerMipmapMode		mipmapMode
			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeU
			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeV
			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeW
			0.0f,										// float					mipLodBias
			VK_FALSE,									// VkBool32					anisotropyEnable
			1.0f,										// float					maxAnisotropy
			VK_FALSE,									// VkBool32					compareEnable
			VK_COMPARE_OP_ALWAYS,						// VkCompareOp				compareOp
			0.0f,										// float					minLod
			0.0f,										// float					maxLod
			VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,	// VkBorderColor			borderColor
			VK_FALSE,									// VkBool32					unnormalizedCoordinates
		};

		sampler = createSampler(vkd, device, &samplerInfo);
	}

	// Create descriptor set layouts.
	Unique<VkDescriptorSetLayout>	descriptorSetLayoutInput	(DescriptorSetLayoutBuilder()
			.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT)
			.build(vkd, device));

	Unique<VkDescriptorSetLayout>	descriptorSetLayoutImageSampler	(DescriptorSetLayoutBuilder()
			.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT)
			.build(vkd, device));

	// Create descriptor pool.
	Unique<VkDescriptorPool>		descriptorPool		(DescriptorPoolBuilder()
			.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u)
			.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1u)
			.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 2u));

	// Create desriptor sets.
	Unique<VkDescriptorSet>			descriptorSetInput	(makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayoutInput));
	Unique<VkDescriptorSet>			descriptorSetImageSampler	(makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayoutImageSampler));

	// Update descriptor set information.
	VkDescriptorImageInfo			descIOAttachment	= makeDescriptorImageInfo(DE_NULL, *imageViewInput, VK_IMAGE_LAYOUT_GENERAL);
	VkDescriptorImageInfo			descImageSampler	= makeDescriptorImageInfo(*sampler, *imageViewInput, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);

	DescriptorSetUpdateBuilder()
		.writeSingle(*descriptorSetInput, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descIOAttachment)
		.update(vkd, device);

	DescriptorSetUpdateBuilder()
		.writeSingle(*descriptorSetImageSampler, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descImageSampler)
		.update(vkd, device);

	// Create pipeline layouts.
	{
		const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
		{
			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType
			DE_NULL,										// const void*					pNext
			(vk::VkPipelineLayoutCreateFlags)0,				// VkPipelineLayoutCreateFlags	flags
			1u,												// deUint32						setLayoutCount
			&descriptorSetLayoutInput.get(),				// const VkDescriptorSetLayout*	pSetLayouts
			0u,												// deUint32						pushConstantRangeCount
			DE_NULL											// const VkPushConstantRange*	pPushConstantRanges
		};

		pipelineLayoutInput = createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);
	}
	{
		const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
		{
			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType
			DE_NULL,										// const void*					pNext
			(vk::VkPipelineLayoutCreateFlags)0,				// VkPipelineLayoutCreateFlags	flags
			1u,												// deUint32						setLayoutCount
			&descriptorSetLayoutImageSampler.get(),			// const VkDescriptorSetLayout*	pSetLayouts
			0u,												// deUint32						pushConstantRangeCount
			DE_NULL											// const VkPushConstantRange*	pPushConstantRanges
		};

		pipelineLayoutImageSampler = createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);
	}

	// Create render passes.
	{
		vector<Attachment>			attachments;
		vector<AttachmentReference>	colorAttachmentReferences;

		attachments.push_back(Attachment(m_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
										 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
										 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));

		colorAttachmentReferences.push_back(AttachmentReference(0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));

		const vector<Subpass>			subpasses	(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
													 colorAttachmentReferences, vector<AttachmentReference>(),
													 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<deUint32>()));

		renderPass1 = createRenderPass(vkd, device, RenderPass(attachments, subpasses, vector<SubpassDependency>()), m_renderPassType);
	}
	{
		vector<Attachment>			attachments;
		vector<AttachmentReference>	colorAttachmentReferences;
		vector<AttachmentReference>	inputAttachmentReferences;

		const VkImageAspectFlags	inputAttachmentAspectMask	((m_renderPassType == RENDERPASS_TYPE_RENDERPASS2)
																? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT)
																: static_cast<VkImageAspectFlags>(0));

		attachments.push_back(Attachment(m_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE,
										 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL));

		colorAttachmentReferences.push_back(AttachmentReference(0u, VK_IMAGE_LAYOUT_GENERAL));
		inputAttachmentReferences.push_back(AttachmentReference(0u, VK_IMAGE_LAYOUT_GENERAL, inputAttachmentAspectMask));

		const vector<Subpass>			subpasses		(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, inputAttachmentReferences,
														 colorAttachmentReferences, vector<AttachmentReference>(),
														 AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<deUint32>()));

		const vector<SubpassDependency>	dependencies	(1, SubpassDependency(0u, 0u, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
														 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
														 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, VK_DEPENDENCY_BY_REGION_BIT));

		renderPass0 = createRenderPass(vkd, device, RenderPass(attachments, subpasses, dependencies), m_renderPassType);
	}

	// Create pipelines.
	{
		const Unique<VkShaderModule>				vertexShaderModule				(createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u));
		const Unique<VkShaderModule>				fragmentShaderModuleInputAtt	(createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag_input_attachment"), 0u));
		const Unique<VkShaderModule>				fragmentShaderModuleSolidColor	(createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag_solid_color"), 0u));
		const Unique<VkShaderModule>				fragmentShaderModuleSampler		(createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag_combined_image_sampler"), 0u));

		const VkVertexInputBindingDescription		vertexBinding0					=
		{
			0u,							// deUint32					binding
			sizeof(Vec4),				// deUint32					strideInBytes
			VK_VERTEX_INPUT_RATE_VERTEX	// VkVertexInputStepRate	stepRate
		};

		const VkVertexInputAttributeDescription		attr0							=
		{
			0u,								// deUint32	location
			0u,								// deUint32	binding
			VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat	format
			0u								// deUint32	offsetInBytes
		};

		const VkPipelineVertexInputStateCreateInfo	vertexInputState				=
		{
			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType
			DE_NULL,													// const void*								pNext
			(VkPipelineVertexInputStateCreateFlags)0u,					// VkPipelineVertexInputStateCreateFlags	flags
			1u,															// deUint32									vertexBindingDescriptionCount
			&vertexBinding0,											// const VkVertexInputBindingDescription*	pVertexBindingDescriptions
			1u,															// deUint32									vertexAttributeDescriptionCount
			&attr0														// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions
		};

		const std::vector<VkViewport>				viewports						(1, makeViewport(tcu::UVec2(m_width, m_height)));
		const std::vector<VkRect2D>					scissors						(1, makeRect2D(tcu::UVec2(m_width, m_height)));

		const VkPipelineColorBlendAttachmentState		colorBlendAttachmentState	=
		{
			VK_TRUE,								// VkBool32					blendEnable
			VK_BLEND_FACTOR_ONE,					// VkBlendFactor			srcColorBlendFactor
			VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,	// VkBlendFactor			dstColorBlendFactor
			VK_BLEND_OP_ADD,						// VkBlendOp				colorBlendOp
			VK_BLEND_FACTOR_ONE,					// VkBlendFactor			srcAlphaBlendFactor
			VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,	// VkBlendFactor			dstAlphaBlendFactor
			VK_BLEND_OP_ADD,						// VkBlendOp				alphaBlendOp
			VK_COLOR_COMPONENT_R_BIT				// VkColorComponentFlags	colorWriteMask
				| VK_COLOR_COMPONENT_G_BIT
				| VK_COLOR_COMPONENT_B_BIT
				| VK_COLOR_COMPONENT_A_BIT
		};

		const VkPipelineColorBlendStateCreateInfo		colorBlendState				=
		{
			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType
			DE_NULL,													// const void*									pNext
			0u,															// VkPipelineColorBlendStateCreateFlags			flags
			VK_FALSE,													// VkBool32										logicOpEnable
			VK_LOGIC_OP_CLEAR,											// VkLogicOp									logicOp
			1u,															// deUint32										attachmentCount
			&colorBlendAttachmentState,									// const VkPipelineColorBlendAttachmentState*	pAttachments
			{ 0.0f, 0.0f, 0.0f, 0.0f }									// float										blendConstants[4]
		};

		pipelineSolidColor = makeGraphicsPipeline(vkd,		// const DeviceInterface&							vk
				device,										// const VkDevice									device
				*pipelineLayoutInput,						// const VkPipelineLayout							pipelineLayout
				*vertexShaderModule,						// const VkShaderModule								vertexShaderModule
				DE_NULL,									// const VkShaderModule								tessellationControlShaderModule
				DE_NULL,									// const VkShaderModule								tessellationEvalShaderModule
				DE_NULL,									// const VkShaderModule								geometryShaderModule
				*fragmentShaderModuleSolidColor,			// const VkShaderModule								fragmentShaderModule
				*renderPass0,								// const VkRenderPass								renderPass
				viewports,									// const std::vector<VkViewport>&					viewports
				scissors,									// const std::vector<VkRect2D>&						scissors
				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,		// const VkPrimitiveTopology						topology
				0u,											// const deUint32									subpass
				0u,											// const deUint32									patchControlPoints
				&vertexInputState,							// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
				DE_NULL,									// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
				DE_NULL,									// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
				DE_NULL,									// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
				&colorBlendState);							// const VkPipelineColorBlendStateCreateInfo*		colorBlendStateCreateInfo

		pipelineInputAtt = makeGraphicsPipeline(vkd,		// const DeviceInterface&							vk
				device,										// const VkDevice									device
				*pipelineLayoutInput,						// const VkPipelineLayout							pipelineLayout
				*vertexShaderModule,						// const VkShaderModule								vertexShaderModule
				DE_NULL,									// const VkShaderModule								tessellationControlShaderModule
				DE_NULL,									// const VkShaderModule								tessellationEvalShaderModule
				DE_NULL,									// const VkShaderModule								geometryShaderModule
				*fragmentShaderModuleInputAtt,				// const VkShaderModule								fragmentShaderModule
				*renderPass0,								// const VkRenderPass								renderPass
				viewports,									// const std::vector<VkViewport>&					viewports
				scissors,									// const std::vector<VkRect2D>&						scissors
				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,		// const VkPrimitiveTopology						topology
				0u,											// const deUint32									subpass
				0u,											// const deUint32									patchControlPoints
				&vertexInputState,							// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
				DE_NULL,									// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
				DE_NULL,									// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
				DE_NULL,									// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
				&colorBlendState);							// const VkPipelineColorBlendStateCreateInfo*		colorBlendStateCreateInfo

		pipelineImageSampler = makeGraphicsPipeline(vkd,	// const DeviceInterface&							vk
				device,										// const VkDevice									device
				*pipelineLayoutImageSampler,				// const VkPipelineLayout							pipelineLayout
				*vertexShaderModule,						// const VkShaderModule								vertexShaderModule
				DE_NULL,									// const VkShaderModule								tessellationControlShaderModule
				DE_NULL,									// const VkShaderModule								tessellationEvalShaderModule
				DE_NULL,									// const VkShaderModule								geometryShaderModule
				*fragmentShaderModuleSampler,				// const VkShaderModule								fragmentShaderModule
				*renderPass1,								// const VkRenderPass								renderPass
				viewports,									// const std::vector<VkViewport>&					viewports
				scissors,									// const std::vector<VkRect2D>&						scissors
				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,		// const VkPrimitiveTopology						topology
				0u,											// const deUint32									subpass
				0u,											// const deUint32									patchControlPoints
				&vertexInputState,							// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
				DE_NULL,									// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
				DE_NULL,									// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
				DE_NULL,									// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
				&colorBlendState);							// const VkPipelineColorBlendStateCreateInfo*		colorBlendStateCreateInfo
	}

	// Create framebuffers.
	{
		const VkFramebufferCreateInfo	framebufferCreateInfo	=
		{
			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType
			DE_NULL,									// const void*				pNext
			0u,											// VkFramebufferCreateFlags	flags
			*renderPass0,								// VkRenderPass				renderPass
			1u,											// uint32_t					attachmentCount
			&imageViewInput.get(),						// const VkImageView*		pAttachments
			256u,										// uint32_t					width
			256u,										// uint32_t					height
			1u											// uint32_t					layers
		};

		framebuffer0 = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
	}
	{
		const VkFramebufferCreateInfo	framebufferCreateInfo	=
		{
			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType
			DE_NULL,									// const void*				pNext
			0u,											// VkFramebufferCreateFlags	flags
			*renderPass1,								// VkRenderPass				renderPass
			1u,											// uint32_t					attachmentCount
			&imageViewResult.get(),						// const VkImageView*		pAttachments
			m_width,									// uint32_t					width
			m_height,									// uint32_t					height
			1u											// uint32_t					layers
		};

		framebuffer1 = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
	}

	// Generate quad vertices.
	{
		const tcu::Vec4	lowerLeftVertex		(-1.0f, -1.0f, 0.5f, 1.0f);
		const tcu::Vec4	lowerRightVertex	(1.0f, -1.0f, 0.5f, 1.0f);
		const tcu::Vec4	upperLeftVertex		(-1.0f, 1.0f, 0.5f, 1.0f);
		const tcu::Vec4	upperRightVertex	(1.0f, 1.0f, 0.5f, 1.0f);

		vertexData.push_back(lowerLeftVertex);
		vertexData.push_back(upperLeftVertex);
		vertexData.push_back(lowerRightVertex);
		vertexData.push_back(upperRightVertex);
	}

	// Upload vertex data.
	{
		const size_t				vertexDataSize		= vertexData.size() * sizeof(Vec4);

		const VkBufferCreateInfo	vertexBufferParams	=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	//	VkStructureType		sType
			DE_NULL,								//	const void*			pNext
			0u,										//	VkBufferCreateFlags	flags
			(VkDeviceSize)vertexDataSize,			//	VkDeviceSize		size
			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		//	VkBufferUsageFlags	usage
			VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode		sharingMode
			1u,										//	deUint32			queueFamilyCount
			&queueFamilyIndex,						//	const deUint32*		pQueueFamilyIndices
		};

		vertexBuffer		= createBuffer(vkd, m_context.getDevice(), &vertexBufferParams);
		vertexBufferMemory	= createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *vertexBuffer);

		deMemcpy(vertexBufferMemory->getHostPtr(), vertexData.data(), vertexDataSize);
		flushAlloc(vkd, device, *vertexBufferMemory);
	}

	beginCommandBuffer(vkd, *commandBuffer);

	// Begin render pass.
	{
		const VkRect2D				renderArea	=
		{
			{ 0u, 0u },				// VkOffset2D	offset
			{ m_width, m_height }	// VkExtent2D	extent
		};

		const VkClearValue			clearValue	= makeClearValueColor(Vec4(0.0f, 0.0f, 0.0f, 0.0f));

		const VkRenderPassBeginInfo	beginInfo	=
		{
			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType
			DE_NULL,									// const void*			pNext
			*renderPass0,								// VkRenderPass			renderPass
			*framebuffer0,								// VkFramebuffer		framebuffer
			renderArea,									// VkRect2D				renderArea
			1u,											// uint32_t				clearValueCount
			&clearValue									// const VkClearValue*	pClearValues
		};

		RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
	}

	// Bind pipeline.
	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineSolidColor);

	// Bind vertex buffer.
	const VkDeviceSize bindingOffset = 0;
	vkd.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer.get(), &bindingOffset);

	// Bind descriptor set.
	vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayoutInput, 0u, 1u, &*descriptorSetInput, 0u, DE_NULL);

	// Draw solid color.
	vkd.cmdDraw(*commandBuffer, 4u, 1u, 0u, 0u);

	// Bind pipeline.
	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineInputAtt);

	// Bind descriptor set.
	vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayoutInput, 0u, 1u, &*descriptorSetInput, 0u, DE_NULL);

	// Pipeline barrier to handle self dependency.
	{
		const VkImageMemoryBarrier imageBarrier =
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType
			DE_NULL,										// const void*				pNext
			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			srcAccessMask
			VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,			// VkAccessFlags			dstAccessMask
			VK_IMAGE_LAYOUT_GENERAL,						// VkImageLayout			oldLayout
			VK_IMAGE_LAYOUT_GENERAL,						// VkImageLayout			newLayout
			VK_QUEUE_FAMILY_IGNORED,						// uint32_t					srcQueueFamilyIndex
			VK_QUEUE_FAMILY_IGNORED,						// uint32_t					dstQueueFamilyIndex
			*colorImage,									// VkImage					image
			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange
		};

		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
	}

	// Draw. Adds (0.1, 0.2, 0.0, 0.0) to the previous result.
	vkd.cmdDraw(*commandBuffer, 4u, 1u, 0u, 0u);

	// End render pass.
	RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);

	// Pipeline barrier.
	{
		const VkImageMemoryBarrier imageBarriers[] =
		{
			{
				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType
				DE_NULL,										// const void*				pNext
				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
				| VK_ACCESS_TRANSFER_WRITE_BIT
				| VK_ACCESS_HOST_WRITE_BIT,						// VkAccessFlags			srcAccessMask
				VK_ACCESS_SHADER_READ_BIT,						// VkAccessFlags			dstAccessMask
				VK_IMAGE_LAYOUT_GENERAL,						// VkImageLayout			oldLayout
				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,		// VkImageLayout			newLayout
				VK_QUEUE_FAMILY_IGNORED,						// uint32_t					srcQueueFamilyIndex
				VK_QUEUE_FAMILY_IGNORED,						// uint32_t					dstQueueFamilyIndex
				*colorImage,									// VkImage					image
				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange
			},
			{
				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType
				DE_NULL,										// const void*				pNext
				VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			srcAccessMask
				VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
				| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			oldLayout
				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			newLayout
				VK_QUEUE_FAMILY_IGNORED,						// uint32_t					srcQueueFamilyIndex
				VK_QUEUE_FAMILY_IGNORED,						// uint32_t					dstQueueFamilyIndex
				*resultImage,									// VkImage					image
				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange
			}
		};

		vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 2u, imageBarriers);
	}

	// Begin render pass.
	{
		const VkRect2D				renderArea	=
		{
			{ 0, 0 },	            // VkOffset2D	offset
			{ m_width, m_height }	// VkExtent2D	extent
		};

		const VkRenderPassBeginInfo	beginInfo	=
		{
			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType
			DE_NULL,									// const void*			pNext
			*renderPass1,								// VkRenderPass			renderPass
			*framebuffer1,								// VkFramebuffer		framebuffer
			renderArea,									// VkRect2D				renderArea
			0u,											// uint32_t				clearValueCount
			DE_NULL										// const VkClearValue*	pClearValues
		};

		RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
	}

	// Bind pipeline.
	vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineImageSampler);

	// Bind descriptor set.
	vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayoutImageSampler, 0u, 1u, &*descriptorSetImageSampler, 0u, DE_NULL);

	// Draw. Samples the previous results and adds (0.1, 0.2, 0.0, 0.0).
	vkd.cmdDraw(*commandBuffer, 4u, 1u, 0u, 0u);

	// End render pass.
	RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);

	// Copy results to a buffer.
	copyImageToBuffer(vkd, *commandBuffer, *resultImage, *resultBuffer, tcu::IVec2(m_width, m_height), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);

	endCommandBuffer(vkd, *commandBuffer);
	submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
	invalidateMappedMemoryRange(vkd, m_context.getDevice(), resultBufferMemory->getMemory(), resultBufferMemory->getOffset(), VK_WHOLE_SIZE);

	// Verify results.
	{
		const tcu::TextureFormat			format			(mapVkFormat(m_format));
		tcu::TextureLevel					reference		(format, m_width, m_height);
		const void* const					ptrResult		(resultBufferMemory->getHostPtr());
		const tcu::ConstPixelBufferAccess	resultAccess	(format, m_width, m_height, 1, ptrResult);
		const PixelBufferAccess				referenceAccess	(reference.getAccess());

		for (deUint32 x = 0; x < m_width; x++)
			for (deUint32 y = 0; y < m_height; y++)
			{
				referenceAccess.setPixel(tcu::Vec4(0.3f, 0.6f, 0.0f, 1.0f), x, y, 0);
			}

		if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(),	// log
										"Rendered result",						// imageSetName
										"",										// imageSetDesc
										referenceAccess,						// reference
										resultAccess,							// result
										Vec4(0.05f),							// threshold
										tcu::COMPARE_LOG_RESULT))				// logMode
		{
			m_resultCollector.fail("Image compare failed.");
		}
	}

	return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
}

// Shader programs for testing dependencies between render pass instances
struct ExternalPrograms
{
	void init (vk::SourceCollections& dst, ExternalTestConfig testConfig) const
	{
		for (size_t renderPassNdx = 0; renderPassNdx < testConfig.renderPasses.size(); renderPassNdx++)
		{
			dst.glslSources.add("quad-vert-" + de::toString(renderPassNdx)) << glu::VertexSource(
				"#version 450\n"
				"layout(location = 0) out highp vec2 vtxTexCoords;\n"
				"highp float;\n"
				"void main (void)\n"
				"{\n"
				"    vec4 position;"
				"    position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
				"                    ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
				"    gl_Position = position;\n"
				"	vtxTexCoords = position.xy / 2.0 + vec2(0.5);"
				"}\n");

			// First pass renders four quads of different color
			if (renderPassNdx == 0)
			{
				dst.glslSources.add("quad-frag-" + de::toString(renderPassNdx)) << glu::FragmentSource(
					"#version 450\n"
					"layout(location = 0) in highp vec2 vtxTexCoords;\n"
					"layout(location = 0) out highp vec4 o_color;\n"
					"void main (void)\n"
					"{\n"
					"    if (gl_FragCoord.x <= " + de::toString(testConfig.imageSize.x() / 2) + " && gl_FragCoord.y <= " + de::toString(testConfig.imageSize.y() / 2) + ")\n"
					"        o_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
					"    else if (gl_FragCoord.x > " + de::toString(testConfig.imageSize.x() / 2) + " && gl_FragCoord.y <= " + de::toString(testConfig.imageSize.y() / 2) + ")\n"
					"        o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
					"    else if (gl_FragCoord.x <= " + de::toString(testConfig.imageSize.x() / 2) + " && gl_FragCoord.y > " + de::toString(testConfig.imageSize.y() / 2) + ")\n"
					"        o_color = vec4(0.0, 0.0, 1.0, 1.0);\n"
					"    else\n"
					"        o_color = vec4(0.0, 0.0, 0.0, 1.0);\n"
					""
					"}\n");
			}
			else
			{
				if (renderPassNdx % 2 == 0)
				{
					// Blur previous pass horizontally
					dst.glslSources.add("quad-frag-" + de::toString(renderPassNdx)) << glu::FragmentSource(
						"#version 450\n"
						"layout(binding = 0) uniform sampler2D previousPass;\n"
						"layout(location = 0) in highp vec2 vtxTexCoords;\n"
						"layout(location = 0) out highp vec4 o_color;\n"
						"void main (void)\n"
						"{\n"
						"    vec2 step = vec2(1.0 / " + de::toString(testConfig.imageSize.x()) + ", 1.0 / " + de::toString(testConfig.imageSize.y()) + ");\n"
						"    vec2 minCoord = vec2(0.0, 0.0);\n"
						"    vec2 maxCoord = vec2(1.0, 1.0);\n"
						"    vec4 blurColor = vec4(0.0);\n"
						"    for(int sampleNdx = 0; sampleNdx < " + de::toString(testConfig.blurKernel + 1) + "; sampleNdx++)\n"
						"    {\n"
						"        vec2 sampleCoord = vec2((vtxTexCoords.x - " + de::toString(testConfig.blurKernel / 2) + " * step.x) + step.x * sampleNdx, vtxTexCoords.y);\n"
						"        blurColor += 0.12 * texture(previousPass, clamp(sampleCoord, minCoord, maxCoord));\n"
						"    }\n"
						"    o_color = blurColor;\n"
						"}\n");
				}
				else
				{
					// Blur previous pass vertically
					dst.glslSources.add("quad-frag-" + de::toString(renderPassNdx)) << glu::FragmentSource(
						"#version 450\n"
						"layout(binding = 0) uniform highp sampler2D previousPass;\n"
						"layout(location = 0) in highp vec2 vtxTexCoords;\n"
						"layout(location = 0) out highp vec4 o_color;\n"
						"void main (void)\n"
						"{\n"
						"    vec2 step = vec2(1.0 / " + de::toString(testConfig.imageSize.x()) + ", 1.0 / " + de::toString(testConfig.imageSize.y()) + ");\n"
						"    vec2 minCoord = vec2(0.0, 0.0);\n"
						"    vec2 maxCoord = vec2(1.0, 1.0);\n"
						"    vec4 blurColor = vec4(0.0);\n"
						"    for(int sampleNdx = 0; sampleNdx < " + de::toString(testConfig.blurKernel + 1) + "; sampleNdx++)\n"
						"    {\n"
						"        vec2 sampleCoord = vec2(vtxTexCoords.x, (vtxTexCoords.y - " + de::toString(testConfig.blurKernel / 2) + " * step.y) + step.y * sampleNdx);\n"
						"        blurColor += 0.12 * texture(previousPass, clamp(sampleCoord, minCoord, maxCoord));\n"
						"    }\n"
						"    o_color = blurColor;\n"
						"}\n");
				}
			}
		}
	}
};

// Shader programs for testing dependencies between subpasses
struct SubpassPrograms
{
	void init (vk::SourceCollections& dst, SubpassTestConfig testConfig) const
	{
		size_t subpassCount = testConfig.renderPass.getSubpasses().size();

		for (size_t subpassNdx = 0; subpassNdx < subpassCount; subpassNdx++)
		{
			if (subpassNdx == 0)
			{
				dst.glslSources.add("subpass-vert-" + de::toString(subpassNdx)) << glu::VertexSource(
				"#version 450\n"
				"highp float;\n"
				"layout(location = 0) in highp vec4 position;\n"
				"void main (void)\n"
				"{\n"
				"    gl_Position = position;\n"
				"}\n");
			}
			else
			{
				dst.glslSources.add("subpass-vert-" + de::toString(subpassNdx)) << glu::VertexSource(
					"#version 450\n"
					"highp float;\n"
					"void main (void)\n"
					"{\n"
					"    vec4 position;"
					"    position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
					"                    ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
					"    gl_Position = position;\n"
					"}\n");
			}

			if (isDepthStencilFormat(testConfig.format))
			{
				if (subpassNdx == 0)
				{
					// Empty fragment shader: Fragment depth unmodified.
					dst.glslSources.add("subpass-frag-" + de::toString(subpassNdx)) << glu::FragmentSource(
						"#version 450\n"
						"void main (void)\n"
						"{\n"
						"}\n");
				}
				else
				{
					// Use fragment depth from previous depth rendering result.
					dst.glslSources.add("subpass-frag-" + de::toString(subpassNdx)) << glu::FragmentSource(
						"#version 450\n"
						"layout (input_attachment_index = 0, binding = 0) uniform subpassInput depthStencil;\n"
						"void main (void)\n"
						"{\n"
						"    float inputDepth = subpassLoad(depthStencil).x;\n"
						"    gl_FragDepth = inputDepth - 0.02;\n"
						"}\n");
				}
			}
			else
				DE_FATAL("Unimplemented");
		}
	}
};

// Shader programs for testing backwards subpass self dependency from geometry stage to indirect draw
struct SubpassSelfDependencyBackwardsPrograms
{
	void init (vk::SourceCollections& dst, SubpassSelfDependencyBackwardsTestConfig testConfig) const
	{
		DE_UNREF(testConfig);

		dst.glslSources.add("vert") << glu::VertexSource(
				"#version 450\n"
				"layout(location = 0) in highp vec4 position;\n"
				"out gl_PerVertex {\n"
				"    vec4 gl_Position;\n"
				"};\n"
				"void main (void)\n"
				"{\n"
				"    gl_Position = position;\n"
				"}\n");

		dst.glslSources.add("geom") << glu::GeometrySource(
				"#version 450\n"
				"layout(points) in;\n"
				"layout(triangle_strip, max_vertices = 4) out;\n"
				"\n"
				"in gl_PerVertex {\n"
				"    vec4 gl_Position;\n"
				"} gl_in[];\n"
				"\n"
				"out gl_PerVertex {\n"
				"    vec4 gl_Position;\n"
				"};\n"
				"layout (binding = 0) buffer IndirectBuffer\n"
				"{\n"
				"    uint vertexCount;\n"
				"    uint instanceCount;\n"
				"    uint firstVertex;\n"
				"    uint firstInstance;\n"
				"} indirectBuffer;\n"
				"\n"
				"void main (void) {\n"
				"    vec4 p = gl_in[0].gl_Position;\n"
				"    float offset = 0.03f;\n"
				"    gl_Position = p + vec4(-offset, offset, 0, 0);\n"
				"    EmitVertex();\n"
				"    gl_Position = p + vec4(-offset, -offset, 0, 0);\n"
				"    EmitVertex();\n"
				"    gl_Position = p + vec4(offset, offset, 0, 0);\n"
				"    EmitVertex();\n"
				"    gl_Position = p + vec4(offset, -offset, 0, 0);\n"
				"    EmitVertex();\n"
				"    EndPrimitive();\n"
				"    indirectBuffer.vertexCount = 64;\n"
				"    indirectBuffer.instanceCount = 1;\n"
				"    indirectBuffer.firstVertex = 64;\n"
				"    indirectBuffer.firstInstance = 0;\n"
				"}\n");

		dst.glslSources.add("frag") << glu::FragmentSource(
				"#version 450\n"
				"layout(location = 0) out highp vec4 fragColor;\n"
				"void main (void)\n"
				"{\n"
				"    fragColor = vec4(1, 0, 0, 1);\n"
				"}\n");
	}
};

struct SeparateChannelsPrograms
{
	void init (vk::SourceCollections& dst, SeparateChannelsTestConfig testConfig) const
	{
		dst.glslSources.add("vert") << glu::VertexSource(
				"#version 450\n"
				"layout(location = 0) in highp vec4 position;\n"
				"void main (void)\n"
				"{\n"
				"    gl_Position = position;\n"
				"}\n");

		if (isDepthStencilFormat(testConfig.format))
		{
			dst.glslSources.add("frag") << glu::FragmentSource(
					"#version 450\n"
					"layout(location = 0) out highp vec4 fragColor;\n"
					"void main (void)\n"
					"{\n"
					"    fragColor = vec4(1);\n"
					"}\n");
		}
		else
		{
			dst.glslSources.add("frag") << glu::FragmentSource(
					"#version 450\n"
					"layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInput inputAtt;\n"
					"layout(location = 0) out highp vec4 fragColor;\n"
					"void main (void)\n"
					"{\n"
					"    vec4 inputColor = subpassLoad(inputAtt);\n"
					"    fragColor = vec4(1, 1, inputColor.r + inputColor.g, 1);\n"
					"}\n");
		}
	}
};

struct SingleAttachmentPrograms
{
	void init (vk::SourceCollections& dst, SingleAttachmentTestConfig testConfig) const
	{
		DE_UNREF(testConfig);

		dst.glslSources.add("vert") << glu::VertexSource(
				"#version 450\n"
				"layout(location = 0) in highp vec4 position;\n"
				"void main (void)\n"
				"{\n"
				"    gl_Position = position;\n"
				"}\n");

		dst.glslSources.add("frag_solid_color") << glu::FragmentSource(
				"#version 450\n"
				"layout(location = 0) out highp vec4 fragColor;\n"
				"void main (void)\n"
				"{\n"
				"    fragColor = vec4(0.1, 0.2, 0.0, 1.0);\n"
				"}\n");

		dst.glslSources.add("frag_input_attachment") << glu::FragmentSource(
				"#version 450\n"
				"layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInput inputAtt;\n"
				"layout(location = 0) out highp vec4 fragColor;\n"
				"void main (void)\n"
				"{\n"
				"    vec4 inputColor = subpassLoad(inputAtt);\n"
				"    fragColor = inputColor + vec4(0.1, 0.2, 0.0, 0.0);\n"
				"}\n");

		dst.glslSources.add("frag_combined_image_sampler") << glu::FragmentSource(
				"#version 450\n"
				"layout(set = 0, binding = 0) uniform highp sampler2D tex;\n"
				"layout(location = 0) out highp vec4 fragColor;\n"
				"void main (void)\n"
				"{\n"
				"    vec2 uv = vec2(gl_FragCoord) / 255.0;\n"
				"    vec4 inputColor = texture(tex, uv);\n"
				"    fragColor = inputColor + vec4(0.1, 0.2, 0.0, 0.0);\n"
				"}\n");
	}
};

std::string formatToName (VkFormat format)
{
	const std::string	formatStr	= de::toString(format);
	const std::string	prefix		= "VK_FORMAT_";

	DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);

	return de::toLower(formatStr.substr(prefix.length()));
}

void initTests (tcu::TestCaseGroup* group, const RenderPassType renderPassType)
{
	tcu::TestContext& testCtx(group->getTestContext());

	// Test external subpass dependencies
	{
		const deUint32	renderPassCounts[]	= { 2u, 3u, 5u};

		const UVec2		renderSizes[]		=
		{
			UVec2(64, 64),
			UVec2(128, 128),
			UVec2(512, 512)
		};

		de::MovePtr<tcu::TestCaseGroup>	externalGroup	(new tcu::TestCaseGroup(testCtx, "external_subpass", "external_subpass"));

		for (size_t renderSizeNdx = 0; renderSizeNdx < DE_LENGTH_OF_ARRAY(renderSizes); renderSizeNdx++)
		{
			string groupName ("render_size_" + de::toString(renderSizes[renderSizeNdx].x()) + "_" + de::toString(renderSizes[renderSizeNdx].y()));
			de::MovePtr<tcu::TestCaseGroup> renderSizeGroup	(new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupName.c_str()));

			for (size_t renderPassCountNdx = 0; renderPassCountNdx < DE_LENGTH_OF_ARRAY(renderPassCounts); renderPassCountNdx++)
			{
				vector<RenderPass>	renderPasses;

				for (size_t renderPassNdx = 0; renderPassNdx < renderPassCounts[renderPassCountNdx]; renderPassNdx++)
				{
					vector<Attachment>			attachments;
					vector<AttachmentReference>	colorAttachmentReferences;

					const VkFormat				format				(VK_FORMAT_R8G8B8A8_UNORM);
					const VkSampleCountFlagBits	sampleCount			(VK_SAMPLE_COUNT_1_BIT);
					const VkAttachmentLoadOp	loadOp				(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
					const VkAttachmentStoreOp	storeOp				(VK_ATTACHMENT_STORE_OP_STORE);
					const VkAttachmentLoadOp	stencilLoadOp		(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
					const VkAttachmentStoreOp	stencilStoreOp		(VK_ATTACHMENT_STORE_OP_DONT_CARE);
					const VkImageLayout			initialLayout		(VK_IMAGE_LAYOUT_UNDEFINED);
					const VkImageLayout			finalLayout			(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
					const VkImageLayout			subpassLayout		(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);

					attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalLayout));
					colorAttachmentReferences.push_back(AttachmentReference((deUint32)0, subpassLayout));

					const VkImageLayout			depthStencilLayout	(VK_IMAGE_LAYOUT_GENERAL);
					const vector<Subpass>		subpasses			(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(),
																		AttachmentReference(VK_ATTACHMENT_UNUSED, depthStencilLayout), vector<deUint32>()));
					vector<SubpassDependency>	deps;

					deps.push_back(SubpassDependency(VK_SUBPASS_EXTERNAL,										// deUint32				srcPass
													 0,															// deUint32				dstPass
													 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,				// VkPipelineStageFlags	srcStageMask
													 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,						// VkPipelineStageFlags	dstStageMask
													 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,						// VkAccessFlags		srcAccessMask
													 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,	// VkAccessFlags		dstAccessMask
													 0));														// VkDependencyFlags	flags

					deps.push_back(SubpassDependency(0,															// deUint32				srcPass
													 VK_SUBPASS_EXTERNAL,										// deUint32				dstPass
													 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,						// VkPipelineStageFlags	srcStageMask
													 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,				// VkPipelineStageFlags	dstStageMask
													 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,	// VkAccessFlags		srcAccessMask
													 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,						// VkAccessFlags		dstAccessMask
													 0));														// VkDependencyFlags	flags

					RenderPass					renderPass			(attachments, subpasses, deps);

					renderPasses.push_back(renderPass);
				}

				const deUint32		blurKernel	(12u);
				string				testName	("render_passes_" + de::toString(renderPassCounts[renderPassCountNdx]));
				ExternalTestConfig	testConfig
				{
					VK_FORMAT_R8G8B8A8_UNORM,
					renderSizes[renderSizeNdx],
					renderPasses,
					renderPassType,
					SYNCHRONIZATION_TYPE_LEGACY,
					blurKernel
				};

				renderSizeGroup->addChild(new InstanceFactory1<ExternalDependencyTestInstance, ExternalTestConfig, ExternalPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
				if (renderPassType == RENDERPASS_TYPE_RENDERPASS2)
				{
					testName += "_sync_2";
					testConfig.synchronizationType = SYNCHRONIZATION_TYPE_SYNCHRONIZATION2;
					renderSizeGroup->addChild(new InstanceFactory1<ExternalDependencyTestInstance, ExternalTestConfig, ExternalPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
				}
			}

			externalGroup->addChild(renderSizeGroup.release());
		}

		group->addChild(externalGroup.release());
	}

	// Test implicit subpass dependencies
	{
		const deUint32					renderPassCounts[]		= { 2u, 3u, 5u };

		de::MovePtr<tcu::TestCaseGroup>	implicitGroup			(new tcu::TestCaseGroup(testCtx, "implicit_dependencies", "implicit_dependencies"));

		for (size_t renderPassCountNdx = 0; renderPassCountNdx < DE_LENGTH_OF_ARRAY(renderPassCounts); renderPassCountNdx++)
		{
			vector<RenderPass> renderPasses;

			for (size_t renderPassNdx = 0; renderPassNdx < renderPassCounts[renderPassCountNdx]; renderPassNdx++)
			{
				vector<Attachment>			attachments;
				vector<AttachmentReference>	colorAttachmentReferences;

				const VkFormat				format					(VK_FORMAT_R8G8B8A8_UNORM);
				const VkSampleCountFlagBits	sampleCount				(VK_SAMPLE_COUNT_1_BIT);
				const VkAttachmentLoadOp	loadOp					(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
				const VkAttachmentStoreOp	storeOp					(VK_ATTACHMENT_STORE_OP_STORE);
				const VkAttachmentLoadOp	stencilLoadOp			(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
				const VkAttachmentStoreOp	stencilStoreOp			(VK_ATTACHMENT_STORE_OP_DONT_CARE);
				const VkImageLayout			initialLayout			(VK_IMAGE_LAYOUT_UNDEFINED);
				const VkImageLayout			finalLayout				(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
				const VkImageLayout			subpassLayout			(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);

				attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalLayout));
				colorAttachmentReferences.push_back(AttachmentReference((deUint32)0, subpassLayout));

				const VkImageLayout			depthStencilLayout		(VK_IMAGE_LAYOUT_GENERAL);
				const vector<Subpass>		subpasses				(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference(VK_ATTACHMENT_UNUSED, depthStencilLayout), vector<deUint32>()));
				vector<SubpassDependency>	deps;

				// The first render pass lets the implementation add all subpass dependencies implicitly.
				// On the following passes only the dependency from external to first subpass is defined as
				// we need to make sure we have the image ready from previous render pass. In this case
				// the dependency from subpass 0 to external is added implicitly by the implementation.
				if (renderPassNdx > 0)
				{
					deps.push_back(SubpassDependency(VK_SUBPASS_EXTERNAL,										// deUint32				srcPass
													 0,															// deUint32				dstPass
													 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,				// VkPipelineStageFlags	srcStageMask
													 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,						// VkPipelineStageFlags	dstStageMask
													 0,						// VkAccessFlags		srcAccessMask
													 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,	// VkAccessFlags		dstAccessMask
													 0));														// VkDependencyFlags	flags
				}

				RenderPass					renderPass				(attachments, subpasses, deps);

				renderPasses.push_back(renderPass);
			}

			const deUint32				blurKernel	(12u);
			const ExternalTestConfig	testConfig	(VK_FORMAT_R8G8B8A8_UNORM, UVec2(128, 128), renderPasses, renderPassType, SYNCHRONIZATION_TYPE_LEGACY, blurKernel);
			const string				testName	("render_passes_" + de::toString(renderPassCounts[renderPassCountNdx]));

			implicitGroup->addChild(new InstanceFactory1<ExternalDependencyTestInstance, ExternalTestConfig, ExternalPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
		}

		group->addChild(implicitGroup.release());
	}

	// Test late fragment operations using depth_stencil attachments in multipass rendering
	{
		const UVec2		renderSizes[]		=
		{
			UVec2(32, 32),
			UVec2(64, 64),
			UVec2(128, 128)
		};

		const deUint32	subpassCounts[]		= { 2u, 3u, 5u };

		// Implementations must support at least one of the following formats
		// for depth_stencil attachments
		const VkFormat formats[]			=
		{
			VK_FORMAT_D24_UNORM_S8_UINT,
			VK_FORMAT_D32_SFLOAT_S8_UINT
		};

		de::MovePtr<tcu::TestCaseGroup>	lateFragmentTestsGroup (new tcu::TestCaseGroup(testCtx, "late_fragment_tests", "wait for late fragment tests"));

		for (size_t renderSizeNdx = 0; renderSizeNdx < DE_LENGTH_OF_ARRAY(renderSizes); renderSizeNdx++)
		{
			string							renderSizeGroupName	("render_size_" + de::toString(renderSizes[renderSizeNdx].x()) + "_" + de::toString(renderSizes[renderSizeNdx].y()));
			de::MovePtr<tcu::TestCaseGroup>	renderSizeGroup		(new tcu::TestCaseGroup(testCtx, renderSizeGroupName.c_str(), renderSizeGroupName.c_str()));

			for (size_t subpassCountNdx = 0; subpassCountNdx < DE_LENGTH_OF_ARRAY(subpassCounts); subpassCountNdx++)
			{
				string							subpassGroupName	("subpass_count_" + de::toString(subpassCounts[subpassCountNdx]));
				de::MovePtr<tcu::TestCaseGroup>	subpassCountGroup	(new tcu::TestCaseGroup(testCtx, subpassGroupName.c_str(), subpassGroupName.c_str()));

				for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
				{
					const deUint32				subpassCount	(subpassCounts[subpassCountNdx]);
					const deUint32				attachmentCount	(subpassCount);
					vector<Subpass>				subpasses;
					vector<Attachment>			attachments;
					vector<SubpassDependency>	deps;

					// Attachments
					for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
					{
						const VkFormat				format						(formats[formatNdx]);
						const VkSampleCountFlagBits	sampleCount					(VK_SAMPLE_COUNT_1_BIT);
						const VkAttachmentLoadOp	loadOp						(VK_ATTACHMENT_LOAD_OP_CLEAR);
						const VkAttachmentStoreOp	storeOp						((attachmentNdx == attachmentCount - 1)
																					? VK_ATTACHMENT_STORE_OP_STORE
																					: VK_ATTACHMENT_STORE_OP_DONT_CARE);
						const VkAttachmentLoadOp	stencilLoadOp				(VK_ATTACHMENT_LOAD_OP_CLEAR);
						const VkAttachmentStoreOp	stencilStoreOp				((attachmentNdx == attachmentCount - 1)
																					? VK_ATTACHMENT_STORE_OP_STORE
																					: VK_ATTACHMENT_STORE_OP_DONT_CARE);
						const VkImageLayout			initialLayout				(VK_IMAGE_LAYOUT_UNDEFINED);
						const VkImageLayout			finalLayout					(VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL);

						attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalLayout));
					}

					// Subpasses
					for (size_t subpassNdx = 0; subpassNdx < subpassCount; subpassNdx++)
					{
						vector<AttachmentReference>	inputAttachmentReferences;
						const VkImageAspectFlags	inputAttachmentAspectMask	((renderPassType == RENDERPASS_TYPE_RENDERPASS2)
																					? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_DEPTH_BIT)
																					: static_cast<VkImageAspectFlags>(0));

						// Input attachment references
						if (subpassNdx > 0)
							inputAttachmentReferences.push_back(AttachmentReference((deUint32)subpassNdx - 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, inputAttachmentAspectMask));

						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, inputAttachmentReferences, vector<AttachmentReference>(), vector<AttachmentReference>(), AttachmentReference((deUint32)subpassNdx, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL), vector<deUint32>()));

						// Subpass dependencies from current subpass to previous subpass.
						// Subpasses will wait for the late fragment operations before reading the contents
						// of previous subpass.
						if (subpassNdx > 0)
						{
							deps.push_back(SubpassDependency((deUint32)subpassNdx - 1,							// deUint32				srcPass
															 (deUint32)subpassNdx,								// deUint32				dstPass
															 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,			// VkPipelineStageFlags	srcStageMask
															 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
																| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,	// VkPipelineStageFlags	dstStageMask
															 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,		// VkAccessFlags		srcAccessMask
															 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,				// VkAccessFlags		dstAccessMask
															 VK_DEPENDENCY_BY_REGION_BIT));						// VkDependencyFlags	flags
						}
					}
					deps.push_back(SubpassDependency((deUint32)subpassCount - 1,								// deUint32				srcPass
													 VK_SUBPASS_EXTERNAL,										// deUint32				dstPass
													 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,					// VkPipelineStageFlags	srcStageMask
													 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,					// VkPipelineStageFlags	dstStageMask
													 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,				// VkAccessFlags		srcAccessMask
													 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags		dstAccessMask
													 VK_DEPENDENCY_BY_REGION_BIT));								// VkDependencyFlags	flags

					const RenderPass		renderPass	(attachments, subpasses, deps);
					const SubpassTestConfig	testConfig	(formats[formatNdx], renderSizes[renderSizeNdx], renderPass, renderPassType);
					const string			format		(formatToName(formats[formatNdx]).c_str());

					subpassCountGroup->addChild(new InstanceFactory1<SubpassDependencyTestInstance, SubpassTestConfig, SubpassPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, format, format, testConfig));
				}

				renderSizeGroup->addChild(subpassCountGroup.release());
			}

			lateFragmentTestsGroup->addChild(renderSizeGroup.release());
		}

		group->addChild(lateFragmentTestsGroup.release());
	}

	// Test subpass self dependency
	{
		const UVec2		renderSizes[]		=
		{
			UVec2(64, 64),
			UVec2(128, 128),
			UVec2(512, 512)
		};

		de::MovePtr<tcu::TestCaseGroup>	selfDependencyGroup	(new tcu::TestCaseGroup(testCtx, "self_dependency", "self_dependency"));

		for (size_t renderSizeNdx = 0; renderSizeNdx < DE_LENGTH_OF_ARRAY(renderSizes); renderSizeNdx++)
		{
			string groupName	("render_size_" + de::toString(renderSizes[renderSizeNdx].x()) + "_" + de::toString(renderSizes[renderSizeNdx].y()));
			de::MovePtr<tcu::TestCaseGroup>	renderSizeGroup	(new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupName.c_str()));

			const SubpassSelfDependencyBackwardsTestConfig	testConfig	(VK_FORMAT_R8G8B8A8_UNORM, renderSizes[renderSizeNdx], renderPassType);
			renderSizeGroup->addChild(new InstanceFactory1<SubpassSelfDependencyBackwardsTestInstance, SubpassSelfDependencyBackwardsTestConfig, SubpassSelfDependencyBackwardsPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, "geometry_to_indirectdraw", "", testConfig));

			selfDependencyGroup->addChild(renderSizeGroup.release());
		}

		group->addChild(selfDependencyGroup.release());
	}

	// Test using a single attachment with reads and writes using separate channels. This should work without subpass self-dependency.
	{
		de::MovePtr<tcu::TestCaseGroup>	separateChannelsGroup	(new tcu::TestCaseGroup(testCtx, "separate_channels", "separate_channels"));

		struct TestConfig
		{
			string		name;
			VkFormat	format;
		} configs[] =
		{
			{	"r8g8b8a8_unorm",		VK_FORMAT_R8G8B8A8_UNORM		},
			{	"r16g16b16a16_sfloat",	VK_FORMAT_R16G16B16A16_SFLOAT	},
			{	"d24_unorm_s8_uint",	VK_FORMAT_D24_UNORM_S8_UINT		},
			{	"d32_sfloat_s8_uint",	VK_FORMAT_D32_SFLOAT_S8_UINT	}
		};

		for (deUint32 configIdx = 0; configIdx < DE_LENGTH_OF_ARRAY(configs); configIdx++)
		{
			const SeparateChannelsTestConfig testConfig(configs[configIdx].format, renderPassType);

			separateChannelsGroup->addChild(new InstanceFactory1<SeparateChannelsTestInstance, SeparateChannelsTestConfig, SeparateChannelsPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, configs[configIdx].name, "", testConfig));
		}

		group->addChild(separateChannelsGroup.release());
	}

	// Test using a single attachment for input and output.
	{
		de::MovePtr<tcu::TestCaseGroup>	singleAttachmentGroup	(new tcu::TestCaseGroup(testCtx, "single_attachment", "single_attachment"));

		struct TestConfig
		{
			string		name;
			VkFormat	format;
		} configs[] =
		{
			{	"r8g8b8a8_unorm",			VK_FORMAT_R8G8B8A8_UNORM		},
			{	"b8g8r8a8_unorm",			VK_FORMAT_B8G8R8A8_UNORM		},
			{	"r16g16b16a16_sfloat",		VK_FORMAT_R16G16B16A16_SFLOAT	},
			{	"r5g6b5_unorm_pack16",		VK_FORMAT_R5G6B5_UNORM_PACK16	},
			{	"a1r5g5b5_unorm_pack16",	VK_FORMAT_A1R5G5B5_UNORM_PACK16	}
		};

		for (deUint32 configIdx = 0; configIdx < DE_LENGTH_OF_ARRAY(configs); configIdx++)
		{
			const SingleAttachmentTestConfig testConfig(configs[configIdx].format, renderPassType);

			singleAttachmentGroup->addChild(new InstanceFactory1<SingleAttachmentTestInstance, SingleAttachmentTestConfig, SingleAttachmentPrograms>(testCtx, tcu::NODETYPE_SELF_VALIDATE, configs[configIdx].name, "", testConfig));
		}

		group->addChild(singleAttachmentGroup.release());
	}
}
} // anonymous

tcu::TestCaseGroup* createRenderPassSubpassDependencyTests (tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "subpass_dependencies", "Subpass dependency tests", initTests, RENDERPASS_TYPE_LEGACY);
}

tcu::TestCaseGroup* createRenderPass2SubpassDependencyTests (tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "subpass_dependencies", "Subpass dependency tests", initTests, RENDERPASS_TYPE_RENDERPASS2);
}
} // vkt
