/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2017 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Texture color conversion tests
 *//*--------------------------------------------------------------------*/

#include "vktYCbCrConversionTests.hpp"

#include "vktShaderExecutor.hpp"
#include "vktTestCaseUtil.hpp"
#include "vktTestGroupUtil.hpp"
#include "vktYCbCrUtil.hpp"

#include "vkImageUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkPrograms.hpp"
#include "vkRefUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkQueryUtil.hpp"

#include "tcuInterval.hpp"
#include "tcuTestLog.hpp"
#include "tcuTexture.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuVector.hpp"
#include "tcuVectorUtil.hpp"
#include "tcuFloatFormat.hpp"
#include "tcuFloat.hpp"

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

#include "deMath.h"
#include "deFloat16.h"

#include <vector>
#include <iomanip>

// \todo When defined color conversion extension is not used and conversion is performed in the shader
// #define FAKE_COLOR_CONVERSION

using tcu::Vec2;
using tcu::Vec4;

using tcu::UVec2;
using tcu::UVec4;

using tcu::IVec2;
using tcu::IVec3;
using tcu::IVec4;

using tcu::TestLog;
using tcu::FloatFormat;

using std::vector;
using std::string;

using namespace vkt::shaderexecutor;

namespace vkt
{
namespace ycbcr
{
namespace
{
typedef de::SharedPtr<vk::Unique<vk::VkBuffer> > VkBufferSp;
typedef de::SharedPtr<vk::Allocation> AllocationSp;

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

ShaderSpec createShaderSpec (deUint32 samplerBinding, const std::vector<vk::VkSamplerYcbcrModelConversion>&	colorModels)
{
	ShaderSpec spec;

	spec.inputs.push_back(Symbol("uv", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_HIGHP)));
	// shader with single sampler
	if (colorModels.size()==1)
	{
		spec.globalDeclarations	= "layout(set=" + de::toString((int)EXTRA_RESOURCES_DESCRIPTOR_SET_INDEX) + ", binding=" + de::toString(samplerBinding) + ") uniform highp sampler2D u_sampler;";

		spec.outputs.push_back(Symbol("o_color", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));

		spec.source				= "o_color = texture(u_sampler, uv);\n";
	}
	else // shader with array of samplers
	{
		spec.globalDeclarations	= "layout(set=" + de::toString((int)EXTRA_RESOURCES_DESCRIPTOR_SET_INDEX) + ", binding=" + de::toString(samplerBinding) + ") uniform highp sampler2D u_sampler[" + de::toString(colorModels.size()) +  "];";

		for (int i = 0; i < (int)colorModels.size(); i++)
		{
			spec.outputs.push_back(Symbol(string("o_color") + de::toString(i), glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));

			spec.source += string("o_color") + de::toString(i) + " = texture(u_sampler[" + de::toString(i) + "], uv);\n";
		}
	}
	return spec;
}

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

		const float	fw	= (float)srcSize.x();
		const float	fh	= (float)srcSize.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(Vec2(s, t));
	}
}

void genOneToOneTexCoords (std::vector<Vec2>&	coords,
						   const UVec2&			size)
{
	for (deUint32 y = 0; y < size.y(); y++)
	for (deUint32 x = 0; x < size.x(); x++)
	{
		const float s = ((float)x + 0.5f) / (float)size.x();
		const float t = ((float)y + 0.5f) / (float)size.y();

		coords.push_back(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_,
				 const UVec2							srcSize_,
				 const UVec2							dstSize_,
				 deUint32								samplerBinding_)
		: 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_)
		, srcSize					(srcSize_)
		, dstSize					(dstSize_)
		, samplerBinding			(samplerBinding_)
	{
	}

	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;
	const UVec2								srcSize;
	const UVec2								dstSize;
	deUint32								samplerBinding;
};

vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface&											vkd,
															   vk::VkDevice															device,
															   const std::vector<de::SharedPtr<vk::Unique<vk::VkSampler> > >&		samplers,
															   deUint32																samplerBinding)
{
	std::vector<vk::VkSampler> sampler;
	for (size_t i = 0; i < samplers.size(); i++)
		sampler.push_back(samplers[i]->get());
	const vk::VkDescriptorSetLayoutBinding		layoutBindings[] =
	{
		{
			samplerBinding,
			vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
			(deUint32)sampler.size(),
			vk::VK_SHADER_STAGE_ALL,
			sampler.data()
		}
	};
	const vk::VkDescriptorSetLayoutCreateInfo	layoutCreateInfo	=
	{
		vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
		DE_NULL,

		0u,
		DE_LENGTH_OF_ARRAY(layoutBindings),
		layoutBindings
	};

	return vk::createDescriptorSetLayout(vkd, device, &layoutCreateInfo);
}

vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface&											vkd,
													 vk::VkDevice														device,
													 const std::vector<de::SharedPtr<vk::Unique<vk::VkSampler> > >&		samplers)
{
	const vk::VkDescriptorPoolSize			poolSizes[]					=
	{
		{ vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, (deUint32)samplers.size() }
	};
	const vk::VkDescriptorPoolCreateInfo	descriptorPoolCreateInfo	=
	{
		vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
		DE_NULL,
		vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,

		1u,
		DE_LENGTH_OF_ARRAY(poolSizes),
		poolSizes
	};

	return createDescriptorPool(vkd, device, &descriptorPoolCreateInfo);
}

vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface&											vkd,
												   vk::VkDevice															device,
												   vk::VkDescriptorPool													descriptorPool,
												   vk::VkDescriptorSetLayout											layout,
												   const std::vector<de::SharedPtr<vk::Unique<vk::VkSampler> > >&		samplers,
												   const std::vector<de::SharedPtr<vk::Unique<vk::VkImageView> > >&		imageViews,
												   deUint32																samplerBinding)
{
	const vk::VkDescriptorSetAllocateInfo		descriptorSetAllocateInfo	=
	{
		vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
		DE_NULL,

		descriptorPool,
		1u,
		&layout
	};
	vk::Move<vk::VkDescriptorSet>	descriptorSet	(vk::allocateDescriptorSet(vkd, device, &descriptorSetAllocateInfo));
	std::vector<vk::VkDescriptorImageInfo>	imageInfo;
	for (size_t i = 0; i < samplers.size(); i++)
	{
		const vk::VkDescriptorImageInfo	ii =
		{
			samplers[i]->get(),
			imageViews[i]->get(),
			vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
		};
		imageInfo.push_back(ii);
	}

	{
		const vk::VkWriteDescriptorSet	writes[]	=
		{
			{
				vk::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
				DE_NULL,

				*descriptorSet,
				samplerBinding,
				0u,
				(deUint32)imageInfo.size(),
				vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
				imageInfo.data(),
				DE_NULL,
				DE_NULL
			}
		};

		vkd.updateDescriptorSets(device, DE_LENGTH_OF_ARRAY(writes), writes, 0u, DE_NULL);
	}

	return descriptorSet;
}

vk::Move<vk::VkSampler> createSampler (const vk::DeviceInterface&		vkd,
									   vk::VkDevice						device,
									   vk::VkFilter						textureFilter,
									   vk::VkSamplerAddressMode			addressModeU,
									   vk::VkSamplerAddressMode			addressModeV,
									   vk::VkSamplerYcbcrConversion		conversion)
{
#if !defined(FAKE_COLOR_CONVERSION)
	const vk::VkSamplerYcbcrConversionInfo	samplerConversionInfo	=
	{
		vk::VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
		DE_NULL,
		conversion
	};
#else
	DE_UNREF(conversion);
#endif
	const vk::VkSamplerCreateInfo	createInfo	=
	{
		vk::VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
#if !defined(FAKE_COLOR_CONVERSION)
		&samplerConversionInfo,
#else
		DE_NULL,
#endif

		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::VkImage> createImage (const vk::DeviceInterface&	vkd,
								   vk::VkDevice					device,
								   vk::VkFormat					format,
								   const UVec2&					size,
								   bool							disjoint,
								   vk::VkImageTiling			tiling)
{
	const vk::VkImageCreateInfo createInfo =
	{
		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
		DE_NULL,
		disjoint ? (vk::VkImageCreateFlags)vk::VK_IMAGE_CREATE_DISJOINT_BIT : (vk::VkImageCreateFlags)0u,

		vk::VK_IMAGE_TYPE_2D,
		format,
		vk::makeExtent3D(size.x(), size.y(), 1u),
		1u,
		1u,
		vk::VK_SAMPLE_COUNT_1_BIT,
		tiling,
		vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT | vk::VK_IMAGE_USAGE_SAMPLED_BIT,
		vk::VK_SHARING_MODE_EXCLUSIVE,
		0u,
		(const deUint32*)DE_NULL,
		vk::VK_IMAGE_LAYOUT_PREINITIALIZED,
	};

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

vk::Move<vk::VkImageView> createImageView (const vk::DeviceInterface&		vkd,
										   vk::VkDevice						device,
										   vk::VkImage						image,
										   vk::VkFormat						format,
										   vk::VkSamplerYcbcrConversion		conversion)
{
#if !defined(FAKE_COLOR_CONVERSION)
	const vk::VkSamplerYcbcrConversionInfo	conversionInfo	=
	{
		vk::VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
		DE_NULL,
		conversion
	};
#else
	DE_UNREF(conversion);
#endif
	const vk::VkImageViewCreateInfo				viewInfo		=
	{
		vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
#if defined(FAKE_COLOR_CONVERSION)
		DE_NULL,
#else
		&conversionInfo,
#endif
		(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,
														 vk::VkDevice							device,
														 vk::VkFormat							format,
														 vk::VkSamplerYcbcrModelConversion		colorModel,
														 vk::VkSamplerYcbcrRange				colorRange,
														 vk::VkChromaLocation					xChromaOffset,
														 vk::VkChromaLocation					yChromaOffset,
														 vk::VkFilter							chromaFilter,
														 const vk::VkComponentMapping&			componentMapping,
														 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 evalShader (Context&												context,
				 glu::ShaderType										shaderType,
				 const MultiPlaneImageData&								imageData,
				 const UVec2&											size,
				 vk::VkFormat											format,
				 vk::VkImageTiling										imageTiling,
				 bool													disjoint,
				 vk::VkFilter											textureFilter,
				 vk::VkSamplerAddressMode								addressModeU,
				 vk::VkSamplerAddressMode								addressModeV,
				 const std::vector<vk::VkSamplerYcbcrModelConversion>&	colorModels,
				 vk::VkSamplerYcbcrRange								colorRange,
				 vk::VkChromaLocation									xChromaOffset,
				 vk::VkChromaLocation									yChromaOffset,
				 vk::VkFilter											chromaFilter,
				 const vk::VkComponentMapping&							componentMapping,
				 bool													explicitReconstruction,
				 const vector<Vec2>&									sts,
				 deUint32												samplerBinding,
				 vector<vector<Vec4> >&									results)
{
	const vk::DeviceInterface&												vkd				(context.getDeviceInterface());
	const vk::VkDevice														device			(context.getDevice());
	std::vector<de::SharedPtr<vk::Unique<vk::VkSamplerYcbcrConversion> > >	conversions;
	std::vector<de::SharedPtr<vk::Unique<vk::VkSampler> > >					samplers;
#if !defined(FAKE_COLOR_CONVERSION)
	for (int i = 0; i < (int)colorModels.size(); i++)
	{
		conversions.push_back(makeSharedPtr(createConversion(vkd, device, format, colorModels[i], colorRange, xChromaOffset, yChromaOffset, chromaFilter, componentMapping, explicitReconstruction)));
		samplers.push_back(makeSharedPtr(createSampler(vkd, device, textureFilter, addressModeU, addressModeV, conversions[i]->get())));
	}
#else
	DE_UNREF(colorRange);
	DE_UNREF(xChromaOffset);
	DE_UNREF(yChromaOffset);
	DE_UNREF(chromaFilter);
	DE_UNREF(explicitReconstruction);
	DE_UNREF(componentMapping);
	samplers.push_back(makeSharedPtr(createSampler(vkd, device, textureFilter, addressModeU, addressModeV, (vk::VkSamplerYcbcrConversion)0u)));
#endif
	const vk::Unique<vk::VkImage>								image				(createImage(vkd, device, format, size, disjoint, imageTiling));
	const vk::MemoryRequirement									memoryRequirement	(imageTiling == vk::VK_IMAGE_TILING_OPTIMAL
																					? vk::MemoryRequirement::Any
																					: vk::MemoryRequirement::HostVisible);
	const vk::VkImageCreateFlags								createFlags			(disjoint ? vk::VK_IMAGE_CREATE_DISJOINT_BIT : (vk::VkImageCreateFlagBits)0u);
	const vector<AllocationSp>									imageMemory			(allocateAndBindImageMemory(vkd, device, context.getDefaultAllocator(), *image, format, createFlags, memoryRequirement));
	std::vector<de::SharedPtr<vk::Unique<vk::VkImageView > > >	imageViews;
#if defined(FAKE_COLOR_CONVERSION)
	imageViews.push_back(makeSharedPtr(createImageView(vkd, device, *image, format, (vk::VkSamplerYcbcrConversion)0)));
#else
	for (int i = 0; i < (int)colorModels.size(); i++)
	{
		imageViews.push_back(makeSharedPtr(createImageView(vkd, device, *image, format, conversions[i]->get())));
	}
#endif

	const vk::Unique<vk::VkDescriptorSetLayout>			layout				(createDescriptorSetLayout(vkd, device, samplers, samplerBinding));
	const vk::Unique<vk::VkDescriptorPool>				descriptorPool		(createDescriptorPool(vkd, device, samplers));
	const vk::Unique<vk::VkDescriptorSet>				descriptorSet		(createDescriptorSet(vkd, device, *descriptorPool, *layout, samplers, imageViews, samplerBinding));

	const ShaderSpec									spec				(createShaderSpec(samplerBinding, colorModels));
	const de::UniquePtr<ShaderExecutor>					executor			(createExecutor(context, shaderType, spec, *layout));

	if (imageTiling == vk::VK_IMAGE_TILING_OPTIMAL)
		uploadImage(vkd, device, context.getUniversalQueueFamilyIndex(), context.getDefaultAllocator(), *image, imageData, vk::VK_ACCESS_SHADER_READ_BIT, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
	else
		fillImageMemory(vkd, device, context.getUniversalQueueFamilyIndex(), *image, imageMemory, imageData, vk::VK_ACCESS_SHADER_READ_BIT, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);

	for(int i=0; i<(int)results.size(); i++)
		results[i].resize(sts.size());

	{
		const void* const	inputs[]	=
		{
			&sts[0]
		};
		vector<void*> outputs;
		for (int i = 0; i < (int)results.size(); i++)
			outputs.push_back((void*)results[i].data());

		executor->execute((int)sts.size(), inputs, outputs.data(), *descriptorSet);
	}
}

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

void checkSupport (Context& context, const TestConfig config)
{
#if !defined(FAKE_COLOR_CONVERSION)
	if (!vk::isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_sampler_ycbcr_conversion"))
		TCU_THROW(NotSupportedError, "Extension VK_KHR_sampler_ycbcr_conversion not supported");

	try
	{
		const vk::VkFormatProperties	properties	(vk::getPhysicalDeviceFormatProperties(context.getInstanceInterface(), 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 (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 (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 (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 (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");
	}
	catch (const vk::Error& err)
	{
		if (err.getError() == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
			TCU_THROW(NotSupportedError, "Format not supported");

		throw;
	}
#endif
}

tcu::TestStatus textureConversionTest (Context& context, const TestConfig config)
{
	const std::vector<FloatFormat>	filteringPrecision		(getPrecision(config.format));
	const std::vector<FloatFormat>	conversionPrecision		(getPrecision(config.format));
	const deUint32					subTexelPrecisionBits	(vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice()).limits.subTexelPrecisionBits);
	const tcu::UVec4				bitDepth				(getYCbCrBitDepth(config.format));
	TestLog&						log						(context.getTestContext().getLog());
	bool							explicitReconstruction	= config.explicitReconstruction;
	const UVec2						srcSize					= config.srcSize;
	const UVec2						dstSize					= config.dstSize;
	bool							isOk					= true;

	logTestCaseInfo(log, config);

#if !defined(FAKE_COLOR_CONVERSION)
	try
	{
		const vk::VkFormatProperties	properties	(vk::getPhysicalDeviceFormatProperties(context.getInstanceInterface(), 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_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT) != 0)
			explicitReconstruction = true;

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

		throw;
	}
#endif

	{
		const vk::PlanarFormatDescription	planeInfo				(vk::getPlanarFormatDescription(config.format));
		MultiPlaneImageData					src						(config.format, srcSize);

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

		vector<Vec2>						sts;
		vector<vector<Vec4> >				results;
		vector<vector<Vec4> >				minBounds;
		vector<vector<Vec4> >				minMidpointBounds;
		vector<vector<Vec4> >				maxBounds;
		vector<vector<Vec4> >				maxMidpointBounds;
		vector<vector<Vec4> >				uvBounds;
		vector<vector<IVec4> >				ijBounds;

		for (deUint32 planeNdx = 0; planeNdx < planeInfo.numPlanes; planeNdx++)
			deMemset(src.getPlanePtr(planeNdx), 0u, src.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(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(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(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(IVec3(x, y, 0), (float)(x * y) / (float)(aChannelAccess.getSize().x() * aChannelAccess.getSize().y()));
		}

		if (dstSize.x() > srcSize.x() && dstSize.y() > srcSize.y())
			genTexCoords(sts, srcSize, dstSize);
		else
			genOneToOneTexCoords(sts, dstSize);

		std::vector< vk::VkSamplerYcbcrModelConversion> colorModels;
		if (config.colorModel != vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_LAST)
		{
			colorModels.push_back(config.colorModel);
		}
		else
		{
			int ycbcrModelConverionCount = std::min( (int)vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_LAST, 4 );
			for (int i = 0; i < ycbcrModelConverionCount; i++)
			{
				colorModels.push_back((vk::VkSamplerYcbcrModelConversion)(vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY + i));
			}
		}

		for (int i = 0; i < (int)colorModels.size(); i++)
		{
			vector<Vec4>				minBound;
			vector<Vec4>				minMidpointBound;
			vector<Vec4>				maxBound;
			vector<Vec4>				maxMidpointBound;
			vector<Vec4>				uvBound;
			vector<IVec4>				ijBound;

			calculateBounds(rChannelAccess, gChannelAccess, bChannelAccess, aChannelAccess, bitDepth, sts, filteringPrecision, conversionPrecision, subTexelPrecisionBits, config.textureFilter, colorModels[i], config.colorRange, config.chromaFilter, config.xChromaOffset, config.yChromaOffset, config.componentMapping, explicitReconstruction, config.addressModeU, config.addressModeV, minBound, maxBound, uvBound, ijBound);

			if (implicitNearestCosited)
			{
				calculateBounds(rChannelAccess, gChannelAccess, bChannelAccess, aChannelAccess, bitDepth, sts, filteringPrecision, conversionPrecision, subTexelPrecisionBits, config.textureFilter, colorModels[i], config.colorRange, config.chromaFilter, vk::VK_CHROMA_LOCATION_MIDPOINT_KHR, vk::VK_CHROMA_LOCATION_MIDPOINT_KHR, config.componentMapping, explicitReconstruction, config.addressModeU, config.addressModeV, minMidpointBound, maxMidpointBound, uvBound, ijBound);
			}
			results.push_back			(vector<Vec4>());
			minBounds.push_back			(minBound);
			minMidpointBounds.push_back	(minMidpointBound);
			maxBounds.push_back			(maxBound);
			maxMidpointBounds.push_back	(maxMidpointBound);
			uvBounds.push_back			(uvBound);
			ijBounds.push_back			(ijBound);
		}

		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(Vec4(rChannelAccess.getChannel(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(Vec4(gChannelAccess.getChannel(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(Vec4(bChannelAccess.getChannel(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(Vec4(aChannelAccess.getChannel(IVec3(x, y, 0))), x, y);

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

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

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

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

		evalShader(context, config.shaderType, src, srcSize, config.format, config.imageTiling, config.disjoint, config.textureFilter, config.addressModeU, config.addressModeV, colorModels, config.colorRange, config.xChromaOffset, config.yChromaOffset, config.chromaFilter, config.componentMapping, config.explicitReconstruction, sts, config.samplerBinding, results);

		{
			std::vector<tcu::TextureLevel>	minImages;
			std::vector<tcu::TextureLevel>	maxImages;
			std::vector<tcu::TextureLevel>	minMidpointImages;
			std::vector<tcu::TextureLevel>	maxMidpointImages;
			std::vector<tcu::TextureLevel>	resImages;
			for (int i = 0; i < (int)colorModels.size(); i++)
			{
				minImages.push_back			(tcu::TextureLevel(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), dstSize.x(), dstSize.y()));
				maxImages.push_back			(tcu::TextureLevel(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), dstSize.x(), dstSize.y()));
				minMidpointImages.push_back	(tcu::TextureLevel(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), dstSize.x(), dstSize.y()));
				maxMidpointImages.push_back	(tcu::TextureLevel(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), dstSize.x(), dstSize.y()));
				resImages.push_back			(tcu::TextureLevel(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), dstSize.x(), dstSize.y()));
			}

			for (int i = 0; i < (int)colorModels.size(); i++)
			for (int y = 0; y < (int)(dstSize.y()); y++)
			for (int x = 0; x < (int)(dstSize.x()); x++)
			{
				const int ndx = x + y * (int)(dstSize.x());
				minImages[i].getAccess().setPixel(minBounds[i][ndx], x, y);
				maxImages[i].getAccess().setPixel(maxBounds[i][ndx], x, y);
			}

			for (int i = 0; i < (int)colorModels.size(); i++)
			for (int y = 0; y < (int)(dstSize.y()); y++)
			for (int x = 0; x < (int)(dstSize.x()); x++)
			{
				const int ndx = x + y * (int)(dstSize.x());
				resImages[i].getAccess().setPixel(results[i][ndx], x, y);
			}

			if (implicitNearestCosited)
			{
				for (int i = 0; i < (int)colorModels.size(); i++)
				for (int y = 0; y < (int)(dstSize.y()); y++)
				for (int x = 0; x < (int)(dstSize.x()); x++)
				{
					const int ndx = x + y * (int)(dstSize.x());
					minMidpointImages[i].getAccess().setPixel(minMidpointBounds[i][ndx], x, y);
					maxMidpointImages[i].getAccess().setPixel(maxMidpointBounds[i][ndx], x, y);
				}
			}

			for (int i = 0; i < (int)colorModels.size(); i++)
			{
				const Vec4	scale	(1.0f);
				const Vec4	bias	(0.0f);

				log << TestLog::Image(string("MinBoundImage_") + de::toString(i), string("MinBoundImage_") + de::toString(i), minImages[i].getAccess(), scale, bias);
				log << TestLog::Image(string("MaxBoundImage_") + de::toString(i), string("MaxBoundImage_") + de::toString(i), maxImages[i].getAccess(), scale, bias);

				if (implicitNearestCosited)
				{
					log << TestLog::Image(string("MinMidpointBoundImage_") + de::toString(i), string("MinMidpointBoundImage_") + de::toString(i), minMidpointImages[i].getAccess(), scale, bias);
					log << TestLog::Image(string("MaxMidpointBoundImage_") + de::toString(i), string("MaxMidpointBoundImage_") + de::toString(i), maxMidpointImages[i].getAccess(), scale, bias);
				}

				log << TestLog::Image(string("ResultImage_") + de::toString(i), string("ResultImage_") + de::toString(i), resImages[i].getAccess(), scale, bias);
			}
		}

		size_t errorCount = 0;

		for (int i = 0; i < (int)colorModels.size(); i++)
		for (size_t ndx = 0; ndx < sts.size(); ndx++)
		{
			bool fail;
			if (implicitNearestCosited)
			{
				fail = (tcu::boolAny(tcu::lessThan(results[i][ndx], minMidpointBounds[i][ndx])) || tcu::boolAny(tcu::greaterThan(results[i][ndx], maxMidpointBounds[i][ndx]))) &&
						(tcu::boolAny(tcu::lessThan(results[i][ndx], minBounds[i][ndx])) || tcu::boolAny(tcu::greaterThan(results[i][ndx], maxBounds[i][ndx])));
			}
			else
			{
				fail = tcu::boolAny(tcu::lessThan(results[i][ndx], minBounds[i][ndx])) || tcu::boolAny(tcu::greaterThan(results[i][ndx], maxBounds[i][ndx]));
			}

			if (fail)
			{
				log << TestLog::Message << "Fail: " << i << " " << sts[ndx] << " " << results[i][ndx] << TestLog::EndMessage;
				log << TestLog::Message << "  Min : " << minBounds[i][ndx] << TestLog::EndMessage;
				log << TestLog::Message << "  Max : " << maxBounds[i][ndx] << TestLog::EndMessage;
				log << TestLog::Message << "  Threshold: " << (maxBounds[i][ndx] - minBounds[i][ndx]) << TestLog::EndMessage;
				log << TestLog::Message << "  UMin : " << uvBounds[i][ndx][0] << TestLog::EndMessage;
				log << TestLog::Message << "  UMax : " << uvBounds[i][ndx][1] << TestLog::EndMessage;
				log << TestLog::Message << "  VMin : " << uvBounds[i][ndx][2] << TestLog::EndMessage;
				log << TestLog::Message << "  VMax : " << uvBounds[i][ndx][3] << TestLog::EndMessage;
				log << TestLog::Message << "  IMin : " << ijBounds[i][ndx][0] << TestLog::EndMessage;
				log << TestLog::Message << "  IMax : " << ijBounds[i][ndx][1] << TestLog::EndMessage;
				log << TestLog::Message << "  JMin : " << ijBounds[i][ndx][2] << TestLog::EndMessage;
				log << TestLog::Message << "  JMax : " << ijBounds[i][ndx][3] << TestLog::EndMessage;

				if (isXChromaSubsampled(config.format))
				{
					log << TestLog::Message << "  LumaAlphaValues : " << TestLog::EndMessage;
					log << TestLog::Message << "    Offset : (" << ijBounds[i][ndx][0] << ", " << ijBounds[i][ndx][2] << ")" << TestLog::EndMessage;

					for (deInt32 k = ijBounds[i][ndx][2]; k <= ijBounds[i][ndx][3] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0); k++)
					{
						const deInt32		wrappedK	= wrap(config.addressModeV, k, gChannelAccess.getSize().y());
						bool				first		= true;
						std::ostringstream	line;

						for (deInt32 j = ijBounds[i][ndx][0]; j <= ijBounds[i][ndx][1] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0); j++)
						{
							const deInt32	wrappedJ	= wrap(config.addressModeU, j, gChannelAccess.getSize().x());

							if (!first)
							{
								line << ", ";
								first = false;
							}

							line << "(" << std::setfill(' ') << std::setw(5) << gChannelAccess.getChannelUint(IVec3(wrappedJ, wrappedK, 0))
								<< ", " << std::setfill(' ') << std::setw(5) << aChannelAccess.getChannelUint(IVec3(wrappedJ, wrappedK, 0)) << ")";
						}
						log << TestLog::Message << "    " << line.str() << TestLog::EndMessage;
					}

					{
						const IVec2 chromaJRange	(divFloor(ijBounds[i][ndx][0], 2) - 1, divFloor(ijBounds[i][ndx][1] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0), 2) + 1);
						const IVec2 chromaKRange	(isYChromaSubsampled(config.format)
													? IVec2(divFloor(ijBounds[i][ndx][2], 2) - 1, divFloor(ijBounds[i][ndx][3] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0), 2) + 1)
													: IVec2(ijBounds[i][ndx][2], ijBounds[i][ndx][3] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0)));

						log << TestLog::Message << "  ChromaValues : " << TestLog::EndMessage;
						log << TestLog::Message << "    Offset : (" << chromaJRange[0] << ", " << chromaKRange[0] << ")" << TestLog::EndMessage;

						for (deInt32 k = chromaKRange[0]; k <= chromaKRange[1]; k++)
						{
							const deInt32		wrappedK	= wrap(config.addressModeV, k, rChannelAccess.getSize().y());
							bool				first		= true;
							std::ostringstream	line;

							for (deInt32 j = chromaJRange[0]; j <= chromaJRange[1]; j++)
							{
								const deInt32	wrappedJ	= wrap(config.addressModeU, j, rChannelAccess.getSize().x());

								if (!first)
								{
									line << ", ";
									first = false;
								}

								line << "(" << std::setfill(' ') << std::setw(5) << rChannelAccess.getChannelUint(IVec3(wrappedJ, wrappedK, 0))
									<< ", " << std::setfill(' ') << std::setw(5) << bChannelAccess.getChannelUint(IVec3(wrappedJ, wrappedK, 0)) << ")";
							}
							log << TestLog::Message << "    " << line.str() << TestLog::EndMessage;
						}
					}
				}
				else
				{
					log << TestLog::Message << "  Values : " << TestLog::EndMessage;
					log << TestLog::Message << "    Offset : (" << ijBounds[i][ndx][0] << ", " << ijBounds[i][ndx][2] << ")" << TestLog::EndMessage;

					for (deInt32 k = ijBounds[i][ndx][2]; k <= ijBounds[i][ndx][3] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0); k++)
					{
						const deInt32		wrappedK	= wrap(config.addressModeV, k, rChannelAccess.getSize().y());
						bool				first		= true;
						std::ostringstream	line;

						for (deInt32 j = ijBounds[i][ndx][0]; j <= ijBounds[i][ndx][1] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0); j++)
						{
							const deInt32	wrappedJ	= wrap(config.addressModeU, j, rChannelAccess.getSize().x());

							if (!first)
							{
								line << ", ";
								first = false;
							}

							line << "(" << std::setfill(' ') << std::setw(5) << rChannelAccess.getChannelUint(IVec3(wrappedJ, wrappedK, 0))
								<< ", " << std::setfill(' ') << std::setw(5) << gChannelAccess.getChannelUint(IVec3(wrappedJ, wrappedK, 0))
								<< ", " << std::setfill(' ') << std::setw(5) << bChannelAccess.getChannelUint(IVec3(wrappedJ, wrappedK, 0))
								<< ", " << std::setfill(' ') << std::setw(5) << aChannelAccess.getChannelUint(IVec3(wrappedJ, wrappedK, 0)) << ")";
						}
						log << TestLog::Message << "    " << line.str() << TestLog::EndMessage;
					}
				}

				errorCount++;
				isOk = false;

				if (errorCount > 30)
				{
					log << TestLog::Message << "Encountered " << errorCount << " errors. Omitting rest of the per result logs." << TestLog::EndMessage;
					break;
				}
			}
		}
	}

	if (isOk)
		return tcu::TestStatus::pass("Pass");
	else
		return tcu::TestStatus::fail("Result comparison failed");
}

#if defined(FAKE_COLOR_CONVERSION)
const char* swizzleToCompName (const char* identity, vk::VkComponentSwizzle swizzle)
{
	switch (swizzle)
	{
		case vk::VK_COMPONENT_SWIZZLE_IDENTITY:	return identity;
		case vk::VK_COMPONENT_SWIZZLE_R:		return "r";
		case vk::VK_COMPONENT_SWIZZLE_G:		return "g";
		case vk::VK_COMPONENT_SWIZZLE_B:		return "b";
		case vk::VK_COMPONENT_SWIZZLE_A:		return "a";
		default:
			DE_FATAL("Unsupported swizzle");
			return DE_NULL;
	}
}
#endif

void createTestShaders (vk::SourceCollections& dst, TestConfig config)
{
	std::vector< vk::VkSamplerYcbcrModelConversion> colorModels;
	if (config.colorModel != vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_LAST)
	{
		colorModels.push_back(config.colorModel);
	}
	else
	{
		int ycbcrModelConverionCount = std::min((int)vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_LAST, 4);
		for (int i = 0; i < ycbcrModelConverionCount; i++)
		{
			colorModels.push_back((vk::VkSamplerYcbcrModelConversion)(vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY + i));
		}
	}
#if !defined(FAKE_COLOR_CONVERSION)
	const ShaderSpec spec (createShaderSpec(config.samplerBinding, colorModels));

	generateSources(config.shaderType, spec, dst);
#else
	const tcu::UVec4	bits	(getYCbCrBitDepth(config.format));
	ShaderSpec			spec;

	spec.globalDeclarations = "layout(set=" + de::toString((int)EXTRA_RESOURCES_DESCRIPTOR_SET_INDEX) + ", binding=" + de::toString(config.samplerBinding) + ") uniform highp sampler2D u_sampler;";

	spec.inputs.push_back(Symbol("uv", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_HIGHP)));
	spec.outputs.push_back(Symbol("o_color", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));

	std::ostringstream	source;

	source << "highp vec4 inputColor = texture(u_sampler, uv);\n";

	source << "highp float r = inputColor." << swizzleToCompName("r", config.componentMapping.r) << ";\n";
	source << "highp float g = inputColor." << swizzleToCompName("g", config.componentMapping.g) << ";\n";
	source << "highp float b = inputColor." << swizzleToCompName("b", config.componentMapping.b) << ";\n";
	source << "highp float a = inputColor." << swizzleToCompName("a", config.componentMapping.a) << ";\n";

	switch (config.colorRange)
	{
		case vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL:
			source << "highp float cr = r - (float(" << (0x1u << (bits[0] - 0x1u)) << ") / float(" << ((0x1u << bits[0]) - 1u) << "));\n";
			source << "highp float y  = g;\n";
			source << "highp float cb = b - (float(" << (0x1u << (bits[2] - 0x1u)) << ") / float(" << ((0x1u << bits[2]) - 1u) << "));\n";
			break;

		case vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW:
			source << "highp float cr = (r * float(" << ((0x1u << bits[0]) - 1u) << ") - float(" << (128u * (0x1u << (bits[0] - 8))) << ")) / float(" << (224u * (0x1u << (bits[0] - 8))) << ");\n";
			source << "highp float y  = (g * float(" << ((0x1u << bits[1]) - 1u) << ") - float(" << (16u * (0x1u << (bits[1] - 8))) << ")) / float(" << (219u * (0x1u << (bits[1] - 8))) << ");\n";
			source << "highp float cb = (b * float(" << ((0x1u << bits[2]) - 1u) << ") - float(" << (128u * (0x1u << (bits[2] - 8))) << ")) / float(" << (224u * (0x1u << (bits[2] - 8))) << ");\n";
			break;

		default:
			DE_FATAL("Unknown color range");
	}

	source << "highp vec4 color;\n";

	switch (config.colorModel)
	{
		case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY:
			source << "color = vec4(r, g, b, a);\n";
			break;

		case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY:
			source << "color = vec4(cr, y, cb, a);\n";
			break;

		case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601:
			source << "color = vec4(y + 1.402 * cr, y - float(" << (0.202008 / 0.587) << ") * cb - float(" << (0.419198 / 0.587) << ") * cr, y + 1.772 * cb, a);\n";
			break;

		case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709:
			source << "color = vec4(y + 1.5748 * cr, y - float(" << (0.13397432 / 0.7152) << ") * cb - float(" << (0.33480248 / 0.7152) << ") * cr, y + 1.8556 * cb, a);\n";
			break;

		case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020:
			source << "color = vec4(y + 1.4746 * cr, (y - float(" << (0.11156702 / 0.6780) << ") * cb) - float(" << (0.38737742 / 0.6780) << ") * cr, y + 1.8814 * cb, a);\n";
			break;

		default:
			DE_FATAL("Unknown color model");
	};

	source << "o_color = color;\n";

	spec.source = source.str();
	generateSources(config.shaderType, spec, dst);
#endif
}

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


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

struct YCbCrConversionTestBuilder
{
	const std::vector<vk::VkFormat> 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
	};
	const std::vector<vk::VkFormat> 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,
	};
	const std::vector<vk::VkFormat> 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,
	};
	struct ColorModelStruct
	{
		const char* const							name;
		const vk::VkSamplerYcbcrModelConversion	value;
	};
	const std::vector<ColorModelStruct> 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 std::vector<RangeNamePair> colorRanges =
	{
		{ "itu_full",		vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL		},
		{ "itu_narrow",		vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW	}
	};
	const std::vector<ChromaLocationNamePair> chromaLocations =
	{
		{ "cosited",		vk::VK_CHROMA_LOCATION_COSITED_EVEN	},
		{ "midpoint",		vk::VK_CHROMA_LOCATION_MIDPOINT		}
	};
	struct TextureFilterStruct
	{
		const char* const	name;
		vk::VkFilter		value;
	};
	const std::vector<TextureFilterStruct> textureFilters =
	{
		{ "linear",			vk::VK_FILTER_LINEAR	},
		{ "nearest",		vk::VK_FILTER_NEAREST	}
	};
	// Used by the chroma reconstruction tests
	const vk::VkSamplerYcbcrModelConversion		defaultColorModel		= vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
	const vk::VkSamplerYcbcrRange				defaultColorRange		= vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
	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 vk::VkComponentMapping				swappedChromaSwizzle	=
	{
		vk::VK_COMPONENT_SWIZZLE_B,
		vk::VK_COMPONENT_SWIZZLE_IDENTITY,
		vk::VK_COMPONENT_SWIZZLE_R,
		vk::VK_COMPONENT_SWIZZLE_IDENTITY
	};
	const std::vector<glu::ShaderType> shaderTypes =
	{
		glu::SHADERTYPE_VERTEX,
		glu::SHADERTYPE_FRAGMENT,
		glu::SHADERTYPE_COMPUTE
	};
	struct ImageTilingStruct
	{
		const char*			name;
		vk::VkImageTiling	value;
	};
	const std::vector<ImageTilingStruct> imageTilings =
	{
		{ "tiling_linear",	vk::VK_IMAGE_TILING_LINEAR },
		{ "tiling_optimal",	vk::VK_IMAGE_TILING_OPTIMAL }
	};
	struct SamplerBindingStruct
	{
		const char*			name;
		deUint32			value;
	};
	const std::vector<SamplerBindingStruct> samplerBindings =
	{
		{ "binding_0",		0	},
		{ "binding_7",		7	},
		{ "binding_15",		15	},
		{ "binding_31",		31	}
	};

	void buildTests(tcu::TestCaseGroup* testGroup)
	{
		tcu::TestContext&							testCtx(testGroup->getTestContext());
		de::Random									rng(1978765638u);

		// Test formats without chroma reconstruction
		for (size_t formatNdx = 0; formatNdx < noChromaSubsampledFormats.size(); formatNdx++)
		{
			const vk::VkFormat						format(noChromaSubsampledFormats[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()));
			const UVec2								srcSize(isXChromaSubsampled(format) ? 12 : 7,
				isYChromaSubsampled(format) ? 8 : 13);
			const UVec2								dstSize(srcSize.x() + srcSize.x() / 2,
				srcSize.y() + srcSize.y() / 2);

			for (size_t modelNdx = 0; modelNdx < colorModels.size(); 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 && getYCbCrFormatChannelCount(format) < 3)
					continue;

				de::MovePtr<tcu::TestCaseGroup>			colorModelGroup(new tcu::TestCaseGroup(testCtx, colorModelName, ("Tests for color model " + string(colorModelName)).c_str()));

				if (colorModel == vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY)
				{
					for (size_t textureFilterNdx = 0; textureFilterNdx < textureFilters.size(); textureFilterNdx++)
					{
						const char* const					textureFilterName(textureFilters[textureFilterNdx].name);
						const vk::VkFilter					textureFilter(textureFilters[textureFilterNdx].value);

						for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
						{
							const vk::VkImageTiling			tiling(imageTilings[tilingNdx].value);
							const char* const				tilingName(imageTilings[tilingNdx].name);
							const glu::ShaderType			shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
							const vk::VkSamplerYcbcrRange	colorRange(rng.choose<RangeNamePair>(begin(colorRanges), end(colorRanges)).value);
							const vk::VkChromaLocation		chromaLocation(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);

							for (size_t bindingNdx = 0; bindingNdx < samplerBindings.size(); bindingNdx++)
							{
								const deUint32					samplerBinding(samplerBindings[bindingNdx].value);
								string							samplerBindingName((samplerBindings[bindingNdx].value != 0) ? string("_") + samplerBindings[bindingNdx].name : string());
								const TestConfig				config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
									textureFilter, chromaLocation, chromaLocation, false, false,
									colorRange, colorModel, identitySwizzle, srcSize, dstSize, samplerBinding);

								addFunctionCaseWithPrograms(colorModelGroup.get(), std::string(textureFilterName) + "_" + tilingName + samplerBindingName, "", checkSupport, createTestShaders, textureConversionTest, config);
							}
						}
					}
				}
				else
				{
					for (size_t rangeNdx = 0; rangeNdx < colorRanges.size(); 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 UVec4					bitDepth(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 " + string(colorRangeName)).c_str()));

						for (size_t textureFilterNdx = 0; textureFilterNdx < textureFilters.size(); textureFilterNdx++)
						{
							const char* const				textureFilterName(textureFilters[textureFilterNdx].name);
							const vk::VkFilter				textureFilter(textureFilters[textureFilterNdx].value);

							for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
							{
								const vk::VkImageTiling		tiling(imageTilings[tilingNdx].value);
								const char* const			tilingName(imageTilings[tilingNdx].name);
								const glu::ShaderType		shaderType(rng.choose<glu::ShaderType>(shaderTypes.begin(), shaderTypes.end()));
								const vk::VkChromaLocation	chromaLocation(rng.choose<ChromaLocationNamePair>(chromaLocations.begin(), chromaLocations.end()).value);
								for (size_t bindingNdx = 0; bindingNdx < samplerBindings.size(); bindingNdx++)								{
									const deUint32				samplerBinding(samplerBindings[bindingNdx].value);
									string						samplerBindingName((samplerBindings[bindingNdx].value != 0) ? string("_") + samplerBindings[bindingNdx].name : string());
									const TestConfig			config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
										textureFilter, chromaLocation, chromaLocation, false, false,
										colorRange, colorModel, identitySwizzle, srcSize, dstSize, samplerBinding);

									addFunctionCaseWithPrograms(colorRangeGroup.get(), std::string(textureFilterName) + "_" + tilingName + samplerBindingName, "", checkSupport, createTestShaders, textureConversionTest, config);
								}
							}
						}

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

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

			// Color conversion tests for array of samplers ( noChromaSubsampledFormats )
			if (getYCbCrFormatChannelCount(format) >= 3)
				buildArrayOfSamplersTests(format, srcSize, dstSize, formatGroup, testCtx, rng);

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

		// Test formats with x chroma reconstruction
		for (size_t formatNdx = 0; formatNdx < xChromaSubsampledFormats.size(); formatNdx++)
		{
			const vk::VkFormat				format(xChromaSubsampledFormats[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()));
			const UVec2						srcSize(isXChromaSubsampled(format) ? 12 : 7,
				isYChromaSubsampled(format) ? 8 : 13);
			const UVec2						dstSize(srcSize.x() + srcSize.x() / 2,
				srcSize.y() + srcSize.y() / 2);

			// Color conversion tests
			{
				de::MovePtr<tcu::TestCaseGroup>	conversionGroup(new tcu::TestCaseGroup(testCtx, "color_conversion", ""));

				for (size_t xChromaOffsetNdx = 0; xChromaOffsetNdx < chromaLocations.size(); xChromaOffsetNdx++)
				{
					const char* const			xChromaOffsetName(chromaLocations[xChromaOffsetNdx].name);
					const vk::VkChromaLocation	xChromaOffset(chromaLocations[xChromaOffsetNdx].value);

					for (size_t modelNdx = 0; modelNdx < colorModels.size(); 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 && getYCbCrFormatChannelCount(format) < 3)
							continue;


						if (colorModel == vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY)
						{
							for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
							{
								const vk::VkImageTiling			tiling(imageTilings[tilingNdx].value);
								const char* const				tilingName(imageTilings[tilingNdx].name);
								const vk::VkSamplerYcbcrRange	colorRange(rng.choose<RangeNamePair>(begin(colorRanges), end(colorRanges)).value);
								const glu::ShaderType			shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
								const vk::VkChromaLocation		yChromaOffset(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
								for (size_t bindingNdx = 0; bindingNdx < samplerBindings.size(); bindingNdx++)
								{
									const deUint32					samplerBinding(samplerBindings[bindingNdx].value);
									string							samplerBindingName((samplerBindings[bindingNdx].value != 0) ? string("_") + samplerBindings[bindingNdx].name : string());
									const TestConfig				config(shaderType, 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, xChromaOffset, yChromaOffset, false, false,
										colorRange, colorModel, identitySwizzle, srcSize, dstSize, samplerBinding);

									addFunctionCaseWithPrograms(conversionGroup.get(), string(colorModelName) + "_" + tilingName + "_" + xChromaOffsetName + samplerBindingName, "", checkSupport, createTestShaders, textureConversionTest, config);
								}
							}
						}
						else
						{
							for (size_t rangeNdx = 0; rangeNdx < colorRanges.size(); 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 UVec4					bitDepth(getYCbCrBitDepth(format));

									if (bitDepth[0] < 8 || bitDepth[1] < 8 || bitDepth[2] < 8)
										continue;
								}

								for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
								{
									const vk::VkImageTiling		tiling(imageTilings[tilingNdx].value);
									const char* const			tilingName(imageTilings[tilingNdx].name);
									const glu::ShaderType		shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
									const vk::VkChromaLocation	yChromaOffset(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
									for (size_t bindingNdx = 0; bindingNdx < samplerBindings.size(); bindingNdx++)
									{
										const deUint32				samplerBinding(samplerBindings[bindingNdx].value);
										string						samplerBindingName((samplerBindings[bindingNdx].value != 0) ? string("_") + samplerBindings[bindingNdx].name : string());
										const TestConfig			config(shaderType, 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, xChromaOffset, yChromaOffset, false, false,
											colorRange, colorModel, identitySwizzle, srcSize, dstSize, samplerBinding);

										addFunctionCaseWithPrograms(conversionGroup.get(), string(colorModelName) + "_" + colorRangeName + "_" + tilingName + "_" + xChromaOffsetName + samplerBindingName, "", checkSupport, createTestShaders, textureConversionTest, config);
									}
								}
							}
						}
					}
				}

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

			// Color conversion tests for array of samplers ( xChromaSubsampledFormats )
			if (getYCbCrFormatChannelCount(format) >= 3)
				buildArrayOfSamplersTests(format, srcSize, dstSize, formatGroup, testCtx, rng);

			// Chroma reconstruction tests
			{
				de::MovePtr<tcu::TestCaseGroup>	reconstrucGroup(new tcu::TestCaseGroup(testCtx, "chroma_reconstruction", ""));

				for (size_t textureFilterNdx = 0; textureFilterNdx < textureFilters.size(); textureFilterNdx++)
				{
					const char* const				textureFilterName(textureFilters[textureFilterNdx].name);
					const vk::VkFilter				textureFilter(textureFilters[textureFilterNdx].value);
					de::MovePtr<tcu::TestCaseGroup>	textureFilterGroup(new tcu::TestCaseGroup(testCtx, textureFilterName, textureFilterName));

					for (size_t explicitReconstructionNdx = 0; explicitReconstructionNdx < 2; explicitReconstructionNdx++)
					{
						const bool	explicitReconstruction(explicitReconstructionNdx == 1);

						for (size_t disjointNdx = 0; disjointNdx < 2; disjointNdx++)
						{
							const bool	disjoint(disjointNdx == 1);

							for (size_t xChromaOffsetNdx = 0; xChromaOffsetNdx < chromaLocations.size(); xChromaOffsetNdx++)
							{
								const vk::VkChromaLocation		xChromaOffset(chromaLocations[xChromaOffsetNdx].value);
								const char* const				xChromaOffsetName(chromaLocations[xChromaOffsetNdx].name);

								for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
								{
									const vk::VkImageTiling		tiling(imageTilings[tilingNdx].value);
									const char* const			tilingName(imageTilings[tilingNdx].name);

									{
										const glu::ShaderType			shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
										const vk::VkChromaLocation		yChromaOffset(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
										const TestConfig				config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
											vk::VK_FILTER_LINEAR, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
											defaultColorRange, defaultColorModel, identitySwizzle, srcSize, dstSize, 0);

										addFunctionCaseWithPrograms(textureFilterGroup.get(), string(explicitReconstruction ? "explicit_linear_" : "default_linear_") + xChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : ""), "", checkSupport, createTestShaders, textureConversionTest, config);
									}

									{
										const glu::ShaderType			shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
										const vk::VkChromaLocation		yChromaOffset(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
										const TestConfig				config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
											vk::VK_FILTER_LINEAR, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
											defaultColorRange, defaultColorModel, swappedChromaSwizzle, srcSize, dstSize, 0);

										addFunctionCaseWithPrograms(textureFilterGroup.get(), string(explicitReconstruction ? "explicit_linear_" : "default_linear_") + xChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : "") + "_swapped_chroma", "", checkSupport, createTestShaders, textureConversionTest, config);
									}

									if (!explicitReconstruction)
									{
										{
											const glu::ShaderType			shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
											const vk::VkChromaLocation		yChromaOffset(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
											const TestConfig				config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
												vk::VK_FILTER_NEAREST, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
												defaultColorRange, defaultColorModel, identitySwizzle, srcSize, dstSize, 0);

											addFunctionCaseWithPrograms(textureFilterGroup.get(), string("default_nearest_") + xChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : ""), "", checkSupport, createTestShaders, textureConversionTest, config);
										}

										{
											const glu::ShaderType			shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
											const vk::VkChromaLocation		yChromaOffset(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
											const TestConfig				config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
												vk::VK_FILTER_NEAREST, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
												defaultColorRange, defaultColorModel, swappedChromaSwizzle, srcSize, dstSize, 0);

											addFunctionCaseWithPrograms(textureFilterGroup.get(), string("default_nearest_") + xChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : "") + "_swapped_chroma", "", checkSupport, createTestShaders, textureConversionTest, config);
										}
									}
								}
							}

							if (explicitReconstruction)
							{
								for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
								{
									const vk::VkImageTiling	tiling(imageTilings[tilingNdx].value);
									const char* const		tilingName(imageTilings[tilingNdx].name);
									{
										const glu::ShaderType			shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
										const vk::VkChromaLocation		chromaLocation(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
										const TestConfig				config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
											vk::VK_FILTER_NEAREST, chromaLocation, chromaLocation, explicitReconstruction, disjoint,
											defaultColorRange, defaultColorModel, identitySwizzle, srcSize, dstSize, 0);

										addFunctionCaseWithPrograms(textureFilterGroup.get(), string("explicit_nearest") + "_" + tilingName + (disjoint ? "_disjoint" : ""), "", checkSupport, createTestShaders, textureConversionTest, config);
									}

									{
										const glu::ShaderType			shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
										const vk::VkChromaLocation		chromaLocation(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
										const TestConfig				config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
											vk::VK_FILTER_NEAREST, chromaLocation, chromaLocation, explicitReconstruction, disjoint,
											defaultColorRange, defaultColorModel, swappedChromaSwizzle, srcSize, dstSize, 0);

										addFunctionCaseWithPrograms(textureFilterGroup.get(), string("explicit_nearest") + "_" + tilingName + (disjoint ? "_disjoint" : "") + "_swapped_chroma", "", checkSupport, createTestShaders, textureConversionTest, config);
									}
								}
							}
						}
					}

					reconstrucGroup->addChild(textureFilterGroup.release());
				}

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

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

		// Test formats with xy chroma reconstruction
		for (size_t formatNdx = 0; formatNdx < xyChromaSubsampledFormats.size(); formatNdx++)
		{
			const vk::VkFormat				format(xyChromaSubsampledFormats[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()));
			const UVec2						srcSize(isXChromaSubsampled(format) ? 12 : 7,
				isYChromaSubsampled(format) ? 8 : 13);
			const UVec2						dstSize(srcSize.x() + srcSize.x() / 2,
				srcSize.y() + srcSize.y() / 2);

			// Color conversion tests
			{
				de::MovePtr<tcu::TestCaseGroup>	conversionGroup(new tcu::TestCaseGroup(testCtx, "color_conversion", ""));

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

					for (size_t modelNdx = 0; modelNdx < colorModels.size(); 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 && getYCbCrFormatChannelCount(format) < 3)
							continue;

						if (colorModel == vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY)
						{
							for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
							{
								const vk::VkImageTiling				tiling(imageTilings[tilingNdx].value);
								const char* const					tilingName(imageTilings[tilingNdx].name);
								const vk::VkSamplerYcbcrRange		colorRange(rng.choose<RangeNamePair>(begin(colorRanges), end(colorRanges)).value);
								const glu::ShaderType				shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
								for (size_t bindingNdx = 0; bindingNdx < samplerBindings.size(); bindingNdx++)
								{
									const deUint32						samplerBinding(samplerBindings[bindingNdx].value);
									string								samplerBindingName((samplerBindings[bindingNdx].value != 0) ? string("_") + samplerBindings[bindingNdx].name : string());
									const TestConfig					config(shaderType, 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, false,
										colorRange, colorModel, identitySwizzle, srcSize, dstSize, samplerBinding);

									addFunctionCaseWithPrograms(conversionGroup.get(), std::string(colorModelName) + "_" + tilingName + "_" + chromaOffsetName + samplerBindingName, "", checkSupport, createTestShaders, textureConversionTest, config);
								}
							}
						}
						else
						{
							for (size_t rangeNdx = 0; rangeNdx < colorRanges.size(); 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 UVec4	bitDepth(getYCbCrBitDepth(format));

									if (bitDepth[0] < 8 || bitDepth[1] < 8 || bitDepth[2] < 8)
										continue;
								}

								for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
								{
									const vk::VkImageTiling			tiling(imageTilings[tilingNdx].value);
									const char* const				tilingName(imageTilings[tilingNdx].name);
									const glu::ShaderType			shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
									for (size_t bindingNdx = 0; bindingNdx < samplerBindings.size(); bindingNdx++)
									{
										const deUint32					samplerBinding(samplerBindings[bindingNdx].value);
										string							samplerBindingName((samplerBindings[bindingNdx].value != 0) ? string("_") + samplerBindings[bindingNdx].name : string());
										const TestConfig				config(shaderType, 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, false,
											colorRange, colorModel, identitySwizzle, srcSize, dstSize, samplerBinding);

										addFunctionCaseWithPrograms(conversionGroup.get(), string(colorModelName) + "_" + colorRangeName + "_" + tilingName + "_" + chromaOffsetName + samplerBindingName, "", checkSupport, createTestShaders, textureConversionTest, config);
									}
								}
							}
						}
					}
				}

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

			// Color conversion tests for array of samplers ( xyChromaSubsampledFormats )
			if (getYCbCrFormatChannelCount(format) >= 3)
				buildArrayOfSamplersTests(format, srcSize, dstSize, formatGroup, testCtx, rng);

			// Chroma reconstruction tests
			{
				de::MovePtr<tcu::TestCaseGroup>	reconstrucGroup(new tcu::TestCaseGroup(testCtx, "chroma_reconstruction", ""));

				for (size_t textureFilterNdx = 0; textureFilterNdx < textureFilters.size(); textureFilterNdx++)
				{
					const char* const				textureFilterName(textureFilters[textureFilterNdx].name);
					const vk::VkFilter				textureFilter(textureFilters[textureFilterNdx].value);
					de::MovePtr<tcu::TestCaseGroup>	textureFilterGroup(new tcu::TestCaseGroup(testCtx, textureFilterName, textureFilterName));

					for (size_t explicitReconstructionNdx = 0; explicitReconstructionNdx < 2; explicitReconstructionNdx++)
					{
						const bool	explicitReconstruction(explicitReconstructionNdx == 1);

						for (size_t disjointNdx = 0; disjointNdx < 2; disjointNdx++)
						{
							const bool	disjoint(disjointNdx == 1);

							for (size_t xChromaOffsetNdx = 0; xChromaOffsetNdx < chromaLocations.size(); xChromaOffsetNdx++)
								for (size_t yChromaOffsetNdx = 0; yChromaOffsetNdx < chromaLocations.size(); yChromaOffsetNdx++)
								{
									const vk::VkChromaLocation		xChromaOffset(chromaLocations[xChromaOffsetNdx].value);
									const char* const				xChromaOffsetName(chromaLocations[xChromaOffsetNdx].name);

									const vk::VkChromaLocation		yChromaOffset(chromaLocations[yChromaOffsetNdx].value);
									const char* const				yChromaOffsetName(chromaLocations[yChromaOffsetNdx].name);

									for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
									{
										const vk::VkImageTiling	tiling(imageTilings[tilingNdx].value);
										const char* const		tilingName(imageTilings[tilingNdx].name);
										{
											const glu::ShaderType	shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
											const TestConfig		config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
												vk::VK_FILTER_LINEAR, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
												defaultColorRange, defaultColorModel, identitySwizzle, srcSize, dstSize, 0);

											addFunctionCaseWithPrograms(textureFilterGroup.get(), string(explicitReconstruction ? "explicit_linear_" : "default_linear_") + xChromaOffsetName + "_" + yChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : ""), "", checkSupport, createTestShaders, textureConversionTest, config);
										}

										{
											const glu::ShaderType	shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
											const TestConfig		config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
												vk::VK_FILTER_LINEAR, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
												defaultColorRange, defaultColorModel, swappedChromaSwizzle, srcSize, dstSize, 0);

											addFunctionCaseWithPrograms(textureFilterGroup.get(), string(explicitReconstruction ? "explicit_linear_" : "default_linear_") + xChromaOffsetName + "_" + yChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : "") + "_swapped_chroma", "", checkSupport, createTestShaders, textureConversionTest, config);
										}

										if (!explicitReconstruction)
										{
											{
												const glu::ShaderType	shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
												const TestConfig		config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
													vk::VK_FILTER_NEAREST, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
													defaultColorRange, defaultColorModel, identitySwizzle, srcSize, dstSize, 0);

												addFunctionCaseWithPrograms(textureFilterGroup.get(), string("default_nearest_") + xChromaOffsetName + "_" + yChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : ""), "", checkSupport, createTestShaders, textureConversionTest, config);
											}

											{
												const glu::ShaderType	shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
												const TestConfig		config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
													vk::VK_FILTER_NEAREST, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
													defaultColorRange, defaultColorModel, swappedChromaSwizzle, srcSize, dstSize, 0);

												addFunctionCaseWithPrograms(textureFilterGroup.get(), string("default_nearest_") + xChromaOffsetName + "_" + yChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : "") + "_swapped_chroma", "", checkSupport, createTestShaders, textureConversionTest, config);
											}
										}
									}
								}

							if (explicitReconstruction)
							{
								for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
								{
									const vk::VkImageTiling	tiling(imageTilings[tilingNdx].value);
									const char* const		tilingName(imageTilings[tilingNdx].name);
									{
										const glu::ShaderType			shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
										const vk::VkChromaLocation		chromaLocation(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
										const TestConfig				config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
											vk::VK_FILTER_NEAREST, chromaLocation, chromaLocation, explicitReconstruction, disjoint,
											defaultColorRange, defaultColorModel, identitySwizzle, srcSize, dstSize, 0);

										addFunctionCaseWithPrograms(textureFilterGroup.get(), string("explicit_nearest") + "_" + tilingName + (disjoint ? "_disjoint" : ""), "", checkSupport, createTestShaders, textureConversionTest, config);
									}

									{
										const glu::ShaderType			shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));
										const vk::VkChromaLocation		chromaLocation(rng.choose<ChromaLocationNamePair>(begin(chromaLocations), end(chromaLocations)).value);
										const TestConfig				config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
											vk::VK_FILTER_NEAREST, chromaLocation, chromaLocation, explicitReconstruction, disjoint,
											defaultColorRange, defaultColorModel, swappedChromaSwizzle, srcSize, dstSize, 0);

										addFunctionCaseWithPrograms(textureFilterGroup.get(), string("explicit_nearest") + "_" + tilingName + (disjoint ? "_disjoint" : "") + "_swapped_chroma", "", checkSupport, createTestShaders, textureConversionTest, config);
									}
								}
							}
						}
					}

					reconstrucGroup->addChild(textureFilterGroup.release());
				}

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

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

		{
			const UVec2 imageSizes[] =
			{
				UVec2(16, 16),
				UVec2(20, 12)
			};

			de::MovePtr<tcu::TestCaseGroup>				oneToOneGroup(new tcu::TestCaseGroup(testCtx, "one_to_one", "Ycbcr images sampled to a frame buffer of the same dimentions."));

			const vk::VkFormat							format(vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR);
			const vk::VkFilter							filter(vk::VK_FILTER_NEAREST);

			for (size_t sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(imageSizes); sizeNdx++)
			{
				const UVec2								srcSize(imageSizes[sizeNdx]);

				for (size_t xChromaOffsetNdx = 0; xChromaOffsetNdx < chromaLocations.size(); xChromaOffsetNdx++)
				{
					const vk::VkChromaLocation			xChromaOffset(chromaLocations[xChromaOffsetNdx].value);
					const char* const					xChromaOffsetName(chromaLocations[xChromaOffsetNdx].name);

					for (size_t yChromaOffsetNdx = 0; yChromaOffsetNdx < chromaLocations.size(); yChromaOffsetNdx++)
					{
						const vk::VkChromaLocation		yChromaOffset(chromaLocations[yChromaOffsetNdx].value);
						const char* const				yChromaOffsetName(chromaLocations[yChromaOffsetNdx].name);

						for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
						{
							const vk::VkImageTiling		tiling(imageTilings[tilingNdx].value);
							const char* const			tilingName(imageTilings[tilingNdx].name);

							const glu::ShaderType		shaderType(rng.choose<glu::ShaderType>(begin(shaderTypes), end(shaderTypes)));

							const TestConfig			config(shaderType, format, tiling, filter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
								filter, xChromaOffset, yChromaOffset, false, false,
								defaultColorRange, defaultColorModel, identitySwizzle, srcSize, srcSize, 0);
							std::ostringstream			testName;
							testName << string("implicit_nearest_") << srcSize.x() << "x" << srcSize.y() << "_" << tilingName << "_" << xChromaOffsetName << "_" << yChromaOffsetName;

							addFunctionCaseWithPrograms(oneToOneGroup.get(), testName.str(), "", checkSupport, createTestShaders, textureConversionTest, config);
						}
					}
				}
			}

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

	void buildArrayOfSamplersTests(const vk::VkFormat& format, const UVec2& srcSize, const UVec2& dstSize, de::MovePtr<tcu::TestCaseGroup>& formatGroup, tcu::TestContext& testCtx, de::Random& rng )
	{
		de::MovePtr<tcu::TestCaseGroup>			samplerArrayGroup(new tcu::TestCaseGroup(testCtx, "sampler_array", "Tests for array of samplers"));

		for (size_t textureFilterNdx = 0; textureFilterNdx < textureFilters.size(); textureFilterNdx++)
		{
			const char* const					textureFilterName(textureFilters[textureFilterNdx].name);
			const vk::VkFilter					textureFilter(textureFilters[textureFilterNdx].value);

			for (size_t tilingNdx = 0; tilingNdx < imageTilings.size(); tilingNdx++)
			{
				const vk::VkImageTiling			tiling(imageTilings[tilingNdx].value);
				const char* const				tilingName(imageTilings[tilingNdx].name);
				const glu::ShaderType			shaderType(rng.choose<glu::ShaderType>(shaderTypes.begin(), shaderTypes.end()));
				const vk::VkSamplerYcbcrRange	colorRange(vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL);
				const vk::VkChromaLocation		chromaLocation(rng.choose<ChromaLocationNamePair>(chromaLocations.begin(), chromaLocations.end()).value);

				for (size_t bindingNdx = 0; bindingNdx < samplerBindings.size(); bindingNdx++)
				{
					const deUint32					samplerBinding(samplerBindings[bindingNdx].value);
					string							samplerBindingName((samplerBindings[bindingNdx].value != 0) ? string("_") + samplerBindings[bindingNdx].name : string());
					// colorModel==VK_SAMPLER_YCBCR_MODEL_CONVERSION_LAST means that we want to create an array of samplers instead of a single sampler
					const TestConfig				config(shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
						textureFilter, chromaLocation, chromaLocation, false, false,
						colorRange, vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_LAST, identitySwizzle, srcSize, dstSize, samplerBinding);

					addFunctionCaseWithPrograms(samplerArrayGroup.get(), std::string(textureFilterName) + "_" + tilingName + samplerBindingName, "", checkSupport, createTestShaders, textureConversionTest, config);
				}
			}
		}
		formatGroup->addChild(samplerArrayGroup.release());
	}
};

void initTests(tcu::TestCaseGroup* testGroup)
{
	YCbCrConversionTestBuilder testBuilder;
	testBuilder.buildTests(testGroup);
}

} // anonymous

tcu::TestCaseGroup* createConversionTests (tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "conversion", "Sampler YCbCr Conversion Tests", initTests);
}

} // ycbcr
} // vkt
