/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2017 The Khronos Group Inc.
 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
 *
 * 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 Protected memory YCbCr image conversion tests
 *//*--------------------------------------------------------------------*/

#include "vktProtectedMemYCbCrConversionTests.hpp"

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

#include "vkBuilderUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkPrograms.hpp"
#include "vkTypeUtil.hpp"
#include "vkYCbCrImageWithMemory.hpp"
#include "vkCmdUtil.hpp"

#include "vktProtectedMemContext.hpp"
#include "vktProtectedMemUtils.hpp"
#include "vktTestCaseUtil.hpp"
#include "vktYCbCrUtil.hpp"


namespace vkt
{
namespace ProtectedMem
{

namespace
{
static const vk::VkFormat	s_colorFormat	= vk::VK_FORMAT_R8G8B8A8_UNORM;

enum {
	CHECK_SIZE	= 50,
};

struct YCbCrValidationData {
	tcu::Vec4	coord;
	tcu::Vec4	minBound;
	tcu::Vec4	maxBound;
};

std::vector<tcu::Vec2> computeVertexPositions (int numValues, const tcu::IVec2& renderSize)
{
	std::vector<tcu::Vec2> positions(numValues);
	for (int valNdx = 0; valNdx < numValues; valNdx++)
	{
		const int	ix	= valNdx % renderSize.x();
		const int	iy	= valNdx / renderSize.x();
		const float	fx	= -1.0f + 2.0f*((float(ix) + 0.5f) / float(renderSize.x()));
		const float	fy	= -1.0f + 2.0f*((float(iy) + 0.5f) / float(renderSize.y()));

		positions[valNdx] = tcu::Vec2(fx, fy);
	}

	return positions;
}

void genTexCoords (std::vector<tcu::Vec2>& coords, const tcu::UVec2& size)
{
	for (deUint32 y = 0; y < size.y(); y++)
	for (deUint32 x = 0; x < size.x(); x++)
	{
		const float	fx	= (float)x;
		const float	fy	= (float)y;

		const float	fw	= (float)size.x();
		const float	fh	= (float)size.y();

		const float	s	= 1.5f * ((fx * 1.5f * fw + fx) / (1.5f * fw * 1.5f * fw)) - 0.25f;
		const float	t	= 1.5f * ((fy * 1.5f * fh + fy) / (1.5f * fh * 1.5f * fh)) - 0.25f;

		coords.push_back(tcu::Vec2(s, t));
	}
}

struct TestConfig
{
	TestConfig	(glu::ShaderType						shaderType_,
				 vk::VkFormat							format_,
				 vk::VkImageTiling						imageTiling_,
				 vk::VkFilter							textureFilter_,
				 vk::VkSamplerAddressMode				addressModeU_,
				 vk::VkSamplerAddressMode				addressModeV_,

				 vk::VkFilter							chromaFilter_,
				 vk::VkChromaLocation					xChromaOffset_,
				 vk::VkChromaLocation					yChromaOffset_,
				 bool									explicitReconstruction_,
				 bool									disjoint_,

				 vk::VkSamplerYcbcrRange				colorRange_,
				 vk::VkSamplerYcbcrModelConversion		colorModel_,
				 vk::VkComponentMapping					componentMapping_)
		: shaderType				(shaderType_)
		, format					(format_)
		, imageTiling				(imageTiling_)
		, textureFilter				(textureFilter_)
		, addressModeU				(addressModeU_)
		, addressModeV				(addressModeV_)

		, chromaFilter				(chromaFilter_)
		, xChromaOffset				(xChromaOffset_)
		, yChromaOffset				(yChromaOffset_)
		, explicitReconstruction	(explicitReconstruction_)
		, disjoint					(disjoint_)

		, colorRange				(colorRange_)
		, colorModel				(colorModel_)
		, componentMapping			(componentMapping_)
	{
	}

	glu::ShaderType							shaderType;
	vk::VkFormat							format;
	vk::VkImageTiling						imageTiling;
	vk::VkFilter							textureFilter;
	vk::VkSamplerAddressMode				addressModeU;
	vk::VkSamplerAddressMode				addressModeV;

	vk::VkFilter							chromaFilter;
	vk::VkChromaLocation					xChromaOffset;
	vk::VkChromaLocation					yChromaOffset;
	bool									explicitReconstruction;
	bool									disjoint;

	vk::VkSamplerYcbcrRange					colorRange;
	vk::VkSamplerYcbcrModelConversion		colorModel;
	vk::VkComponentMapping					componentMapping;
};


void validateFormatSupport (ProtectedContext& context, TestConfig& config)
{
	tcu::TestLog&						log			(context.getTestContext().getLog());

	try
	{
		const vk::VkFormatProperties	properties	(vk::getPhysicalDeviceFormatProperties(context.getInstanceDriver(), context.getPhysicalDevice(), config.format));
		const vk::VkFormatFeatureFlags	features	(config.imageTiling == vk::VK_IMAGE_TILING_OPTIMAL
													? properties.optimalTilingFeatures
													: properties.linearTilingFeatures);

		if ((features & (vk::VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT | vk::VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT)) == 0)
			TCU_THROW(NotSupportedError, "Format doesn't support YCbCr conversions");

		if ((features & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) == 0)
			TCU_THROW(NotSupportedError, "Format doesn't support sampling");

		if (config.textureFilter == vk::VK_FILTER_LINEAR && ((features & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT) == 0))
			TCU_THROW(NotSupportedError, "Format doesn't support YCbCr linear chroma reconstruction");

		if (config.chromaFilter == vk::VK_FILTER_LINEAR && ((features & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT) == 0))
			TCU_THROW(NotSupportedError, "Format doesn't support YCbCr linear chroma reconstruction");

		if (config.chromaFilter != config.textureFilter && ((features & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT) == 0))
			TCU_THROW(NotSupportedError, "Format doesn't support different chroma and texture filters");

		if (config.explicitReconstruction && ((features & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT) == 0))
			TCU_THROW(NotSupportedError, "Format doesn't support explicit chroma reconstruction");

		if (config.disjoint && ((features & vk::VK_FORMAT_FEATURE_DISJOINT_BIT) == 0))
			TCU_THROW(NotSupportedError, "Format doesn't disjoint planes");

		if (ycbcr::isXChromaSubsampled(config.format) && (config.xChromaOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN) && ((features & vk::VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT) == 0))
			TCU_THROW(NotSupportedError, "Format doesn't support cosited chroma samples");

		if (ycbcr::isXChromaSubsampled(config.format) && (config.xChromaOffset == vk::VK_CHROMA_LOCATION_MIDPOINT) && ((features & vk::VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT) == 0))
			TCU_THROW(NotSupportedError, "Format doesn't support midpoint chroma samples");

		if (ycbcr::isYChromaSubsampled(config.format) && (config.yChromaOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN) && ((features & vk::VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT) == 0))
			TCU_THROW(NotSupportedError, "Format doesn't support cosited chroma samples");

		if (ycbcr::isYChromaSubsampled(config.format) && (config.yChromaOffset == vk::VK_CHROMA_LOCATION_MIDPOINT) && ((features & vk::VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT) == 0))
			TCU_THROW(NotSupportedError, "Format doesn't support midpoint chroma samples");

		if ((features & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT) != 0)
			config.explicitReconstruction = true;

		log << tcu::TestLog::Message << "FormatFeatures: " << vk::getFormatFeatureFlagsStr(features) << tcu::TestLog::EndMessage;
	}
	catch (const vk::Error& err)
	{
		if (err.getError() == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
			TCU_THROW(NotSupportedError, "Format not supported");

		throw;
	}
}

vk::Move<vk::VkSampler> createSampler (const vk::DeviceInterface&				vkd,
									   const vk::VkDevice						device,
									   const vk::VkFilter						textureFilter,
									   const vk::VkSamplerAddressMode			addressModeU,
									   const vk::VkSamplerAddressMode			addressModeV,
									   const vk::VkSamplerYcbcrConversion		conversion)
{
	const vk::VkSamplerYcbcrConversionInfo		samplerConversionInfo	=
	{
		vk::VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
		DE_NULL,
		conversion
	};

	const vk::VkSamplerCreateInfo	createInfo	=
	{
		vk::VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
		&samplerConversionInfo,
		0u,
		textureFilter,
		textureFilter,
		vk::VK_SAMPLER_MIPMAP_MODE_NEAREST,
		addressModeU,
		addressModeV,
		vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
		0.0f,
		VK_FALSE,
		1.0f,
		VK_FALSE,
		vk::VK_COMPARE_OP_ALWAYS,
		0.0f,
		0.0f,
		vk::VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,
		VK_FALSE,
	};

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

vk::Move<vk::VkImageView> createImageView (const vk::DeviceInterface&				vkd,
										   const vk::VkDevice						device,
										   const vk::VkImage						image,
										   const vk::VkFormat						format,
										   const vk::VkSamplerYcbcrConversion		conversion)
{
	const vk::VkSamplerYcbcrConversionInfo		conversionInfo	=
	{
		vk::VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
		DE_NULL,
		conversion
	};

	const vk::VkImageViewCreateInfo				viewInfo		=
	{
		vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
		&conversionInfo,
		(vk::VkImageViewCreateFlags)0,
		image,
		vk::VK_IMAGE_VIEW_TYPE_2D,
		format,
		{
			vk::VK_COMPONENT_SWIZZLE_IDENTITY,
			vk::VK_COMPONENT_SWIZZLE_IDENTITY,
			vk::VK_COMPONENT_SWIZZLE_IDENTITY,
			vk::VK_COMPONENT_SWIZZLE_IDENTITY,
		},
		{ vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },
	};

	return vk::createImageView(vkd, device, &viewInfo);
}

vk::Move<vk::VkSamplerYcbcrConversion> createConversion (const vk::DeviceInterface&					vkd,
														const vk::VkDevice							device,
														const vk::VkFormat							format,
														const vk::VkSamplerYcbcrModelConversion		colorModel,
														const vk::VkSamplerYcbcrRange				colorRange,
														const vk::VkChromaLocation					xChromaOffset,
														const vk::VkChromaLocation					yChromaOffset,
														const vk::VkFilter							chromaFilter,
														const vk::VkComponentMapping&				componentMapping,
														const bool									explicitReconstruction)
{
	const vk::VkSamplerYcbcrConversionCreateInfo	conversionInfo	=
	{
		vk::VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
		DE_NULL,

		format,
		colorModel,
		colorRange,
		componentMapping,
		xChromaOffset,
		yChromaOffset,
		chromaFilter,
		explicitReconstruction ? VK_TRUE : VK_FALSE
	};

	return vk::createSamplerYcbcrConversion(vkd, device, &conversionInfo);
}

void uploadYCbCrImage (ProtectedContext&					ctx,
					   const vk::VkImage					image,
					   const ycbcr::MultiPlaneImageData&	imageData,
					   const vk::VkAccessFlags				nextAccess,
					   const vk::VkImageLayout				finalLayout)
{
	const vk::DeviceInterface&				vk					= ctx.getDeviceInterface();
	const vk::VkDevice						device				= ctx.getDevice();
	const vk::VkQueue						queue				= ctx.getQueue();
	const deUint32							queueFamilyIndex	= ctx.getQueueFamilyIndex();

	const vk::Unique<vk::VkCommandPool>		cmdPool				(makeCommandPool(vk, device, PROTECTION_ENABLED, queueFamilyIndex));
	const vk::Unique<vk::VkCommandBuffer>	cmdBuffer			(vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	const vk::PlanarFormatDescription&		formatDesc			= imageData.getDescription();

	std::vector<de::SharedPtr<de::MovePtr<vk::BufferWithMemory> > > stagingBuffers;
	std::vector<vk::VkBufferMemoryBarrier>	bufferBarriers;

	for (deUint32 planeNdx = 0; planeNdx < imageData.getDescription().numPlanes; ++planeNdx)
	{
		de::MovePtr<vk::BufferWithMemory> buffer	(makeBuffer(ctx,
																		PROTECTION_DISABLED,
																		queueFamilyIndex,
																		(deUint32)imageData.getPlaneSize(planeNdx),
																		vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT,
																		vk::MemoryRequirement::HostVisible));

		const vk::VkBufferMemoryBarrier		bufferBarrier	=
		{
			vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
			DE_NULL,
			(vk::VkAccessFlags)0,
			vk::VK_ACCESS_TRANSFER_READ_BIT,
			queueFamilyIndex,
			queueFamilyIndex,
			**buffer,
			0,
			(deUint32)imageData.getPlaneSize(planeNdx)
		};
		bufferBarriers.push_back(bufferBarrier);

		deMemcpy(buffer->getAllocation().getHostPtr(), imageData.getPlanePtr(planeNdx), imageData.getPlaneSize(planeNdx));
		flushMappedMemoryRange(vk, device, buffer->getAllocation().getMemory(), buffer->getAllocation().getOffset(), (deUint32)imageData.getPlaneSize(planeNdx));
		stagingBuffers.push_back(de::SharedPtr<de::MovePtr<vk::BufferWithMemory> >(new de::MovePtr<vk::BufferWithMemory>(buffer.release())));
	}


	beginCommandBuffer(vk, *cmdBuffer);

	for (deUint32 planeNdx = 0; planeNdx < imageData.getDescription().numPlanes; ++planeNdx)
	{
		const vk::VkImageAspectFlagBits	aspect	= formatDesc.numPlanes > 1
												? vk::getPlaneAspect(planeNdx)
												: vk::VK_IMAGE_ASPECT_COLOR_BIT;

		const vk::VkImageMemoryBarrier		preCopyBarrier	=
		{
			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
			DE_NULL,
			(vk::VkAccessFlags)0,
			vk::VK_ACCESS_TRANSFER_WRITE_BIT,
			vk::VK_IMAGE_LAYOUT_UNDEFINED,
			vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
			queueFamilyIndex,
			queueFamilyIndex,
			image,
			{ aspect, 0u, 1u, 0u, 1u }
		};

		vk.cmdPipelineBarrier(*cmdBuffer,
								(vk::VkPipelineStageFlags)vk::VK_PIPELINE_STAGE_HOST_BIT,
								(vk::VkPipelineStageFlags)vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
								(vk::VkDependencyFlags)0u,
								0u, (const vk::VkMemoryBarrier*)DE_NULL,
								(deUint32)bufferBarriers.size(), &bufferBarriers[0],
								1u, &preCopyBarrier);
	}

	for (deUint32 planeNdx = 0; planeNdx < imageData.getDescription().numPlanes; ++planeNdx)
	{
		const vk::VkImageAspectFlagBits	aspect	= (formatDesc.numPlanes > 1)
												? vk::getPlaneAspect(planeNdx)
												: vk::VK_IMAGE_ASPECT_COLOR_BIT;
		const deUint32					planeW	= (formatDesc.numPlanes > 1)
												? imageData.getSize().x() / formatDesc.planes[planeNdx].widthDivisor
												: imageData.getSize().x();
		const deUint32					planeH	= (formatDesc.numPlanes > 1)
												? imageData.getSize().y() / formatDesc.planes[planeNdx].heightDivisor
												: imageData.getSize().y();
		const vk::VkBufferImageCopy		copy	=
		{
			0u,		// bufferOffset
			0u,		// bufferRowLength
			0u,		// bufferImageHeight
			{ (vk::VkImageAspectFlags)aspect, 0u, 0u, 1u },
			vk::makeOffset3D(0u, 0u, 0u),
			vk::makeExtent3D(planeW, planeH, 1u),
		};

		vk.cmdCopyBufferToImage(*cmdBuffer, ***stagingBuffers[planeNdx], image, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copy);
	}

	for (deUint32 planeNdx = 0; planeNdx < imageData.getDescription().numPlanes; ++planeNdx)
	{
		const vk::VkImageAspectFlagBits	aspect	= formatDesc.numPlanes > 1
												? vk::getPlaneAspect(planeNdx)
												: vk::VK_IMAGE_ASPECT_COLOR_BIT;

		const vk::VkImageMemoryBarrier		postCopyBarrier	=
		{
			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
			DE_NULL,
			vk::VK_ACCESS_TRANSFER_WRITE_BIT,
			nextAccess,
			vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
			finalLayout,
			VK_QUEUE_FAMILY_IGNORED,
			VK_QUEUE_FAMILY_IGNORED,
			image,
			{ aspect, 0u, 1u, 0u, 1u }
		};

		vk.cmdPipelineBarrier(*cmdBuffer,
								(vk::VkPipelineStageFlags)vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
								(vk::VkPipelineStageFlags)vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
								(vk::VkDependencyFlags)0u,
								0u, (const vk::VkMemoryBarrier*)DE_NULL,
								0u, (const vk::VkBufferMemoryBarrier*)DE_NULL,
								1u, &postCopyBarrier);
	}

	endCommandBuffer(vk, *cmdBuffer);

	{
		const vk::Unique<vk::VkFence>	fence		(createFence(vk, device));
		VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull));
	}
}

void logTestCaseInfo (tcu::TestLog& log, const TestConfig& config)
{
	log << tcu::TestLog::Message << "ShaderType: " << config.shaderType << tcu::TestLog::EndMessage;
	log << tcu::TestLog::Message << "Format: "  << config.format << tcu::TestLog::EndMessage;
	log << tcu::TestLog::Message << "ImageTiling: " << config.imageTiling << tcu::TestLog::EndMessage;
	log << tcu::TestLog::Message << "TextureFilter: " << config.textureFilter << tcu::TestLog::EndMessage;
	log << tcu::TestLog::Message << "AddressModeU: " << config.addressModeU << tcu::TestLog::EndMessage;
	log << tcu::TestLog::Message << "AddressModeV: " << config.addressModeV << tcu::TestLog::EndMessage;
	log << tcu::TestLog::Message << "ChromaFilter: " << config.chromaFilter << tcu::TestLog::EndMessage;
	log << tcu::TestLog::Message << "XChromaOffset: " << config.xChromaOffset << tcu::TestLog::EndMessage;
	log << tcu::TestLog::Message << "YChromaOffset: " << config.yChromaOffset << tcu::TestLog::EndMessage;
	log << tcu::TestLog::Message << "ExplicitReconstruction: " << (config.explicitReconstruction ? "true" : "false") << tcu::TestLog::EndMessage;
	log << tcu::TestLog::Message << "Disjoint: " << (config.disjoint ? "true" : "false") << tcu::TestLog::EndMessage;
	log << tcu::TestLog::Message << "ColorRange: " << config.colorRange << tcu::TestLog::EndMessage;
	log << tcu::TestLog::Message << "ColorModel: " << config.colorModel << tcu::TestLog::EndMessage;
	log << tcu::TestLog::Message << "ComponentMapping: " << config.componentMapping << tcu::TestLog::EndMessage;
}

void logBoundImages (tcu::TestLog& log, const tcu::UVec2 size, const std::vector<tcu::Vec4>& minBounds, const std::vector<tcu::Vec4>& maxBounds)
{
	tcu::TextureLevel	minImage	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), size.x(), size.y());
	tcu::TextureLevel	maxImage	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), size.x(), size.y());

	for (int y = 0; y < (int)(size.y()); y++)
	for (int x = 0; x < (int)(size.x()); x++)
	{
		const int ndx = x + y * (int)(size.x());
		minImage.getAccess().setPixel(minBounds[ndx], x, y);
		maxImage.getAccess().setPixel(maxBounds[ndx], x, y);
	}

	const tcu::Vec4	scale	(1.0f);
	const tcu::Vec4	bias	(0.0f);

	log << tcu::TestLog::Image("MinBoundImage", "MinBoundImage", minImage.getAccess(), scale, bias);
	log << tcu::TestLog::Image("MaxBoundImage", "MaxBoundImage", maxImage.getAccess(), scale, bias);
}

bool validateImage (ProtectedContext&							ctx,
					 const std::vector<YCbCrValidationData>&	refData,
					 const vk::VkSampler						sampler,
					 const vk::VkImageView						imageView)
{
	{
		tcu::TestLog&	log	(ctx.getTestContext().getLog());

		log << tcu::TestLog::Message << "Reference values:" << tcu::TestLog::EndMessage;
		for (deUint32 ndx = 0; ndx < refData.size(); ndx++)
		{
			log << tcu::TestLog::Message << (ndx + 1) << refData[ndx].coord << ": [" << refData[ndx].minBound << ", " << refData[ndx].maxBound << "]" << tcu::TestLog::EndMessage;
		}
	}

	const deUint64								oneSec				= 1000 * 1000 * 1000;

	const vk::DeviceInterface&					vk					= ctx.getDeviceInterface();
	const vk::VkDevice							device				= ctx.getDevice();
	const vk::VkQueue							queue				= ctx.getQueue();
	const deUint32								queueFamilyIndex	= ctx.getQueueFamilyIndex();

	DE_ASSERT(refData.size() >= CHECK_SIZE && CHECK_SIZE > 0);
	const deUint32								refUniformSize		= (deUint32)(sizeof(YCbCrValidationData) * refData.size());
	const de::UniquePtr<vk::BufferWithMemory>	refUniform			(makeBuffer(ctx,
																				PROTECTION_DISABLED,
																				queueFamilyIndex,
																				refUniformSize,
																				vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
																				vk::MemoryRequirement::HostVisible));

	// Set the reference uniform data
	{
		deMemcpy(refUniform->getAllocation().getHostPtr(), &refData[0], refUniformSize);
		vk::flushMappedMemoryRange(vk, device, refUniform->getAllocation().getMemory(), refUniform->getAllocation().getOffset(), refUniformSize);
	}

	const deUint32								helperBufferSize	= (deUint32)(2 * sizeof(deUint32));
	const de::MovePtr<vk::BufferWithMemory>		helperBuffer		(makeBuffer(ctx,
																				PROTECTION_ENABLED,
																				queueFamilyIndex,
																				helperBufferSize,
																				vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
																				vk::MemoryRequirement::Protected));
	const vk::Unique<vk::VkShaderModule>		resetSSBOShader		(vk::createShaderModule(vk, device, ctx.getBinaryCollection().get("ResetSSBO"), 0));
	const vk::Unique<vk::VkShaderModule>		validatorShader		(vk::createShaderModule(vk, device, ctx.getBinaryCollection().get("ImageValidator"), 0));

	// Create descriptors
	const vk::Unique<vk::VkDescriptorSetLayout>	descriptorSetLayout(vk::DescriptorSetLayoutBuilder()
		.addSingleSamplerBinding(vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, vk::VK_SHADER_STAGE_COMPUTE_BIT, &sampler)
		.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT)
		.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT)
		.build(vk, device));
	const vk::Unique<vk::VkDescriptorPool>		descriptorPool(vk::DescriptorPoolBuilder()
		.addType(vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1u)
		.addType(vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1u)
		.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u)
		.build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
	const vk::Unique<vk::VkDescriptorSet>		descriptorSet		(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));

	// Update descriptor set infirmation
	{
		vk::VkDescriptorBufferInfo	descRefUniform	= makeDescriptorBufferInfo(**refUniform, 0, refUniformSize);
		vk::VkDescriptorBufferInfo	descBuffer		= makeDescriptorBufferInfo(**helperBuffer, 0, helperBufferSize);
		vk::VkDescriptorImageInfo	descSampledImg	= makeDescriptorImageInfo(sampler, imageView, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);

		vk::DescriptorSetUpdateBuilder()
			.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descSampledImg)
			.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &descRefUniform)
			.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descBuffer)
			.update(vk, device);
	}

	const vk::Unique<vk::VkPipelineLayout>		pipelineLayout		(makePipelineLayout(vk, device, *descriptorSetLayout));
	const vk::Unique<vk::VkCommandPool>			cmdPool				(makeCommandPool(vk, device, PROTECTION_ENABLED, queueFamilyIndex));

	// Reset helper SSBO
	{
		const vk::Unique<vk::VkFence>			fence				(vk::createFence(vk, device));
		const vk::Unique<vk::VkPipeline>		resetSSBOPipeline	(makeComputePipeline(vk, device, *pipelineLayout, *resetSSBOShader, DE_NULL));
		const vk::Unique<vk::VkCommandBuffer>	resetCmdBuffer		(vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
		beginCommandBuffer(vk, *resetCmdBuffer);

		vk.cmdBindPipeline(*resetCmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *resetSSBOPipeline);
		vk.cmdBindDescriptorSets(*resetCmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
		vk.cmdDispatch(*resetCmdBuffer, 1u, 1u, 1u);

		endCommandBuffer(vk, *resetCmdBuffer);
		VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *resetCmdBuffer, *fence, ~0ull));
	}

	// Create validation compute commands & submit
	vk::VkResult							queueSubmitResult;
	{
		const vk::Unique<vk::VkFence>			fence				(vk::createFence(vk, device));
		const vk::Unique<vk::VkPipeline>		validationPipeline	(makeComputePipeline(vk, device, *pipelineLayout, *validatorShader, DE_NULL));
		const vk::Unique<vk::VkCommandBuffer>	cmdBuffer			(vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));

		beginCommandBuffer(vk, *cmdBuffer);

		vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *validationPipeline);
		vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
		vk.cmdDispatch(*cmdBuffer, CHECK_SIZE, 1u, 1u);

		endCommandBuffer(vk, *cmdBuffer);

		queueSubmitResult = queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, oneSec * 5);
	}

	// \todo do we need to check the fence status?
	if (queueSubmitResult == vk::VK_TIMEOUT)
		return false;

	// at this point the submit result should be VK_TRUE
	VK_CHECK(queueSubmitResult);
	return true;
}

void testShaders (vk::SourceCollections& dst, const TestConfig config)
{
	const char* const	shaderHeader		=
			"layout(constant_id = 1) const float threshold = 0.01f;\n"
			"layout(set = 0, binding = 0) uniform highp sampler2D protectedImage;\n"
			"\n"
			"struct validationData {\n"
			"    highp vec4 imageCoord;\n"
			"    highp vec4 imageRefMinBound;\n"
			"    highp vec4 imageRefMaxBound;\n"
			"};\n"
			"layout(std140, set = 0, binding = 1) uniform Data\n"
			"{\n"
			"    validationData ref[250];\n"
			"};\n";

	const char* const	compareFunction	=
			"bool compare(highp vec4 value, highp vec4 minValue, highp vec4 maxValue)\n"
			"{\n"
			"    return all(greaterThanEqual(value, minValue - threshold)) && all(lessThanEqual(value, maxValue + threshold));\n"
			"}\n";

	std::map<std::string, std::string> validatorSpec;
	validatorSpec["CHECK_SIZE"]			= de::toString((deUint32)CHECK_SIZE);
	validatorSpec["SHADER_HEADER"]		= shaderHeader;
	validatorSpec["COMPARE_FUNCTION"]	= compareFunction;

	const char* const validatorShader =
		"#version 450\n"
		"\n"
		"${SHADER_HEADER}"
		"\n"
		"layout(std140, set = 0, binding = 2) buffer ProtectedHelper\n"
		"{\n"
		"    highp uint zero;\n"
		"    highp uint dummyOut;\n"
		"} helper;\n"
		"\n"
		"void error()\n"
		"{\n"
		"    for (uint x = 0u; x < 10u; x += helper.zero)\n"
		"        atomicAdd(helper.dummyOut, 1u);\n"
		"}\n"
		"\n"
		"${COMPARE_FUNCTION}"
		"\n"
		"void main(void)\n"
		"{\n"
		"    int idx = int(gl_GlobalInvocationID.x);\n"
		"    vec4 currentValue = texture(protectedImage, ref[idx].imageCoord.xy);\n"
		"    if (!compare(currentValue, ref[idx].imageRefMinBound, ref[idx].imageRefMaxBound))\n"
		"    {\n"
		"      error();\n"
		"    }\n"
		"}\n";

	const char* const resetSSBOShader =
		"#version 450\n"
		"layout(local_size_x = 1) in;\n"
		"\n"
		"layout(std140, set=0, binding=2) buffer ProtectedHelper\n"
		"{\n"
		"    highp uint zero; // set to 0\n"
		"    highp uint dummyOut;\n"
		"} helper;\n"
		"\n"
		"void main (void)\n"
		"{\n"
		"    helper.zero = 0;\n"
		"    helper.dummyOut = 0;\n"
		"}\n";

	dst.glslSources.add("ResetSSBO") << glu::ComputeSource(resetSSBOShader);
	dst.glslSources.add("ImageValidator") << glu::ComputeSource(tcu::StringTemplate(validatorShader).specialize(validatorSpec));

	if (config.shaderType == glu::SHADERTYPE_COMPUTE)
		return; // Bail early as the YCbCr image validator already have the test programs set for compute tests

	const char* const compareOperation =
			"    highp vec4 currentValue = texture(protectedImage, ref[v_idx].imageCoord.xy);\n"
			"    if (compare(currentValue, ref[v_idx].imageRefMinBound, ref[v_idx].imageRefMaxBound))\n"
			"    {\n"
			"        o_color = vec4(0.0f, 1.0f, 0.0f, 1.0f);\n"	// everything is ok, green
			"    }\n"
			"    else"
			"    {\n"
			"        o_color = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n"
			"    }\n";

	std::map<std::string, std::string>	shaderSpec;
	shaderSpec["SHADER_HEADER"]		= shaderHeader;
	shaderSpec["COMPARE_FUNCTION"]	= compareFunction;
	shaderSpec["COMPARE_OPERATION"]	= compareOperation;

	if (config.shaderType == glu::SHADERTYPE_VERTEX)
	{
		const char* const vertexShader =
			"#version 450\n"
			"${SHADER_HEADER}\n"
			"\n"
			"layout(location = 0) in highp vec2 a_position;\n"
			"layout(location = 0) flat out highp vec4 o_color;\n"
			"\n"
			"${COMPARE_FUNCTION}"
			"\n"
			"void main(void)\n"
			"{\n"
			"    gl_Position = vec4(a_position, 0.0f, 1.0f);\n"
			"    gl_PointSize = 1.0f;\n"
			"    int v_idx = gl_VertexIndex;\n"
			"${COMPARE_OPERATION}"
			"}\n";

		const char* const fragmentShader =
			"#version 450\n"
			"\n"
			"layout(location = 0) flat in highp vec4 v_color;\n"
			"layout(location = 0) out highp vec4 o_color;\n"
			"\n"
			"void main(void)\n"
			"{\n"
			"    o_color = v_color;\n"
			"}\n";

		dst.glslSources.add("vert") << glu::VertexSource(tcu::StringTemplate(vertexShader).specialize(shaderSpec));
		dst.glslSources.add("frag") << glu::FragmentSource(fragmentShader);
	}
	else if (config.shaderType == glu::SHADERTYPE_FRAGMENT)
	{
		const char* const vertexShader =
			"#version 450\n"
			"layout(location = 0) in highp vec2 a_position;\n"
			"layout(location = 0) flat out highp int o_idx;\n"
			"\n"
			"void main(void)\n"
			"{\n"
			"    gl_Position = vec4(a_position, 0.0f, 1.0f);\n"
			"    gl_PointSize = 1.0f;\n"
			"    o_idx = gl_VertexIndex;\n"
			"}\n";

		const char* const fragmentShader =
			"#version 450\n"
			"${SHADER_HEADER}\n"
			"\n"
			"layout(location = 0) flat in highp int v_idx;\n"
			"layout(location = 0) out highp vec4 o_color;\n"
			"\n"
			"${COMPARE_FUNCTION}"
			"\n"
			"void main(void)\n"
			"{\n"
			"${COMPARE_OPERATION}"
			"}\n";

		dst.glslSources.add("vert") << glu::VertexSource(vertexShader);
		dst.glslSources.add("frag") << glu::FragmentSource(tcu::StringTemplate(fragmentShader).specialize(shaderSpec));
	}
}

de::MovePtr<vk::YCbCrImageWithMemory>	createYcbcrImage2D	(ProtectedContext&				context,
															 const ProtectionMode			protectionMode,
															 const deUint32					width,
															 const deUint32					height,
															 const vk::VkFormat				format,
															 const vk::VkImageCreateFlags	createFlags,
															 const vk::VkImageUsageFlags	usageFlags)
{
	const vk::DeviceInterface&	vk			= context.getDeviceInterface();
	const vk::VkDevice&			device		= context.getDevice();
	vk::Allocator&				allocator	= context.getDefaultAllocator();
	const deUint32				queueIdx	= context.getQueueFamilyIndex();
#ifndef NOT_PROTECTED
	const deUint32				flags		= (protectionMode == PROTECTION_ENABLED) ? vk::VK_IMAGE_CREATE_PROTECTED_BIT : 0x0;
	const vk::MemoryRequirement	memReq		= (protectionMode == PROTECTION_ENABLED) ? vk::MemoryRequirement::Protected : vk::MemoryRequirement::Any;
#else
	const deUint32				flags		= 0x0;
	const vk::MemoryRequirement	memReq		= vk::MemoryRequirement::Any;
	DE_UNREF(protectionMode);
#endif

	const vk::VkImageCreateInfo	params		=
	{
		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType			stype
		DE_NULL,										// const void*				pNext
		(vk::VkImageCreateFlags)(flags | createFlags),	// VkImageCreateFlags		flags
		vk::VK_IMAGE_TYPE_2D,							// VkImageType				imageType
		format,											// VkFormat					format
		{ width, height, 1 },							// VkExtent3D				extent
		1u,												// deUint32					mipLevels
		1u,												// deUint32					arrayLayers
		vk::VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits	samples
		vk::VK_IMAGE_TILING_OPTIMAL,					// VkImageTiling			tiling
		usageFlags,										// VkImageUsageFlags		usage
		vk::VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode			sharingMode
		1u,												// deUint32					queueFamilyIndexCount
		&queueIdx,										// const deUint32*			pQueueFamilyIndices
		vk::VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			initialLayout
	};

	return de::MovePtr<vk::YCbCrImageWithMemory>(new vk::YCbCrImageWithMemory(vk, device, allocator, params, memReq));
}


void renderYCbCrToColor (ProtectedContext&							ctx,
						 const tcu::UVec2							size,
						 const vk::VkSampler						ycbcrSampler,
						 const vk::VkImageView						ycbcrImageView,
						 const vk::VkImage							colorImage,
						 const vk::VkImageView						colorImageView,
						 const std::vector<YCbCrValidationData>&	referenceData,
						 const std::vector<tcu::Vec2>&				posCoords)
{
	const vk::DeviceInterface&					vk					= ctx.getDeviceInterface();
	const vk::VkDevice							device				= ctx.getDevice();
	const vk::VkQueue							queue				= ctx.getQueue();
	const deUint32								queueFamilyIndex	= ctx.getQueueFamilyIndex();

	const vk::Unique<vk::VkRenderPass>			renderPass			(createRenderPass(ctx, s_colorFormat));
	const vk::Unique<vk::VkFramebuffer>			framebuffer			(createFramebuffer(ctx, size.x(), size.y(), *renderPass, colorImageView));
	const vk::Unique<vk::VkShaderModule>		vertexShader		(createShaderModule(vk, device, ctx.getBinaryCollection().get("vert"), 0));
	const vk::Unique<vk::VkShaderModule>		fragmentShader		(createShaderModule(vk, device, ctx.getBinaryCollection().get("frag"), 0));
	const vk::Unique<vk::VkDescriptorSetLayout>	descriptorSetLayout (vk::DescriptorSetLayoutBuilder()
																		.addSingleSamplerBinding(vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
																							 vk::VK_SHADER_STAGE_ALL,
																							 &ycbcrSampler)
																		.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, vk::VK_SHADER_STAGE_ALL)
																		.build(vk, device));
	const vk::Unique<vk::VkDescriptorPool>		descriptorPool		(vk::DescriptorPoolBuilder()
																		.addType(vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1u)
																		.addType(vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1u)
																		.build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
	const vk::Unique<vk::VkDescriptorSet>		descriptorSet		(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
	const vk::Unique<vk::VkPipelineLayout>		pipelineLayout		(makePipelineLayout(vk, device, *descriptorSetLayout));


	const deUint32								refUniformSize		= (deUint32)(sizeof(YCbCrValidationData) * referenceData.size());
	const de::UniquePtr<vk::BufferWithMemory>	refUniform			(makeBuffer(ctx,
																				PROTECTION_DISABLED,
																				queueFamilyIndex,
																				refUniformSize,
																				vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
																				vk::MemoryRequirement::HostVisible));

	// Set the reference uniform data
	{
		deMemcpy(refUniform->getAllocation().getHostPtr(), &referenceData[0], refUniformSize);
		vk::flushMappedMemoryRange(vk, device, refUniform->getAllocation().getMemory(), refUniform->getAllocation().getOffset(), refUniformSize);
	}

	// Update descriptor set
	{
		vk::VkDescriptorImageInfo	ycbcrSampled	(makeDescriptorImageInfo(ycbcrSampler, ycbcrImageView, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
		vk::VkDescriptorBufferInfo	descRefUniform	= makeDescriptorBufferInfo(**refUniform, 0, refUniformSize);
		vk::DescriptorSetUpdateBuilder()
			.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &ycbcrSampled)
			.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &descRefUniform)
			.update(vk, device);
	}

	VertexBindings							vertexBindings;
	VertexAttribs							vertexAttribs;
	de::MovePtr<vk::BufferWithMemory>		vertexBuffer;
	{
		const deUint32	bufferSize		= (deUint32)(sizeof(tcu::Vec2) * posCoords.size());
		{
			const vk::VkVertexInputBindingDescription	inputBinding	=
			{
				0u,									// deUint32					binding;
				sizeof(tcu::Vec2),					// deUint32					strideInBytes;
				vk::VK_VERTEX_INPUT_RATE_VERTEX		// VkVertexInputStepRate	inputRate;
			};
			const vk::VkVertexInputAttributeDescription	inputAttribute	=
			{
				0u,									// deUint32	location;
				0u,									// deUint32	binding;
				vk::VK_FORMAT_R32G32_SFLOAT,		// VkFormat	format;
				0u									// deUint32	offsetInBytes;
			};

			vertexBindings.push_back(inputBinding);
			vertexAttribs.push_back(inputAttribute);
		}

		vertexBuffer = makeBuffer(ctx,
								  PROTECTION_DISABLED,
								  queueFamilyIndex,
								  bufferSize,
								  vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
								  vk::MemoryRequirement::HostVisible);

		deMemcpy(vertexBuffer->getAllocation().getHostPtr(), &posCoords[0], bufferSize);
		vk::flushMappedMemoryRange(vk, device, vertexBuffer->getAllocation().getMemory(), vertexBuffer->getAllocation().getOffset(), bufferSize);
	}

	const vk::Unique<vk::VkPipeline>		pipeline			(makeGraphicsPipeline(vk,
																					  device,
																					  *pipelineLayout,
																					  *renderPass,
																					  *vertexShader,
																					  *fragmentShader,
																					  vertexBindings,
																					  vertexAttribs,
																					  size,
																					  vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST));
	const vk::Unique<vk::VkCommandPool>		cmdPool			(makeCommandPool(vk, device, PROTECTION_ENABLED, queueFamilyIndex));
	const vk::Unique<vk::VkCommandBuffer>	cmdBuffer		(vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	beginCommandBuffer(vk, *cmdBuffer);
	{
		const vk::VkImageMemoryBarrier	attachmentStartBarrier =
		{
			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
			DE_NULL,
			0u,
			vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
			vk::VK_IMAGE_LAYOUT_UNDEFINED,
			vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
			queueFamilyIndex,
			queueFamilyIndex,
			colorImage,
			{ vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }
		};

		vk.cmdPipelineBarrier(*cmdBuffer,
							  (vk::VkPipelineStageFlags)vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
							  (vk::VkPipelineStageFlags)vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
							  (vk::VkDependencyFlags)0u,
							  0u, (const vk::VkMemoryBarrier*)DE_NULL,
							  0u, (const vk::VkBufferMemoryBarrier*)DE_NULL,
							  1u, &attachmentStartBarrier);
	}

	beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, vk::makeRect2D(0, 0, size.x(), size.y()), tcu::Vec4(0.0f, 0.0f, 0.5f, 1.0f));

	vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
	vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);

	{
		const vk::VkDeviceSize vertexBufferOffset = 0;
		vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &**vertexBuffer, &vertexBufferOffset);
	}

	vk.cmdDraw(*cmdBuffer, /*vertexCount*/ (deUint32)posCoords.size(), 1u, 0u, 0u);

	endRenderPass(vk, *cmdBuffer);

	// color attachment render end barrier
	{
		const vk::VkImageMemoryBarrier	attachmentEndBarrier =
		{
			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
			DE_NULL,
			vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
			vk::VK_ACCESS_SHADER_READ_BIT,
			vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
			vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
			queueFamilyIndex,
			queueFamilyIndex,
			colorImage,
			{ vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }
		};

		vk.cmdPipelineBarrier(*cmdBuffer,
							  (vk::VkPipelineStageFlags)vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
							  (vk::VkPipelineStageFlags)vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
							  (vk::VkDependencyFlags)0u,
							  0u, (const vk::VkMemoryBarrier*)DE_NULL,
							  0u, (const vk::VkBufferMemoryBarrier*)DE_NULL,
							  1u, &attachmentEndBarrier);
	}

	endCommandBuffer(vk, *cmdBuffer);

	// Submit command buffer
	{
		const vk::Unique<vk::VkFence>	fence		(vk::createFence(vk, device));
		VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull));
	}
}

void generateYCbCrImage (ProtectedContext&				ctx,
						const TestConfig&				config,
						const tcu::UVec2				size,
						const std::vector<tcu::Vec2>&	texCoords,
						ycbcr::MultiPlaneImageData&		ycbcrSrc,
						std::vector<tcu::Vec4>&			ycbcrMinBounds,
						std::vector<tcu::Vec4>&			ycbcrMaxBounds)
{
	tcu::TestLog&							log						(ctx.getTestContext().getLog());
	const tcu::FloatFormat					filteringPrecision		(ycbcr::getYCbCrFilteringPrecision(config.format));
	const tcu::FloatFormat					conversionPrecision		(ycbcr::getYCbCrConversionPrecision(config.format));
	const tcu::UVec4						bitDepth				(ycbcr::getYCbCrBitDepth(config.format));
	bool									explicitReconstruction	= config.explicitReconstruction;
	const deUint32							subTexelPrecisionBits	(vk::getPhysicalDeviceProperties(ctx.getInstanceDriver(),
																									 ctx.getPhysicalDevice()).limits.subTexelPrecisionBits);


	const vk::PlanarFormatDescription	planeInfo				(vk::getPlanarFormatDescription(config.format));

	deUint32							nullAccessData			(0u);
	ycbcr::ChannelAccess				nullAccess				(tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT, 1u, tcu::IVec3(size.x(), size.y(), 1), tcu::IVec3(0, 0, 0), &nullAccessData, 0u);
	deUint32							nullAccessAlphaData		(~0u);
	ycbcr::ChannelAccess				nullAccessAlpha			(tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT, 1u, tcu::IVec3(size.x(), size.y(), 1), tcu::IVec3(0, 0, 0), &nullAccessAlphaData, 0u);
	ycbcr::ChannelAccess				rChannelAccess			(planeInfo.hasChannelNdx(0) ? getChannelAccess(ycbcrSrc, planeInfo, size, 0) : nullAccess);
	ycbcr::ChannelAccess				gChannelAccess			(planeInfo.hasChannelNdx(1) ? getChannelAccess(ycbcrSrc, planeInfo, size, 1) : nullAccess);
	ycbcr::ChannelAccess				bChannelAccess			(planeInfo.hasChannelNdx(2) ? getChannelAccess(ycbcrSrc, planeInfo, size, 2) : nullAccess);
	ycbcr::ChannelAccess				aChannelAccess			(planeInfo.hasChannelNdx(3) ? getChannelAccess(ycbcrSrc, planeInfo, size, 3) : nullAccessAlpha);
	const bool							implicitNearestCosited	((config.chromaFilter == vk::VK_FILTER_NEAREST && !explicitReconstruction) &&
																 (config.xChromaOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN_KHR || config.yChromaOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN_KHR));

	for (deUint32 planeNdx = 0; planeNdx < planeInfo.numPlanes; planeNdx++)
		deMemset(ycbcrSrc.getPlanePtr(planeNdx), 0u, ycbcrSrc.getPlaneSize(planeNdx));

	// \todo Limit values to only values that produce defined values using selected colorRange and colorModel? The verification code handles those cases already correctly.
	if (planeInfo.hasChannelNdx(0))
	{
		for (int y = 0; y < rChannelAccess.getSize().y(); y++)
		for (int x = 0; x < rChannelAccess.getSize().x(); x++)
			rChannelAccess.setChannel(tcu::IVec3(x, y, 0), (float)x / (float)rChannelAccess.getSize().x());
	}

	if (planeInfo.hasChannelNdx(1))
	{
		for (int y = 0; y < gChannelAccess.getSize().y(); y++)
		for (int x = 0; x < gChannelAccess.getSize().x(); x++)
			gChannelAccess.setChannel(tcu::IVec3(x, y, 0), (float)y / (float)gChannelAccess.getSize().y());
	}

	if (planeInfo.hasChannelNdx(2))
	{
		for (int y = 0; y < bChannelAccess.getSize().y(); y++)
		for (int x = 0; x < bChannelAccess.getSize().x(); x++)
			bChannelAccess.setChannel(tcu::IVec3(x, y, 0), (float)(x + y) / (float)(bChannelAccess.getSize().x() + bChannelAccess.getSize().y()));
	}

	if (planeInfo.hasChannelNdx(3))
	{
		for (int y = 0; y < aChannelAccess.getSize().y(); y++)
		for (int x = 0; x < aChannelAccess.getSize().x(); x++)
			aChannelAccess.setChannel(tcu::IVec3(x, y, 0), (float)(x * y) / (float)(aChannelAccess.getSize().x() * aChannelAccess.getSize().y()));
	}

	std::vector<tcu::Vec4>				uvBounds;
	std::vector<tcu::IVec4>				ijBounds;
	ycbcr::calculateBounds(rChannelAccess, gChannelAccess, bChannelAccess, aChannelAccess, bitDepth, texCoords, filteringPrecision, conversionPrecision, subTexelPrecisionBits, config.textureFilter, config.colorModel, config.colorRange, config.chromaFilter, config.xChromaOffset, config.yChromaOffset, config.componentMapping, explicitReconstruction, config.addressModeU, config.addressModeV, ycbcrMinBounds, ycbcrMaxBounds, uvBounds, ijBounds);

	// Handle case: If implicit reconstruction and chromaFilter == NEAREST, an implementation may behave as if both chroma offsets are MIDPOINT.
	if (implicitNearestCosited)
	{
		std::vector<tcu::Vec4>			relaxedYcbcrMinBounds;
		std::vector<tcu::Vec4>			relaxedYcbcrMaxBounds;

		ycbcr::calculateBounds(rChannelAccess, gChannelAccess, bChannelAccess, aChannelAccess, bitDepth, texCoords, filteringPrecision, conversionPrecision, subTexelPrecisionBits, config.textureFilter, config.colorModel, config.colorRange, config.chromaFilter, vk::VK_CHROMA_LOCATION_MIDPOINT_KHR, vk::VK_CHROMA_LOCATION_MIDPOINT_KHR, config.componentMapping, explicitReconstruction, config.addressModeU, config.addressModeV, relaxedYcbcrMinBounds, relaxedYcbcrMaxBounds, uvBounds, ijBounds);

		DE_ASSERT(relaxedYcbcrMinBounds.size() == ycbcrMinBounds.size());
		DE_ASSERT(relaxedYcbcrMaxBounds.size() == ycbcrMaxBounds.size());

		for (size_t i = 0; i < ycbcrMinBounds.size(); i++)
		{
			ycbcrMinBounds[i] = tcu::Vec4(de::min<float>(ycbcrMinBounds[i].x(), relaxedYcbcrMinBounds[i].x()),
										  de::min<float>(ycbcrMinBounds[i].y(), relaxedYcbcrMinBounds[i].y()),
										  de::min<float>(ycbcrMinBounds[i].z(), relaxedYcbcrMinBounds[i].z()),
										  de::min<float>(ycbcrMinBounds[i].w(), relaxedYcbcrMinBounds[i].w()));

			ycbcrMaxBounds[i] = tcu::Vec4(de::max<float>(ycbcrMaxBounds[i].x(), relaxedYcbcrMaxBounds[i].x()),
										  de::max<float>(ycbcrMaxBounds[i].y(), relaxedYcbcrMaxBounds[i].y()),
										  de::max<float>(ycbcrMaxBounds[i].z(), relaxedYcbcrMaxBounds[i].z()),
										  de::max<float>(ycbcrMaxBounds[i].w(), relaxedYcbcrMaxBounds[i].w()));
		}
	}

	if (vk::isYCbCrFormat(config.format))
	{
		tcu::TextureLevel	rImage	(tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::FLOAT), rChannelAccess.getSize().x(), rChannelAccess.getSize().y());
		tcu::TextureLevel	gImage	(tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::FLOAT), gChannelAccess.getSize().x(), gChannelAccess.getSize().y());
		tcu::TextureLevel	bImage	(tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::FLOAT), bChannelAccess.getSize().x(), bChannelAccess.getSize().y());
		tcu::TextureLevel	aImage	(tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::FLOAT), aChannelAccess.getSize().x(), aChannelAccess.getSize().y());

		for (int y = 0; y < (int)rChannelAccess.getSize().y(); y++)
		for (int x = 0; x < (int)rChannelAccess.getSize().x(); x++)
			rImage.getAccess().setPixel(tcu::Vec4(rChannelAccess.getChannel(tcu::IVec3(x, y, 0))), x, y);

		for (int y = 0; y < (int)gChannelAccess.getSize().y(); y++)
		for (int x = 0; x < (int)gChannelAccess.getSize().x(); x++)
			gImage.getAccess().setPixel(tcu::Vec4(gChannelAccess.getChannel(tcu::IVec3(x, y, 0))), x, y);

		for (int y = 0; y < (int)bChannelAccess.getSize().y(); y++)
		for (int x = 0; x < (int)bChannelAccess.getSize().x(); x++)
			bImage.getAccess().setPixel(tcu::Vec4(bChannelAccess.getChannel(tcu::IVec3(x, y, 0))), x, y);

		for (int y = 0; y < (int)aChannelAccess.getSize().y(); y++)
		for (int x = 0; x < (int)aChannelAccess.getSize().x(); x++)
			aImage.getAccess().setPixel(tcu::Vec4(aChannelAccess.getChannel(tcu::IVec3(x, y, 0))), x, y);

		{
			const tcu::Vec4	scale	(1.0f);
			const tcu::Vec4	bias	(0.0f);

			log << tcu::TestLog::Image("SourceImageR", "SourceImageR", rImage.getAccess(), scale, bias);
			log << tcu::TestLog::Image("SourceImageG", "SourceImageG", gImage.getAccess(), scale, bias);
			log << tcu::TestLog::Image("SourceImageB", "SourceImageB", bImage.getAccess(), scale, bias);
			log << tcu::TestLog::Image("SourceImageA", "SourceImageA", aImage.getAccess(), scale, bias);
		}
	}
	else
	{
		tcu::TextureLevel	ycbcrSrcImage	(vk::mapVkFormat(config.format), size.x(), size.y());

		for (int y = 0; y < (int)size.y(); y++)
		for (int x = 0; x < (int)size.x(); x++)
		{
			const tcu::IVec3 pos (x, y, 0);
			ycbcrSrcImage.getAccess().setPixel(tcu::Vec4(rChannelAccess.getChannel(pos),
														 gChannelAccess.getChannel(pos),
														 bChannelAccess.getChannel(pos),
														 aChannelAccess.getChannel(pos)),
											   x, y);
		}

		log << tcu::TestLog::Image("SourceImage", "SourceImage", ycbcrSrcImage.getAccess());
	}
}

tcu::TestStatus conversionTest (Context& context, TestConfig config)
{
	std::vector<std::string>							requiredDevExt;
	requiredDevExt.push_back("VK_KHR_sampler_ycbcr_conversion");
	requiredDevExt.push_back("VK_KHR_get_memory_requirements2");
	requiredDevExt.push_back("VK_KHR_bind_memory2");
	requiredDevExt.push_back("VK_KHR_maintenance1");

	const tcu::UVec2									size					(ycbcr::isXChromaSubsampled(config.format) ? 12 : 7,
																				 ycbcr::isYChromaSubsampled(config.format) ?  8 : 13);

	ProtectedContext									ctx						(context, std::vector<std::string>(), requiredDevExt);
	const vk::DeviceInterface&							vk						= ctx.getDeviceInterface();
	const vk::VkDevice									device					= ctx.getDevice();
	const deUint32										queueFamilyIndex		= ctx.getQueueFamilyIndex();

	tcu::TestLog&										log						(context.getTestContext().getLog());

	validateFormatSupport(ctx, config);
	logTestCaseInfo(log, config);

	const vk::VkImageCreateFlagBits						ycbcrImageFlags			 = config.disjoint
																					? vk::VK_IMAGE_CREATE_DISJOINT_BIT
																					: (vk::VkImageCreateFlagBits)0u;
	const de::MovePtr<vk::YCbCrImageWithMemory>			ycbcrImage				(createYcbcrImage2D(ctx, PROTECTION_ENABLED,
																									size.x(), size.y(),
																									config.format,
																									ycbcrImageFlags,
																									vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT
																									 | vk::VK_IMAGE_USAGE_SAMPLED_BIT));
	const vk::Unique<vk::VkSamplerYcbcrConversion>		conversion				(createConversion(vk,
																								  device,
																								  config.format,
																								  config.colorModel,
																								  config.colorRange,
																								  config.xChromaOffset,
																								  config.yChromaOffset,
																								  config.chromaFilter,
																								  config.componentMapping,
																								  config.explicitReconstruction));
	const vk::Unique<vk::VkSampler>						ycbcrSampler			(createSampler(vk,
																							   device,
																							   config.textureFilter,
																							   config.addressModeU,
																							   config.addressModeV,
																							   *conversion));
	const vk::Unique<vk::VkImageView>					ycbcrImageView			(createImageView(vk, device, **ycbcrImage, config.format, *conversion));


	// Input attributes
	std::vector<tcu::Vec2>								texCoords;
	std::vector<tcu::Vec2>								posCoords;
	genTexCoords(texCoords, size);
	posCoords = computeVertexPositions((deUint32)texCoords.size(), size.cast<int>());

	// Input validation data
	std::vector<tcu::Vec4>								ycbcrMinBounds;
	std::vector<tcu::Vec4>								ycbcrMaxBounds;

	// Generate input ycbcr image and conversion reference
	{
		ycbcr::MultiPlaneImageData						ycbcrSrc				(config.format, size);

		generateYCbCrImage(ctx, config, size, texCoords, ycbcrSrc, ycbcrMinBounds, ycbcrMaxBounds);
		logBoundImages(log, size, ycbcrMinBounds, ycbcrMaxBounds);
		uploadYCbCrImage(ctx,
						 **ycbcrImage,
						 ycbcrSrc,
						 vk::VK_ACCESS_SHADER_READ_BIT,
						 vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
	}

	// Build up the reference data structure
	DE_ASSERT(posCoords.size() == ycbcrMinBounds.size());
	DE_ASSERT(posCoords.size() == ycbcrMaxBounds.size());
	DE_ASSERT(texCoords.size() >= CHECK_SIZE);
	std::vector<YCbCrValidationData>	referenceData;
	std::vector<YCbCrValidationData>	colorReferenceData;

	for (deUint32 ndx = 0; ndx < texCoords.size(); ++ndx)
	{
		YCbCrValidationData	data;
		data.coord		= texCoords[ndx].toWidth<4>();
		data.minBound	= ycbcrMinBounds[ndx];
		data.maxBound	= ycbcrMaxBounds[ndx];

		referenceData.push_back(data);

		YCbCrValidationData	colorData;
		colorData.coord		= posCoords[ndx].toWidth<4>();
		colorData.minBound	= tcu::Vec4(0.0f, 0.9f, 0.0f, 1.0f);
		colorData.maxBound	= tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);

		colorReferenceData.push_back(colorData);
	}

	if (config.shaderType == glu::SHADERTYPE_VERTEX
		|| config.shaderType == glu::SHADERTYPE_FRAGMENT)
	{
		const de::UniquePtr<vk::ImageWithMemory>	colorImage			(createImage2D(ctx,
																				   PROTECTION_ENABLED,
																				   queueFamilyIndex,
																				   size.x(),
																				   size.y(),
																				   s_colorFormat,
																				   vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
																				    | vk::VK_IMAGE_USAGE_SAMPLED_BIT));
		const vk::Unique<vk::VkImageView>			colorImageView		(createImageView(ctx, **colorImage, s_colorFormat));
		const vk::Unique<vk::VkSampler>				colorSampler		(makeSampler(vk, device));

		renderYCbCrToColor(ctx, size, *ycbcrSampler, *ycbcrImageView, **colorImage, *colorImageView, referenceData, posCoords);

		if (!validateImage(ctx, colorReferenceData, *colorSampler, *colorImageView))
			return tcu::TestStatus::fail("YCbCr image conversion via fragment shader failed");
	}
	else if (config.shaderType == glu::SHADERTYPE_COMPUTE)
	{
		if (!validateImage(ctx, referenceData, *ycbcrSampler, *ycbcrImageView))
			return tcu::TestStatus::fail("YCbCr image conversion via compute shader failed");
	}
	else
	{
		TCU_THROW(NotSupportedError, "Unsupported shader test type");
	}

	return tcu::TestStatus::pass("YCbCr image conversion was OK");
}

} // anonymous


tcu::TestCaseGroup*	createYCbCrConversionTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> testGroup (new tcu::TestCaseGroup(testCtx, "ycbcr", "YCbCr conversion tests"));

	struct {
		const char *			name;
		const glu::ShaderType	type;
	} shaderTypes[]	=
	{
		{ "fragment",	glu::SHADERTYPE_FRAGMENT	},
		{ "compute",	glu::SHADERTYPE_COMPUTE		}
	};

	struct RangeNamePair
	{
		const char*					name;
		vk::VkSamplerYcbcrRange		value;
	};
	struct ChromaLocationNamePair
	{
		const char*				name;
		vk::VkChromaLocation	value;
	};

	const vk::VkComponentMapping			identitySwizzle		=
	{
		vk::VK_COMPONENT_SWIZZLE_IDENTITY,
		vk::VK_COMPONENT_SWIZZLE_IDENTITY,
		vk::VK_COMPONENT_SWIZZLE_IDENTITY,
		vk::VK_COMPONENT_SWIZZLE_IDENTITY
	};

	const RangeNamePair						colorRanges[]		=
	{
		{ "itu_full",		vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL		},
		{ "itu_narrow",		vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW	}
	};

	const ChromaLocationNamePair			chromaLocations[] =
	{
		{ "cosited",		vk::VK_CHROMA_LOCATION_COSITED_EVEN		},
		{ "midpoint",		vk::VK_CHROMA_LOCATION_MIDPOINT			}
	};

	const struct
	{
		const char* const							name;
		const vk::VkSamplerYcbcrModelConversion		value;
	}										colorModels[] =
	{
		{ "rgb_identity",	vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY		},
		{ "ycbcr_identity",	vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY	},
		{ "ycbcr_709",		vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709			},
		{ "ycbcr_601",		vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601			},
		{ "ycbcr_2020",		vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020		}
	};

	const struct
	{
		const char*			name;
		vk::VkImageTiling	value;
	}										imageTilings[] =
	{
		{ "tiling_linear",	vk::VK_IMAGE_TILING_LINEAR },
		{ "tiling_optimal",	vk::VK_IMAGE_TILING_OPTIMAL }
	};

	const deUint32					tilingNdx				= 1;
	const vk::VkImageTiling			tiling					= imageTilings[tilingNdx].value;
	const char*						tilingName				= imageTilings[tilingNdx].name;

	const vk::VkFormat testFormats[] =
	{
		// noChromaSubsampledFormats
		vk::VK_FORMAT_R4G4B4A4_UNORM_PACK16,
		vk::VK_FORMAT_B4G4R4A4_UNORM_PACK16,
		vk::VK_FORMAT_R5G6B5_UNORM_PACK16,
		vk::VK_FORMAT_B5G6R5_UNORM_PACK16,
		vk::VK_FORMAT_R5G5B5A1_UNORM_PACK16,
		vk::VK_FORMAT_B5G5R5A1_UNORM_PACK16,
		vk::VK_FORMAT_A1R5G5B5_UNORM_PACK16,
		vk::VK_FORMAT_R8G8B8_UNORM,
		vk::VK_FORMAT_B8G8R8_UNORM,
		vk::VK_FORMAT_R8G8B8A8_UNORM,
		vk::VK_FORMAT_B8G8R8A8_UNORM,
		vk::VK_FORMAT_A8B8G8R8_UNORM_PACK32,
		vk::VK_FORMAT_A2R10G10B10_UNORM_PACK32,
		vk::VK_FORMAT_A2B10G10R10_UNORM_PACK32,
		vk::VK_FORMAT_R16G16B16_UNORM,
		vk::VK_FORMAT_R16G16B16A16_UNORM,
		vk::VK_FORMAT_R10X6_UNORM_PACK16,
		vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16,
		vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
		vk::VK_FORMAT_R12X4_UNORM_PACK16,
		vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16,
		vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16,
		vk::VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM,
		vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16,
		vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16,
		vk::VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM,

		// xChromaSubsampledFormats
		vk::VK_FORMAT_G8B8G8R8_422_UNORM,
		vk::VK_FORMAT_B8G8R8G8_422_UNORM,
		vk::VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
		vk::VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,

		vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
		vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16,
		vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16,
		vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,
		vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
		vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16,
		vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16,
		vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,
		vk::VK_FORMAT_G16B16G16R16_422_UNORM,
		vk::VK_FORMAT_B16G16R16G16_422_UNORM,
		vk::VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM,
		vk::VK_FORMAT_G16_B16R16_2PLANE_422_UNORM,

		// xyChromaSubsampledFormats
		vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
		vk::VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
		vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16,
		vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
		vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16,
		vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
		vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM,
		vk::VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,
	};

	for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(testFormats); formatNdx++)
	{
		const vk::VkFormat				format		(testFormats[formatNdx]);
		const std::string				formatName	(de::toLower(std::string(getFormatName(format)).substr(10)));
		de::MovePtr<tcu::TestCaseGroup>	formatGroup	(new tcu::TestCaseGroup(testCtx, formatName.c_str(), ("Tests for color conversion using format " + formatName).c_str()));

		for (size_t shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(shaderTypes); shaderNdx++)
		{
			const char*						shaderTypeName	= shaderTypes[shaderNdx].name;
			de::MovePtr<tcu::TestCaseGroup>	shaderGroup (new tcu::TestCaseGroup(testCtx, shaderTypeName, "YCbCr conversion tests"));

			for (size_t modelNdx = 0; modelNdx < DE_LENGTH_OF_ARRAY(colorModels); modelNdx++)
			{
				const char* const							colorModelName	(colorModels[modelNdx].name);
				const vk::VkSamplerYcbcrModelConversion		colorModel		(colorModels[modelNdx].value);

				if (colorModel != vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY && ycbcr::getYCbCrFormatChannelCount(format) < 3)
					continue;

				de::MovePtr<tcu::TestCaseGroup> colorModelGroup (new tcu::TestCaseGroup(testCtx, colorModelName, "YCbCr conversion tests"));

				for (size_t rangeNdx = 0; rangeNdx < DE_LENGTH_OF_ARRAY(colorRanges); rangeNdx++)
				{
					const char* const					colorRangeName	(colorRanges[rangeNdx].name);
					const vk::VkSamplerYcbcrRange		colorRange		(colorRanges[rangeNdx].value);

					// Narrow range doesn't really work with formats that have less than 8 bits
					if (colorRange == vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW)
					{
						const tcu::UVec4 bitDepth	(ycbcr::getYCbCrBitDepth(format));
						if (bitDepth[0] < 8 || bitDepth[1] < 8 || bitDepth[2] < 8)
							continue;
					}

					de::MovePtr<tcu::TestCaseGroup>		colorRangeGroup	(new tcu::TestCaseGroup(testCtx, colorRangeName, ("Tests for color range " + std::string(colorRangeName)).c_str()));

					for (size_t chromaOffsetNdx = 0; chromaOffsetNdx < DE_LENGTH_OF_ARRAY(chromaLocations); chromaOffsetNdx++)
					{
						const char* const				chromaOffsetName	(chromaLocations[chromaOffsetNdx].name);
						const vk::VkChromaLocation		chromaOffset		(chromaLocations[chromaOffsetNdx].value);


						for (deUint32 disjointNdx = 0; disjointNdx < 2; ++disjointNdx)
						{
							bool				disjoint	= (disjointNdx == 1);
							const TestConfig	config	(shaderTypes[shaderNdx].type,
														 format,
														 tiling,
														 vk::VK_FILTER_NEAREST,
														 vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
														 vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
														 vk::VK_FILTER_NEAREST,
														 chromaOffset,
														 chromaOffset,
														 false,
														 disjoint,
														 colorRange,
														 colorModel,
														 identitySwizzle);

							addFunctionCaseWithPrograms(colorRangeGroup.get(),
														std::string(tilingName) + "_" + chromaOffsetName + (disjoint ? "_disjoint" : ""),
														"",
														testShaders,
														conversionTest,
														config);
						}
					}

					colorModelGroup->addChild(colorRangeGroup.release());
				}

				shaderGroup->addChild(colorModelGroup.release());
			}

			formatGroup->addChild(shaderGroup.release());

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

	return testGroup.release();
}

} // ProtectedMem
} // vkt
