/*-------------------------------------------------------------------------
 * 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;

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	(formatDesc.blockWidth, formatDesc.blockHeight);

	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
