/*------------------------------------------------------------------------
 * 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 YCbCr format copy tests
 *//*--------------------------------------------------------------------*/

#include "vktYCbCrCopyTests.hpp"

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

#include "vkQueryUtil.hpp"
#include "vkRefUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkCmdUtil.hpp"

#include "tcuSeedBuilder.hpp"
#include "tcuTestLog.hpp"
#include "tcuVector.hpp"
#include "tcuVectorUtil.hpp"

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

#include <string>
#include <utility>
#include <vector>

using tcu::UVec2;
using tcu::Vec4;
using tcu::TestLog;

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

namespace vkt
{
namespace ycbcr
{
namespace
{

struct ImageConfig
{
						ImageConfig	(vk::VkFormat		format_,
									 vk::VkImageTiling	tiling_,
									 bool				disjoint_,
									 const UVec2&		size_)
		: format	(format_)
		, tiling	(tiling_)
		, disjoint	(disjoint_)
		, size		(size_)
	{
	}

	vk::VkFormat		format;
	vk::VkImageTiling	tiling;
	bool				disjoint;
	UVec2				size;
};

struct TestConfig
{
				TestConfig		(const ImageConfig&	src_,
								 const ImageConfig&	dst_)
		: src	(src_)
		, dst	(dst_)
	{
	}

	ImageConfig	src;
	ImageConfig	dst;
};

void checkFormatSupport(Context& context, const ImageConfig& config)
{
	try
	{
		const vk::VkFormatProperties	properties	(vk::getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), config.format));
		const vk::VkFormatFeatureFlags	features	(config.tiling == vk::VK_IMAGE_TILING_OPTIMAL
													? properties.optimalTilingFeatures
													: properties.linearTilingFeatures);

		if ((features & vk::VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0
			&& (features & vk::VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0)
		{
			TCU_THROW(NotSupportedError, "Format doesn't support copies");
		}

		if (config.disjoint && ((features & vk::VK_FORMAT_FEATURE_DISJOINT_BIT) == 0))
			TCU_THROW(NotSupportedError, "Format doesn't support disjoint planes");
	}
	catch (const vk::Error& err)
	{
		if (err.getError() == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
			TCU_THROW(NotSupportedError, "Format not supported");

		throw;
	}
}

void checkSupport (Context& context, const TestConfig config)
{
	const vk::VkPhysicalDeviceLimits limits = context.getDeviceProperties().limits;

	if (config.src.size.x() > limits.maxImageDimension2D || config.src.size.y() > limits.maxImageDimension2D
		|| config.dst.size.x() > limits.maxImageDimension2D || config.dst.size.y() > limits.maxImageDimension2D)
	{
		TCU_THROW(NotSupportedError, "Requested image dimensions not supported");
	}

	if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), string("VK_KHR_sampler_ycbcr_conversion")))
		TCU_THROW(NotSupportedError, "Extension VK_KHR_sampler_ycbcr_conversion not supported");

	checkFormatSupport(context, config.src);
	checkFormatSupport(context, config.dst);
}

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_SRC_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT,
		vk::VK_SHARING_MODE_EXCLUSIVE,
		0u,
		(const deUint32*)DE_NULL,
		tiling == vk::VK_IMAGE_TILING_LINEAR ? vk::VK_IMAGE_LAYOUT_PREINITIALIZED : vk::VK_IMAGE_LAYOUT_UNDEFINED,
	};

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

bool isCompatible (vk::VkFormat	srcFormat,
				   vk::VkFormat	dstFormat)
{
	if (srcFormat == dstFormat)
		return true;
	else
	{
		const vk::VkFormat class8Bit[] =
		{
			vk::VK_FORMAT_R4G4_UNORM_PACK8,
			vk::VK_FORMAT_R8_UNORM,
			vk::VK_FORMAT_R8_SNORM,
			vk::VK_FORMAT_R8_USCALED,
			vk::VK_FORMAT_R8_SSCALED,
			vk::VK_FORMAT_R8_UINT,
			vk::VK_FORMAT_R8_SINT,
			vk::VK_FORMAT_R8_SRGB
		};
		const vk::VkFormat class16Bit[] =
		{
			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_R8G8_UNORM,
			vk::VK_FORMAT_R8G8_SNORM,
			vk::VK_FORMAT_R8G8_USCALED,
			vk::VK_FORMAT_R8G8_SSCALED,
			vk::VK_FORMAT_R8G8_UINT,
			vk::VK_FORMAT_R8G8_SINT,
			vk::VK_FORMAT_R8G8_SRGB,
			vk::VK_FORMAT_R16_UNORM,
			vk::VK_FORMAT_R16_SNORM,
			vk::VK_FORMAT_R16_USCALED,
			vk::VK_FORMAT_R16_SSCALED,
			vk::VK_FORMAT_R16_UINT,
			vk::VK_FORMAT_R16_SINT,
			vk::VK_FORMAT_R16_SFLOAT,
			vk::VK_FORMAT_R10X6_UNORM_PACK16,
			vk::VK_FORMAT_R12X4_UNORM_PACK16
		};
		const vk::VkFormat class24Bit[] =
		{
			vk::VK_FORMAT_R8G8B8_UNORM,
			vk::VK_FORMAT_R8G8B8_SNORM,
			vk::VK_FORMAT_R8G8B8_USCALED,
			vk::VK_FORMAT_R8G8B8_SSCALED,
			vk::VK_FORMAT_R8G8B8_UINT,
			vk::VK_FORMAT_R8G8B8_SINT,
			vk::VK_FORMAT_R8G8B8_SRGB,
			vk::VK_FORMAT_B8G8R8_UNORM,
			vk::VK_FORMAT_B8G8R8_SNORM,
			vk::VK_FORMAT_B8G8R8_USCALED,
			vk::VK_FORMAT_B8G8R8_SSCALED,
			vk::VK_FORMAT_B8G8R8_UINT,
			vk::VK_FORMAT_B8G8R8_SINT,
			vk::VK_FORMAT_B8G8R8_SRGB
		};
		const vk::VkFormat class32Bit[] =
		{
			vk::VK_FORMAT_R8G8B8A8_UNORM,
			vk::VK_FORMAT_R8G8B8A8_SNORM,
			vk::VK_FORMAT_R8G8B8A8_USCALED,
			vk::VK_FORMAT_R8G8B8A8_SSCALED,
			vk::VK_FORMAT_R8G8B8A8_UINT,
			vk::VK_FORMAT_R8G8B8A8_SINT,
			vk::VK_FORMAT_R8G8B8A8_SRGB,
			vk::VK_FORMAT_B8G8R8A8_UNORM,
			vk::VK_FORMAT_B8G8R8A8_SNORM,
			vk::VK_FORMAT_B8G8R8A8_USCALED,
			vk::VK_FORMAT_B8G8R8A8_SSCALED,
			vk::VK_FORMAT_B8G8R8A8_UINT,
			vk::VK_FORMAT_B8G8R8A8_SINT,
			vk::VK_FORMAT_B8G8R8A8_SRGB,
			vk::VK_FORMAT_A8B8G8R8_UNORM_PACK32,
			vk::VK_FORMAT_A8B8G8R8_SNORM_PACK32,
			vk::VK_FORMAT_A8B8G8R8_USCALED_PACK32,
			vk::VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
			vk::VK_FORMAT_A8B8G8R8_UINT_PACK32,
			vk::VK_FORMAT_A8B8G8R8_SINT_PACK32,
			vk::VK_FORMAT_A8B8G8R8_SRGB_PACK32,
			vk::VK_FORMAT_A2R10G10B10_UNORM_PACK32,
			vk::VK_FORMAT_A2R10G10B10_SNORM_PACK32,
			vk::VK_FORMAT_A2R10G10B10_USCALED_PACK32,
			vk::VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
			vk::VK_FORMAT_A2R10G10B10_UINT_PACK32,
			vk::VK_FORMAT_A2R10G10B10_SINT_PACK32,
			vk::VK_FORMAT_A2B10G10R10_UNORM_PACK32,
			vk::VK_FORMAT_A2B10G10R10_SNORM_PACK32,
			vk::VK_FORMAT_A2B10G10R10_USCALED_PACK32,
			vk::VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
			vk::VK_FORMAT_A2B10G10R10_UINT_PACK32,
			vk::VK_FORMAT_A2B10G10R10_SINT_PACK32,
			vk::VK_FORMAT_R16G16_UNORM,
			vk::VK_FORMAT_R16G16_SNORM,
			vk::VK_FORMAT_R16G16_USCALED,
			vk::VK_FORMAT_R16G16_SSCALED,
			vk::VK_FORMAT_R16G16_UINT,
			vk::VK_FORMAT_R16G16_SINT,
			vk::VK_FORMAT_R16G16_SFLOAT,
			vk::VK_FORMAT_R32_UINT,
			vk::VK_FORMAT_R32_SINT,
			vk::VK_FORMAT_R32_SFLOAT,
			vk::VK_FORMAT_B10G11R11_UFLOAT_PACK32,
			vk::VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
			vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16,
			vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16
		};
		const vk::VkFormat class48Bit[] =
		{
			vk::VK_FORMAT_R16G16B16_UNORM,
			vk::VK_FORMAT_R16G16B16_SNORM,
			vk::VK_FORMAT_R16G16B16_USCALED,
			vk::VK_FORMAT_R16G16B16_SSCALED,
			vk::VK_FORMAT_R16G16B16_UINT,
			vk::VK_FORMAT_R16G16B16_SINT,
			vk::VK_FORMAT_R16G16B16_SFLOAT
		};
		const vk::VkFormat class64Bit[] =
		{
			vk::VK_FORMAT_R16G16B16A16_UNORM,
			vk::VK_FORMAT_R16G16B16A16_SNORM,
			vk::VK_FORMAT_R16G16B16A16_USCALED,
			vk::VK_FORMAT_R16G16B16A16_SSCALED,
			vk::VK_FORMAT_R16G16B16A16_UINT,
			vk::VK_FORMAT_R16G16B16A16_SINT,
			vk::VK_FORMAT_R16G16B16A16_SFLOAT,
			vk::VK_FORMAT_R32G32_UINT,
			vk::VK_FORMAT_R32G32_SINT,
			vk::VK_FORMAT_R32G32_SFLOAT,
			vk::VK_FORMAT_R64_UINT,
			vk::VK_FORMAT_R64_SINT,
			vk::VK_FORMAT_R64_SFLOAT
		};
		const vk::VkFormat class96Bit[] =
		{
			vk::VK_FORMAT_R32G32B32_UINT,
			vk::VK_FORMAT_R32G32B32_SINT,
			vk::VK_FORMAT_R32G32B32_SFLOAT
		};
		const vk::VkFormat class128Bit[] =
		{
			vk::VK_FORMAT_R32G32B32A32_UINT,
			vk::VK_FORMAT_R32G32B32A32_SINT,
			vk::VK_FORMAT_R32G32B32A32_SFLOAT,
			vk::VK_FORMAT_R64G64_UINT,
			vk::VK_FORMAT_R64G64_SINT,
			vk::VK_FORMAT_R64G64_SFLOAT
		};
		const vk::VkFormat class192Bit[] =
		{
			vk::VK_FORMAT_R64G64B64_UINT,
			vk::VK_FORMAT_R64G64B64_SINT,
			vk::VK_FORMAT_R64G64B64_SFLOAT
		};
		const vk::VkFormat class256Bit[] =
		{
			vk::VK_FORMAT_R64G64B64A64_UINT,
			vk::VK_FORMAT_R64G64B64A64_SINT,
			vk::VK_FORMAT_R64G64B64A64_SFLOAT
		};

		if (de::contains(DE_ARRAY_BEGIN(class8Bit), DE_ARRAY_END(class8Bit), srcFormat)
			&& de::contains(DE_ARRAY_BEGIN(class8Bit), DE_ARRAY_END(class8Bit), dstFormat))
			return true;

		if (de::contains(DE_ARRAY_BEGIN(class16Bit), DE_ARRAY_END(class16Bit), srcFormat)
			&& de::contains(DE_ARRAY_BEGIN(class16Bit), DE_ARRAY_END(class16Bit), dstFormat))
			return true;

		if (de::contains(DE_ARRAY_BEGIN(class24Bit), DE_ARRAY_END(class24Bit), srcFormat)
			&& de::contains(DE_ARRAY_BEGIN(class24Bit), DE_ARRAY_END(class24Bit), dstFormat))
			return true;

		if (de::contains(DE_ARRAY_BEGIN(class32Bit), DE_ARRAY_END(class32Bit), srcFormat)
			&& de::contains(DE_ARRAY_BEGIN(class32Bit), DE_ARRAY_END(class32Bit), dstFormat))
			return true;

		if (de::contains(DE_ARRAY_BEGIN(class48Bit), DE_ARRAY_END(class48Bit), srcFormat)
			&& de::contains(DE_ARRAY_BEGIN(class48Bit), DE_ARRAY_END(class48Bit), dstFormat))
			return true;

		if (de::contains(DE_ARRAY_BEGIN(class64Bit), DE_ARRAY_END(class64Bit), srcFormat)
			&& de::contains(DE_ARRAY_BEGIN(class64Bit), DE_ARRAY_END(class64Bit), dstFormat))
			return true;

		if (de::contains(DE_ARRAY_BEGIN(class96Bit), DE_ARRAY_END(class96Bit), srcFormat)
			&& de::contains(DE_ARRAY_BEGIN(class96Bit), DE_ARRAY_END(class96Bit), dstFormat))
			return true;

		if (de::contains(DE_ARRAY_BEGIN(class128Bit), DE_ARRAY_END(class128Bit), srcFormat)
			&& de::contains(DE_ARRAY_BEGIN(class128Bit), DE_ARRAY_END(class128Bit), dstFormat))
			return true;

		if (de::contains(DE_ARRAY_BEGIN(class192Bit), DE_ARRAY_END(class192Bit), srcFormat)
			&& de::contains(DE_ARRAY_BEGIN(class192Bit), DE_ARRAY_END(class192Bit), dstFormat))
			return true;

		if (de::contains(DE_ARRAY_BEGIN(class256Bit), DE_ARRAY_END(class256Bit), srcFormat)
			&& de::contains(DE_ARRAY_BEGIN(class256Bit), DE_ARRAY_END(class256Bit), dstFormat))
			return true;

		return false;
	}
}

deUint32 getBlockByteSize (vk::VkFormat format)
{
	switch (format)
	{
		case vk::VK_FORMAT_B8G8R8G8_422_UNORM:
		case vk::VK_FORMAT_G8B8G8R8_422_UNORM:
			return 4u;

		case vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
		case vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
		case vk::VK_FORMAT_B16G16R16G16_422_UNORM:
		case vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
		case vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
		case vk::VK_FORMAT_G16B16G16R16_422_UNORM:
		case vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
		case vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
		case vk::VK_FORMAT_R16G16B16A16_UNORM:
			return 4u * 2u;

		case vk::VK_FORMAT_R10X6_UNORM_PACK16:
		case vk::VK_FORMAT_R12X4_UNORM_PACK16:
			return 2u;

		case vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
		case vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
			return 2u * 2u;

		case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
		case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
			return 3u * 2u;

		case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
		case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
		case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
		case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
		case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
		case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
		case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
		case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
		case vk::VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
		case vk::VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
		case vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
		case vk::VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
		case vk::VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
		case vk::VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
		case vk::VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
		case vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
		case vk::VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
		case vk::VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
			DE_FATAL("Plane formats not supported");
			return ~0u;

		default:
			return (deUint32)vk::mapVkFormat(format).getPixelSize();
	}
}

UVec2 randomUVec2 (de::Random&	rng,
				   const UVec2&	min,
				   const UVec2&	max)
{
	UVec2 result;

	result[0] = min[0] + (rng.getUint32() % (1 + max[0] - min[0]));
	result[1] = min[1] + (rng.getUint32() % (1 + max[1] - min[1]));

	return result;
}

void genCopies (de::Random&					rng,
				size_t						copyCount,
				vk::VkFormat				srcFormat,
				const UVec2&				srcSize,
				vk::VkFormat				dstFormat,
				const UVec2&				dstSize,
				vector<vk::VkImageCopy>*	copies)
{
	vector<pair<deUint32, deUint32> >	pairs;
	const vk::PlanarFormatDescription	srcPlaneInfo	(vk::getPlanarFormatDescription(srcFormat));
	const vk::PlanarFormatDescription	dstPlaneInfo	(vk::getPlanarFormatDescription(dstFormat));

	for (deUint32 srcPlaneNdx = 0; srcPlaneNdx < srcPlaneInfo.numPlanes; srcPlaneNdx++)
	{
		for (deUint32 dstPlaneNdx = 0; dstPlaneNdx < dstPlaneInfo.numPlanes; dstPlaneNdx++)
		{
			const vk::VkFormat srcPlaneFormat (getPlaneCompatibleFormat(srcPlaneInfo, srcPlaneNdx));
			const vk::VkFormat dstPlaneFormat (getPlaneCompatibleFormat(dstPlaneInfo, dstPlaneNdx));

			if (isCompatible(srcPlaneFormat, dstPlaneFormat))
				pairs.push_back(std::make_pair(srcPlaneNdx, dstPlaneNdx));
		}
	}

	DE_ASSERT(!pairs.empty());

	copies->reserve(copyCount);

	for (size_t copyNdx = 0; copyNdx < copyCount; copyNdx++)
	{
		const pair<deUint32, deUint32>	planes			(rng.choose<pair<deUint32, deUint32> >(pairs.begin(), pairs.end()));

		const deUint32					srcPlaneNdx			(planes.first);
		const vk::VkFormat				srcPlaneFormat		(getPlaneCompatibleFormat(srcPlaneInfo, srcPlaneNdx));
		const UVec2						srcBlockExtent		(getBlockExtent(srcPlaneFormat));
		const UVec2						srcPlaneExtent		(getPlaneExtent(srcPlaneInfo, srcSize, srcPlaneNdx, 0));
		const UVec2						srcPlaneBlockExtent	(srcPlaneExtent / srcBlockExtent);

		const deUint32					dstPlaneNdx			(planes.second);
		const vk::VkFormat				dstPlaneFormat		(getPlaneCompatibleFormat(dstPlaneInfo, dstPlaneNdx));
		const UVec2						dstBlockExtent		(getBlockExtent(dstPlaneFormat));
		const UVec2						dstPlaneExtent		(getPlaneExtent(dstPlaneInfo, dstSize, dstPlaneNdx, 0));
		const UVec2						dstPlaneBlockExtent	(dstPlaneExtent / dstBlockExtent);

		const UVec2						copyBlockExtent		(randomUVec2(rng, UVec2(1u, 1u), tcu::min(srcPlaneBlockExtent, dstPlaneBlockExtent)));
		const UVec2						srcOffset			(srcBlockExtent * randomUVec2(rng, UVec2(0u, 0u), srcPlaneBlockExtent - copyBlockExtent));
		const UVec2						dstOffset			(dstBlockExtent * randomUVec2(rng, UVec2(0u, 0u), dstPlaneBlockExtent - copyBlockExtent));
		const UVec2						copyExtent			(copyBlockExtent * srcBlockExtent);
		const vk::VkImageCopy			copy				=
		{
			// src
			{
				static_cast<vk::VkImageAspectFlags>(srcPlaneInfo.numPlanes > 1 ?  vk::getPlaneAspect(srcPlaneNdx) : vk::VK_IMAGE_ASPECT_COLOR_BIT),
				0u,
				0u,
				1u
			},
			{
				(deInt32)srcOffset.x(),
				(deInt32)srcOffset.y(),
				0,
			},
			// dst
			{
				static_cast<vk::VkImageAspectFlags>(dstPlaneInfo.numPlanes > 1 ?  vk::getPlaneAspect(dstPlaneNdx) : vk::VK_IMAGE_ASPECT_COLOR_BIT),
				0u,
				0u,
				1u
			},
			{
				(deInt32)dstOffset.x(),
				(deInt32)dstOffset.y(),
				0,
			},
			// size
			{
				copyExtent.x(),
				copyExtent.y(),
				1u
			}
		};

		copies->push_back(copy);
	}
}

tcu::SeedBuilder& operator<< (tcu::SeedBuilder& builder, const ImageConfig& config)
{

	builder << (deUint32)config.format << (deUint32)config.tiling << config.disjoint << config.size[0] << config.size[1];
	return builder;
}

deUint32 buildSeed (const TestConfig& config)
{
	tcu::SeedBuilder builder;

	builder << 6792903u << config.src << config.dst;

	return builder.get();
}

void logImageInfo (TestLog&				log,
				   const ImageConfig&	config)
{
	log << TestLog::Message << "Format: " << config.format << TestLog::EndMessage;
	log << TestLog::Message << "Tiling: " << config.tiling << TestLog::EndMessage;
	log << TestLog::Message << "Size: " << config.size << TestLog::EndMessage;
	log << TestLog::Message << "Disjoint: " << (config.disjoint ? "true" : "false") << TestLog::EndMessage;
}
void logTestCaseInfo (TestLog&							log,
					  const TestConfig&					config,
					  const vector<vk::VkImageCopy>&	copies)
{
	{
		const tcu::ScopedLogSection section (log, "SourceImage", "SourceImage");
		logImageInfo(log, config.src);
	}

	{
		const tcu::ScopedLogSection section (log, "DestinationImage", "DestinationImage");
		logImageInfo(log, config.dst);
	}
	{
		const tcu::ScopedLogSection section (log, "Copies", "Copies");

		for (size_t copyNdx = 0; copyNdx < copies.size(); copyNdx++)
			log << TestLog::Message << copies[copyNdx] << TestLog::EndMessage;
	}
}

tcu::TestStatus imageCopyTest (Context& context, const TestConfig config)
{
	{
		const size_t			copyCount	= 10;
		TestLog&				log			(context.getTestContext().getLog());

		MultiPlaneImageData		srcData		(config.src.format, config.src.size);
		MultiPlaneImageData		dstData		(config.dst.format, config.dst.size);
		MultiPlaneImageData		result		(config.dst.format, config.dst.size);
		vector<vk::VkImageCopy>	copies;

		de::Random				rng			(buildSeed(config));

		genCopies(rng, copyCount, config.src.format, config.src.size, config.dst.format, config.dst.size, &copies);

		logTestCaseInfo(log, config, copies);

		fillRandom(&rng, &srcData);
		fillRandom(&rng, &dstData);

		{
			const vk::DeviceInterface&		vkd						(context.getDeviceInterface());
			const vk::VkDevice				device					(context.getDevice());

			const vk::Unique<vk::VkImage>	srcImage				(createImage(vkd, device, config.src.format, config.src.size, config.src.disjoint, config.src.tiling));
			const vk::MemoryRequirement		srcMemoryRequirement	(config.src.tiling == vk::VK_IMAGE_TILING_OPTIMAL
																	? vk::MemoryRequirement::Any
																	: vk::MemoryRequirement::HostVisible);
			const vk::VkImageCreateFlags	srcCreateFlags			(config.src.disjoint ? vk::VK_IMAGE_CREATE_DISJOINT_BIT : (vk::VkImageCreateFlagBits)0u);
			const vector<AllocationSp>		srcImageMemory			(allocateAndBindImageMemory(vkd, device, context.getDefaultAllocator(), *srcImage, config.src.format, srcCreateFlags, srcMemoryRequirement));

			const vk::Unique<vk::VkImage>	dstImage				(createImage(vkd, device, config.dst.format, config.dst.size, config.dst.disjoint, config.dst.tiling));
			const vk::MemoryRequirement		dstMemoryRequirement	(config.dst.tiling == vk::VK_IMAGE_TILING_OPTIMAL
																	? vk::MemoryRequirement::Any
																	: vk::MemoryRequirement::HostVisible);
			const vk::VkImageCreateFlags	dstCreateFlags			(config.dst.disjoint ? vk::VK_IMAGE_CREATE_DISJOINT_BIT : (vk::VkImageCreateFlagBits)0u);
			const vector<AllocationSp>		dstImageMemory			(allocateAndBindImageMemory(vkd, device, context.getDefaultAllocator(), *dstImage, config.dst.format, dstCreateFlags, dstMemoryRequirement));

			if (config.src.tiling == vk::VK_IMAGE_TILING_OPTIMAL)
				uploadImage(vkd, device, context.getUniversalQueueFamilyIndex(), context.getDefaultAllocator(), *srcImage, srcData, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
			else
				fillImageMemory(vkd, device, context.getUniversalQueueFamilyIndex(), *srcImage, srcImageMemory, srcData, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);

			if (config.dst.tiling == vk::VK_IMAGE_TILING_OPTIMAL)
				uploadImage(vkd, device, context.getUniversalQueueFamilyIndex(), context.getDefaultAllocator(), *dstImage, dstData, vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
			else
				fillImageMemory(vkd, device, context.getUniversalQueueFamilyIndex(), *dstImage, dstImageMemory, dstData, vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);

			{
				const deUint32							queueFamilyNdx	(context.getUniversalQueueFamilyIndex());
				const vk::VkQueue						queue			(context.getUniversalQueue());
				const vk::Unique<vk::VkCommandPool>		cmdPool			(createCommandPool(vkd, device, (vk::VkCommandPoolCreateFlags)0, queueFamilyNdx));
				const vk::Unique<vk::VkCommandBuffer>	cmdBuffer		(allocateCommandBuffer(vkd, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));

				beginCommandBuffer(vkd, *cmdBuffer);

				for (size_t i = 0; i < copies.size(); i++)
				{
					vkd.cmdCopyImage(*cmdBuffer, *srcImage, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *dstImage, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copies[i]);

					const vk::VkImageMemoryBarrier preCopyBarrier =
					{
						vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
						DE_NULL,
						vk::VK_ACCESS_TRANSFER_WRITE_BIT,
						vk::VK_ACCESS_TRANSFER_WRITE_BIT,
						vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
						vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
						VK_QUEUE_FAMILY_IGNORED,
						VK_QUEUE_FAMILY_IGNORED,
						*dstImage,
						{ vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }
					};

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

				endCommandBuffer(vkd, *cmdBuffer);

				submitCommandsAndWait(vkd, device, queue, *cmdBuffer);
			}

			if (config.dst.tiling == vk::VK_IMAGE_TILING_OPTIMAL)
				downloadImage(vkd, device, context.getUniversalQueueFamilyIndex(), context.getDefaultAllocator(), *dstImage, &result, vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
			else
				readImageMemory(vkd, device, context.getUniversalQueueFamilyIndex(), *dstImage, dstImageMemory, &result, vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
		}

		{
			MultiPlaneImageData	reference		(dstData);
			const size_t		maxErrorCount	= 30;
			size_t				errorCount		= 0;

			for (size_t copyNdx = 0; copyNdx < copies.size(); copyNdx++)
			{
				const vk::VkImageCopy&	copy				(copies[copyNdx]);

				const deUint32			srcPlaneNdx			(copy.srcSubresource.aspectMask != vk::VK_IMAGE_ASPECT_COLOR_BIT
															? vk::getAspectPlaneNdx((vk::VkImageAspectFlagBits)copy.srcSubresource.aspectMask)
															: 0u);
				const UVec2				srcPlaneExtent		(getPlaneExtent(srcData.getDescription(), config.src.size, srcPlaneNdx, 0));

				const vk::VkFormat		srcPlaneFormat		(getPlaneCompatibleFormat(config.src.format, srcPlaneNdx));
				const UVec2				srcBlockExtent		(getBlockExtent(srcPlaneFormat));

				const deUint32			blockSizeBytes		(getBlockByteSize(srcPlaneFormat));

				const UVec2				srcPlaneBlockExtent	(srcPlaneExtent / srcBlockExtent);
				const UVec2				srcBlockOffset		(copy.srcOffset.x / srcBlockExtent.x(), copy.srcOffset.y / srcBlockExtent.y());
				const UVec2				srcBlockPitch		(blockSizeBytes, blockSizeBytes * srcPlaneBlockExtent.x());

				const deUint32			dstPlaneNdx			(copy.dstSubresource.aspectMask != vk::VK_IMAGE_ASPECT_COLOR_BIT
															? vk::getAspectPlaneNdx((vk::VkImageAspectFlagBits)copy.dstSubresource.aspectMask)
															: 0u);
				const UVec2				dstPlaneExtent		(getPlaneExtent(dstData.getDescription(), config.dst.size, dstPlaneNdx, 0));

				const vk::VkFormat		dstPlaneFormat		(getPlaneCompatibleFormat(config.dst.format, dstPlaneNdx));
				const UVec2				dstBlockExtent		(getBlockExtent(dstPlaneFormat));

				const UVec2				dstPlaneBlockExtent	(dstPlaneExtent / dstBlockExtent);
				const UVec2				dstBlockOffset		(copy.dstOffset.x / dstBlockExtent.x(), copy.dstOffset.y / dstBlockExtent.y());
				const UVec2				dstBlockPitch		(blockSizeBytes, blockSizeBytes * dstPlaneBlockExtent.x());

				const UVec2				blockExtent			(copy.extent.width / srcBlockExtent.x(), copy.extent.height / srcBlockExtent.y());

				DE_ASSERT(blockSizeBytes == getBlockByteSize(dstPlaneFormat));

				for (deUint32 y = 0; y < blockExtent.y(); y++)
				{
					const deUint32	size	= blockExtent.x() * blockSizeBytes;
					const deUint32	srcPos	= tcu::dot(srcBlockPitch, UVec2(srcBlockOffset.x(), srcBlockOffset.y() + y));
					const deUint32	dstPos	= tcu::dot(dstBlockPitch, UVec2(dstBlockOffset.x(), dstBlockOffset.y() + y));

					deMemcpy(((deUint8*)reference.getPlanePtr(dstPlaneNdx)) + dstPos,
							 ((const deUint8*)srcData.getPlanePtr(srcPlaneNdx)) + srcPos, size);
				}
			}

			bool ignoreLsb6Bits = areLsb6BitsDontCare(srcData.getFormat(), dstData.getFormat());
			bool ignoreLsb4Bits = areLsb4BitsDontCare(srcData.getFormat(), dstData.getFormat());

			for (deUint32 planeNdx = 0; planeNdx < result.getDescription().numPlanes; ++planeNdx)
			{
				deUint32 planeSize = vk::getPlaneSizeInBytes(result.getDescription(), result.getSize(), planeNdx, 0u, 1u);
				for (size_t byteNdx = 0; byteNdx < planeSize; byteNdx++)
				{
					const deUint8	res	= ((const deUint8*)result.getPlanePtr(planeNdx))[byteNdx];
					const deUint8	ref	= ((const deUint8*)reference.getPlanePtr(planeNdx))[byteNdx];

					deUint8 mask = 0xFF;
					if (!(byteNdx & 0x01) && (ignoreLsb6Bits))
						mask = 0xC0;
					else if (!(byteNdx & 0x01) && (ignoreLsb4Bits))
						mask = 0xF0;

					if ((res & mask) != (ref & mask))
					{
						log << TestLog::Message << "Plane: " << planeNdx << ", Offset: " << byteNdx << ", Expected: " << (deUint32)(ref & mask) << ", Got: " << (deUint32)(res & mask) << TestLog::EndMessage;
						errorCount++;

						if (errorCount > maxErrorCount)
							break;
					}
				}

				if (errorCount > maxErrorCount)
					break;
			}

			if (errorCount > 0)
				return tcu::TestStatus::fail("Failed, found " + (errorCount > maxErrorCount ?  de::toString(maxErrorCount) + "+" : de::toString(errorCount))  + " incorrect bytes");
			else
				return tcu::TestStatus::pass("Pass");
		}
	}
}

bool isCopyCompatible (vk::VkFormat srcFormat, vk::VkFormat dstFormat)
{
	if (isYCbCrFormat(srcFormat) && isYCbCrFormat(dstFormat))
	{
		const vk::PlanarFormatDescription	srcPlaneInfo	(vk::getPlanarFormatDescription(srcFormat));
		const vk::PlanarFormatDescription	dstPlaneInfo	(vk::getPlanarFormatDescription(dstFormat));

		for (deUint32 srcPlaneNdx = 0; srcPlaneNdx < srcPlaneInfo.numPlanes; srcPlaneNdx++)
		{
			for (deUint32 dstPlaneNdx = 0; dstPlaneNdx < dstPlaneInfo.numPlanes; dstPlaneNdx++)
			{
				const vk::VkFormat srcPlaneFormat (getPlaneCompatibleFormat(srcFormat, srcPlaneNdx));
				const vk::VkFormat dstPlaneFormat (getPlaneCompatibleFormat(dstFormat, dstPlaneNdx));

				if (isCompatible(srcPlaneFormat, dstPlaneFormat))
					return true;
			}
		}
	}
	else if (isYCbCrFormat(srcFormat))
	{
		const vk::PlanarFormatDescription	srcPlaneInfo	(vk::getPlanarFormatDescription(srcFormat));

		for (deUint32 srcPlaneNdx = 0; srcPlaneNdx < srcPlaneInfo.numPlanes; srcPlaneNdx++)
		{
			const vk::VkFormat srcPlaneFormat (getPlaneCompatibleFormat(srcFormat, srcPlaneNdx));

			if (isCompatible(srcPlaneFormat, dstFormat))
				return true;
		}
	}
	else if (isYCbCrFormat(dstFormat))
	{
		const vk::PlanarFormatDescription	dstPlaneInfo	(vk::getPlanarFormatDescription(dstFormat));

		for (deUint32 dstPlaneNdx = 0; dstPlaneNdx < dstPlaneInfo.numPlanes; dstPlaneNdx++)
		{
			const vk::VkFormat dstPlaneFormat (getPlaneCompatibleFormat(dstFormat, dstPlaneNdx));

			if (isCompatible(dstPlaneFormat, srcFormat))
				return true;
		}
	}
	else
		return isCompatible(srcFormat, dstFormat);

	return false;
}

void initYcbcrDefaultCopyTests (tcu::TestCaseGroup* testGroup)
{
	const vk::VkFormat ycbcrFormats[] =
	{
		vk::VK_FORMAT_R4G4_UNORM_PACK8,
		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_R8_UNORM,
		vk::VK_FORMAT_R8G8_UNORM,
		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_R16_UNORM,
		vk::VK_FORMAT_R16G16_UNORM,
		vk::VK_FORMAT_R16G16B16_UNORM,
		vk::VK_FORMAT_R16G16B16A16_UNORM,
		vk::VK_FORMAT_B10G11R11_UFLOAT_PACK32,
		vk::VK_FORMAT_G8B8G8R8_422_UNORM,
		vk::VK_FORMAT_B8G8R8G8_422_UNORM,
		vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
		vk::VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
		vk::VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
		vk::VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,
		vk::VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM,
		vk::VK_FORMAT_R10X6_UNORM_PACK16,
		vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16,
		vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
		vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
		vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16,
		vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16,
		vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
		vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16,
		vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,
		vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16,
		vk::VK_FORMAT_R12X4_UNORM_PACK16,
		vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16,
		vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16,
		vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
		vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16,
		vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16,
		vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
		vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16,
		vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,
		vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16,
		vk::VK_FORMAT_G16B16G16R16_422_UNORM,
		vk::VK_FORMAT_B16G16R16G16_422_UNORM,
		vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM,
		vk::VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,
		vk::VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM,
		vk::VK_FORMAT_G16_B16R16_2PLANE_422_UNORM,
		vk::VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM
	};
	const struct
	{
		const char*			name;
		vk::VkImageTiling	value;
	} imageTilings[] =
	{
		{ "linear",	vk::VK_IMAGE_TILING_LINEAR },
		{ "optimal",	vk::VK_IMAGE_TILING_OPTIMAL }
	};
	tcu::TestContext&	testCtx	= testGroup->getTestContext();

	for (size_t srcFormatNdx = 0; srcFormatNdx < DE_LENGTH_OF_ARRAY(ycbcrFormats); srcFormatNdx++)
	{
		const vk::VkFormat				srcFormat		(ycbcrFormats[srcFormatNdx]);
		const UVec2						srcSize			(isYCbCrFormat(srcFormat) ? UVec2(24u, 16u) : UVec2(23u, 17u));
		const string					srcFormatName	(de::toLower(std::string(getFormatName(srcFormat)).substr(10)));
		de::MovePtr<tcu::TestCaseGroup>	srcFormatGroup	(new tcu::TestCaseGroup(testCtx, srcFormatName.c_str(), ("Tests for copies using format " + srcFormatName).c_str()));

		for (size_t dstFormatNdx = 0; dstFormatNdx < DE_LENGTH_OF_ARRAY(ycbcrFormats); dstFormatNdx++)
		{
			const vk::VkFormat				dstFormat		(ycbcrFormats[dstFormatNdx]);
			const UVec2						dstSize			(isYCbCrFormat(dstFormat) ? UVec2(24u, 16u) : UVec2(23u, 17u));
			const string					dstFormatName	(de::toLower(std::string(getFormatName(dstFormat)).substr(10)));

			if ((!vk::isYCbCrFormat(srcFormat) && !vk::isYCbCrFormat(dstFormat))
					|| !isCopyCompatible(srcFormat, dstFormat))
				continue;

			de::MovePtr<tcu::TestCaseGroup>	dstFormatGroup	(new tcu::TestCaseGroup(testCtx, dstFormatName.c_str(), ("Tests for copies using format " + dstFormatName).c_str()));

			for (size_t srcTilingNdx = 0; srcTilingNdx < DE_LENGTH_OF_ARRAY(imageTilings); srcTilingNdx++)
			{
				const vk::VkImageTiling	srcTiling		= imageTilings[srcTilingNdx].value;
				const char* const		srcTilingName	= imageTilings[srcTilingNdx].name;

				for (size_t dstTilingNdx = 0; dstTilingNdx < DE_LENGTH_OF_ARRAY(imageTilings); dstTilingNdx++)
				{
					const vk::VkImageTiling	dstTiling		= imageTilings[dstTilingNdx].value;
					const char* const		dstTilingName	= imageTilings[dstTilingNdx].name;

					for (size_t srcDisjointNdx = 0; srcDisjointNdx < 2; srcDisjointNdx++)
					for (size_t dstDisjointNdx = 0; dstDisjointNdx < 2; dstDisjointNdx++)
					{
						const bool			srcDisjoint	= srcDisjointNdx == 1;
						const bool			dstDisjoint	= dstDisjointNdx == 1;
						const TestConfig	config		(ImageConfig(srcFormat, srcTiling, srcDisjoint, srcSize), ImageConfig(dstFormat, dstTiling, dstDisjoint, dstSize));

						addFunctionCase(dstFormatGroup.get(), string(srcTilingName) + (srcDisjoint ? "_disjoint_" : "_") + string(dstTilingName) + (dstDisjoint ? "_disjoint" : ""), "", checkSupport, imageCopyTest, config);
					}
				}
			}

			srcFormatGroup->addChild(dstFormatGroup.release());
		}

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

void initYcbcrDimensionsCopyTests (tcu::TestCaseGroup* testGroup)
{
	tcu::TestContext&	testCtx				= testGroup->getTestContext();

	const vk::VkFormat	testFormats[]		=
	{
		// 8-bit
		vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
		// 10-bit
		vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16,
		// 12-bit
		vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16,
		// 16-bit
		vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM,
		// Non-ycbcr
		vk::VK_FORMAT_R8G8B8A8_UNORM,
	};

	const tcu::UVec2	imageDimensions[]	=
	{
		// Wide: large pot x small pot
		tcu::UVec2(4096,	4u),
		tcu::UVec2(8192,	4u),
		tcu::UVec2(16384,	4u),
		tcu::UVec2(32768,	4u),

		// Wide: large pot x small npot
		tcu::UVec2(4096,	6u),
		tcu::UVec2(8192,	6u),
		tcu::UVec2(16384,	6u),
		tcu::UVec2(32768,	6u),

		// Tall: small pot x large pot
		tcu::UVec2(4u, 4096),
		tcu::UVec2(4u, 8192),
		tcu::UVec2(4u, 16384),
		tcu::UVec2(4u, 32768),

		// Tall: small npot x large pot
		tcu::UVec2(6u, 4096),
		tcu::UVec2(6u, 8192),
		tcu::UVec2(6u, 16384),
		tcu::UVec2(6u, 32768)
	};

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

	for (size_t imageDimensionNdx = 0; imageDimensionNdx < DE_LENGTH_OF_ARRAY(imageDimensions); imageDimensionNdx++)
	{
		const UVec2						srcSize			(imageDimensions[imageDimensionNdx]);
		const UVec2						dstSize			(imageDimensions[imageDimensionNdx]);
		const string					dimensionsName	("src" + de::toString(srcSize.x()) + "x" + de::toString(srcSize.y()) + "_dst" + de::toString(dstSize.x()) + "x" + de::toString(dstSize.y()));

		de::MovePtr<tcu::TestCaseGroup>	dimensionGroup	(new tcu::TestCaseGroup(testCtx, dimensionsName.c_str(), ("Image dimensions " + dimensionsName).c_str()));

		for (size_t srcFormatNdx = 0; srcFormatNdx < DE_LENGTH_OF_ARRAY(testFormats); srcFormatNdx++)
		{
			const vk::VkFormat				srcFormat		(testFormats[srcFormatNdx]);
			const string					srcFormatName	(de::toLower(std::string(getFormatName(srcFormat)).substr(10)));
			de::MovePtr<tcu::TestCaseGroup>	srcFormatGroup	(new tcu::TestCaseGroup(testCtx, srcFormatName.c_str(), ("Tests for copies using format " + srcFormatName).c_str()));

			for (size_t dstFormatNdx = 0; dstFormatNdx < DE_LENGTH_OF_ARRAY(testFormats); dstFormatNdx++)
			{
				const vk::VkFormat	dstFormat		(testFormats[dstFormatNdx]);
				const string		dstFormatName	(de::toLower(std::string(getFormatName(dstFormat)).substr(10)));

				if ((!vk::isYCbCrFormat(srcFormat) && !vk::isYCbCrFormat(dstFormat))
						|| !isCopyCompatible(srcFormat, dstFormat))
					continue;

				de::MovePtr<tcu::TestCaseGroup>	dstFormatGroup	(new tcu::TestCaseGroup(testCtx, dstFormatName.c_str(), ("Tests for copies using format " + dstFormatName).c_str()));

				for (size_t srcTilingNdx = 0; srcTilingNdx < DE_LENGTH_OF_ARRAY(imageTilings); srcTilingNdx++)
				{
					const vk::VkImageTiling	srcTiling		= imageTilings[srcTilingNdx].value;
					const char* const		srcTilingName	= imageTilings[srcTilingNdx].name;

					for (size_t dstTilingNdx = 0; dstTilingNdx < DE_LENGTH_OF_ARRAY(imageTilings); dstTilingNdx++)
					{
						const vk::VkImageTiling	dstTiling		= imageTilings[dstTilingNdx].value;
						const char* const		dstTilingName	= imageTilings[dstTilingNdx].name;

						for (size_t srcDisjointNdx = 0; srcDisjointNdx < 2; srcDisjointNdx++)
						for (size_t dstDisjointNdx = 0; dstDisjointNdx < 2; dstDisjointNdx++)
						{
							const bool			srcDisjoint	= srcDisjointNdx == 1;
							const bool			dstDisjoint	= dstDisjointNdx == 1;
							const TestConfig	config		(ImageConfig(srcFormat, srcTiling, srcDisjoint, srcSize), ImageConfig(dstFormat, dstTiling, dstDisjoint, dstSize));

							addFunctionCase(dstFormatGroup.get(), string(srcTilingName) + (srcDisjoint ? "_disjoint_" : "_") + string(dstTilingName) + (dstDisjoint ? "_disjoint" : ""), "", checkSupport, imageCopyTest, config);
						}
					}
				}

				srcFormatGroup->addChild(dstFormatGroup.release());
			}

			dimensionGroup->addChild(srcFormatGroup.release());
		}

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

} // anonymous

tcu::TestCaseGroup* createCopyTests (tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "copy", "YCbCr Format Copy Tests", initYcbcrDefaultCopyTests);
}

tcu::TestCaseGroup* createDimensionsCopyTests (tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "copy_dimensions", "YCbCr format copy tests between different image dimensions", initYcbcrDimensionsCopyTests);
}

} // ycbcr
} // vkt
