/*-------------------------------------------------------------------------
 * 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 Image View Tests
 *//*--------------------------------------------------------------------*/

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

#include "vkStrUtil.hpp"
#include "vkRef.hpp"
#include "vkRefUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkMemUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkCmdUtil.hpp"

#include "tcuTestLog.hpp"
#include "tcuVectorUtil.hpp"

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

namespace vkt
{
namespace ycbcr
{
namespace
{

using namespace vk;
using namespace shaderexecutor;

using tcu::UVec2;
using tcu::Vec2;
using tcu::Vec4;
using tcu::TestLog;
using de::MovePtr;
using de::UniquePtr;
using std::vector;
using std::string;

typedef de::SharedPtr<Allocation>				AllocationSp;
typedef de::SharedPtr<vk::Unique<VkBuffer> >	VkBufferSp;

VkFormat getPlaneCompatibleFormat (VkFormat multiPlanarFormat, deUint32 planeNdx)
{
	switch (multiPlanarFormat)
	{
		case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
		case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
		case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
			if (de::inRange(planeNdx, 0u, 2u))
				return VK_FORMAT_R8_UNORM;
			else
				break;

		case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
		case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
			if (planeNdx == 0)
				return VK_FORMAT_R8_UNORM;
			else if (planeNdx == 1)
				return VK_FORMAT_R8G8_UNORM;
			else
				break;

		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
		case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
			if (de::inRange(planeNdx, 0u, 2u))
				return VK_FORMAT_R10X6_UNORM_PACK16;
			else
				break;

		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
		case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
			if (planeNdx == 0)
				return VK_FORMAT_R10X6_UNORM_PACK16;
			else if (planeNdx == 1)
				return VK_FORMAT_R10X6G10X6_UNORM_2PACK16;
			else
				break;

		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
		case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
			if (de::inRange(planeNdx, 0u, 2u))
				return VK_FORMAT_R12X4_UNORM_PACK16;
			else
				break;

		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
		case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
			if (planeNdx == 0)
				return VK_FORMAT_R12X4_UNORM_PACK16;
			else if (planeNdx == 1)
				return VK_FORMAT_R12X4G12X4_UNORM_2PACK16;
			else
				break;

		case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
		case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
		case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
			if (de::inRange(planeNdx, 0u, 2u))
				return VK_FORMAT_R16_UNORM;
			else
				break;

		case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM:
		case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM:
			if (planeNdx == 0)
				return VK_FORMAT_R16_UNORM;
			else if (planeNdx == 1)
				return VK_FORMAT_R16G16_UNORM;
			else
				break;

		default:
			break;
	}

	DE_FATAL("Invalid format and plane index combination");
	return VK_FORMAT_UNDEFINED;
}

Move<VkImage> createTestImage (const DeviceInterface&	vkd,
							   VkDevice					device,
							   VkFormat					format,
							   const UVec2&				size,
							   VkImageCreateFlags		createFlags)
{
	const VkImageCreateInfo		createInfo	=
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
		DE_NULL,
		createFlags,
		VK_IMAGE_TYPE_2D,
		format,
		makeExtent3D(size.x(), size.y(), 1u),
		1u,		// mipLevels
		1u,		// arrayLayers
		VK_SAMPLE_COUNT_1_BIT,
		VK_IMAGE_TILING_OPTIMAL,
		VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT,
		VK_SHARING_MODE_EXCLUSIVE,
		0u,
		(const deUint32*)DE_NULL,
		VK_IMAGE_LAYOUT_UNDEFINED,
	};

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

Move<VkImageView> createImageView (const DeviceInterface&				vkd,
								   VkDevice								device,
								   VkImage								image,
								   VkFormat								format,
								   VkImageAspectFlagBits				imageAspect,
								   const VkSamplerYcbcrConversionInfo*	samplerConversionInfo)
{
	const VkImageViewCreateInfo				viewInfo	=
	{
		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
		samplerConversionInfo,
		(VkImageViewCreateFlags)0,
		image,
		VK_IMAGE_VIEW_TYPE_2D,
		format,
		{
			VK_COMPONENT_SWIZZLE_IDENTITY,
			VK_COMPONENT_SWIZZLE_IDENTITY,
			VK_COMPONENT_SWIZZLE_IDENTITY,
			VK_COMPONENT_SWIZZLE_IDENTITY,
		},
		{ (VkImageAspectFlags)imageAspect, 0u, 1u, 0u, 1u },
	};

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

// Descriptor layout for set 1:
// 0: Plane view bound as COMBINED_IMAGE_SAMPLER
// 1: "Whole" image bound as COMBINED_IMAGE_SAMPLER
//    + immutable sampler (required for color conversion)

Move<VkDescriptorSetLayout> createDescriptorSetLayout (const DeviceInterface& vkd, VkDevice device, VkSampler conversionSampler)
{
	const VkDescriptorSetLayoutBinding		bindings[]	=
	{
		{
			0u,												// binding
			VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
			1u,												// descriptorCount
			VK_SHADER_STAGE_ALL,
			(const VkSampler*)DE_NULL
		},
		{
			1u,												// binding
			VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
			1u,												// descriptorCount
			VK_SHADER_STAGE_ALL,
			&conversionSampler
		}
	};
	const VkDescriptorSetLayoutCreateInfo	layoutInfo	=
	{
		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
		DE_NULL,
		(VkDescriptorSetLayoutCreateFlags)0u,
		DE_LENGTH_OF_ARRAY(bindings),
		bindings,
	};

	return createDescriptorSetLayout(vkd, device, &layoutInfo);
}

Move<VkDescriptorPool> createDescriptorPool (const DeviceInterface& vkd, VkDevice device)
{
	const VkDescriptorPoolSize			poolSizes[]	=
	{
		{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	2u	},
	};
	const VkDescriptorPoolCreateInfo	poolInfo	=
	{
		VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
		DE_NULL,
		(VkDescriptorPoolCreateFlags)VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
		1u,		// maxSets
		DE_LENGTH_OF_ARRAY(poolSizes),
		poolSizes,
	};

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

Move<VkDescriptorSet> createDescriptorSet (const DeviceInterface&	vkd,
										   VkDevice					device,
										   VkDescriptorPool			descPool,
										   VkDescriptorSetLayout	descLayout,
										   VkImageView				planeView,
										   VkSampler				planeViewSampler,
										   VkImageView				wholeView,
										   VkSampler				wholeViewSampler)
{
	Move<VkDescriptorSet>	descSet;

	{
		const VkDescriptorSetAllocateInfo	allocInfo	=
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
			DE_NULL,
			descPool,
			1u,
			&descLayout,
		};

		descSet = allocateDescriptorSet(vkd, device, &allocInfo);
	}

	{
		const VkDescriptorImageInfo		imageInfo0			=
		{
			planeViewSampler,
			planeView,
			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
		};
		const VkDescriptorImageInfo		imageInfo1			=
		{
			wholeViewSampler,
			wholeView,
			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
		};
		const VkWriteDescriptorSet		descriptorWrites[]		=
		{
			{
				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
				DE_NULL,
				*descSet,
				0u,		// dstBinding
				0u,		// dstArrayElement
				1u,		// descriptorCount
				VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
				&imageInfo0,
				(const VkDescriptorBufferInfo*)DE_NULL,
				(const VkBufferView*)DE_NULL,
			},
			{
				VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
				DE_NULL,
				*descSet,
				1u,		// dstBinding
				0u,		// dstArrayElement
				1u,		// descriptorCount
				VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
				&imageInfo1,
				(const VkDescriptorBufferInfo*)DE_NULL,
				(const VkBufferView*)DE_NULL,
			}
		};

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

	return descSet;
}

void executeImageBarrier (const DeviceInterface&		vkd,
						  VkDevice						device,
						  deUint32						queueFamilyNdx,
						  VkPipelineStageFlags			srcStage,
						  VkPipelineStageFlags			dstStage,
						  const VkImageMemoryBarrier&	barrier)
{
	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));

	beginCommandBuffer(vkd, *cmdBuffer);

	vkd.cmdPipelineBarrier(*cmdBuffer,
						   srcStage,
						   dstStage,
						   (VkDependencyFlags)0u,
						   0u,
						   (const VkMemoryBarrier*)DE_NULL,
						   0u,
						   (const VkBufferMemoryBarrier*)DE_NULL,
						   1u,
						   &barrier);

	endCommandBuffer(vkd, *cmdBuffer);

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

struct TestParameters
{
	enum ViewType
	{
		VIEWTYPE_IMAGE_VIEW	= 0,
		VIEWTYPE_MEMORY_ALIAS,

		VIEWTYPE_LAST
	};

	ViewType			viewType;
	VkFormat			format;
	UVec2				size;
	VkImageCreateFlags	createFlags;
	deUint32			planeNdx;
	glu::ShaderType		shaderType;

	TestParameters (ViewType viewType_, VkFormat format_, const UVec2& size_, VkImageCreateFlags createFlags_, deUint32 planeNdx_, glu::ShaderType shaderType_)
		: viewType		(viewType_)
		, format		(format_)
		, size			(size_)
		, createFlags	(createFlags_)
		, planeNdx		(planeNdx_)
		, shaderType	(shaderType_)
	{
	}

	TestParameters (void)
		: viewType		(VIEWTYPE_LAST)
		, format		(VK_FORMAT_UNDEFINED)
		, createFlags	(0u)
		, planeNdx		(0u)
		, shaderType	(glu::SHADERTYPE_LAST)
	{
	}
};

ShaderSpec getShaderSpec (const TestParameters&)
{
	ShaderSpec spec;

	spec.inputs.push_back(Symbol("texCoord", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_HIGHP)));
	spec.outputs.push_back(Symbol("result0", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
	spec.outputs.push_back(Symbol("result1", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));

	spec.globalDeclarations =
		"layout(binding = 1, set = 1) uniform highp sampler2D u_image;\n"
		"layout(binding = 0, set = 1) uniform highp sampler2D u_planeView;\n";

	spec.source =
		"result0 = texture(u_image, texCoord);\n"
		"result1 = texture(u_planeView, texCoord);\n";

	return spec;
}


void generateLookupCoordinates (const UVec2& imageSize, size_t numCoords, de::Random* rnd, vector<Vec2>* dst)
{
	dst->resize(numCoords);

	for (size_t coordNdx = 0; coordNdx < numCoords; ++coordNdx)
	{
		const deUint32	texelX	= rnd->getUint32() % imageSize.x();
		const deUint32	texelY	= rnd->getUint32() % imageSize.y();
		const float		x		= ((float)texelX + 0.5f) / (float)imageSize.x();
		const float		y		= ((float)texelY + 0.5f) / (float)imageSize.y();

		(*dst)[coordNdx] = Vec2(x, y);
	}
}

void checkImageUsageSupport (Context&			context,
							 VkFormat			format,
							 VkImageUsageFlags	usage)
{
	{
		const VkFormatProperties	formatProperties	= getPhysicalDeviceFormatProperties(context.getInstanceInterface(),
																							context.getPhysicalDevice(),
																							format);
		const VkFormatFeatureFlags	featureFlags		= formatProperties.optimalTilingFeatures;

		if ((usage & VK_IMAGE_USAGE_SAMPLED_BIT) != 0
			&& (featureFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) == 0)
		{
			TCU_THROW(NotSupportedError, "Format doesn't support sampling");
		}

		// Other image usages are not handled currently
		DE_ASSERT((usage & ~(VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT)) == 0);
	}
}

void checkSupport(Context& context, TestParameters params)
{
	const VkFormat					planeViewFormat	= getPlaneCompatibleFormat(params.format, params.planeNdx);
	const VkImageUsageFlags			usage			= VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;

	checkImageSupport(context, params.format, params.createFlags);
	checkImageUsageSupport(context, params.format, usage);
	checkImageUsageSupport(context, planeViewFormat, usage);
}

tcu::TestStatus testPlaneView (Context& context, TestParameters params)
{
	de::Random						randomGen		(deInt32Hash((deUint32)params.format)	^
													 deInt32Hash((deUint32)params.planeNdx)	^
													 deInt32Hash((deUint32)params.shaderType));

	const DeviceInterface&			vkd				= context.getDeviceInterface();
	const VkDevice					device			= context.getDevice();

	const VkFormat					format			= params.format;
	const VkImageCreateFlags		createFlags		= params.createFlags;
	const VkFormat					planeViewFormat	= getPlaneCompatibleFormat(format, params.planeNdx);
	const PlanarFormatDescription	formatInfo		= getPlanarFormatDescription(format);
	const UVec2						size			= params.size;
	const UVec2						planeSize		(size.x() / formatInfo.planes[params.planeNdx].widthDivisor,
													 size.y() / formatInfo.planes[params.planeNdx].heightDivisor);

	const Unique<VkImage>			image			(createTestImage(vkd, device, format, size, createFlags));
	const Unique<VkImage>			imageAlias		((params.viewType == TestParameters::VIEWTYPE_MEMORY_ALIAS)
													 ? createTestImage(vkd, device, planeViewFormat, planeSize, createFlags)
													 : Move<VkImage>());
	const vector<AllocationSp>		allocations		(allocateAndBindImageMemory(vkd, device, context.getDefaultAllocator(), *image, format, createFlags));

	if (imageAlias)
		VK_CHECK(vkd.bindImageMemory(device, *imageAlias, allocations[params.planeNdx]->getMemory(), allocations[params.planeNdx]->getOffset()));

	const VkSamplerYcbcrConversionCreateInfo	conversionInfo	=
	{
		VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
		DE_NULL,
		format,
		VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY,
		VK_SAMPLER_YCBCR_RANGE_ITU_FULL,
		{
			VK_COMPONENT_SWIZZLE_IDENTITY,
			VK_COMPONENT_SWIZZLE_IDENTITY,
			VK_COMPONENT_SWIZZLE_IDENTITY,
			VK_COMPONENT_SWIZZLE_IDENTITY,
		},
		VK_CHROMA_LOCATION_MIDPOINT,
		VK_CHROMA_LOCATION_MIDPOINT,
		VK_FILTER_NEAREST,
		VK_FALSE,									// forceExplicitReconstruction
	};
	const Unique<VkSamplerYcbcrConversion>		conversion	(createSamplerYcbcrConversion(vkd, device, &conversionInfo));
	const VkSamplerYcbcrConversionInfo			samplerConversionInfo	=
	{
		VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
		DE_NULL,
		*conversion,
	};
	const Unique<VkImageView>					wholeView	(createImageView(vkd, device, *image, format, VK_IMAGE_ASPECT_COLOR_BIT, &samplerConversionInfo));
	const Unique<VkImageView>					planeView	(createImageView(vkd,
																			 device,
																			 !imageAlias ? *image : *imageAlias,
																			 planeViewFormat,
																			 !imageAlias ? getPlaneAspect(params.planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT,
																			 DE_NULL));

	const VkSamplerCreateInfo					wholeSamplerInfo		=
	{
		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
		&samplerConversionInfo,
		0u,
		VK_FILTER_NEAREST,							// magFilter
		VK_FILTER_NEAREST,							// minFilter
		VK_SAMPLER_MIPMAP_MODE_NEAREST,				// mipmapMode
		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// addressModeU
		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// addressModeV
		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// addressModeW
		0.0f,										// mipLodBias
		VK_FALSE,									// anisotropyEnable
		1.0f,										// maxAnisotropy
		VK_FALSE,									// compareEnable
		VK_COMPARE_OP_ALWAYS,						// compareOp
		0.0f,										// minLod
		0.0f,										// maxLod
		VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,	// borderColor
		VK_FALSE,									// unnormalizedCoords
	};
	const VkSamplerCreateInfo					planeSamplerInfo		=
	{
		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
		DE_NULL,
		0u,
		VK_FILTER_NEAREST,							// magFilter
		VK_FILTER_NEAREST,							// minFilter
		VK_SAMPLER_MIPMAP_MODE_NEAREST,				// mipmapMode
		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// addressModeU
		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// addressModeV
		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// addressModeW
		0.0f,										// mipLodBias
		VK_FALSE,									// anisotropyEnable
		1.0f,										// maxAnisotropy
		VK_FALSE,									// compareEnable
		VK_COMPARE_OP_ALWAYS,						// compareOp
		0.0f,										// minLod
		0.0f,										// maxLod
		VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,	// borderColor
		VK_FALSE,									// unnormalizedCoords
	};

	const Unique<VkSampler>					wholeSampler(createSampler(vkd, device, &wholeSamplerInfo));
	const Unique<VkSampler>					planeSampler(createSampler(vkd, device, &planeSamplerInfo));

	const Unique<VkDescriptorSetLayout>		descLayout	(createDescriptorSetLayout(vkd, device, *wholeSampler));
	const Unique<VkDescriptorPool>			descPool	(createDescriptorPool(vkd, device));
	const Unique<VkDescriptorSet>			descSet		(createDescriptorSet(vkd, device, *descPool, *descLayout, *planeView, *planeSampler, *wholeView, *wholeSampler));

	MultiPlaneImageData						imageData	(format, size);

	// Prepare texture data
	fillRandom(&randomGen, &imageData);

	if (imageAlias)
	{
		// Transition alias to right layout first
		const VkImageMemoryBarrier		initAliasBarrier	=
		{
			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
			DE_NULL,
			(VkAccessFlags)0,
			VK_ACCESS_SHADER_READ_BIT,
			VK_IMAGE_LAYOUT_UNDEFINED,
			VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
			VK_QUEUE_FAMILY_IGNORED,
			VK_QUEUE_FAMILY_IGNORED,
			*imageAlias,
			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }
		};

		executeImageBarrier(vkd,
							device,
							context.getUniversalQueueFamilyIndex(),
							(VkPipelineStageFlags)VK_PIPELINE_STAGE_HOST_BIT,
							(VkPipelineStageFlags)VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
							initAliasBarrier);
	}

	// Upload and prepare image
	uploadImage(vkd,
				device,
				context.getUniversalQueueFamilyIndex(),
				context.getDefaultAllocator(),
				*image,
				imageData,
				(VkAccessFlags)VK_ACCESS_SHADER_READ_BIT,
				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);

	{
		const size_t	numValues		= 500;
		vector<Vec2>	texCoord		(numValues);
		vector<Vec4>	resultWhole		(numValues);
		vector<Vec4>	resultPlane		(numValues);
		vector<Vec4>	referenceWhole	(numValues);
		vector<Vec4>	referencePlane	(numValues);
		bool			allOk			= true;
		Vec4			threshold		(0.02f);

		generateLookupCoordinates(size, numValues, &randomGen, &texCoord);

		{
			UniquePtr<ShaderExecutor>	executor	(createExecutor(context, params.shaderType, getShaderSpec(params), *descLayout));
			const void*					inputs[]	= { texCoord[0].getPtr() };
			void*						outputs[]	= { resultWhole[0].getPtr(), resultPlane[0].getPtr() };

			executor->execute((int)numValues, inputs, outputs, *descSet);
		}

		// Whole image sampling reference
		for (deUint32 channelNdx = 0; channelNdx < 4; channelNdx++)
		{
			if (formatInfo.hasChannelNdx(channelNdx))
			{
				const tcu::ConstPixelBufferAccess	channelAccess	= imageData.getChannelAccess(channelNdx);
				const tcu::Sampler					refSampler		= mapVkSampler(wholeSamplerInfo);
				const tcu::Texture2DView			refTexView		(1u, &channelAccess);

				for (size_t ndx = 0; ndx < numValues; ++ndx)
				{
					const Vec2&	coord	= texCoord[ndx];
					referenceWhole[ndx][channelNdx] = refTexView.sample(refSampler, coord.x(), coord.y(), 0.0f)[0];
				}
			}
			else
			{
				for (size_t ndx = 0; ndx < numValues; ++ndx)
					referenceWhole[ndx][channelNdx] = channelNdx == 3 ? 1.0f : 0.0f;
			}
		}

		// Plane view sampling reference
		{
			const tcu::ConstPixelBufferAccess	planeAccess		(mapVkFormat(planeViewFormat),
																 tcu::IVec3((int)planeSize.x(), (int)planeSize.y(), 1),
																 imageData.getPlanePtr(params.planeNdx));
			const tcu::Sampler					refSampler		= mapVkSampler(planeSamplerInfo);
			const tcu::Texture2DView			refTexView		(1u, &planeAccess);

			for (size_t ndx = 0; ndx < numValues; ++ndx)
			{
				const Vec2&	coord	= texCoord[ndx];
				referencePlane[ndx] = refTexView.sample(refSampler, coord.x(), coord.y(), 0.0f);
			}
		}

		for (int viewNdx = 0; viewNdx < 2; ++viewNdx)
		{
			const char* const	viewName	= (viewNdx == 0) ? "complete image"	: "plane view";
			const vector<Vec4>&	reference	= (viewNdx == 0) ? referenceWhole	: referencePlane;
			const vector<Vec4>&	result		= (viewNdx == 0) ? resultWhole		: resultPlane;

			for (size_t ndx = 0; ndx < numValues; ++ndx)
			{
				if (boolAny(greaterThanEqual(abs(result[ndx] - reference[ndx]), threshold)))
				{
					context.getTestContext().getLog()
						<< TestLog::Message << "ERROR: When sampling " << viewName << " at " << texCoord[ndx]
											<< ": got " << result[ndx]
											<< ", expected " << reference[ndx]
						<< TestLog::EndMessage;
					allOk = false;
				}
			}
		}

		if (allOk)
			return tcu::TestStatus::pass("All samples passed");
		else
			return tcu::TestStatus::fail("Got invalid results");
	}
}

void initPrograms (SourceCollections& dst, TestParameters params)
{
	const ShaderSpec	spec	= getShaderSpec(params);

	generateSources(params.shaderType, spec, dst);
}

void addPlaneViewCase (tcu::TestCaseGroup* group, const TestParameters& params)
{
	std::ostringstream name;

	name << de::toLower(de::toString(params.format).substr(10));

	if ((params.viewType != TestParameters::VIEWTYPE_MEMORY_ALIAS) &&
		((params.createFlags & VK_IMAGE_CREATE_DISJOINT_BIT) != 0))
		name << "_disjoint";

	name << "_plane_" << params.planeNdx;

	addFunctionCaseWithPrograms(group, name.str(), "", checkSupport, initPrograms, testPlaneView, params);
}

void populateViewTypeGroup (tcu::TestCaseGroup* group, TestParameters::ViewType viewType)
{
	const glu::ShaderType		shaderType	= glu::SHADERTYPE_FRAGMENT;
	const UVec2					size		(32, 58);
	const VkImageCreateFlags	baseFlags	= (VkImageCreateFlags)VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
											| (viewType == TestParameters::VIEWTYPE_MEMORY_ALIAS ? (VkImageCreateFlags)VK_IMAGE_CREATE_ALIAS_BIT : 0u);

	for (int formatNdx = VK_YCBCR_FORMAT_FIRST; formatNdx < VK_YCBCR_FORMAT_LAST; formatNdx++)
	{
		const VkFormat	format		= (VkFormat)formatNdx;
		const deUint32	numPlanes	= getPlaneCount(format);

		if (numPlanes == 1)
			continue; // Plane views not possible

		for (int isDisjoint = 0; isDisjoint < 2; ++isDisjoint)
		{
			const VkImageCreateFlags	flags	= baseFlags | (isDisjoint == 1 ? (VkImageCreateFlags)VK_IMAGE_CREATE_DISJOINT_BIT : 0u);

			if ((viewType == TestParameters::VIEWTYPE_MEMORY_ALIAS) &&
				((flags & VK_IMAGE_CREATE_DISJOINT_BIT) == 0))
				continue; // Memory alias cases require disjoint planes

			for (deUint32 planeNdx = 0; planeNdx < numPlanes; ++planeNdx)
				addPlaneViewCase(group, TestParameters(viewType, format, size, flags, planeNdx, shaderType));
		}
	}
}

void populateViewGroup (tcu::TestCaseGroup* group)
{
	addTestGroup(group, "image_view",	"Plane View via VkImageView",		populateViewTypeGroup,	TestParameters::VIEWTYPE_IMAGE_VIEW);
	addTestGroup(group, "memory_alias",	"Plane View via Memory Aliasing",	populateViewTypeGroup,	TestParameters::VIEWTYPE_MEMORY_ALIAS);
}

} // anonymous

tcu::TestCaseGroup* createViewTests (tcu::TestContext& testCtx)
{
	// \todo [2017-05-24 pyry] Extend with memory alias views
	return createTestGroup(testCtx, "plane_view", "YCbCr Plane View Tests", populateViewGroup);
}

} // ycbcr
} // vkt

