/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2020 The Khronos Group Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file vktSynchronizationNoneStageTests.cpp
 * \brief Tests for VK_PIPELINE_STAGE_NONE{_2}_KHR that iterate over each writable layout
		  and over each readable layout. Data to tested image is writen using method
		  appropriate for the writable layout and read via readable layout appropriate method.
		  Betwean read and write operation there are bariers that use none stage.
		  Implemented tests are also testing generalized layouts (VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR,
		  VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR) and access flags (MEMORY_ACCESS_READ|WRITE_BIT) to
		  test contextual synchronization introduced with VK_KHR_synchronization2 extension.
 *//*--------------------------------------------------------------------*/

#include "vktSynchronizationNoneStageTests.hpp"
#include "vktSynchronizationOperation.hpp"
#include "vktSynchronizationUtil.hpp"
#include "vktTestCase.hpp"

#include "vkBuilderUtil.hpp"
#include "vkBarrierUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"

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

#include "deUniquePtr.hpp"

#include <vector>

namespace vkt
{
namespace synchronization
{

using namespace vk;
using namespace de;
using namespace tcu;

namespace
{

static const deUint32 IMAGE_ASPECT_DEPTH_STENCIL	= VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
static const deUint32 IMAGE_ASPECT_ALL				= 0u;

struct TestParams
{
	SynchronizationType		type;
	bool					useGenericAccessFlags;
	VkImageLayout			writeLayout;
	VkImageAspectFlags		writeAspect;
	VkImageLayout			readLayout;
	VkImageAspectFlags		readAspect;
};

// Helper class representing image
class ImageWrapper
{
public:

			ImageWrapper	() = default;
	void	create			(Context& context, SimpleAllocator& alloc, VkFormat format, VkExtent3D extent, VkImageUsageFlags usage);

public:
	Move<VkImage>			handle;
	MovePtr<Allocation>		memory;
};

void ImageWrapper::create(Context& context, SimpleAllocator& alloc, VkFormat format, VkExtent3D extent, VkImageUsageFlags usage)
{
	const DeviceInterface&	vk					= context.getDeviceInterface();
	const VkDevice&			device				= context.getDevice();
	const deUint32			queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
	const VkImageCreateInfo imageParams
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// sType
		DE_NULL,								// pNext
		0u,										// flags
		VK_IMAGE_TYPE_2D,						// imageType
		format,									// format
		extent,									// extent
		1u,										// mipLevels
		1u,										// arraySize
		VK_SAMPLE_COUNT_1_BIT,					// samples
		VK_IMAGE_TILING_OPTIMAL,				// tiling
		usage,									// usage
		VK_SHARING_MODE_EXCLUSIVE,				// sharingMode
		1u,										// queueFamilyIndexCount
		&queueFamilyIndex,						// pQueueFamilyIndices
		VK_IMAGE_LAYOUT_UNDEFINED,				// initialLayout
	};

	handle = createImage(vk, device, &imageParams);
	memory = alloc.allocate(getImageMemoryRequirements(vk, device, *handle), MemoryRequirement::Any);

	vk.bindImageMemory(device, *handle, memory->getMemory(), memory->getOffset());
}

// Helper class representing buffer
class BufferWrapper
{
public:

			BufferWrapper	() = default;
	void	create			(Context& context, SimpleAllocator& alloc, VkDeviceSize size, VkBufferUsageFlags usage);

public:
	Move<VkBuffer>			handle;
	MovePtr<Allocation>		memory;
};

void BufferWrapper::create(Context& context, SimpleAllocator& alloc, VkDeviceSize size, VkBufferUsageFlags usage)
{
	const DeviceInterface&		vk					= context.getDeviceInterface();
	const VkDevice&				device				= context.getDevice();
	const VkBufferCreateInfo	bufferCreateInfo	= makeBufferCreateInfo(size, usage);

	handle = createBuffer(vk, device, &bufferCreateInfo);
	memory = alloc.allocate(getBufferMemoryRequirements(vk, device, *handle), MemoryRequirement::HostVisible);

	VK_CHECK(vk.bindBufferMemory(device, *handle, memory->getMemory(), memory->getOffset()));
}

class NoneStageTestInstance : public vkt::TestInstance
{
public:
									NoneStageTestInstance			(Context&			context,
																	 const TestParams&	testParams);
	virtual							~NoneStageTestInstance			(void) = default;

	tcu::TestStatus					iterate							(void) override;

protected:

	VkAccessFlags2KHR				getAccessFlag					(VkAccessFlags2KHR					access);
	VkBufferImageCopy				buildCopyRegion					(VkExtent3D							extent,
																	 VkImageAspectFlags					aspect);
	void							buildVertexBuffer				(void);
	Move<VkRenderPass>				buildBasicRenderPass			(VkFormat							outputFormat,
																	 VkImageLayout						outputLayout,
																	 VkAttachmentLoadOp					loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE);
	Move<VkRenderPass>				buildComplexRenderPass			(VkFormat							intermediateFormat,
																	 VkImageLayout						intermediateLayout,
																	 VkFormat							outputFormat,
																	 VkImageLayout						outputLayout);
	Move<VkImageView>				buildImageView					(VkImage							image,
																	 VkFormat							format,
																	 const VkImageSubresourceRange&		subresourceRange);
	Move<VkFramebuffer>				buildFramebuffer				(VkRenderPass						renderPass,
																	 const VkImageView*					outView1,
																	 const VkImageView*					outView2 = DE_NULL);
	Move<VkSampler>					buildSampler					(void);
	Move<VkDescriptorSetLayout>		buildDescriptorSetLayout		(VkDescriptorType					descriptorType);
	Move<VkDescriptorPool>			buildDescriptorPool				(VkDescriptorType					descriptorType);
	Move<VkDescriptorSet>			buildDescriptorSet				(VkDescriptorPool					descriptorPool,
																	 VkDescriptorSetLayout				descriptorSetLayout,
																	 VkDescriptorType					descriptorType,
																	 VkImageView						inputView,
																	 VkImageLayout						inputLayout,
																	 const VkSampler*					sampler = DE_NULL);
	Move<VkPipeline>				buildPipeline					(deUint32							subpass,
																	 VkImageAspectFlags					resultAspect,
																	 VkPipelineLayout					pipelineLayout,
																	 VkShaderModule						vertShaderModule,
																	 VkShaderModule						fragShaderModule,
																	 VkRenderPass						renderPass);
	bool							verifyResult					(const PixelBufferAccess&			reference,
																	 const PixelBufferAccess&			result);

private:

	const TestParams				m_testParams;

	VkFormat						m_referenceImageFormat;
	VkFormat						m_transitionImageFormat;
	VkFormat						m_readImageFormat;
	VkImageSubresourceRange			m_referenceSubresourceRange;
	VkImageSubresourceRange			m_transitionSubresourceRange;
	VkImageSubresourceRange			m_readSubresourceRange;
	VkImageAspectFlags				m_transitionImageAspect;

	VkExtent3D						m_imageExtent;
	VkImageLayout					m_writeRenderPassOutputLayout;

	// flag indicating that graphics pipeline is constructed to write data to tested image
	bool							m_usePipelineToWrite;

	// flag indicating that graphics pipeline is constructed to read data from tested image
	bool							m_usePipelineToRead;

	// flag indicating that write pipeline should be constructed in a special way to fill stencil buffer
	bool							m_useStencilDuringWrite;

	// flag indicating that read pipeline should be constructed in a special way to use input attachment as a data source
	bool							m_useInputAttachmentToRead;

	VkPipelineStageFlags2KHR		m_srcStageToNoneStageMask;
	VkAccessFlags2KHR				m_srcAccessToNoneAccessMask;
	VkPipelineStageFlags2KHR		m_dstStageFromNoneStageMask;
	VkAccessFlags2KHR				m_dstAccessFromNoneAccessMask;

	SimpleAllocator					m_alloc;

	ImageWrapper					m_referenceImage;
	VkImageUsageFlags				m_referenceImageUsage;

	// objects/variables initialized only when needed
	ImageWrapper					m_imageToWrite;
	VkImageUsageFlags				m_imageToWriteUsage;

	ImageWrapper					m_imageToRead;

	BufferWrapper					m_vertexBuffer;
	std::vector<Move<VkImageView> >	m_attachmentViews;

	std::string						m_writeFragShaderName;
	Move<VkShaderModule>			m_writeVertShaderModule;
	Move<VkShaderModule>			m_writeFragShaderModule;
	Move<VkRenderPass>				m_writeRenderPass;
	Move<VkSampler>					m_writeSampler;
	Move<VkDescriptorSetLayout>		m_writeDescriptorSetLayout;
	Move<VkDescriptorPool>			m_writeDescriptorPool;
	Move<VkDescriptorSet>			m_writeDescriptorSet;
	Move<VkPipelineLayout>			m_writePipelineLayout;
	Move<VkPipeline>				m_writePipeline;
	Move<VkFramebuffer>				m_writeFramebuffer;

	std::string						m_readFragShaderName;
	Move<VkShaderModule>			m_readVertShaderModule;
	Move<VkShaderModule>			m_readFragShaderModule;
	Move<VkShaderModule>			m_readFragShaderModule2;
	Move<VkRenderPass>				m_readRenderPass;
	Move<VkSampler>					m_readSampler;
	Move<VkDescriptorSetLayout>		m_readDescriptorSetLayout;
	Move<VkDescriptorPool>			m_readDescriptorPool;
	Move<VkDescriptorSet>			m_readDescriptorSet;
	Move<VkPipelineLayout>			m_readPipelineLayout;
	Move<VkPipeline>				m_readPipeline;
	Move<VkFramebuffer>				m_readFramebuffer;
};

NoneStageTestInstance::NoneStageTestInstance(Context& context, const TestParams& testParams)
	: vkt::TestInstance(context)
	, m_testParams		(testParams)
	, m_imageExtent		{ 32, 32, 1 }
	, m_alloc			(m_context.getDeviceInterface(),
		m_context.getDevice(),
		getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()))
{
	// note: for clarity whole configuration of whats going on in iterate method was moved here

	const auto writeLayout	= m_testParams.writeLayout;
	const auto writeAspect	= m_testParams.writeAspect;
	const auto readLayout	= m_testParams.readLayout;
	const auto readAspect	= m_testParams.readAspect;

	// select format that will be used for test
	if ((writeAspect == VK_IMAGE_ASPECT_DEPTH_BIT) || (readAspect == VK_IMAGE_ASPECT_DEPTH_BIT))
	{
		m_transitionImageFormat			= VK_FORMAT_D32_SFLOAT;
		m_transitionImageAspect			= VK_IMAGE_ASPECT_DEPTH_BIT;
		m_writeRenderPassOutputLayout	= VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
	}
	else if ((writeAspect == VK_IMAGE_ASPECT_STENCIL_BIT) || (readAspect == VK_IMAGE_ASPECT_STENCIL_BIT))
	{
		m_transitionImageFormat			= VK_FORMAT_S8_UINT;
		m_transitionImageAspect			= VK_IMAGE_ASPECT_STENCIL_BIT;
		m_writeRenderPassOutputLayout	= VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL;
	}
	else if ((writeAspect == IMAGE_ASPECT_DEPTH_STENCIL) || (readAspect == IMAGE_ASPECT_DEPTH_STENCIL))
	{
		m_transitionImageFormat			= VK_FORMAT_D24_UNORM_S8_UINT;
		// note: in test we focus only on depth aspect; no need to check both in those cases
		m_transitionImageAspect			= VK_IMAGE_ASPECT_DEPTH_BIT;
		m_writeRenderPassOutputLayout	= VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
	}
	else
	{
		m_transitionImageFormat			= VK_FORMAT_R8G8B8A8_UNORM;
		m_transitionImageAspect			= VK_IMAGE_ASPECT_COLOR_BIT;
		m_writeRenderPassOutputLayout	= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
	}

	m_referenceSubresourceRange		= { m_transitionImageAspect, 0u, 1u, 0u, 1u };
	m_transitionSubresourceRange	= { m_transitionImageAspect, 0u, 1u, 0u, 1u };
	m_readSubresourceRange			= { m_transitionImageAspect, 0u, 1u, 0u, 1u };
	m_referenceImageFormat			= m_transitionImageFormat;
	m_readImageFormat				= m_transitionImageFormat;
	m_referenceImageUsage			= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
	m_imageToWriteUsage				= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;

	// pipeline is not created for transfer and general layouts (general layouts in tests follow same path as transfer layouts)
	m_usePipelineToWrite	= (writeLayout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) && (writeLayout != VK_IMAGE_LAYOUT_GENERAL);
	m_usePipelineToRead		= (readLayout  != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) && (readLayout  != VK_IMAGE_LAYOUT_GENERAL);
	m_useStencilDuringWrite = false;

	m_srcStageToNoneStageMask		= VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR;
	m_srcAccessToNoneAccessMask		= getAccessFlag(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR);
	m_dstStageFromNoneStageMask		= VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR;
	m_dstAccessFromNoneAccessMask	= getAccessFlag(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR);

	// when graphics pipelines are not created only image with gradient is used for test
	if (!m_usePipelineToWrite && !m_usePipelineToRead)
	{
		m_referenceImageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
		return;
	}

	if (m_usePipelineToWrite)
	{
		// depth/stencil layouts need diferent configuration
		if (writeAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
		{
			if (writeAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
			{
				m_referenceImageFormat					 = VK_FORMAT_R32_SFLOAT;
				m_referenceImageUsage					|= VK_IMAGE_USAGE_SAMPLED_BIT;
				m_referenceSubresourceRange.aspectMask	 = VK_IMAGE_ASPECT_COLOR_BIT;
				m_writeFragShaderName					 = "frag-color-to-depth";
			}
			else
			{
				m_referenceImageUsage					 = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
				m_useStencilDuringWrite					 = true;
				m_writeFragShaderName					 = "frag-color-to-stencil";
			}

			m_srcStageToNoneStageMask		 = VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR;
			m_srcAccessToNoneAccessMask		 = getAccessFlag(VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR);
			m_imageToWriteUsage				|= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
		}
		else
		{
			m_referenceImageUsage			|= VK_IMAGE_USAGE_SAMPLED_BIT;
			m_srcStageToNoneStageMask		 = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR;
			m_srcAccessToNoneAccessMask		 = getAccessFlag(VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR);
			m_writeFragShaderName			 = "frag-color";
			m_imageToWriteUsage				|= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
		}
	}

	if (m_usePipelineToRead)
	{
		m_dstStageFromNoneStageMask		= VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR;
		m_dstAccessFromNoneAccessMask	= getAccessFlag(VK_ACCESS_2_SHADER_READ_BIT_KHR);

		m_readSubresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
		if ((readAspect | writeAspect) & VK_IMAGE_ASPECT_DEPTH_BIT)
			m_readImageFormat = VK_FORMAT_R32_SFLOAT;
		else if ((readAspect | writeAspect) & VK_IMAGE_ASPECT_STENCIL_BIT)
			m_readImageFormat = VK_FORMAT_R8_UINT;

		// for layouts that operate on depth or stencil (not depth_stencil) use input attachment to read
		if ((readAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) && (readAspect != IMAGE_ASPECT_DEPTH_STENCIL))
		{
			m_useInputAttachmentToRead		 = true;
			m_readFragShaderName			 = "frag-depth-or-stencil-to-color";
			m_imageToWriteUsage				|= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
			m_dstAccessFromNoneAccessMask	 = getAccessFlag(VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR);

			if (!m_usePipelineToWrite)
				m_referenceImageUsage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
		}
		else // use image sampler for color and depth_stencil layouts
		{
			m_useInputAttachmentToRead		 = false;
			m_readFragShaderName			 = "frag-color";
			m_referenceImageUsage			|= VK_IMAGE_USAGE_SAMPLED_BIT;
			m_imageToWriteUsage				|= VK_IMAGE_USAGE_SAMPLED_BIT;

			// for depth_stencil layouts we need to have depth_stencil_attachment usage
			if (!m_usePipelineToWrite && (readAspect & VK_IMAGE_ASPECT_STENCIL_BIT))
				m_referenceImageUsage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;

			// when we read stencil as color we need to use usampler2D
			if (writeAspect == VK_IMAGE_ASPECT_STENCIL_BIT)
				m_readFragShaderName		 = "frag-stencil-to-color";
		}
	}
}

VkAccessFlags2KHR NoneStageTestInstance::getAccessFlag(VkAccessFlags2KHR access)
{
	if (m_testParams.useGenericAccessFlags)
	{
		switch (access)
		{
		case VK_ACCESS_2_HOST_READ_BIT_KHR:
		case VK_ACCESS_2_TRANSFER_READ_BIT_KHR:
		case VK_ACCESS_2_SHADER_READ_BIT_KHR:
		case VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR:
			return VK_ACCESS_2_MEMORY_READ_BIT_KHR;

		case VK_ACCESS_2_HOST_WRITE_BIT_KHR:
		case VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR:
		case VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR:
		case VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR:
				return VK_ACCESS_2_MEMORY_WRITE_BIT_KHR;

		default:
			TCU_THROW(TestError, "Unhandled access flag");
		}
	}
	return access;
}

VkBufferImageCopy NoneStageTestInstance::buildCopyRegion(VkExtent3D extent, VkImageAspectFlags aspect)
{
	return
	{
		0u,								// VkDeviceSize					bufferOffset
		extent.width,					// deUint32						bufferRowLength
		extent.height,					// deUint32						bufferImageHeight
		{ aspect, 0u, 0u, 1u },			// VkImageSubresourceLayers		imageSubresource
		{ 0, 0, 0 },					// VkOffset3D					imageOffset
		extent							// VkExtent3D					imageExtent
	};
}

void NoneStageTestInstance::buildVertexBuffer()
{
	const DeviceInterface&	vk		= m_context.getDeviceInterface();
	const VkDevice&			device	= m_context.getDevice();

	std::vector<float> vertices
	{
		 1.0f,  1.0f, 0.0f, 1.0f,
		-1.0f,  1.0f, 0.0f, 1.0f,
		 1.0f, -1.0f, 0.0f, 1.0f,
		-1.0f, -1.0f, 0.0f, 1.0f,
	};
	m_vertexBuffer.create(m_context, m_alloc, sizeof(float) * vertices.size(), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);

	deMemcpy(m_vertexBuffer.memory->getHostPtr(), vertices.data(), vertices.size() * sizeof(float));
	flushAlloc(vk, device, *m_vertexBuffer.memory);
}

Move<VkRenderPass> NoneStageTestInstance::buildBasicRenderPass(VkFormat outputFormat, VkImageLayout outputLayout, VkAttachmentLoadOp loadOp)
{
	// output color/depth attachment
	VkAttachmentDescription2 attachmentDescription
	{
		VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,				// VkStructureType					sType
		DE_NULL,												// const void*						pNext
		(VkAttachmentDescriptionFlags)0,						// VkAttachmentDescriptionFlags		flags
		outputFormat,											// VkFormat							format
		VK_SAMPLE_COUNT_1_BIT,									// VkSampleCountFlagBits			samples
		loadOp,													// VkAttachmentLoadOp				loadOp
		VK_ATTACHMENT_STORE_OP_STORE,							// VkAttachmentStoreOp				storeOp
		loadOp,													// VkAttachmentLoadOp				stencilLoadOp
		VK_ATTACHMENT_STORE_OP_STORE,							// VkAttachmentStoreOp				stencilStoreOp
		VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout					initialLayout
		outputLayout											// VkImageLayout					finalLayout
	};

	VkImageAspectFlags		imageAspect		= getImageAspectFlags(mapVkFormat(outputFormat));
	VkAttachmentReference2	attachmentRef
	{
		VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, DE_NULL, 0u, outputLayout, imageAspect
	};

	VkAttachmentReference2* pColorAttachment			= DE_NULL;
	VkAttachmentReference2* pDepthStencilAttachment		= DE_NULL;
	if (imageAspect == VK_IMAGE_ASPECT_COLOR_BIT)
		pColorAttachment = &attachmentRef;
	else
		pDepthStencilAttachment = &attachmentRef;

	VkSubpassDescription2 subpassDescription
	{
		VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
		DE_NULL,
		(VkSubpassDescriptionFlags)0,							// VkSubpassDescriptionFlags		flags
		VK_PIPELINE_BIND_POINT_GRAPHICS,						// VkPipelineBindPoint				pipelineBindPoint
		0u,														// deUint32							viewMask
		0u,														// deUint32							inputAttachmentCount
		DE_NULL,												// const VkAttachmentReference2*	pInputAttachments
		!!pColorAttachment,										// deUint32							colorAttachmentCount
		pColorAttachment,										// const VkAttachmentReference2*	pColorAttachments
		DE_NULL,												// const VkAttachmentReference2*	pResolveAttachments
		pDepthStencilAttachment,								// const VkAttachmentReference2*	pDepthStencilAttachment
		0u,														// deUint32							preserveAttachmentCount
		DE_NULL													// const deUint32*					pPreserveAttachments
	};

	const VkRenderPassCreateInfo2 renderPassInfo
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
		DE_NULL,												// const void*						pNext
		(VkRenderPassCreateFlags)0,								// VkRenderPassCreateFlags			flags
		1u,														// deUint32							attachmentCount
		&attachmentDescription,									// const VkAttachmentDescription*	pAttachments
		1u,														// deUint32							subpassCount
		&subpassDescription,									// const VkSubpassDescription*		pSubpasses
		0u,														// deUint32							dependencyCount
		DE_NULL,												// const VkSubpassDependency*		pDependencies
		0u,														// deUint32							correlatedViewMaskCount
		DE_NULL													// const deUint32*					pCorrelatedViewMasks
	};

	return vk::createRenderPass2(m_context.getDeviceInterface(), m_context.getDevice(), &renderPassInfo);;
}

Move<VkRenderPass> NoneStageTestInstance::buildComplexRenderPass(VkFormat intermediateFormat,	VkImageLayout intermediateLayout,
																 VkFormat outputFormat,			VkImageLayout outputLayout)
{
	std::vector<VkAttachmentDescription2> attachmentDescriptions
	{
		// depth/stencil attachment (when used in read pipeline it loads data filed in write pipeline)
		{
			VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,				// VkStructureType					sType
			DE_NULL,												// const void*						pNext
			(VkAttachmentDescriptionFlags)0,						// VkAttachmentDescriptionFlags		flags
			intermediateFormat,										// VkFormat							format
			VK_SAMPLE_COUNT_1_BIT,									// VkSampleCountFlagBits			samples
			VK_ATTACHMENT_LOAD_OP_LOAD,								// VkAttachmentLoadOp				loadOp
			VK_ATTACHMENT_STORE_OP_STORE,							// VkAttachmentStoreOp				storeOp
			VK_ATTACHMENT_LOAD_OP_DONT_CARE,						// VkAttachmentLoadOp				stencilLoadOp
			VK_ATTACHMENT_STORE_OP_STORE,							// VkAttachmentStoreOp				stencilStoreOp
			intermediateLayout,										// VkImageLayout					initialLayout
			intermediateLayout										// VkImageLayout					finalLayout
		},
		// color attachment
		{
			VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,				// VkStructureType					sType
			DE_NULL,												// const void*						pNext
			(VkAttachmentDescriptionFlags)0,						// VkAttachmentDescriptionFlags		flags
			outputFormat,											// VkFormat							format
			VK_SAMPLE_COUNT_1_BIT,									// VkSampleCountFlagBits			samples
			VK_ATTACHMENT_LOAD_OP_DONT_CARE,						// VkAttachmentLoadOp				loadOp
			VK_ATTACHMENT_STORE_OP_STORE,							// VkAttachmentStoreOp				storeOp
			VK_ATTACHMENT_LOAD_OP_DONT_CARE,						// VkAttachmentLoadOp				stencilLoadOp
			VK_ATTACHMENT_STORE_OP_DONT_CARE,						// VkAttachmentStoreOp				stencilStoreOp
			VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout					initialLayout
			outputLayout											// VkImageLayout					finalLayout
		}
	};

	VkImageAspectFlags					intermediateAspect	= getImageAspectFlags(mapVkFormat(intermediateFormat));
	VkImageAspectFlags					outputAspect		= getImageAspectFlags(mapVkFormat(outputFormat));
	std::vector<VkAttachmentReference2>	attachmentRefs
	{
		{ VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, DE_NULL, 0u, intermediateLayout, intermediateAspect },
		{ VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, DE_NULL, 1u, outputLayout, outputAspect }
	};

	VkAttachmentReference2* pDepthStencilAttachment = &attachmentRefs[0];
	VkAttachmentReference2* pColorAttachment		= &attachmentRefs[1];

	std::vector<VkSubpassDescription2> subpassDescriptions
	{
		{
			VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
			DE_NULL,
			(VkSubpassDescriptionFlags)0,						// VkSubpassDescriptionFlags		flags
			VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint
			0u,													// deUint32							viewMask
			1u,													// deUint32							inputAttachmentCount
			pDepthStencilAttachment,							// const VkAttachmentReference2*	pInputAttachments
			1u,													// deUint32							colorAttachmentCount
			pColorAttachment,									// const VkAttachmentReference2*	pColorAttachments
			DE_NULL,											// const VkAttachmentReference2*	pResolveAttachments
			DE_NULL,											// const VkAttachmentReference2*	pDepthStencilAttachment
			0u,													// deUint32							preserveAttachmentCount
			DE_NULL												// deUint32*						pPreserveAttachments
		}
	};

	const VkRenderPassCreateInfo2 renderPassInfo
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
		DE_NULL,												// const void*						pNext
		(VkRenderPassCreateFlags)0,								// VkRenderPassCreateFlags			flags
		(deUint32)attachmentDescriptions.size(),				// deUint32							attachmentCount
		attachmentDescriptions.data(),							// const VkAttachmentDescription*	pAttachments
		(deUint32)subpassDescriptions.size(),					// deUint32							subpassCount
		subpassDescriptions.data(),								// const VkSubpassDescription*		pSubpasses
		0u,														// deUint32							dependencyCount
		DE_NULL,												// const VkSubpassDependency*		pDependencies
		0u,														// deUint32							correlatedViewMaskCount
		DE_NULL													// const deUint32*					pCorrelatedViewMasks
	};

	return vk::createRenderPass2(m_context.getDeviceInterface(), m_context.getDevice(), &renderPassInfo);
}

Move<VkImageView> NoneStageTestInstance::buildImageView(VkImage image, VkFormat format, const VkImageSubresourceRange& subresourceRange)
{
	const DeviceInterface&	vk		= m_context.getDeviceInterface();
	const VkDevice&			device	= m_context.getDevice();

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

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

Move<VkFramebuffer> NoneStageTestInstance::buildFramebuffer(VkRenderPass renderPass, const VkImageView* outView1, const VkImageView* outView2)
{
	const DeviceInterface&	vk		= m_context.getDeviceInterface();
	const VkDevice&			device	= m_context.getDevice();

	std::vector<VkImageView> imageViews = { *outView1 };
	if (outView2)
		imageViews.push_back(*outView2);

	const VkFramebufferCreateInfo framebufferParams
	{
		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,				// VkStructureType				sType
		DE_NULL,												// const void*					pNext
		0u,														// VkFramebufferCreateFlags		flags
		renderPass,												// VkRenderPass					renderPass
		(deUint32)imageViews.size(),							// deUint32						attachmentCount
		imageViews.data(),										// const VkImageView*			pAttachments
		m_imageExtent.width,									// deUint32						width
		m_imageExtent.height,									// deUint32						height
		1u,														// deUint32						layers
	};
	return createFramebuffer(vk, device, &framebufferParams);
}

Move<VkSampler> NoneStageTestInstance::buildSampler()
{
	const DeviceInterface&	vk		= m_context.getDeviceInterface();
	const VkDevice&			device	= m_context.getDevice();

	const VkSamplerCreateInfo samplerInfo
	{
		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,					// VkStructureType				sType
		DE_NULL,												// const void*					pNext
		0u,														// VkSamplerCreateFlags			flags
		VK_FILTER_NEAREST,										// VkFilter						magFilter
		VK_FILTER_NEAREST,										// VkFilter						minFilter
		VK_SAMPLER_MIPMAP_MODE_NEAREST,							// VkSamplerMipmapMode			mipmapMode
		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,					// VkSamplerAddressMode			addressModeU
		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,					// VkSamplerAddressMode			addressModeV
		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,					// VkSamplerAddressMode			addressModeW
		0.0f,													// float						mipLodBias
		VK_FALSE,												// VkBool32						anisotropyEnable
		1.0f,													// float						maxAnisotropy
		DE_FALSE,												// VkBool32						compareEnable
		VK_COMPARE_OP_ALWAYS,									// VkCompareOp					compareOp
		0.0f,													// float						minLod
		0.0f,													// float						maxLod
		VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,				// VkBorderColor				borderColor
		VK_FALSE,												// VkBool32						unnormalizedCoords
	};
	return createSampler(vk, device, &samplerInfo);
}

Move<VkDescriptorSetLayout> NoneStageTestInstance::buildDescriptorSetLayout(VkDescriptorType descriptorType)
{
	const DeviceInterface&		vk		= m_context.getDeviceInterface();
	const VkDevice&				device	= m_context.getDevice();

	return
		DescriptorSetLayoutBuilder()
		.addSingleSamplerBinding(descriptorType, VK_SHADER_STAGE_FRAGMENT_BIT, DE_NULL)
		.build(vk, device);
}

Move<VkDescriptorPool> NoneStageTestInstance::buildDescriptorPool(VkDescriptorType descriptorType)
{
	const DeviceInterface&		vk		= m_context.getDeviceInterface();
	const VkDevice&				device	= m_context.getDevice();

	return
		DescriptorPoolBuilder()
		.addType(descriptorType, 1u)
		.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
}

Move<VkDescriptorSet> NoneStageTestInstance::buildDescriptorSet(VkDescriptorPool		descriptorPool,
																VkDescriptorSetLayout	descriptorSetLayout,
																VkDescriptorType		descriptorType,
																VkImageView				inputView,
																VkImageLayout			inputLayout,
																const VkSampler*		sampler)
{
	const DeviceInterface&		vk				= m_context.getDeviceInterface();
	const VkDevice&				device			= m_context.getDevice();

	const VkDescriptorImageInfo inputImageInfo	= makeDescriptorImageInfo(sampler ? *sampler : 0u, inputView, inputLayout);
	Move<VkDescriptorSet>		descriptorSet	= makeDescriptorSet(vk, device, descriptorPool, descriptorSetLayout);

	DescriptorSetUpdateBuilder()
		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &inputImageInfo)
		.update(vk, device);

	return descriptorSet;
}

Move<VkPipeline> NoneStageTestInstance::buildPipeline(deUint32				subpass,
													  VkImageAspectFlags	resultAspect,
													  VkPipelineLayout		pipelineLayout,
													  VkShaderModule		vertShaderModule,
													  VkShaderModule		fragShaderModule,
													  VkRenderPass			renderPass)
{
	const DeviceInterface&			vk				= m_context.getDeviceInterface();
	const VkDevice&					device			= m_context.getDevice();
	const std::vector<VkViewport>	viewports		{ makeViewport(m_imageExtent) };
	const std::vector<VkRect2D>		scissors		{ makeRect2D(m_imageExtent) };
	const bool						useDepth		= resultAspect & VK_IMAGE_ASPECT_DEPTH_BIT;
	const bool						useStencil		= resultAspect & VK_IMAGE_ASPECT_STENCIL_BIT;

	const VkStencilOpState stencilOpState = makeStencilOpState(
		VK_STENCIL_OP_REPLACE,											// stencil fail
		VK_STENCIL_OP_REPLACE,											// depth & stencil pass
		VK_STENCIL_OP_REPLACE,											// depth only fail
		VK_COMPARE_OP_ALWAYS,											// compare op
		1u,																// compare mask
		1u,																// write mask
		1u);															// reference

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

	return makeGraphicsPipeline(
		vk,																// DeviceInterface&								vk
		device,															// VkDevice										device
		pipelineLayout,													// VkPipelineLayout								pipelineLayout
		vertShaderModule,												// VkShaderModule								vertexShaderModule
		DE_NULL,														// VkShaderModule								tessellationControlModule
		DE_NULL,														// VkShaderModule								tessellationEvalModule
		DE_NULL,														// VkShaderModule								geometryShaderModule
		fragShaderModule,												// VkShaderModule								fragmentShaderModule
		renderPass,														// VkRenderPass									renderPass
		viewports,														// std::vector<VkViewport>&						viewports
		scissors,														// std::vector<VkRect2D>&						scissors
		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,							// VkPrimitiveTopology							topology
		subpass,														// deUint32										subpass
		0u,																// deUint32										patchControlPoints
		DE_NULL,														// VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
		DE_NULL,														// VkPipelineRasterizationStateCreateInfo*		rasterizationStateCreateInfo
		DE_NULL,														// VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
		&depthStencilStateCreateInfo);									// VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
}

tcu::TestStatus NoneStageTestInstance::iterate(void)
{
	const DeviceInterface&		vk						= m_context.getDeviceInterface();
	const VkDevice&				device					= m_context.getDevice();
	const deUint32				queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
	VkQueue						queue					= m_context.getUniversalQueue();
	Move<VkCommandPool>			cmdPool					= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
	Move<VkCommandBuffer>		cmdBuffer				= makeCommandBuffer(vk, device, *cmdPool);
	const VkDeviceSize			vertexBufferOffset		= 0;
	ImageWrapper*				transitionImagePtr		= &m_referenceImage;
	ImageWrapper*				imageToVerifyPtr		= &m_referenceImage;
	const deUint32				imageSizeInBytes		= m_imageExtent.width * m_imageExtent.height * 4;
	SynchronizationWrapperPtr	synchronizationWrapper	= getSynchronizationWrapper(m_testParams.type, vk, false);
	const VkRect2D				renderArea				= makeRect2D(0, 0, m_imageExtent.width, m_imageExtent.height);
	const VkBufferImageCopy		transitionCopyRegion	= buildCopyRegion(m_imageExtent, m_transitionImageAspect);
	const VkBufferImageCopy		colorCopyRegion			= buildCopyRegion(m_imageExtent, VK_IMAGE_ASPECT_COLOR_BIT);

	// create image that will have gradient (without data atm)
	m_referenceImage.create(m_context, m_alloc, m_referenceImageFormat, m_imageExtent, m_referenceImageUsage);

	// create buffer used for gradient data source
	BufferWrapper srcBuffer;
	srcBuffer.create(m_context, m_alloc, imageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);

	// generate gradient
	std::vector<deUint32>	referenceData	(m_imageExtent.width * m_imageExtent.height);
	tcu::TextureFormat		referenceFormat	(mapVkFormat(m_referenceImageFormat));
	PixelBufferAccess		referencePBA	(referenceFormat, m_imageExtent.width, m_imageExtent.height, m_imageExtent.depth, referenceData.data());
	fillWithComponentGradients(referencePBA, tcu::Vec4(0.0f), tcu::Vec4(1.0f));
	deMemcpy(srcBuffer.memory->getHostPtr(), referenceData.data(), static_cast<size_t>(imageSizeInBytes));
	flushAlloc(vk, device, *srcBuffer.memory);

	// create buffer for result transfer
	BufferWrapper			dstBuffer;
	tcu::TextureFormat		resultFormat	(mapVkFormat(m_readImageFormat));
	dstBuffer.create(m_context, m_alloc, imageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);

	if (m_usePipelineToWrite || m_usePipelineToRead)
	{
		buildVertexBuffer();

		// create image view for reference image (its always at index 0)
		m_attachmentViews.push_back(buildImageView(*m_referenceImage.handle, m_referenceImageFormat, m_referenceSubresourceRange));

		// create graphics pipeline used to write image data
		if (m_usePipelineToWrite)
		{
			// create image that will be used as attachment to write to
			m_imageToWrite.create(m_context, m_alloc, m_transitionImageFormat, m_imageExtent, m_imageToWriteUsage);
			m_attachmentViews.push_back(buildImageView(*m_imageToWrite.handle, m_transitionImageFormat, m_transitionSubresourceRange));

			m_writeVertShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0);
			m_writeFragShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get(m_writeFragShaderName), 0);

			if (m_useStencilDuringWrite)
			{
				// this is used only for cases where writable layout is VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL
				// in this case generated gradient is only used for verification
				m_writeRenderPass			= buildBasicRenderPass(m_transitionImageFormat, m_writeRenderPassOutputLayout, VK_ATTACHMENT_LOAD_OP_CLEAR);
				m_writePipelineLayout		= makePipelineLayout(vk, device, DE_NULL);
				m_writePipeline				= buildPipeline(0u, m_transitionImageAspect, *m_writePipelineLayout,
															*m_writeVertShaderModule, *m_writeFragShaderModule, *m_writeRenderPass);
				m_writeFramebuffer			= buildFramebuffer(*m_writeRenderPass, &m_attachmentViews[1].get());
			}
			else
			{
				m_writeRenderPass			= buildBasicRenderPass(m_transitionImageFormat, m_writeRenderPassOutputLayout);
				m_writeSampler				= buildSampler();
				m_writeDescriptorSetLayout	= buildDescriptorSetLayout(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
				m_writeDescriptorPool		= buildDescriptorPool(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
				m_writeDescriptorSet		= buildDescriptorSet(*m_writeDescriptorPool, *m_writeDescriptorSetLayout, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
																 *m_attachmentViews[0], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, &m_writeSampler.get());
				m_writePipelineLayout		= makePipelineLayout(vk, device, *m_writeDescriptorSetLayout);
				m_writePipeline				= buildPipeline(0u, m_transitionImageAspect, *m_writePipelineLayout,
															*m_writeVertShaderModule, *m_writeFragShaderModule, *m_writeRenderPass);
				m_writeFramebuffer			= buildFramebuffer(*m_writeRenderPass, &m_attachmentViews[1].get());
			}

			transitionImagePtr	= &m_imageToWrite;
			imageToVerifyPtr	= &m_imageToWrite;
		}

		// create graphics pipeline used to read image data
		if (m_usePipelineToRead)
		{
			m_imageToRead.create(m_context, m_alloc, m_readImageFormat, m_imageExtent, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
			m_attachmentViews.push_back(buildImageView(*m_imageToRead.handle, m_readImageFormat, m_readSubresourceRange));
			imageToVerifyPtr = &m_imageToRead;

			m_readVertShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0);
			m_readFragShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get(m_readFragShaderName), 0);

			if (m_useInputAttachmentToRead)
			{
				m_readDescriptorSetLayout	= buildDescriptorSetLayout(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
				m_readDescriptorPool		= buildDescriptorPool(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
				m_readDescriptorSet			= buildDescriptorSet(*m_readDescriptorPool, *m_readDescriptorSetLayout, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
																 *m_attachmentViews[m_usePipelineToWrite], m_testParams.readLayout);
				m_readRenderPass			= buildComplexRenderPass(m_transitionImageFormat, m_testParams.readLayout,
																	 m_readImageFormat, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
				m_readFramebuffer			= buildFramebuffer(*m_readRenderPass, &m_attachmentViews[m_usePipelineToWrite].get(),
																				  &m_attachmentViews[m_usePipelineToWrite+1].get());
				m_readPipelineLayout		= makePipelineLayout(vk, device, *m_readDescriptorSetLayout);
				m_readPipeline				= buildPipeline(0u, VK_IMAGE_ASPECT_COLOR_BIT, *m_readPipelineLayout,
															*m_readVertShaderModule, *m_readFragShaderModule, *m_readRenderPass);
			}
			else
			{
				m_readSampler				= buildSampler();
				m_readDescriptorSetLayout	= buildDescriptorSetLayout(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
				m_readDescriptorPool		= buildDescriptorPool(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
				m_readDescriptorSet			= buildDescriptorSet(*m_readDescriptorPool, *m_readDescriptorSetLayout, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
																 *m_attachmentViews[m_usePipelineToWrite], m_testParams.readLayout, &m_readSampler.get());
				m_readRenderPass			= buildBasicRenderPass(m_readImageFormat, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
				m_readFramebuffer			= buildFramebuffer(*m_readRenderPass, &m_attachmentViews[m_usePipelineToWrite + 1].get());
				m_readPipelineLayout		= makePipelineLayout(vk, device, *m_readDescriptorSetLayout);
				m_readPipeline				= buildPipeline(0u, m_transitionImageAspect, *m_readPipelineLayout,
															*m_readVertShaderModule, *m_readFragShaderModule, *m_readRenderPass);
			}
		}
	}

	beginCommandBuffer(vk, *cmdBuffer);

	// write data from buffer with gradient to image (for stencil_attachment cases we dont need to do that)
	if (!m_useStencilDuringWrite)
	{
		// wait for reference data to be in buffer
		const VkBufferMemoryBarrier2KHR preBufferMemoryBarrier2 = makeBufferMemoryBarrier2(
			VK_PIPELINE_STAGE_2_HOST_BIT_KHR,					// VkPipelineStageFlags2KHR			srcStageMask
			getAccessFlag(VK_ACCESS_2_HOST_WRITE_BIT_KHR),		// VkAccessFlags2KHR				srcAccessMask
			VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,				// VkPipelineStageFlags2KHR			dstStageMask
			getAccessFlag(VK_ACCESS_2_TRANSFER_READ_BIT_KHR),	// VkAccessFlags2KHR				dstAccessMask
			*srcBuffer.handle,									// VkBuffer							buffer
			0u,													// VkDeviceSize						offset
			imageSizeInBytes									// VkDeviceSize						size
		);

		VkImageLayout copyBufferToImageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
		if(m_testParams.writeLayout == VK_IMAGE_LAYOUT_GENERAL)
			copyBufferToImageLayout = VK_IMAGE_LAYOUT_GENERAL;

		// change image layout so that we can copy to it data from buffer
		const VkImageMemoryBarrier2KHR preImageMemoryBarrier2 = makeImageMemoryBarrier2(
			VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,				// VkPipelineStageFlags2KHR			srcStageMask
			getAccessFlag(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR),	// VkAccessFlags2KHR				srcAccessMask
			VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,				// VkPipelineStageFlags2KHR			dstStageMask
			getAccessFlag(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR),	// VkAccessFlags2KHR				dstAccessMask
			VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout					oldLayout
			copyBufferToImageLayout,							// VkImageLayout					newLayout
			*m_referenceImage.handle,							// VkImage							image
			m_referenceSubresourceRange							// VkImageSubresourceRange			subresourceRange
		);
		VkDependencyInfoKHR buffDependencyInfo = makeCommonDependencyInfo(DE_NULL, &preBufferMemoryBarrier2, &preImageMemoryBarrier2);
		synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &buffDependencyInfo);

		const VkBufferImageCopy* copyRegion = m_usePipelineToWrite ? &colorCopyRegion : &transitionCopyRegion;
		vk.cmdCopyBufferToImage(*cmdBuffer, *srcBuffer.handle, *m_referenceImage.handle, copyBufferToImageLayout, 1u, copyRegion);
	}

	if (m_usePipelineToWrite)
	{
		// wait till data is transfered to image (in all cases except when stencil_attachment is tested)
		if (!m_useStencilDuringWrite)
		{
			const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
				VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,				// VkPipelineStageFlags2KHR			srcStageMask
				getAccessFlag(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR),	// VkAccessFlags2KHR				srcAccessMask
				VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR,		// VkPipelineStageFlags2KHR			dstStageMask
				getAccessFlag(VK_ACCESS_2_SHADER_READ_BIT_KHR),		// VkAccessFlags2KHR				dstAccessMask
				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout					oldLayout
				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,			// VkImageLayout					newLayout
				*m_referenceImage.handle,							// VkImage							image
				m_referenceSubresourceRange							// VkImageSubresourceRange			subresourceRange
			);
			VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
			synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &dependencyInfo);
		}

		beginRenderPass(vk, *cmdBuffer, *m_writeRenderPass, *m_writeFramebuffer, renderArea, tcu::Vec4(0.0f ,0.0f, 0.0f, 1.0f));

		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_writePipeline);
		vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &m_vertexBuffer.handle.get(), &vertexBufferOffset);
		if (m_useStencilDuringWrite)
		{
			// when writing to stencil buffer draw single triangle (to simulate gradient over 1bit)
			vk.cmdDraw(*cmdBuffer, 3u, 1u, 0u, 0u);
		}
		else
		{
			vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_writePipelineLayout, 0, 1, &m_writeDescriptorSet.get(), 0, DE_NULL);
			vk.cmdDraw(*cmdBuffer, 4u, 1u, 0u, 0u);
		}

		endRenderPass(vk, *cmdBuffer);
	}

	// use none stage to wait till data is transfered to image
	{
		const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
			m_srcStageToNoneStageMask,							// VkPipelineStageFlags2KHR			srcStageMask
			m_srcAccessToNoneAccessMask,						// VkAccessFlags2KHR				srcAccessMask
			VK_PIPELINE_STAGE_2_NONE_KHR,						// VkPipelineStageFlags2KHR			dstStageMask
			VK_ACCESS_2_NONE_KHR,								// VkAccessFlags2KHR				dstAccessMask
			m_testParams.writeLayout,							// VkImageLayout					oldLayout
			m_testParams.writeLayout,							// VkImageLayout					newLayout
			*transitionImagePtr->handle,						// VkImage							image
			m_transitionSubresourceRange						// VkImageSubresourceRange			subresourceRange
		);
		VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
		synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &dependencyInfo);
	}

	// use all commands stage to change image layout
	{
		const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
			VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR,			// VkPipelineStageFlags2KHR			srcStageMask
			VK_ACCESS_2_NONE_KHR,								// VkAccessFlags2KHR				srcAccessMask
			m_dstStageFromNoneStageMask,						// VkPipelineStageFlags2KHR			dstStageMask
			m_dstAccessFromNoneAccessMask,						// VkAccessFlags2KHR				dstAccessMask
			m_testParams.writeLayout,							// VkImageLayout					oldLayout
			m_testParams.readLayout,							// VkImageLayout					newLayout
			*transitionImagePtr->handle,						// VkImage							image
			m_transitionSubresourceRange						// VkImageSubresourceRange			subresourceRange
		);
		VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
		synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &dependencyInfo);
	}

	VkImageLayout copyImageToBufferLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
	if (m_testParams.readLayout == VK_IMAGE_LAYOUT_GENERAL)
		copyImageToBufferLayout = VK_IMAGE_LAYOUT_GENERAL;

	if (m_usePipelineToRead)
	{
		beginRenderPass(vk, *cmdBuffer, *m_readRenderPass, *m_readFramebuffer, renderArea);

		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_readPipeline);
		vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_readPipelineLayout, 0, 1, &m_readDescriptorSet.get(), 0, DE_NULL);
		vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &m_vertexBuffer.handle.get(), &vertexBufferOffset);
		vk.cmdDraw(*cmdBuffer, 4u, 1u, 0u, 0u);

		endRenderPass(vk, *cmdBuffer);

		// wait till data is transfered to image
		const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
			VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR,	// VkPipelineStageFlags2KHR			srcStageMask
			VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR,				// VkAccessFlags2KHR				srcAccessMask
			VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,					// VkPipelineStageFlags2KHR			dstStageMask
			getAccessFlag(VK_ACCESS_2_TRANSFER_READ_BIT_KHR),		// VkAccessFlags2KHR				dstAccessMask
			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				// VkImageLayout					oldLayout
			copyImageToBufferLayout,								// VkImageLayout					newLayout
			*imageToVerifyPtr->handle,								// VkImage							image
			m_readSubresourceRange									// VkImageSubresourceRange			subresourceRange
		);
		VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
		synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &dependencyInfo);
	}

	// read back image
	{
		const VkBufferImageCopy* copyRegion = m_usePipelineToRead ? &colorCopyRegion : &transitionCopyRegion;
		vk.cmdCopyImageToBuffer(*cmdBuffer, *imageToVerifyPtr->handle, copyImageToBufferLayout, *dstBuffer.handle, 1u, copyRegion);

		const VkBufferMemoryBarrier2KHR postBufferMemoryBarrier2 = makeBufferMemoryBarrier2(
			VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,				// VkPipelineStageFlags2KHR			srcStageMask
			getAccessFlag(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR),	// VkAccessFlags2KHR				srcAccessMask
			VK_PIPELINE_STAGE_2_HOST_BIT_KHR,					// VkPipelineStageFlags2KHR			dstStageMask
			getAccessFlag(VK_ACCESS_2_HOST_READ_BIT_KHR),		// VkAccessFlags2KHR				dstAccessMask
			*dstBuffer.handle,									// VkBuffer							buffer
			0u,													// VkDeviceSize						offset
			imageSizeInBytes									// VkDeviceSize						size
		);
		VkDependencyInfoKHR bufDependencyInfo = makeCommonDependencyInfo(DE_NULL, &postBufferMemoryBarrier2);
		synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &bufDependencyInfo);
	}

	endCommandBuffer(vk, *cmdBuffer);

	Move<VkFence>					fence			= createFence(vk, device);
	VkCommandBufferSubmitInfoKHR	cmdBuffersInfo	= makeCommonCommandBufferSubmitInfo(*cmdBuffer);
	synchronizationWrapper->addSubmitInfo(0u, DE_NULL, 1u, &cmdBuffersInfo, 0u, DE_NULL);
	VK_CHECK(synchronizationWrapper->queueSubmit(queue, *fence));
	VK_CHECK(vk.waitForFences(device, 1, &fence.get(), VK_TRUE, ~0ull));

	// read image data
	invalidateAlloc(vk, device, *dstBuffer.memory);
	PixelBufferAccess resultPBA(resultFormat, m_imageExtent.width, m_imageExtent.height, m_imageExtent.depth, dstBuffer.memory->getHostPtr());

	// if result/reference is depth-stencil format then focus only on depth component
	if (isCombinedDepthStencilType(referenceFormat.type))
		referencePBA = getEffectiveDepthStencilAccess(referencePBA, tcu::Sampler::MODE_DEPTH);
	if (isCombinedDepthStencilType(resultFormat.type))
		resultPBA = getEffectiveDepthStencilAccess(resultPBA, tcu::Sampler::MODE_DEPTH);

	if (verifyResult(referencePBA, resultPBA))
		return TestStatus::pass("Pass");
	return TestStatus::fail("Fail");
}

bool NoneStageTestInstance::verifyResult(const PixelBufferAccess& reference, const PixelBufferAccess& result)
{
	TestLog& log = m_context.getTestContext().getLog();

	if (isIntFormat(m_referenceImageFormat) || isUintFormat(m_referenceImageFormat))
	{
		// special case for stencil (1bit gradient - top-left of image is 0, bottom-right is 1)

		bool				isResultCorrect = true;
		TextureLevel		errorMaskStorage(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8),
											 m_imageExtent.width, m_imageExtent.height, 1);
		PixelBufferAccess	errorMask		= errorMaskStorage.getAccess();

		for (deUint32 y = 0; y < m_imageExtent.height; y++)
			for (deUint32 x = 0; x < m_imageExtent.width; x++)
			{
				// skip textels on diagonal (gradient lights texels on diagonal and stencil operation in test does not)
				if ((x + y) == (m_imageExtent.width - 1))
				{
					errorMask.setPixel(IVec4(0, 0xff, 0, 0xff), x, y, 0);
					continue;
				}

				IVec4	refPix = reference.getPixelInt(x, y, 0);
				IVec4	cmpPix = result.getPixelInt(x, y, 0);
				bool	isOk = (refPix[0] == cmpPix[0]);
				errorMask.setPixel(isOk ? IVec4(0, 0xff, 0, 0xff) : IVec4(0xff, 0, 0, 0xff), x, y, 0);
				isResultCorrect &= isOk;
			}

		Vec4 pixelBias(0.0f);
		Vec4 pixelScale(1.0f);
		if (isResultCorrect)
		{
			log << TestLog::ImageSet("Image comparison", "")
				<< TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
				<< TestLog::EndImageSet;
			return true;
		}

		log << TestLog::ImageSet("Image comparison", "")
			<< TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
			<< TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
			<< TestLog::Image("ErrorMask", "Error mask", errorMask)
			<< TestLog::EndImageSet;
		return false;
	}

	return floatThresholdCompare(log, "Image comparison", "", reference, result, tcu::Vec4(0.01f), tcu::COMPARE_LOG_RESULT);
}

class NoneStageTestCase : public vkt::TestCase
{
public:
							NoneStageTestCase		(tcu::TestContext&		testContext,
													 const std::string&		name,
													 const TestParams&		testParams);
							~NoneStageTestCase		(void) = default;

	void					initPrograms			(SourceCollections&		sourceCollections) const override;
	TestInstance*			createInstance			(Context&				context) const override;
	void					checkSupport			(Context&				context) const override;

private:
	const TestParams		m_testParams;
};

NoneStageTestCase::NoneStageTestCase(tcu::TestContext&	testContext, const std::string&	name, const TestParams&	testParams)
	: vkt::TestCase	(testContext, name, "")
	, m_testParams	(testParams)
{
}

void NoneStageTestCase::initPrograms(SourceCollections& sourceCollections) const
{
	const auto writeLayout	= m_testParams.writeLayout;
	const auto writeAspect	= m_testParams.writeAspect;
	const auto readLayout	= m_testParams.readLayout;
	const auto readAspect	= m_testParams.readAspect;

	// for tests that use only transfer and general layouts we don't create pipeline
	if (((writeLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) || (readLayout == VK_IMAGE_LAYOUT_GENERAL)) &&
		((writeLayout == VK_IMAGE_LAYOUT_GENERAL) || (readLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)))
		return;

	sourceCollections.glslSources.add("vert") << glu::VertexSource(
		"#version 450\n"
		"layout(location = 0) in  vec4 inPosition;\n"
		"layout(location = 0) out vec2 outUV;\n"
		"void main(void)\n"
		"{\n"
		"  outUV = vec2(inPosition.x * 0.5 + 0.5, inPosition.y * 0.5 + 0.5);\n"
		"  gl_Position = inPosition;\n"
		"}\n"
	);

	sourceCollections.glslSources.add("frag-color") << glu::FragmentSource(
		"#version 450\n"
		"layout(binding = 0) uniform sampler2D u_sampler;\n"
		"layout(location = 0) in vec2 inUV;\n"
		"layout(location = 0) out vec4 fragColor;\n"
		"void main(void)\n"
		"{\n"
		"  fragColor = texture(u_sampler, inUV);\n"
		"}\n"
	);

	if (writeAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
	{
		sourceCollections.glslSources.add("frag-color-to-depth") << glu::FragmentSource(
			"#version 450\n"
			"layout(binding = 0) uniform sampler2D u_sampler;\n"
			"layout(location = 0) in vec2 inUV;\n"
			"void main(void)\n"
			"{\n"
			"  gl_FragDepth = texture(u_sampler, inUV).r;\n"
			"}\n"
		);
	}

	if (writeAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
	{
		sourceCollections.glslSources.add("frag-color-to-stencil") << glu::FragmentSource(
			"#version 450\n"
			"void main(void)\n"
			"{\n"
			"}\n"
		);

		if ((readLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) ||
		   ((readLayout == VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR) && (readAspect == IMAGE_ASPECT_ALL)))
		{
			// use usampler2D and uvec4 for color
			sourceCollections.glslSources.add("frag-stencil-to-color") << glu::FragmentSource(
				"#version 450\n"
				"layout(binding = 0) uniform usampler2D u_sampler;\n"
				"layout(location = 0) in vec2 inUV;\n"
				"layout(location = 0) out uvec4 fragColor;\n"
				"void main(void)\n"
				"{\n"
				"  fragColor = texture(u_sampler, inUV);\n"
				"}\n"
			);
		}
	}

	if (readAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
	{
		// for stencil only cases we need to use usubpassInput (for depth and depth_stencil we need to use subpassInput)
		const bool									readDepth			= readAspect & VK_IMAGE_ASPECT_DEPTH_BIT;
		const std::map<std::string, std::string>	specializations
		{
			{ "SUBPASS_INPUT",	(readDepth ? "subpassInput"	: "usubpassInput")	},
			{ "VALUE_TYPE",		(readDepth ? "float"		: "uint")			}
		};

		std::string source =
			"#version 450\n"
			"layout (input_attachment_index = 0, binding = 0) uniform ${SUBPASS_INPUT} depthOrStencilInput;\n"
			"layout(location = 0) in vec2 inUV;\n"
			"layout(location = 0) out ${VALUE_TYPE} fragColor;\n"
			"void main (void)\n"
			"{\n"
			"  fragColor = subpassLoad(depthOrStencilInput).x;\n"
			"}\n";
		sourceCollections.glslSources.add("frag-depth-or-stencil-to-color")
			<< glu::FragmentSource(tcu::StringTemplate(source).specialize(specializations));
	}
}

TestInstance* NoneStageTestCase::createInstance(Context& context) const
{
	return new NoneStageTestInstance(context, m_testParams);
}

void NoneStageTestCase::checkSupport(Context& context) const
{
	context.requireDeviceFunctionality("VK_KHR_synchronization2");

	const auto writeAspect	= m_testParams.writeAspect;
	const auto readAspect	= m_testParams.readAspect;

	// check whether implementation supports separate depth/stencil layouts
	if (((writeAspect == VK_IMAGE_ASPECT_DEPTH_BIT) && (readAspect == VK_IMAGE_ASPECT_DEPTH_BIT)) ||
		((writeAspect == VK_IMAGE_ASPECT_STENCIL_BIT) && (readAspect == VK_IMAGE_ASPECT_STENCIL_BIT)))
	{
		if(!context.getSeparateDepthStencilLayoutsFeatures().separateDepthStencilLayouts)
			TCU_THROW(NotSupportedError, "Implementation does not support separateDepthStencilLayouts");
	}

	const auto writeLayout	= m_testParams.writeLayout;
	const auto readLayout	= m_testParams.readLayout;
	bool usePipelineToWrite	= (writeLayout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) && (writeLayout != VK_IMAGE_LAYOUT_GENERAL);
	bool usePipelineToRead	= (readLayout  != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) && (readLayout  != VK_IMAGE_LAYOUT_GENERAL);

	if (!usePipelineToWrite && !usePipelineToRead)
		return;

	VkFormat transitionImageFormat = VK_FORMAT_R8G8B8A8_UNORM;
	if ((writeAspect == VK_IMAGE_ASPECT_DEPTH_BIT) || (readAspect == VK_IMAGE_ASPECT_DEPTH_BIT))
		transitionImageFormat = VK_FORMAT_D32_SFLOAT;
	else if ((writeAspect == VK_IMAGE_ASPECT_STENCIL_BIT) || (readAspect == VK_IMAGE_ASPECT_STENCIL_BIT))
		transitionImageFormat = VK_FORMAT_S8_UINT;
	else if ((writeAspect == IMAGE_ASPECT_DEPTH_STENCIL) || (readAspect == IMAGE_ASPECT_DEPTH_STENCIL))
		transitionImageFormat = VK_FORMAT_D24_UNORM_S8_UINT;

	struct FormatToCheck
	{
		VkFormat			format;
		VkImageUsageFlags	usage;
	};
	std::vector<FormatToCheck> formatsToCheck
	{
		// reference image
		{ transitionImageFormat, (VkImageUsageFlags)VK_IMAGE_USAGE_TRANSFER_DST_BIT },

		// image to write
		{ transitionImageFormat, (VkImageUsageFlags)VK_IMAGE_USAGE_TRANSFER_SRC_BIT }
	};

	// note: conditions here are analogic to conditions in test case constructor
	//       everything not needed was cout out leaving only logic related to
	//       m_referenceImage and m_imageToWrite
	if (usePipelineToWrite)
	{
		if (writeAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
		{
			if (writeAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
			{
				formatsToCheck[0].format = VK_FORMAT_R32_SFLOAT;
				formatsToCheck[0].usage	|= VK_IMAGE_USAGE_SAMPLED_BIT;
			}
			else
				formatsToCheck[0].usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;

			formatsToCheck[1].usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
		}
		else
		{
			formatsToCheck[0].usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
			formatsToCheck[1].usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
		}
	}

	if (usePipelineToRead)
	{
		// for layouts that operate on depth or stencil (not depth_stencil) use input attachment to read
		if ((readAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) && (readAspect != IMAGE_ASPECT_DEPTH_STENCIL))
		{
			formatsToCheck[1].usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;

			if (!usePipelineToWrite)
				formatsToCheck[0].usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
		}
		else // use image sampler for color and depth_stencil layouts
		{
			formatsToCheck[0].usage |= VK_IMAGE_USAGE_SAMPLED_BIT;

			// for depth_stencil layouts we need to have depth_stencil_attachment usage
			if (!usePipelineToWrite && (readAspect & VK_IMAGE_ASPECT_STENCIL_BIT))
				formatsToCheck[0].usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
		}
	}

	// it simplifies logic to pop image to write then to add conditions everywhere above
	if (!usePipelineToWrite)
		formatsToCheck.pop_back();

	for (const auto& formatData : formatsToCheck)
	{
		VkImageFormatProperties			properties;
		const vk::InstanceInterface&	vki = context.getInstanceInterface();
		if (vki.getPhysicalDeviceImageFormatProperties(context.getPhysicalDevice(),
													   formatData.format,
													   VK_IMAGE_TYPE_2D,
													   VK_IMAGE_TILING_OPTIMAL,
													   formatData.usage,
													   0,
													   &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
		{
			std::string error = std::string("Format (") +
								vk::getFormatName(formatData.format) + ") doesn't support required capabilities.";
			TCU_THROW(NotSupportedError, error.c_str());
		}
	}
}

} // anonymous

tcu::TestCaseGroup* createNoneStageTests(tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> noneStageTests(new tcu::TestCaseGroup(testCtx, "none_stage", ""));

	struct LayoutData
	{
		VkImageLayout		token;
		VkImageAspectFlags	aspect;
		std::string			name;
	};

	const std::vector<LayoutData> writableLayoutsData
	{
		{ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,							IMAGE_ASPECT_ALL,				"transfer_dst" },
		{ VK_IMAGE_LAYOUT_GENERAL,										IMAGE_ASPECT_ALL,				"general" },
		{ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,						VK_IMAGE_ASPECT_COLOR_BIT,		"color_attachment" },
		{ VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,				IMAGE_ASPECT_DEPTH_STENCIL,		"depth_stencil_attachment" },
		{ VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,						VK_IMAGE_ASPECT_DEPTH_BIT,		"depth_attachment" },
		{ VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL,					VK_IMAGE_ASPECT_STENCIL_BIT,	"stencil_attachment" },
		{ VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR,						VK_IMAGE_ASPECT_COLOR_BIT,		"generic_color_attachment" },
		{ VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR,						VK_IMAGE_ASPECT_DEPTH_BIT,		"generic_depth_attachment" },
		{ VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR,						VK_IMAGE_ASPECT_STENCIL_BIT,	"generic_stencil_attachment" },
		{ VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR,						IMAGE_ASPECT_DEPTH_STENCIL,		"generic_depth_stencil_attachment" },
	};
	const std::vector<LayoutData> readableLayoutsData
	{
		{ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,							IMAGE_ASPECT_ALL,				"transfer_src" },
		{ VK_IMAGE_LAYOUT_GENERAL,										IMAGE_ASPECT_ALL,				"general" },
		{ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,						IMAGE_ASPECT_ALL,				"shader_read" },
		{ VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,				IMAGE_ASPECT_DEPTH_STENCIL,		"depth_stencil_read" },
		{ VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL,	IMAGE_ASPECT_DEPTH_STENCIL,		"depth_read_stencil_attachment" },
		{ VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL,	IMAGE_ASPECT_DEPTH_STENCIL,		"depth_attachment_stencil_read" },
		{ VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL,						VK_IMAGE_ASPECT_DEPTH_BIT,		"depth_read" },
		{ VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL,					VK_IMAGE_ASPECT_STENCIL_BIT,	"stencil_read" },
		{ VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR,						IMAGE_ASPECT_ALL,				"generic_color_read" },
		{ VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR,						VK_IMAGE_ASPECT_DEPTH_BIT,		"generic_depth_read" },
		{ VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR,						VK_IMAGE_ASPECT_STENCIL_BIT,	"generic_stencil_read" },
		{ VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR,						IMAGE_ASPECT_DEPTH_STENCIL,		"generic_depth_stencil_read" },
	};

	struct SynchronizationData
	{
		SynchronizationType		type;
		std::string				casePrefix;
		bool					useGenericAccessFlags;
	};
	std::vector<SynchronizationData> synchronizationData
	{
		{ SynchronizationType::SYNCHRONIZATION2,	"",					true },
		{ SynchronizationType::SYNCHRONIZATION2,	"old_access_",		false },

		// using legacy synchronization structures with NONE_STAGE
		{ SynchronizationType::LEGACY,				"legacy_",			false }
	};

	for (const auto& syncData : synchronizationData)
	{
		for (const auto& writeData : writableLayoutsData)
		{
			for (const auto& readData : readableLayoutsData)
			{
				if (readData.aspect && writeData.aspect &&
				   (readData.aspect != writeData.aspect))
					continue;

				const std::string name = syncData.casePrefix + writeData.name + "_to_" + readData.name;
				noneStageTests->addChild(new NoneStageTestCase(testCtx, name, {
					syncData.type,
					syncData.useGenericAccessFlags,
					writeData.token,
					writeData.aspect,
					readData.token,
					readData.aspect
				}));
			}
		}
	}

	return noneStageTests.release();
}

} // synchronization
} // vkt
