/*-------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2015 Google 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 RenderPass tests
 *//*--------------------------------------------------------------------*/

#include "vktRenderPassTests.hpp"

#include "vktRenderPassMultisampleTests.hpp"
#include "vktRenderPassMultisampleResolveTests.hpp"

#include "vktTestCaseUtil.hpp"
#include "vktTestGroupUtil.hpp"

#include "vkDefs.hpp"
#include "vkDeviceUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkPlatform.hpp"
#include "vkPrograms.hpp"
#include "vkQueryUtil.hpp"
#include "vkRef.hpp"
#include "vkRefUtil.hpp"
#include "vkStrUtil.hpp"
#include "vkTypeUtil.hpp"

#include "tcuFloat.hpp"
#include "tcuFormatUtil.hpp"
#include "tcuMaybe.hpp"
#include "tcuResultCollector.hpp"
#include "tcuTestLog.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuVectorUtil.hpp"

#include "deRandom.hpp"
#include "deSTLUtil.hpp"
#include "deSharedPtr.hpp"
#include "deStringUtil.hpp"
#include "deUniquePtr.hpp"

#include <limits>
#include <set>
#include <string>
#include <vector>

using namespace vk;

using tcu::BVec4;
using tcu::IVec2;
using tcu::IVec4;
using tcu::UVec2;
using tcu::UVec4;
using tcu::Vec2;
using tcu::Vec4;

using tcu::Maybe;
using tcu::just;
using tcu::nothing;

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

using tcu::TestLog;

using de::UniquePtr;

using std::pair;
using std::set;
using std::string;
using std::vector;

namespace vkt
{
namespace
{
enum AllocationKind
{
	ALLOCATION_KIND_SUBALLOCATED,
	ALLOCATION_KIND_DEDICATED,
};

de::MovePtr<Allocation> allocateBuffer (const InstanceInterface&	vki,
										const DeviceInterface&		vkd,
										const VkPhysicalDevice&		physDevice,
										const VkDevice				device,
										const VkBuffer&				buffer,
										const MemoryRequirement		requirement,
										Allocator&					allocator,
										AllocationKind				allocationKind)
{
	switch (allocationKind)
	{
		case ALLOCATION_KIND_SUBALLOCATED:
		{
			const VkMemoryRequirements	memoryRequirements	= getBufferMemoryRequirements(vkd, device, buffer);

			return allocator.allocate(memoryRequirements, requirement);
		}

		case ALLOCATION_KIND_DEDICATED:
		{
			return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
		}

		default:
		{
			TCU_THROW(InternalError, "Invalid allocation kind");
		}
	}
}

de::MovePtr<Allocation> allocateImage (const InstanceInterface&		vki,
									   const DeviceInterface&		vkd,
									   const VkPhysicalDevice&		physDevice,
									   const VkDevice				device,
									   const VkImage&				image,
									   const MemoryRequirement		requirement,
									   Allocator&					allocator,
									   AllocationKind				allocationKind)
{
	switch (allocationKind)
	{
		case ALLOCATION_KIND_SUBALLOCATED:
		{
			const VkMemoryRequirements	memoryRequirements	= getImageMemoryRequirements(vkd, device, image);

			return allocator.allocate(memoryRequirements, requirement);
		}

		case ALLOCATION_KIND_DEDICATED:
		{
			return allocateDedicated(vki, vkd, physDevice, device, image, requirement);
		}

		default:
		{
			TCU_THROW(InternalError, "Invalid allocation kind");
		}
	}
}

enum BoolOp
{
	BOOLOP_AND,
	BOOLOP_OR,
	BOOLOP_EQ,
	BOOLOP_NEQ
};

const char* boolOpToString (BoolOp op)
{
	switch (op)
	{
		case BOOLOP_OR:
			return "||";

		case BOOLOP_AND:
			return "&&";

		case BOOLOP_EQ:
			return "==";

		case BOOLOP_NEQ:
			return "!=";

		default:
			DE_FATAL("Unknown boolean operation.");
			return DE_NULL;
	}
}

bool performBoolOp (BoolOp op, bool a, bool b)
{
	switch (op)
	{
		case BOOLOP_OR:
			return a || b;

		case BOOLOP_AND:
			return a && b;

		case BOOLOP_EQ:
			return a == b;

		case BOOLOP_NEQ:
			return a != b;

		default:
			DE_FATAL("Unknown boolean operation.");
			return false;
	}
}

BoolOp boolOpFromIndex (size_t index)
{
	const BoolOp ops[] =
	{
		BOOLOP_OR,
		BOOLOP_AND,
		BOOLOP_EQ,
		BOOLOP_NEQ
	};

	return ops[index % DE_LENGTH_OF_ARRAY(ops)];
}

Move<VkFramebuffer> createFramebuffer (const DeviceInterface&	vk,
									   VkDevice					device,
									   VkFramebufferCreateFlags	pCreateInfo_flags,
									   VkRenderPass				pCreateInfo_renderPass,
									   deUint32					pCreateInfo_attachmentCount,
									   const VkImageView*		pCreateInfo_pAttachments,
									   deUint32					pCreateInfo_width,
									   deUint32					pCreateInfo_height,
									   deUint32					pCreateInfo_layers)
{
	const VkFramebufferCreateInfo pCreateInfo =
	{
		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
		DE_NULL,
		pCreateInfo_flags,
		pCreateInfo_renderPass,
		pCreateInfo_attachmentCount,
		pCreateInfo_pAttachments,
		pCreateInfo_width,
		pCreateInfo_height,
		pCreateInfo_layers,
	};
	return createFramebuffer(vk, device, &pCreateInfo);
}

Move<VkImage> createImage (const DeviceInterface&	vk,
						   VkDevice					device,
						   VkImageCreateFlags		pCreateInfo_flags,
						   VkImageType				pCreateInfo_imageType,
						   VkFormat					pCreateInfo_format,
						   VkExtent3D				pCreateInfo_extent,
						   deUint32					pCreateInfo_mipLevels,
						   deUint32					pCreateInfo_arrayLayers,
						   VkSampleCountFlagBits	pCreateInfo_samples,
						   VkImageTiling			pCreateInfo_tiling,
						   VkImageUsageFlags		pCreateInfo_usage,
						   VkSharingMode			pCreateInfo_sharingMode,
						   deUint32					pCreateInfo_queueFamilyCount,
						   const deUint32*			pCreateInfo_pQueueFamilyIndices,
						   VkImageLayout			pCreateInfo_initialLayout)
{
	const VkImageCreateInfo pCreateInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
		DE_NULL,
		pCreateInfo_flags,
		pCreateInfo_imageType,
		pCreateInfo_format,
		pCreateInfo_extent,
		pCreateInfo_mipLevels,
		pCreateInfo_arrayLayers,
		pCreateInfo_samples,
		pCreateInfo_tiling,
		pCreateInfo_usage,
		pCreateInfo_sharingMode,
		pCreateInfo_queueFamilyCount,
		pCreateInfo_pQueueFamilyIndices,
		pCreateInfo_initialLayout
	};
	return createImage(vk, device, &pCreateInfo);
}

void bindBufferMemory (const DeviceInterface& vk, VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memOffset)
{
	VK_CHECK(vk.bindBufferMemory(device, buffer, mem, memOffset));
}

void bindImageMemory (const DeviceInterface& vk, VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memOffset)
{
	VK_CHECK(vk.bindImageMemory(device, image, mem, memOffset));
}

Move<VkImageView> createImageView (const DeviceInterface&	vk,
									VkDevice				device,
									VkImageViewCreateFlags	pCreateInfo_flags,
									VkImage					pCreateInfo_image,
									VkImageViewType			pCreateInfo_viewType,
									VkFormat				pCreateInfo_format,
									VkComponentMapping		pCreateInfo_components,
									VkImageSubresourceRange	pCreateInfo_subresourceRange)
{
	const VkImageViewCreateInfo pCreateInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
		DE_NULL,
		pCreateInfo_flags,
		pCreateInfo_image,
		pCreateInfo_viewType,
		pCreateInfo_format,
		pCreateInfo_components,
		pCreateInfo_subresourceRange,
	};
	return createImageView(vk, device, &pCreateInfo);
}

Move<VkBuffer> createBuffer (const DeviceInterface&	vk,
							 VkDevice				device,
							 VkBufferCreateFlags	pCreateInfo_flags,
							 VkDeviceSize			pCreateInfo_size,
							 VkBufferUsageFlags		pCreateInfo_usage,
							 VkSharingMode			pCreateInfo_sharingMode,
							 deUint32				pCreateInfo_queueFamilyCount,
							 const deUint32*		pCreateInfo_pQueueFamilyIndices)
{
	const VkBufferCreateInfo pCreateInfo =
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
		DE_NULL,
		pCreateInfo_flags,
		pCreateInfo_size,
		pCreateInfo_usage,
		pCreateInfo_sharingMode,
		pCreateInfo_queueFamilyCount,
		pCreateInfo_pQueueFamilyIndices,
	};
	return createBuffer(vk, device, &pCreateInfo);
}

void cmdBeginRenderPass (const DeviceInterface&	vk,
						 VkCommandBuffer		cmdBuffer,
						 VkRenderPass			pRenderPassBegin_renderPass,
						 VkFramebuffer			pRenderPassBegin_framebuffer,
						 VkRect2D				pRenderPassBegin_renderArea,
						 deUint32				pRenderPassBegin_clearValueCount,
						 const VkClearValue*	pRenderPassBegin_pAttachmentClearValues,
						 VkSubpassContents		contents)
{
	const VkRenderPassBeginInfo pRenderPassBegin =
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
		DE_NULL,
		pRenderPassBegin_renderPass,
		pRenderPassBegin_framebuffer,
		pRenderPassBegin_renderArea,
		pRenderPassBegin_clearValueCount,
		pRenderPassBegin_pAttachmentClearValues,
	};
	vk.cmdBeginRenderPass(cmdBuffer, &pRenderPassBegin, contents);
}

void beginCommandBuffer (const DeviceInterface&			vk,
						 VkCommandBuffer				cmdBuffer,
						 VkCommandBufferUsageFlags		pBeginInfo_flags,
						 VkRenderPass					pInheritanceInfo_renderPass,
						 deUint32						pInheritanceInfo_subpass,
						 VkFramebuffer					pInheritanceInfo_framebuffer,
						 VkBool32						pInheritanceInfo_occlusionQueryEnable,
						 VkQueryControlFlags			pInheritanceInfo_queryFlags,
						 VkQueryPipelineStatisticFlags	pInheritanceInfo_pipelineStatistics)
{
	const VkCommandBufferInheritanceInfo pInheritanceInfo =
	{
		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
		DE_NULL,
		pInheritanceInfo_renderPass,
		pInheritanceInfo_subpass,
		pInheritanceInfo_framebuffer,
		pInheritanceInfo_occlusionQueryEnable,
		pInheritanceInfo_queryFlags,
		pInheritanceInfo_pipelineStatistics,
	};
	const VkCommandBufferBeginInfo pBeginInfo =
	{
		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
		DE_NULL,
		pBeginInfo_flags,
		&pInheritanceInfo,
	};
	VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &pBeginInfo));
}

void endCommandBuffer (const DeviceInterface& vk, VkCommandBuffer cmdBuffer)
{
	VK_CHECK(vk.endCommandBuffer(cmdBuffer));
}

void queueSubmit (const DeviceInterface& vk, VkQueue queue, deUint32 cmdBufferCount, const VkCommandBuffer* pCmdBuffers, VkFence fence)
{
	const VkSubmitInfo submitInfo =
	{
		VK_STRUCTURE_TYPE_SUBMIT_INFO,
		DE_NULL,
		0u,								// waitSemaphoreCount
		(const VkSemaphore*)DE_NULL,	// pWaitSemaphores
		(const VkPipelineStageFlags*)DE_NULL,
		cmdBufferCount,					// commandBufferCount
		pCmdBuffers,
		0u,								// signalSemaphoreCount
		(const VkSemaphore*)DE_NULL,	// pSignalSemaphores
	};
	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence));
}

void waitForFences (const DeviceInterface& vk, VkDevice device, deUint32 fenceCount, const VkFence* pFences, VkBool32 waitAll, deUint64 timeout)
{
	VK_CHECK(vk.waitForFences(device, fenceCount, pFences, waitAll, timeout));
}

VkImageAspectFlags getImageAspectFlags (VkFormat vkFormat)
{
	const tcu::TextureFormat format = mapVkFormat(vkFormat);

	DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 21);

	switch (format.order)
	{
		case tcu::TextureFormat::DS:
			return VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;

		case tcu::TextureFormat::D:
			return VK_IMAGE_ASPECT_DEPTH_BIT;

		case tcu::TextureFormat::S:
			return VK_IMAGE_ASPECT_STENCIL_BIT;

		default:
			return VK_IMAGE_ASPECT_COLOR_BIT;
	}
}

VkAccessFlags getAllMemoryReadFlags (void)
{
	return VK_ACCESS_TRANSFER_READ_BIT
		   | VK_ACCESS_UNIFORM_READ_BIT
		   | VK_ACCESS_HOST_READ_BIT
		   | VK_ACCESS_INDEX_READ_BIT
		   | VK_ACCESS_SHADER_READ_BIT
		   | VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT
		   | VK_ACCESS_INDIRECT_COMMAND_READ_BIT
		   | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
		   | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
		   | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
}

VkAccessFlags getAllMemoryWriteFlags (void)
{
	return VK_ACCESS_TRANSFER_WRITE_BIT
		   | VK_ACCESS_HOST_WRITE_BIT
		   | VK_ACCESS_SHADER_WRITE_BIT
		   | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
		   | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
}

VkAccessFlags getMemoryFlagsForLayout (const VkImageLayout layout)
{
	switch (layout)
	{
		case VK_IMAGE_LAYOUT_GENERAL:							return getAllMemoryReadFlags() | getAllMemoryWriteFlags();
		case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:			return VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
		case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:	return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
		case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:	return VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
		case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:			return VK_ACCESS_SHADER_READ_BIT;
		case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:				return VK_ACCESS_TRANSFER_READ_BIT;
		case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:				return VK_ACCESS_TRANSFER_WRITE_BIT;

		default:
			return (VkAccessFlags)0;
	}
}

VkPipelineStageFlags getAllPipelineStageFlags (void)
{
	return VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT
		   | VK_PIPELINE_STAGE_TRANSFER_BIT
		   | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
		   | VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
		   | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
		   | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
		   | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
		   | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
		   | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT
		   | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
		   | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
		   | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
		   | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
}

class AttachmentReference
{
public:
					AttachmentReference		(deUint32		attachment,
											 VkImageLayout	layout)
		: m_attachment	(attachment)
		, m_layout		(layout)
	{
	}

	deUint32		getAttachment			(void) const { return m_attachment;	}
	VkImageLayout	getImageLayout			(void) const { return m_layout;		}

private:
	deUint32		m_attachment;
	VkImageLayout	m_layout;
};

class Subpass
{
public:
										Subpass						(VkPipelineBindPoint				pipelineBindPoint,
																	 VkSubpassDescriptionFlags			flags,
																	 const vector<AttachmentReference>&	inputAttachments,
																	 const vector<AttachmentReference>&	colorAttachments,
																	 const vector<AttachmentReference>&	resolveAttachments,
																	 AttachmentReference				depthStencilAttachment,
																	 const vector<deUint32>&			preserveAttachments)
		: m_pipelineBindPoint		(pipelineBindPoint)
		, m_flags					(flags)
		, m_inputAttachments		(inputAttachments)
		, m_colorAttachments		(colorAttachments)
		, m_resolveAttachments		(resolveAttachments)
		, m_depthStencilAttachment	(depthStencilAttachment)
		, m_preserveAttachments		(preserveAttachments)
	{
	}

	VkPipelineBindPoint					getPipelineBindPoint		(void) const { return m_pipelineBindPoint;		}
	VkSubpassDescriptionFlags			getFlags					(void) const { return m_flags;					}
	const vector<AttachmentReference>&	getInputAttachments			(void) const { return m_inputAttachments;		}
	const vector<AttachmentReference>&	getColorAttachments			(void) const { return m_colorAttachments;		}
	const vector<AttachmentReference>&	getResolveAttachments		(void) const { return m_resolveAttachments;		}
	const AttachmentReference&			getDepthStencilAttachment	(void) const { return m_depthStencilAttachment;	}
	const vector<deUint32>&				getPreserveAttachments		(void) const { return m_preserveAttachments;	}

private:
	VkPipelineBindPoint					m_pipelineBindPoint;
	VkSubpassDescriptionFlags			m_flags;

	vector<AttachmentReference>			m_inputAttachments;
	vector<AttachmentReference>			m_colorAttachments;
	vector<AttachmentReference>			m_resolveAttachments;
	AttachmentReference					m_depthStencilAttachment;

	vector<deUint32>					m_preserveAttachments;
};

class SubpassDependency
{
public:
							SubpassDependency	(deUint32				srcPass,
												 deUint32				dstPass,

												 VkPipelineStageFlags	srcStageMask,
												 VkPipelineStageFlags	dstStageMask,

												 VkAccessFlags			outputMask,
												 VkAccessFlags			inputMask,

												 VkDependencyFlags		flags)
		: m_srcPass			(srcPass)
		, m_dstPass			(dstPass)

		, m_srcStageMask	(srcStageMask)
		, m_dstStageMask	(dstStageMask)

		, m_outputMask		(outputMask)
		, m_inputMask		(inputMask)
		, m_flags			(flags)
	{
	}

	deUint32				getSrcPass			(void) const { return m_srcPass;		}
	deUint32				getDstPass			(void) const { return m_dstPass;		}

	VkPipelineStageFlags	getSrcStageMask		(void) const { return m_srcStageMask;	}
	VkPipelineStageFlags	getDstStageMask		(void) const { return m_dstStageMask;	}

	VkAccessFlags			getOutputMask		(void) const { return m_outputMask;		}
	VkAccessFlags			getInputMask		(void) const { return m_inputMask;		}

	VkDependencyFlags		getFlags			(void) const { return m_flags;		}

private:
	deUint32				m_srcPass;
	deUint32				m_dstPass;

	VkPipelineStageFlags	m_srcStageMask;
	VkPipelineStageFlags	m_dstStageMask;

	VkAccessFlags			m_outputMask;
	VkAccessFlags			m_inputMask;
	VkDependencyFlags		m_flags;
};

class Attachment
{
public:
							Attachment			(VkFormat				format,
												 VkSampleCountFlagBits	samples,

												 VkAttachmentLoadOp		loadOp,
												 VkAttachmentStoreOp	storeOp,

												 VkAttachmentLoadOp		stencilLoadOp,
												 VkAttachmentStoreOp	stencilStoreOp,

												 VkImageLayout			initialLayout,
												 VkImageLayout			finalLayout)
		: m_format			(format)
		, m_samples			(samples)

		, m_loadOp			(loadOp)
		, m_storeOp			(storeOp)

		, m_stencilLoadOp	(stencilLoadOp)
		, m_stencilStoreOp	(stencilStoreOp)

		, m_initialLayout	(initialLayout)
		, m_finalLayout		(finalLayout)
	{
	}

	VkFormat				getFormat			(void) const { return m_format;			}
	VkSampleCountFlagBits	getSamples			(void) const { return m_samples;		}

	VkAttachmentLoadOp		getLoadOp			(void) const { return m_loadOp;			}
	VkAttachmentStoreOp		getStoreOp			(void) const { return m_storeOp;		}


	VkAttachmentLoadOp		getStencilLoadOp	(void) const { return m_stencilLoadOp;	}
	VkAttachmentStoreOp		getStencilStoreOp	(void) const { return m_stencilStoreOp;	}

	VkImageLayout			getInitialLayout	(void) const { return m_initialLayout;	}
	VkImageLayout			getFinalLayout		(void) const { return m_finalLayout;	}

private:
	VkFormat				m_format;
	VkSampleCountFlagBits	m_samples;

	VkAttachmentLoadOp		m_loadOp;
	VkAttachmentStoreOp		m_storeOp;

	VkAttachmentLoadOp		m_stencilLoadOp;
	VkAttachmentStoreOp		m_stencilStoreOp;

	VkImageLayout			m_initialLayout;
	VkImageLayout			m_finalLayout;
};

class RenderPass
{
public:
										RenderPass		(const vector<Attachment>&			attachments,
														 const vector<Subpass>&				subpasses,
														 const vector<SubpassDependency>&	dependencies)
		: m_attachments		(attachments)
		, m_subpasses		(subpasses)
		, m_dependencies	(dependencies)
	{
	}

	const vector<Attachment>&			getAttachments	(void) const { return m_attachments;	}
	const vector<Subpass>&				getSubpasses	(void) const { return m_subpasses;		}
	const vector<SubpassDependency>&	getDependencies	(void) const { return m_dependencies;	}

private:
	const vector<Attachment>			m_attachments;
	const vector<Subpass>				m_subpasses;
	const vector<SubpassDependency>		m_dependencies;
};

struct TestConfig
{
	enum RenderTypes
	{
		RENDERTYPES_NONE	= 0,
		RENDERTYPES_CLEAR	= (1<<1),
		RENDERTYPES_DRAW	= (1<<2)
	};

	enum CommandBufferTypes
	{
		COMMANDBUFFERTYPES_INLINE		= (1<<0),
		COMMANDBUFFERTYPES_SECONDARY	= (1<<1)
	};

	enum ImageMemory
	{
		IMAGEMEMORY_STRICT		= (1<<0),
		IMAGEMEMORY_LAZY		= (1<<1)
	};

						TestConfig (const RenderPass&	renderPass_,
									RenderTypes			renderTypes_,
									CommandBufferTypes	commandBufferTypes_,
									ImageMemory			imageMemory_,
									const UVec2&		targetSize_,
									const UVec2&		renderPos_,
									const UVec2&		renderSize_,
									deUint32			seed_,
									AllocationKind		allocationKind_)
		: renderPass			(renderPass_)
		, renderTypes			(renderTypes_)
		, commandBufferTypes	(commandBufferTypes_)
		, imageMemory			(imageMemory_)
		, targetSize			(targetSize_)
		, renderPos				(renderPos_)
		, renderSize			(renderSize_)
		, seed					(seed_)
		, allocationKind		(allocationKind_)
	{
	}

	RenderPass			renderPass;
	RenderTypes			renderTypes;
	CommandBufferTypes	commandBufferTypes;
	ImageMemory			imageMemory;
	UVec2				targetSize;
	UVec2				renderPos;
	UVec2				renderSize;
	deUint32			seed;
	AllocationKind		allocationKind;
};

TestConfig::RenderTypes operator| (TestConfig::RenderTypes a, TestConfig::RenderTypes b)
{
	return (TestConfig::RenderTypes)(((deUint32)a) | ((deUint32)b));
}

TestConfig::CommandBufferTypes operator| (TestConfig::CommandBufferTypes a, TestConfig::CommandBufferTypes b)
{
	return (TestConfig::CommandBufferTypes)(((deUint32)a) | ((deUint32)b));
}

TestConfig::ImageMemory operator| (TestConfig::ImageMemory a, TestConfig::ImageMemory b)
{
	return (TestConfig::ImageMemory)(((deUint32)a) | ((deUint32)b));
}

void logRenderPassInfo (TestLog&			log,
						const RenderPass&	renderPass)
{
	const tcu::ScopedLogSection section (log, "RenderPass", "RenderPass");

	{
		const tcu::ScopedLogSection	attachmentsSection	(log, "Attachments", "Attachments");
		const vector<Attachment>&	attachments			= renderPass.getAttachments();

		for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
		{
			const tcu::ScopedLogSection	attachmentSection	(log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));
			const Attachment&			attachment			= attachments[attachmentNdx];

			log << TestLog::Message << "Format: " << attachment.getFormat() << TestLog::EndMessage;
			log << TestLog::Message << "Samples: " << attachment.getSamples() << TestLog::EndMessage;

			log << TestLog::Message << "LoadOp: " << attachment.getLoadOp() << TestLog::EndMessage;
			log << TestLog::Message << "StoreOp: " << attachment.getStoreOp() << TestLog::EndMessage;

			log << TestLog::Message << "StencilLoadOp: " << attachment.getStencilLoadOp() << TestLog::EndMessage;
			log << TestLog::Message << "StencilStoreOp: " << attachment.getStencilStoreOp() << TestLog::EndMessage;

			log << TestLog::Message << "InitialLayout: " << attachment.getInitialLayout() << TestLog::EndMessage;
			log << TestLog::Message << "FinalLayout: " << attachment.getFinalLayout() << TestLog::EndMessage;
		}
	}

	{
		const tcu::ScopedLogSection	subpassesSection	(log, "Subpasses", "Subpasses");
		const vector<Subpass>&		subpasses			= renderPass.getSubpasses();

		for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
		{
			const tcu::ScopedLogSection			subpassSection		(log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));
			const Subpass&						subpass				= subpasses[subpassNdx];

			const vector<AttachmentReference>&	inputAttachments	= subpass.getInputAttachments();
			const vector<AttachmentReference>&	colorAttachments	= subpass.getColorAttachments();
			const vector<AttachmentReference>&	resolveAttachments	= subpass.getResolveAttachments();
			const vector<deUint32>&				preserveAttachments	= subpass.getPreserveAttachments();

			if (!inputAttachments.empty())
			{
				const tcu::ScopedLogSection	inputAttachmentsSection	(log, "Inputs", "Inputs");

				for (size_t inputNdx = 0; inputNdx < inputAttachments.size(); inputNdx++)
				{
					const tcu::ScopedLogSection	inputAttachmentSection	(log, "Input" + de::toString(inputNdx), "Input " + de::toString(inputNdx));
					const AttachmentReference&	inputAttachment			= inputAttachments[inputNdx];

					log << TestLog::Message << "Attachment: " << inputAttachment.getAttachment() << TestLog::EndMessage;
					log << TestLog::Message << "Layout: " << inputAttachment.getImageLayout() << TestLog::EndMessage;
				}
			}

			if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
			{
				const tcu::ScopedLogSection	depthStencilAttachmentSection	(log, "DepthStencil", "DepthStencil");
				const AttachmentReference&	depthStencilAttachment			= subpass.getDepthStencilAttachment();

				log << TestLog::Message << "Attachment: " << depthStencilAttachment.getAttachment() << TestLog::EndMessage;
				log << TestLog::Message << "Layout: " << depthStencilAttachment.getImageLayout() << TestLog::EndMessage;
			}

			if (!colorAttachments.empty())
			{
				const tcu::ScopedLogSection	colorAttachmentsSection	(log, "Colors", "Colors");

				for (size_t colorNdx = 0; colorNdx < colorAttachments.size(); colorNdx++)
				{
					const tcu::ScopedLogSection	colorAttachmentSection	(log, "Color" + de::toString(colorNdx), "Color " + de::toString(colorNdx));
					const AttachmentReference&	colorAttachment			= colorAttachments[colorNdx];

					log << TestLog::Message << "Attachment: " << colorAttachment.getAttachment() << TestLog::EndMessage;
					log << TestLog::Message << "Layout: " << colorAttachment.getImageLayout() << TestLog::EndMessage;
				}
			}

			if (!resolveAttachments.empty())
			{
				const tcu::ScopedLogSection	resolveAttachmentsSection	(log, "Resolves", "Resolves");

				for (size_t resolveNdx = 0; resolveNdx < resolveAttachments.size(); resolveNdx++)
				{
					const tcu::ScopedLogSection	resolveAttachmentSection	(log, "Resolve" + de::toString(resolveNdx), "Resolve " + de::toString(resolveNdx));
					const AttachmentReference&	resolveAttachment			= resolveAttachments[resolveNdx];

					log << TestLog::Message << "Attachment: " << resolveAttachment.getAttachment() << TestLog::EndMessage;
					log << TestLog::Message << "Layout: " << resolveAttachment.getImageLayout() << TestLog::EndMessage;
				}
			}

			if (!preserveAttachments.empty())
			{
				const tcu::ScopedLogSection	preserveAttachmentsSection	(log, "Preserves", "Preserves");

				for (size_t preserveNdx = 0; preserveNdx < preserveAttachments.size(); preserveNdx++)
				{
					const tcu::ScopedLogSection	preserveAttachmentSection	(log, "Preserve" + de::toString(preserveNdx), "Preserve " + de::toString(preserveNdx));
					const deUint32				preserveAttachment			= preserveAttachments[preserveNdx];

					log << TestLog::Message << "Attachment: " << preserveAttachment << TestLog::EndMessage;
				}
			}
		}

	}

	if (!renderPass.getDependencies().empty())
	{
		const tcu::ScopedLogSection	dependenciesSection	(log, "Dependencies", "Dependencies");

		for (size_t depNdx = 0; depNdx < renderPass.getDependencies().size(); depNdx++)
		{
			const tcu::ScopedLogSection	dependencySection	(log, "Dependency" + de::toString(depNdx), "Dependency " + de::toString(depNdx));
			const SubpassDependency&	dep					= renderPass.getDependencies()[depNdx];

			log << TestLog::Message << "Source: " << dep.getSrcPass() << TestLog::EndMessage;
			log << TestLog::Message << "Destination: " << dep.getDstPass() << TestLog::EndMessage;

			log << TestLog::Message << "Source Stage Mask: " << dep.getSrcStageMask() << TestLog::EndMessage;
			log << TestLog::Message << "Destination Stage Mask: " << dep.getDstStageMask() << TestLog::EndMessage;

			log << TestLog::Message << "Input Mask: " << dep.getInputMask() << TestLog::EndMessage;
			log << TestLog::Message << "Output Mask: " << dep.getOutputMask() << TestLog::EndMessage;
			log << TestLog::Message << "Dependency Flags: " << getDependencyFlagsStr(dep.getFlags()) << TestLog::EndMessage;
		}
	}
}

std::string clearColorToString (VkFormat vkFormat, VkClearColorValue value)
{
	const tcu::TextureFormat		format			= mapVkFormat(vkFormat);
	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(format.type);
	const tcu::BVec4				channelMask		= tcu::getTextureFormatChannelMask(format);

	std::ostringstream				stream;

	stream << "(";

	switch (channelClass)
	{
		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
			for (int i = 0; i < 4; i++)
			{
				if (i > 0)
					stream << ", ";

				if (channelMask[i])
					stream << value.int32[i];
				else
					stream << "Undef";
			}
			break;

		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
			for (int i = 0; i < 4; i++)
			{
				if (i > 0)
					stream << ", ";

				if (channelMask[i])
					stream << value.uint32[i];
				else
					stream << "Undef";
			}
			break;

		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
			for (int i = 0; i < 4; i++)
			{
				if (i > 0)
					stream << ", ";

				if (channelMask[i])
					stream << value.float32[i];
				else
					stream << "Undef";
			}
			break;

		default:
			DE_FATAL("Unknown channel class");
	}

	stream << ")";

	return stream.str();
}

std::string clearValueToString (VkFormat vkFormat, VkClearValue value)
{
	const tcu::TextureFormat	format	= mapVkFormat(vkFormat);

	if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
	{
		std::ostringstream stream;

		stream << "(";

		if (tcu::hasStencilComponent(format.order))
			stream << "stencil: " << value.depthStencil.stencil;

		if (tcu::hasStencilComponent(format.order) && tcu::hasDepthComponent(format.order))
			stream << ", ";

		if (tcu::hasDepthComponent(format.order))
			stream << "depth: " << value.depthStencil.depth;

		stream << ")";

		return stream.str();
	}
	else
		return clearColorToString(vkFormat, value.color);
}

VkClearColorValue randomColorClearValue (const Attachment& attachment, de::Random& rng)
{
	const float						clearNan		= tcu::Float32::nan().asFloat();
	const tcu::TextureFormat		format			= mapVkFormat(attachment.getFormat());
	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(format.type);
	const tcu::BVec4				channelMask		= tcu::getTextureFormatChannelMask(format);
	VkClearColorValue				clearColor;

	switch (channelClass)
	{
		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
		{
			for (int ndx = 0; ndx < 4; ndx++)
			{
				if (!channelMask[ndx])
					clearColor.int32[ndx] = std::numeric_limits<deInt32>::min();
				else
					clearColor.uint32[ndx] = rng.getBool() ? 1u : 0u;
			}
			break;
		}

		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
		{
			for (int ndx = 0; ndx < 4; ndx++)
			{
				if (!channelMask[ndx])
					clearColor.uint32[ndx] = std::numeric_limits<deUint32>::max();
				else
					clearColor.uint32[ndx] = rng.getBool() ? 1u : 0u;
			}
			break;
		}

		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
		{
			for (int ndx = 0; ndx < 4; ndx++)
			{
				if (!channelMask[ndx])
					clearColor.float32[ndx] = clearNan;
				else
					clearColor.float32[ndx] = rng.getBool() ? 1.0f : 0.0f;
			}
			break;
		}

		default:
			DE_FATAL("Unknown channel class");
	}

	return clearColor;
}

VkAttachmentDescription createAttachmentDescription (const Attachment& attachment)
{
	const VkAttachmentDescription attachmentDescription =
	{
		0,								// flags

		attachment.getFormat(),			// format
		attachment.getSamples(),		// samples

		attachment.getLoadOp(),			// loadOp
		attachment.getStoreOp(),		// storeOp

		attachment.getStencilLoadOp(),	// stencilLoadOp
		attachment.getStencilStoreOp(),	// stencilStoreOp

		attachment.getInitialLayout(),	// initialLayout
		attachment.getFinalLayout(),	// finalLayout
	};

	return attachmentDescription;
}

VkAttachmentReference createAttachmentReference (const AttachmentReference& referenceInfo)
{
	const VkAttachmentReference reference =
	{
		referenceInfo.getAttachment(),	// attachment;
		referenceInfo.getImageLayout()	// layout;
	};

	return reference;
}

VkSubpassDescription createSubpassDescription (const Subpass&					subpass,
											   vector<VkAttachmentReference>*	attachmentReferenceLists,
											   vector<deUint32>*				preserveAttachmentReferences)
{
	vector<VkAttachmentReference>&	inputAttachmentReferences			= attachmentReferenceLists[0];
	vector<VkAttachmentReference>&	colorAttachmentReferences			= attachmentReferenceLists[1];
	vector<VkAttachmentReference>&	resolveAttachmentReferences			= attachmentReferenceLists[2];
	vector<VkAttachmentReference>&	depthStencilAttachmentReferences	= attachmentReferenceLists[3];

	for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
		colorAttachmentReferences.push_back(createAttachmentReference(subpass.getColorAttachments()[attachmentNdx]));

	for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
		inputAttachmentReferences.push_back(createAttachmentReference(subpass.getInputAttachments()[attachmentNdx]));

	for (size_t attachmentNdx = 0; attachmentNdx < subpass.getResolveAttachments().size(); attachmentNdx++)
		resolveAttachmentReferences.push_back(createAttachmentReference(subpass.getResolveAttachments()[attachmentNdx]));

	depthStencilAttachmentReferences.push_back(createAttachmentReference(subpass.getDepthStencilAttachment()));

	for (size_t attachmentNdx = 0; attachmentNdx < subpass.getPreserveAttachments().size(); attachmentNdx++)
		preserveAttachmentReferences->push_back(subpass.getPreserveAttachments()[attachmentNdx]);

	DE_ASSERT(resolveAttachmentReferences.empty() || colorAttachmentReferences.size() == resolveAttachmentReferences.size());

	{
		const VkSubpassDescription subpassDescription =
		{
			subpass.getFlags(),																		// flags;
			subpass.getPipelineBindPoint(),															// pipelineBindPoint;

			(deUint32)inputAttachmentReferences.size(),												// inputCount;
			inputAttachmentReferences.empty() ? DE_NULL : &inputAttachmentReferences[0],			// inputAttachments;

			(deUint32)colorAttachmentReferences.size(),												// colorCount;
			colorAttachmentReferences.empty() ? DE_NULL :  &colorAttachmentReferences[0],			// colorAttachments;
			resolveAttachmentReferences.empty() ? DE_NULL : &resolveAttachmentReferences[0],		// resolveAttachments;

			&depthStencilAttachmentReferences[0],													// pDepthStencilAttachment;
			(deUint32)preserveAttachmentReferences->size(),											// preserveCount;
			preserveAttachmentReferences->empty() ? DE_NULL : &(*preserveAttachmentReferences)[0]	// preserveAttachments;
		};

		return subpassDescription;
	}
}

VkSubpassDependency createSubpassDependency	(const SubpassDependency& dependencyInfo)
{
	const VkSubpassDependency dependency =
	{
		dependencyInfo.getSrcPass(),		// srcSubpass;
		dependencyInfo.getDstPass(),		// destSubpass;

		dependencyInfo.getSrcStageMask(),	// srcStageMask;
		dependencyInfo.getDstStageMask(),	// destStageMask;

		dependencyInfo.getOutputMask(),		// outputMask;
		dependencyInfo.getInputMask(),		// inputMask;

		dependencyInfo.getFlags()			// dependencyFlags;
	};

	return dependency;
}

Move<VkRenderPass> createRenderPass (const DeviceInterface&	vk,
									 VkDevice				device,
									 const RenderPass&		renderPassInfo)
{
	const size_t							perSubpassAttachmentReferenceLists = 4;
	vector<VkAttachmentDescription>			attachments;
	vector<VkSubpassDescription>			subpasses;
	vector<VkSubpassDependency>				dependencies;
	vector<vector<VkAttachmentReference> >	attachmentReferenceLists(renderPassInfo.getSubpasses().size() * perSubpassAttachmentReferenceLists);
	vector<vector<deUint32> >				preserveAttachments(renderPassInfo.getSubpasses().size());

	for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
		attachments.push_back(createAttachmentDescription(renderPassInfo.getAttachments()[attachmentNdx]));

	for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
		subpasses.push_back(createSubpassDescription(renderPassInfo.getSubpasses()[subpassNdx], &(attachmentReferenceLists[subpassNdx * perSubpassAttachmentReferenceLists]), &preserveAttachments[subpassNdx]));

	for (size_t depNdx = 0; depNdx < renderPassInfo.getDependencies().size(); depNdx++)
		dependencies.push_back(createSubpassDependency(renderPassInfo.getDependencies()[depNdx]));

	{
		const VkRenderPassCreateInfo	createInfo	=
		{
			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
			DE_NULL,
			(VkRenderPassCreateFlags)0u,
			(deUint32)attachments.size(),
			(attachments.empty() ? DE_NULL : &attachments[0]),
			(deUint32)subpasses.size(),
			(subpasses.empty() ? DE_NULL : &subpasses[0]),
			(deUint32)dependencies.size(),
			(dependencies.empty() ? DE_NULL : &dependencies[0])
		};

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

Move<VkFramebuffer> createFramebuffer (const DeviceInterface&		vk,
									   VkDevice						device,
									   VkRenderPass					renderPass,
									   const UVec2&					size,
									   const vector<VkImageView>&	attachments)
{
	return createFramebuffer(vk, device, 0u, renderPass, (deUint32)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0], size.x(), size.y(), 1u);
}

Move<VkImage> createAttachmentImage (const DeviceInterface&	vk,
									 VkDevice				device,
									 deUint32				queueIndex,
									 const UVec2&			size,
									 VkFormat				format,
									 VkSampleCountFlagBits	samples,
									 VkImageUsageFlags		usageFlags,
									 VkImageLayout			layout)
{
	VkImageUsageFlags			targetUsageFlags	= 0;
	const tcu::TextureFormat	textureFormat		= mapVkFormat(format);

	DE_ASSERT(!(tcu::hasDepthComponent(vk::mapVkFormat(format).order) || tcu::hasStencilComponent(vk::mapVkFormat(format).order))
					|| ((usageFlags & vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) == 0));

	DE_ASSERT((tcu::hasDepthComponent(vk::mapVkFormat(format).order) || tcu::hasStencilComponent(vk::mapVkFormat(format).order))
					|| ((usageFlags & vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0));

	if (tcu::hasDepthComponent(textureFormat.order) || tcu::hasStencilComponent(textureFormat.order))
		targetUsageFlags |= vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
	else
		targetUsageFlags |= vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;

	return createImage(vk, device,
					   (VkImageCreateFlags)0,
					   VK_IMAGE_TYPE_2D,
					   format,
					   vk::makeExtent3D(size.x(), size.y(), 1u),
					   1u /* mipLevels */,
					   1u /* arraySize */,
					   samples,
					   VK_IMAGE_TILING_OPTIMAL,
					   usageFlags | targetUsageFlags,
					   VK_SHARING_MODE_EXCLUSIVE,
					   1,
					   &queueIndex,
					   layout);
}

de::MovePtr<Allocation> createImageMemory (const InstanceInterface&	vki,
										   const VkPhysicalDevice&	vkd,
										   const DeviceInterface&	vk,
										   VkDevice					device,
										   Allocator&				allocator,
										   VkImage					image,
										   bool						lazy,
										   AllocationKind			allocationKind)
{
	const MemoryRequirement memoryRequirement	= lazy ? MemoryRequirement::LazilyAllocated : MemoryRequirement::Any;
	de::MovePtr<Allocation> allocation			= allocateImage(vki, vk, vkd, device, image, memoryRequirement, allocator, allocationKind);

	bindImageMemory(vk, device, image, allocation->getMemory(), allocation->getOffset());

	return allocation;
}

Move<VkImageView> createImageAttachmentView (const DeviceInterface&	vk,
											 VkDevice				device,
											 VkImage				image,
											 VkFormat				format,
											 VkImageAspectFlags		aspect)
{
	const VkImageSubresourceRange range =
	{
		aspect,
		0,
		1,
		0,
		1
	};

	return createImageView(vk, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
}

VkClearValue randomClearValue (const Attachment& attachment, de::Random& rng)
{
	const float					clearNan	= tcu::Float32::nan().asFloat();
	const tcu::TextureFormat	format		= mapVkFormat(attachment.getFormat());

	if (tcu::hasStencilComponent(format.order) || tcu::hasDepthComponent(format.order))
	{
		VkClearValue clearValue;

		clearValue.depthStencil.depth	= clearNan;
		clearValue.depthStencil.stencil	= 0xCDu;

		if (tcu::hasStencilComponent(format.order))
			clearValue.depthStencil.stencil	= rng.getBool()
											? 0xFFu
											: 0x0u;

		if (tcu::hasDepthComponent(format.order))
			clearValue.depthStencil.depth	= rng.getBool()
											? 1.0f
											: 0.0f;

		return clearValue;
	}
	else
	{
		VkClearValue clearValue;

		clearValue.color = randomColorClearValue(attachment, rng);

		return clearValue;
	}
}

class AttachmentResources
{
public:
	AttachmentResources (const InstanceInterface&	vki,
						 const VkPhysicalDevice&	physDevice,
						 const DeviceInterface&		vk,
						 VkDevice					device,
						 Allocator&					allocator,
						 deUint32					queueIndex,
						 const UVec2&				size,
						 const Attachment&			attachmentInfo,
						 VkImageUsageFlags			usageFlags,
						 const AllocationKind		allocationKind)
		: m_image			(createAttachmentImage(vk, device, queueIndex, size, attachmentInfo.getFormat(), attachmentInfo.getSamples(), usageFlags, VK_IMAGE_LAYOUT_UNDEFINED))
		, m_imageMemory		(createImageMemory(vki, physDevice, vk, device, allocator, *m_image, ((usageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0), allocationKind))
		, m_attachmentView	(createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), getImageAspectFlags(attachmentInfo.getFormat())))
	{
		const tcu::TextureFormat	format			= mapVkFormat(attachmentInfo.getFormat());
		const bool					isDepthFormat	= tcu::hasDepthComponent(format.order);
		const bool					isStencilFormat	= tcu::hasStencilComponent(format.order);

		if (isDepthFormat && isStencilFormat)
		{
			m_depthInputAttachmentView		= createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), VK_IMAGE_ASPECT_DEPTH_BIT);
			m_stencilInputAttachmentView	= createImageAttachmentView(vk, device, *m_image, attachmentInfo.getFormat(), VK_IMAGE_ASPECT_STENCIL_BIT);

			m_inputAttachmentViews = std::make_pair(*m_depthInputAttachmentView, *m_stencilInputAttachmentView);
		}
		else
			m_inputAttachmentViews = std::make_pair(*m_attachmentView, (vk::VkImageView)0u);

		if ((usageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) == 0)
		{
			if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
			{
				const tcu::TextureFormat	depthFormat		= getDepthCopyFormat(attachmentInfo.getFormat());
				const tcu::TextureFormat	stencilFormat	= getStencilCopyFormat(attachmentInfo.getFormat());

				m_bufferSize			= size.x() * size.y() * depthFormat.getPixelSize();
				m_secondaryBufferSize	= size.x() * size.y() * stencilFormat.getPixelSize();

				m_buffer				= createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
				m_bufferMemory			= allocateBuffer(vki, vk, physDevice, device, *m_buffer, MemoryRequirement::HostVisible, allocator, allocationKind);

				bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());

				m_secondaryBuffer		= createBuffer(vk, device, 0, m_secondaryBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
				m_secondaryBufferMemory	= allocateBuffer(vki, vk, physDevice, device, *m_secondaryBuffer, MemoryRequirement::HostVisible, allocator, allocationKind);

				bindBufferMemory(vk, device, *m_secondaryBuffer, m_secondaryBufferMemory->getMemory(), m_secondaryBufferMemory->getOffset());
			}
			else
			{
				m_bufferSize	= size.x() * size.y() * format.getPixelSize();

				m_buffer		= createBuffer(vk, device, 0, m_bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, 1, &queueIndex);
				m_bufferMemory	= allocateBuffer(vki, vk, physDevice, device, *m_buffer, MemoryRequirement::HostVisible, allocator, allocationKind);

				bindBufferMemory(vk, device, *m_buffer, m_bufferMemory->getMemory(), m_bufferMemory->getOffset());
			}
		}
	}

	const pair<VkImageView, VkImageView>& getInputAttachmentViews (void) const
	{
		return m_inputAttachmentViews;
	}

	~AttachmentResources (void)
	{
	}

	VkImageView getAttachmentView (void) const
	{
		return *m_attachmentView;
	}

	VkImage getImage (void) const
	{
		return *m_image;
	}

	VkBuffer getBuffer (void) const
	{
		DE_ASSERT(*m_buffer != DE_NULL);
		return *m_buffer;
	}

	VkDeviceSize getBufferSize (void) const
	{
		DE_ASSERT(*m_buffer != DE_NULL);
		return m_bufferSize;
	}

	const Allocation& getResultMemory (void) const
	{
		DE_ASSERT(m_bufferMemory);
		return *m_bufferMemory;
	}

	VkBuffer getSecondaryBuffer (void) const
	{
		DE_ASSERT(*m_secondaryBuffer != DE_NULL);
		return *m_secondaryBuffer;
	}

	VkDeviceSize getSecondaryBufferSize (void) const
	{
		DE_ASSERT(*m_secondaryBuffer != DE_NULL);
		return m_secondaryBufferSize;
	}

	const Allocation& getSecondaryResultMemory (void) const
	{
		DE_ASSERT(m_secondaryBufferMemory);
		return *m_secondaryBufferMemory;
	}

private:
	const Unique<VkImage>			m_image;
	const UniquePtr<Allocation>		m_imageMemory;
	const Unique<VkImageView>		m_attachmentView;

	Move<VkImageView>				m_depthInputAttachmentView;
	Move<VkImageView>				m_stencilInputAttachmentView;
	pair<VkImageView, VkImageView>	m_inputAttachmentViews;

	Move<VkBuffer>					m_buffer;
	VkDeviceSize					m_bufferSize;
	de::MovePtr<Allocation>			m_bufferMemory;

	Move<VkBuffer>					m_secondaryBuffer;
	VkDeviceSize					m_secondaryBufferSize;
	de::MovePtr<Allocation>			m_secondaryBufferMemory;
};

void uploadBufferData (const DeviceInterface&	vk,
					   VkDevice					device,
					   const Allocation&		memory,
					   size_t					size,
					   const void*				data)
{
	const VkMappedMemoryRange range =
	{
		VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,	// sType;
		DE_NULL,								// pNext;
		memory.getMemory(),						// mem;
		memory.getOffset(),						// offset;
		(VkDeviceSize)size						// size;
	};
	void* const ptr = memory.getHostPtr();

	deMemcpy(ptr, data, size);
	VK_CHECK(vk.flushMappedMemoryRanges(device, 1, &range));
}

VkImageAspectFlagBits getPrimaryImageAspect (tcu::TextureFormat::ChannelOrder order)
{
	DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST == 21);

	switch (order)
	{
		case tcu::TextureFormat::D:
		case tcu::TextureFormat::DS:
			return VK_IMAGE_ASPECT_DEPTH_BIT;

		case tcu::TextureFormat::S:
			return VK_IMAGE_ASPECT_STENCIL_BIT;

		default:
			return VK_IMAGE_ASPECT_COLOR_BIT;
	}
}

class RenderQuad
{
public:
					RenderQuad			(const Vec2& posA, const Vec2& posB)
		: m_vertices(6)
	{
		m_vertices[0] = posA;
		m_vertices[1] = Vec2(posA[0], posB[1]);
		m_vertices[2] = posB;

		m_vertices[3] = posB;
		m_vertices[4] = Vec2(posB[0], posA[1]);
		m_vertices[5] = posA;
	}

	const Vec2&		getCornerA			(void) const
	{
		return m_vertices[0];
	}

	const Vec2&		getCornerB			(void) const
	{
		return m_vertices[2];
	}

	const void*		getVertexPointer	(void) const
	{
		return &m_vertices[0];
	}

	size_t			getVertexDataSize	(void) const
	{
		return sizeof(Vec2) * m_vertices.size();
	}

private:
	vector<Vec2>	m_vertices;
};

class ColorClear
{
public:
								ColorClear	(const UVec2&				offset,
											 const UVec2&				size,
											 const VkClearColorValue&	color)
		: m_offset	(offset)
		, m_size	(size)
		, m_color	(color)
	{
	}

	const UVec2&				getOffset	(void) const { return m_offset;	}
	const UVec2&				getSize		(void) const { return m_size;	}
	const VkClearColorValue&	getColor	(void) const { return m_color;	}

private:
	UVec2						m_offset;
	UVec2						m_size;
	VkClearColorValue			m_color;
};

class DepthStencilClear
{
public:
					DepthStencilClear	(const UVec2&	offset,
										 const UVec2&	size,
										 float			depth,
										 deUint32		stencil)
		: m_offset	(offset)
		, m_size	(size)
		, m_depth	(depth)
		, m_stencil	(stencil)
	{
	}

	const UVec2&	getOffset			(void) const { return m_offset;		}
	const UVec2&	getSize				(void) const { return m_size;		}
	float			getDepth			(void) const { return m_depth;		}
	deUint32		getStencil			(void) const { return m_stencil;	}

private:
	const UVec2		m_offset;
	const UVec2		m_size;

	const float		m_depth;
	const deUint32	m_stencil;
};

class SubpassRenderInfo
{
public:
									SubpassRenderInfo				(const RenderPass&					renderPass,
																	 deUint32							subpassIndex,

																	 bool								isSecondary_,

																	 const UVec2&						viewportOffset,
																	 const UVec2&						viewportSize,

																	 const Maybe<RenderQuad>&			renderQuad,
																	 const vector<ColorClear>&			colorClears,
																	 const Maybe<DepthStencilClear>&	depthStencilClear)
		: m_viewportOffset		(viewportOffset)
		, m_viewportSize		(viewportSize)
		, m_subpassIndex		(subpassIndex)
		, m_isSecondary			(isSecondary_)
		, m_flags				(renderPass.getSubpasses()[subpassIndex].getFlags())
		, m_renderQuad			(renderQuad)
		, m_colorClears			(colorClears)
		, m_depthStencilClear	(depthStencilClear)
		, m_colorAttachments	(renderPass.getSubpasses()[subpassIndex].getColorAttachments())
		, m_inputAttachments	(renderPass.getSubpasses()[subpassIndex].getInputAttachments())
	{
		for (deUint32 attachmentNdx = 0; attachmentNdx < (deUint32)m_colorAttachments.size(); attachmentNdx++)
			m_colorAttachmentInfo.push_back(renderPass.getAttachments()[m_colorAttachments[attachmentNdx].getAttachment()]);

		if (renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
		{
			m_depthStencilAttachment		= tcu::just(renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment());
			m_depthStencilAttachmentInfo	= tcu::just(renderPass.getAttachments()[renderPass.getSubpasses()[subpassIndex].getDepthStencilAttachment().getAttachment()]);
		}
	}

	const UVec2&					getViewportOffset				(void) const { return m_viewportOffset;		}
	const UVec2&					getViewportSize					(void) const { return m_viewportSize;		}

	deUint32						getSubpassIndex					(void) const { return m_subpassIndex;		}
	bool							isSecondary						(void) const { return m_isSecondary;		}

	const Maybe<RenderQuad>&		getRenderQuad					(void) const { return m_renderQuad;			}
	const vector<ColorClear>&		getColorClears					(void) const { return m_colorClears;		}
	const Maybe<DepthStencilClear>&	getDepthStencilClear			(void) const { return m_depthStencilClear;	}

	deUint32						getInputAttachmentCount			(void) const { return (deUint32)m_inputAttachments.size(); }
	deUint32						getInputAttachmentIndex			(deUint32 attachmentNdx) const { return m_inputAttachments[attachmentNdx].getAttachment(); }
	VkImageLayout					getInputAttachmentLayout		(deUint32 attachmentNdx) const { return m_inputAttachments[attachmentNdx].getImageLayout(); }

	deUint32						getColorAttachmentCount			(void) const { return (deUint32)m_colorAttachments.size(); }
	VkImageLayout					getColorAttachmentLayout		(deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getImageLayout(); }
	deUint32						getColorAttachmentIndex			(deUint32 attachmentNdx) const { return m_colorAttachments[attachmentNdx].getAttachment(); }
	const Attachment&				getColorAttachment				(deUint32 attachmentNdx) const { return m_colorAttachmentInfo[attachmentNdx]; }
	Maybe<VkImageLayout>			getDepthStencilAttachmentLayout	(void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getImageLayout()) : tcu::nothing<VkImageLayout>(); }
	Maybe<deUint32>					getDepthStencilAttachmentIndex	(void) const { return m_depthStencilAttachment ? tcu::just(m_depthStencilAttachment->getAttachment()) : tcu::nothing<deUint32>(); };
	const Maybe<Attachment>&		getDepthStencilAttachment		(void) const { return m_depthStencilAttachmentInfo; }
	VkSubpassDescriptionFlags		getSubpassFlags					(void) const { return m_flags; }

private:
	UVec2							m_viewportOffset;
	UVec2							m_viewportSize;

	deUint32						m_subpassIndex;
	bool							m_isSecondary;
	VkSubpassDescriptionFlags		m_flags;

	Maybe<RenderQuad>				m_renderQuad;
	vector<ColorClear>				m_colorClears;
	Maybe<DepthStencilClear>		m_depthStencilClear;

	vector<AttachmentReference>		m_colorAttachments;
	vector<Attachment>				m_colorAttachmentInfo;

	Maybe<AttachmentReference>		m_depthStencilAttachment;
	Maybe<Attachment>				m_depthStencilAttachmentInfo;

	vector<AttachmentReference>		m_inputAttachments;
};

Move<VkPipeline> createSubpassPipeline (const DeviceInterface&		vk,
										VkDevice					device,
										VkRenderPass				renderPass,
										VkShaderModule				vertexShaderModule,
										VkShaderModule				fragmentShaderModule,
										VkPipelineLayout			pipelineLayout,
										const SubpassRenderInfo&	renderInfo)
{
	const VkSpecializationInfo emptyShaderSpecializations =
	{
		0u,			// mapEntryCount
		DE_NULL,	// pMap
		0u,			// dataSize
		DE_NULL,	// pData
	};

	Maybe<VkSampleCountFlagBits>				rasterSamples;
	vector<VkPipelineColorBlendAttachmentState>	attachmentBlendStates;

	for (deUint32 attachmentNdx = 0; attachmentNdx < renderInfo.getColorAttachmentCount(); attachmentNdx++)
	{
		const Attachment&	attachment	= renderInfo.getColorAttachment(attachmentNdx);

		DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());

		rasterSamples = attachment.getSamples();

		{
			const VkPipelineColorBlendAttachmentState	attachmentBlendState =
			{
				VK_FALSE,																								// blendEnable
				VK_BLEND_FACTOR_SRC_ALPHA,																				// srcBlendColor
				VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,																	// destBlendColor
				VK_BLEND_OP_ADD,																						// blendOpColor
				VK_BLEND_FACTOR_ONE,																					// srcBlendAlpha
				VK_BLEND_FACTOR_ONE,																					// destBlendAlpha
				VK_BLEND_OP_ADD,																						// blendOpAlpha
				VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT,	// channelWriteMask
			};

			attachmentBlendStates.push_back(attachmentBlendState);
		}
	}

	if (renderInfo.getDepthStencilAttachment())
	{
		const Attachment& attachment = *renderInfo.getDepthStencilAttachment();

		DE_ASSERT(!rasterSamples || *rasterSamples == attachment.getSamples());
		rasterSamples = attachment.getSamples();
	}

	// If there are no attachment use single sample
	if (!rasterSamples)
		rasterSamples = VK_SAMPLE_COUNT_1_BIT;

	const VkPipelineShaderStageCreateInfo shaderStages[2] =
	{
		{
			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// sType
			DE_NULL,												// pNext
			(VkPipelineShaderStageCreateFlags)0u,
			VK_SHADER_STAGE_VERTEX_BIT,								// stage
			vertexShaderModule,										// shader
			"main",
			&emptyShaderSpecializations
		},
		{
			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// sType
			DE_NULL,												// pNext
			(VkPipelineShaderStageCreateFlags)0u,
			VK_SHADER_STAGE_FRAGMENT_BIT,							// stage
			fragmentShaderModule,									// shader
			"main",
			&emptyShaderSpecializations
		}
	};
	const VkVertexInputBindingDescription vertexBinding =
	{
		0u,															// binding
		(deUint32)sizeof(tcu::Vec2),								// strideInBytes
		VK_VERTEX_INPUT_RATE_VERTEX,								// stepRate
	};
	const VkVertexInputAttributeDescription vertexAttrib =
	{
		0u,															// location
		0u,															// binding
		VK_FORMAT_R32G32_SFLOAT,									// format
		0u,															// offsetInBytes
	};
	const VkPipelineVertexInputStateCreateInfo vertexInputState =
	{
		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	//	sType
		DE_NULL,													//	pNext
		(VkPipelineVertexInputStateCreateFlags)0u,
		1u,															//	bindingCount
		&vertexBinding,												//	pVertexBindingDescriptions
		1u,															//	attributeCount
		&vertexAttrib,												//	pVertexAttributeDescriptions
	};
	const VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
	{
		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// sType
		DE_NULL,														// pNext
		(VkPipelineInputAssemblyStateCreateFlags)0u,
		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,							// topology
		VK_FALSE,														// primitiveRestartEnable
	};
	const VkViewport viewport =
	{
		(float)renderInfo.getViewportOffset().x(),	(float)renderInfo.getViewportOffset().y(),
		(float)renderInfo.getViewportSize().x(),	(float)renderInfo.getViewportSize().y(),
		0.0f, 1.0f
	};
	const VkRect2D scissor =
	{
		{ (deInt32)renderInfo.getViewportOffset().x(),	(deInt32)renderInfo.getViewportOffset().y() },
		{ renderInfo.getViewportSize().x(),				renderInfo.getViewportSize().y() }
	};
	const VkPipelineViewportStateCreateInfo viewportState =
	{
		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
		DE_NULL,
		(VkPipelineViewportStateCreateFlags)0u,
		1u,
		&viewport,
		1u,
		&scissor
	};
	const VkPipelineRasterizationStateCreateInfo rasterState =
	{
		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// sType
		DE_NULL,														// pNext
		(VkPipelineRasterizationStateCreateFlags)0u,
		VK_TRUE,														// depthClipEnable
		VK_FALSE,														// rasterizerDiscardEnable
		VK_POLYGON_MODE_FILL,											// fillMode
		VK_CULL_MODE_NONE,												// cullMode
		VK_FRONT_FACE_COUNTER_CLOCKWISE,								// frontFace
		VK_FALSE,														// depthBiasEnable
		0.0f,															// depthBias
		0.0f,															// depthBiasClamp
		0.0f,															// slopeScaledDepthBias
		1.0f															// lineWidth
	};
	const VkPipelineMultisampleStateCreateInfo multisampleState =
	{
		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,		// sType
		DE_NULL,														// pNext
		(VkPipelineMultisampleStateCreateFlags)0u,
		*rasterSamples,													// rasterSamples
		VK_FALSE,														// sampleShadingEnable
		0.0f,															// minSampleShading
		DE_NULL,														// pSampleMask
		VK_FALSE,														// alphaToCoverageEnable
		VK_FALSE,														// alphaToOneEnable
	};
	const size_t stencilIndex = renderInfo.getSubpassIndex();
	const VkPipelineDepthStencilStateCreateInfo depthStencilState =
	{
		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// sType
		DE_NULL,													// pNext
		(VkPipelineDepthStencilStateCreateFlags)0u,
		VK_TRUE,													// depthTestEnable
		VK_TRUE,													// depthWriteEnable
		VK_COMPARE_OP_ALWAYS,										// depthCompareOp
		VK_FALSE,													// depthBoundsEnable
		VK_TRUE,													// stencilTestEnable
		{
			VK_STENCIL_OP_REPLACE,									// stencilFailOp
			VK_STENCIL_OP_REPLACE,									// stencilPassOp
			VK_STENCIL_OP_REPLACE,									// stencilDepthFailOp
			VK_COMPARE_OP_ALWAYS,									// stencilCompareOp
			~0u,													// stencilCompareMask
			~0u,													// stencilWriteMask
			((stencilIndex % 2) == 0) ? ~0x0u : 0x0u				// stencilReference
		},															// front
		{
			VK_STENCIL_OP_REPLACE,									// stencilFailOp
			VK_STENCIL_OP_REPLACE,									// stencilPassOp
			VK_STENCIL_OP_REPLACE,									// stencilDepthFailOp
			VK_COMPARE_OP_ALWAYS,									// stencilCompareOp
			~0u,													// stencilCompareMask
			~0u,													// stencilWriteMask
			((stencilIndex % 2) == 0) ? ~0x0u : 0x0u				// stencilReference
		},															// back

		0.0f,														// minDepthBounds;
		1.0f														// maxDepthBounds;
	};
	const VkPipelineColorBlendStateCreateInfo blendState =
	{
		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,			// sType
		DE_NULL,															// pNext
		(VkPipelineColorBlendStateCreateFlags)0u,
		VK_FALSE,															// logicOpEnable
		VK_LOGIC_OP_COPY,													// logicOp
		(deUint32)attachmentBlendStates.size(),								// attachmentCount
		attachmentBlendStates.empty() ? DE_NULL : &attachmentBlendStates[0],// pAttachments
		{ 0.0f, 0.0f, 0.0f, 0.0f }											// blendConst
	};
	const VkGraphicsPipelineCreateInfo createInfo =
	{
		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// sType
		DE_NULL,											// pNext
		(VkPipelineCreateFlags)0u,

		2,													// stageCount
		shaderStages,										// pStages

		&vertexInputState,									// pVertexInputState
		&inputAssemblyState,								// pInputAssemblyState
		DE_NULL,											// pTessellationState
		&viewportState,										// pViewportState
		&rasterState,										// pRasterState
		&multisampleState,									// pMultisampleState
		&depthStencilState,									// pDepthStencilState
		&blendState,										// pColorBlendState
		(const VkPipelineDynamicStateCreateInfo*)DE_NULL,	// pDynamicState
		pipelineLayout,										// layout

		renderPass,											// renderPass
		renderInfo.getSubpassIndex(),						// subpass
		DE_NULL,											// basePipelineHandle
		0u													// basePipelineIndex
	};

	return createGraphicsPipeline(vk, device, DE_NULL, &createInfo);
}

class SubpassRenderer
{
public:
	SubpassRenderer (Context&										context,
					 const DeviceInterface&							vk,
					 VkDevice										device,
					 Allocator&										allocator,
					 VkRenderPass									renderPass,
					 VkFramebuffer									framebuffer,
					 VkCommandPool									commandBufferPool,
					 deUint32										queueFamilyIndex,
					 const vector<VkImage>&							attachmentImages,
					 const vector<pair<VkImageView, VkImageView> >&	attachmentViews,
					 const SubpassRenderInfo&						renderInfo,
					 const vector<Attachment>&						attachmentInfos,
					 const AllocationKind							allocationKind)
		: m_renderInfo	(renderInfo)
	{
		const InstanceInterface&				vki				= context.getInstanceInterface();
		const VkPhysicalDevice&					physDevice		= context.getPhysicalDevice();
		const deUint32							subpassIndex	= renderInfo.getSubpassIndex();
		vector<VkDescriptorSetLayoutBinding>	bindings;

		for (deUint32 colorAttachmentNdx = 0; colorAttachmentNdx < renderInfo.getColorAttachmentCount();  colorAttachmentNdx++)
			m_colorAttachmentImages.push_back(attachmentImages[renderInfo.getColorAttachmentIndex(colorAttachmentNdx)]);

		if (renderInfo.getDepthStencilAttachmentIndex())
			m_depthStencilAttachmentImage = attachmentImages[*renderInfo.getDepthStencilAttachmentIndex()];

		if (renderInfo.getRenderQuad())
		{
			const RenderQuad&	renderQuad	= *renderInfo.getRenderQuad();

			if (renderInfo.getInputAttachmentCount() > 0)
			{
				deUint32								bindingIndex	= 0;

				for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
				{
					const Attachment			attachmentInfo	= attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)];
					const tcu::TextureFormat	format			= mapVkFormat(attachmentInfo.getFormat());
					const bool					isDepthFormat	= tcu::hasDepthComponent(format.order);
					const bool					isStencilFormat	= tcu::hasStencilComponent(format.order);
					const deUint32				bindingCount	= isDepthFormat && isStencilFormat ? 2u : 1u;

					for (deUint32 bindingNdx = 0; bindingNdx < bindingCount; bindingNdx++)
					{
						const VkDescriptorSetLayoutBinding binding =
						{
							bindingIndex,
							vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
							1u,
							vk::VK_SHADER_STAGE_FRAGMENT_BIT,
							DE_NULL
						};

						bindings.push_back(binding);
						bindingIndex++;
					}
				}

				const VkDescriptorSetLayoutCreateInfo createInfo =
				{
					vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
					DE_NULL,

					0u,
					(deUint32)bindings.size(),
					&bindings[0]
				};

				m_descriptorSetLayout = vk::createDescriptorSetLayout(vk, device, &createInfo);
			}

			const VkDescriptorSetLayout			descriptorSetLayout		= *m_descriptorSetLayout;
			const VkPipelineLayoutCreateInfo	pipelineLayoutParams	=
			{
				VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,			// sType;
				DE_NULL,												// pNext;
				(vk::VkPipelineLayoutCreateFlags)0,
				m_descriptorSetLayout ? 1u :0u ,						// setLayoutCount;
				m_descriptorSetLayout ? &descriptorSetLayout : DE_NULL,	// pSetLayouts;
				0u,														// pushConstantRangeCount;
				DE_NULL,												// pPushConstantRanges;
			};

			m_vertexShaderModule	= createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-vert"), 0u);
			m_fragmentShaderModule	= createShaderModule(vk, device, context.getBinaryCollection().get(de::toString(subpassIndex) + "-frag"), 0u);
			m_pipelineLayout		= createPipelineLayout(vk, device, &pipelineLayoutParams);
			m_pipeline				= createSubpassPipeline(vk, device, renderPass, *m_vertexShaderModule, *m_fragmentShaderModule, *m_pipelineLayout, m_renderInfo);

			m_vertexBuffer			= createBuffer(vk, device, 0u, (VkDeviceSize)renderQuad.getVertexDataSize(), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_SHARING_MODE_EXCLUSIVE, 1u, &queueFamilyIndex);
			m_vertexBufferMemory	= allocateBuffer(vki, vk, physDevice, device, *m_vertexBuffer, MemoryRequirement::HostVisible, allocator, allocationKind);

			bindBufferMemory(vk, device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset());
			uploadBufferData(vk, device, *m_vertexBufferMemory, renderQuad.getVertexDataSize(), renderQuad.getVertexPointer());

			if (renderInfo.getInputAttachmentCount() > 0)
			{
				{
					const VkDescriptorPoolSize poolSize =
					{
						vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
						// \note Reserve 2 per input attachment since depthStencil attachments require 2.
						renderInfo.getInputAttachmentCount() * 2u
					};
					const VkDescriptorPoolCreateInfo createInfo =
					{
						vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
						DE_NULL,
						VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,

						// \note Reserve 2 per input attachment since depthStencil attachments require 2.
						renderInfo.getInputAttachmentCount() * 2u,
						1u,
						&poolSize
					};

					m_descriptorPool = vk::createDescriptorPool(vk, device, &createInfo);
				}
				{
					const VkDescriptorSetAllocateInfo	allocateInfo =
					{
						vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
						DE_NULL,

						*m_descriptorPool,
						1u,
						&descriptorSetLayout
					};

					m_descriptorSet = vk::allocateDescriptorSet(vk, device, &allocateInfo);
				}
				{
					vector<VkWriteDescriptorSet>	writes			(bindings.size());
					vector<VkDescriptorImageInfo>	imageInfos		(bindings.size());
					deUint32						bindingIndex	= 0;

					for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
					{
						const Attachment			attachmentInfo			= attachmentInfos[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)];
						const tcu::TextureFormat	format					= mapVkFormat(attachmentInfo.getFormat());
						const bool					isDepthFormat			= tcu::hasDepthComponent(format.order);
						const bool					isStencilFormat			= tcu::hasStencilComponent(format.order);
						const VkImageLayout			inputAttachmentLayout	= renderInfo.getInputAttachmentLayout(inputAttachmentNdx);

						if (isDepthFormat && isStencilFormat)
						{
							{
								const VkDescriptorImageInfo	imageInfo =
								{
									(VkSampler)0,
									attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first,
									inputAttachmentLayout
								};
								imageInfos[bindingIndex] = imageInfo;

								{
									const VkWriteDescriptorSet	write =
									{
										VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
										DE_NULL,

										*m_descriptorSet,
										bindingIndex,
										0u,
										1u,
										VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
										&imageInfos[bindingIndex],
										DE_NULL,
										DE_NULL
									};
									writes[bindingIndex] = write;

									bindingIndex++;
								}
							}
							{
								const VkDescriptorImageInfo	imageInfo =
								{
									(VkSampler)0,
									attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].second,
									inputAttachmentLayout
								};
								imageInfos[bindingIndex] = imageInfo;

								{
									const VkWriteDescriptorSet	write =
									{
										VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
										DE_NULL,

										*m_descriptorSet,
										bindingIndex,
										0u,
										1u,
										VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
										&imageInfos[bindingIndex],
										DE_NULL,
										DE_NULL
									};
									writes[bindingIndex] = write;

									bindingIndex++;
								}
							}
						}
						else
						{
							const VkDescriptorImageInfo	imageInfo =
							{
								(VkSampler)0,
								attachmentViews[renderInfo.getInputAttachmentIndex(inputAttachmentNdx)].first,
								inputAttachmentLayout
							};
							imageInfos[bindingIndex] = imageInfo;

							{
								const VkWriteDescriptorSet	write =
								{
									VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
									DE_NULL,

									*m_descriptorSet,
									bindingIndex,
									0u,
									1u,
									VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
									&imageInfos[bindingIndex],
									DE_NULL,
									DE_NULL
								};
								writes[bindingIndex] = write;

								bindingIndex++;
							}
						}
					}

					vk.updateDescriptorSets(device, (deUint32)writes.size(), &writes[0], 0u, DE_NULL);
				}
			}
		}

		if (renderInfo.isSecondary())
		{
			m_commandBuffer = allocateCommandBuffer(vk, device, commandBufferPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);

			beginCommandBuffer(vk, *m_commandBuffer, vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, renderPass, subpassIndex, framebuffer, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
			pushRenderCommands(vk, *m_commandBuffer);
			endCommandBuffer(vk, *m_commandBuffer);
		}
	}

	bool isSecondary (void) const
	{
		return m_commandBuffer;
	}

	VkCommandBuffer getCommandBuffer (void) const
	{
		DE_ASSERT(isSecondary());
		return *m_commandBuffer;
	}

	void pushRenderCommands (const DeviceInterface&		vk,
							 VkCommandBuffer			commandBuffer)
	{
		if (!m_renderInfo.getColorClears().empty())
		{
			const vector<ColorClear>&	colorClears	(m_renderInfo.getColorClears());

			for (deUint32 attachmentNdx = 0; attachmentNdx < m_renderInfo.getColorAttachmentCount(); attachmentNdx++)
			{
				const ColorClear&		colorClear	= colorClears[attachmentNdx];
				const VkClearAttachment	attachment	=
				{
					VK_IMAGE_ASPECT_COLOR_BIT,
					attachmentNdx,
					makeClearValue(colorClear.getColor()),
				};
				const VkClearRect		rect		=
				{
					{
						{ (deInt32)colorClear.getOffset().x(),	(deInt32)colorClear.getOffset().y()	},
						{ colorClear.getSize().x(),				colorClear.getSize().y()			}
					},					// rect
					0u,					// baseArrayLayer
					1u,					// layerCount
				};

				vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
			}
		}

		if (m_renderInfo.getDepthStencilClear())
		{
			const DepthStencilClear&	depthStencilClear	= *m_renderInfo.getDepthStencilClear();
			const deUint32				attachmentNdx		= m_renderInfo.getColorAttachmentCount();
			tcu::TextureFormat			format				= mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
			const VkClearAttachment		attachment			=
			{
				(VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
					| (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
				attachmentNdx,
				makeClearValueDepthStencil(depthStencilClear.getDepth(), depthStencilClear.getStencil())
			};
			const VkClearRect				rect				=
			{
				{
					{ (deInt32)depthStencilClear.getOffset().x(),	(deInt32)depthStencilClear.getOffset().y()	},
					{ depthStencilClear.getSize().x(),				depthStencilClear.getSize().y()				}
				},							// rect
				0u,							// baseArrayLayer
				1u,							// layerCount
			};

			vk.cmdClearAttachments(commandBuffer, 1u, &attachment, 1u, &rect);
		}

		vector<VkImageMemoryBarrier>	selfDeps;
		VkPipelineStageFlags			srcStages = 0;
		VkPipelineStageFlags			dstStages = 0;

		for (deUint32 inputAttachmentNdx = 0; inputAttachmentNdx < m_renderInfo.getInputAttachmentCount(); inputAttachmentNdx++)
		{
			for (deUint32 colorAttachmentNdx = 0; colorAttachmentNdx < m_renderInfo.getColorAttachmentCount(); colorAttachmentNdx++)
			{
				if (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) == m_renderInfo.getColorAttachmentIndex(colorAttachmentNdx))
				{
					const VkImageMemoryBarrier	barrier   =
					{
						VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// sType
						DE_NULL,										// pNext

						VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// srcAccessMask
						VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,			// dstAccessMask

						VK_IMAGE_LAYOUT_GENERAL,						// oldLayout
						VK_IMAGE_LAYOUT_GENERAL,						// newLayout

						VK_QUEUE_FAMILY_IGNORED,						// srcQueueFamilyIndex
						VK_QUEUE_FAMILY_IGNORED,						// destQueueFamilyIndex

						m_colorAttachmentImages[colorAttachmentNdx],	// image
						{												// subresourceRange
							VK_IMAGE_ASPECT_COLOR_BIT,						// aspect
							0,												// baseMipLevel
							1,												// mipLevels
							0,												// baseArraySlice
							1												// arraySize
						}
					};

					srcStages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
					dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;

					selfDeps.push_back(barrier);
				}
			}

			if (m_renderInfo.getDepthStencilAttachmentIndex() && (m_renderInfo.getInputAttachmentIndex(inputAttachmentNdx) == *m_renderInfo.getDepthStencilAttachmentIndex()))
			{
				const tcu::TextureFormat	format		= mapVkFormat(m_renderInfo.getDepthStencilAttachment()->getFormat());
				const bool					hasDepth	= hasDepthComponent(format.order);
				const bool					hasStencil	= hasStencilComponent(format.order);
				const VkImageMemoryBarrier	barrier		=
				{
					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// sType;
					DE_NULL,										// pNext;

					VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,	// srcAccessMask
					VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,			// dstAccessMask

					VK_IMAGE_LAYOUT_GENERAL,						// oldLayout
					VK_IMAGE_LAYOUT_GENERAL,						// newLayout;

					VK_QUEUE_FAMILY_IGNORED,						// srcQueueFamilyIndex;
					VK_QUEUE_FAMILY_IGNORED,						// destQueueFamilyIndex;

					m_depthStencilAttachmentImage,					// image;
					{												// subresourceRange;
						(hasDepth ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT : 0u)
							| (hasStencil ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT : 0u),	// aspect;
						0,															// baseMipLevel;
						1,															// mipLevels;
						0,															// baseArraySlice;
						1															// arraySize;
					}
				};

				srcStages |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
				dstStages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;

				selfDeps.push_back(barrier);
			}
		}

		if (!selfDeps.empty())
		{
			DE_ASSERT(srcStages != 0);
			DE_ASSERT(dstStages != 0);
			vk.cmdPipelineBarrier(commandBuffer, srcStages, dstStages, VK_DEPENDENCY_BY_REGION_BIT, 0, DE_NULL, 0, DE_NULL, (deUint32)selfDeps.size(), &selfDeps[0]);
		}

		if (m_renderInfo.getRenderQuad())
		{
			const VkDeviceSize	offset			= 0;
			const VkBuffer		vertexBuffer	= *m_vertexBuffer;

			vk.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);

			if (m_descriptorSet)
			{
				const VkDescriptorSet descriptorSet = *m_descriptorSet;
				vk.cmdBindDescriptorSets(commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &descriptorSet, 0u, NULL);
			}

			vk.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &vertexBuffer, &offset);
			vk.cmdDraw(commandBuffer, 6u, 1u, 0u, 0u);
		}
	}

private:
	const SubpassRenderInfo		m_renderInfo;
	Move<VkCommandBuffer>		m_commandBuffer;
	Move<VkPipeline>			m_pipeline;
	Move<VkDescriptorSetLayout>	m_descriptorSetLayout;
	Move<VkPipelineLayout>		m_pipelineLayout;

	Move<VkShaderModule>		m_vertexShaderModule;
	Move<VkShaderModule>		m_fragmentShaderModule;

	Move<VkDescriptorPool>		m_descriptorPool;
	Move<VkDescriptorSet>		m_descriptorSet;
	Move<VkBuffer>				m_vertexBuffer;
	de::MovePtr<Allocation>		m_vertexBufferMemory;
	vector<VkImage>				m_colorAttachmentImages;
	VkImage						m_depthStencilAttachmentImage;
};

void pushImageInitializationCommands (const DeviceInterface&								vk,
									  VkCommandBuffer										commandBuffer,
									  const vector<Attachment>&								attachmentInfo,
									  const vector<de::SharedPtr<AttachmentResources> >&	attachmentResources,
									  deUint32												queueIndex,
									  const vector<Maybe<VkClearValue> >&					clearValues)
{
	{
		vector<VkImageMemoryBarrier>	initializeLayouts;

		for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
		{
			if (!clearValues[attachmentNdx])
				continue;

			const VkImageMemoryBarrier barrier =
			{
				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,							// sType;
				DE_NULL,														// pNext;

				(VkAccessFlags)0,												// srcAccessMask
				getAllMemoryReadFlags() | VK_ACCESS_TRANSFER_WRITE_BIT,			// dstAccessMask

				VK_IMAGE_LAYOUT_UNDEFINED,										// oldLayout
				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,							// newLayout;

				queueIndex,														// srcQueueFamilyIndex;
				queueIndex,														// destQueueFamilyIndex;

				attachmentResources[attachmentNdx]->getImage(),					// image;
				{																// subresourceRange;
					getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()),		// aspect;
					0,																	// baseMipLevel;
					1,																	// mipLevels;
					0,																	// baseArraySlice;
					1																	// arraySize;
				}
			};

			initializeLayouts.push_back(barrier);
		}

		if (!initializeLayouts.empty())
			vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
								  VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
								  0, (const VkMemoryBarrier*)DE_NULL,
								  0, (const VkBufferMemoryBarrier*)DE_NULL,
								  (deUint32)initializeLayouts.size(), &initializeLayouts[0]);
	}

	for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
	{
		if (!clearValues[attachmentNdx])
			continue;

		const tcu::TextureFormat format = mapVkFormat(attachmentInfo[attachmentNdx].getFormat());

		if (hasStencilComponent(format.order) || hasDepthComponent(format.order))
		{
			const float						clearNan		= tcu::Float32::nan().asFloat();
			const float						clearDepth		= hasDepthComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.depth : clearNan;
			const deUint32					clearStencil	= hasStencilComponent(format.order) ? clearValues[attachmentNdx]->depthStencil.stencil : 0xDEu;
			const VkClearDepthStencilValue	depthStencil	=
			{
				clearDepth,
				clearStencil
			};
			const VkImageSubresourceRange range =
			{
				(VkImageAspectFlags)((hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0)
									 | (hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0)),
				0,
				1,
				0,
				1
			};

			vk.cmdClearDepthStencilImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthStencil, 1, &range);
		}
		else
		{
			const VkImageSubresourceRange	range		=
			{
				VK_IMAGE_ASPECT_COLOR_BIT,	// aspectMask;
				0,							// baseMipLevel;
				1,							// mipLevels;
				0,							// baseArrayLayer;
				1							// layerCount;
			};
			const VkClearColorValue			clearColor	= clearValues[attachmentNdx]->color;

			vk.cmdClearColorImage(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
		}
	}

	{
		vector<VkImageMemoryBarrier>	renderPassLayouts;

		for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
		{
			const VkImageLayout			oldLayout	= clearValues[attachmentNdx] ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
			const VkImageMemoryBarrier	barrier		=
			{
				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,					// sType;
				DE_NULL,												// pNext;

				(oldLayout != VK_IMAGE_LAYOUT_UNDEFINED ? getAllMemoryWriteFlags() : (VkAccessFlags)0),					// srcAccessMask
				getAllMemoryReadFlags() | getMemoryFlagsForLayout(attachmentInfo[attachmentNdx].getInitialLayout()),	// dstAccessMask

				oldLayout,												// oldLayout
				attachmentInfo[attachmentNdx].getInitialLayout(),		// newLayout;

				queueIndex,												// srcQueueFamilyIndex;
				queueIndex,												// destQueueFamilyIndex;

				attachmentResources[attachmentNdx]->getImage(),			// image;
				{														// subresourceRange;
					getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()),		// aspect;
					0,																	// baseMipLevel;
					1,																	// mipLevels;
					0,																	// baseArraySlice;
					1																	// arraySize;
				}
			};

			renderPassLayouts.push_back(barrier);
		}

		if (!renderPassLayouts.empty())
			vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
								  VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0,
								  0, (const VkMemoryBarrier*)DE_NULL,
								  0, (const VkBufferMemoryBarrier*)DE_NULL,
								  (deUint32)renderPassLayouts.size(), &renderPassLayouts[0]);
	}
}

void pushRenderPassCommands (const DeviceInterface&							vk,
							 VkCommandBuffer								commandBuffer,
							 VkRenderPass									renderPass,
							 VkFramebuffer									framebuffer,
							 const vector<de::SharedPtr<SubpassRenderer> >&	subpassRenderers,
							 const UVec2&									renderPos,
							 const UVec2&									renderSize,
							 const vector<Maybe<VkClearValue> >&			renderPassClearValues,
							 TestConfig::RenderTypes						render)
{
	const float				clearNan				= tcu::Float32::nan().asFloat();
	vector<VkClearValue>	attachmentClearValues;

	for (size_t attachmentNdx = 0; attachmentNdx < renderPassClearValues.size(); attachmentNdx++)
	{
		if (renderPassClearValues[attachmentNdx])
			attachmentClearValues.push_back(*renderPassClearValues[attachmentNdx]);
		else
			attachmentClearValues.push_back(makeClearValueColorF32(clearNan, clearNan, clearNan, clearNan));
	}

	{
		const VkRect2D renderArea =
		{
			{ (deInt32)renderPos.x(),	(deInt32)renderPos.y()	},
			{ renderSize.x(),			renderSize.y()			}
		};

		for (size_t subpassNdx = 0; subpassNdx < subpassRenderers.size(); subpassNdx++)
		{
			const VkSubpassContents	contents = subpassRenderers[subpassNdx]->isSecondary() ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : VK_SUBPASS_CONTENTS_INLINE;

			if (subpassNdx == 0)
				cmdBeginRenderPass(vk, commandBuffer, renderPass, framebuffer, renderArea, (deUint32)attachmentClearValues.size(), attachmentClearValues.empty() ? DE_NULL : &attachmentClearValues[0], contents);
			else
				vk.cmdNextSubpass(commandBuffer, contents);

			if (render)
			{
				if (contents == VK_SUBPASS_CONTENTS_INLINE)
				{
					subpassRenderers[subpassNdx]->pushRenderCommands(vk, commandBuffer);
				}
				else if (contents == VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS)
				{
					const VkCommandBuffer cmd = subpassRenderers[subpassNdx]->getCommandBuffer();
					vk.cmdExecuteCommands(commandBuffer, 1, &cmd);
				}
				else
					DE_FATAL("Invalid contents");
			}
		}

		vk.cmdEndRenderPass(commandBuffer);
	}
}

void pushReadImagesToBuffers (const DeviceInterface&								vk,
							  VkCommandBuffer										commandBuffer,
							  deUint32												queueIndex,

							  const vector<de::SharedPtr<AttachmentResources> >&	attachmentResources,
							  const vector<Attachment>&								attachmentInfo,
							  const vector<bool>&									isLazy,

							  const UVec2&											targetSize)
{
	{
		vector<VkImageMemoryBarrier>	imageBarriers;

		for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
		{
			if (isLazy[attachmentNdx])
				continue;

			const VkImageLayout			oldLayout	= attachmentInfo[attachmentNdx].getFinalLayout();
			const VkImageMemoryBarrier	barrier		=
			{
				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,							// sType
				DE_NULL,														// pNext

				getAllMemoryWriteFlags() | getMemoryFlagsForLayout(oldLayout),	// srcAccessMask
				getAllMemoryReadFlags(),										// dstAccessMask

				oldLayout,														// oldLayout
				VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,							// newLayout

				queueIndex,														// srcQueueFamilyIndex
				queueIndex,														// destQueueFamilyIndex

				attachmentResources[attachmentNdx]->getImage(),					// image
				{																// subresourceRange
					getImageAspectFlags(attachmentInfo[attachmentNdx].getFormat()),		// aspect;
					0,																	// baseMipLevel
					1,																	// mipLevels
					0,																	// baseArraySlice
					1																	// arraySize
				}
			};

			imageBarriers.push_back(barrier);
		}

		if (!imageBarriers.empty())
			vk.cmdPipelineBarrier(commandBuffer,
								  getAllPipelineStageFlags(),
								  getAllPipelineStageFlags(),
								  (VkDependencyFlags)0,
								  0, (const VkMemoryBarrier*)DE_NULL,
								  0, (const VkBufferMemoryBarrier*)DE_NULL,
								  (deUint32)imageBarriers.size(), &imageBarriers[0]);
	}

	for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
	{
		if (isLazy[attachmentNdx])
			continue;

		const tcu::TextureFormat::ChannelOrder	order	= mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
		const VkBufferImageCopy					rect	=
		{
			0, // bufferOffset
			0, // bufferRowLength
			0, // bufferImageHeight
			{							// imageSubresource
				(vk::VkImageAspectFlags)getPrimaryImageAspect(mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order),	// aspect
				0,						// mipLevel
				0,						// arraySlice
				1						// arraySize
			},
			{ 0, 0, 0 },				// imageOffset
			{ targetSize.x(), targetSize.y(), 1u }		// imageExtent
		};

		vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getBuffer(), 1, &rect);

		if (tcu::TextureFormat::DS == order)
		{
			const VkBufferImageCopy stencilRect =
			{
				0,										// bufferOffset
				0,										// bufferRowLength
				0,										// bufferImageHeight
				{									// imageSubresource
					VK_IMAGE_ASPECT_STENCIL_BIT,	// aspect
					0,								// mipLevel
					0,								// arraySlice
					1								// arraySize
				},
				{ 0, 0, 0 },							// imageOffset
				{ targetSize.x(), targetSize.y(), 1u }	// imageExtent
			};

			vk.cmdCopyImageToBuffer(commandBuffer, attachmentResources[attachmentNdx]->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, attachmentResources[attachmentNdx]->getSecondaryBuffer(), 1, &stencilRect);
		}
	}

	{
		vector<VkBufferMemoryBarrier>	bufferBarriers;

		for (size_t attachmentNdx = 0; attachmentNdx < attachmentInfo.size(); attachmentNdx++)
		{
			if (isLazy[attachmentNdx])
				continue;

			const tcu::TextureFormat::ChannelOrder	order			= mapVkFormat(attachmentInfo[attachmentNdx].getFormat()).order;
			const VkBufferMemoryBarrier				bufferBarrier	=
			{
				VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
				DE_NULL,

				getAllMemoryWriteFlags(),
				getAllMemoryReadFlags(),

				queueIndex,
				queueIndex,

				attachmentResources[attachmentNdx]->getBuffer(),
				0,
				attachmentResources[attachmentNdx]->getBufferSize()
			};

			bufferBarriers.push_back(bufferBarrier);

			if (tcu::TextureFormat::DS == order)
			{
				const VkBufferMemoryBarrier secondaryBufferBarrier =
				{
					VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
					DE_NULL,

					getAllMemoryWriteFlags(),
					getAllMemoryReadFlags(),

					queueIndex,
					queueIndex,

					attachmentResources[attachmentNdx]->getSecondaryBuffer(),
					0,
					attachmentResources[attachmentNdx]->getSecondaryBufferSize()
				};

				bufferBarriers.push_back(secondaryBufferBarrier);
			}
		}

		if (!bufferBarriers.empty())
			vk.cmdPipelineBarrier(commandBuffer,
								  getAllPipelineStageFlags(),
								  getAllPipelineStageFlags(),
								  (VkDependencyFlags)0,
								  0, (const VkMemoryBarrier*)DE_NULL,
								  (deUint32)bufferBarriers.size(), &bufferBarriers[0],
								  0, (const VkImageMemoryBarrier*)DE_NULL);
	}
}

class PixelValue
{
public:
				PixelValue		(const Maybe<bool>&	x = nothing<bool>(),
								 const Maybe<bool>&	y = nothing<bool>(),
								 const Maybe<bool>&	z = nothing<bool>(),
								 const Maybe<bool>&	w = nothing<bool>());

	void		setUndefined	(size_t ndx);
	void		setValue		(size_t ndx, bool value);
	Maybe<bool>	getValue		(size_t ndx) const;

private:
	deUint16	m_status;
};

PixelValue::PixelValue (const Maybe<bool>&	x,
						const Maybe<bool>&	y,
						const Maybe<bool>&	z,
						const Maybe<bool>&	w)
	: m_status (0)
{
	const Maybe<bool> values[] =
	{
		x, y, z, w
	};

	for (size_t ndx = 0; ndx < DE_LENGTH_OF_ARRAY(values); ndx++)
	{
		if (values[ndx])
			setValue(ndx, *values[ndx]);
		else
			setUndefined(ndx);
	}

	DE_ASSERT(m_status <= 0xFFu);
}

void PixelValue::setUndefined (size_t ndx)
{
	DE_ASSERT(ndx < 4);
	DE_ASSERT(m_status <= 0xFFu);

	m_status &= (deUint16)~(0x1u << (deUint16)(ndx * 2));
	DE_ASSERT(m_status <= 0xFFu);
}

void PixelValue::setValue (size_t ndx, bool value)
{
	DE_ASSERT(ndx < 4);
	DE_ASSERT(m_status <= 0xFFu);

	m_status |= (deUint16)(0x1u << (ndx * 2));

	if (value)
		m_status |= (deUint16)(0x1u << (ndx * 2 + 1));
	else
		m_status &= (deUint16)~(0x1u << (deUint16)(ndx * 2 + 1));

	DE_ASSERT(m_status <= 0xFFu);
}

Maybe<bool> PixelValue::getValue (size_t ndx) const
{
	DE_ASSERT(ndx < 4);
	DE_ASSERT(m_status <= 0xFFu);

	if ((m_status & (0x1u << (deUint16)(ndx * 2))) != 0)
	{
		return just((m_status & (0x1u << (deUint32)(ndx * 2 + 1))) != 0);
	}
	else
		return nothing<bool>();
}

void clearReferenceValues (vector<PixelValue>&	values,
						   const UVec2&			targetSize,
						   const UVec2&			offset,
						   const UVec2&			size,
						   const BVec4&			mask,
						   const PixelValue&	value)
{
	DE_ASSERT(targetSize.x() * targetSize.y() == (deUint32)values.size());
	DE_ASSERT(offset.x() + size.x() <= targetSize.x());
	DE_ASSERT(offset.y() + size.y() <= targetSize.y());

	for (deUint32 y = offset.y(); y < offset.y() + size.y(); y++)
	for (deUint32 x = offset.x(); x < offset.x() + size.x(); x++)
	{
		for (int compNdx = 0; compNdx < 4; compNdx++)
		{
			if (mask[compNdx])
			{
				if (value.getValue(compNdx))
					values[x + y * targetSize.x()].setValue(compNdx, *value.getValue(compNdx));
				else
					values[x + y * targetSize.x()].setUndefined(compNdx);
			}
		}
	}
}

void markUndefined (vector<PixelValue>&	values,
					const BVec4&		mask,
					const UVec2&		targetSize,
					const UVec2&		offset,
					const UVec2&		size)
{
	DE_ASSERT(targetSize.x() * targetSize.y() == (deUint32)values.size());

	for (deUint32 y = offset.y(); y < offset.y() + size.y(); y++)
	for (deUint32 x = offset.x(); x < offset.x() + size.x(); x++)
	{
		for (int compNdx = 0; compNdx < 4; compNdx++)
		{
			if (mask[compNdx])
				values[x + y * targetSize.x()].setUndefined(compNdx);
		}
	}
}

PixelValue clearValueToPixelValue (const VkClearValue&			value,
								   const tcu::TextureFormat&	format)
{
	const bool	isDepthAttachment			= hasDepthComponent(format.order);
	const bool	isStencilAttachment			= hasStencilComponent(format.order);
	const bool	isDepthOrStencilAttachment	= isDepthAttachment || isStencilAttachment;
	PixelValue	pixelValue;

	if (isDepthOrStencilAttachment)
	{
		if (isDepthAttachment)
		{
			if (value.depthStencil.depth == 1.0f)
				pixelValue.setValue(0, true);
			else if (value.depthStencil.depth == 0.0f)
				pixelValue.setValue(0, false);
			else
				DE_FATAL("Unknown depth value");
		}

		if (isStencilAttachment)
		{
			if (value.depthStencil.stencil == 0xFFu)
				pixelValue.setValue(1, true);
			else if (value.depthStencil.stencil == 0x0u)
				pixelValue.setValue(1, false);
			else
				DE_FATAL("Unknown stencil value");
		}
	}
	else
	{
		const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(format.type);
		const tcu::BVec4				channelMask		= tcu::getTextureFormatChannelMask(format);

		switch (channelClass)
		{
			case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
				for (int i = 0; i < 4; i++)
				{
					if (channelMask[i])
					{
						if (value.color.int32[i] == 1)
							pixelValue.setValue(i, true);
						else if (value.color.int32[i] == 0)
							pixelValue.setValue(i, false);
						else
							DE_FATAL("Unknown clear color value");
					}
				}
				break;

			case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
				for (int i = 0; i < 4; i++)
				{
					if (channelMask[i])
					{
						if (value.color.uint32[i] == 1u)
							pixelValue.setValue(i, true);
						else if (value.color.uint32[i] == 0u)
							pixelValue.setValue(i, false);
						else
							DE_FATAL("Unknown clear color value");
					}
				}
				break;

			case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
			case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
			case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
				for (int i = 0; i < 4; i++)
				{
					if (channelMask[i])
					{
						if (value.color.float32[i] == 1.0f)
							pixelValue.setValue(i, true);
						else if (value.color.float32[i] == 0.0f)
							pixelValue.setValue(i, false);
						else
							DE_FATAL("Unknown clear color value");
					}
				}
				break;

			default:
				DE_FATAL("Unknown channel class");
		}
	}

	return pixelValue;
}

void renderReferenceValues (vector<vector<PixelValue> >&		referenceAttachments,
							const RenderPass&					renderPassInfo,
							const UVec2&						targetSize,
							const vector<Maybe<VkClearValue> >&	imageClearValues,
							const vector<Maybe<VkClearValue> >&	renderPassClearValues,
							const vector<SubpassRenderInfo>&	subpassRenderInfo,
							const UVec2&						renderPos,
							const UVec2&						renderSize)
{
	const vector<Subpass>&	subpasses		= renderPassInfo.getSubpasses();
	vector<bool>			attachmentUsed	(renderPassInfo.getAttachments().size(), false);

	referenceAttachments.resize(renderPassInfo.getAttachments().size());

	for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
	{
		const Attachment			attachment	= renderPassInfo.getAttachments()[attachmentNdx];
		const tcu::TextureFormat	format		= mapVkFormat(attachment.getFormat());
		vector<PixelValue>&			reference	= referenceAttachments[attachmentNdx];

		reference.resize(targetSize.x() * targetSize.y());

		if (imageClearValues[attachmentNdx])
			clearReferenceValues(reference, targetSize, UVec2(0, 0), targetSize, BVec4(true), clearValueToPixelValue(*imageClearValues[attachmentNdx], format));
	}

	for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
	{
		const Subpass&						subpass				= subpasses[subpassNdx];
		const SubpassRenderInfo&			renderInfo			= subpassRenderInfo[subpassNdx];
		const vector<AttachmentReference>&	colorAttachments	= subpass.getColorAttachments();

		// Apply load op if attachment was used for the first time
		for (size_t attachmentNdx = 0; attachmentNdx < colorAttachments.size(); attachmentNdx++)
		{
			const deUint32 attachmentIndex = colorAttachments[attachmentNdx].getAttachment();

			if (!attachmentUsed[attachmentIndex])
			{
				const Attachment&			attachment	= renderPassInfo.getAttachments()[attachmentIndex];
				vector<PixelValue>&			reference	= referenceAttachments[attachmentIndex];
				const tcu::TextureFormat	format		= mapVkFormat(attachment.getFormat());

				DE_ASSERT(!tcu::hasDepthComponent(format.order));
				DE_ASSERT(!tcu::hasStencilComponent(format.order));

				if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
					clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(true), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format));
				else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
					markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize);

				attachmentUsed[attachmentIndex] = true;
			}
		}

		// Apply load op to depth/stencil attachment if it was used for the first time
		if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
		{
			const deUint32 attachmentIndex = subpass.getDepthStencilAttachment().getAttachment();

			// Apply load op if attachment was used for the first time
			if (!attachmentUsed[attachmentIndex])
			{
				const Attachment&			attachment	= renderPassInfo.getAttachments()[attachmentIndex];
				vector<PixelValue>&			reference	= referenceAttachments[attachmentIndex];
				const tcu::TextureFormat	format		= mapVkFormat(attachment.getFormat());

				if (tcu::hasDepthComponent(format.order))
				{
					if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
						clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(true, false, false, false), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format));
					else if (attachment.getLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
						markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize);
				}

				if (tcu::hasStencilComponent(format.order))
				{
					if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
						clearReferenceValues(reference, targetSize, renderPos, renderSize, BVec4(false, true, false, false), clearValueToPixelValue(*renderPassClearValues[attachmentIndex], format));
					else if (attachment.getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
						markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize);
				}

				attachmentUsed[attachmentIndex] = true;
			}
		}

		for (size_t colorClearNdx = 0; colorClearNdx < renderInfo.getColorClears().size(); colorClearNdx++)
		{
			const ColorClear&			colorClear		= renderInfo.getColorClears()[colorClearNdx];
			const UVec2					offset			= colorClear.getOffset();
			const UVec2					size			= colorClear.getSize();
			const deUint32				attachmentIndex	= subpass.getColorAttachments()[colorClearNdx].getAttachment();
			const Attachment&			attachment		= renderPassInfo.getAttachments()[attachmentIndex];
			const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
			vector<PixelValue>&			reference		= referenceAttachments[attachmentIndex];
			VkClearValue				value;

			value.color = colorClear.getColor();

			clearReferenceValues(reference, targetSize, offset, size, BVec4(true), clearValueToPixelValue(value, format));
		}

		if (renderInfo.getDepthStencilClear())
		{
			const DepthStencilClear&	dsClear			= *renderInfo.getDepthStencilClear();
			const UVec2					offset			= dsClear.getOffset();
			const UVec2					size			= dsClear.getSize();
			const deUint32				attachmentIndex	= subpass.getDepthStencilAttachment().getAttachment();
			const Attachment&			attachment		= renderPassInfo.getAttachments()[attachmentIndex];
			const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
			const bool					hasStencil		= tcu::hasStencilComponent(format.order);
			const bool					hasDepth		= tcu::hasDepthComponent(format.order);
			vector<PixelValue>&			reference		= referenceAttachments[attachmentIndex];
			VkClearValue				value;

			value.depthStencil.depth = dsClear.getDepth();
			value.depthStencil.stencil = dsClear.getStencil();

			clearReferenceValues(reference, targetSize, offset, size, BVec4(hasDepth, hasStencil, false, false), clearValueToPixelValue(value, format));
		}

		if (renderInfo.getRenderQuad())
		{
			const RenderQuad&	renderQuad	= *renderInfo.getRenderQuad();
			const Vec2			posA		= renderQuad.getCornerA();
			const Vec2			posB		= renderQuad.getCornerB();
			const Vec2			origin		= Vec2((float)renderInfo.getViewportOffset().x(), (float)renderInfo.getViewportOffset().y()) + Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
			const Vec2			p			= Vec2((float)renderInfo.getViewportSize().x(), (float)renderInfo.getViewportSize().y()) / Vec2(2.0f);
			const IVec2			posAI		(deRoundFloatToInt32(origin.x() + (p.x() * posA.x())),
											 deRoundFloatToInt32(origin.y() + (p.y() * posA.y())));
			const IVec2			posBI		(deRoundFloatToInt32(origin.x() + (p.x() * posB.x())),
											 deRoundFloatToInt32(origin.y() + (p.y() * posB.y())));

			DE_ASSERT(posAI.x() < posBI.x());
			DE_ASSERT(posAI.y() < posBI.y());

			if (subpass.getInputAttachments().empty())
			{
				for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
				{
					const deUint32				attachmentIndex	= subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
					const Attachment&			attachment		= renderPassInfo.getAttachments()[attachmentIndex];
					const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
					const tcu::BVec4			channelMask		= tcu::getTextureFormatChannelMask(format);
					vector<PixelValue>&			reference		= referenceAttachments[attachmentIndex];

					for (int y = posAI.y(); y < (int)posBI.y(); y++)
					for (int x = posAI.x(); x < (int)posBI.x(); x++)
					{
						for (int compNdx = 0; compNdx < 4; compNdx++)
						{
							const size_t	index	= subpassNdx + attachmentIndex + compNdx;
							const BoolOp	op		= boolOpFromIndex(index);
							const bool		boolX	= x % 2 == (int)(index % 2);
							const bool		boolY	= y % 2 == (int)((index / 2) % 2);

							if (channelMask[compNdx])
								reference[x + y * targetSize.x()].setValue(compNdx, performBoolOp(op, boolX, boolY));
						}
					}
				}

				if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
				{
					const deUint32				attachmentIndex	= subpass.getDepthStencilAttachment().getAttachment();
					const Attachment&			attachment		= renderPassInfo.getAttachments()[attachmentIndex];
					const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
					vector<PixelValue>&			reference		= referenceAttachments[attachmentIndex];

					for (int y = posAI.y(); y < (int)posBI.y(); y++)
					for (int x = posAI.x(); x < (int)posBI.x(); x++)
					{
						if (tcu::hasDepthComponent(format.order))
						{
							const size_t	index	= subpassNdx + 1;
							const BoolOp	op		= boolOpFromIndex(index);
							const bool		boolX	= x % 2 == (int)(index % 2);
							const bool		boolY	= y % 2 == (int)((index / 2) % 2);

							reference[x + y * targetSize.x()].setValue(0, performBoolOp(op, boolX, boolY));
						}

						if (tcu::hasStencilComponent(format.order))
						{
							const size_t	index	= subpassNdx;
							reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0);
						}
					}
				}
			}
			else
			{
				size_t					outputComponentCount	= 0;
				vector<Maybe<bool> >	inputs;

				DE_ASSERT(posAI.x() < posBI.x());
				DE_ASSERT(posAI.y() < posBI.y());

				for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
				{
					const deUint32				attachmentIndex	= subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
					const Attachment&			attachment		= renderPassInfo.getAttachments()[attachmentIndex];
					const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
					const int					componentCount	= tcu::getNumUsedChannels(format.order);

					outputComponentCount += (size_t)componentCount;
				}

				if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
					outputComponentCount++;

				for (int y = posAI.y(); y < (int)posBI.y(); y++)
				for (int x = posAI.x(); x < (int)posBI.x(); x++)
				{
					for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpass.getInputAttachments().size(); inputAttachmentNdx++)
					{
						const deUint32				attachmentIndex	= subpass.getInputAttachments()[inputAttachmentNdx].getAttachment();
						const Attachment&			attachment		= renderPassInfo.getAttachments()[attachmentIndex];
						const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
						const int					componentCount	= tcu::getNumUsedChannels(format.order);

						for (int compNdx = 0; compNdx < componentCount; compNdx++)
							inputs.push_back(referenceAttachments[attachmentIndex][x + y * targetSize.x()].getValue(compNdx));
					}

					const size_t inputsPerOutput = inputs.size() >= outputComponentCount
													? ((inputs.size() / outputComponentCount)
														+ ((inputs.size() % outputComponentCount) != 0 ? 1 : 0))
													: 1;

					size_t outputValueNdx = 0;

					for (size_t attachmentRefNdx = 0; attachmentRefNdx < subpass.getColorAttachments().size(); attachmentRefNdx++)
					{
						const deUint32				attachmentIndex	= subpass.getColorAttachments()[attachmentRefNdx].getAttachment();
						const Attachment&			attachment		= renderPassInfo.getAttachments()[attachmentIndex];
						const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
						vector<PixelValue>&			reference		= referenceAttachments[attachmentIndex];
						const int					componentCount	= tcu::getNumUsedChannels(format.order);

						for (int compNdx = 0; compNdx < componentCount; compNdx++)
						{
							const size_t	index	= subpassNdx + attachmentIndex + outputValueNdx;
							const BoolOp	op		= boolOpFromIndex(index);
							const bool		boolX	= x % 2 == (int)(index % 2);
							const bool		boolY	= y % 2 == (int)((index / 2) % 2);
							Maybe<bool>		output	= tcu::just(performBoolOp(op, boolX, boolY));

							for (size_t i = 0; i < inputsPerOutput; i++)
							{
								if (!output)
									break;
								else if (!inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) % inputs.size()])
									output = tcu::nothing<bool>();
								else
									output = (*output) == (*inputs[((outputValueNdx + compNdx) * inputsPerOutput + i) % inputs.size()]);
							}

							if (output)
								reference[x + y * targetSize.x()].setValue(compNdx, *output);
							else
								reference[x + y * targetSize.x()].setUndefined(compNdx);
						}

						outputValueNdx += componentCount;
					}

					if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
					{
						const deUint32		attachmentIndex	= subpass.getDepthStencilAttachment().getAttachment();
						vector<PixelValue>&	reference		= referenceAttachments[attachmentIndex];
						const size_t		index			= subpassNdx + attachmentIndex;
						const BoolOp		op				= boolOpFromIndex(index);
						const bool			boolX			= x % 2 == (int)(index % 2);
						const bool			boolY			= y % 2 == (int)((index / 2) % 2);
						Maybe<bool>			output			= tcu::just(performBoolOp(op, boolX, boolY));

						for (size_t i = 0; i < inputsPerOutput; i++)
						{
							if (!output)
								break;
							else if (inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()])
								output = (*output) == (*inputs[(outputValueNdx * inputsPerOutput + i) % inputs.size()]);
							else
								output = tcu::nothing<bool>();
						}

						if (output)
							reference[x + y * targetSize.x()].setValue(0, *output);
						else
							reference[x + y * targetSize.x()].setUndefined(0);
					}

					inputs.clear();
				}

				if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
				{
					const deUint32				attachmentIndex	= subpass.getDepthStencilAttachment().getAttachment();
					const Attachment&			attachment		= renderPassInfo.getAttachments()[attachmentIndex];
					const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
					vector<PixelValue>&			reference		= referenceAttachments[attachmentIndex];

					if (tcu::hasStencilComponent(format.order))
					{
						for (int y = posAI.y(); y < (int)posBI.y(); y++)
						for (int x = posAI.x(); x < (int)posBI.x(); x++)
						{
							const size_t	index	= subpassNdx;
							reference[x + y * targetSize.x()].setValue(1, (index % 2) == 0);
						}
					}
				}
			}
		}
	}

	// Mark all attachments that were used but not stored as undefined
	for (size_t attachmentIndex = 0; attachmentIndex < renderPassInfo.getAttachments().size(); attachmentIndex++)
	{
		const Attachment			attachment					= renderPassInfo.getAttachments()[attachmentIndex];
		const tcu::TextureFormat	format						= mapVkFormat(attachment.getFormat());
		vector<PixelValue>&			reference					= referenceAttachments[attachmentIndex];
		const bool					isStencilAttachment			= hasStencilComponent(format.order);
		const bool					isDepthOrStencilAttachment	= hasDepthComponent(format.order) || isStencilAttachment;

		if (attachmentUsed[attachmentIndex] && renderPassInfo.getAttachments()[attachmentIndex].getStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
		{
			if (isDepthOrStencilAttachment)
				markUndefined(reference, BVec4(true, false, false, false), targetSize, renderPos, renderSize);
			else
				markUndefined(reference, BVec4(true), targetSize, renderPos, renderSize);
		}

		if (attachmentUsed[attachmentIndex] && isStencilAttachment && renderPassInfo.getAttachments()[attachmentIndex].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_DONT_CARE)
			markUndefined(reference, BVec4(false, true, false, false), targetSize, renderPos, renderSize);
	}
}

void renderReferenceImagesFromValues (vector<tcu::TextureLevel>&			referenceImages,
									  const vector<vector<PixelValue> >&	referenceValues,
									  const UVec2&							targetSize,
									  const RenderPass&						renderPassInfo)
{
	referenceImages.resize(referenceValues.size());

	for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
	{
		const Attachment			attachment			= renderPassInfo.getAttachments()[attachmentNdx];
		const tcu::TextureFormat	format				= mapVkFormat(attachment.getFormat());
		const vector<PixelValue>&	reference			= referenceValues[attachmentNdx];
		const bool					hasDepth			= tcu::hasDepthComponent(format.order);
		const bool					hasStencil			= tcu::hasStencilComponent(format.order);
		const bool					hasDepthOrStencil	= hasDepth || hasStencil;
		tcu::TextureLevel&			referenceImage		= referenceImages[attachmentNdx];

		referenceImage.setStorage(format, targetSize.x(), targetSize.y());

		if (hasDepthOrStencil)
		{
			if (hasDepth)
			{
				const PixelBufferAccess depthAccess (tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_DEPTH));

				for (deUint32 y = 0; y < targetSize.y(); y++)
				for (deUint32 x = 0; x < targetSize.x(); x++)
				{
					if (reference[x + y * targetSize.x()].getValue(0))
					{
						if (*reference[x + y * targetSize.x()].getValue(0))
							depthAccess.setPixDepth(1.0f, x, y);
						else
							depthAccess.setPixDepth(0.0f, x, y);
					}
					else // Fill with 3x3 grid
						depthAccess.setPixDepth(((x / 3) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f, x, y);
				}
			}

			if (hasStencil)
			{
				const PixelBufferAccess stencilAccess (tcu::getEffectiveDepthStencilAccess(referenceImage.getAccess(), tcu::Sampler::MODE_STENCIL));

				for (deUint32 y = 0; y < targetSize.y(); y++)
				for (deUint32 x = 0; x < targetSize.x(); x++)
				{
					if (reference[x + y * targetSize.x()].getValue(1))
					{
						if (*reference[x + y * targetSize.x()].getValue(1))
							stencilAccess.setPixStencil(0xFFu, x, y);
						else
							stencilAccess.setPixStencil(0x0u, x, y);
					}
					else // Fill with 3x3 grid
						stencilAccess.setPixStencil(((x / 3) % 2) == ((y / 3) % 2) ? 85 : 170, x, y);
				}
			}
		}
		else
		{
			for (deUint32 y = 0; y < targetSize.y(); y++)
			for (deUint32 x = 0; x < targetSize.x(); x++)
			{
				tcu::Vec4 color;

				for (int compNdx = 0; compNdx < 4; compNdx++)
				{
					if (reference[x + y * targetSize.x()].getValue(compNdx))
					{
						if (*reference[x + y * targetSize.x()].getValue(compNdx))
							color[compNdx] = 1.0f;
						else
							color[compNdx] = 0.0f;
					}
					else // Fill with 3x3 grid
						color[compNdx] = ((compNdx + (x / 3)) % 2) == ((y / 3) % 2) ? 0.33f : 0.66f;
				}

				referenceImage.getAccess().setPixel(color, x, y);
			}
		}
	}
}

bool verifyColorAttachment (const vector<PixelValue>&		reference,
							const ConstPixelBufferAccess&	result,
							const PixelBufferAccess&		errorImage)
{
	const Vec4	red		(1.0f, 0.0f, 0.0f, 1.0f);
	const Vec4	green	(0.0f, 1.0f, 0.0f, 1.0f);
	bool		ok		= true;

	DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
	DE_ASSERT(result.getWidth() == errorImage.getWidth());
	DE_ASSERT(result.getHeight() == errorImage.getHeight());

	for (int y = 0; y < result.getHeight(); y++)
	for (int x = 0; x < result.getWidth(); x++)
	{
		const Vec4			resultColor		= result.getPixel(x, y);
		const PixelValue&	referenceValue	= reference[x + y * result.getWidth()];
		bool				pixelOk			= true;

		for (int compNdx = 0; compNdx < 4; compNdx++)
		{
			const Maybe<bool> maybeValue = referenceValue.getValue(compNdx);

			if (maybeValue)
			{
				const bool value = *maybeValue;

				if ((value && (resultColor[compNdx] != 1.0f))
					|| (!value && resultColor[compNdx] != 0.0f))
					pixelOk = false;
			}
		}

		if (!pixelOk)
		{
			errorImage.setPixel(red, x, y);
			ok = false;
		}
		else
			errorImage.setPixel(green, x, y);
	}

	return ok;
}

bool verifyDepthAttachment (const vector<PixelValue>&		reference,
							const ConstPixelBufferAccess&	result,
							const PixelBufferAccess&		errorImage)
{
	const Vec4	red		(1.0f, 0.0f, 0.0f, 1.0f);
	const Vec4	green	(0.0f, 1.0f, 0.0f, 1.0f);
	bool		ok		= true;

	DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
	DE_ASSERT(result.getWidth() == errorImage.getWidth());
	DE_ASSERT(result.getHeight() == errorImage.getHeight());

	for (int y = 0; y < result.getHeight(); y++)
	for (int x = 0; x < result.getWidth(); x++)
	{
		bool pixelOk = true;

		const float			resultDepth		= result.getPixDepth(x, y);
		const PixelValue&	referenceValue	= reference[x + y * result.getWidth()];
		const Maybe<bool>	maybeValue		= referenceValue.getValue(0);

		if (maybeValue)
		{
			const bool value = *maybeValue;

			if ((value && (resultDepth != 1.0f))
				|| (!value && resultDepth != 0.0f))
				pixelOk = false;
		}

		if (!pixelOk)
		{
			errorImage.setPixel(red, x, y);
			ok = false;
		}
		else
			errorImage.setPixel(green, x, y);
	}

	return ok;
}

bool verifyStencilAttachment (const vector<PixelValue>&		reference,
							  const ConstPixelBufferAccess&	result,
							  const PixelBufferAccess&		errorImage)
{
	const Vec4	red		(1.0f, 0.0f, 0.0f, 1.0f);
	const Vec4	green	(0.0f, 1.0f, 0.0f, 1.0f);
	bool		ok		= true;

	DE_ASSERT(result.getWidth() * result.getHeight() == (int)reference.size());
	DE_ASSERT(result.getWidth() == errorImage.getWidth());
	DE_ASSERT(result.getHeight() == errorImage.getHeight());

	for (int y = 0; y < result.getHeight(); y++)
	for (int x = 0; x < result.getWidth(); x++)
	{
		bool pixelOk = true;

		const deUint32		resultStencil	= result.getPixStencil(x, y);
		const PixelValue&	referenceValue	= reference[x + y * result.getWidth()];
		const Maybe<bool>	maybeValue		= referenceValue.getValue(1);

		if (maybeValue)
		{
			const bool value = *maybeValue;

			if ((value && (resultStencil != 0xFFu))
				|| (!value && resultStencil != 0x0u))
				pixelOk = false;
		}

		if (!pixelOk)
		{
			errorImage.setPixel(red, x, y);
			ok = false;
		}
		else
			errorImage.setPixel(green, x, y);
	}

	return ok;
}

bool logAndVerifyImages (TestLog&											log,
						 const DeviceInterface&								vk,
						 VkDevice											device,
						 const vector<de::SharedPtr<AttachmentResources> >&	attachmentResources,
						 const vector<bool>&								attachmentIsLazy,
						 const RenderPass&									renderPassInfo,
						 const vector<Maybe<VkClearValue> >&				renderPassClearValues,
						 const vector<Maybe<VkClearValue> >&				imageClearValues,
						 const vector<SubpassRenderInfo>&					subpassRenderInfo,
						 const UVec2&										targetSize,
						 const TestConfig&									config)
{
	vector<vector<PixelValue> >	referenceValues;
	vector<tcu::TextureLevel>	referenceAttachments;
	bool						isOk					= true;

	log << TestLog::Message << "Reference images fill undefined pixels with 3x3 grid pattern." << TestLog::EndMessage;

	renderReferenceValues(referenceValues, renderPassInfo, targetSize, imageClearValues, renderPassClearValues, subpassRenderInfo, config.renderPos, config.renderSize);
	renderReferenceImagesFromValues(referenceAttachments, referenceValues, targetSize, renderPassInfo);

	for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
	{
		if (!attachmentIsLazy[attachmentNdx])
		{
			const Attachment			attachment		= renderPassInfo.getAttachments()[attachmentNdx];
			const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());

			if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
			{
				const tcu::TextureFormat	depthFormat			= getDepthCopyFormat(attachment.getFormat());
				const VkDeviceSize			depthBufferSize		= targetSize.x() * targetSize.y() * depthFormat.getPixelSize();
				void* const					depthPtr			= attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();

				const tcu::TextureFormat	stencilFormat		= getStencilCopyFormat(attachment.getFormat());
				const VkDeviceSize			stencilBufferSize	= targetSize.x() * targetSize.y() * stencilFormat.getPixelSize();
				void* const					stencilPtr			= attachmentResources[attachmentNdx]->getSecondaryResultMemory().getHostPtr();

				const VkMappedMemoryRange	ranges[]			=
				{
					{
						VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,								// sType;
						DE_NULL,															// pNext;
						attachmentResources[attachmentNdx]->getResultMemory().getMemory(),	// mem;
						attachmentResources[attachmentNdx]->getResultMemory().getOffset(),	// offset;
						depthBufferSize														// size;
					},
					{
						VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,										// sType;
						DE_NULL,																	// pNext;
						attachmentResources[attachmentNdx]->getSecondaryResultMemory().getMemory(),	// mem;
						attachmentResources[attachmentNdx]->getSecondaryResultMemory().getOffset(),	// offset;
						stencilBufferSize															// size;
					}
				};
				VK_CHECK(vk.invalidateMappedMemoryRanges(device, 2u, ranges));

				{
					const ConstPixelBufferAccess	depthAccess			(depthFormat, targetSize.x(), targetSize.y(), 1, depthPtr);
					const ConstPixelBufferAccess	stencilAccess		(stencilFormat, targetSize.x(), targetSize.y(), 1, stencilPtr);
					tcu::TextureLevel				depthErrorImage		(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());
					tcu::TextureLevel				stencilErrorImage	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());

					log << TestLog::Image("Attachment" + de::toString(attachmentNdx) + "Depth", "Attachment " + de::toString(attachmentNdx) + " Depth", depthAccess);
					log << TestLog::Image("Attachment" + de::toString(attachmentNdx) + "Stencil", "Attachment " + de::toString(attachmentNdx) + " Stencil", stencilAccess);

					log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());

					if (renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
						&& !verifyDepthAttachment(referenceValues[attachmentNdx], depthAccess, depthErrorImage.getAccess()))
					{
						log << TestLog::Image("DepthAttachmentError" + de::toString(attachmentNdx), "Depth Attachment Error " + de::toString(attachmentNdx), depthErrorImage.getAccess());
						isOk = false;
					}

					if (renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE
						&& !verifyStencilAttachment(referenceValues[attachmentNdx], stencilAccess, stencilErrorImage.getAccess()))
					{
						log << TestLog::Image("StencilAttachmentError" + de::toString(attachmentNdx), "Stencil Attachment Error " + de::toString(attachmentNdx), stencilErrorImage.getAccess());
						isOk = false;
					}
				}
			}
			else
			{
				const VkDeviceSize			bufferSize	= targetSize.x() * targetSize.y() * format.getPixelSize();
				void* const					ptr			= attachmentResources[attachmentNdx]->getResultMemory().getHostPtr();

				const VkMappedMemoryRange	range		=
				{
					VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,								// sType;
					DE_NULL,															// pNext;
					attachmentResources[attachmentNdx]->getResultMemory().getMemory(),	// mem;
					attachmentResources[attachmentNdx]->getResultMemory().getOffset(),	// offset;
					bufferSize															// size;
				};
				VK_CHECK(vk.invalidateMappedMemoryRanges(device, 1u, &range));

				if (tcu::hasDepthComponent(format.order))
				{
					const ConstPixelBufferAccess	access		(format, targetSize.x(), targetSize.y(), 1, ptr);
					tcu::TextureLevel				errorImage	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());

					log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
					log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());

					if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
						&& !verifyDepthAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess()))
					{
						log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
						isOk = false;
					}
				}
				else if (tcu::hasStencilComponent(format.order))
				{
					const ConstPixelBufferAccess	access		(format, targetSize.x(), targetSize.y(), 1, ptr);
					tcu::TextureLevel				errorImage	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());

					log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
					log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());

					if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
						&& !verifyStencilAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess()))
					{
						log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
						isOk = false;
					}
				}
				else
				{
					const ConstPixelBufferAccess	access		(format, targetSize.x(), targetSize.y(), 1, ptr);
					tcu::TextureLevel				errorImage	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), targetSize.x(), targetSize.y());

					log << TestLog::Image("Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx), access);
					log << TestLog::Image("AttachmentReference" + de::toString(attachmentNdx), "Attachment reference " + de::toString(attachmentNdx), referenceAttachments[attachmentNdx].getAccess());

					if ((renderPassInfo.getAttachments()[attachmentNdx].getStoreOp() == VK_ATTACHMENT_STORE_OP_STORE || renderPassInfo.getAttachments()[attachmentNdx].getStencilStoreOp() == VK_ATTACHMENT_STORE_OP_STORE)
						&& !verifyColorAttachment(referenceValues[attachmentNdx], access, errorImage.getAccess()))
					{
						log << TestLog::Image("AttachmentError" + de::toString(attachmentNdx), "Attachment Error " + de::toString(attachmentNdx), errorImage.getAccess());
						isOk = false;
					}
				}
			}
		}
	}

	return isOk;
}

std::string getInputAttachmentType (VkFormat vkFormat)
{
	const tcu::TextureFormat		format			= mapVkFormat(vkFormat);
	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(format.type);

	switch (channelClass)
	{
		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
			return "isubpassInput";

		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
			return "usubpassInput";

		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
			return "subpassInput";

		default:
			DE_FATAL("Unknown channel class");
			return "";
	}
}

std::string getAttachmentType (VkFormat vkFormat)
{
	const tcu::TextureFormat		format			= mapVkFormat(vkFormat);
	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(format.type);

	switch (channelClass)
	{
		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
			return "ivec4";

		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
			return "uvec4";

		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
			return "vec4";

		default:
			DE_FATAL("Unknown channel class");
			return "";
	}
}

void createTestShaders (SourceCollections& dst, TestConfig config)
{
	if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
	{
		const vector<Subpass>&	subpasses	= config.renderPass.getSubpasses();

		for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
		{
			const Subpass&		subpass					= subpasses[subpassNdx];
			deUint32			inputAttachmentBinding	= 0;
			std::ostringstream	vertexShader;
			std::ostringstream	fragmentShader;

			vertexShader << "#version 310 es\n"
						 << "layout(location = 0) in highp vec2 a_position;\n"
						 << "void main (void) {\n"
						 << "\tgl_Position = vec4(a_position, 1.0, 1.0);\n"
						 << "}\n";

			fragmentShader << "#version 310 es\n"
						   << "precision highp float;\n";

			for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
			{
				const deUint32				attachmentIndex	= subpass.getInputAttachments()[attachmentNdx].getAttachment();
				const Attachment			attachment		= config.renderPass.getAttachments()[attachmentIndex];
				const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
				const bool					isDepthFormat	= tcu::hasDepthComponent(format.order);
				const bool					isStencilFormat	= tcu::hasStencilComponent(format.order);

				if (isDepthFormat || isStencilFormat)
				{
					if (isDepthFormat)
					{
						fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp subpassInput i_depth" << attachmentNdx << ";\n";
						inputAttachmentBinding++;
					}

					if (isStencilFormat)
					{
						fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp usubpassInput i_stencil" << attachmentNdx << ";\n";
						inputAttachmentBinding++;
					}
				}
				else
				{
					const std::string attachmentType = getInputAttachmentType(attachment.getFormat());

					fragmentShader << "layout(input_attachment_index = " << attachmentNdx << ", set=0, binding=" << inputAttachmentBinding << ") uniform highp " << attachmentType << " i_color" << attachmentNdx << ";\n";
					inputAttachmentBinding++;
				}
			}

			for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
			{
				const std::string attachmentType = getAttachmentType(config.renderPass.getAttachments()[subpass.getColorAttachments()[attachmentNdx].getAttachment()].getFormat());
				fragmentShader << "layout(location = " << attachmentNdx << ") out highp " << attachmentType << " o_color" << attachmentNdx << ";\n";
			}

			fragmentShader << "void main (void) {\n";

			if (subpass.getInputAttachments().empty())
			{
				for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
				{
					const deUint32		attachmentIndex	= subpass.getColorAttachments()[attachmentNdx].getAttachment();
					const std::string	attachmentType	= getAttachmentType(config.renderPass.getAttachments()[attachmentIndex].getFormat());

					fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(vec4(";

					for (size_t compNdx = 0; compNdx < 4; compNdx++)
					{
						const size_t	index	= subpassNdx + attachmentIndex + compNdx;
						const BoolOp	op		= boolOpFromIndex(index);

						if (compNdx > 0)
							fragmentShader << ",\n\t\t";

						fragmentShader	<< "((int(gl_FragCoord.x) % 2 == " << (index % 2)
										<< ") " << boolOpToString(op) << " ("
										<< "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
										<< ") ? 1.0 : 0.0)";
					}

					fragmentShader << "));\n";
				}

				if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
				{
					const size_t	index	= subpassNdx + 1;
					const BoolOp	op		= boolOpFromIndex(index);

					fragmentShader	<< "\tgl_FragDepth = ((int(gl_FragCoord.x) % 2 == " << (index % 2)
									<< ") " << boolOpToString(op) << " ("
									<< "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
									<< ") ? 1.0 : 0.0);\n";
				}
			}
			else
			{
				size_t	inputComponentCount		= 0;
				size_t	outputComponentCount	= 0;

				for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
				{
					const deUint32				attachmentIndex	= subpass.getInputAttachments()[attachmentNdx].getAttachment();
					const Attachment			attachment		= config.renderPass.getAttachments()[attachmentIndex];
					const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
					const size_t				componentCount	= (size_t)tcu::getNumUsedChannels(format.order);

					inputComponentCount += componentCount;
				}

				for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
				{
					const deUint32				attachmentIndex	= subpass.getColorAttachments()[attachmentNdx].getAttachment();
					const Attachment			attachment		= config.renderPass.getAttachments()[attachmentIndex];
					const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
					const size_t				componentCount	= (size_t)tcu::getNumUsedChannels(format.order);

					outputComponentCount += componentCount;
				}

				if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
					outputComponentCount++;

				const size_t inputsPerOutput = inputComponentCount >= outputComponentCount
												? ((inputComponentCount / outputComponentCount)
													+ ((inputComponentCount % outputComponentCount) != 0 ? 1 : 0))
												: 1;

				fragmentShader << "\tbool inputs[" << inputComponentCount << "];\n"
								  "\tbool outputs[" << outputComponentCount << "];\n";

				size_t inputValueNdx = 0;

				for (size_t attachmentNdx = 0; attachmentNdx < subpass.getInputAttachments().size(); attachmentNdx++)
				{
					const char* const	components[]	=
					{
						"x", "y", "z", "w"
					};
					const deUint32				attachmentIndex	= subpass.getInputAttachments()[attachmentNdx].getAttachment();
					const Attachment			attachment		= config.renderPass.getAttachments()[attachmentIndex];
					const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
					const size_t				componentCount	= (size_t)tcu::getNumUsedChannels(format.order);
					const bool					isDepthFormat	= tcu::hasDepthComponent(format.order);
					const bool					isStencilFormat	= tcu::hasStencilComponent(format.order);

					if (isDepthFormat || isStencilFormat)
					{
						if (isDepthFormat)
						{
							fragmentShader << "\tinputs[" << inputValueNdx << "] = 1.0 == float(subpassLoad(i_depth" << attachmentNdx << ").x);\n";
							inputValueNdx++;
						}

						if (isStencilFormat)
						{
							fragmentShader << "\tinputs[" << inputValueNdx << "] = 255u == subpassLoad(i_stencil" << attachmentNdx << ").x;\n";
							inputValueNdx++;
						}
					}
					else
					{
						for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
						{
							fragmentShader << "\tinputs[" << inputValueNdx << "] = 1.0 == float(subpassLoad(i_color" << attachmentNdx << ")." << components[compNdx] << ");\n";
							inputValueNdx++;
						}
					}
				}

				size_t outputValueNdx = 0;

				for (size_t attachmentNdx = 0; attachmentNdx < subpass.getColorAttachments().size(); attachmentNdx++)
				{
					const deUint32				attachmentIndex	= subpass.getColorAttachments()[attachmentNdx].getAttachment();
					const Attachment			attachment		= config.renderPass.getAttachments()[attachmentIndex];
					const std::string			attachmentType	= getAttachmentType(config.renderPass.getAttachments()[attachmentIndex].getFormat());
					const tcu::TextureFormat	format			= mapVkFormat(attachment.getFormat());
					const size_t				componentCount	= (size_t)tcu::getNumUsedChannels(format.order);

					for (size_t compNdx = 0; compNdx < componentCount; compNdx++)
					{
						const size_t	index	= subpassNdx + attachmentIndex + outputValueNdx;
						const BoolOp	op		= boolOpFromIndex(index);

						fragmentShader << "\toutputs[" << outputValueNdx + compNdx << "] = "
										<< "(int(gl_FragCoord.x) % 2 == " << (index % 2)
										<< ") " << boolOpToString(op) << " ("
										<< "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
										<< ");\n";

						for (size_t i = 0; i < inputsPerOutput; i++)
							fragmentShader << "\toutputs[" << outputValueNdx + compNdx << "] = outputs[" << outputValueNdx + compNdx << "] == inputs[" <<  ((outputValueNdx + compNdx) * inputsPerOutput + i) %  inputComponentCount << "];\n";
					}

					fragmentShader << "\to_color" << attachmentNdx << " = " << attachmentType << "(";

					for (size_t compNdx = 0; compNdx < 4; compNdx++)
					{
						if (compNdx > 0)
							fragmentShader << ", ";

						if (compNdx < componentCount)
							fragmentShader << "outputs[" << outputValueNdx + compNdx << "]";
						else
							fragmentShader << "0";
					}

					outputValueNdx += componentCount;

					fragmentShader << ");\n";
				}

				if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
				{
					const deUint32	attachmentIndex	= subpass.getDepthStencilAttachment().getAttachment();
					const size_t	index			= subpassNdx + attachmentIndex;
					const BoolOp	op				= boolOpFromIndex(index);

					fragmentShader << "\toutputs[" << outputValueNdx << "] = "
									<< "(int(gl_FragCoord.x) % 2 == " << (index % 2)
									<< ") " << boolOpToString(op) << " ("
									<< "int(gl_FragCoord.y) % 2 == " << ((index / 2) % 2)
									<< ");\n";

					for (size_t i = 0; i < inputsPerOutput; i++)
						fragmentShader << "\toutputs[" << outputValueNdx << "] = outputs[" << outputValueNdx << "] == inputs[" <<  (outputValueNdx * inputsPerOutput + i) %  inputComponentCount << "];\n";

					fragmentShader << "\tgl_FragDepth = outputs[" << outputValueNdx << "] ? 1.0 : 0.0;";
				}
			}

			fragmentShader << "}\n";

			dst.glslSources.add(de::toString(subpassNdx) + "-vert") << glu::VertexSource(vertexShader.str());
			dst.glslSources.add(de::toString(subpassNdx) + "-frag") << glu::FragmentSource(fragmentShader.str());
		}
	}
}

void initializeAttachmentIsLazy (vector<bool>& attachmentIsLazy, const vector<Attachment>& attachments, TestConfig::ImageMemory imageMemory)
{
	bool lastAttachmentWasLazy	= false;

	for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
	{
		if (attachments[attachmentNdx].getLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
			&& attachments[attachmentNdx].getStoreOp() != VK_ATTACHMENT_STORE_OP_STORE
			&& attachments[attachmentNdx].getStencilLoadOp() != VK_ATTACHMENT_LOAD_OP_LOAD
			&& attachments[attachmentNdx].getStencilStoreOp() != VK_ATTACHMENT_STORE_OP_STORE)
		{
			if (imageMemory == TestConfig::IMAGEMEMORY_LAZY || (imageMemory & TestConfig::IMAGEMEMORY_LAZY && !lastAttachmentWasLazy))
			{
				attachmentIsLazy.push_back(true);

				lastAttachmentWasLazy	= true;
			}
			else if (imageMemory & TestConfig::IMAGEMEMORY_STRICT)
			{
				attachmentIsLazy.push_back(false);
				lastAttachmentWasLazy = false;
			}
			else
				DE_FATAL("Unknown imageMemory");
		}
		else
			attachmentIsLazy.push_back(false);
	}
}

enum AttachmentRefType
{
	ATTACHMENTREFTYPE_COLOR,
	ATTACHMENTREFTYPE_DEPTH_STENCIL,
	ATTACHMENTREFTYPE_INPUT,
	ATTACHMENTREFTYPE_RESOLVE,
};

VkImageUsageFlags getImageUsageFromLayout (VkImageLayout layout)
{
	switch (layout)
	{
		case VK_IMAGE_LAYOUT_GENERAL:
		case VK_IMAGE_LAYOUT_PREINITIALIZED:
			return 0;

		case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
			return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;

		case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
		case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
			return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;

		case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
			return VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;

		case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
			return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;

		case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
			return VK_IMAGE_USAGE_TRANSFER_DST_BIT;

		default:
			DE_FATAL("Unexpected image layout");
			return 0;
	}
}

void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags>& attachmentImageUsage, AttachmentRefType refType, size_t count, const AttachmentReference* references)
{
	for (size_t referenceNdx = 0; referenceNdx < count; ++referenceNdx)
	{
		const deUint32 attachment = references[referenceNdx].getAttachment();

		if (attachment != VK_ATTACHMENT_UNUSED)
		{
			VkImageUsageFlags usage;

			switch (refType)
			{
				case ATTACHMENTREFTYPE_COLOR:
				case ATTACHMENTREFTYPE_RESOLVE:
					usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
					break;

				case ATTACHMENTREFTYPE_DEPTH_STENCIL:
					usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
					break;

				case ATTACHMENTREFTYPE_INPUT:
					usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
					break;

				default:
					DE_FATAL("Unexpected attachment reference type");
					usage = 0;
					break;
			}

			attachmentImageUsage[attachment] |= usage;
		}
	}
}

void getImageUsageFromAttachmentReferences(vector<VkImageUsageFlags>& attachmentImageUsage, AttachmentRefType refType, const vector<AttachmentReference>& references)
{
	if (!references.empty())
	{
		getImageUsageFromAttachmentReferences(attachmentImageUsage, refType, references.size(), &references[0]);
	}
}

void initializeAttachmentImageUsage (Context &context, vector<VkImageUsageFlags>& attachmentImageUsage, const RenderPass& renderPassInfo, const vector<bool>& attachmentIsLazy, const vector<Maybe<VkClearValue> >& clearValues)
{
	attachmentImageUsage.resize(renderPassInfo.getAttachments().size(), VkImageUsageFlags(0));

	for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); ++subpassNdx)
	{
		const Subpass& subpass = renderPassInfo.getSubpasses()[subpassNdx];

		getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_COLOR, subpass.getColorAttachments());
		getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_DEPTH_STENCIL, 1, &subpass.getDepthStencilAttachment());
		getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_INPUT, subpass.getInputAttachments());
		getImageUsageFromAttachmentReferences(attachmentImageUsage, ATTACHMENTREFTYPE_RESOLVE, subpass.getResolveAttachments());
	}

	for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
	{
		const Attachment& attachment = renderPassInfo.getAttachments()[attachmentNdx];
		const VkFormatProperties	formatProperties	= getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), attachment.getFormat());
		const VkFormatFeatureFlags	supportedFeatures	= formatProperties.optimalTilingFeatures;

		if ((supportedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
			attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_SAMPLED_BIT;

		if ((supportedFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0)
			attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_STORAGE_BIT;

		attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getInitialLayout());
		attachmentImageUsage[attachmentNdx] |= getImageUsageFromLayout(attachment.getFinalLayout());

		if (!attachmentIsLazy[attachmentNdx])
		{
			if (clearValues[attachmentNdx])
				attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;

			attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
		}
		else
		{
			const VkImageUsageFlags allowedTransientBits = static_cast<VkImageUsageFlags>(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);

			attachmentImageUsage[attachmentNdx] &= allowedTransientBits;
			attachmentImageUsage[attachmentNdx] |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
		}
	}
}

void initializeSubpassIsSecondary (vector<bool>& subpassIsSecondary, const vector<Subpass>& subpasses, TestConfig::CommandBufferTypes commandBuffer)
{
	bool lastSubpassWasSecondary = false;

	for (size_t subpassNdx = 0; subpassNdx < subpasses.size(); subpassNdx++)
	{
		if (commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY || (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary))
		{
			subpassIsSecondary.push_back(true);
			lastSubpassWasSecondary = true;
		}
		else if (commandBuffer & TestConfig::COMMANDBUFFERTYPES_INLINE)
		{
			subpassIsSecondary.push_back(false);
			lastSubpassWasSecondary = false;
		}
		else
			DE_FATAL("Unknown commandBuffer");
	}
}

void initializeImageClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments, const vector<bool>& isLazy)
{
	for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
	{
		if (!isLazy[attachmentNdx])
			clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng)));
		else
			clearValues.push_back(nothing<VkClearValue>());
	}
}

void initializeRenderPassClearValues (de::Random& rng, vector<Maybe<VkClearValue> >& clearValues, const vector<Attachment>& attachments)
{
	for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
	{
		if (attachments[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR
			|| attachments[attachmentNdx].getStencilLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR)
		{
			clearValues.push_back(just(randomClearValue(attachments[attachmentNdx], rng)));
		}
		else
			clearValues.push_back(nothing<VkClearValue>());
	}
}

void initializeSubpassClearValues (de::Random& rng, vector<vector<VkClearColorValue> >& clearValues, const RenderPass& renderPass)
{
	clearValues.resize(renderPass.getSubpasses().size());

	for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
	{
		const Subpass&						subpass				= renderPass.getSubpasses()[subpassNdx];
		const vector<AttachmentReference>&	colorAttachments	= subpass.getColorAttachments();

		clearValues[subpassNdx].resize(colorAttachments.size());

		for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
		{
			const AttachmentReference&	attachmentRef	= colorAttachments[attachmentRefNdx];
			const Attachment&			attachment		= renderPass.getAttachments()[attachmentRef.getAttachment()];

			clearValues[subpassNdx][attachmentRefNdx] = randomColorClearValue(attachment, rng);
		}
	}
}

void logSubpassRenderInfo (TestLog&					log,
						   const SubpassRenderInfo&	info)
{
	log << TestLog::Message << "Viewport, offset: " << info.getViewportOffset() << ", size: " << info.getViewportSize() << TestLog::EndMessage;

	if (info.isSecondary())
		log << TestLog::Message << "Subpass uses secondary command buffers" << TestLog::EndMessage;
	else
		log << TestLog::Message << "Subpass uses inlined commands" << TestLog::EndMessage;

	for (deUint32 attachmentNdx = 0; attachmentNdx < info.getColorClears().size(); attachmentNdx++)
	{
		const ColorClear&	colorClear	= info.getColorClears()[attachmentNdx];

		log << TestLog::Message << "Clearing color attachment " << attachmentNdx
			<< ". Offset: " << colorClear.getOffset()
			<< ", Size: " << colorClear.getSize()
			<< ", Color: " << clearColorToString(info.getColorAttachment(attachmentNdx).getFormat(), colorClear.getColor()) << TestLog::EndMessage;
	}

	if (info.getDepthStencilClear())
	{
		const DepthStencilClear&	depthStencilClear	= *info.getDepthStencilClear();

		log << TestLog::Message << "Clearing depth stencil attachment"
			<< ". Offset: " << depthStencilClear.getOffset()
			<< ", Size: " << depthStencilClear.getSize()
			<< ", Depth: " << depthStencilClear.getDepth()
			<< ", Stencil: " << depthStencilClear.getStencil() << TestLog::EndMessage;
	}

	if (info.getRenderQuad())
	{
		const RenderQuad&	renderQuad	= *info.getRenderQuad();

		log << TestLog::Message << "Rendering grid quad to " << renderQuad.getCornerA() << " -> " << renderQuad.getCornerB() << TestLog::EndMessage;
	}
}

void logTestCaseInfo (TestLog&								log,
					  const TestConfig&						config,
					  const vector<bool>&					attachmentIsLazy,
					  const vector<Maybe<VkClearValue> >&	imageClearValues,
					  const vector<Maybe<VkClearValue> >&	renderPassClearValues,
					  const vector<SubpassRenderInfo>&		subpassRenderInfo)
{
	const RenderPass&	renderPass	= config.renderPass;

	logRenderPassInfo(log, renderPass);

	DE_ASSERT(attachmentIsLazy.size() == renderPass.getAttachments().size());
	DE_ASSERT(imageClearValues.size() == renderPass.getAttachments().size());
	DE_ASSERT(renderPassClearValues.size() == renderPass.getAttachments().size());

	log << TestLog::Message << "TargetSize: " << config.targetSize << TestLog::EndMessage;
	log << TestLog::Message << "Render area, Offset: " << config.renderPos << ", Size: " << config.renderSize << TestLog::EndMessage;

	for (size_t attachmentNdx = 0; attachmentNdx < attachmentIsLazy.size(); attachmentNdx++)
	{
		const tcu::ScopedLogSection	section	(log, "Attachment" + de::toString(attachmentNdx), "Attachment " + de::toString(attachmentNdx));

		if (attachmentIsLazy[attachmentNdx])
			log << TestLog::Message << "Is lazy." << TestLog::EndMessage;

		if (imageClearValues[attachmentNdx])
			log << TestLog::Message << "Image is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(), *imageClearValues[attachmentNdx]) << " before rendering." << TestLog::EndMessage;

		if (renderPass.getAttachments()[attachmentNdx].getLoadOp() == VK_ATTACHMENT_LOAD_OP_CLEAR && renderPassClearValues[attachmentNdx])
			log << TestLog::Message << "Attachment is cleared to " << clearValueToString(renderPass.getAttachments()[attachmentNdx].getFormat(), *renderPassClearValues[attachmentNdx]) << " in the beginning of the render pass." << TestLog::EndMessage;
	}

	for (size_t subpassNdx = 0; subpassNdx < renderPass.getSubpasses().size(); subpassNdx++)
	{
		const tcu::ScopedLogSection section (log, "Subpass" + de::toString(subpassNdx), "Subpass " + de::toString(subpassNdx));

		logSubpassRenderInfo(log, subpassRenderInfo[subpassNdx]);
	}
}

float roundToViewport (float x, deUint32 offset, deUint32 size)
{
	const float		origin	= (float)(offset) + ((float(size) / 2.0f));
	const float		p		= (float)(size) / 2.0f;
	const deInt32	xi		= deRoundFloatToInt32(origin + (p * x));

	return (((float)xi) - origin) / p;
}

void initializeSubpassRenderInfo (vector<SubpassRenderInfo>& renderInfos, de::Random& rng, const RenderPass& renderPass, const TestConfig& config)
{
	const TestConfig::CommandBufferTypes	commandBuffer			= config.commandBufferTypes;
	const vector<Subpass>&					subpasses				= renderPass.getSubpasses();
	bool									lastSubpassWasSecondary	= false;

	for (deUint32 subpassNdx = 0; subpassNdx < (deUint32)subpasses.size(); subpassNdx++)
	{
		const Subpass&				subpass				= subpasses[subpassNdx];
		const bool					subpassIsSecondary	= commandBuffer == TestConfig::COMMANDBUFFERTYPES_SECONDARY
														|| (commandBuffer & TestConfig::COMMANDBUFFERTYPES_SECONDARY && !lastSubpassWasSecondary) ? true : false;
		const UVec2					viewportSize		((config.renderSize * UVec2(2)) / UVec2(3));
		const UVec2					viewportOffset		(config.renderPos.x() + (subpassNdx % 2) * (config.renderSize.x() / 3),
														 config.renderPos.y() + ((subpassNdx / 2) % 2) * (config.renderSize.y() / 3));

		vector<ColorClear>			colorClears;
		Maybe<DepthStencilClear>	depthStencilClear;
		Maybe<RenderQuad>			renderQuad;

		lastSubpassWasSecondary		= subpassIsSecondary;

		if (config.renderTypes & TestConfig::RENDERTYPES_CLEAR)
		{
			const vector<AttachmentReference>&	colorAttachments	= subpass.getColorAttachments();

			for (size_t attachmentRefNdx = 0; attachmentRefNdx < colorAttachments.size(); attachmentRefNdx++)
			{
				const AttachmentReference&	attachmentRef	= colorAttachments[attachmentRefNdx];
				const Attachment&			attachment		= renderPass.getAttachments()[attachmentRef.getAttachment()];
				const UVec2					size			((viewportSize * UVec2(2)) / UVec2(3));
				const UVec2					offset			(viewportOffset.x() + ((deUint32)attachmentRefNdx % 2u) * (viewportSize.x() / 3u),
															 viewportOffset.y() + (((deUint32)attachmentRefNdx / 2u) % 2u) * (viewportSize.y() / 3u));
				const VkClearColorValue		color			= randomColorClearValue(attachment, rng);

				colorClears.push_back(ColorClear(offset, size, color));
			}

			if (subpass.getDepthStencilAttachment().getAttachment() != VK_ATTACHMENT_UNUSED)
			{
				const Attachment&	attachment	= renderPass.getAttachments()[subpass.getDepthStencilAttachment().getAttachment()];
				const UVec2			size		((viewportSize * UVec2(2)) / UVec2(3));
				const UVec2			offset		(viewportOffset.x() + ((deUint32)colorAttachments.size() % 2u) * (viewportSize.x() / 3u),
												 viewportOffset.y() + (((deUint32)colorAttachments.size() / 2u) % 2u) * (viewportSize.y() / 3u));
				const VkClearValue	value		= randomClearValue(attachment, rng);

				depthStencilClear = tcu::just(DepthStencilClear(offset, size, value.depthStencil.depth, value.depthStencil.stencil));
			}
		}

		if (config.renderTypes & TestConfig::RENDERTYPES_DRAW)
		{
			const float	w	= (subpassNdx % 2) == 0 ? 1.0f : 1.25f;
			const float	h	= (subpassNdx % 2) == 0 ? 1.25f : 1.0f;

			const float	x0	= roundToViewport((subpassNdx % 2) == 0 ? 1.0f - w : -1.0f, viewportOffset.x(), viewportSize.x());
			const float	x1	= roundToViewport((subpassNdx % 2) == 0 ? 1.0f : -1.0f + w, viewportOffset.x(), viewportSize.x());

			const float	y0	= roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f - h : -1.0f, viewportOffset.y(), viewportSize.y());
			const float	y1	= roundToViewport(((subpassNdx / 2) % 2) == 0 ? 1.0f : -1.0f + h, viewportOffset.y(), viewportSize.y());

			renderQuad = tcu::just(RenderQuad(tcu::Vec2(x0, y0), tcu::Vec2(x1, y1)));
		}

		renderInfos.push_back(SubpassRenderInfo(renderPass, subpassNdx, subpassIsSecondary, viewportOffset, viewportSize, renderQuad, colorClears, depthStencilClear));
	}
}

void checkTextureFormatSupport (TestLog&					log,
								const InstanceInterface&	vk,
								VkPhysicalDevice			device,
								const vector<Attachment>&	attachments)
{
	bool supported = true;

	for (size_t attachmentNdx = 0; attachmentNdx < attachments.size(); attachmentNdx++)
	{
		const Attachment&			attachment					= attachments[attachmentNdx];
		const tcu::TextureFormat	format						= mapVkFormat(attachment.getFormat());
		const bool					isDepthOrStencilAttachment	= hasDepthComponent(format.order) || hasStencilComponent(format.order);
		const VkFormatFeatureFlags	flags						= isDepthOrStencilAttachment? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
		VkFormatProperties			properties;

		vk.getPhysicalDeviceFormatProperties(device, attachment.getFormat(), &properties);

		if ((properties.optimalTilingFeatures & flags) != flags)
		{
			supported = false;
			log << TestLog::Message << "Format: " << attachment.getFormat() << " not supported as " << (isDepthOrStencilAttachment ? "depth stencil attachment" : "color attachment") << TestLog::EndMessage;
		}
	}

	if (!supported)
		TCU_THROW(NotSupportedError, "Format not supported");
}

tcu::TestStatus renderPassTest (Context& context, TestConfig config)
{
	const UVec2							targetSize			= config.targetSize;
	const UVec2							renderPos			= config.renderPos;
	const UVec2							renderSize			= config.renderSize;
	const RenderPass&					renderPassInfo		= config.renderPass;

	TestLog&							log					= context.getTestContext().getLog();
	de::Random							rng					(config.seed);

	vector<bool>						attachmentIsLazy;
	vector<VkImageUsageFlags>			attachmentImageUsage;
	vector<Maybe<VkClearValue> >		imageClearValues;
	vector<Maybe<VkClearValue> >		renderPassClearValues;

	vector<bool>						subpassIsSecondary;
	vector<SubpassRenderInfo>			subpassRenderInfo;
	vector<vector<VkClearColorValue> >	subpassColorClearValues;

	if (config.allocationKind == ALLOCATION_KIND_DEDICATED)
	{
		const std::string extensionName("VK_KHR_dedicated_allocation");

		if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName))
			TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
	}

	initializeAttachmentIsLazy(attachmentIsLazy, renderPassInfo.getAttachments(), config.imageMemory);
	initializeImageClearValues(rng, imageClearValues, renderPassInfo.getAttachments(), attachmentIsLazy);
	initializeAttachmentImageUsage(context, attachmentImageUsage, renderPassInfo, attachmentIsLazy, imageClearValues);
	initializeRenderPassClearValues(rng, renderPassClearValues, renderPassInfo.getAttachments());

	initializeSubpassIsSecondary(subpassIsSecondary, renderPassInfo.getSubpasses(), config.commandBufferTypes);
	initializeSubpassClearValues(rng, subpassColorClearValues, renderPassInfo);
	initializeSubpassRenderInfo(subpassRenderInfo, rng, renderPassInfo, config);

	logTestCaseInfo(log, config, attachmentIsLazy, imageClearValues, renderPassClearValues, subpassRenderInfo);

	checkTextureFormatSupport(log, context.getInstanceInterface(), context.getPhysicalDevice(), config.renderPass.getAttachments());

	{
		const vk::VkPhysicalDeviceProperties properties = vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice());

		log << TestLog::Message << "Max color attachments: " << properties.limits.maxColorAttachments << TestLog::EndMessage;

		for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
		{
			 if (renderPassInfo.getSubpasses()[subpassNdx].getColorAttachments().size() > (size_t)properties.limits.maxColorAttachments)
				 TCU_THROW(NotSupportedError, "Subpass uses more than maxColorAttachments.");
		}
	}

	{
		const InstanceInterface&					vki									= context.getInstanceInterface();
		const VkPhysicalDevice&						physDevice							= context.getPhysicalDevice();
		const VkDevice								device								= context.getDevice();
		const DeviceInterface&						vk									= context.getDeviceInterface();
		const VkQueue								queue								= context.getUniversalQueue();
		const deUint32								queueIndex							= context.getUniversalQueueFamilyIndex();
		Allocator&									allocator							= context.getDefaultAllocator();

		const Unique<VkRenderPass>					renderPass							(createRenderPass(vk, device, renderPassInfo));
		const Unique<VkCommandPool>					commandBufferPool					(createCommandPool(vk, device, queueIndex, 0));
		const Unique<VkCommandBuffer>				initializeImagesCommandBuffer		(allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
		const Unique<VkCommandBuffer>				renderCommandBuffer					(allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
		const Unique<VkCommandBuffer>				readImagesToBuffersCommandBuffer	(allocateCommandBuffer(vk, device, *commandBufferPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

		vector<de::SharedPtr<AttachmentResources> >	attachmentResources;
		vector<de::SharedPtr<SubpassRenderer> >		subpassRenderers;
		vector<VkImage>								attachmentImages;
		vector<VkImageView>							attachmentViews;
		vector<pair<VkImageView, VkImageView> >		inputAttachmentViews;

		for (size_t attachmentNdx = 0; attachmentNdx < renderPassInfo.getAttachments().size(); attachmentNdx++)
		{
			const Attachment&	attachmentInfo	= renderPassInfo.getAttachments()[attachmentNdx];

			attachmentResources.push_back(de::SharedPtr<AttachmentResources>(new AttachmentResources(vki, physDevice, vk, device, allocator, queueIndex, targetSize, attachmentInfo, attachmentImageUsage[attachmentNdx], config.allocationKind)));
			attachmentViews.push_back(attachmentResources[attachmentNdx]->getAttachmentView());
			attachmentImages.push_back(attachmentResources[attachmentNdx]->getImage());

			inputAttachmentViews.push_back(attachmentResources[attachmentNdx]->getInputAttachmentViews());
		}

		beginCommandBuffer(vk, *initializeImagesCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
		pushImageInitializationCommands(vk, *initializeImagesCommandBuffer, renderPassInfo.getAttachments(), attachmentResources, queueIndex, imageClearValues);
		endCommandBuffer(vk, *initializeImagesCommandBuffer);

		{
			const Unique<VkFramebuffer> framebuffer (createFramebuffer(vk, device, *renderPass, targetSize, attachmentViews));

			for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
				subpassRenderers.push_back(de::SharedPtr<SubpassRenderer>(new SubpassRenderer(context, vk, device, allocator, *renderPass, *framebuffer, *commandBufferPool, queueIndex, attachmentImages, inputAttachmentViews, subpassRenderInfo[subpassNdx], config.renderPass.getAttachments(), config.allocationKind)));

			beginCommandBuffer(vk, *renderCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
			pushRenderPassCommands(vk, *renderCommandBuffer, *renderPass, *framebuffer, subpassRenderers, renderPos, renderSize, renderPassClearValues, config.renderTypes);
			endCommandBuffer(vk, *renderCommandBuffer);

			beginCommandBuffer(vk, *readImagesToBuffersCommandBuffer, (VkCommandBufferUsageFlags)0, DE_NULL, 0, DE_NULL, VK_FALSE, (VkQueryControlFlags)0, (VkQueryPipelineStatisticFlags)0);
			pushReadImagesToBuffers(vk, *readImagesToBuffersCommandBuffer, queueIndex, attachmentResources, renderPassInfo.getAttachments(), attachmentIsLazy, targetSize);
			endCommandBuffer(vk, *readImagesToBuffersCommandBuffer);
			{
				const VkCommandBuffer commandBuffers[] =
				{
					*initializeImagesCommandBuffer,
					*renderCommandBuffer,
					*readImagesToBuffersCommandBuffer
				};
				const Unique<VkFence>	fence		(createFence(vk, device, 0u));

				queueSubmit(vk, queue, DE_LENGTH_OF_ARRAY(commandBuffers), commandBuffers, *fence);
				waitForFences(vk, device, 1, &fence.get(), VK_TRUE, ~0ull);
			}
		}

		if (logAndVerifyImages(log, vk, device, attachmentResources, attachmentIsLazy, renderPassInfo, renderPassClearValues, imageClearValues, subpassRenderInfo, targetSize, config))
			return tcu::TestStatus::pass("Pass");
		else
			return tcu::TestStatus::fail("Result verification failed");
	}
}

static const VkFormat s_coreColorFormats[] =
{
	VK_FORMAT_R5G6B5_UNORM_PACK16,
	VK_FORMAT_R8_UNORM,
	VK_FORMAT_R8_SNORM,
	VK_FORMAT_R8_UINT,
	VK_FORMAT_R8_SINT,
	VK_FORMAT_R8G8_UNORM,
	VK_FORMAT_R8G8_SNORM,
	VK_FORMAT_R8G8_UINT,
	VK_FORMAT_R8G8_SINT,
	VK_FORMAT_R8G8B8A8_UNORM,
	VK_FORMAT_R8G8B8A8_SNORM,
	VK_FORMAT_R8G8B8A8_UINT,
	VK_FORMAT_R8G8B8A8_SINT,
	VK_FORMAT_R8G8B8A8_SRGB,
	VK_FORMAT_A8B8G8R8_UNORM_PACK32,
	VK_FORMAT_A8B8G8R8_SNORM_PACK32,
	VK_FORMAT_A8B8G8R8_UINT_PACK32,
	VK_FORMAT_A8B8G8R8_SINT_PACK32,
	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
	VK_FORMAT_B8G8R8A8_UNORM,
	VK_FORMAT_B8G8R8A8_SRGB,
	VK_FORMAT_A2R10G10B10_UNORM_PACK32,
	VK_FORMAT_A2B10G10R10_UNORM_PACK32,
	VK_FORMAT_A2B10G10R10_UINT_PACK32,
	VK_FORMAT_R16_UNORM,
	VK_FORMAT_R16_SNORM,
	VK_FORMAT_R16_UINT,
	VK_FORMAT_R16_SINT,
	VK_FORMAT_R16_SFLOAT,
	VK_FORMAT_R16G16_UNORM,
	VK_FORMAT_R16G16_SNORM,
	VK_FORMAT_R16G16_UINT,
	VK_FORMAT_R16G16_SINT,
	VK_FORMAT_R16G16_SFLOAT,
	VK_FORMAT_R16G16B16A16_UNORM,
	VK_FORMAT_R16G16B16A16_SNORM,
	VK_FORMAT_R16G16B16A16_UINT,
	VK_FORMAT_R16G16B16A16_SINT,
	VK_FORMAT_R16G16B16A16_SFLOAT,
	VK_FORMAT_R32_UINT,
	VK_FORMAT_R32_SINT,
	VK_FORMAT_R32_SFLOAT,
	VK_FORMAT_R32G32_UINT,
	VK_FORMAT_R32G32_SINT,
	VK_FORMAT_R32G32_SFLOAT,
	VK_FORMAT_R32G32B32A32_UINT,
	VK_FORMAT_R32G32B32A32_SINT,
	VK_FORMAT_R32G32B32A32_SFLOAT
};

static const VkFormat s_coreDepthStencilFormats[] =
{
	VK_FORMAT_D16_UNORM,

	VK_FORMAT_X8_D24_UNORM_PACK32,
	VK_FORMAT_D32_SFLOAT,

	VK_FORMAT_D24_UNORM_S8_UINT,
	VK_FORMAT_D32_SFLOAT_S8_UINT
};

void addAttachmentTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
{
	const deUint32 attachmentCounts[] = { 1, 3, 4, 8 };
	const VkAttachmentLoadOp loadOps[] =
	{
		VK_ATTACHMENT_LOAD_OP_LOAD,
		VK_ATTACHMENT_LOAD_OP_CLEAR,
		VK_ATTACHMENT_LOAD_OP_DONT_CARE
	};

	const VkAttachmentStoreOp storeOps[] =
	{
		VK_ATTACHMENT_STORE_OP_STORE,
		VK_ATTACHMENT_STORE_OP_DONT_CARE
	};

	const VkImageLayout initialAndFinalColorLayouts[] =
	{
		VK_IMAGE_LAYOUT_GENERAL,
		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
	};

	const VkImageLayout initialAndFinalDepthStencilLayouts[] =
	{
		VK_IMAGE_LAYOUT_GENERAL,
		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
		VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
	};

	const VkImageLayout subpassLayouts[] =
	{
		VK_IMAGE_LAYOUT_GENERAL,
		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
	};

	const VkImageLayout depthStencilLayouts[] =
	{
		VK_IMAGE_LAYOUT_GENERAL,
		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
	};

	const TestConfig::RenderTypes renderCommands[] =
	{
		TestConfig::RENDERTYPES_NONE,
		TestConfig::RENDERTYPES_CLEAR,
		TestConfig::RENDERTYPES_DRAW,
		TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
	};

	const TestConfig::CommandBufferTypes commandBuffers[] =
	{
		TestConfig::COMMANDBUFFERTYPES_INLINE,
		TestConfig::COMMANDBUFFERTYPES_SECONDARY,
		TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
	};

	const TestConfig::ImageMemory imageMemories[] =
	{
		TestConfig::IMAGEMEMORY_STRICT,
		TestConfig::IMAGEMEMORY_LAZY,
		TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
	};

	const UVec2 targetSizes[] =
	{
		UVec2(64, 64),
		UVec2(63, 65)
	};

	const UVec2 renderPositions[] =
	{
		UVec2(0, 0),
		UVec2(3, 17)
	};

	const UVec2 renderSizes[] =
	{
		UVec2(32, 32),
		UVec2(60, 47)
	};

	tcu::TestContext&	testCtx	= group->getTestContext();
	de::Random			rng		(1433774382u);

	for (size_t attachmentCountNdx = 0; attachmentCountNdx < DE_LENGTH_OF_ARRAY(attachmentCounts); attachmentCountNdx++)
	{
		const deUint32					attachmentCount			= attachmentCounts[attachmentCountNdx];
		const deUint32					testCaseCount			= (attachmentCount == 1 ? 100 : 200);
		de::MovePtr<tcu::TestCaseGroup>	attachmentCountGroup	(new tcu::TestCaseGroup(testCtx, de::toString(attachmentCount).c_str(), de::toString(attachmentCount).c_str()));

		for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
		{
			const bool					useDepthStencil		= rng.getBool();
			VkImageLayout				depthStencilLayout	= VK_IMAGE_LAYOUT_GENERAL;
			vector<Attachment>			attachments;
			vector<AttachmentReference>	colorAttachmentReferences;

			for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
			{
				const VkSampleCountFlagBits	sampleCount		= VK_SAMPLE_COUNT_1_BIT;
				const VkFormat				format			= rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
				const VkAttachmentLoadOp	loadOp			= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
				const VkAttachmentStoreOp	storeOp			= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));

				const VkImageLayout			initialLayout	= rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
				const VkImageLayout			finalizeLayout	= rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
				const VkImageLayout			subpassLayout	= rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));

				const VkAttachmentLoadOp	stencilLoadOp	= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
				const VkAttachmentStoreOp	stencilStoreOp	= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));

				attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
				colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
			}

			if (useDepthStencil)
			{
				const VkSampleCountFlagBits	sampleCount		= VK_SAMPLE_COUNT_1_BIT;
				const VkFormat				format			= rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));
				const VkAttachmentLoadOp	loadOp			= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
				const VkAttachmentStoreOp	storeOp			= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));

				const VkImageLayout			initialLayout	= rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts));
				const VkImageLayout			finalizeLayout	= rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts));

				const VkAttachmentLoadOp	stencilLoadOp	= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
				const VkAttachmentStoreOp	stencilStoreOp	= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));

				depthStencilLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(depthStencilLayouts), DE_ARRAY_END(depthStencilLayouts));
				attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
			}

			{
				const TestConfig::RenderTypes			render			= rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
				const TestConfig::CommandBufferTypes	commandBuffer	= rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
				const TestConfig::ImageMemory			imageMemory		= rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));
				const vector<Subpass>					subpasses		(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(), colorAttachmentReferences, vector<AttachmentReference>(), AttachmentReference((useDepthStencil ? (deUint32)(attachments.size() - 1) : VK_ATTACHMENT_UNUSED), depthStencilLayout), vector<deUint32>()));
				const vector<SubpassDependency>			deps;

				const string							testCaseName	= de::toString(attachmentCountNdx * testCaseCount + testCaseNdx);
				const RenderPass						renderPass		(attachments, subpasses, deps);
				const UVec2								targetSize		= rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
				const UVec2								renderPos		= rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
				const UVec2								renderSize		= rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));

				addFunctionCaseWithPrograms<TestConfig>(attachmentCountGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 1293809, allocationKind));
			}
		}

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

template<typename T>
T chooseRandom (de::Random& rng, const set<T>& values)
{
	size_t							ndx		= ((size_t)rng.getUint32()) % values.size();
	typename set<T>::const_iterator	iter	= values.begin();

	for (; ndx > 0; ndx--)
		iter++;

	return *iter;
}

void addAttachmentAllocationTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
{
	const deUint32 attachmentCounts[] = { 4, 8 };
	const VkAttachmentLoadOp loadOps[] =
	{
		VK_ATTACHMENT_LOAD_OP_LOAD,
		VK_ATTACHMENT_LOAD_OP_CLEAR,
		VK_ATTACHMENT_LOAD_OP_DONT_CARE
	};

	const VkAttachmentStoreOp storeOps[] =
	{
		VK_ATTACHMENT_STORE_OP_STORE,
		VK_ATTACHMENT_STORE_OP_DONT_CARE
	};

	const VkImageLayout initialAndFinalColorLayouts[] =
	{
		VK_IMAGE_LAYOUT_GENERAL,
		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
	};

	const VkImageLayout initialAndFinalDepthStencilLayouts[] =
	{
		VK_IMAGE_LAYOUT_GENERAL,
		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
		VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
	};

	const VkImageLayout subpassLayouts[] =
	{
		VK_IMAGE_LAYOUT_GENERAL,
		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
	};

	enum AllocationType
	{
		// Each pass uses one more attachmen than previous one
		ALLOCATIONTYPE_GROW,
		// Each pass uses one less attachment than previous one
		ALLOCATIONTYPE_SHRINK,
		// Each pass drops one attachment and picks up new one
		ALLOCATIONTYPE_ROLL,
		// Start by growing and end by shrinking
		ALLOCATIONTYPE_GROW_SHRINK,
		// Each subpass has single input and single output attachment
		ALLOCATIONTYPE_IO_CHAIN,
		// Each subpass has multiple inputs and multiple outputs attachment
		ALLOCATIONTYPE_IO_GENERIC
	};

	const AllocationType allocationTypes[] =
	{
		ALLOCATIONTYPE_GROW,
		ALLOCATIONTYPE_SHRINK,
		ALLOCATIONTYPE_ROLL,
		ALLOCATIONTYPE_GROW_SHRINK,
		ALLOCATIONTYPE_IO_CHAIN,
		ALLOCATIONTYPE_IO_GENERIC
	};

	const char* const allocationTypeStr[] =
	{
		"grow",
		"shrink",
		"roll",
		"grow_shrink",
		"input_output_chain",
		"input_output",
	};

	const TestConfig::RenderTypes renderCommands[] =
	{
		TestConfig::RENDERTYPES_NONE,
		TestConfig::RENDERTYPES_CLEAR,
		TestConfig::RENDERTYPES_DRAW,
		TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW,
	};

	const TestConfig::CommandBufferTypes commandBuffers[] =
	{
		TestConfig::COMMANDBUFFERTYPES_INLINE,
		TestConfig::COMMANDBUFFERTYPES_SECONDARY,
		TestConfig::COMMANDBUFFERTYPES_INLINE|TestConfig::COMMANDBUFFERTYPES_SECONDARY
	};

	const TestConfig::ImageMemory imageMemories[] =
	{
		TestConfig::IMAGEMEMORY_STRICT,
		TestConfig::IMAGEMEMORY_LAZY,
		TestConfig::IMAGEMEMORY_STRICT|TestConfig::IMAGEMEMORY_LAZY
	};

	const UVec2 targetSizes[] =
	{
		UVec2(64, 64),
		UVec2(63, 65)
	};

	const UVec2 renderPositions[] =
	{
		UVec2(0, 0),
		UVec2(3, 17)
	};

	const UVec2 renderSizes[] =
	{
		UVec2(32, 32),
		UVec2(60, 47)
	};

	tcu::TestContext&				testCtx	= group->getTestContext();
	de::Random						rng		(3700649827u);

	for (size_t allocationTypeNdx = 0; allocationTypeNdx < DE_LENGTH_OF_ARRAY(allocationTypes); allocationTypeNdx++)
	{
		const AllocationType			allocationType		= allocationTypes[allocationTypeNdx];
		const size_t					testCaseCount		= 100;
		de::MovePtr<tcu::TestCaseGroup>	allocationTypeGroup	(new tcu::TestCaseGroup(testCtx, allocationTypeStr[allocationTypeNdx], allocationTypeStr[allocationTypeNdx]));

		for (size_t testCaseNdx = 0; testCaseNdx < testCaseCount; testCaseNdx++)
		{
			if (allocationType == ALLOCATIONTYPE_IO_GENERIC)
			{
				const deUint32		attachmentCount	= 4u + rng.getUint32() % 31u;
				const deUint32		subpassCount	= 4u + rng.getUint32() % 31u;
				vector<Attachment>	attachments;

				set<deUint32>		definedAttachments;

				vector<Subpass>		subpasses;
				set<deUint32>		colorAttachments;
				set<deUint32>		depthStencilAttachments;

				for (deUint32 attachmentIndex = 0; attachmentIndex < attachmentCount; attachmentIndex++)
				{
					const bool					isDepthStencilAttachment	= rng.getFloat() < 0.01f;
					const VkSampleCountFlagBits	sampleCount					= VK_SAMPLE_COUNT_1_BIT;
					const VkAttachmentLoadOp	loadOp						= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
					const VkAttachmentStoreOp	storeOp						= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));

					const VkImageLayout			initialLayout				= isDepthStencilAttachment
																			? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
																			: rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
					const VkImageLayout			finalizeLayout				= isDepthStencilAttachment
																			? rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalDepthStencilLayouts), DE_ARRAY_END(initialAndFinalDepthStencilLayouts))
																			: rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));

					const VkAttachmentLoadOp	stencilLoadOp				= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
					const VkAttachmentStoreOp	stencilStoreOp				= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));

					if (isDepthStencilAttachment)
					{
						const VkFormat	format	= rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreDepthStencilFormats), DE_ARRAY_END(s_coreDepthStencilFormats));

						if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR
							|| stencilLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD || stencilLoadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
							definedAttachments.insert(attachmentIndex);

						depthStencilAttachments.insert(attachmentIndex);

						attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
					}
					else
					{
						const VkFormat	format	= rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));

						if (loadOp == VK_ATTACHMENT_LOAD_OP_LOAD || loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
							definedAttachments.insert(attachmentIndex);

						colorAttachments.insert(attachmentIndex);

						attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp, initialLayout, finalizeLayout));
					}
				}
				vector<Maybe<deUint32> >	lastUseOfAttachment	(attachments.size(), nothing<deUint32>());
				vector<SubpassDependency>	deps;

				for (deUint32 subpassIndex = 0; subpassIndex < subpassCount; subpassIndex++)
				{
					const deUint32				colorAttachmentCount		= depthStencilAttachments.empty()
																			? 1 + rng.getUint32() % de::min(4u, (deUint32)colorAttachments.size())
																			: rng.getUint32() % (de::min(4u, (deUint32)colorAttachments.size()) + 1u);
					const deUint32				inputAttachmentCount		= rng.getUint32() % (deUint32)(de::min<size_t>(4, definedAttachments.size()) + 1);
					const bool					useDepthStencilAttachment	= !depthStencilAttachments.empty() && (colorAttachmentCount == 0 || rng.getBool());
					std::vector<deUint32>		subpassColorAttachments		(colorAttachmentCount);
					std::vector<deUint32>		subpassInputAttachments		(inputAttachmentCount);
					Maybe<deUint32>				depthStencilAttachment		(useDepthStencilAttachment
																			? just(chooseRandom(rng, depthStencilAttachments))
																			: nothing<deUint32>());
					std::vector<deUint32>		subpassPreserveAttachments;

					rng.choose(colorAttachments.begin(), colorAttachments.end(), subpassColorAttachments.begin(), colorAttachmentCount);
					rng.choose(definedAttachments.begin(), definedAttachments.end(), subpassInputAttachments.begin(), inputAttachmentCount);

					for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++)
						definedAttachments.insert(subpassColorAttachments[colorAttachmentNdx]);

					if (depthStencilAttachment)
						definedAttachments.insert(*depthStencilAttachment);

					{
						std::vector<AttachmentReference>	inputAttachmentReferences;
						std::vector<AttachmentReference>	colorAttachmentReferences;
						AttachmentReference					depthStencilAttachmentReference (VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL);

						for (size_t colorAttachmentNdx = 0; colorAttachmentNdx < subpassColorAttachments.size(); colorAttachmentNdx++)
						{
							const deUint32		colorAttachmentIndex	= subpassColorAttachments[colorAttachmentNdx];
							// \todo [mika 2016-08-25] Check if attachment is not used as input attachment and use other image layouts
							const VkImageLayout	subpassLayout			= VK_IMAGE_LAYOUT_GENERAL;

							if (lastUseOfAttachment[colorAttachmentIndex])
							{
								const bool byRegion = rng.getBool();

								deps.push_back(SubpassDependency(*lastUseOfAttachment[colorAttachmentIndex], subpassIndex,
																 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
																	| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
																	| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
																	| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,

																 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
																	| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
																	| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
																	| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,

																 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
																 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,

																 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
							}

							lastUseOfAttachment[colorAttachmentIndex] = just(subpassIndex);

							colorAttachmentReferences.push_back(AttachmentReference((deUint32)subpassColorAttachments[colorAttachmentNdx], subpassLayout));
						}

						for (size_t inputAttachmentNdx = 0; inputAttachmentNdx < subpassInputAttachments.size(); inputAttachmentNdx++)
						{
							const deUint32		inputAttachmentIndex	= subpassInputAttachments[inputAttachmentNdx];
							// \todo [mika 2016-08-25] Check if attachment is not used as color attachment and use other image layouts
							const VkImageLayout	subpassLayout			= VK_IMAGE_LAYOUT_GENERAL;

							if(lastUseOfAttachment[inputAttachmentIndex])
							{
								if(*lastUseOfAttachment[inputAttachmentIndex] == subpassIndex)
								{
									deps.push_back(SubpassDependency(subpassIndex, subpassIndex,
																	 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
																		| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
																		| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
																		| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,

																	 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
																		| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
																		| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
																		| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,

																	 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
																	 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,

																	 VK_DEPENDENCY_BY_REGION_BIT));
								}
								else
								{
									const bool byRegion = rng.getBool();

									deps.push_back(SubpassDependency(*lastUseOfAttachment[inputAttachmentIndex], subpassIndex,
																	 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
																		| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
																		| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
																		| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,

																	 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
																		| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
																		| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
																		| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,

																	 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
																	 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,

																	 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
								}

								lastUseOfAttachment[inputAttachmentIndex] = just(subpassIndex);

								inputAttachmentReferences.push_back(AttachmentReference((deUint32)subpassInputAttachments[inputAttachmentNdx], subpassLayout));
							}
						}

						if (depthStencilAttachment)
						{
							// \todo [mika 2016-08-25] Check if attachment is not used as input attachment and use other image layouts
							if (lastUseOfAttachment[*depthStencilAttachment])
							{
								if(*lastUseOfAttachment[*depthStencilAttachment] == subpassIndex)
								{
									deps.push_back(SubpassDependency(subpassIndex, subpassIndex,
																	 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
																		| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
																		| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
																		| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,

																	 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
																		| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
																		| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
																		| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,

																	 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
																	 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,

																	 VK_DEPENDENCY_BY_REGION_BIT));
								}
								else
								{
									const bool byRegion = rng.getBool();

									deps.push_back(SubpassDependency(*lastUseOfAttachment[*depthStencilAttachment], subpassIndex,
																	 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
																		| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
																		| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
																		| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,

																	 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
																		| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
																		| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
																		| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,

																	 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
																	 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,

																	 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
								}
							}

							lastUseOfAttachment[*depthStencilAttachment] = just(subpassIndex);
							depthStencilAttachmentReference = AttachmentReference(*depthStencilAttachment, VK_IMAGE_LAYOUT_GENERAL);
						}
						else
							depthStencilAttachmentReference = AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL);

						vector<deUint32>	preserveAttachments;
						for (deUint32 attachmentIndex = 0; attachmentIndex < (deUint32)attachments.size(); attachmentIndex++)
						{
							if (lastUseOfAttachment[attachmentIndex] && (*lastUseOfAttachment[attachmentIndex]) != subpassIndex)
								preserveAttachments.push_back(attachmentIndex);
						}

						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
												inputAttachmentReferences,
												colorAttachmentReferences,
												vector<AttachmentReference>(),
												depthStencilAttachmentReference,
												preserveAttachments));
					}
				}
				{
					const TestConfig::RenderTypes			render			= rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
					const TestConfig::CommandBufferTypes	commandBuffer	= rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
					const TestConfig::ImageMemory			imageMemory		= rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));

					const string							testCaseName	= de::toString(testCaseNdx);
					const UVec2								targetSize		= rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
					const UVec2								renderPos		= rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
					const UVec2								renderSize		= rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));

					const RenderPass						renderPass		(attachments, subpasses, deps);

					addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 80329, allocationKind));
				}
			}
			else
			{
				const deUint32		attachmentCount	= rng.choose<deUint32>(DE_ARRAY_BEGIN(attachmentCounts), DE_ARRAY_END(attachmentCounts));
				vector<Attachment>	attachments;
				vector<Subpass>		subpasses;

				for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
				{
					const VkSampleCountFlagBits	sampleCount		= VK_SAMPLE_COUNT_1_BIT;
					const VkFormat				format			= rng.choose<VkFormat>(DE_ARRAY_BEGIN(s_coreColorFormats), DE_ARRAY_END(s_coreColorFormats));
					const VkAttachmentLoadOp	loadOp			= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
					const VkAttachmentStoreOp	storeOp			= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));

					const VkImageLayout			initialLayout	= rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));
					const VkImageLayout			finalizeLayout	= rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(initialAndFinalColorLayouts), DE_ARRAY_END(initialAndFinalColorLayouts));

					const VkAttachmentLoadOp	stencilLoadOp	= rng.choose<VkAttachmentLoadOp>(DE_ARRAY_BEGIN(loadOps), DE_ARRAY_END(loadOps));
					const VkAttachmentStoreOp	stencilStoreOp	= rng.choose<VkAttachmentStoreOp>(DE_ARRAY_BEGIN(storeOps), DE_ARRAY_END(storeOps));

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

				if (allocationType == ALLOCATIONTYPE_GROW)
				{
					for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
					{
						vector<AttachmentReference>	colorAttachmentReferences;

						for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
						{
							const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));

							colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
						}

						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
												vector<AttachmentReference>(),
												colorAttachmentReferences,
												vector<AttachmentReference>(),
												AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
												vector<deUint32>()));
					}
				}
				else if (allocationType == ALLOCATIONTYPE_SHRINK)
				{
					for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
					{
						vector<AttachmentReference>	colorAttachmentReferences;

						for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
						{
							const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));

							colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
						}

						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
													vector<AttachmentReference>(),
													colorAttachmentReferences,
													vector<AttachmentReference>(),
													AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
													vector<deUint32>()));
					}
				}
				else if (allocationType == ALLOCATIONTYPE_ROLL)
				{
					for (size_t subpassNdx = 0; subpassNdx < attachmentCount / 2; subpassNdx++)
					{
						vector<AttachmentReference>	colorAttachmentReferences;

						for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount / 2; attachmentNdx++)
						{
							const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));

							colorAttachmentReferences.push_back(AttachmentReference((deUint32)(subpassNdx + attachmentNdx), subpassLayout));
						}

						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
													vector<AttachmentReference>(),
													colorAttachmentReferences,
													vector<AttachmentReference>(),
													AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
													vector<deUint32>()));
					}
				}
				else if (allocationType == ALLOCATIONTYPE_GROW_SHRINK)
				{
					for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
					{
						vector<AttachmentReference>	colorAttachmentReferences;

						for (size_t attachmentNdx = 0; attachmentNdx < subpassNdx + 1; attachmentNdx++)
						{
							const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));

							colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
						}

						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
													vector<AttachmentReference>(),
													colorAttachmentReferences,
													vector<AttachmentReference>(),
													AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
													vector<deUint32>()));
					}

					for (size_t subpassNdx = 0; subpassNdx < attachmentCount; subpassNdx++)
					{
						vector<AttachmentReference>	colorAttachmentReferences;

						for (size_t attachmentNdx = 0; attachmentNdx < (attachmentCount - subpassNdx); attachmentNdx++)
						{
							const VkImageLayout subpassLayout = rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts));

							colorAttachmentReferences.push_back(AttachmentReference((deUint32)attachmentNdx, subpassLayout));
						}

						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
											vector<AttachmentReference>(),
											colorAttachmentReferences,
											vector<AttachmentReference>(),
											AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
											vector<deUint32>()));
					}
				}
				else if (allocationType == ALLOCATIONTYPE_IO_CHAIN)
				{
					subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
											vector<AttachmentReference>(),
											vector<AttachmentReference>(1, AttachmentReference(0, rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)))),
											vector<AttachmentReference>(),
											AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
											vector<deUint32>()));

					for (size_t subpassNdx = 1; subpassNdx < attachmentCount; subpassNdx++)
					{
						subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u,
												vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx - 1), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)),
												vector<AttachmentReference>(1, AttachmentReference((deUint32)(subpassNdx), rng.choose<VkImageLayout>(DE_ARRAY_BEGIN(subpassLayouts), DE_ARRAY_END(subpassLayouts)))),
												vector<AttachmentReference>(),
												AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
												vector<deUint32>()));
					}
				}
				else
					DE_FATAL("Unknown allocation type");

				{
					const TestConfig::RenderTypes			render			= rng.choose<TestConfig::RenderTypes>(DE_ARRAY_BEGIN(renderCommands), DE_ARRAY_END(renderCommands));
					const TestConfig::CommandBufferTypes	commandBuffer	= rng.choose<TestConfig::CommandBufferTypes>(DE_ARRAY_BEGIN(commandBuffers), DE_ARRAY_END(commandBuffers));
					const TestConfig::ImageMemory			imageMemory		= rng.choose<TestConfig::ImageMemory>(DE_ARRAY_BEGIN(imageMemories), DE_ARRAY_END(imageMemories));

					const string							testCaseName	= de::toString(testCaseNdx);
					const UVec2								targetSize		= rng.choose<UVec2>(DE_ARRAY_BEGIN(targetSizes), DE_ARRAY_END(targetSizes));
					const UVec2								renderPos		= rng.choose<UVec2>(DE_ARRAY_BEGIN(renderPositions), DE_ARRAY_END(renderPositions));
					const UVec2								renderSize		= rng.choose<UVec2>(DE_ARRAY_BEGIN(renderSizes), DE_ARRAY_END(renderSizes));

					vector<SubpassDependency>				deps;

					for (size_t subpassNdx = 0; subpassNdx < subpasses.size() - 1; subpassNdx++)
					{
						const bool byRegion				= rng.getBool();
						deps.push_back(SubpassDependency((deUint32)subpassNdx, (deUint32)subpassNdx + 1,
														 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
															| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
															| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
															| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,

														 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
															| VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
															| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
															| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,

														 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
														 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,

														 byRegion ? (VkDependencyFlags)VK_DEPENDENCY_BY_REGION_BIT : 0u));
					}

					const RenderPass					renderPass		(attachments, subpasses, deps);

					addFunctionCaseWithPrograms<TestConfig>(allocationTypeGroup.get(), testCaseName.c_str(), testCaseName.c_str(), createTestShaders, renderPassTest, TestConfig(renderPass, render, commandBuffer, imageMemory, targetSize, renderPos, renderSize, 80329, allocationKind));
				}
			}
		}
		group->addChild(allocationTypeGroup.release());
	}
}

void addSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
{
	const UVec2	targetSize	(64, 64);
	const UVec2	renderPos	(0, 0);
	const UVec2	renderSize	(64, 64);

	// color
	{
		const RenderPass	renderPass	(vector<Attachment>(1, Attachment(VK_FORMAT_R8G8B8A8_UNORM,
																		  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_COLOR_ATTACHMENT_OPTIMAL,
																		  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
																	0u,
																	vector<AttachmentReference>(),
																	vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
																	vector<AttachmentReference>(),
																	AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
																	vector<deUint32>())),
										 vector<SubpassDependency>());

		addFunctionCaseWithPrograms<TestConfig>(group, "color", "Single color attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
	}

	// depth
	{
		const RenderPass	renderPass	(vector<Attachment>(1, Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
																		  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_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
																	0u,
																	vector<AttachmentReference>(),
																	vector<AttachmentReference>(),
																	vector<AttachmentReference>(),
																	AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
																	vector<deUint32>())),
										 vector<SubpassDependency>());

		addFunctionCaseWithPrograms<TestConfig>(group, "depth", "Single depth attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
	}

	// stencil
	{
		const RenderPass	renderPass	(vector<Attachment>(1, Attachment(VK_FORMAT_S8_UINT,
																		  VK_SAMPLE_COUNT_1_BIT,
																		  VK_ATTACHMENT_LOAD_OP_DONT_CARE,
																		  VK_ATTACHMENT_STORE_OP_DONT_CARE,
																		  VK_ATTACHMENT_LOAD_OP_CLEAR,
																		  VK_ATTACHMENT_STORE_OP_STORE,
																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
																	0u,
																	vector<AttachmentReference>(),
																	vector<AttachmentReference>(),
																	vector<AttachmentReference>(),
																	AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
																	vector<deUint32>())),
										 vector<SubpassDependency>());

		addFunctionCaseWithPrograms<TestConfig>(group, "stencil", "Single stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
	}

	// depth_stencil
	{
		const RenderPass	renderPass	(vector<Attachment>(1, Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
																		  VK_SAMPLE_COUNT_1_BIT,
																		  VK_ATTACHMENT_LOAD_OP_CLEAR,
																		  VK_ATTACHMENT_STORE_OP_STORE,
																		  VK_ATTACHMENT_LOAD_OP_CLEAR,
																		  VK_ATTACHMENT_STORE_OP_STORE,
																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
																		  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
																	0u,
																	vector<AttachmentReference>(),
																	vector<AttachmentReference>(),
																	vector<AttachmentReference>(),
																	AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
																	vector<deUint32>())),
										 vector<SubpassDependency>());

		addFunctionCaseWithPrograms<TestConfig>(group, "depth_stencil", "Single depth stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
	}

	// color_depth
	{
		const Attachment	attachments[] =
		{
			Attachment(VK_FORMAT_R8G8B8A8_UNORM,
					   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_COLOR_ATTACHMENT_OPTIMAL,
					   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
			Attachment(VK_FORMAT_X8_D24_UNORM_PACK32,
					   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_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
					   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
		};

		const RenderPass	renderPass	(vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
																	0u,
																	vector<AttachmentReference>(),
																	vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
																	vector<AttachmentReference>(),
																	AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
																	vector<deUint32>())),
										 vector<SubpassDependency>());

		addFunctionCaseWithPrograms<TestConfig>(group, "color_depth", "Color and depth attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
	}

	// color_stencil
	{
		const Attachment	attachments[] =
		{
			Attachment(VK_FORMAT_R8G8B8A8_UNORM,
					   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_COLOR_ATTACHMENT_OPTIMAL,
					   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
			Attachment(VK_FORMAT_S8_UINT,
					   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_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
					   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
		};

		const RenderPass	renderPass	(vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
																	0u,
																	vector<AttachmentReference>(),
																	vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
																	vector<AttachmentReference>(),
																	AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
																	vector<deUint32>())),
										 vector<SubpassDependency>());


		addFunctionCaseWithPrograms<TestConfig>(group, "color_stencil", "Color and stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
	}

	// color_depth_stencil
	{
		const Attachment	attachments[] =
		{
			Attachment(VK_FORMAT_R8G8B8A8_UNORM,
					   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_COLOR_ATTACHMENT_OPTIMAL,
					   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL),
			Attachment(VK_FORMAT_D24_UNORM_S8_UINT,
					   VK_SAMPLE_COUNT_1_BIT,
					   VK_ATTACHMENT_LOAD_OP_CLEAR,
					   VK_ATTACHMENT_STORE_OP_STORE,
					   VK_ATTACHMENT_LOAD_OP_CLEAR,
					   VK_ATTACHMENT_STORE_OP_STORE,
					   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
					   VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
		};

		const RenderPass	renderPass	(vector<Attachment>(DE_ARRAY_BEGIN(attachments), DE_ARRAY_END(attachments)),
										 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
																	0u,
																	vector<AttachmentReference>(),
																	vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
																	vector<AttachmentReference>(),
																	AttachmentReference(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
																	vector<deUint32>())),
										 vector<SubpassDependency>());

		addFunctionCaseWithPrograms<TestConfig>(group, "color_depth_stencil", "Color, depth and stencil attachment case.", createTestShaders, renderPassTest, TestConfig(renderPass, TestConfig::RENDERTYPES_DRAW, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
	}
}

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 addFormatTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
{
	tcu::TestContext&	testCtx		= group->getTestContext();

	const UVec2			targetSize	(64, 64);
	const UVec2			renderPos	(0, 0);
	const UVec2			renderSize	(64, 64);

	const struct
	{
		const char* const			str;
		const VkAttachmentStoreOp	op;
	} storeOps[] =
	{
		{ "store",		VK_ATTACHMENT_STORE_OP_STORE		},
		{ "dont_care",	VK_ATTACHMENT_STORE_OP_DONT_CARE	}
	};

	const struct
	{
		const char* const			str;
		const VkAttachmentLoadOp	op;
	} loadOps[] =
	{
		{ "clear",		VK_ATTACHMENT_LOAD_OP_CLEAR		},
		{ "load",		VK_ATTACHMENT_LOAD_OP_LOAD		},
		{ "dont_care",	VK_ATTACHMENT_LOAD_OP_DONT_CARE	}
	};

	const struct
	{
		 const char* const				str;
		 const TestConfig::RenderTypes	types;
	} renderTypes[] =
	{
		{ "clear",		TestConfig::RENDERTYPES_CLEAR								},
		{ "draw",		TestConfig::RENDERTYPES_DRAW								},
		{ "clear_draw",	TestConfig::RENDERTYPES_CLEAR|TestConfig::RENDERTYPES_DRAW	}
	};

	// Color formats
	for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreColorFormats); formatNdx++)
	{
		const VkFormat					format		= s_coreColorFormats[formatNdx];
		de::MovePtr<tcu::TestCaseGroup>	formatGroup	(new tcu::TestCaseGroup(testCtx, formatToName(format).c_str(), de::toString(format).c_str()));

		for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
		{
			const VkAttachmentLoadOp		loadOp	= loadOps[loadOpNdx].op;
			de::MovePtr<tcu::TestCaseGroup>	loadOpGroup	(new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));

			for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
			{
				const RenderPass	renderPass	(vector<Attachment>(1, Attachment(format,
																				  VK_SAMPLE_COUNT_1_BIT,
																				  loadOp,
																				  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)),
												 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
																			0u,
																			vector<AttachmentReference>(),
																			vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
																			vector<AttachmentReference>(),
																			AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
																			vector<deUint32>())),
												 vector<SubpassDependency>());

				addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
			}

			formatGroup->addChild(loadOpGroup.release());
		}

		{
			de::MovePtr<tcu::TestCaseGroup>	inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input"));

			for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
			{
				const VkAttachmentLoadOp		loadOp		= loadOps[loadOpNdx].op;
				de::MovePtr<tcu::TestCaseGroup>	loadOpGroup	(new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));

				for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
				{
					const VkAttachmentStoreOp		storeOp			= storeOps[storeOpNdx].op;
					de::MovePtr<tcu::TestCaseGroup>	storeOpGroup	(new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str));

					for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
					{
						{
							vector<Attachment>			attachments;
							vector<Subpass>				subpasses;
							vector<SubpassDependency>	deps;

							attachments.push_back(Attachment(format,
															 VK_SAMPLE_COUNT_1_BIT,
															 loadOp,
															 storeOp,
															 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
															 VK_ATTACHMENT_STORE_OP_DONT_CARE,
															 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
															 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));

							attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
															 VK_SAMPLE_COUNT_1_BIT,
															 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
															 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));

							subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
														0u,
														vector<AttachmentReference>(),
														vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
														vector<AttachmentReference>(),
														AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
														vector<deUint32>()));
							subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
														0u,
														vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)),
														vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
														vector<AttachmentReference>(),
														AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
														vector<deUint32>()));

							deps.push_back(SubpassDependency(0, 1,

															vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
															vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,

															vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
															vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
															vk::VK_DEPENDENCY_BY_REGION_BIT));

							{
								const RenderPass renderPass (attachments, subpasses, deps);

								addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind));
							}
						}
						{
							vector<Attachment>			attachments;
							vector<Subpass>				subpasses;
							vector<SubpassDependency>	deps;

							attachments.push_back(Attachment(format,
															 VK_SAMPLE_COUNT_1_BIT,
															 loadOp,
															 storeOp,
															 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
															 VK_ATTACHMENT_STORE_OP_DONT_CARE,
															 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
															 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));

							subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
														0u,
														vector<AttachmentReference>(),
														vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
														vector<AttachmentReference>(),
														AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
														vector<deUint32>()));
							subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
														0u,
														vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
														vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_GENERAL)),
														vector<AttachmentReference>(),
														AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
														vector<deUint32>()));

							deps.push_back(SubpassDependency(0, 1,
															vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
															vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,

															vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
															vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
															vk::VK_DEPENDENCY_BY_REGION_BIT));

							{
								const RenderPass renderPass (attachments, subpasses, deps);

								addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), string("self_dep_") + renderTypes[renderTypeNdx].str, string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind));
							}
						}
					}

					loadOpGroup->addChild(storeOpGroup.release());
				}

				inputGroup->addChild(loadOpGroup.release());
			}

			formatGroup->addChild(inputGroup.release());
		}

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

	// Depth stencil formats
	for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(s_coreDepthStencilFormats); formatNdx++)
	{
		const VkFormat					vkFormat		= s_coreDepthStencilFormats[formatNdx];
		de::MovePtr<tcu::TestCaseGroup>	formatGroup	(new tcu::TestCaseGroup(testCtx, formatToName(vkFormat).c_str(), de::toString(vkFormat).c_str()));

		for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
		{
			const VkAttachmentLoadOp		loadOp	= loadOps[loadOpNdx].op;
			de::MovePtr<tcu::TestCaseGroup>	loadOpGroup	(new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));

			for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
			{
				const tcu::TextureFormat	format				= mapVkFormat(vkFormat);
				const bool					isStencilAttachment	= hasStencilComponent(format.order);
				const bool					isDepthAttachment	= hasDepthComponent(format.order);
				const RenderPass			renderPass			(vector<Attachment>(1, Attachment(vkFormat,
																				  VK_SAMPLE_COUNT_1_BIT,
																				  isDepthAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
																				  isDepthAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
																				  isStencilAttachment ? loadOp : VK_ATTACHMENT_LOAD_OP_DONT_CARE,
																				  isStencilAttachment ? VK_ATTACHMENT_STORE_OP_STORE :VK_ATTACHMENT_STORE_OP_DONT_CARE,
																				  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
																				  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)),
												 vector<Subpass>(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
																			0u,
																			vector<AttachmentReference>(),
																			vector<AttachmentReference>(),
																			vector<AttachmentReference>(),
																			AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
																			vector<deUint32>())),
												 vector<SubpassDependency>());

				addFunctionCaseWithPrograms<TestConfig>(loadOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 90239, allocationKind));
			}

			formatGroup->addChild(loadOpGroup.release());
		}

		{
			de::MovePtr<tcu::TestCaseGroup>	inputGroup (new tcu::TestCaseGroup(testCtx, "input", "Test attachment format as input"));

			for (size_t loadOpNdx = 0; loadOpNdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpNdx++)
			{
				const VkAttachmentLoadOp		loadOp		= loadOps[loadOpNdx].op;
				de::MovePtr<tcu::TestCaseGroup>	loadOpGroup	(new tcu::TestCaseGroup(testCtx, loadOps[loadOpNdx].str, loadOps[loadOpNdx].str));

				for (size_t storeOpNdx = 0; storeOpNdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpNdx++)
				{
					const VkAttachmentStoreOp		storeOp			= storeOps[storeOpNdx].op;
					de::MovePtr<tcu::TestCaseGroup>	storeOpGroup	(new tcu::TestCaseGroup(testCtx, storeOps[storeOpNdx].str, storeOps[storeOpNdx].str));

					for (size_t renderTypeNdx = 0; renderTypeNdx < DE_LENGTH_OF_ARRAY(renderTypes); renderTypeNdx++)
					{
						{
							vector<Attachment>			attachments;
							vector<Subpass>				subpasses;
							vector<SubpassDependency>	deps;

							attachments.push_back(Attachment(vkFormat,
															 VK_SAMPLE_COUNT_1_BIT,
															 loadOp,
															 storeOp,
															 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
															 VK_ATTACHMENT_STORE_OP_DONT_CARE,
															 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
															 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));

							attachments.push_back(Attachment(vk::VK_FORMAT_R8G8B8A8_UNORM,
															 VK_SAMPLE_COUNT_1_BIT,
															 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
															 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));

							subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
														0u,
														vector<AttachmentReference>(),
														vector<AttachmentReference>(),
														vector<AttachmentReference>(),
														AttachmentReference(0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
														vector<deUint32>()));
							subpasses.push_back(Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS,
														0u,
														vector<AttachmentReference>(1, AttachmentReference(0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)),
														vector<AttachmentReference>(1, AttachmentReference(1, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)),
														vector<AttachmentReference>(),
														AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
														vector<deUint32>()));

							deps.push_back(SubpassDependency(0, 1,
															vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
															vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,

															vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
															vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
															0u));

							deps.push_back(SubpassDependency(1, 1,
															vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
															vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,

															vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
															vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
															vk::VK_DEPENDENCY_BY_REGION_BIT));
							{
								const RenderPass renderPass (attachments, subpasses, deps);

								addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), renderTypes[renderTypeNdx].str, renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind));
							}
						}
						{
							vector<Attachment>			attachments;
							vector<Subpass>				subpasses;
							vector<SubpassDependency>	deps;

							attachments.push_back(Attachment(vkFormat,
															 VK_SAMPLE_COUNT_1_BIT,
															 loadOp,
															 storeOp,
															 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
															 VK_ATTACHMENT_STORE_OP_DONT_CARE,
															 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
															 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));

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

							deps.push_back(SubpassDependency(0, 1,
															vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
															vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,

															vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
															vk::VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
															vk::VK_DEPENDENCY_BY_REGION_BIT));

							{
								const RenderPass renderPass (attachments, subpasses, deps);

								addFunctionCaseWithPrograms<TestConfig>(storeOpGroup.get(), string("self_dep_") + renderTypes[renderTypeNdx].str, string("self_dep_") + renderTypes[renderTypeNdx].str, createTestShaders, renderPassTest, TestConfig(renderPass, renderTypes[renderTypeNdx].types, TestConfig::COMMANDBUFFERTYPES_INLINE, TestConfig::IMAGEMEMORY_STRICT, targetSize, renderPos, renderSize, 89246, allocationKind));
							}
						}
					}

					loadOpGroup->addChild(storeOpGroup.release());
				}

				inputGroup->addChild(loadOpGroup.release());
			}

			formatGroup->addChild(inputGroup.release());
		}

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

void addRenderPassTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
{
	addTestGroup(group, "simple", "Simple basic render pass tests", addSimpleTests, allocationKind);
	addTestGroup(group, "formats", "Tests for different image formats.", addFormatTests, allocationKind);
	addTestGroup(group, "attachment", "Attachment format and count tests with load and store ops and image layouts", addAttachmentTests, allocationKind);
	addTestGroup(group, "attachment_allocation", "Attachment allocation tests", addAttachmentAllocationTests, allocationKind);
}

de::MovePtr<tcu::TestCaseGroup> createSuballocationTests(tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup>	suballocationTestsGroup(new tcu::TestCaseGroup(testCtx, "suballocation", "Suballocation RenderPass Tests"));

	addRenderPassTests(suballocationTestsGroup.get(), ALLOCATION_KIND_SUBALLOCATED);

	return suballocationTestsGroup;
}

de::MovePtr<tcu::TestCaseGroup> createDedicatedAllocationTests(tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup>	dedicatedAllocationTestsGroup(new tcu::TestCaseGroup(testCtx, "dedicated_allocation", "RenderPass Tests For Dedicated Allocation"));

	addRenderPassTests(dedicatedAllocationTestsGroup.get(), ALLOCATION_KIND_DEDICATED);

	return dedicatedAllocationTestsGroup;
}

} // anonymous

tcu::TestCaseGroup* createRenderPassTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup>	renderpassTests					(new tcu::TestCaseGroup(testCtx, "renderpass", "RenderPass Tests"));
	de::MovePtr<tcu::TestCaseGroup>	suballocationTestGroup			= createSuballocationTests(testCtx);
	de::MovePtr<tcu::TestCaseGroup>	dedicatedAllocationTestGroup	= createDedicatedAllocationTests(testCtx);

	suballocationTestGroup->addChild(createRenderPassMultisampleTests(testCtx));
	suballocationTestGroup->addChild(createRenderPassMultisampleResolveTests(testCtx));

	renderpassTests->addChild(suballocationTestGroup.release());
	renderpassTests->addChild(dedicatedAllocationTestGroup.release());

	return renderpassTests.release();
}

} // vkt
