/*-------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2019 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 OpImageQuery & YCbCr Tests
 *//*--------------------------------------------------------------------*/

#include "vktYCbCrImageQueryTests.hpp"
#include "vktTestCaseUtil.hpp"
#include "vktTestGroupUtil.hpp"
#include "vktShaderExecutor.hpp"
#include "vktYCbCrUtil.hpp"
#include "vktDrawUtil.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 "vkBarrierUtil.hpp"

#include "tcuTestLog.hpp"
#include "tcuVectorUtil.hpp"
#include "tcuTexLookupVerifier.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;

enum QueryType
{
	QUERY_TYPE_IMAGE_SIZE_LOD,			// OpImageQuerySizeLod
	QUERY_TYPE_IMAGE_LOD,				// OpImageQueryLod
	QUERY_TYPE_IMAGE_LEVELS,			// OpImageQueryLevels

	QUERY_TYPE_LAST
};

struct TestParameters
{
	QueryType			query;
	VkFormat			format;
	VkImageCreateFlags	flags;
	glu::ShaderType		shaderType;

	TestParameters (QueryType query_, VkFormat format_, VkImageCreateFlags flags_, glu::ShaderType shaderType_)
		: query		(query_)
		, format	(format_)
		, flags		(flags_)
		, shaderType(shaderType_)
	{
	}

	TestParameters (void)
		: query		(QUERY_TYPE_LAST)
		, format	(VK_FORMAT_UNDEFINED)
		, flags		(0u)
		, shaderType(glu::SHADERTYPE_LAST)
	{
	}
};

ShaderSpec getShaderSpec (const TestParameters& params)
{
	ShaderSpec		spec;
	const char*		expr		= DE_NULL;
	glu::DataType	resultType	= glu::TYPE_LAST;

	switch (params.query)
	{
		case QUERY_TYPE_IMAGE_SIZE_LOD:
			expr		= "textureSize(u_image, lod)";
			resultType	= glu::TYPE_INT_VEC2;
			break;

		case QUERY_TYPE_IMAGE_LEVELS:
			expr		= "textureQueryLevels(u_image)";
			resultType	= glu::TYPE_INT;
			break;

		default:
			DE_FATAL("Unknown query");
	}

	spec.glslVersion = glu::GLSL_VERSION_450;

	spec.inputs.push_back(Symbol("lod", glu::VarType(glu::TYPE_INT, glu::PRECISION_HIGHP)));
	spec.outputs.push_back(Symbol("result", glu::VarType(resultType, glu::PRECISION_HIGHP)));

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

	spec.source =
		string("result = ") + expr + ";\n";

	return spec;
}

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_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_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,
								   VkSamplerYcbcrConversion	conversion)
{
	const VkSamplerYcbcrConversionInfo				samplerConversionInfo	=
	{
		VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
		DE_NULL,
		conversion
	};

	const VkImageViewCreateInfo	viewInfo	=
	{
		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
		(conversion != DE_NULL) ? &samplerConversionInfo : DE_NULL,
		(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,
		},
		{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },
	};

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

class TestImage
{
public:
								TestImage		(const Context&				context,
												 const DeviceInterface&		vkd,
												 VkDevice					device,
												 Allocator&					allocator,
												 VkFormat					format,
												 const UVec2&				size,
												 const VkImageCreateFlags	createFlags,
												 VkSamplerYcbcrConversion	conversion);

	const UVec2&				getSize			(void) const { return m_size;		}
	VkImageView					getImageView	(void) const { return *m_imageView; }

private:
	const UVec2					m_size;
	const Unique<VkImage>		m_image;
	const vector<AllocationSp>	m_allocations;
	const Unique<VkImageView>	m_imageView;
};

TestImage::TestImage (const Context&			context,
					  const DeviceInterface&	vkd,
					  VkDevice					device,
					  Allocator&				allocator,
					  VkFormat					format,
					  const UVec2&				size,
					  const VkImageCreateFlags	createFlags,
					  VkSamplerYcbcrConversion	conversion)
	: m_size		(size)
	, m_image		(createTestImage(vkd, device, format, size, createFlags))
	, m_allocations	(allocateAndBindImageMemory(vkd, device, allocator, *m_image, format, createFlags))
	, m_imageView	(createImageView(vkd, device, *m_image, format, conversion))
{
	// Transition image layout
	{
		Move<VkCommandPool>		cmdPool;
		Move<VkCommandBuffer>	cmdBuffer;
		const VkQueue			queue				= context.getUniversalQueue();
		const deUint32			queueFamilyIndex	= context.getUniversalQueueFamilyIndex();

		cmdPool		= createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
		cmdBuffer	= allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

		beginCommandBuffer(vkd, *cmdBuffer);

		VkImageSubresourceRange subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u };
		const VkImageMemoryBarrier imageBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, *m_image, subresourceRange);

		vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
			0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);

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

typedef de::SharedPtr<TestImage> TestImageSp;

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

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

Move<VkDescriptorPool> createDescriptorPool (const DeviceInterface& vkd, VkDevice device)
{
	const VkDescriptorPoolSize			poolSizes[]	=
	{
		{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,	1u	},
	};
	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)
{
	const VkDescriptorSetAllocateInfo	allocInfo	=
	{
		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
		DE_NULL,
		descPool,
		1u,
		&descLayout,
	};

	return allocateDescriptorSet(vkd, device, &allocInfo);
}

void bindImage (const DeviceInterface& vkd,
				VkDevice device,
				VkDescriptorSet descriptorSet,
				VkImageView imageView,
				VkSampler sampler)
{
	const VkDescriptorImageInfo		imageInfo			=
	{
		sampler,
		imageView,
		VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
	};
	const VkWriteDescriptorSet		descriptorWrite		=
	{
		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
		DE_NULL,
		descriptorSet,
		0u,		// dstBinding
		0u,		// dstArrayElement
		1u,		// descriptorCount
		VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
		&imageInfo,
		(const VkDescriptorBufferInfo*)DE_NULL,
		(const VkBufferView*)DE_NULL,
	};

	vkd.updateDescriptorSets(device, 1u, &descriptorWrite, 0u, DE_NULL);
}

UVec2 getMaxPlaneDivisor (const PlanarFormatDescription& formatDesc)
{
	UVec2	maxDivisor	(1u, 1u);

	for (deUint32 ndx = 0; ndx < formatDesc.numPlanes; ++ndx)
	{
		maxDivisor.x() = de::max<deUint32>(maxDivisor.x(), formatDesc.planes[ndx].widthDivisor);
		maxDivisor.y() = de::max<deUint32>(maxDivisor.y(), formatDesc.planes[ndx].heightDivisor);
	}

	return maxDivisor;
}

tcu::TestStatus testImageQuery (Context& context, TestParameters params)
{
	const bool							isYCbCrImage	= isYCbCrFormat(params.format);
	const DeviceInterface&				vkd				= context.getDeviceInterface();
	const VkDevice						device			= context.getDevice();

	const VkSamplerYcbcrConversionCreateInfo		conversionInfo			=
	{
		VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
		DE_NULL,
		params.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				(isYCbCrImage
																			 ? createSamplerYcbcrConversion(vkd, device, &conversionInfo)
																			 : Move<VkSamplerYcbcrConversion>());

	const VkSamplerYcbcrConversionInfo				samplerConversionInfo	=
	{
		VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
		DE_NULL,
		*conversion,
	};

	const VkSamplerCreateInfo						samplerInfo				=
	{
		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
		isYCbCrImage ? &samplerConversionInfo : 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>				sampler		(createSampler(vkd, device, &samplerInfo));
	const Unique<VkDescriptorSetLayout>	descLayout	(createDescriptorSetLayout(vkd, device, *sampler));
	const Unique<VkDescriptorPool>		descPool	(createDescriptorPool(vkd, device));
	const Unique<VkDescriptorSet>		descSet		(createDescriptorSet(vkd, device, *descPool, *descLayout));

	vector<TestImageSp>					testImages;

	if (params.query == QUERY_TYPE_IMAGE_SIZE_LOD)
	{
		const PlanarFormatDescription&	formatDesc	= getPlanarFormatDescription(params.format);
		const UVec2						maxDivisor	= getMaxPlaneDivisor(formatDesc);
		vector<UVec2>					testSizes;

		testSizes.push_back(maxDivisor);
		testSizes.push_back(maxDivisor * UVec2(2u, 1u));
		testSizes.push_back(maxDivisor * UVec2(1u, 2u));
		testSizes.push_back(maxDivisor * UVec2(63u, 79u));
		testSizes.push_back(maxDivisor * UVec2(99u, 1u));
		testSizes.push_back(maxDivisor * UVec2(421u, 1117u));

		testImages.resize(testSizes.size());

		for (size_t ndx = 0; ndx < testSizes.size(); ++ndx)
			testImages[ndx] = TestImageSp(new TestImage(context, vkd, device, context.getDefaultAllocator(), params.format, testSizes[ndx], params.flags, *conversion));
	}
	else
		testImages.push_back(TestImageSp(new TestImage(context, vkd, device, context.getDefaultAllocator(), params.format, UVec2(16, 18), params.flags, *conversion)));

	{
		UniquePtr<ShaderExecutor>	executor	(createExecutor(context, params.shaderType, getShaderSpec(params), *descLayout));
		bool						allOk		= true;

		for (size_t imageNdx = 0; imageNdx < testImages.size(); ++imageNdx)
		{
			const deUint32	lod			= 0u;
			UVec2			result		(~0u, ~0u);
			const void*		inputs[]	= { &lod };
			void*			outputs[]	= { result.getPtr() };

			bindImage(vkd, device, *descSet, testImages[imageNdx]->getImageView(), *sampler);

			executor->execute(1, inputs, outputs, *descSet);

			switch (params.query)
			{
				case QUERY_TYPE_IMAGE_SIZE_LOD:
				{
					const UVec2	reference	= testImages[imageNdx]->getSize();

					if (result != reference)
					{
						context.getTestContext().getLog()
							<< TestLog::Message << "ERROR: Image " << imageNdx
												<< ": got " << result
												<< ", expected " << reference
							<< TestLog::EndMessage;
						allOk = false;
					}
					break;
				}

				case QUERY_TYPE_IMAGE_LEVELS:
				{
					if (result.x() != 1u)
					{
						context.getTestContext().getLog()
							<< TestLog::Message << "ERROR: Image " << imageNdx
												<< ": got " << result.x()
												<< ", expected " << 1
							<< TestLog::EndMessage;
						allOk = false;
					}
					break;
				}

				default:
					DE_FATAL("Invalid query type");
			}
		}

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

void checkSupport (Context& context, TestParameters params)
{
	const bool isYCbCrImage = isYCbCrFormat(params.format);

	if (isYCbCrImage)
		checkImageSupport(context, params.format, params.flags);
}

tcu::TestStatus testImageQueryLod (Context& context, TestParameters params)
{
	const bool							isYCbCrImage	= isYCbCrFormat(params.format);
	const DeviceInterface&				vkd				= context.getDeviceInterface();
	const VkDevice						device			= context.getDevice();

	const VkSamplerYcbcrConversionCreateInfo			conversionInfo			=
	{
		VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
		DE_NULL,
		params.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				(isYCbCrImage
																				 ? createSamplerYcbcrConversion(vkd, device, &conversionInfo)
																				 : Move<VkSamplerYcbcrConversion>());

	const VkSamplerYcbcrConversionInfo				samplerConversionInfo	=
	{
		VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
		DE_NULL,
		*conversion,
	};

	const VkSamplerCreateInfo						samplerInfo				=
	{
		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
		isYCbCrImage ? &samplerConversionInfo : 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>				sampler		(createSampler(vkd, device, &samplerInfo));
	const Unique<VkDescriptorSetLayout>	descLayout	(createDescriptorSetLayout(vkd, device, *sampler));
	const Unique<VkDescriptorPool>		descPool	(createDescriptorPool(vkd, device));
	const Unique<VkDescriptorSet>		descSet		(createDescriptorSet(vkd, device, *descPool, *descLayout));

	vector<TestImageSp>					testImages;

	DE_ASSERT(params.query == QUERY_TYPE_IMAGE_LOD);
	DE_ASSERT(params.shaderType == glu::SHADERTYPE_FRAGMENT);

	{
		const PlanarFormatDescription&		formatDesc	= getPlanarFormatDescription(params.format);
		const UVec2							maxDivisor	= getMaxPlaneDivisor(formatDesc);
		vector<UVec2>						testSizes;

		testSizes.push_back(maxDivisor);
		testSizes.push_back(maxDivisor * UVec2(2u, 1u));
		testSizes.push_back(maxDivisor * UVec2(1u, 2u));
		testSizes.push_back(maxDivisor * UVec2(4u, 123u));
		testSizes.push_back(maxDivisor * UVec2(312u, 13u));
		testSizes.push_back(maxDivisor * UVec2(841u, 917u));

		testImages.resize(testSizes.size());

		for (size_t ndx = 0; ndx < testSizes.size(); ++ndx)
			testImages[ndx] = TestImageSp(new TestImage(context, vkd, device, context.getDefaultAllocator(), params.format, testSizes[ndx], params.flags, *conversion));
	}

	{
		using namespace drawutil;

		struct LocalUtil
		{
			static DrawState getDrawState (UVec2 renderSize, const int subpixelBits)
			{
				DrawState state(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, renderSize.x(), renderSize.y(), subpixelBits);
				state.colorFormat = VK_FORMAT_R32G32_SFLOAT;
				return state;
			}

			static vector<Vec4> getVertices (void)
			{
				vector<Vec4> vertices;

				vertices.push_back(Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
				vertices.push_back(Vec4(+1.0f, -1.0f, 0.0f, 1.0f));
				vertices.push_back(Vec4(-1.0f, +1.0f, 0.0f, 1.0f));

				vertices.push_back(Vec4(+1.0f, -1.0f, 0.0f, 1.0f));
				vertices.push_back(Vec4(-1.0f, +1.0f, 0.0f, 1.0f));
				vertices.push_back(Vec4(+1.0f, +1.0f, 0.0f, 1.0f));

				return vertices;
			}

			static VulkanProgram getProgram (Context& ctx, VkDescriptorSetLayout descriptorLayout, VkDescriptorSet descriptorSet)
			{
				VulkanProgram	prog;

				prog.shaders.push_back(VulkanShader(VK_SHADER_STAGE_VERTEX_BIT,		ctx.getBinaryCollection().get("vert")));
				prog.shaders.push_back(VulkanShader(VK_SHADER_STAGE_FRAGMENT_BIT,	ctx.getBinaryCollection().get("frag")));

				prog.descriptorSet			= descriptorSet;
				prog.descriptorSetLayout	= descriptorLayout;

				return prog;
			}
		};

		const UVec2					renderSize	(128, 256);
		const vector<Vec4>			vertices	(LocalUtil::getVertices());
		const DrawState				drawState	(LocalUtil::getDrawState(renderSize, context.getDeviceProperties().limits.subPixelPrecisionBits));
		const DrawCallData			drawCallData(vertices);
		const VulkanProgram			program		(LocalUtil::getProgram(context, *descLayout, *descSet));

		bool						allOk		= true;

		context.getTestContext().getLog()
			<< TestLog::Message << "Rendering " << renderSize << " quad" << TestLog::EndMessage;

		for (size_t imageNdx = 0; imageNdx < testImages.size(); ++imageNdx)
		{
			context.getTestContext().getLog()
				<< TestLog::Message << "Testing image size " << testImages[imageNdx]->getSize() << TestLog::EndMessage;

			bindImage(vkd, device, *descSet, testImages[imageNdx]->getImageView(), *sampler);

			VulkanDrawContext	renderer	(context, drawState, drawCallData, program);
			renderer.draw();

			{
				// Only du/dx and dv/dy are non-zero
				const Vec2					dtdp		= testImages[imageNdx]->getSize().cast<float>() / renderSize.cast<float>();
				const tcu::LodPrecision		lodPrec		(16, 4); // Pretty lax since we are not verifying LOD precision
				const Vec2					lodBounds	(tcu::computeLodBoundsFromDerivates(dtdp.x(), 0.0f, 0.0f, dtdp.y(), lodPrec));
				tcu::ConstPixelBufferAccess	resultImg	(renderer.getColorPixels());
				const int					maxErrors	= 5;
				int							numErrors	= 0;

				for (int y = 0; y < resultImg.getHeight(); ++y)
				for (int x = 0; x < resultImg.getWidth(); ++x)
				{
					const Vec2	result		= resultImg.getPixel(x, y).swizzle(0,1);
					const bool	levelOk		= result.x() == 0.0f;
					const bool	lodOk		= de::inRange(result.y(), lodBounds.x(), lodBounds.y());

					if (!levelOk || !lodOk)
					{
						if (numErrors < maxErrors)
						{
							context.getTestContext().getLog()
								<< TestLog::Message << "ERROR: At (" << x << ", " << y << ")"
													<< ": got " << result
													<< ", expected (0, [" << lodBounds.x() << ", " << lodBounds.y() << "])"
								<< TestLog::EndMessage;
						}
						else if (numErrors == maxErrors)
							context.getTestContext().getLog() << TestLog::Message << "..." << TestLog::EndMessage;

						numErrors += 1;
					}
				}

				allOk = allOk && (numErrors  == 0);
			}
		}

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

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

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

void initImageQueryLodPrograms (SourceCollections& dst, TestParameters)
{
	dst.glslSources.add("vert")
		<< glu::VertexSource("#version 450\n"
							 "layout(location = 0) in highp vec4 a_position;\n"
							 "layout(location = 0) out highp vec2 v_texCoord;\n"
							 "\n"
							 "void main (void)\n"
							 "{\n"
							 "	gl_Position = a_position;\n"
							 "	v_texCoord = a_position.xy * 0.5 - 0.5;\n"
							 "}\n");
	dst.glslSources.add("frag")
		<< glu::FragmentSource("#version 450\n"
							   "layout(binding = 0, set = 0) uniform highp sampler2D u_image;\n"
							   "layout(location = 0) in highp vec2 v_texCoord;\n"
							   "layout(location = 0) out highp vec2 o_lod;\n"
							   "\n"
							   "void main (void)\n"
							   "{\n"
							   "	o_lod = textureQueryLod(u_image, v_texCoord);\n"
							   "}\n");
}

void addImageQueryCase (tcu::TestCaseGroup* group, const TestParameters& params)
{
	std::string	name	= de::toLower(de::toString(params.format).substr(10));
	const bool	isLod	= params.query == QUERY_TYPE_IMAGE_LOD;

	if ((params.flags & VK_IMAGE_CREATE_DISJOINT_BIT) != 0)
		name += "_disjoint";

	addFunctionCaseWithPrograms(group,
								name,
								"",
								checkSupport,
								isLod ? initImageQueryLodPrograms : initImageQueryPrograms,
								isLod ? testImageQueryLod : testImageQuery,
								params);
}

struct QueryGroupParams
{
	QueryType		query;
	glu::ShaderType	shaderType;

	QueryGroupParams (QueryType query_, glu::ShaderType shaderType_)
		: query		(query_)
		, shaderType(shaderType_)
	{}

	QueryGroupParams (void)
		: query		(QUERY_TYPE_LAST)
		, shaderType(glu::SHADERTYPE_LAST)
	{}
};

void populateQueryInShaderGroup (tcu::TestCaseGroup* group, QueryGroupParams params)
{
	// "Reference" formats for testing
	addImageQueryCase(group, TestParameters(params.query, VK_FORMAT_R8G8B8A8_UNORM, 0u, params.shaderType));

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

		addImageQueryCase(group, TestParameters(params.query, format, 0u, params.shaderType));

		if (getPlaneCount(format) > 1)
			addImageQueryCase(group, TestParameters(params.query, format, (VkImageCreateFlags)VK_IMAGE_CREATE_DISJOINT_BIT, params.shaderType));
	}
}

void populateQueryGroup (tcu::TestCaseGroup* group, QueryType query)
{
	for (int shaderTypeNdx = 0; shaderTypeNdx < glu::SHADERTYPE_LAST; ++shaderTypeNdx)
	{
		const glu::ShaderType	shaderType	= (glu::ShaderType)shaderTypeNdx;

		if (query == QUERY_TYPE_IMAGE_LOD && shaderType != glu::SHADERTYPE_FRAGMENT)
			continue;

		if (!executorSupported(shaderType))
			continue;

		addTestGroup(group, glu::getShaderTypeName(shaderType), "", populateQueryInShaderGroup, QueryGroupParams(query, shaderType));
	}
}

void populateImageQueryGroup (tcu::TestCaseGroup* group)
{
	addTestGroup(group, "size_lod",	"OpImageQuerySizeLod",	populateQueryGroup, QUERY_TYPE_IMAGE_SIZE_LOD);
	addTestGroup(group, "lod",		"OpImageQueryLod",		populateQueryGroup, QUERY_TYPE_IMAGE_LOD);
	addTestGroup(group, "levels",	"OpImageQueryLevels",	populateQueryGroup, QUERY_TYPE_IMAGE_LEVELS);
}

} // namespace

tcu::TestCaseGroup* createImageQueryTests (tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "query", "Image Query Tests", populateImageQueryGroup);
}

} // ycbcr
} // vkt
