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

#include "vktYCbCrUtil.hpp"

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

#include "tcuTextureUtil.hpp"
#include "deMath.h"
#include "deFloat16.h"
#include "tcuVector.hpp"
#include "tcuVectorUtil.hpp"

#include "deSTLUtil.hpp"
#include "deUniquePtr.hpp"

namespace vkt
{
namespace ycbcr
{

using namespace vk;

using de::MovePtr;
using tcu::FloatFormat;
using tcu::Interval;
using tcu::IVec2;
using tcu::IVec4;
using tcu::UVec2;
using tcu::UVec4;
using tcu::Vec2;
using tcu::Vec4;
using std::vector;
using std::string;

// MultiPlaneImageData

MultiPlaneImageData::MultiPlaneImageData (VkFormat format, const UVec2& size)
	: m_format		(format)
	, m_description	(getPlanarFormatDescription(format))
	, m_size		(size)
{
	for (deUint32 planeNdx = 0; planeNdx < m_description.numPlanes; ++planeNdx)
		m_planeData[planeNdx].resize(getPlaneSizeInBytes(m_description, size, planeNdx, 0, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY));
}

MultiPlaneImageData::MultiPlaneImageData (const MultiPlaneImageData& other)
	: m_format		(other.m_format)
	, m_description	(other.m_description)
	, m_size		(other.m_size)
{
	for (deUint32 planeNdx = 0; planeNdx < m_description.numPlanes; ++planeNdx)
		m_planeData[planeNdx] = other.m_planeData[planeNdx];
}

MultiPlaneImageData::~MultiPlaneImageData (void)
{
}

tcu::PixelBufferAccess MultiPlaneImageData::getChannelAccess (deUint32 channelNdx)
{
	void*		planePtrs[PlanarFormatDescription::MAX_PLANES];
	deUint32	planeRowPitches[PlanarFormatDescription::MAX_PLANES];

	for (deUint32 planeNdx = 0; planeNdx < m_description.numPlanes; ++planeNdx)
	{
		const deUint32	planeW		= m_size.x() / ( m_description.blockWidth * m_description.planes[planeNdx].widthDivisor);
		planeRowPitches[planeNdx]	= m_description.planes[planeNdx].elementSizeBytes * planeW;
		planePtrs[planeNdx]			= &m_planeData[planeNdx][0];
	}

	return vk::getChannelAccess(m_description,
								m_size,
								planeRowPitches,
								planePtrs,
								channelNdx);
}

tcu::ConstPixelBufferAccess MultiPlaneImageData::getChannelAccess (deUint32 channelNdx) const
{
	const void*	planePtrs[PlanarFormatDescription::MAX_PLANES];
	deUint32	planeRowPitches[PlanarFormatDescription::MAX_PLANES];

	for (deUint32 planeNdx = 0; planeNdx < m_description.numPlanes; ++planeNdx)
	{
		const deUint32	planeW		= m_size.x() / (m_description.blockWidth * m_description.planes[planeNdx].widthDivisor);
		planeRowPitches[planeNdx]	= m_description.planes[planeNdx].elementSizeBytes * planeW;
		planePtrs[planeNdx]			= &m_planeData[planeNdx][0];
	}

	return vk::getChannelAccess(m_description,
								m_size,
								planeRowPitches,
								planePtrs,
								channelNdx);
}

// Misc utilities

namespace
{

void allocateStagingBuffers (const DeviceInterface&			vkd,
							 VkDevice						device,
							 Allocator&						allocator,
							 const MultiPlaneImageData&		imageData,
							 vector<VkBufferSp>*			buffers,
							 vector<AllocationSp>*			allocations)
{
	for (deUint32 planeNdx = 0; planeNdx < imageData.getDescription().numPlanes; ++planeNdx)
	{
		const VkBufferCreateInfo	bufferInfo	=
		{
			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
			DE_NULL,
			(VkBufferCreateFlags)0u,
			(VkDeviceSize)imageData.getPlaneSize(planeNdx),
			VK_BUFFER_USAGE_TRANSFER_SRC_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT,
			VK_SHARING_MODE_EXCLUSIVE,
			0u,
			(const deUint32*)DE_NULL,
		};
		Move<VkBuffer>				buffer		(createBuffer(vkd, device, &bufferInfo));
		MovePtr<Allocation>			allocation	(allocator.allocate(getBufferMemoryRequirements(vkd, device, *buffer),
																	MemoryRequirement::HostVisible|MemoryRequirement::Any));

		VK_CHECK(vkd.bindBufferMemory(device, *buffer, allocation->getMemory(), allocation->getOffset()));

		buffers->push_back(VkBufferSp(new Unique<VkBuffer>(buffer)));
		allocations->push_back(AllocationSp(allocation.release()));
	}
}

void allocateAndWriteStagingBuffers (const DeviceInterface&		vkd,
									  VkDevice						device,
									  Allocator&					allocator,
									  const MultiPlaneImageData&	imageData,
									  vector<VkBufferSp>*			buffers,
									  vector<AllocationSp>*			allocations)
{
	allocateStagingBuffers(vkd, device, allocator, imageData, buffers, allocations);

	for (deUint32 planeNdx = 0; planeNdx < imageData.getDescription().numPlanes; ++planeNdx)
	{
		deMemcpy((*allocations)[planeNdx]->getHostPtr(), imageData.getPlanePtr(planeNdx), imageData.getPlaneSize(planeNdx));
		flushMappedMemoryRange(vkd, device, (*allocations)[planeNdx]->getMemory(), 0u, VK_WHOLE_SIZE);
	}
}

void readStagingBuffers (MultiPlaneImageData*			imageData,
						 const DeviceInterface&			vkd,
						 VkDevice						device,
						 const vector<AllocationSp>&	allocations)
{
	for (deUint32 planeNdx = 0; planeNdx < imageData->getDescription().numPlanes; ++planeNdx)
	{
		invalidateMappedMemoryRange(vkd, device, allocations[planeNdx]->getMemory(), 0u, VK_WHOLE_SIZE);
		deMemcpy(imageData->getPlanePtr(planeNdx), allocations[planeNdx]->getHostPtr(), imageData->getPlaneSize(planeNdx));
	}
}

} // anonymous

void checkImageSupport (Context& context, VkFormat format, VkImageCreateFlags createFlags, VkImageTiling tiling)
{
	const bool													disjoint	= (createFlags & VK_IMAGE_CREATE_DISJOINT_BIT) != 0;
	const VkPhysicalDeviceSamplerYcbcrConversionFeatures		features	= context.getSamplerYcbcrConversionFeatures();
	vector<string>												reqExts;

	if (!isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_sampler_ycbcr_conversion"))
		reqExts.push_back("VK_KHR_sampler_ycbcr_conversion");

	if (disjoint)
	{
		if (!isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_bind_memory2"))
			reqExts.push_back("VK_KHR_bind_memory2");
		if (!isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_get_memory_requirements2"))
			reqExts.push_back("VK_KHR_get_memory_requirements2");
	}

	for (const string& ext : reqExts)
		context.requireDeviceFunctionality(ext);

	if (features.samplerYcbcrConversion == VK_FALSE)
	{
		TCU_THROW(NotSupportedError, "samplerYcbcrConversion is not supported");
	}

	{
		const VkFormatProperties	formatProperties	= getPhysicalDeviceFormatProperties(context.getInstanceInterface(),
																							context.getPhysicalDevice(),
																							format);
		const VkFormatFeatureFlags	featureFlags		= tiling == VK_IMAGE_TILING_OPTIMAL
														? formatProperties.optimalTilingFeatures
														: formatProperties.linearTilingFeatures;

		if ((featureFlags & (VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT | VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT)) == 0)
			TCU_THROW(NotSupportedError, "YCbCr conversion is not supported for format");

		if (disjoint && ((featureFlags & VK_FORMAT_FEATURE_DISJOINT_BIT) == 0))
			TCU_THROW(NotSupportedError, "Disjoint planes are not supported for format");
	}
}

void fillRandom (de::Random* randomGen, MultiPlaneImageData* imageData)
{
	// \todo [pyry] Optimize, take into account bits that must be 0

	for (deUint32 planeNdx = 0; planeNdx < imageData->getDescription().numPlanes; ++planeNdx)
	{
		const size_t	planeSize	= imageData->getPlaneSize(planeNdx);
		deUint8* const	planePtr	= (deUint8*)imageData->getPlanePtr(planeNdx);

		for (size_t ndx = 0; ndx < planeSize; ++ndx)
			planePtr[ndx] = randomGen->getUint8();
	}
}

void fillGradient (MultiPlaneImageData* imageData, const tcu::Vec4& minVal, const tcu::Vec4& maxVal)
{
	const PlanarFormatDescription&	formatInfo	= imageData->getDescription();

	// \todo [pyry] Optimize: no point in re-rendering source gradient for each channel.

	for (deUint32 channelNdx = 0; channelNdx < 4; channelNdx++)
	{
		if (formatInfo.hasChannelNdx(channelNdx))
		{
			const tcu::PixelBufferAccess		channelAccess	= imageData->getChannelAccess(channelNdx);
			tcu::TextureLevel					tmpTexture		(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT),  channelAccess.getWidth(), channelAccess.getHeight());
			const tcu::ConstPixelBufferAccess	tmpAccess		= tmpTexture.getAccess();

			tcu::fillWithComponentGradients(tmpTexture, minVal, maxVal);

			for (int y = 0; y < channelAccess.getHeight(); ++y)
			for (int x = 0; x < channelAccess.getWidth(); ++x)
			{
				channelAccess.setPixel(tcu::Vec4(tmpAccess.getPixel(x, y)[channelNdx]), x, y);
			}
		}
	}
}

void fillZero (MultiPlaneImageData* imageData)
{
	for (deUint32 planeNdx = 0; planeNdx < imageData->getDescription().numPlanes; ++planeNdx)
		deMemset(imageData->getPlanePtr(planeNdx), 0, imageData->getPlaneSize(planeNdx));
}

vector<AllocationSp> allocateAndBindImageMemory (const DeviceInterface&	vkd,
												 VkDevice				device,
												 Allocator&				allocator,
												 VkImage				image,
												 VkFormat				format,
												 VkImageCreateFlags		createFlags,
												 vk::MemoryRequirement	requirement)
{
	vector<AllocationSp> allocations;

	if ((createFlags & VK_IMAGE_CREATE_DISJOINT_BIT) != 0)
	{
		const deUint32	numPlanes	= getPlaneCount(format);

		bindImagePlanesMemory(vkd, device, image, numPlanes, allocations, allocator, requirement);
	}
	else
	{
		const VkMemoryRequirements	reqs	= getImageMemoryRequirements(vkd, device, image);

		allocations.push_back(AllocationSp(allocator.allocate(reqs, requirement).release()));

		VK_CHECK(vkd.bindImageMemory(device, image, allocations.back()->getMemory(), allocations.back()->getOffset()));
	}

	return allocations;
}

void uploadImage (const DeviceInterface&		vkd,
				  VkDevice						device,
				  deUint32						queueFamilyNdx,
				  Allocator&					allocator,
				  VkImage						image,
				  const MultiPlaneImageData&	imageData,
				  VkAccessFlags					nextAccess,
				  VkImageLayout					finalLayout,
				  deUint32						arrayLayer)
{
	const VkQueue					queue			= getDeviceQueue(vkd, device, queueFamilyNdx, 0u);
	const Unique<VkCommandPool>		cmdPool			(createCommandPool(vkd, device, (VkCommandPoolCreateFlags)0, queueFamilyNdx));
	const Unique<VkCommandBuffer>	cmdBuffer		(allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
	vector<VkBufferSp>				stagingBuffers;
	vector<AllocationSp>			stagingMemory;

	const PlanarFormatDescription&	formatDesc		= imageData.getDescription();

	allocateAndWriteStagingBuffers(vkd, device, allocator, imageData, &stagingBuffers, &stagingMemory);

	beginCommandBuffer(vkd, *cmdBuffer);

	{
		const VkImageMemoryBarrier		preCopyBarrier	=
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
			DE_NULL,
			(VkAccessFlags)0,
			VK_ACCESS_TRANSFER_WRITE_BIT,
			VK_IMAGE_LAYOUT_UNDEFINED,
			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
			VK_QUEUE_FAMILY_IGNORED,
			VK_QUEUE_FAMILY_IGNORED,
			image,
			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, arrayLayer, 1u }
		};

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

	for (deUint32 planeNdx = 0; planeNdx < imageData.getDescription().numPlanes; ++planeNdx)
	{
		const VkImageAspectFlagBits	aspect	= (formatDesc.numPlanes > 1)
											? getPlaneAspect(planeNdx)
											: VK_IMAGE_ASPECT_COLOR_BIT;
		const VkExtent3D imageExtent		= makeExtent3D(imageData.getSize().x(), imageData.getSize().y(), 1u);
		const VkExtent3D planeExtent		= getPlaneExtent(formatDesc, imageExtent, planeNdx, 0);
		const VkBufferImageCopy		copy	=
		{
			0u,		// bufferOffset
			0u,		// bufferRowLength
			0u,		// bufferImageHeight
			{ (VkImageAspectFlags)aspect, 0u, arrayLayer, 1u },
			makeOffset3D(0u, 0u, 0u),
			planeExtent
		};

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

	{
		const VkImageMemoryBarrier		postCopyBarrier	=
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
			DE_NULL,
			VK_ACCESS_TRANSFER_WRITE_BIT,
			nextAccess,
			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
			finalLayout,
			VK_QUEUE_FAMILY_IGNORED,
			VK_QUEUE_FAMILY_IGNORED,
			image,
			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, arrayLayer, 1u }
		};

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

	endCommandBuffer(vkd, *cmdBuffer);

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

void fillImageMemory (const vk::DeviceInterface&							vkd,
					  vk::VkDevice											device,
					  deUint32												queueFamilyNdx,
					  vk::VkImage											image,
					  const std::vector<de::SharedPtr<vk::Allocation> >&	allocations,
					  const MultiPlaneImageData&							imageData,
					  vk::VkAccessFlags										nextAccess,
					  vk::VkImageLayout										finalLayout,
					  deUint32												arrayLayer)
{
	const VkQueue					queue			= getDeviceQueue(vkd, device, queueFamilyNdx, 0u);
	const Unique<VkCommandPool>		cmdPool			(createCommandPool(vkd, device, (VkCommandPoolCreateFlags)0, queueFamilyNdx));
	const Unique<VkCommandBuffer>	cmdBuffer		(allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
	const PlanarFormatDescription&	formatDesc		= imageData.getDescription();

	for (deUint32 planeNdx = 0; planeNdx < formatDesc.numPlanes; ++planeNdx)
	{
		const VkImageAspectFlagBits			aspect		= (formatDesc.numPlanes > 1)
														? getPlaneAspect(planeNdx)
														: VK_IMAGE_ASPECT_COLOR_BIT;
		const de::SharedPtr<Allocation>&	allocation	= allocations.size() > 1
														? allocations[planeNdx]
														: allocations[0];
		const size_t						planeSize	= imageData.getPlaneSize(planeNdx);
		const deUint32						planeH		= imageData.getSize().y() / formatDesc.planes[planeNdx].heightDivisor;
		const VkImageSubresource			subresource	=
		{
			static_cast<vk::VkImageAspectFlags>(aspect),
			0u,
			arrayLayer,
		};
		VkSubresourceLayout			layout;

		vkd.getImageSubresourceLayout(device, image, &subresource, &layout);

		for (deUint32 row = 0; row < planeH; ++row)
		{
			const size_t		rowSize		= planeSize / planeH;
			void* const			dstPtr		= ((deUint8*)allocation->getHostPtr()) + layout.offset + layout.rowPitch * row;
			const void* const	srcPtr		= ((const deUint8*)imageData.getPlanePtr(planeNdx)) + row * rowSize;

			deMemcpy(dstPtr, srcPtr, rowSize);
		}
		flushMappedMemoryRange(vkd, device, allocation->getMemory(), 0u, VK_WHOLE_SIZE);
	}

	beginCommandBuffer(vkd, *cmdBuffer);

	{
		const VkImageMemoryBarrier		postCopyBarrier	=
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
			DE_NULL,
			0u,
			nextAccess,
			VK_IMAGE_LAYOUT_PREINITIALIZED,
			finalLayout,
			VK_QUEUE_FAMILY_IGNORED,
			VK_QUEUE_FAMILY_IGNORED,
			image,
			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, arrayLayer, 1u }
		};

		vkd.cmdPipelineBarrier(*cmdBuffer,
								(VkPipelineStageFlags)VK_PIPELINE_STAGE_HOST_BIT,
								(VkPipelineStageFlags)VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
								(VkDependencyFlags)0u,
								0u,
								(const VkMemoryBarrier*)DE_NULL,
								0u,
								(const VkBufferMemoryBarrier*)DE_NULL,
								1u,
								&postCopyBarrier);
	}

	endCommandBuffer(vkd, *cmdBuffer);

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

void downloadImage (const DeviceInterface&	vkd,
					VkDevice				device,
					deUint32				queueFamilyNdx,
					Allocator&				allocator,
					VkImage					image,
					MultiPlaneImageData*	imageData,
					VkAccessFlags			prevAccess,
					VkImageLayout			initialLayout)
{
	const VkQueue					queue			= getDeviceQueue(vkd, device, queueFamilyNdx, 0u);
	const Unique<VkCommandPool>		cmdPool			(createCommandPool(vkd, device, (VkCommandPoolCreateFlags)0, queueFamilyNdx));
	const Unique<VkCommandBuffer>	cmdBuffer		(allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
	vector<VkBufferSp>				stagingBuffers;
	vector<AllocationSp>			stagingMemory;

	const PlanarFormatDescription&	formatDesc		= imageData->getDescription();

	allocateStagingBuffers(vkd, device, allocator, *imageData, &stagingBuffers, &stagingMemory);

	beginCommandBuffer(vkd, *cmdBuffer);

	for (deUint32 planeNdx = 0; planeNdx < imageData->getDescription().numPlanes; ++planeNdx)
	{
		const VkImageAspectFlagBits	aspect	= (formatDesc.numPlanes > 1)
											? getPlaneAspect(planeNdx)
											: VK_IMAGE_ASPECT_COLOR_BIT;
		{
			const VkImageMemoryBarrier		preCopyBarrier	=
			{
				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
				DE_NULL,
				prevAccess,
				VK_ACCESS_TRANSFER_READ_BIT,
				initialLayout,
				VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
				VK_QUEUE_FAMILY_IGNORED,
				VK_QUEUE_FAMILY_IGNORED,
				image,
				{
					static_cast<vk::VkImageAspectFlags>(aspect),
					0u,
					1u,
					0u,
					1u
				}
			};

			vkd.cmdPipelineBarrier(*cmdBuffer,
									(VkPipelineStageFlags)VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
									(VkPipelineStageFlags)VK_PIPELINE_STAGE_TRANSFER_BIT,
									(VkDependencyFlags)0u,
									0u,
									(const VkMemoryBarrier*)DE_NULL,
									0u,
									(const VkBufferMemoryBarrier*)DE_NULL,
									1u,
									&preCopyBarrier);
		}
		{
			const VkExtent3D imageExtent		= makeExtent3D(imageData->getSize().x(), imageData->getSize().y(), 1u);
			const VkExtent3D planeExtent		= getPlaneExtent(formatDesc, imageExtent, planeNdx, 0);
			const VkBufferImageCopy		copy	=
			{
				0u,		// bufferOffset
				0u,		// bufferRowLength
				0u,		// bufferImageHeight
				{ (VkImageAspectFlags)aspect, 0u, 0u, 1u },
				makeOffset3D(0u, 0u, 0u),
				planeExtent
			};

			vkd.cmdCopyImageToBuffer(*cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **stagingBuffers[planeNdx], 1u, &copy);
		}
		{
			const VkBufferMemoryBarrier		postCopyBarrier	=
			{
				VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
				DE_NULL,
				VK_ACCESS_TRANSFER_WRITE_BIT,
				VK_ACCESS_HOST_READ_BIT,
				VK_QUEUE_FAMILY_IGNORED,
				VK_QUEUE_FAMILY_IGNORED,
				**stagingBuffers[planeNdx],
				0u,
				VK_WHOLE_SIZE
			};

			vkd.cmdPipelineBarrier(*cmdBuffer,
									(VkPipelineStageFlags)VK_PIPELINE_STAGE_TRANSFER_BIT,
									(VkPipelineStageFlags)VK_PIPELINE_STAGE_HOST_BIT,
									(VkDependencyFlags)0u,
									0u,
									(const VkMemoryBarrier*)DE_NULL,
									1u,
									&postCopyBarrier,
									0u,
									(const VkImageMemoryBarrier*)DE_NULL);
		}
	}

	endCommandBuffer(vkd, *cmdBuffer);

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

	readStagingBuffers(imageData, vkd, device, stagingMemory);
}

void readImageMemory (const vk::DeviceInterface&							vkd,
					  vk::VkDevice											device,
					  deUint32												queueFamilyNdx,
					  vk::VkImage											image,
					  const std::vector<de::SharedPtr<vk::Allocation> >&	allocations,
					  MultiPlaneImageData*									imageData,
					  vk::VkAccessFlags										prevAccess,
					  vk::VkImageLayout										initialLayout)
{
	const VkQueue					queue			= getDeviceQueue(vkd, device, queueFamilyNdx, 0u);
	const Unique<VkCommandPool>		cmdPool			(createCommandPool(vkd, device, (VkCommandPoolCreateFlags)0, queueFamilyNdx));
	const Unique<VkCommandBuffer>	cmdBuffer		(allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
	const PlanarFormatDescription&	formatDesc		= imageData->getDescription();

	beginCommandBuffer(vkd, *cmdBuffer);

	{
		const VkImageMemoryBarrier		preCopyBarrier	=
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
			DE_NULL,
			prevAccess,
			vk::VK_ACCESS_HOST_READ_BIT,
			initialLayout,
			VK_IMAGE_LAYOUT_GENERAL,
			VK_QUEUE_FAMILY_IGNORED,
			VK_QUEUE_FAMILY_IGNORED,
			image,
			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }
		};

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

	endCommandBuffer(vkd, *cmdBuffer);

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

	for (deUint32 planeNdx = 0; planeNdx < formatDesc.numPlanes; ++planeNdx)
	{
		const VkImageAspectFlagBits			aspect		= (formatDesc.numPlanes > 1)
														? getPlaneAspect(planeNdx)
														: VK_IMAGE_ASPECT_COLOR_BIT;
		const de::SharedPtr<Allocation>&	allocation	= allocations.size() > 1
														? allocations[planeNdx]
														: allocations[0];
		const size_t						planeSize	= imageData->getPlaneSize(planeNdx);
		const deUint32						planeH		= imageData->getSize().y() / formatDesc.planes[planeNdx].heightDivisor;
		const VkImageSubresource			subresource	=
		{
			static_cast<vk::VkImageAspectFlags>(aspect),
			0u,
			0u,
		};
		VkSubresourceLayout			layout;

		vkd.getImageSubresourceLayout(device, image, &subresource, &layout);

		invalidateMappedMemoryRange(vkd, device, allocation->getMemory(), 0u, VK_WHOLE_SIZE);

		for (deUint32 row = 0; row < planeH; ++row)
		{
			const size_t		rowSize	= planeSize / planeH;
			const void* const	srcPtr	= ((const deUint8*)allocation->getHostPtr()) + layout.offset + layout.rowPitch * row;
			void* const			dstPtr	= ((deUint8*)imageData->getPlanePtr(planeNdx)) + row * rowSize;

			deMemcpy(dstPtr, srcPtr, rowSize);
		}
	}
}

// ChannelAccess utilities
namespace
{

//! Extend < 32b signed integer to 32b
inline deInt32 signExtend (deUint32 src, int bits)
{
	const deUint32 signBit = 1u << (bits-1);

	src |= ~((src & signBit) - 1);

	return (deInt32)src;
}

deUint32 divRoundUp (deUint32 a, deUint32 b)
{
	if (a % b == 0)
		return a / b;
	else
		return (a / b) + 1;
}

// \todo Taken from tcuTexture.cpp
// \todo [2011-09-21 pyry] Move to tcutil?
template <typename T>
inline T convertSatRte (float f)
{
	// \note Doesn't work for 64-bit types
	DE_STATIC_ASSERT(sizeof(T) < sizeof(deUint64));
	DE_STATIC_ASSERT((-3 % 2 != 0) && (-4 % 2 == 0));

	deInt64	minVal	= std::numeric_limits<T>::min();
	deInt64 maxVal	= std::numeric_limits<T>::max();
	float	q		= deFloatFrac(f);
	deInt64 intVal	= (deInt64)(f-q);

	// Rounding.
	if (q == 0.5f)
	{
		if (intVal % 2 != 0)
			intVal++;
	}
	else if (q > 0.5f)
		intVal++;
	// else Don't add anything

	// Saturate.
	intVal = de::max(minVal, de::min(maxVal, intVal));

	return (T)intVal;
}

} // anonymous

ChannelAccess::ChannelAccess (tcu::TextureChannelClass	channelClass,
							  deUint8					channelSize,
							  const tcu::IVec3&			size,
							  const tcu::IVec3&			bitPitch,
							  void*						data,
							  deUint32					bitOffset)
	: m_channelClass	(channelClass)
	, m_channelSize		(channelSize)
	, m_size			(size)
	, m_bitPitch		(bitPitch)
	, m_data			((deUint8*)data + (bitOffset / 8))
	, m_bitOffset		(bitOffset % 8)
{
}

deUint32 ChannelAccess::getChannelUint (const tcu::IVec3& pos) const
{
	DE_ASSERT(pos[0] < m_size[0]);
	DE_ASSERT(pos[1] < m_size[1]);
	DE_ASSERT(pos[2] < m_size[2]);

	const deInt32			bitOffset	(m_bitOffset + tcu::dot(m_bitPitch, pos));
	const deUint8* const	firstByte	= ((const deUint8*)m_data) + (bitOffset / 8);
	const deUint32			byteCount	= divRoundUp((bitOffset + m_channelSize) - 8u * (bitOffset / 8u), 8u);
	const deUint32			mask		(m_channelSize == 32u ? ~0x0u : (0x1u << m_channelSize) - 1u);
	const deUint32			offset		= bitOffset % 8;
	deUint32				bits		= 0u;

	deMemcpy(&bits, firstByte, byteCount);

	return (bits >> offset) & mask;
}

void ChannelAccess::setChannel (const tcu::IVec3& pos, deUint32 x)
{
	DE_ASSERT(pos[0] < m_size[0]);
	DE_ASSERT(pos[1] < m_size[1]);
	DE_ASSERT(pos[2] < m_size[2]);

	const deInt32	bitOffset	(m_bitOffset + tcu::dot(m_bitPitch, pos));
	deUint8* const	firstByte	= ((deUint8*)m_data) + (bitOffset / 8);
	const deUint32	byteCount	= divRoundUp((bitOffset + m_channelSize) - 8u * (bitOffset / 8u), 8u);
	const deUint32	mask		(m_channelSize == 32u ? ~0x0u : (0x1u << m_channelSize) - 1u);
	const deUint32	offset		= bitOffset % 8;

	const deUint32	bits		= (x & mask) << offset;
	deUint32		oldBits		= 0;

	deMemcpy(&oldBits, firstByte, byteCount);

	{
		const deUint32	newBits	= bits | (oldBits & (~(mask << offset)));

		deMemcpy(firstByte, &newBits,  byteCount);
	}
}

float ChannelAccess::getChannel (const tcu::IVec3& pos) const
{
	const deUint32	bits	(getChannelUint(pos));

	switch (m_channelClass)
	{
		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
			return (float)bits / (float)(m_channelSize == 32 ? ~0x0u : ((0x1u << m_channelSize) - 1u));

		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
			return (float)bits;

		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
			return de::max(-1.0f, (float)signExtend(bits, m_channelSize) / (float)((0x1u << (m_channelSize - 1u)) - 1u));

		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
			return (float)signExtend(bits, m_channelSize);

		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
			if (m_channelSize == 32)
				return tcu::Float32(bits).asFloat();
			else
			{
				DE_FATAL("Float type not supported");
				return -1.0f;
			}

		default:
			DE_FATAL("Unknown texture channel class");
			return -1.0f;
	}
}

tcu::Interval ChannelAccess::getChannel (const tcu::FloatFormat&	conversionFormat,
										 const tcu::IVec3&			pos) const
{
	const deUint32	bits	(getChannelUint(pos));

	switch (m_channelClass)
	{
		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
			return conversionFormat.roundOut(conversionFormat.roundOut((double)bits, false)
											/ conversionFormat.roundOut((double)(m_channelSize == 32 ? ~0x0u : ((0x1u << m_channelSize) - 1u)), false), false);

		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
			return conversionFormat.roundOut((double)bits, false);

		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
		{
			const tcu::Interval result (conversionFormat.roundOut(conversionFormat.roundOut((double)signExtend(bits, m_channelSize), false)
																/ conversionFormat.roundOut((double)((0x1u << (m_channelSize - 1u)) - 1u), false), false));

			return tcu::Interval(de::max(-1.0, result.lo()), de::max(-1.0, result.hi()));
		}

		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
			return conversionFormat.roundOut((double)signExtend(bits, m_channelSize), false);

		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
			if (m_channelSize == 32)
				return conversionFormat.roundOut(tcu::Float32(bits).asFloat(), false);
			else
			{
				DE_FATAL("Float type not supported");
				return tcu::Interval();
			}

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

void ChannelAccess::setChannel (const tcu::IVec3& pos, float x)
{
	DE_ASSERT(pos[0] < m_size[0]);
	DE_ASSERT(pos[1] < m_size[1]);
	DE_ASSERT(pos[2] < m_size[2]);

	const deUint32	mask	(m_channelSize == 32u ? ~0x0u : (0x1u << m_channelSize) - 1u);

	switch (m_channelClass)
	{
		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
		{
			const deUint32	maxValue	(mask);
			const deUint32	value		(de::min(maxValue, (deUint32)convertSatRte<deUint32>(x * (float)maxValue)));
			setChannel(pos, value);
			break;
		}

		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
		{
			const deInt32	range	((0x1u << (m_channelSize - 1u)) - 1u);
			const deUint32	value	((deUint32)de::clamp<deInt32>(convertSatRte<deInt32>(x * (float)range), -range, range));
			setChannel(pos, value);
			break;
		}

		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
		{
			const deUint32	maxValue	(mask);
			const deUint32	value		(de::min(maxValue, (deUint32)x));
			setChannel(pos, value);
			break;
		}

		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
		{
			const deInt32	minValue	(-(deInt32)(1u << (m_channelSize - 1u)));
			const deInt32	maxValue	((deInt32)((1u << (m_channelSize - 1u)) - 1u));
			const deUint32	value		((deUint32)de::clamp((deInt32)x, minValue, maxValue));
			setChannel(pos, value);
			break;
		}

		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
		{
			if (m_channelSize == 32)
			{
				const deUint32	value		= tcu::Float32(x).bits();
				setChannel(pos, value);
			}
			else
				DE_FATAL("Float type not supported");
			break;
		}

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

ChannelAccess getChannelAccess (MultiPlaneImageData&				data,
								const vk::PlanarFormatDescription&	formatInfo,
								const UVec2&						size,
								int									channelNdx)
{
	DE_ASSERT(formatInfo.hasChannelNdx(channelNdx));

	const deUint32	planeNdx			= formatInfo.channels[channelNdx].planeNdx;
	const deUint32	valueOffsetBits		= formatInfo.channels[channelNdx].offsetBits;
	const deUint32	pixelStrideBytes	= formatInfo.channels[channelNdx].strideBytes;
	const deUint32	pixelStrideBits		= pixelStrideBytes * 8;
	const deUint8	sizeBits			= formatInfo.channels[channelNdx].sizeBits;

	DE_ASSERT(size.x() % (formatInfo.blockWidth * formatInfo.planes[planeNdx].widthDivisor) == 0);
	DE_ASSERT(size.y() % (formatInfo.blockHeight * formatInfo.planes[planeNdx].heightDivisor) == 0);

	deUint32		accessWidth			= size.x() / ( formatInfo.blockWidth * formatInfo.planes[planeNdx].widthDivisor );
	const deUint32	accessHeight		= size.y() / ( formatInfo.blockHeight * formatInfo.planes[planeNdx].heightDivisor );
	const deUint32	elementSizeBytes	= formatInfo.planes[planeNdx].elementSizeBytes;
	const deUint32	rowPitch			= formatInfo.planes[planeNdx].elementSizeBytes * accessWidth;
	const deUint32	rowPitchBits		= rowPitch * 8;

	if (pixelStrideBytes != elementSizeBytes)
	{
		DE_ASSERT(elementSizeBytes % pixelStrideBytes == 0);
		accessWidth *= elementSizeBytes/pixelStrideBytes;
	}

	return ChannelAccess((tcu::TextureChannelClass)formatInfo.channels[channelNdx].type, sizeBits, tcu::IVec3(accessWidth, accessHeight, 1u), tcu::IVec3((int)pixelStrideBits, (int)rowPitchBits, 0), data.getPlanePtr(planeNdx), (deUint32)valueOffsetBits);
}

bool isXChromaSubsampled (vk::VkFormat format)
{
	switch (format)
	{
		case vk::VK_FORMAT_G8B8G8R8_422_UNORM:
		case vk::VK_FORMAT_B8G8R8G8_422_UNORM:
		case vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
		case vk::VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
		case vk::VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
		case vk::VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
		case vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
		case vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
		case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
		case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
		case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
		case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
		case vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
		case vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
		case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
		case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
		case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
		case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
		case vk::VK_FORMAT_G16B16G16R16_422_UNORM:
		case vk::VK_FORMAT_B16G16R16G16_422_UNORM:
		case vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
		case vk::VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
		case vk::VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
		case vk::VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
			return true;

		default:
			return false;
	}
}

bool isYChromaSubsampled (vk::VkFormat format)
{
	switch (format)
	{
		case vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
		case vk::VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
		case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
		case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
		case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
		case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
		case vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
		case vk::VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
			return true;

		default:
			return false;
	}
}

bool areLsb6BitsDontCare(vk::VkFormat srcFormat, vk::VkFormat dstFormat)
{
	if ((srcFormat == vk::VK_FORMAT_R10X6_UNORM_PACK16)	                        ||
		(dstFormat == vk::VK_FORMAT_R10X6_UNORM_PACK16)                         ||
		(srcFormat == vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16)                   ||
		(dstFormat == vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16)                   ||
		(srcFormat == vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16)         ||
		(dstFormat == vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16)         ||
		(srcFormat == vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16)     ||
		(dstFormat == vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16)     ||
		(srcFormat == vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16)     ||
		(dstFormat == vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16)     ||
		(srcFormat == vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16)  ||
		(dstFormat == vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16)  ||
		(srcFormat == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16) ||
		(dstFormat == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16) ||
		(srcFormat == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16) ||
		(dstFormat == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16) ||
		(srcFormat == vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16)  ||
		(dstFormat == vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16)  ||
		(srcFormat == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16) ||
		(dstFormat == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16))
	{
		return true;
	}

	return false;
}

bool areLsb4BitsDontCare(vk::VkFormat srcFormat, vk::VkFormat dstFormat)
{
	if ((srcFormat == vk::VK_FORMAT_R12X4_UNORM_PACK16)                         ||
		(dstFormat == vk::VK_FORMAT_R12X4_UNORM_PACK16)                         ||
		(srcFormat == vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16)                   ||
		(dstFormat == vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16)                   ||
		(srcFormat == vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16)         ||
		(dstFormat == vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16)         ||
		(srcFormat == vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16)     ||
		(dstFormat == vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16)     ||
		(srcFormat == vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16)     ||
		(dstFormat == vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16)     ||
		(srcFormat == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16) ||
		(dstFormat == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16) ||
		(srcFormat == vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16)  ||
		(dstFormat == vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16)  ||
		(srcFormat == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16) ||
		(dstFormat == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16) ||
		(srcFormat == vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16)  ||
		(dstFormat == vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16)  ||
		(srcFormat == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16) ||
		(dstFormat == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16))
	{
		return true;
	}

	return false;
}

// \note Used for range expansion
tcu::UVec4 getYCbCrBitDepth (vk::VkFormat format)
{
	switch (format)
	{
		case vk::VK_FORMAT_G8B8G8R8_422_UNORM:
		case vk::VK_FORMAT_B8G8R8G8_422_UNORM:
		case vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
		case vk::VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
		case vk::VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
		case vk::VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
		case vk::VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
			return tcu::UVec4(8, 8, 8, 0);

		case vk::VK_FORMAT_R10X6_UNORM_PACK16:
			return tcu::UVec4(10, 0, 0, 0);

		case vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16:
			return tcu::UVec4(10, 10, 0, 0);

		case vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
			return tcu::UVec4(10, 10, 10, 10);

		case vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
		case vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16:
		case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
		case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
		case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
		case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
		case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
			return tcu::UVec4(10, 10, 10, 0);

		case vk::VK_FORMAT_R12X4_UNORM_PACK16:
			return tcu::UVec4(12, 0, 0, 0);

		case vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16:
			return tcu::UVec4(12, 12, 0, 0);

		case vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
		case vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
		case vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16:
		case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
		case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
		case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
		case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
		case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
			return tcu::UVec4(12, 12, 12, 12);

		case vk::VK_FORMAT_G16B16G16R16_422_UNORM:
		case vk::VK_FORMAT_B16G16R16G16_422_UNORM:
		case vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
		case vk::VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
		case vk::VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
		case vk::VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
		case vk::VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
			return tcu::UVec4(16, 16, 16, 0);

		default:
			return tcu::getTextureFormatBitDepth(vk::mapVkFormat(format)).cast<deUint32>();
	}
}

std::vector<tcu::FloatFormat> getPrecision (VkFormat format)
{
	std::vector<FloatFormat>	floatFormats;
	UVec4						channelDepth	= getYCbCrBitDepth (format);

	for (deUint32 channelIdx = 0; channelIdx < 4; channelIdx++)
		floatFormats.push_back(tcu::FloatFormat(0, 0, channelDepth[channelIdx], false, tcu::YES));

	return floatFormats;
}

deUint32 getYCbCrFormatChannelCount (vk::VkFormat format)
{
	switch (format)
	{
		case vk::VK_FORMAT_A1R5G5B5_UNORM_PACK16:
		case vk::VK_FORMAT_A2B10G10R10_UNORM_PACK32:
		case vk::VK_FORMAT_A2R10G10B10_UNORM_PACK32:
		case vk::VK_FORMAT_A8B8G8R8_UNORM_PACK32:
		case vk::VK_FORMAT_B4G4R4A4_UNORM_PACK16:
		case vk::VK_FORMAT_B5G5R5A1_UNORM_PACK16:
		case vk::VK_FORMAT_B8G8R8A8_UNORM:
		case vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
		case vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16:
		case vk::VK_FORMAT_R16G16B16A16_UNORM:
		case vk::VK_FORMAT_R4G4B4A4_UNORM_PACK16:
		case vk::VK_FORMAT_R5G5B5A1_UNORM_PACK16:
		case vk::VK_FORMAT_R8G8B8A8_UNORM:
			return 4;

		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_B5G6R5_UNORM_PACK16:
		case vk::VK_FORMAT_B8G8R8G8_422_UNORM:
		case vk::VK_FORMAT_B8G8R8_UNORM:
		case vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16:
		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_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
		case vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16:
		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_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
		case vk::VK_FORMAT_G16B16G16R16_422_UNORM:
		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_G8B8G8R8_422_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:
		case vk::VK_FORMAT_R16G16B16_UNORM:
		case vk::VK_FORMAT_R5G6B5_UNORM_PACK16:
		case vk::VK_FORMAT_R8G8B8_UNORM:
			return 3;

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

		case vk::VK_FORMAT_R10X6_UNORM_PACK16:
		case vk::VK_FORMAT_R12X4_UNORM_PACK16:
			return 1;

		default:
			DE_FATAL("Unknown number of channels");
			return -1;
	}
}

// YCbCr color conversion utilities
namespace
{

tcu::Interval rangeExpandChroma (vk::VkSamplerYcbcrRange		range,
								 const tcu::FloatFormat&		conversionFormat,
								 const deUint32					bits,
								 const tcu::Interval&			sample)
{
	const deUint32	values	(0x1u << bits);

	switch (range)
	{
		case vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL:
			return conversionFormat.roundOut(sample - conversionFormat.roundOut(tcu::Interval((double)(0x1u << (bits - 1u)) / (double)((0x1u << bits) - 1u)), false), false);

		case vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW:
		{
			const tcu::Interval	a			(conversionFormat.roundOut(sample * tcu::Interval((double)(values - 1u)), false));
			const tcu::Interval	dividend	(conversionFormat.roundOut(a - tcu::Interval((double)(128u * (0x1u << (bits - 8u)))), false));
			const tcu::Interval	divisor		((double)(224u * (0x1u << (bits - 8u))));
			const tcu::Interval	result		(conversionFormat.roundOut(dividend / divisor, false));

			return result;
		}

		default:
			DE_FATAL("Unknown YCbCrRange");
			return tcu::Interval();
	}
}

tcu::Interval rangeExpandLuma (vk::VkSamplerYcbcrRange		range,
							   const tcu::FloatFormat&		conversionFormat,
							   const deUint32				bits,
							   const tcu::Interval&			sample)
{
	const deUint32	values	(0x1u << bits);

	switch (range)
	{
		case vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL:
			return conversionFormat.roundOut(sample, false);

		case vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW:
		{
			const tcu::Interval	a			(conversionFormat.roundOut(sample * tcu::Interval((double)(values - 1u)), false));
			const tcu::Interval	dividend	(conversionFormat.roundOut(a - tcu::Interval((double)(16u * (0x1u << (bits - 8u)))), false));
			const tcu::Interval	divisor		((double)(219u * (0x1u << (bits - 8u))));
			const tcu::Interval	result		(conversionFormat.roundOut(dividend / divisor, false));

			return result;
		}

		default:
			DE_FATAL("Unknown YCbCrRange");
			return tcu::Interval();
	}
}

tcu::Interval clampMaybe (const tcu::Interval&	x,
						  double				min,
						  double				max)
{
	tcu::Interval result = x;

	DE_ASSERT(min <= max);

	if (x.lo() < min)
		result = result | tcu::Interval(min);

	if (x.hi() > max)
		result = result | tcu::Interval(max);

	return result;
}

void convertColor (vk::VkSamplerYcbcrModelConversion	colorModel,
				   vk::VkSamplerYcbcrRange				range,
				   const vector<tcu::FloatFormat>&		conversionFormat,
				   const tcu::UVec4&					bitDepth,
				   const tcu::Interval					input[4],
				   tcu::Interval						output[4])
{
	switch (colorModel)
	{
		case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY:
		{
			for (size_t ndx = 0; ndx < 4; ndx++)
				output[ndx] = input[ndx];
			break;
		}

		case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY:
		{
			output[0] = clampMaybe(rangeExpandChroma(range, conversionFormat[0], bitDepth[0], input[0]), -0.5, 0.5);
			output[1] = clampMaybe(rangeExpandLuma(range, conversionFormat[1], bitDepth[1], input[1]), 0.0, 1.0);
			output[2] = clampMaybe(rangeExpandChroma(range, conversionFormat[2], bitDepth[2], input[2]), -0.5, 0.5);
			output[3] = input[3];
			break;
		}

		case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601:
		case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709:
		case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020:
		{
			const tcu::Interval	y			(rangeExpandLuma(range, conversionFormat[1], bitDepth[1], input[1]));
			const tcu::Interval	cr			(rangeExpandChroma(range, conversionFormat[0], bitDepth[0], input[0]));
			const tcu::Interval	cb			(rangeExpandChroma(range, conversionFormat[2], bitDepth[2], input[2]));

			const tcu::Interval	yClamped	(clampMaybe(y,   0.0, 1.0));
			const tcu::Interval	crClamped	(clampMaybe(cr, -0.5, 0.5));
			const tcu::Interval	cbClamped	(clampMaybe(cb, -0.5, 0.5));

			if (colorModel == vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601)
			{
				output[0] = conversionFormat[0].roundOut(yClamped + conversionFormat[0].roundOut(1.402 * crClamped, false), false);
				output[1] = conversionFormat[1].roundOut(conversionFormat[1].roundOut(yClamped - conversionFormat[1].roundOut((0.202008 / 0.587) * cbClamped, false), false) - conversionFormat[1].roundOut((0.419198 / 0.587) * crClamped, false), false);
				output[2] = conversionFormat[2].roundOut(yClamped + conversionFormat[2].roundOut(1.772 * cbClamped, false), false);
			}
			else if (colorModel == vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709)
			{
				output[0] = conversionFormat[0].roundOut(yClamped + conversionFormat[0].roundOut(1.5748 * crClamped, false), false);
				output[1] = conversionFormat[1].roundOut(conversionFormat[1].roundOut(yClamped - conversionFormat[1].roundOut((0.13397432 / 0.7152) * cbClamped, false), false) - conversionFormat[1].roundOut((0.33480248 / 0.7152) * crClamped, false), false);
				output[2] = conversionFormat[2].roundOut(yClamped + conversionFormat[2].roundOut(1.8556 * cbClamped, false), false);
			}
			else
			{
				output[0] = conversionFormat[0].roundOut(yClamped + conversionFormat[0].roundOut(1.4746 * crClamped, false), false);
				output[1] = conversionFormat[1].roundOut(conversionFormat[1].roundOut(yClamped - conversionFormat[1].roundOut(conversionFormat[1].roundOut(0.11156702 / 0.6780, false) * cbClamped, false), false) - conversionFormat[1].roundOut(conversionFormat[1].roundOut(0.38737742 / 0.6780, false) * crClamped, false), false);
				output[2] = conversionFormat[2].roundOut(yClamped + conversionFormat[2].roundOut(1.8814 * cbClamped, false), false);
			}
			output[3] = input[3];
			break;
		}

		default:
			DE_FATAL("Unknown YCbCrModel");
	}

	if (colorModel != vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY)
	{
		for (int ndx = 0; ndx < 3; ndx++)
			output[ndx] = clampMaybe(output[ndx], 0.0, 1.0);
	}
}

int mirror (int coord)
{
	return coord >= 0 ? coord : -(1 + coord);
}

int imod (int a, int b)
{
	int m = a % b;
	return m < 0 ? m + b : m;
}

tcu::Interval frac (const tcu::Interval& x)
{
	if (x.hi() - x.lo() >= 1.0)
		return tcu::Interval(0.0, 1.0);
	else
	{
		const tcu::Interval ret (deFrac(x.lo()), deFrac(x.hi()));

		return ret;
	}
}

tcu::Interval calculateUV (const tcu::FloatFormat&	coordFormat,
						   const tcu::Interval&		st,
						   const int				size)
{
	return coordFormat.roundOut(coordFormat.roundOut(st, false) * tcu::Interval((double)size), false);
}

tcu::IVec2 calculateNearestIJRange (const tcu::FloatFormat&	coordFormat,
								    const tcu::Interval&	uv)
{
	const tcu::Interval	ij	(coordFormat.roundOut(coordFormat.roundOut(uv, false) - tcu::Interval(0.5), false));

	return tcu::IVec2(deRoundToInt32(ij.lo() - coordFormat.ulp(ij.lo(), 1)), deRoundToInt32(ij.hi() + coordFormat.ulp(ij.hi(), 1)));
}

// Calculate range of pixel coordinates that can be used as lower coordinate for linear sampling
tcu::IVec2 calculateLinearIJRange (const tcu::FloatFormat&	coordFormat,
								   const tcu::Interval&		uv)
{
	const tcu::Interval	ij	(coordFormat.roundOut(uv - tcu::Interval(0.5), false));

	return tcu::IVec2(deFloorToInt32(ij.lo()), deFloorToInt32(ij.hi()));
}

tcu::IVec2 calculateIJRange (vk::VkFilter				filter,
							 const tcu::FloatFormat&	coordFormat,
							 const tcu::Interval&		uv)
{
	DE_ASSERT(filter == vk::VK_FILTER_NEAREST || filter == vk::VK_FILTER_LINEAR);
	return (filter == vk::VK_FILTER_LINEAR)	? calculateLinearIJRange(coordFormat, uv)
											: calculateNearestIJRange(coordFormat, uv);
}

tcu::Interval calculateAB (const deUint32		subTexelPrecisionBits,
						   const tcu::Interval&	uv,
						   int					ij)
{
	const deUint32		subdivisions	= 0x1u << subTexelPrecisionBits;
	const tcu::Interval	ab				(frac((uv - 0.5) & tcu::Interval((double)ij, (double)(ij + 1))));
	const tcu::Interval	gridAB			(ab * tcu::Interval(subdivisions));
	const tcu::Interval	rounded			(de::max(deFloor(gridAB.lo()) / subdivisions, 0.0) , de::min(deCeil(gridAB.hi()) / subdivisions, 1.0));

	return rounded;
}

tcu::Interval lookupWrapped (const ChannelAccess&		access,
							 const tcu::FloatFormat&	conversionFormat,
							 vk::VkSamplerAddressMode	addressModeU,
							 vk::VkSamplerAddressMode	addressModeV,
							 const tcu::IVec2&			coord)
{
	return access.getChannel(conversionFormat,
							 tcu::IVec3(wrap(addressModeU, coord.x(), access.getSize().x()), wrap(addressModeV, coord.y(), access.getSize().y()), 0));
}

tcu::Interval linearInterpolate (const tcu::FloatFormat&	filteringFormat,
								 const tcu::Interval&		a,
								 const tcu::Interval&		b,
								 const tcu::Interval&		p00,
								 const tcu::Interval&		p10,
								 const tcu::Interval&		p01,
								 const tcu::Interval&		p11)
{
	const tcu::Interval	p[4] =
	{
		p00,
		p10,
		p01,
		p11
	};
	tcu::Interval		result	(0.0);

	for (size_t ndx = 0; ndx < 4; ndx++)
	{
		const tcu::Interval	weightA	(filteringFormat.roundOut((ndx % 2) == 0 ? (1.0 - a) : a, false));
		const tcu::Interval	weightB	(filteringFormat.roundOut((ndx / 2) == 0 ? (1.0 - b) : b, false));
		const tcu::Interval	weight	(filteringFormat.roundOut(weightA * weightB, false));

		result = filteringFormat.roundOut(result + filteringFormat.roundOut(p[ndx] * weight, false), false);
	}

	return result;
}

tcu::Interval calculateImplicitChromaUV (const tcu::FloatFormat&	coordFormat,
										 vk::VkChromaLocation		offset,
										 const tcu::Interval&		uv)
{
	if (offset == vk::VK_CHROMA_LOCATION_COSITED_EVEN)
		return coordFormat.roundOut(0.5 * coordFormat.roundOut(uv + 0.5, false), false);
	else
		return coordFormat.roundOut(0.5 * uv, false);
}

tcu::Interval linearSample (const ChannelAccess&		access,
						    const tcu::FloatFormat&		conversionFormat,
						    const tcu::FloatFormat&		filteringFormat,
						    vk::VkSamplerAddressMode	addressModeU,
						    vk::VkSamplerAddressMode	addressModeV,
						    const tcu::IVec2&			coord,
						    const tcu::Interval&		a,
						    const tcu::Interval&		b)
{
	return linearInterpolate(filteringFormat, a, b,
									lookupWrapped(access, conversionFormat, addressModeU, addressModeV, coord + tcu::IVec2(0, 0)),
									lookupWrapped(access, conversionFormat, addressModeU, addressModeV, coord + tcu::IVec2(1, 0)),
									lookupWrapped(access, conversionFormat, addressModeU, addressModeV, coord + tcu::IVec2(0, 1)),
									lookupWrapped(access, conversionFormat, addressModeU, addressModeV, coord + tcu::IVec2(1, 1)));
}

tcu::Interval reconstructLinearXChromaSample (const tcu::FloatFormat&	filteringFormat,
											  const tcu::FloatFormat&	conversionFormat,
											  vk::VkChromaLocation		offset,
											  vk::VkSamplerAddressMode	addressModeU,
											  vk::VkSamplerAddressMode	addressModeV,
											  const ChannelAccess&		access,
											  int						i,
											  int						j)
{
	const int subI	= offset == vk::VK_CHROMA_LOCATION_COSITED_EVEN
					? divFloor(i, 2)
					: (i % 2 == 0 ? divFloor(i, 2) - 1 : divFloor(i, 2));
	const double a	= offset == vk::VK_CHROMA_LOCATION_COSITED_EVEN
					? (i % 2 == 0 ? 0.0 : 0.5)
					: (i % 2 == 0 ? 0.25 : 0.75);

	const tcu::Interval A (filteringFormat.roundOut(       a  * lookupWrapped(access, conversionFormat, addressModeU, addressModeV, tcu::IVec2(subI, j)), false));
	const tcu::Interval B (filteringFormat.roundOut((1.0 - a) * lookupWrapped(access, conversionFormat, addressModeU, addressModeV, tcu::IVec2(subI + 1, j)), false));
	return filteringFormat.roundOut(A + B, false);
}

tcu::Interval reconstructLinearXYChromaSample (const tcu::FloatFormat&	filteringFormat,
										  const tcu::FloatFormat&		conversionFormat,
										  vk::VkChromaLocation			xOffset,
										  vk::VkChromaLocation			yOffset,
										  vk::VkSamplerAddressMode		addressModeU,
										  vk::VkSamplerAddressMode		addressModeV,
										  const ChannelAccess&			access,
										  int							i,
										  int							j)
{
	const int		subI	= xOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN
							? divFloor(i, 2)
							: (i % 2 == 0 ? divFloor(i, 2) - 1 : divFloor(i, 2));
	const int		subJ	= yOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN
							? divFloor(j, 2)
							: (j % 2 == 0 ? divFloor(j, 2) - 1 : divFloor(j, 2));

	const double	a		= xOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN
							? (i % 2 == 0 ? 0.0 : 0.5)
							: (i % 2 == 0 ? 0.25 : 0.75);
	const double	b		= yOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN
							? (j % 2 == 0 ? 0.0 : 0.5)
							: (j % 2 == 0 ? 0.25 : 0.75);

	return linearSample(access, conversionFormat, filteringFormat, addressModeU, addressModeV, tcu::IVec2(subI, subJ), a, b);
}

const ChannelAccess& swizzle (vk::VkComponentSwizzle	swizzle,
							  const ChannelAccess&		identityPlane,
							  const ChannelAccess&		rPlane,
							  const ChannelAccess&		gPlane,
							  const ChannelAccess&		bPlane,
							  const ChannelAccess&		aPlane)
{
	switch (swizzle)
	{
		case vk::VK_COMPONENT_SWIZZLE_IDENTITY:	return identityPlane;
		case vk::VK_COMPONENT_SWIZZLE_R:		return rPlane;
		case vk::VK_COMPONENT_SWIZZLE_G:		return gPlane;
		case vk::VK_COMPONENT_SWIZZLE_B:		return bPlane;
		case vk::VK_COMPONENT_SWIZZLE_A:		return aPlane;

		default:
			DE_FATAL("Unsupported swizzle");
			return identityPlane;
	}
}

} // anonymous

int wrap (vk::VkSamplerAddressMode	addressMode,
		  int						coord,
		  int						size)
{
	switch (addressMode)
	{
		case vk::VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:
			return (size - 1) - mirror(imod(coord, 2 * size) - size);

		case vk::VK_SAMPLER_ADDRESS_MODE_REPEAT:
			return imod(coord, size);

		case vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
			return de::clamp(coord, 0, size - 1);

		case vk::VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:
			return de::clamp(mirror(coord), 0, size - 1);

		default:
			DE_FATAL("Unknown wrap mode");
			return ~0;
	}
}

int divFloor (int a, int b)
{
	if (a % b == 0)
		return a / b;
	else if (a > 0)
		return a / b;
	else
		return (a / b) - 1;
}

void calculateBounds (const ChannelAccess&				rPlane,
					  const ChannelAccess&				gPlane,
					  const ChannelAccess&				bPlane,
					  const ChannelAccess&				aPlane,
					  const UVec4&						bitDepth,
					  const vector<Vec2>&				sts,
					  const vector<FloatFormat>&		filteringFormat,
					  const vector<FloatFormat>&		conversionFormat,
					  const deUint32					subTexelPrecisionBits,
					  vk::VkFilter						filter,
					  vk::VkSamplerYcbcrModelConversion	colorModel,
					  vk::VkSamplerYcbcrRange			range,
					  vk::VkFilter						chromaFilter,
					  vk::VkChromaLocation				xChromaOffset,
					  vk::VkChromaLocation				yChromaOffset,
					  const vk::VkComponentMapping&		componentMapping,
					  bool								explicitReconstruction,
					  vk::VkSamplerAddressMode			addressModeU,
					  vk::VkSamplerAddressMode			addressModeV,
					  std::vector<Vec4>&				minBounds,
					  std::vector<Vec4>&				maxBounds,
					  std::vector<Vec4>&				uvBounds,
					  std::vector<IVec4>&				ijBounds)
{
	const FloatFormat		highp			(-126, 127, 23, true,
											 tcu::MAYBE,	// subnormals
											 tcu::YES,		// infinities
											 tcu::MAYBE);	// NaN
	const FloatFormat		coordFormat		(-32, 32, 16, true);
	const ChannelAccess&	rAccess			(swizzle(componentMapping.r, rPlane, rPlane, gPlane, bPlane, aPlane));
	const ChannelAccess&	gAccess			(swizzle(componentMapping.g, gPlane, rPlane, gPlane, bPlane, aPlane));
	const ChannelAccess&	bAccess			(swizzle(componentMapping.b, bPlane, rPlane, gPlane, bPlane, aPlane));
	const ChannelAccess&	aAccess			(swizzle(componentMapping.a, aPlane, rPlane, gPlane, bPlane, aPlane));

	const bool				subsampledX		= gAccess.getSize().x() > rAccess.getSize().x();
	const bool				subsampledY		= gAccess.getSize().y() > rAccess.getSize().y();

	minBounds.resize(sts.size(), Vec4(TCU_INFINITY));
	maxBounds.resize(sts.size(), Vec4(-TCU_INFINITY));

	uvBounds.resize(sts.size(), Vec4(TCU_INFINITY, -TCU_INFINITY, TCU_INFINITY, -TCU_INFINITY));
	ijBounds.resize(sts.size(), IVec4(0x7FFFFFFF, -1 -0x7FFFFFFF, 0x7FFFFFFF, -1 -0x7FFFFFFF));

	// Chroma plane sizes must match
	DE_ASSERT(rAccess.getSize() == bAccess.getSize());

	// Luma plane sizes must match
	DE_ASSERT(gAccess.getSize() == aAccess.getSize());

	// Luma plane size must match chroma plane or be twice as big
	DE_ASSERT(rAccess.getSize().x() == gAccess.getSize().x() || 2 * rAccess.getSize().x() == gAccess.getSize().x());
	DE_ASSERT(rAccess.getSize().y() == gAccess.getSize().y() || 2 * rAccess.getSize().y() == gAccess.getSize().y());

	DE_ASSERT(filter == vk::VK_FILTER_NEAREST || filter == vk::VK_FILTER_LINEAR);
	DE_ASSERT(chromaFilter == vk::VK_FILTER_NEAREST || chromaFilter == vk::VK_FILTER_LINEAR);
	DE_ASSERT(subsampledX || !subsampledY);


	for (size_t ndx = 0; ndx < sts.size(); ndx++)
	{
		const Vec2	st		(sts[ndx]);
		Interval	bounds[4];

		const Interval	u	(calculateUV(coordFormat, st[0], gAccess.getSize().x()));
		const Interval	v	(calculateUV(coordFormat, st[1], gAccess.getSize().y()));

		uvBounds[ndx][0] = (float)u.lo();
		uvBounds[ndx][1] = (float)u.hi();

		uvBounds[ndx][2] = (float)v.lo();
		uvBounds[ndx][3] = (float)v.hi();

		const IVec2	iRange	(calculateIJRange(filter, coordFormat, u));
		const IVec2	jRange	(calculateIJRange(filter, coordFormat, v));

		ijBounds[ndx][0] = iRange[0];
		ijBounds[ndx][1] = iRange[1];

		ijBounds[ndx][2] = jRange[0];
		ijBounds[ndx][3] = jRange[1];

		for (int j = jRange.x(); j <= jRange.y(); j++)
		for (int i = iRange.x(); i <= iRange.y(); i++)
		{
			if (filter == vk::VK_FILTER_NEAREST)
			{
				const Interval	gValue	(lookupWrapped(gAccess, conversionFormat[1], addressModeU, addressModeV, IVec2(i, j)));
				const Interval	aValue	(lookupWrapped(aAccess, conversionFormat[3], addressModeU, addressModeV, IVec2(i, j)));

				if (explicitReconstruction || !(subsampledX || subsampledY))
				{
					Interval rValue, bValue;
					if (chromaFilter == vk::VK_FILTER_NEAREST || !subsampledX)
					{
						// Reconstruct using nearest if needed, otherwise, just take what's already there.
						const int subI = subsampledX ? i / 2 : i;
						const int subJ = subsampledY ? j / 2 : j;
						rValue = lookupWrapped(rAccess, conversionFormat[0], addressModeU, addressModeV, IVec2(subI, subJ));
						bValue = lookupWrapped(bAccess, conversionFormat[2], addressModeU, addressModeV, IVec2(subI, subJ));
					}
					else // vk::VK_FILTER_LINEAR
					{
						if (subsampledY)
						{
							rValue = reconstructLinearXYChromaSample(filteringFormat[0], conversionFormat[0], xChromaOffset, yChromaOffset, addressModeU, addressModeV, rAccess, i, j);
							bValue = reconstructLinearXYChromaSample(filteringFormat[2], conversionFormat[2], xChromaOffset, yChromaOffset, addressModeU, addressModeV, bAccess, i, j);
						}
						else
						{
							rValue = reconstructLinearXChromaSample(filteringFormat[0], conversionFormat[0], xChromaOffset, addressModeU, addressModeV, rAccess, i, j);
							bValue = reconstructLinearXChromaSample(filteringFormat[2], conversionFormat[2], xChromaOffset, addressModeU, addressModeV, bAccess, i, j);
						}
					}

					const Interval srcColor[] =
					{
						rValue,
						gValue,
						bValue,
						aValue
					};
					Interval dstColor[4];

					convertColor(colorModel, range, conversionFormat, bitDepth, srcColor, dstColor);

					for (size_t compNdx = 0; compNdx < 4; compNdx++)
						bounds[compNdx] |= highp.roundOut(dstColor[compNdx], false);
				}
				else
				{
					const Interval	chromaU	(subsampledX ? calculateImplicitChromaUV(coordFormat, xChromaOffset, u) : u);
					const Interval	chromaV	(subsampledY ? calculateImplicitChromaUV(coordFormat, yChromaOffset, v) : v);

					// Reconstructed chroma samples with implicit filtering
					const IVec2	chromaIRange	(subsampledX ? calculateIJRange(chromaFilter, coordFormat, chromaU) : IVec2(i, i));
					const IVec2	chromaJRange	(subsampledY ? calculateIJRange(chromaFilter, coordFormat, chromaV) : IVec2(j, j));

					for (int chromaJ = chromaJRange.x(); chromaJ <= chromaJRange.y(); chromaJ++)
					for (int chromaI = chromaIRange.x(); chromaI <= chromaIRange.y(); chromaI++)
					{
						Interval rValue, bValue;

						if (chromaFilter == vk::VK_FILTER_NEAREST)
						{
							rValue = lookupWrapped(rAccess, conversionFormat[0], addressModeU, addressModeV, IVec2(chromaI, chromaJ));
							bValue = lookupWrapped(bAccess, conversionFormat[2], addressModeU, addressModeV, IVec2(chromaI, chromaJ));
						}
						else // vk::VK_FILTER_LINEAR
						{
							const Interval	chromaA	(calculateAB(subTexelPrecisionBits, chromaU, chromaI));
							const Interval	chromaB	(calculateAB(subTexelPrecisionBits, chromaV, chromaJ));

							rValue = linearSample(rAccess, conversionFormat[0], filteringFormat[0], addressModeU, addressModeV, IVec2(chromaI, chromaJ), chromaA, chromaB);
							bValue = linearSample(bAccess, conversionFormat[2], filteringFormat[2], addressModeU, addressModeV, IVec2(chromaI, chromaJ), chromaA, chromaB);
						}

						const Interval	srcColor[]	=
						{
							rValue,
							gValue,
							bValue,
							aValue
						};

						Interval dstColor[4];
						convertColor(colorModel, range, conversionFormat, bitDepth, srcColor, dstColor);

						for (size_t compNdx = 0; compNdx < 4; compNdx++)
							bounds[compNdx] |= highp.roundOut(dstColor[compNdx], false);
					}
				}
			}
			else // filter == vk::VK_FILTER_LINEAR
			{
				const Interval	lumaA		(calculateAB(subTexelPrecisionBits, u, i));
				const Interval	lumaB		(calculateAB(subTexelPrecisionBits, v, j));

				const Interval	gValue		(linearSample(gAccess, conversionFormat[1], filteringFormat[1], addressModeU, addressModeV, IVec2(i, j), lumaA, lumaB));
				const Interval	aValue		(linearSample(aAccess, conversionFormat[3], filteringFormat[3], addressModeU, addressModeV, IVec2(i, j), lumaA, lumaB));

				if (explicitReconstruction || !(subsampledX || subsampledY))
				{
					Interval rValue, bValue;
					if (chromaFilter == vk::VK_FILTER_NEAREST || !subsampledX)
					{
						rValue = linearInterpolate(filteringFormat[0], lumaA, lumaB,
													lookupWrapped(rAccess, conversionFormat[0], addressModeU, addressModeV, IVec2(i       / (subsampledX ? 2 : 1), j       / (subsampledY ? 2 : 1))),
													lookupWrapped(rAccess, conversionFormat[0], addressModeU, addressModeV, IVec2((i + 1) / (subsampledX ? 2 : 1), j       / (subsampledY ? 2 : 1))),
													lookupWrapped(rAccess, conversionFormat[0], addressModeU, addressModeV, IVec2(i       / (subsampledX ? 2 : 1), (j + 1) / (subsampledY ? 2 : 1))),
													lookupWrapped(rAccess, conversionFormat[0], addressModeU, addressModeV, IVec2((i + 1) / (subsampledX ? 2 : 1), (j + 1) / (subsampledY ? 2 : 1))));
						bValue = linearInterpolate(filteringFormat[2], lumaA, lumaB,
													lookupWrapped(bAccess, conversionFormat[2], addressModeU, addressModeV, IVec2(i       / (subsampledX ? 2 : 1), j       / (subsampledY ? 2 : 1))),
													lookupWrapped(bAccess, conversionFormat[2], addressModeU, addressModeV, IVec2((i + 1) / (subsampledX ? 2 : 1), j       / (subsampledY ? 2 : 1))),
													lookupWrapped(bAccess, conversionFormat[2], addressModeU, addressModeV, IVec2(i       / (subsampledX ? 2 : 1), (j + 1) / (subsampledY ? 2 : 1))),
													lookupWrapped(bAccess, conversionFormat[2], addressModeU, addressModeV, IVec2((i + 1) / (subsampledX ? 2 : 1), (j + 1) / (subsampledY ? 2 : 1))));
					}
					else // vk::VK_FILTER_LINEAR
					{
						if (subsampledY)
						{
							// Linear, Reconstructed xx chroma samples with explicit linear filtering
							rValue = linearInterpolate(filteringFormat[0], lumaA, lumaB,
														reconstructLinearXYChromaSample(filteringFormat[0], conversionFormat[0], xChromaOffset, yChromaOffset, addressModeU, addressModeV, rAccess, i, j),
														reconstructLinearXYChromaSample(filteringFormat[0], conversionFormat[0], xChromaOffset, yChromaOffset, addressModeU, addressModeV, rAccess, i + 1, j),
														reconstructLinearXYChromaSample(filteringFormat[0], conversionFormat[0], xChromaOffset, yChromaOffset, addressModeU, addressModeV, rAccess, i , j + 1),
														reconstructLinearXYChromaSample(filteringFormat[0], conversionFormat[0], xChromaOffset, yChromaOffset, addressModeU, addressModeV, rAccess, i + 1, j + 1));
							bValue = linearInterpolate(filteringFormat[2], lumaA, lumaB,
														reconstructLinearXYChromaSample(filteringFormat[2], conversionFormat[2], xChromaOffset, yChromaOffset, addressModeU, addressModeV, bAccess, i, j),
														reconstructLinearXYChromaSample(filteringFormat[2], conversionFormat[2], xChromaOffset, yChromaOffset, addressModeU, addressModeV, bAccess, i + 1, j),
														reconstructLinearXYChromaSample(filteringFormat[2], conversionFormat[2], xChromaOffset, yChromaOffset, addressModeU, addressModeV, bAccess, i , j + 1),
														reconstructLinearXYChromaSample(filteringFormat[2], conversionFormat[2], xChromaOffset, yChromaOffset, addressModeU, addressModeV, bAccess, i + 1, j + 1));
						}
						else
						{
							// Linear, Reconstructed x chroma samples with explicit linear filtering
							rValue = linearInterpolate(filteringFormat[0], lumaA, lumaB,
														reconstructLinearXChromaSample(filteringFormat[0], conversionFormat[0], xChromaOffset, addressModeU, addressModeV, rAccess, i, j),
														reconstructLinearXChromaSample(filteringFormat[0], conversionFormat[0], xChromaOffset, addressModeU, addressModeV, rAccess, i + 1, j),
														reconstructLinearXChromaSample(filteringFormat[0], conversionFormat[0], xChromaOffset, addressModeU, addressModeV, rAccess, i , j + 1),
														reconstructLinearXChromaSample(filteringFormat[0], conversionFormat[0], xChromaOffset, addressModeU, addressModeV, rAccess, i + 1, j + 1));
							bValue = linearInterpolate(filteringFormat[2], lumaA, lumaB,
														reconstructLinearXChromaSample(filteringFormat[2], conversionFormat[2], xChromaOffset, addressModeU, addressModeV, bAccess, i, j),
														reconstructLinearXChromaSample(filteringFormat[2], conversionFormat[2], xChromaOffset, addressModeU, addressModeV, bAccess, i + 1, j),
														reconstructLinearXChromaSample(filteringFormat[2], conversionFormat[2], xChromaOffset, addressModeU, addressModeV, bAccess, i , j + 1),
														reconstructLinearXChromaSample(filteringFormat[2], conversionFormat[2], xChromaOffset, addressModeU, addressModeV, bAccess, i + 1, j + 1));
						}
					}

					const Interval	srcColor[]	=
					{
						rValue,
						gValue,
						bValue,
						aValue
					};
					Interval dstColor[4];

					convertColor(colorModel, range, conversionFormat, bitDepth, srcColor, dstColor);

					for (size_t compNdx = 0; compNdx < 4; compNdx++)
						bounds[compNdx] |= highp.roundOut(dstColor[compNdx], false);
				}
				else
				{
					const Interval	chromaU	(subsampledX ? calculateImplicitChromaUV(coordFormat, xChromaOffset, u) : u);
					const Interval	chromaV	(subsampledY ? calculateImplicitChromaUV(coordFormat, yChromaOffset, v) : v);

					// TODO: It looks incorrect to ignore the chroma filter here. Is it?
					const IVec2	chromaIRange	(calculateNearestIJRange(coordFormat, chromaU));
					const IVec2	chromaJRange	(calculateNearestIJRange(coordFormat, chromaV));

					for (int chromaJ = chromaJRange.x(); chromaJ <= chromaJRange.y(); chromaJ++)
					for (int chromaI = chromaIRange.x(); chromaI <= chromaIRange.y(); chromaI++)
					{
						Interval rValue, bValue;

						if (chromaFilter == vk::VK_FILTER_NEAREST)
						{
							rValue = lookupWrapped(rAccess, conversionFormat[1], addressModeU, addressModeV, IVec2(chromaI, chromaJ));
							bValue = lookupWrapped(bAccess, conversionFormat[3], addressModeU, addressModeV, IVec2(chromaI, chromaJ));
						}
						else // vk::VK_FILTER_LINEAR
						{
							const Interval	chromaA	(calculateAB(subTexelPrecisionBits, chromaU, chromaI));
							const Interval	chromaB	(calculateAB(subTexelPrecisionBits, chromaV, chromaJ));

							rValue = linearSample(rAccess, conversionFormat[0], filteringFormat[0], addressModeU, addressModeV, IVec2(chromaI, chromaJ), chromaA, chromaB);
							bValue = linearSample(bAccess, conversionFormat[2], filteringFormat[2], addressModeU, addressModeV, IVec2(chromaI, chromaJ), chromaA, chromaB);
						}

						const Interval	srcColor[]	=
						{
							rValue,
							gValue,
							bValue,
							aValue
						};
						Interval dstColor[4];
						convertColor(colorModel, range, conversionFormat, bitDepth, srcColor, dstColor);

						for (size_t compNdx = 0; compNdx < 4; compNdx++)
							bounds[compNdx] |= highp.roundOut(dstColor[compNdx], false);
					}
				}
			}
		}

		minBounds[ndx] = Vec4((float)bounds[0].lo(), (float)bounds[1].lo(), (float)bounds[2].lo(), (float)bounds[3].lo());
		maxBounds[ndx] = Vec4((float)bounds[0].hi(), (float)bounds[1].hi(), (float)bounds[2].hi(), (float)bounds[3].hi());
	}
}

} // ycbcr

} // vkt
