/*-------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2015 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 Api Feature Query tests
 *//*--------------------------------------------------------------------*/

#include "vktApiFeatureInfo.hpp"

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

#include "vkPlatform.hpp"
#include "vkStrUtil.hpp"
#include "vkRef.hpp"
#include "vkRefUtil.hpp"
#include "vkDeviceUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkApiVersion.hpp"

#include "tcuTestLog.hpp"
#include "tcuFormatUtil.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuResultCollector.hpp"
#include "tcuCommandLine.hpp"

#include "deUniquePtr.hpp"
#include "deString.h"
#include "deStringUtil.hpp"
#include "deSTLUtil.hpp"
#include "deMemory.h"
#include "deMath.h"

#include <vector>
#include <set>
#include <string>

namespace vkt
{
namespace api
{
namespace
{

#include "vkApiExtensionDependencyInfo.inl"

using namespace vk;
using std::vector;
using std::set;
using std::string;
using tcu::TestLog;
using tcu::ScopedLogSection;

enum
{
	GUARD_SIZE								= 0x20,			//!< Number of bytes to check
	GUARD_VALUE								= 0xcd,			//!< Data pattern
};

static const VkDeviceSize MINIMUM_REQUIRED_IMAGE_RESOURCE_SIZE =	(1LLU<<31);	//!< Minimum value for VkImageFormatProperties::maxResourceSize (2GiB)

enum LimitFormat
{
	LIMIT_FORMAT_SIGNED_INT,
	LIMIT_FORMAT_UNSIGNED_INT,
	LIMIT_FORMAT_FLOAT,
	LIMIT_FORMAT_DEVICE_SIZE,
	LIMIT_FORMAT_BITMASK,

	LIMIT_FORMAT_LAST
};

enum LimitType
{
	LIMIT_TYPE_MIN,
	LIMIT_TYPE_MAX,
	LIMIT_TYPE_NONE,

	LIMIT_TYPE_LAST
};

#define LIMIT(_X_)		DE_OFFSET_OF(VkPhysicalDeviceLimits, _X_), (const char*)(#_X_)
#define FEATURE(_X_)	DE_OFFSET_OF(VkPhysicalDeviceFeatures, _X_)

bool validateFeatureLimits(VkPhysicalDeviceProperties* properties, VkPhysicalDeviceFeatures* features, TestLog& log)
{
	bool						limitsOk				= true;
	VkPhysicalDeviceLimits*		limits					= &properties->limits;
	deUint32					shaderStages			= 3;
	deUint32					maxPerStageResourcesMin	= deMin32(128,	limits->maxPerStageDescriptorUniformBuffers		+
																		limits->maxPerStageDescriptorStorageBuffers		+
																		limits->maxPerStageDescriptorSampledImages		+
																		limits->maxPerStageDescriptorStorageImages		+
																		limits->maxPerStageDescriptorInputAttachments	+
																		limits->maxColorAttachments);

	if (features->tessellationShader)
	{
		shaderStages += 2;
	}

	if (features->geometryShader)
	{
		shaderStages++;
	}

	struct FeatureLimitTable
	{
		deUint32		offset;
		const char*		name;
		deUint32		uintVal;			//!< Format is UNSIGNED_INT
		deInt32			intVal;				//!< Format is SIGNED_INT
		deUint64		deviceSizeVal;		//!< Format is DEVICE_SIZE
		float			floatVal;			//!< Format is FLOAT
		LimitFormat		format;
		LimitType		type;
		deInt32			unsuppTableNdx;
	} featureLimitTable[] =   //!< Based on 1.0.28 Vulkan spec
	{
		{ LIMIT(maxImageDimension1D),								4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(maxImageDimension2D),								4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
		{ LIMIT(maxImageDimension3D),								256, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxImageDimensionCube),								4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
		{ LIMIT(maxImageArrayLayers),								256, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN   , -1 },
		{ LIMIT(maxTexelBufferElements),							65536, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxUniformBufferRange),								16384, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxStorageBufferRange),								134217728, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(maxPushConstantsSize),								128, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxMemoryAllocationCount),							4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
		{ LIMIT(maxSamplerAllocationCount),							4000, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
		{ LIMIT(bufferImageGranularity),							0, 0, 1, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(bufferImageGranularity),							0, 0, 131072, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MAX, -1 },
		{ LIMIT(sparseAddressSpaceSize),							0, 0, 2UL*1024*1024*1024, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(maxBoundDescriptorSets),							4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(maxPerStageDescriptorSamplers),						16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(maxPerStageDescriptorUniformBuffers),				12, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
		{ LIMIT(maxPerStageDescriptorStorageBuffers),				4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
		{ LIMIT(maxPerStageDescriptorSampledImages),				16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
		{ LIMIT(maxPerStageDescriptorStorageImages),				4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
		{ LIMIT(maxPerStageDescriptorInputAttachments),				4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
		{ LIMIT(maxPerStageResources),								maxPerStageResourcesMin, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
		{ LIMIT(maxDescriptorSetSamplers),							shaderStages * 16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(maxDescriptorSetUniformBuffers),					shaderStages * 12, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(maxDescriptorSetUniformBuffersDynamic),				8, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(maxDescriptorSetStorageBuffers),					shaderStages * 4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(maxDescriptorSetStorageBuffersDynamic),				4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxDescriptorSetSampledImages),						shaderStages * 16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(maxDescriptorSetStorageImages),						shaderStages * 4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(maxDescriptorSetInputAttachments),					4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxVertexInputAttributes),							16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxVertexInputBindings),							16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxVertexInputAttributeOffset),						2047, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxVertexInputBindingStride),						2048, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxVertexOutputComponents),							64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxTessellationGenerationLevel),					64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxTessellationPatchSize),							32, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
		{ LIMIT(maxTessellationControlPerVertexInputComponents),	64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxTessellationControlPerVertexOutputComponents),	64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxTessellationControlPerPatchOutputComponents),	120, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxTessellationControlTotalOutputComponents),		2048, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxTessellationEvaluationInputComponents),			64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxTessellationEvaluationOutputComponents),			64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxGeometryShaderInvocations),						32, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxGeometryInputComponents),						64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxGeometryOutputComponents),						64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxGeometryOutputVertices),							256, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxGeometryTotalOutputComponents),					1024, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxFragmentInputComponents),						64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxFragmentOutputAttachments),						4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxFragmentDualSrcAttachments),						1, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxFragmentCombinedOutputResources),				4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
		{ LIMIT(maxComputeSharedMemorySize),						16384, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN   , -1 },
		{ LIMIT(maxComputeWorkGroupCount[0]),						65535, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN   , -1 },
		{ LIMIT(maxComputeWorkGroupCount[1]),						65535, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN   , -1 },
		{ LIMIT(maxComputeWorkGroupCount[2]),						65535,  0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN   , -1 },
		{ LIMIT(maxComputeWorkGroupInvocations),					128, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN    , -1 },
		{ LIMIT(maxComputeWorkGroupSize[0]),						128, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN    , -1 },
		{ LIMIT(maxComputeWorkGroupSize[1]),						128, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN    , -1 },
		{ LIMIT(maxComputeWorkGroupSize[2]),						64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN    , -1 },
		{ LIMIT(subPixelPrecisionBits),								4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN    , -1 },
		{ LIMIT(subTexelPrecisionBits),								4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN    , -1 },
		{ LIMIT(mipmapPrecisionBits),								4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN    , -1 },
		{ LIMIT(maxDrawIndexedIndexValue),							(deUint32)~0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(maxDrawIndirectCount),								65535, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN    , -1 },
		{ LIMIT(maxSamplerLodBias),									0, 0, 0, 2.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(maxSamplerAnisotropy),								0, 0, 0, 16.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(maxViewports),										16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(maxViewportDimensions[0]),							4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
		{ LIMIT(maxViewportDimensions[1]),							4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
		{ LIMIT(viewportBoundsRange[0]),							0, 0, 0, -8192.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 },
		{ LIMIT(viewportBoundsRange[1]),							0, 0, 0, 8191.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(viewportSubPixelBits),								0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(minMemoryMapAlignment),								64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(minTexelBufferOffsetAlignment),						0, 0, 1, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(minTexelBufferOffsetAlignment),						0, 0, 256, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MAX, -1 },
		{ LIMIT(minUniformBufferOffsetAlignment),					0, 0, 1, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(minUniformBufferOffsetAlignment),					0, 0, 256, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MAX, -1 },
		{ LIMIT(minStorageBufferOffsetAlignment),					0, 0, 1, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(minStorageBufferOffsetAlignment),					0, 0, 256, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MAX, -1 },
		{ LIMIT(minTexelOffset),									0, -8, 0, 0.0f, LIMIT_FORMAT_SIGNED_INT, LIMIT_TYPE_MAX, -1 },
		{ LIMIT(maxTexelOffset),									7, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(minTexelGatherOffset),								0, -8, 0, 0.0f, LIMIT_FORMAT_SIGNED_INT, LIMIT_TYPE_MAX, -1 },
		{ LIMIT(maxTexelGatherOffset),								7, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(minInterpolationOffset),							0, 0, 0, -0.5f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 },
		{ LIMIT(maxInterpolationOffset),							0, 0, 0, 0.5f - (1.0f/deFloatPow(2.0f, (float)limits->subPixelInterpolationOffsetBits)), LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(subPixelInterpolationOffsetBits),					4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(maxFramebufferWidth),								4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(maxFramebufferHeight),								4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(maxFramebufferLayers),								0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(framebufferColorSampleCounts),						VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(framebufferDepthSampleCounts),						VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(framebufferStencilSampleCounts),					VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(framebufferNoAttachmentsSampleCounts),				VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(maxColorAttachments),								4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(sampledImageColorSampleCounts),						VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(sampledImageIntegerSampleCounts),					VK_SAMPLE_COUNT_1_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(sampledImageDepthSampleCounts),						VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(sampledImageStencilSampleCounts),					VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(storageImageSampleCounts),							VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(maxSampleMaskWords),								1, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(timestampComputeAndGraphics),						0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_NONE, -1 },
		{ LIMIT(timestampPeriod),									0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_NONE, -1 },
		{ LIMIT(maxClipDistances),									8, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(maxCullDistances),									8, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(maxCombinedClipAndCullDistances),					8, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(discreteQueuePriorities),							2, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(pointSizeRange[0]),									0, 0, 0, 0.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(pointSizeRange[0]),									0, 0, 0, 1.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 },
		{ LIMIT(pointSizeRange[1]),									0, 0, 0, 64.0f - limits->pointSizeGranularity , LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(lineWidthRange[0]),									0, 0, 0, 0.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(lineWidthRange[0]),									0, 0, 0, 1.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 },
		{ LIMIT(lineWidthRange[1]),									0, 0, 0, 8.0f - limits->lineWidthGranularity, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(pointSizeGranularity),								0, 0, 0, 1.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 },
		{ LIMIT(lineWidthGranularity),								0, 0, 0, 1.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 },
		{ LIMIT(strictLines),										0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_NONE, -1 },
		{ LIMIT(standardSampleLocations),							0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_NONE, -1 },
		{ LIMIT(optimalBufferCopyOffsetAlignment),					0, 0, 0, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_NONE, -1 },
		{ LIMIT(optimalBufferCopyRowPitchAlignment),				0, 0, 0, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_NONE, -1 },
		{ LIMIT(nonCoherentAtomSize),								0, 0, 1, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1 },
		{ LIMIT(nonCoherentAtomSize),								0, 0, 256, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MAX, -1 },
	};

	const struct UnsupportedFeatureLimitTable
	{
		deUint32		limitOffset;
		const char*		name;
		deUint32		featureOffset;
		deUint32		uintVal;			//!< Format is UNSIGNED_INT
		deInt32			intVal;				//!< Format is SIGNED_INT
		deUint64		deviceSizeVal;		//!< Format is DEVICE_SIZE
		float			floatVal;			//!< Format is FLOAT
	} unsupportedFeatureTable[] =
	{
		{ LIMIT(sparseAddressSpaceSize),							FEATURE(sparseBinding),					0, 0, 0, 0.0f },
		{ LIMIT(maxTessellationGenerationLevel),					FEATURE(tessellationShader),			0, 0, 0, 0.0f },
		{ LIMIT(maxTessellationPatchSize),							FEATURE(tessellationShader),			0, 0, 0, 0.0f },
		{ LIMIT(maxTessellationControlPerVertexInputComponents),	FEATURE(tessellationShader),			0, 0, 0, 0.0f },
		{ LIMIT(maxTessellationControlPerVertexOutputComponents),	FEATURE(tessellationShader),			0, 0, 0, 0.0f },
		{ LIMIT(maxTessellationControlPerPatchOutputComponents),	FEATURE(tessellationShader),			0, 0, 0, 0.0f },
		{ LIMIT(maxTessellationControlTotalOutputComponents),		FEATURE(tessellationShader),			0, 0, 0, 0.0f },
		{ LIMIT(maxTessellationEvaluationInputComponents),			FEATURE(tessellationShader),			0, 0, 0, 0.0f },
		{ LIMIT(maxTessellationEvaluationOutputComponents),			FEATURE(tessellationShader),			0, 0, 0, 0.0f },
		{ LIMIT(maxGeometryShaderInvocations),						FEATURE(geometryShader),				0, 0, 0, 0.0f },
		{ LIMIT(maxGeometryInputComponents),						FEATURE(geometryShader),				0, 0, 0, 0.0f },
		{ LIMIT(maxGeometryOutputComponents),						FEATURE(geometryShader),				0, 0, 0, 0.0f },
		{ LIMIT(maxGeometryOutputVertices),							FEATURE(geometryShader),				0, 0, 0, 0.0f },
		{ LIMIT(maxGeometryTotalOutputComponents),					FEATURE(geometryShader),				0, 0, 0, 0.0f },
		{ LIMIT(maxFragmentDualSrcAttachments),						FEATURE(dualSrcBlend),					0, 0, 0, 0.0f },
		{ LIMIT(maxDrawIndexedIndexValue),							FEATURE(fullDrawIndexUint32),			(1<<24)-1, 0, 0, 0.0f },
		{ LIMIT(maxDrawIndirectCount),								FEATURE(multiDrawIndirect),				1, 0, 0, 0.0f },
		{ LIMIT(maxSamplerAnisotropy),								FEATURE(samplerAnisotropy),				1, 0, 0, 0.0f },
		{ LIMIT(maxViewports),										FEATURE(multiViewport),					1, 0, 0, 0.0f },
		{ LIMIT(minTexelGatherOffset),								FEATURE(shaderImageGatherExtended),		0, 0, 0, 0.0f },
		{ LIMIT(maxTexelGatherOffset),								FEATURE(shaderImageGatherExtended),		0, 0, 0, 0.0f },
		{ LIMIT(minInterpolationOffset),							FEATURE(sampleRateShading),				0, 0, 0, 0.0f },
		{ LIMIT(maxInterpolationOffset),							FEATURE(sampleRateShading),				0, 0, 0, 0.0f },
		{ LIMIT(subPixelInterpolationOffsetBits),					FEATURE(sampleRateShading),				0, 0, 0, 0.0f },
		{ LIMIT(storageImageSampleCounts),							FEATURE(shaderStorageImageMultisample),	VK_SAMPLE_COUNT_1_BIT, 0, 0, 0.0f },
		{ LIMIT(maxClipDistances),									FEATURE(shaderClipDistance),			0, 0, 0, 0.0f },
		{ LIMIT(maxCullDistances),									FEATURE(shaderClipDistance),			0, 0, 0, 0.0f },
		{ LIMIT(maxCombinedClipAndCullDistances),					FEATURE(shaderClipDistance),			0, 0, 0, 0.0f },
		{ LIMIT(pointSizeRange[0]),									FEATURE(largePoints),					0, 0, 0, 1.0f },
		{ LIMIT(pointSizeRange[1]),									FEATURE(largePoints),					0, 0, 0, 1.0f },
		{ LIMIT(lineWidthRange[0]),									FEATURE(wideLines),						0, 0, 0, 1.0f },
		{ LIMIT(lineWidthRange[1]),									FEATURE(wideLines),						0, 0, 0, 1.0f },
		{ LIMIT(pointSizeGranularity),								FEATURE(largePoints),					0, 0, 0, 0.0f },
		{ LIMIT(lineWidthGranularity),								FEATURE(wideLines),						0, 0, 0, 0.0f }
	};

	log << TestLog::Message << *limits << TestLog::EndMessage;

	//!< First build a map from limit to unsupported table index
	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
	{
		for (deUint32 unsuppNdx = 0; unsuppNdx < DE_LENGTH_OF_ARRAY(unsupportedFeatureTable); unsuppNdx++)
		{
			if (unsupportedFeatureTable[unsuppNdx].limitOffset == featureLimitTable[ndx].offset)
			{
				featureLimitTable[ndx].unsuppTableNdx = unsuppNdx;
				break;
			}
		}
	}

	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
	{
		switch (featureLimitTable[ndx].format)
		{
			case LIMIT_FORMAT_UNSIGNED_INT:
			{
				deUint32 limitToCheck = featureLimitTable[ndx].uintVal;
				if (featureLimitTable[ndx].unsuppTableNdx != -1)
				{
					if (*((VkBool32*)((deUint8*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)) == VK_FALSE)
						limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].uintVal;
				}

				if (featureLimitTable[ndx].type == LIMIT_TYPE_MIN)
				{

					if (*((deUint32*)((deUint8*)limits+featureLimitTable[ndx].offset)) < limitToCheck)
					{
						log << TestLog::Message << "limit Validation failed " << featureLimitTable[ndx].name
							<< " not valid-limit type MIN - actual is "
							<< *((deUint32*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
						limitsOk = false;
					}
				}
				else if (featureLimitTable[ndx].type == LIMIT_TYPE_MAX)
				{
					if (*((deUint32*)((deUint8*)limits+featureLimitTable[ndx].offset)) > limitToCheck)
					{
						log << TestLog::Message << "limit validation failed,  " << featureLimitTable[ndx].name
							<< " not valid-limit type MAX - actual is "
							<< *((deUint32*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
						limitsOk = false;
					}
				}
				break;
			}

			case LIMIT_FORMAT_FLOAT:
			{
				float limitToCheck = featureLimitTable[ndx].floatVal;
				if (featureLimitTable[ndx].unsuppTableNdx != -1)
				{
					if (*((VkBool32*)((deUint8*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)) == VK_FALSE)
						limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].floatVal;
				}

				if (featureLimitTable[ndx].type == LIMIT_TYPE_MIN)
				{
					if (*((float*)((deUint8*)limits+featureLimitTable[ndx].offset)) < limitToCheck)
					{
						log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
							<< " not valid-limit type MIN - actual is "
							<< *((float*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
						limitsOk = false;
					}
				}
				else if (featureLimitTable[ndx].type == LIMIT_TYPE_MAX)
				{
					if (*((float*)((deUint8*)limits+featureLimitTable[ndx].offset)) > limitToCheck)
					{
						log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
							<< " not valid-limit type MAX actual is "
							<< *((float*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
						limitsOk = false;
					}
				}
				break;
			}

			case LIMIT_FORMAT_SIGNED_INT:
			{
				deInt32 limitToCheck = featureLimitTable[ndx].intVal;
				if (featureLimitTable[ndx].unsuppTableNdx != -1)
				{
					if (*((VkBool32*)((deUint8*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)) == VK_FALSE)
						limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].intVal;
				}
				if (featureLimitTable[ndx].type == LIMIT_TYPE_MIN)
				{
					if (*((deInt32*)((deUint8*)limits+featureLimitTable[ndx].offset)) < limitToCheck)
					{
						log << TestLog::Message <<  "limit validation failed, " << featureLimitTable[ndx].name
							<< " not valid-limit type MIN actual is "
							<< *((deInt32*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
						limitsOk = false;
					}
				}
				else if (featureLimitTable[ndx].type == LIMIT_TYPE_MAX)
				{
					if (*((deInt32*)((deUint8*)limits+featureLimitTable[ndx].offset)) > limitToCheck)
					{
						log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
							<< " not valid-limit type MAX actual is "
							<< *((deInt32*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
						limitsOk = false;
					}
				}
				break;
			}

			case LIMIT_FORMAT_DEVICE_SIZE:
			{
				deUint64 limitToCheck = featureLimitTable[ndx].deviceSizeVal;
				if (featureLimitTable[ndx].unsuppTableNdx != -1)
				{
					if (*((VkBool32*)((deUint8*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)) == VK_FALSE)
						limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].deviceSizeVal;
				}

				if (featureLimitTable[ndx].type == LIMIT_TYPE_MIN)
				{
					if (*((deUint64*)((deUint8*)limits+featureLimitTable[ndx].offset)) < limitToCheck)
					{
						log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
							<< " not valid-limit type MIN actual is "
							<< *((deUint64*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
						limitsOk = false;
					}
				}
				else if (featureLimitTable[ndx].type == LIMIT_TYPE_MAX)
				{
					if (*((deUint64*)((deUint8*)limits+featureLimitTable[ndx].offset)) > limitToCheck)
					{
						log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
							<< " not valid-limit type MAX actual is "
							<< *((deUint64*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
						limitsOk = false;
					}
				}
				break;
			}

			case LIMIT_FORMAT_BITMASK:
			{
				deUint32 limitToCheck = featureLimitTable[ndx].uintVal;
				if (featureLimitTable[ndx].unsuppTableNdx != -1)
				{
					if (*((VkBool32*)((deUint8*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)) == VK_FALSE)
						limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].uintVal;
				}

				if (featureLimitTable[ndx].type == LIMIT_TYPE_MIN)
				{
					if ((*((deUint32*)((deUint8*)limits+featureLimitTable[ndx].offset)) & limitToCheck) != limitToCheck)
					{
						log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
							<< " not valid-limit type bitmask actual is "
							<< *((deUint64*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
						limitsOk = false;
					}
				}
				break;
			}

			default:
				DE_ASSERT(0);
				limitsOk = false;
		}
	}

	if (limits->maxFramebufferWidth > limits->maxViewportDimensions[0] ||
		limits->maxFramebufferHeight > limits->maxViewportDimensions[1])
	{
		log << TestLog::Message << "limit validation failed, maxFramebufferDimension of "
			<< "[" << limits->maxFramebufferWidth << ", " << limits->maxFramebufferHeight << "] "
			<< "is larger than maxViewportDimension of "
			<< "[" << limits->maxViewportDimensions[0] << ", " << limits->maxViewportDimensions[1] << "]" << TestLog::EndMessage;
		limitsOk = false;
	}

	if (limits->viewportBoundsRange[0] > float(-2 * limits->maxViewportDimensions[0]))
	{
		log << TestLog::Message << "limit validation failed, viewPortBoundsRange[0] of " << limits->viewportBoundsRange[0]
			<< "is larger than -2*maxViewportDimension[0] of " << -2*limits->maxViewportDimensions[0] << TestLog::EndMessage;
		limitsOk = false;
	}

	if (limits->viewportBoundsRange[1] < float(2 * limits->maxViewportDimensions[1] - 1))
	{
		log << TestLog::Message << "limit validation failed, viewportBoundsRange[1] of " << limits->viewportBoundsRange[1]
			<< "is less than 2*maxViewportDimension[1] of " << 2*limits->maxViewportDimensions[1] << TestLog::EndMessage;
		limitsOk = false;
	}

	return limitsOk;
}

template<typename T>
class CheckIncompleteResult
{
public:
	virtual			~CheckIncompleteResult	(void) {}
	virtual void	getResult				(Context& context, T* data) = 0;

	void operator() (Context& context, tcu::ResultCollector& results, const std::size_t expectedCompleteSize)
	{
		if (expectedCompleteSize == 0)
			return;

		vector<T>		outputData	(expectedCompleteSize);
		const deUint32	usedSize	= static_cast<deUint32>(expectedCompleteSize / 3);

		ValidateQueryBits::fillBits(outputData.begin(), outputData.end());	// unused entries should have this pattern intact
		m_count		= usedSize;
		m_result	= VK_SUCCESS;

		getResult(context, &outputData[0]);									// update m_count and m_result

		if (m_count != usedSize || m_result != VK_INCOMPLETE || !ValidateQueryBits::checkBits(outputData.begin() + m_count, outputData.end()))
			results.fail("Query didn't return VK_INCOMPLETE");
	}

protected:
	deUint32	m_count;
	VkResult	m_result;
};

struct CheckEnumeratePhysicalDevicesIncompleteResult : public CheckIncompleteResult<VkPhysicalDevice>
{
	void getResult (Context& context, VkPhysicalDevice* data)
	{
		m_result = context.getInstanceInterface().enumeratePhysicalDevices(context.getInstance(), &m_count, data);
	}
};

struct CheckEnumeratePhysicalDeviceGroupsIncompleteResult : public CheckIncompleteResult<VkPhysicalDeviceGroupProperties>
{
	void getResult (Context& context, VkPhysicalDeviceGroupProperties* data)
	{
		m_result = context.getInstanceInterface().enumeratePhysicalDeviceGroups(context.getInstance(), &m_count, data);
	}
};

struct CheckEnumerateInstanceLayerPropertiesIncompleteResult : public CheckIncompleteResult<VkLayerProperties>
{
	void getResult (Context& context, VkLayerProperties* data)
	{
		m_result = context.getPlatformInterface().enumerateInstanceLayerProperties(&m_count, data);
	}
};

struct CheckEnumerateDeviceLayerPropertiesIncompleteResult : public CheckIncompleteResult<VkLayerProperties>
{
	void getResult (Context& context, VkLayerProperties* data)
	{
		m_result = context.getInstanceInterface().enumerateDeviceLayerProperties(context.getPhysicalDevice(), &m_count, data);
	}
};

struct CheckEnumerateInstanceExtensionPropertiesIncompleteResult : public CheckIncompleteResult<VkExtensionProperties>
{
	CheckEnumerateInstanceExtensionPropertiesIncompleteResult (std::string layerName = std::string()) : m_layerName(layerName) {}

	void getResult (Context& context, VkExtensionProperties* data)
	{
		const char* pLayerName = (m_layerName.length() != 0 ? m_layerName.c_str() : DE_NULL);
		m_result = context.getPlatformInterface().enumerateInstanceExtensionProperties(pLayerName, &m_count, data);
	}

private:
	const std::string	m_layerName;
};

struct CheckEnumerateDeviceExtensionPropertiesIncompleteResult : public CheckIncompleteResult<VkExtensionProperties>
{
	CheckEnumerateDeviceExtensionPropertiesIncompleteResult (std::string layerName = std::string()) : m_layerName(layerName) {}

	void getResult (Context& context, VkExtensionProperties* data)
	{
		const char* pLayerName = (m_layerName.length() != 0 ? m_layerName.c_str() : DE_NULL);
		m_result = context.getInstanceInterface().enumerateDeviceExtensionProperties(context.getPhysicalDevice(), pLayerName, &m_count, data);
	}

private:
	const std::string	m_layerName;
};

tcu::TestStatus enumeratePhysicalDevices (Context& context)
{
	TestLog&						log		= context.getTestContext().getLog();
	tcu::ResultCollector			results	(log);
	const vector<VkPhysicalDevice>	devices	= enumeratePhysicalDevices(context.getInstanceInterface(), context.getInstance());

	log << TestLog::Integer("NumDevices", "Number of devices", "", QP_KEY_TAG_NONE, deInt64(devices.size()));

	for (size_t ndx = 0; ndx < devices.size(); ndx++)
		log << TestLog::Message << ndx << ": " << devices[ndx] << TestLog::EndMessage;

	CheckEnumeratePhysicalDevicesIncompleteResult()(context, results, devices.size());

	return tcu::TestStatus(results.getResult(), results.getMessage());
}

tcu::TestStatus enumeratePhysicalDeviceGroups (Context& context)
{
	TestLog&											log				= context.getTestContext().getLog();
	tcu::ResultCollector								results			(log);
	const PlatformInterface&							vkp				= context.getPlatformInterface();
	const Unique<VkInstance>							instance		(createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_device_group_creation"));
	const InstanceDriver								vki				(vkp, *instance);
	const vector<VkPhysicalDeviceGroupProperties>		devicegroups	= enumeratePhysicalDeviceGroups(vki, *instance);

	log << TestLog::Integer("NumDevices", "Number of device groups", "", QP_KEY_TAG_NONE, deInt64(devicegroups.size()));

	for (size_t ndx = 0; ndx < devicegroups.size(); ndx++)
		log << TestLog::Message << ndx << ": " << devicegroups[ndx] << TestLog::EndMessage;

	CheckEnumeratePhysicalDeviceGroupsIncompleteResult()(context, results, devicegroups.size());

	return tcu::TestStatus(results.getResult(), results.getMessage());
}

template<typename T>
void collectDuplicates (set<T>& duplicates, const vector<T>& values)
{
	set<T> seen;

	for (size_t ndx = 0; ndx < values.size(); ndx++)
	{
		const T& value = values[ndx];

		if (!seen.insert(value).second)
			duplicates.insert(value);
	}
}

void checkDuplicates (tcu::ResultCollector& results, const char* what, const vector<string>& values)
{
	set<string> duplicates;

	collectDuplicates(duplicates, values);

	for (set<string>::const_iterator iter = duplicates.begin(); iter != duplicates.end(); ++iter)
	{
		std::ostringstream msg;
		msg << "Duplicate " << what << ": " << *iter;
		results.fail(msg.str());
	}
}

void checkDuplicateExtensions (tcu::ResultCollector& results, const vector<string>& extensions)
{
	checkDuplicates(results, "extension", extensions);
}

void checkDuplicateLayers (tcu::ResultCollector& results, const vector<string>& layers)
{
	checkDuplicates(results, "layer", layers);
}

void checkKhrExtensions (tcu::ResultCollector&		results,
						 const vector<string>&		extensions,
						 const int					numAllowedKhrExtensions,
						 const char* const*			allowedKhrExtensions)
{
	const set<string>	allowedExtSet		(allowedKhrExtensions, allowedKhrExtensions+numAllowedKhrExtensions);

	for (vector<string>::const_iterator extIter = extensions.begin(); extIter != extensions.end(); ++extIter)
	{
		// Only Khronos-controlled extensions are checked
		if (de::beginsWith(*extIter, "VK_KHR_") &&
			!de::contains(allowedExtSet, *extIter))
		{
			results.fail("Unknown  extension " + *extIter);
		}
	}
}

void checkInstanceExtensions (tcu::ResultCollector& results, const vector<string>& extensions)
{
	static const char* s_allowedInstanceKhrExtensions[] =
	{
		"VK_KHR_surface",
		"VK_KHR_display",
		"VK_KHR_android_surface",
		"VK_KHR_mir_surface",
		"VK_KHR_wayland_surface",
		"VK_KHR_win32_surface",
		"VK_KHR_xcb_surface",
		"VK_KHR_xlib_surface",
		"VK_KHR_get_physical_device_properties2",
		"VK_KHR_get_surface_capabilities2",
		"VK_KHR_external_memory_capabilities",
		"VK_KHR_external_semaphore_capabilities",
		"VK_KHR_external_fence_capabilities",
		"VK_KHR_device_group_creation",
		"VK_KHR_get_display_properties2",
	};

	checkKhrExtensions(results, extensions, DE_LENGTH_OF_ARRAY(s_allowedInstanceKhrExtensions), s_allowedInstanceKhrExtensions);
	checkDuplicateExtensions(results, extensions);
}

void checkDeviceExtensions (tcu::ResultCollector& results, const vector<string>& extensions)
{
	static const char* s_allowedDeviceKhrExtensions[] =
	{
		"VK_KHR_swapchain",
		"VK_KHR_display_swapchain",
		"VK_KHR_sampler_mirror_clamp_to_edge",
		"VK_KHR_shader_draw_parameters",
		"VK_KHR_shader_float_controls",
		"VK_KHR_shader_float16_int8",
		"VK_KHR_maintenance1",
		"VK_KHR_push_descriptor",
		"VK_KHR_descriptor_update_template",
		"VK_KHR_incremental_present",
		"VK_KHR_shared_presentable_image",
		"VK_KHR_storage_buffer_storage_class",
		"VK_KHR_8bit_storage",
		"VK_KHR_16bit_storage",
		"VK_KHR_get_memory_requirements2",
		"VK_KHR_external_memory",
		"VK_KHR_external_memory_fd",
		"VK_KHR_external_memory_win32",
		"VK_KHR_external_semaphore",
		"VK_KHR_external_semaphore_fd",
		"VK_KHR_external_semaphore_win32",
		"VK_KHR_external_fence",
		"VK_KHR_external_fence_fd",
		"VK_KHR_external_fence_win32",
		"VK_KHR_win32_keyed_mutex",
		"VK_KHR_dedicated_allocation",
		"VK_KHR_variable_pointers",
		"VK_KHR_relaxed_block_layout",
		"VK_KHR_bind_memory2",
		"VK_KHR_maintenance2",
		"VK_KHR_image_format_list",
		"VK_KHR_sampler_ycbcr_conversion",
		"VK_KHR_device_group",
		"VK_KHR_multiview",
		"VK_KHR_maintenance3",
		"VK_KHR_draw_indirect_count",
		"VK_KHR_create_renderpass2",
		"VK_KHR_depth_stencil_resolve",
		"VK_KHR_driver_properties",
		"VK_KHR_swapchain_mutable_format",
		"VK_KHR_shader_atomic_int64",
		"VK_KHR_vulkan_memory_model",
		"VK_KHR_swapchain_mutable_format",
	};

	checkKhrExtensions(results, extensions, DE_LENGTH_OF_ARRAY(s_allowedDeviceKhrExtensions), s_allowedDeviceKhrExtensions);
	checkDuplicateExtensions(results, extensions);
}

void checkInstanceExtensionDependencies(tcu::ResultCollector& results,
										int dependencyLength,
										const std::pair<const char*, const char*>* dependencies,
										const vector<VkExtensionProperties>& extensionProperties)
{
	for (int ndx = 0; ndx < dependencyLength; ndx++)
	{
		if (isExtensionSupported(extensionProperties, RequiredExtension(dependencies[ndx].first)) &&
			!isExtensionSupported(extensionProperties, RequiredExtension(dependencies[ndx].second)))
		{
			results.fail("Extension " + string(dependencies[ndx].first) + " is missing dependency: " + string(dependencies[ndx].second));
		}
	}
}

void checkDeviceExtensionDependencies(tcu::ResultCollector& results,
									  int dependencyLength,
									  const std::pair<const char*, const char*>* dependencies,
									  const vector<VkExtensionProperties>& instanceExtensionProperties,
									  const vector<VkExtensionProperties>& deviceExtensionProperties)
{
	for (int ndx = 0; ndx < dependencyLength; ndx++)
	{
		if (isExtensionSupported(deviceExtensionProperties, RequiredExtension(dependencies[ndx].first)) &&
			!isExtensionSupported(deviceExtensionProperties, RequiredExtension(dependencies[ndx].second)) &&
			!isExtensionSupported(instanceExtensionProperties, RequiredExtension(dependencies[ndx].second)))
		{
			results.fail("Extension " + string(dependencies[ndx].first) + " is missing dependency: " + string(dependencies[ndx].second));
		}
	}
}

tcu::TestStatus enumerateInstanceLayers (Context& context)
{
	TestLog&						log					= context.getTestContext().getLog();
	tcu::ResultCollector			results				(log);
	const vector<VkLayerProperties>	properties			= enumerateInstanceLayerProperties(context.getPlatformInterface());
	vector<string>					layerNames;

	for (size_t ndx = 0; ndx < properties.size(); ndx++)
	{
		log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage;

		layerNames.push_back(properties[ndx].layerName);
	}

	checkDuplicateLayers(results, layerNames);
	CheckEnumerateInstanceLayerPropertiesIncompleteResult()(context, results, layerNames.size());

	return tcu::TestStatus(results.getResult(), results.getMessage());
}

tcu::TestStatus enumerateInstanceExtensions (Context& context)
{
	TestLog&				log		= context.getTestContext().getLog();
	tcu::ResultCollector	results	(log);

	{
		const ScopedLogSection				section		(log, "Global", "Global Extensions");
		const vector<VkExtensionProperties>	properties	= enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL);
		vector<string>						extensionNames;

		for (size_t ndx = 0; ndx < properties.size(); ndx++)
		{
			log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage;

			extensionNames.push_back(properties[ndx].extensionName);
		}

		checkInstanceExtensions(results, extensionNames);
		CheckEnumerateInstanceExtensionPropertiesIncompleteResult()(context, results, properties.size());

		if (context.contextSupports(vk::ApiVersion(1, 1, 0)))
		{
			checkInstanceExtensionDependencies(results,
											   DE_LENGTH_OF_ARRAY(instanceExtensionDependencies_1_1),
											   instanceExtensionDependencies_1_1, properties);
		}
		else if (context.contextSupports(vk::ApiVersion(1, 0, 0)))
		{
			checkInstanceExtensionDependencies(results,
											   DE_LENGTH_OF_ARRAY(instanceExtensionDependencies_1_0),
											   instanceExtensionDependencies_1_0, properties);
		}
	}

	{
		const vector<VkLayerProperties>	layers	= enumerateInstanceLayerProperties(context.getPlatformInterface());

		for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
		{
			const ScopedLogSection				section				(log, layer->layerName, string("Layer: ") + layer->layerName);
			const vector<VkExtensionProperties>	properties			= enumerateInstanceExtensionProperties(context.getPlatformInterface(), layer->layerName);
			vector<string>						extensionNames;

			for (size_t extNdx = 0; extNdx < properties.size(); extNdx++)
			{
				log << TestLog::Message << extNdx << ": " << properties[extNdx] << TestLog::EndMessage;

				extensionNames.push_back(properties[extNdx].extensionName);
			}

			checkInstanceExtensions(results, extensionNames);
			CheckEnumerateInstanceExtensionPropertiesIncompleteResult(layer->layerName)(context, results, properties.size());
		}
	}

	return tcu::TestStatus(results.getResult(), results.getMessage());
}

tcu::TestStatus testNoKhxExtensions (Context& context)
{
	VkPhysicalDevice			physicalDevice	= context.getPhysicalDevice();
	const PlatformInterface&	vkp				= context.getPlatformInterface();
	const InstanceInterface&	vki				= context.getInstanceInterface();

	tcu::ResultCollector		results(context.getTestContext().getLog());
	bool						testSucceeded = true;
	deUint32					instanceExtensionsCount;
	deUint32					deviceExtensionsCount;

	// grab number of instance and device extensions
	vkp.enumerateInstanceExtensionProperties(DE_NULL, &instanceExtensionsCount, DE_NULL);
	vki.enumerateDeviceExtensionProperties(physicalDevice, DE_NULL, &deviceExtensionsCount, DE_NULL);
	vector<VkExtensionProperties> extensionsProperties(instanceExtensionsCount + deviceExtensionsCount);

	// grab instance and device extensions into single vector
	if (instanceExtensionsCount)
		vkp.enumerateInstanceExtensionProperties(DE_NULL, &instanceExtensionsCount, &extensionsProperties[0]);
	if (deviceExtensionsCount)
		vki.enumerateDeviceExtensionProperties(physicalDevice, DE_NULL, &deviceExtensionsCount, &extensionsProperties[instanceExtensionsCount]);

	// iterate over all extensions and verify their names
	vector<VkExtensionProperties>::const_iterator extension = extensionsProperties.begin();
	while (extension != extensionsProperties.end())
	{
		// KHX author ID is no longer used, all KHX extensions have been promoted to KHR status
		std::string extensionName(extension->extensionName);
		bool caseFailed = de::beginsWith(extensionName, "VK_KHX_");
		if (caseFailed)
		{
			results.fail("Invalid extension name " + extensionName);
			testSucceeded = false;
		}
		++extension;
	}

	if (testSucceeded)
		return tcu::TestStatus::pass("No extensions begining with \"VK_KHX\"");
	return tcu::TestStatus::fail("One or more extensions begins with \"VK_KHX\"");
}

tcu::TestStatus enumerateDeviceLayers (Context& context)
{
	TestLog&						log			= context.getTestContext().getLog();
	tcu::ResultCollector			results		(log);
	const vector<VkLayerProperties>	properties	= enumerateDeviceLayerProperties(context.getInstanceInterface(), context.getPhysicalDevice());
	vector<string>					layerNames;

	for (size_t ndx = 0; ndx < properties.size(); ndx++)
	{
		log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage;

		layerNames.push_back(properties[ndx].layerName);
	}

	checkDuplicateLayers(results, layerNames);
	CheckEnumerateDeviceLayerPropertiesIncompleteResult()(context, results, layerNames.size());

	return tcu::TestStatus(results.getResult(), results.getMessage());
}

tcu::TestStatus enumerateDeviceExtensions (Context& context)
{
	TestLog&				log		= context.getTestContext().getLog();
	tcu::ResultCollector	results	(log);

	{
		const ScopedLogSection				section						(log, "Global", "Global Extensions");
		const vector<VkExtensionProperties>	instanceExtensionProperties	= enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL);
		const vector<VkExtensionProperties>	deviceExtensionProperties	= enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), DE_NULL);
		vector<string>						deviceExtensionNames;

		for (size_t ndx = 0; ndx < deviceExtensionProperties.size(); ndx++)
		{
			log << TestLog::Message << ndx << ": " << deviceExtensionProperties[ndx] << TestLog::EndMessage;

			deviceExtensionNames.push_back(deviceExtensionProperties[ndx].extensionName);
		}

		checkDeviceExtensions(results, deviceExtensionNames);
		CheckEnumerateDeviceExtensionPropertiesIncompleteResult()(context, results, deviceExtensionProperties.size());

		if (context.contextSupports(vk::ApiVersion(1, 1, 0)))
		{
			checkDeviceExtensionDependencies(results,
											 DE_LENGTH_OF_ARRAY(deviceExtensionDependencies_1_1),
											 deviceExtensionDependencies_1_1,
											 instanceExtensionProperties,
											 deviceExtensionProperties);
		}
		else if (context.contextSupports(vk::ApiVersion(1, 0, 0)))
		{
			checkDeviceExtensionDependencies(results,
											 DE_LENGTH_OF_ARRAY(deviceExtensionDependencies_1_0),
											 deviceExtensionDependencies_1_0,
											 instanceExtensionProperties,
											 deviceExtensionProperties);
		}
	}

	{
		const vector<VkLayerProperties>	layers	= enumerateDeviceLayerProperties(context.getInstanceInterface(), context.getPhysicalDevice());

		for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
		{
			const ScopedLogSection				section		(log, layer->layerName, string("Layer: ") + layer->layerName);
			const vector<VkExtensionProperties>	properties	= enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), layer->layerName);
			vector<string>						extensionNames;

			for (size_t extNdx = 0; extNdx < properties.size(); extNdx++)
			{
				log << TestLog::Message << extNdx << ": " << properties[extNdx] << TestLog::EndMessage;


				extensionNames.push_back(properties[extNdx].extensionName);
			}

			checkDeviceExtensions(results, extensionNames);
			CheckEnumerateDeviceExtensionPropertiesIncompleteResult(layer->layerName)(context, results, properties.size());
		}
	}

	return tcu::TestStatus(results.getResult(), results.getMessage());
}

#define VK_SIZE_OF(STRUCT, MEMBER)					(sizeof(((STRUCT*)0)->MEMBER))
#define OFFSET_TABLE_ENTRY(STRUCT, MEMBER)			{ (size_t)DE_OFFSET_OF(STRUCT, MEMBER), VK_SIZE_OF(STRUCT, MEMBER) }

tcu::TestStatus deviceFeatures (Context& context)
{
	using namespace ValidateQueryBits;

	TestLog&						log			= context.getTestContext().getLog();
	VkPhysicalDeviceFeatures*		features;
	deUint8							buffer[sizeof(VkPhysicalDeviceFeatures) + GUARD_SIZE];

	const QueryMemberTableEntry featureOffsetTable[] =
	{
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, robustBufferAccess),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, fullDrawIndexUint32),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, imageCubeArray),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, independentBlend),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, geometryShader),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, tessellationShader),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sampleRateShading),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, dualSrcBlend),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, logicOp),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, multiDrawIndirect),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, drawIndirectFirstInstance),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, depthClamp),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, depthBiasClamp),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, fillModeNonSolid),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, depthBounds),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, wideLines),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, largePoints),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, alphaToOne),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, multiViewport),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, samplerAnisotropy),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, textureCompressionETC2),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, textureCompressionASTC_LDR),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, textureCompressionBC),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, occlusionQueryPrecise),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, pipelineStatisticsQuery),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, vertexPipelineStoresAndAtomics),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, fragmentStoresAndAtomics),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderTessellationAndGeometryPointSize),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderImageGatherExtended),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderStorageImageExtendedFormats),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderStorageImageMultisample),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderStorageImageReadWithoutFormat),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderStorageImageWriteWithoutFormat),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderUniformBufferArrayDynamicIndexing),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderSampledImageArrayDynamicIndexing),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderStorageBufferArrayDynamicIndexing),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderStorageImageArrayDynamicIndexing),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderClipDistance),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderCullDistance),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderFloat64),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderInt64),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderInt16),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderResourceResidency),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderResourceMinLod),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseBinding),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidencyBuffer),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidencyImage2D),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidencyImage3D),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidency2Samples),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidency4Samples),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidency8Samples),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidency16Samples),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidencyAliased),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, variableMultisampleRate),
		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, inheritedQueries),
		{ 0, 0 }
	};

	deMemset(buffer, GUARD_VALUE, sizeof(buffer));
	features = reinterpret_cast<VkPhysicalDeviceFeatures*>(buffer);

	context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), features);

	log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage
		<< TestLog::Message << *features << TestLog::EndMessage;

	// Requirements and dependencies
	{
		if (!features->robustBufferAccess)
			return tcu::TestStatus::fail("robustBufferAccess is not supported");

		// multiViewport requires MultiViewport (SPIR-V capability) support, which depends on Geometry
		if (features->multiViewport && !features->geometryShader)
			return tcu::TestStatus::fail("multiViewport is supported but geometryShader is not");
	}

	for (int ndx = 0; ndx < GUARD_SIZE; ndx++)
	{
		if (buffer[ndx + sizeof(VkPhysicalDeviceFeatures)] != GUARD_VALUE)
		{
			log << TestLog::Message << "deviceFeatures - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
			return tcu::TestStatus::fail("deviceFeatures buffer overflow");
		}
	}

	if (!validateInitComplete(context.getPhysicalDevice(), &InstanceInterface::getPhysicalDeviceFeatures, context.getInstanceInterface(), featureOffsetTable))
	{
		log << TestLog::Message << "deviceFeatures - VkPhysicalDeviceFeatures not completely initialized" << TestLog::EndMessage;
		return tcu::TestStatus::fail("deviceFeatures incomplete initialization");
	}

	return tcu::TestStatus::pass("Query succeeded");
}

static const ValidateQueryBits::QueryMemberTableEntry s_physicalDevicePropertiesOffsetTable[] =
{
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, apiVersion),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, driverVersion),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, vendorID),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, deviceID),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, deviceType),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, pipelineCacheUUID),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxImageDimension1D),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxImageDimension2D),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxImageDimension3D),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxImageDimensionCube),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxImageArrayLayers),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTexelBufferElements),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxUniformBufferRange),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxStorageBufferRange),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPushConstantsSize),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxMemoryAllocationCount),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxSamplerAllocationCount),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.bufferImageGranularity),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.sparseAddressSpaceSize),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxBoundDescriptorSets),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageDescriptorSamplers),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageDescriptorUniformBuffers),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageDescriptorStorageBuffers),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageDescriptorSampledImages),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageDescriptorStorageImages),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageDescriptorInputAttachments),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageResources),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetSamplers),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetUniformBuffers),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetUniformBuffersDynamic),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetStorageBuffers),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetStorageBuffersDynamic),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetSampledImages),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetStorageImages),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetInputAttachments),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxVertexInputAttributes),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxVertexInputBindings),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxVertexInputAttributeOffset),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxVertexInputBindingStride),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxVertexOutputComponents),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationGenerationLevel),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationPatchSize),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationControlPerVertexInputComponents),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationControlPerVertexOutputComponents),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationControlPerPatchOutputComponents),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationControlTotalOutputComponents),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationEvaluationInputComponents),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationEvaluationOutputComponents),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxGeometryShaderInvocations),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxGeometryInputComponents),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxGeometryOutputComponents),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxGeometryOutputVertices),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxGeometryTotalOutputComponents),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFragmentInputComponents),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFragmentOutputAttachments),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFragmentDualSrcAttachments),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFragmentCombinedOutputResources),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxComputeSharedMemorySize),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxComputeWorkGroupCount[3]),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxComputeWorkGroupInvocations),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxComputeWorkGroupSize[3]),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.subPixelPrecisionBits),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.subTexelPrecisionBits),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.mipmapPrecisionBits),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDrawIndexedIndexValue),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDrawIndirectCount),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxSamplerLodBias),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxSamplerAnisotropy),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxViewports),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxViewportDimensions[2]),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.viewportBoundsRange[2]),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.viewportSubPixelBits),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minMemoryMapAlignment),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minTexelBufferOffsetAlignment),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minUniformBufferOffsetAlignment),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minStorageBufferOffsetAlignment),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minTexelOffset),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTexelOffset),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minTexelGatherOffset),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTexelGatherOffset),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minInterpolationOffset),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxInterpolationOffset),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.subPixelInterpolationOffsetBits),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFramebufferWidth),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFramebufferHeight),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFramebufferLayers),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.framebufferColorSampleCounts),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.framebufferDepthSampleCounts),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.framebufferStencilSampleCounts),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.framebufferNoAttachmentsSampleCounts),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxColorAttachments),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.sampledImageColorSampleCounts),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.sampledImageIntegerSampleCounts),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.sampledImageDepthSampleCounts),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.sampledImageStencilSampleCounts),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.storageImageSampleCounts),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxSampleMaskWords),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.timestampComputeAndGraphics),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.timestampPeriod),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxClipDistances),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxCullDistances),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxCombinedClipAndCullDistances),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.discreteQueuePriorities),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.pointSizeRange[2]),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.lineWidthRange[2]),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.pointSizeGranularity),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.lineWidthGranularity),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.strictLines),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.standardSampleLocations),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.optimalBufferCopyOffsetAlignment),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.optimalBufferCopyRowPitchAlignment),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.nonCoherentAtomSize),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, sparseProperties.residencyStandard2DBlockShape),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, sparseProperties.residencyStandard2DMultisampleBlockShape),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, sparseProperties.residencyStandard3DBlockShape),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, sparseProperties.residencyAlignedMipSize),
	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, sparseProperties.residencyNonResidentStrict),
	{ 0, 0 }
};

tcu::TestStatus deviceProperties (Context& context)
{
	using namespace ValidateQueryBits;

	TestLog&						log			= context.getTestContext().getLog();
	VkPhysicalDeviceProperties*		props;
	VkPhysicalDeviceFeatures		features;
	deUint8							buffer[sizeof(VkPhysicalDeviceProperties) + GUARD_SIZE];

	props = reinterpret_cast<VkPhysicalDeviceProperties*>(buffer);
	deMemset(props, GUARD_VALUE, sizeof(buffer));

	context.getInstanceInterface().getPhysicalDeviceProperties(context.getPhysicalDevice(), props);
	context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), &features);

	log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage
		<< TestLog::Message << *props << TestLog::EndMessage;

	if (!validateFeatureLimits(props, &features, log))
		return tcu::TestStatus::fail("deviceProperties - feature limits failed");

	for (int ndx = 0; ndx < GUARD_SIZE; ndx++)
	{
		if (buffer[ndx + sizeof(VkPhysicalDeviceProperties)] != GUARD_VALUE)
		{
			log << TestLog::Message << "deviceProperties - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
			return tcu::TestStatus::fail("deviceProperties buffer overflow");
		}
	}

	if (!validateInitComplete(context.getPhysicalDevice(), &InstanceInterface::getPhysicalDeviceProperties, context.getInstanceInterface(), s_physicalDevicePropertiesOffsetTable))
	{
		log << TestLog::Message << "deviceProperties - VkPhysicalDeviceProperties not completely initialized" << TestLog::EndMessage;
		return tcu::TestStatus::fail("deviceProperties incomplete initialization");
	}

	// Check if deviceName string is properly terminated.
	if (deStrnlen(props->deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE) == VK_MAX_PHYSICAL_DEVICE_NAME_SIZE)
	{
		log << TestLog::Message << "deviceProperties - VkPhysicalDeviceProperties deviceName not properly initialized" << TestLog::EndMessage;
		return tcu::TestStatus::fail("deviceProperties incomplete initialization");
	}

	{
		const ApiVersion deviceVersion = unpackVersion(props->apiVersion);
		const ApiVersion deqpVersion = unpackVersion(VK_API_VERSION_1_1);

		if (deviceVersion.majorNum != deqpVersion.majorNum)
		{
			log << TestLog::Message << "deviceProperties - API Major Version " << deviceVersion.majorNum << " is not valid" << TestLog::EndMessage;
			return tcu::TestStatus::fail("deviceProperties apiVersion not valid");
		}

		if (deviceVersion.minorNum > deqpVersion.minorNum)
		{
			log << TestLog::Message << "deviceProperties - API Minor Version " << deviceVersion.minorNum << " is not valid for this version of dEQP" << TestLog::EndMessage;
			return tcu::TestStatus::fail("deviceProperties apiVersion not valid");
		}
	}

	return tcu::TestStatus::pass("DeviceProperites query succeeded");
}

tcu::TestStatus deviceQueueFamilyProperties (Context& context)
{
	TestLog&								log					= context.getTestContext().getLog();
	const vector<VkQueueFamilyProperties>	queueProperties		= getPhysicalDeviceQueueFamilyProperties(context.getInstanceInterface(), context.getPhysicalDevice());

	log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage;

	for (size_t queueNdx = 0; queueNdx < queueProperties.size(); queueNdx++)
		log << TestLog::Message << queueNdx << ": " << queueProperties[queueNdx] << TestLog::EndMessage;

	return tcu::TestStatus::pass("Querying queue properties succeeded");
}

tcu::TestStatus deviceMemoryProperties (Context& context)
{
	TestLog&							log			= context.getTestContext().getLog();
	VkPhysicalDeviceMemoryProperties*	memProps;
	deUint8								buffer[sizeof(VkPhysicalDeviceMemoryProperties) + GUARD_SIZE];

	memProps = reinterpret_cast<VkPhysicalDeviceMemoryProperties*>(buffer);
	deMemset(buffer, GUARD_VALUE, sizeof(buffer));

	context.getInstanceInterface().getPhysicalDeviceMemoryProperties(context.getPhysicalDevice(), memProps);

	log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage
		<< TestLog::Message << *memProps << TestLog::EndMessage;

	for (deInt32 ndx = 0; ndx < GUARD_SIZE; ndx++)
	{
		if (buffer[ndx + sizeof(VkPhysicalDeviceMemoryProperties)] != GUARD_VALUE)
		{
			log << TestLog::Message << "deviceMemoryProperties - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
			return tcu::TestStatus::fail("deviceMemoryProperties buffer overflow");
		}
	}

	if (memProps->memoryHeapCount >= VK_MAX_MEMORY_HEAPS)
	{
		log << TestLog::Message << "deviceMemoryProperties - HeapCount larger than " << (deUint32)VK_MAX_MEMORY_HEAPS << TestLog::EndMessage;
		return tcu::TestStatus::fail("deviceMemoryProperties HeapCount too large");
	}

	if (memProps->memoryHeapCount == 1)
	{
		if ((memProps->memoryHeaps[0].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) == 0)
		{
			log << TestLog::Message << "deviceMemoryProperties - Single heap is not marked DEVICE_LOCAL" << TestLog::EndMessage;
			return tcu::TestStatus::fail("deviceMemoryProperties invalid HeapFlags");
		}
	}

	const VkMemoryPropertyFlags validPropertyFlags[] =
	{
		0,
		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_CACHED_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_CACHED_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
	};

	const VkMemoryPropertyFlags requiredPropertyFlags[] =
	{
		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
	};

	bool requiredFlagsFound[DE_LENGTH_OF_ARRAY(requiredPropertyFlags)];
	std::fill(DE_ARRAY_BEGIN(requiredFlagsFound), DE_ARRAY_END(requiredFlagsFound), false);

	for (deUint32 memoryNdx = 0; memoryNdx < memProps->memoryTypeCount; memoryNdx++)
	{
		bool validPropTypeFound = false;

		if (memProps->memoryTypes[memoryNdx].heapIndex >= memProps->memoryHeapCount)
		{
			log << TestLog::Message << "deviceMemoryProperties - heapIndex " << memProps->memoryTypes[memoryNdx].heapIndex << " larger than heapCount" << TestLog::EndMessage;
			return tcu::TestStatus::fail("deviceMemoryProperties - invalid heapIndex");
		}

		const VkMemoryPropertyFlags bitsToCheck = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT|VK_MEMORY_PROPERTY_HOST_CACHED_BIT|VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;

		for (const VkMemoryPropertyFlags* requiredFlagsIterator = DE_ARRAY_BEGIN(requiredPropertyFlags); requiredFlagsIterator != DE_ARRAY_END(requiredPropertyFlags); requiredFlagsIterator++)
			if ((memProps->memoryTypes[memoryNdx].propertyFlags & *requiredFlagsIterator) == *requiredFlagsIterator)
				requiredFlagsFound[requiredFlagsIterator - DE_ARRAY_BEGIN(requiredPropertyFlags)] = true;

		if (de::contains(DE_ARRAY_BEGIN(validPropertyFlags), DE_ARRAY_END(validPropertyFlags), memProps->memoryTypes[memoryNdx].propertyFlags & bitsToCheck))
			validPropTypeFound = true;

		if (!validPropTypeFound)
		{
			log << TestLog::Message << "deviceMemoryProperties - propertyFlags "
				<< memProps->memoryTypes[memoryNdx].propertyFlags << " not valid" << TestLog::EndMessage;
			return tcu::TestStatus::fail("deviceMemoryProperties propertyFlags not valid");
		}

		if (memProps->memoryTypes[memoryNdx].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
		{
			if ((memProps->memoryHeaps[memProps->memoryTypes[memoryNdx].heapIndex].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) == 0)
			{
				log << TestLog::Message << "deviceMemoryProperties - DEVICE_LOCAL memory type references heap which is not DEVICE_LOCAL" << TestLog::EndMessage;
				return tcu::TestStatus::fail("deviceMemoryProperties inconsistent memoryType and HeapFlags");
			}
		}
		else
		{
			if (memProps->memoryHeaps[memProps->memoryTypes[memoryNdx].heapIndex].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)
			{
				log << TestLog::Message << "deviceMemoryProperties - non-DEVICE_LOCAL memory type references heap with is DEVICE_LOCAL" << TestLog::EndMessage;
				return tcu::TestStatus::fail("deviceMemoryProperties inconsistent memoryType and HeapFlags");
			}
		}
	}

	bool* requiredFlagsFoundIterator = std::find(DE_ARRAY_BEGIN(requiredFlagsFound), DE_ARRAY_END(requiredFlagsFound), false);
	if (requiredFlagsFoundIterator != DE_ARRAY_END(requiredFlagsFound))
	{
		DE_ASSERT(requiredFlagsFoundIterator - DE_ARRAY_BEGIN(requiredFlagsFound) <= DE_LENGTH_OF_ARRAY(requiredPropertyFlags));
		log << TestLog::Message << "deviceMemoryProperties - required property flags "
			<< getMemoryPropertyFlagsStr(requiredPropertyFlags[requiredFlagsFoundIterator - DE_ARRAY_BEGIN(requiredFlagsFound)]) << " not found" << TestLog::EndMessage;

		return tcu::TestStatus::fail("deviceMemoryProperties propertyFlags not valid");
	}

	return tcu::TestStatus::pass("Querying memory properties succeeded");
}

tcu::TestStatus deviceGroupPeerMemoryFeatures (Context& context)
{
	TestLog&							log						= context.getTestContext().getLog();
	const PlatformInterface&			vkp						= context.getPlatformInterface();
	const Unique<VkInstance>			instance				(createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_device_group_creation"));
	const InstanceDriver				vki						(vkp, *instance);
	const tcu::CommandLine&				cmdLine					= context.getTestContext().getCommandLine();
	const deUint32						devGroupIdx				= cmdLine.getVKDeviceGroupId() - 1;
	const deUint32						deviceIdx				= vk::chooseDeviceIndex(context.getInstanceInterface(), *instance, cmdLine);
	const float							queuePriority			= 1.0f;
	VkPhysicalDeviceMemoryProperties	memProps;
	VkPeerMemoryFeatureFlags*			peerMemFeatures;
	deUint8								buffer					[sizeof(VkPeerMemoryFeatureFlags) + GUARD_SIZE];
	deUint32							numPhysicalDevices		= 0;
	deUint32							queueFamilyIndex		= 0;

	const vector<VkPhysicalDeviceGroupProperties>		deviceGroupProps = enumeratePhysicalDeviceGroups(vki, *instance);
	std::vector<const char*>							deviceExtensions;
	deviceExtensions.push_back("VK_KHR_device_group");

	if (!isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_device_group"))
		deviceExtensions.push_back("VK_KHR_device_group");

	const std::vector<VkQueueFamilyProperties>	queueProps		= getPhysicalDeviceQueueFamilyProperties(vki, deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx]);
	for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
	{
		if (queueProps[queueNdx].queueFlags & VK_QUEUE_GRAPHICS_BIT)
			queueFamilyIndex = (deUint32)queueNdx;
	}
	const VkDeviceQueueCreateInfo		deviceQueueCreateInfo	=
	{
		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,			//type
		DE_NULL,											//pNext
		(VkDeviceQueueCreateFlags)0u,						//flags
		queueFamilyIndex,									//queueFamilyIndex;
		1u,													//queueCount;
		&queuePriority,										//pQueuePriorities;
	};

	// Need atleast 2 devices for peer memory features
	numPhysicalDevices = deviceGroupProps[devGroupIdx].physicalDeviceCount;
	if (numPhysicalDevices < 2)
		TCU_THROW(NotSupportedError, "Need a device Group with at least 2 physical devices.");

	// Create device groups
	const VkDeviceGroupDeviceCreateInfo						deviceGroupInfo =
	{
		VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO,	//stype
		DE_NULL,											//pNext
		deviceGroupProps[devGroupIdx].physicalDeviceCount,	//physicalDeviceCount
		deviceGroupProps[devGroupIdx].physicalDevices		//physicalDevices
	};
	const VkDeviceCreateInfo								deviceCreateInfo =
	{
		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,							//sType;
		&deviceGroupInfo,												//pNext;
		(VkDeviceCreateFlags)0u,										//flags
		1,																//queueRecordCount;
		&deviceQueueCreateInfo,											//pRequestedQueues;
		0,																//layerCount;
		DE_NULL,														//ppEnabledLayerNames;
		deUint32(deviceExtensions.size()),								//extensionCount;
		(deviceExtensions.empty() ? DE_NULL : &deviceExtensions[0]),	//ppEnabledExtensionNames;
		DE_NULL,														//pEnabledFeatures;
	};

	Move<VkDevice>		deviceGroup = createDevice(vkp, *instance, vki, deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx], &deviceCreateInfo);
	const DeviceDriver	vk	(vkp, *instance, *deviceGroup);
	context.getInstanceInterface().getPhysicalDeviceMemoryProperties(deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx], &memProps);

	peerMemFeatures = reinterpret_cast<VkPeerMemoryFeatureFlags*>(buffer);
	deMemset(buffer, GUARD_VALUE, sizeof(buffer));

	for (deUint32 heapIndex = 0; heapIndex < memProps.memoryHeapCount; heapIndex++)
	{
		for (deUint32 localDeviceIndex = 0; localDeviceIndex < numPhysicalDevices; localDeviceIndex++)
		{
			for (deUint32 remoteDeviceIndex = 0; remoteDeviceIndex < numPhysicalDevices; remoteDeviceIndex++)
			{
				if (localDeviceIndex != remoteDeviceIndex)
				{
					vk.getDeviceGroupPeerMemoryFeatures(deviceGroup.get(), heapIndex, localDeviceIndex, remoteDeviceIndex, peerMemFeatures);

					// Check guard
					for (deInt32 ndx = 0; ndx < GUARD_SIZE; ndx++)
					{
						if (buffer[ndx + sizeof(VkPeerMemoryFeatureFlags)] != GUARD_VALUE)
						{
							log << TestLog::Message << "deviceGroupPeerMemoryFeatures - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
							return tcu::TestStatus::fail("deviceGroupPeerMemoryFeatures buffer overflow");
						}
					}

					VkPeerMemoryFeatureFlags requiredFlag = VK_PEER_MEMORY_FEATURE_COPY_DST_BIT;
					VkPeerMemoryFeatureFlags maxValidFlag = VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT|VK_PEER_MEMORY_FEATURE_COPY_DST_BIT|
																VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT|VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT;
					if ((!(*peerMemFeatures & requiredFlag)) ||
						*peerMemFeatures > maxValidFlag)
						return tcu::TestStatus::fail("deviceGroupPeerMemoryFeatures invalid flag");

					log << TestLog::Message << "deviceGroup = " << deviceGroup.get() << TestLog::EndMessage
						<< TestLog::Message << "heapIndex = " << heapIndex << TestLog::EndMessage
						<< TestLog::Message << "localDeviceIndex = " << localDeviceIndex << TestLog::EndMessage
						<< TestLog::Message << "remoteDeviceIndex = " << remoteDeviceIndex << TestLog::EndMessage
						<< TestLog::Message << "PeerMemoryFeatureFlags = " << *peerMemFeatures << TestLog::EndMessage;
				}
			} // remote device
		} // local device
	} // heap Index

	return tcu::TestStatus::pass("Querying deviceGroup peer memory features succeeded");
}

// \todo [2016-01-22 pyry] Optimize by doing format -> flags mapping instead

VkFormatFeatureFlags getRequiredOptimalTilingFeatures (VkFormat format)
{
	static const VkFormat s_requiredSampledImageBlitSrcFormats[] =
	{
		VK_FORMAT_B4G4R4A4_UNORM_PACK16,
		VK_FORMAT_R5G6B5_UNORM_PACK16,
		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
		VK_FORMAT_R8_UNORM,
		VK_FORMAT_R8_SNORM,
		VK_FORMAT_R8_UINT,
		VK_FORMAT_R8_SINT,
		VK_FORMAT_R8G8_UNORM,
		VK_FORMAT_R8G8_SNORM,
		VK_FORMAT_R8G8_UINT,
		VK_FORMAT_R8G8_SINT,
		VK_FORMAT_R8G8B8A8_UNORM,
		VK_FORMAT_R8G8B8A8_SNORM,
		VK_FORMAT_R8G8B8A8_UINT,
		VK_FORMAT_R8G8B8A8_SINT,
		VK_FORMAT_R8G8B8A8_SRGB,
		VK_FORMAT_B8G8R8A8_UNORM,
		VK_FORMAT_B8G8R8A8_SRGB,
		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
		VK_FORMAT_A8B8G8R8_UINT_PACK32,
		VK_FORMAT_A8B8G8R8_SINT_PACK32,
		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
		VK_FORMAT_A2B10G10R10_UINT_PACK32,
		VK_FORMAT_R16_UINT,
		VK_FORMAT_R16_SINT,
		VK_FORMAT_R16_SFLOAT,
		VK_FORMAT_R16G16_UINT,
		VK_FORMAT_R16G16_SINT,
		VK_FORMAT_R16G16_SFLOAT,
		VK_FORMAT_R16G16B16A16_UINT,
		VK_FORMAT_R16G16B16A16_SINT,
		VK_FORMAT_R16G16B16A16_SFLOAT,
		VK_FORMAT_R32_UINT,
		VK_FORMAT_R32_SINT,
		VK_FORMAT_R32_SFLOAT,
		VK_FORMAT_R32G32_UINT,
		VK_FORMAT_R32G32_SINT,
		VK_FORMAT_R32G32_SFLOAT,
		VK_FORMAT_R32G32B32A32_UINT,
		VK_FORMAT_R32G32B32A32_SINT,
		VK_FORMAT_R32G32B32A32_SFLOAT,
		VK_FORMAT_B10G11R11_UFLOAT_PACK32,
		VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
		VK_FORMAT_D16_UNORM,
		VK_FORMAT_D32_SFLOAT
	};
	static const VkFormat s_requiredSampledImageFilterLinearFormats[] =
	{
		VK_FORMAT_B4G4R4A4_UNORM_PACK16,
		VK_FORMAT_R5G6B5_UNORM_PACK16,
		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
		VK_FORMAT_R8_UNORM,
		VK_FORMAT_R8_SNORM,
		VK_FORMAT_R8G8_UNORM,
		VK_FORMAT_R8G8_SNORM,
		VK_FORMAT_R8G8B8A8_UNORM,
		VK_FORMAT_R8G8B8A8_SNORM,
		VK_FORMAT_R8G8B8A8_SRGB,
		VK_FORMAT_B8G8R8A8_UNORM,
		VK_FORMAT_B8G8R8A8_SRGB,
		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
		VK_FORMAT_R16_SFLOAT,
		VK_FORMAT_R16G16_SFLOAT,
		VK_FORMAT_R16G16B16A16_SFLOAT,
		VK_FORMAT_B10G11R11_UFLOAT_PACK32,
		VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
	};
	static const VkFormat s_requiredStorageImageFormats[] =
	{
		VK_FORMAT_R8G8B8A8_UNORM,
		VK_FORMAT_R8G8B8A8_SNORM,
		VK_FORMAT_R8G8B8A8_UINT,
		VK_FORMAT_R8G8B8A8_SINT,
		VK_FORMAT_R16G16B16A16_UINT,
		VK_FORMAT_R16G16B16A16_SINT,
		VK_FORMAT_R16G16B16A16_SFLOAT,
		VK_FORMAT_R32_UINT,
		VK_FORMAT_R32_SINT,
		VK_FORMAT_R32_SFLOAT,
		VK_FORMAT_R32G32_UINT,
		VK_FORMAT_R32G32_SINT,
		VK_FORMAT_R32G32_SFLOAT,
		VK_FORMAT_R32G32B32A32_UINT,
		VK_FORMAT_R32G32B32A32_SINT,
		VK_FORMAT_R32G32B32A32_SFLOAT
	};
	static const VkFormat s_requiredStorageImageAtomicFormats[] =
	{
		VK_FORMAT_R32_UINT,
		VK_FORMAT_R32_SINT
	};
	static const VkFormat s_requiredColorAttachmentBlitDstFormats[] =
	{
		VK_FORMAT_R5G6B5_UNORM_PACK16,
		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
		VK_FORMAT_R8_UNORM,
		VK_FORMAT_R8_UINT,
		VK_FORMAT_R8_SINT,
		VK_FORMAT_R8G8_UNORM,
		VK_FORMAT_R8G8_UINT,
		VK_FORMAT_R8G8_SINT,
		VK_FORMAT_R8G8B8A8_UNORM,
		VK_FORMAT_R8G8B8A8_UINT,
		VK_FORMAT_R8G8B8A8_SINT,
		VK_FORMAT_R8G8B8A8_SRGB,
		VK_FORMAT_B8G8R8A8_UNORM,
		VK_FORMAT_B8G8R8A8_SRGB,
		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
		VK_FORMAT_A8B8G8R8_UINT_PACK32,
		VK_FORMAT_A8B8G8R8_SINT_PACK32,
		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
		VK_FORMAT_A2B10G10R10_UINT_PACK32,
		VK_FORMAT_R16_UINT,
		VK_FORMAT_R16_SINT,
		VK_FORMAT_R16_SFLOAT,
		VK_FORMAT_R16G16_UINT,
		VK_FORMAT_R16G16_SINT,
		VK_FORMAT_R16G16_SFLOAT,
		VK_FORMAT_R16G16B16A16_UINT,
		VK_FORMAT_R16G16B16A16_SINT,
		VK_FORMAT_R16G16B16A16_SFLOAT,
		VK_FORMAT_R32_UINT,
		VK_FORMAT_R32_SINT,
		VK_FORMAT_R32_SFLOAT,
		VK_FORMAT_R32G32_UINT,
		VK_FORMAT_R32G32_SINT,
		VK_FORMAT_R32G32_SFLOAT,
		VK_FORMAT_R32G32B32A32_UINT,
		VK_FORMAT_R32G32B32A32_SINT,
		VK_FORMAT_R32G32B32A32_SFLOAT
	};
	static const VkFormat s_requiredColorAttachmentBlendFormats[] =
	{
		VK_FORMAT_R5G6B5_UNORM_PACK16,
		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
		VK_FORMAT_R8_UNORM,
		VK_FORMAT_R8G8_UNORM,
		VK_FORMAT_R8G8B8A8_UNORM,
		VK_FORMAT_R8G8B8A8_SRGB,
		VK_FORMAT_B8G8R8A8_UNORM,
		VK_FORMAT_B8G8R8A8_SRGB,
		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
		VK_FORMAT_R16_SFLOAT,
		VK_FORMAT_R16G16_SFLOAT,
		VK_FORMAT_R16G16B16A16_SFLOAT
	};
	static const VkFormat s_requiredDepthStencilAttachmentFormats[] =
	{
		VK_FORMAT_D16_UNORM
	};

	VkFormatFeatureFlags	flags	= (VkFormatFeatureFlags)0;

	if (de::contains(DE_ARRAY_BEGIN(s_requiredSampledImageBlitSrcFormats), DE_ARRAY_END(s_requiredSampledImageBlitSrcFormats), format))
		flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT|VK_FORMAT_FEATURE_BLIT_SRC_BIT;

	if (de::contains(DE_ARRAY_BEGIN(s_requiredSampledImageFilterLinearFormats), DE_ARRAY_END(s_requiredSampledImageFilterLinearFormats), format))
		flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;

	if (de::contains(DE_ARRAY_BEGIN(s_requiredStorageImageFormats), DE_ARRAY_END(s_requiredStorageImageFormats), format))
		flags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;

	if (de::contains(DE_ARRAY_BEGIN(s_requiredStorageImageAtomicFormats), DE_ARRAY_END(s_requiredStorageImageAtomicFormats), format))
		flags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT;

	if (de::contains(DE_ARRAY_BEGIN(s_requiredColorAttachmentBlitDstFormats), DE_ARRAY_END(s_requiredColorAttachmentBlitDstFormats), format))
		flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT|VK_FORMAT_FEATURE_BLIT_DST_BIT;

	if (de::contains(DE_ARRAY_BEGIN(s_requiredColorAttachmentBlendFormats), DE_ARRAY_END(s_requiredColorAttachmentBlendFormats), format))
		flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;

	if (de::contains(DE_ARRAY_BEGIN(s_requiredDepthStencilAttachmentFormats), DE_ARRAY_END(s_requiredDepthStencilAttachmentFormats), format))
		flags |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;

	return flags;
}

VkFormatFeatureFlags getRequiredOptimalExtendedTilingFeatures (Context& context, VkFormat format, VkFormatFeatureFlags queriedFlags)
{
	VkFormatFeatureFlags	flags	= (VkFormatFeatureFlags)0;

	// VK_EXT_sampler_filter_minmax:
	//	If filterMinmaxSingleComponentFormats is VK_TRUE, the following formats must
	//	support the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT feature with
	//	VK_IMAGE_TILING_OPTIMAL, if they support VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT.

	static const VkFormat s_requiredSampledImageFilterMinMaxFormats[] =
	{
		VK_FORMAT_R8_UNORM,
		VK_FORMAT_R8_SNORM,
		VK_FORMAT_R16_UNORM,
		VK_FORMAT_R16_SNORM,
		VK_FORMAT_R16_SFLOAT,
		VK_FORMAT_R32_SFLOAT,
		VK_FORMAT_D16_UNORM,
		VK_FORMAT_X8_D24_UNORM_PACK32,
		VK_FORMAT_D32_SFLOAT,
		VK_FORMAT_D16_UNORM_S8_UINT,
		VK_FORMAT_D24_UNORM_S8_UINT,
		VK_FORMAT_D32_SFLOAT_S8_UINT,
	};

	if ((queriedFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
	{
		if (de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_EXT_sampler_filter_minmax"))
		{
			if (de::contains(DE_ARRAY_BEGIN(s_requiredSampledImageFilterMinMaxFormats), DE_ARRAY_END(s_requiredSampledImageFilterMinMaxFormats), format))
			{
				VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT	physicalDeviceSamplerMinMaxProperties =
				{
					VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT,
					DE_NULL,
					DE_FALSE,
					DE_FALSE
				};

				{
					VkPhysicalDeviceProperties2		physicalDeviceProperties;
					physicalDeviceProperties.sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
					physicalDeviceProperties.pNext	= &physicalDeviceSamplerMinMaxProperties;

					const InstanceInterface&		vk = context.getInstanceInterface();
					vk.getPhysicalDeviceProperties2(context.getPhysicalDevice(), &physicalDeviceProperties);
				}

				if (physicalDeviceSamplerMinMaxProperties.filterMinmaxSingleComponentFormats)
				{
					flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT;
				}
			}
		}
	}
	return flags;
}

VkFormatFeatureFlags getRequiredBufferFeatures (VkFormat format)
{
	static const VkFormat s_requiredVertexBufferFormats[] =
	{
		VK_FORMAT_R8_UNORM,
		VK_FORMAT_R8_SNORM,
		VK_FORMAT_R8_UINT,
		VK_FORMAT_R8_SINT,
		VK_FORMAT_R8G8_UNORM,
		VK_FORMAT_R8G8_SNORM,
		VK_FORMAT_R8G8_UINT,
		VK_FORMAT_R8G8_SINT,
		VK_FORMAT_R8G8B8A8_UNORM,
		VK_FORMAT_R8G8B8A8_SNORM,
		VK_FORMAT_R8G8B8A8_UINT,
		VK_FORMAT_R8G8B8A8_SINT,
		VK_FORMAT_B8G8R8A8_UNORM,
		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
		VK_FORMAT_A8B8G8R8_UINT_PACK32,
		VK_FORMAT_A8B8G8R8_SINT_PACK32,
		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
		VK_FORMAT_R16_UNORM,
		VK_FORMAT_R16_SNORM,
		VK_FORMAT_R16_UINT,
		VK_FORMAT_R16_SINT,
		VK_FORMAT_R16_SFLOAT,
		VK_FORMAT_R16G16_UNORM,
		VK_FORMAT_R16G16_SNORM,
		VK_FORMAT_R16G16_UINT,
		VK_FORMAT_R16G16_SINT,
		VK_FORMAT_R16G16_SFLOAT,
		VK_FORMAT_R16G16B16A16_UNORM,
		VK_FORMAT_R16G16B16A16_SNORM,
		VK_FORMAT_R16G16B16A16_UINT,
		VK_FORMAT_R16G16B16A16_SINT,
		VK_FORMAT_R16G16B16A16_SFLOAT,
		VK_FORMAT_R32_UINT,
		VK_FORMAT_R32_SINT,
		VK_FORMAT_R32_SFLOAT,
		VK_FORMAT_R32G32_UINT,
		VK_FORMAT_R32G32_SINT,
		VK_FORMAT_R32G32_SFLOAT,
		VK_FORMAT_R32G32B32_UINT,
		VK_FORMAT_R32G32B32_SINT,
		VK_FORMAT_R32G32B32_SFLOAT,
		VK_FORMAT_R32G32B32A32_UINT,
		VK_FORMAT_R32G32B32A32_SINT,
		VK_FORMAT_R32G32B32A32_SFLOAT
	};
	static const VkFormat s_requiredUniformTexelBufferFormats[] =
	{
		VK_FORMAT_R8_UNORM,
		VK_FORMAT_R8_SNORM,
		VK_FORMAT_R8_UINT,
		VK_FORMAT_R8_SINT,
		VK_FORMAT_R8G8_UNORM,
		VK_FORMAT_R8G8_SNORM,
		VK_FORMAT_R8G8_UINT,
		VK_FORMAT_R8G8_SINT,
		VK_FORMAT_R8G8B8A8_UNORM,
		VK_FORMAT_R8G8B8A8_SNORM,
		VK_FORMAT_R8G8B8A8_UINT,
		VK_FORMAT_R8G8B8A8_SINT,
		VK_FORMAT_B8G8R8A8_UNORM,
		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
		VK_FORMAT_A8B8G8R8_UINT_PACK32,
		VK_FORMAT_A8B8G8R8_SINT_PACK32,
		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
		VK_FORMAT_A2B10G10R10_UINT_PACK32,
		VK_FORMAT_R16_UINT,
		VK_FORMAT_R16_SINT,
		VK_FORMAT_R16_SFLOAT,
		VK_FORMAT_R16G16_UINT,
		VK_FORMAT_R16G16_SINT,
		VK_FORMAT_R16G16_SFLOAT,
		VK_FORMAT_R16G16B16A16_UINT,
		VK_FORMAT_R16G16B16A16_SINT,
		VK_FORMAT_R16G16B16A16_SFLOAT,
		VK_FORMAT_R32_UINT,
		VK_FORMAT_R32_SINT,
		VK_FORMAT_R32_SFLOAT,
		VK_FORMAT_R32G32_UINT,
		VK_FORMAT_R32G32_SINT,
		VK_FORMAT_R32G32_SFLOAT,
		VK_FORMAT_R32G32B32A32_UINT,
		VK_FORMAT_R32G32B32A32_SINT,
		VK_FORMAT_R32G32B32A32_SFLOAT,
		VK_FORMAT_B10G11R11_UFLOAT_PACK32
	};
	static const VkFormat s_requiredStorageTexelBufferFormats[] =
	{
		VK_FORMAT_R8G8B8A8_UNORM,
		VK_FORMAT_R8G8B8A8_SNORM,
		VK_FORMAT_R8G8B8A8_UINT,
		VK_FORMAT_R8G8B8A8_SINT,
		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
		VK_FORMAT_A8B8G8R8_UINT_PACK32,
		VK_FORMAT_A8B8G8R8_SINT_PACK32,
		VK_FORMAT_R16G16B16A16_UINT,
		VK_FORMAT_R16G16B16A16_SINT,
		VK_FORMAT_R16G16B16A16_SFLOAT,
		VK_FORMAT_R32_UINT,
		VK_FORMAT_R32_SINT,
		VK_FORMAT_R32_SFLOAT,
		VK_FORMAT_R32G32_UINT,
		VK_FORMAT_R32G32_SINT,
		VK_FORMAT_R32G32_SFLOAT,
		VK_FORMAT_R32G32B32A32_UINT,
		VK_FORMAT_R32G32B32A32_SINT,
		VK_FORMAT_R32G32B32A32_SFLOAT
	};
	static const VkFormat s_requiredStorageTexelBufferAtomicFormats[] =
	{
		VK_FORMAT_R32_UINT,
		VK_FORMAT_R32_SINT
	};

	VkFormatFeatureFlags	flags	= (VkFormatFeatureFlags)0;

	if (de::contains(DE_ARRAY_BEGIN(s_requiredVertexBufferFormats), DE_ARRAY_END(s_requiredVertexBufferFormats), format))
		flags |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT;

	if (de::contains(DE_ARRAY_BEGIN(s_requiredUniformTexelBufferFormats), DE_ARRAY_END(s_requiredUniformTexelBufferFormats), format))
		flags |= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT;

	if (de::contains(DE_ARRAY_BEGIN(s_requiredStorageTexelBufferFormats), DE_ARRAY_END(s_requiredStorageTexelBufferFormats), format))
		flags |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT;

	if (de::contains(DE_ARRAY_BEGIN(s_requiredStorageTexelBufferAtomicFormats), DE_ARRAY_END(s_requiredStorageTexelBufferAtomicFormats), format))
		flags |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;

	return flags;
}

tcu::TestStatus formatProperties (Context& context, VkFormat format)
{
	TestLog&					log					= context.getTestContext().getLog();
	const VkFormatProperties	properties			= getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), format);
	bool						allOk				= true;

	// \todo [2017-05-16 pyry] This should be extended to cover for example COLOR_ATTACHMENT for depth formats etc.
	// \todo [2017-05-18 pyry] Any other color conversion related features that can't be supported by regular formats?
	const VkFormatFeatureFlags	extOptimalFeatures	= getRequiredOptimalExtendedTilingFeatures(context, format, properties.optimalTilingFeatures);

	const VkFormatFeatureFlags	notAllowedFeatures	= VK_FORMAT_FEATURE_DISJOINT_BIT;

	const struct
	{
		VkFormatFeatureFlags VkFormatProperties::*	field;
		const char*									fieldName;
		VkFormatFeatureFlags						requiredFeatures;
	} fields[] =
	{
		{ &VkFormatProperties::linearTilingFeatures,	"linearTilingFeatures",		(VkFormatFeatureFlags)0											},
		{ &VkFormatProperties::optimalTilingFeatures,	"optimalTilingFeatures",	getRequiredOptimalTilingFeatures(format) | extOptimalFeatures	},
		{ &VkFormatProperties::bufferFeatures,			"bufferFeatures",			getRequiredBufferFeatures(format)								}
	};

	log << TestLog::Message << properties << TestLog::EndMessage;

	for (int fieldNdx = 0; fieldNdx < DE_LENGTH_OF_ARRAY(fields); fieldNdx++)
	{
		const char* const				fieldName	= fields[fieldNdx].fieldName;
		const VkFormatFeatureFlags		supported	= properties.*fields[fieldNdx].field;
		const VkFormatFeatureFlags		required	= fields[fieldNdx].requiredFeatures;

		if ((supported & required) != required)
		{
			log << TestLog::Message << "ERROR in " << fieldName << ":\n"
									<< "  required: " << getFormatFeatureFlagsStr(required) << "\n  "
									<< "  missing: " << getFormatFeatureFlagsStr(~supported & required)
				<< TestLog::EndMessage;
			allOk = false;
		}

		if ((supported & notAllowedFeatures) != 0)
		{
			log << TestLog::Message << "ERROR in " << fieldName << ":\n"
									<< "  has: " << getFormatFeatureFlagsStr(supported & notAllowedFeatures)
				<< TestLog::EndMessage;
			allOk = false;
		}
	}

	if (allOk)
		return tcu::TestStatus::pass("Query and validation passed");
	else
		return tcu::TestStatus::fail("Required features not supported");
}

VkPhysicalDeviceSamplerYcbcrConversionFeatures getPhysicalDeviceSamplerYcbcrConversionFeatures (const InstanceInterface& vk, VkPhysicalDevice physicalDevice)
{
	VkPhysicalDeviceFeatures2						coreFeatures;
	VkPhysicalDeviceSamplerYcbcrConversionFeatures	ycbcrFeatures;

	deMemset(&coreFeatures, 0, sizeof(coreFeatures));
	deMemset(&ycbcrFeatures, 0, sizeof(ycbcrFeatures));

	coreFeatures.sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
	coreFeatures.pNext		= &ycbcrFeatures;
	ycbcrFeatures.sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;

	vk.getPhysicalDeviceFeatures2(physicalDevice, &coreFeatures);

	return ycbcrFeatures;
}

void checkYcbcrApiSupport (Context& context)
{
	// check if YCbcr API and are supported by implementation

	// the support for formats and YCbCr may still be optional - see isYcbcrConversionSupported below

	if (!vk::isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_sampler_ycbcr_conversion"))
	{
		if (!vk::isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_sampler_ycbcr_conversion"))
			TCU_THROW(NotSupportedError, "VK_KHR_sampler_ycbcr_conversion is not supported");

		// Hard dependency for ycbcr
		TCU_CHECK(de::contains(context.getInstanceExtensions().begin(), context.getInstanceExtensions().end(), "VK_KHR_get_physical_device_properties2"));
	}
}

bool isYcbcrConversionSupported (Context& context)
{
	checkYcbcrApiSupport(context);

	const VkPhysicalDeviceSamplerYcbcrConversionFeatures	ycbcrFeatures	= getPhysicalDeviceSamplerYcbcrConversionFeatures(context.getInstanceInterface(), context.getPhysicalDevice());

	return (ycbcrFeatures.samplerYcbcrConversion == VK_TRUE);
}

VkFormatFeatureFlags getAllowedYcbcrFormatFeatures (VkFormat format)
{
	DE_ASSERT(isYCbCrFormat(format));

	VkFormatFeatureFlags	flags	= (VkFormatFeatureFlags)0;

	// all formats *may* support these
	flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
	flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
	flags |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT;
	flags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
	flags |= VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT;
	flags |= VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT;
	flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT;
	flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT;
	flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT;
	flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT;
	flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT;

	// multi-plane formats *may* support DISJOINT_BIT
	if (getPlaneCount(format) >= 2)
		flags |= VK_FORMAT_FEATURE_DISJOINT_BIT;

	if (isChromaSubsampled(format))
		flags |= VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT;

	return flags;
}

tcu::TestStatus ycbcrFormatProperties (Context& context, VkFormat format)
{
	DE_ASSERT(isYCbCrFormat(format));
	// check if Ycbcr format enums are valid given the version and extensions
	checkYcbcrApiSupport(context);

	TestLog&					log						= context.getTestContext().getLog();
	const VkFormatProperties	properties				= getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), format);
	bool						allOk					= true;
	const VkFormatFeatureFlags	allowedImageFeatures	= getAllowedYcbcrFormatFeatures(format);

	const struct
	{
		VkFormatFeatureFlags VkFormatProperties::*	field;
		const char*									fieldName;
		bool										requiredFeatures;
		VkFormatFeatureFlags						allowedFeatures;
	} fields[] =
	{
		{ &VkFormatProperties::linearTilingFeatures,	"linearTilingFeatures",		false,	allowedImageFeatures	},
		{ &VkFormatProperties::optimalTilingFeatures,	"optimalTilingFeatures",	true,	allowedImageFeatures	},
		{ &VkFormatProperties::bufferFeatures,			"bufferFeatures",			false,	(VkFormatFeatureFlags)0	}
	};
	static const VkFormat		s_requiredBaseFormats[]	=
	{
		VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
		VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM
	};
	const bool					isRequiredBaseFormat	= isYcbcrConversionSupported(context) &&
														  de::contains(DE_ARRAY_BEGIN(s_requiredBaseFormats), DE_ARRAY_END(s_requiredBaseFormats), format);

	log << TestLog::Message << properties << TestLog::EndMessage;

	for (int fieldNdx = 0; fieldNdx < DE_LENGTH_OF_ARRAY(fields); fieldNdx++)
	{
		const char* const				fieldName	= fields[fieldNdx].fieldName;
		const VkFormatFeatureFlags		supported	= properties.*fields[fieldNdx].field;
		const VkFormatFeatureFlags		allowed		= fields[fieldNdx].allowedFeatures;

		if (isRequiredBaseFormat && fields[fieldNdx].requiredFeatures)
		{
			const VkFormatFeatureFlags	required	= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
													| VK_FORMAT_FEATURE_TRANSFER_SRC_BIT
													| VK_FORMAT_FEATURE_TRANSFER_DST_BIT;

			if ((supported & required) != required)
			{
				log << TestLog::Message << "ERROR in " << fieldName << ":\n"
										<< "  required: " << getFormatFeatureFlagsStr(required) << "\n  "
										<< "  missing: " << getFormatFeatureFlagsStr(~supported & required)
					<< TestLog::EndMessage;
				allOk = false;
			}

			if ((supported & (VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT | VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT)) == 0)
			{
				log << TestLog::Message << "ERROR in " << fieldName << ":\n"
										<< "  Either VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT or VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT required"
					<< TestLog::EndMessage;
				allOk = false;
			}
		}

		if ((supported & ~allowed) != 0)
		{
			log << TestLog::Message << "ERROR in " << fieldName << ":\n"
									<< "  has: " << getFormatFeatureFlagsStr(supported & ~allowed)
				<< TestLog::EndMessage;
			allOk = false;
		}
	}

	if (allOk)
		return tcu::TestStatus::pass("Query and validation passed");
	else
		return tcu::TestStatus::fail("Required features not supported");
}

bool optimalTilingFeaturesSupported (Context& context, VkFormat format, VkFormatFeatureFlags features)
{
	const VkFormatProperties	properties	= getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), format);

	return (properties.optimalTilingFeatures & features) == features;
}

bool optimalTilingFeaturesSupportedForAll (Context& context, const VkFormat* begin, const VkFormat* end, VkFormatFeatureFlags features)
{
	for (const VkFormat* cur = begin; cur != end; ++cur)
	{
		if (!optimalTilingFeaturesSupported(context, *cur, features))
			return false;
	}

	return true;
}

tcu::TestStatus testDepthStencilSupported (Context& context)
{
	if (!optimalTilingFeaturesSupported(context, VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) &&
		!optimalTilingFeaturesSupported(context, VK_FORMAT_D32_SFLOAT, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
		return tcu::TestStatus::fail("Doesn't support one of VK_FORMAT_X8_D24_UNORM_PACK32 or VK_FORMAT_D32_SFLOAT");

	if (!optimalTilingFeaturesSupported(context, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) &&
		!optimalTilingFeaturesSupported(context, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
		return tcu::TestStatus::fail("Doesn't support one of VK_FORMAT_D24_UNORM_S8_UINT or VK_FORMAT_D32_SFLOAT_S8_UINT");

	return tcu::TestStatus::pass("Required depth/stencil formats supported");
}

tcu::TestStatus testCompressedFormatsSupported (Context& context)
{
	static const VkFormat s_allBcFormats[] =
	{
		VK_FORMAT_BC1_RGB_UNORM_BLOCK,
		VK_FORMAT_BC1_RGB_SRGB_BLOCK,
		VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
		VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
		VK_FORMAT_BC2_UNORM_BLOCK,
		VK_FORMAT_BC2_SRGB_BLOCK,
		VK_FORMAT_BC3_UNORM_BLOCK,
		VK_FORMAT_BC3_SRGB_BLOCK,
		VK_FORMAT_BC4_UNORM_BLOCK,
		VK_FORMAT_BC4_SNORM_BLOCK,
		VK_FORMAT_BC5_UNORM_BLOCK,
		VK_FORMAT_BC5_SNORM_BLOCK,
		VK_FORMAT_BC6H_UFLOAT_BLOCK,
		VK_FORMAT_BC6H_SFLOAT_BLOCK,
		VK_FORMAT_BC7_UNORM_BLOCK,
		VK_FORMAT_BC7_SRGB_BLOCK,
	};
	static const VkFormat s_allEtc2Formats[] =
	{
		VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
		VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
		VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
		VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
		VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
		VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
		VK_FORMAT_EAC_R11_UNORM_BLOCK,
		VK_FORMAT_EAC_R11_SNORM_BLOCK,
		VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
		VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
	};
	static const VkFormat s_allAstcLdrFormats[] =
	{
		VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
		VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
		VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
		VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
		VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
		VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
		VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
		VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
		VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
		VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
		VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
		VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
		VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
		VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
		VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
		VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
		VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
		VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
		VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
		VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
		VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
		VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
		VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
		VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
		VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
		VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
		VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
		VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
	};

	static const struct
	{
		const char*									setName;
		const char*									featureName;
		const VkBool32 VkPhysicalDeviceFeatures::*	feature;
		const VkFormat*								formatsBegin;
		const VkFormat*								formatsEnd;
	} s_compressedFormatSets[] =
	{
		{ "BC",			"textureCompressionBC",			&VkPhysicalDeviceFeatures::textureCompressionBC,		DE_ARRAY_BEGIN(s_allBcFormats),			DE_ARRAY_END(s_allBcFormats)		},
		{ "ETC2",		"textureCompressionETC2",		&VkPhysicalDeviceFeatures::textureCompressionETC2,		DE_ARRAY_BEGIN(s_allEtc2Formats),		DE_ARRAY_END(s_allEtc2Formats)		},
		{ "ASTC LDR",	"textureCompressionASTC_LDR",	&VkPhysicalDeviceFeatures::textureCompressionASTC_LDR,	DE_ARRAY_BEGIN(s_allAstcLdrFormats),	DE_ARRAY_END(s_allAstcLdrFormats)	},
	};

	TestLog&						log					= context.getTestContext().getLog();
	const VkPhysicalDeviceFeatures&	features			= context.getDeviceFeatures();
	int								numSupportedSets	= 0;
	int								numErrors			= 0;
	int								numWarnings			= 0;

	for (int setNdx = 0; setNdx < DE_LENGTH_OF_ARRAY(s_compressedFormatSets); ++setNdx)
	{
		const char* const	setName			= s_compressedFormatSets[setNdx].setName;
		const char* const	featureName		= s_compressedFormatSets[setNdx].featureName;
		const bool			featureBitSet	= features.*s_compressedFormatSets[setNdx].feature == VK_TRUE;
		const bool			allSupported	= optimalTilingFeaturesSupportedForAll(context,
																				   s_compressedFormatSets[setNdx].formatsBegin,
																				   s_compressedFormatSets[setNdx].formatsEnd,
																				   VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);

		if (featureBitSet && !allSupported)
		{
			log << TestLog::Message << "ERROR: " << featureName << " = VK_TRUE but " << setName << " formats not supported" << TestLog::EndMessage;
			numErrors += 1;
		}
		else if (allSupported && !featureBitSet)
		{
			log << TestLog::Message << "WARNING: " << setName << " formats supported but " << featureName << " = VK_FALSE" << TestLog::EndMessage;
			numWarnings += 1;
		}

		if (featureBitSet)
		{
			log << TestLog::Message << "All " << setName << " formats are supported" << TestLog::EndMessage;
			numSupportedSets += 1;
		}
		else
			log << TestLog::Message << setName << " formats are not supported" << TestLog::EndMessage;
	}

	if (numSupportedSets == 0)
	{
		log << TestLog::Message << "No compressed format sets supported" << TestLog::EndMessage;
		numErrors += 1;
	}

	if (numErrors > 0)
		return tcu::TestStatus::fail("Compressed format support not valid");
	else if (numWarnings > 0)
		return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Found inconsistencies in compressed format support");
	else
		return tcu::TestStatus::pass("Compressed texture format support is valid");
}

void createFormatTests (tcu::TestCaseGroup* testGroup)
{
	DE_STATIC_ASSERT(VK_FORMAT_UNDEFINED == 0);

	static const struct
	{
		VkFormat								begin;
		VkFormat								end;
		FunctionInstance1<VkFormat>::Function	testFunction;
	} s_formatRanges[] =
	{
		// core formats
		{ (VkFormat)(VK_FORMAT_UNDEFINED+1),	VK_CORE_FORMAT_LAST,										formatProperties },

		// YCbCr formats
		{ VK_FORMAT_G8B8G8R8_422_UNORM,			(VkFormat)(VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM+1),	ycbcrFormatProperties },
	};

	for (int rangeNdx = 0; rangeNdx < DE_LENGTH_OF_ARRAY(s_formatRanges); ++rangeNdx)
	{
		const VkFormat								rangeBegin		= s_formatRanges[rangeNdx].begin;
		const VkFormat								rangeEnd		= s_formatRanges[rangeNdx].end;
		const FunctionInstance1<VkFormat>::Function	testFunction	= s_formatRanges[rangeNdx].testFunction;

		for (VkFormat format = rangeBegin; format != rangeEnd; format = (VkFormat)(format+1))
		{
			const char* const	enumName	= getFormatName(format);
			const string		caseName	= de::toLower(string(enumName).substr(10));

			addFunctionCase(testGroup, caseName, enumName, testFunction, format);
		}
	}

	addFunctionCase(testGroup, "depth_stencil",			"",	testDepthStencilSupported);
	addFunctionCase(testGroup, "compressed_formats",	"",	testCompressedFormatsSupported);
}

VkImageUsageFlags getValidImageUsageFlags (const VkFormatFeatureFlags supportedFeatures, const bool useKhrMaintenance1Semantics)
{
	VkImageUsageFlags	flags	= (VkImageUsageFlags)0;

	if (useKhrMaintenance1Semantics)
	{
		if ((supportedFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) != 0)
			flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;

		if ((supportedFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) != 0)
			flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
	}
	else
	{
		// If format is supported at all, it must be valid transfer src+dst
		if (supportedFeatures != 0)
			flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT;
	}

	if ((supportedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
		flags |= VK_IMAGE_USAGE_SAMPLED_BIT;

	if ((supportedFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) != 0)
		flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT|VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;

	if ((supportedFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)
		flags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;

	if ((supportedFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0)
		flags |= VK_IMAGE_USAGE_STORAGE_BIT;

	return flags;
}

bool isValidImageUsageFlagCombination (VkImageUsageFlags usage)
{
	if ((usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0)
	{
		const VkImageUsageFlags		allowedFlags	= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
													| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
													| VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
													| VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;

		// Only *_ATTACHMENT_BIT flags can be combined with TRANSIENT_ATTACHMENT_BIT
		if ((usage & ~allowedFlags) != 0)
			return false;

		// TRANSIENT_ATTACHMENT_BIT is not valid without COLOR_ or DEPTH_STENCIL_ATTACHMENT_BIT
		if ((usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) == 0)
			return false;
	}

	return usage != 0;
}

VkImageCreateFlags getValidImageCreateFlags (const VkPhysicalDeviceFeatures& deviceFeatures, VkFormat format, VkFormatFeatureFlags formatFeatures, VkImageType type, VkImageUsageFlags usage)
{
	VkImageCreateFlags	flags	= (VkImageCreateFlags)0;

	if ((usage & VK_IMAGE_USAGE_SAMPLED_BIT) != 0)
	{
		flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;

		if (type == VK_IMAGE_TYPE_2D && !isYCbCrFormat(format))
		{
			flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
		}
	}

	if (isYCbCrFormat(format) && getPlaneCount(format) > 1)
	{
		if (formatFeatures & VK_FORMAT_FEATURE_DISJOINT_BIT_KHR)
			flags |= VK_IMAGE_CREATE_DISJOINT_BIT_KHR;
	}

	if ((usage & (VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_STORAGE_BIT)) != 0 &&
		(usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) == 0)
	{
		if (deviceFeatures.sparseBinding)
			flags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT|VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT;

		if (deviceFeatures.sparseResidencyAliased)
			flags |= VK_IMAGE_CREATE_SPARSE_ALIASED_BIT;
	}

	return flags;
}

bool isValidImageCreateFlagCombination (VkImageCreateFlags)
{
	return true;
}

bool isRequiredImageParameterCombination (const VkPhysicalDeviceFeatures&	deviceFeatures,
										  const VkFormat					format,
										  const VkFormatProperties&			formatProperties,
										  const VkImageType					imageType,
										  const VkImageTiling				imageTiling,
										  const VkImageUsageFlags			usageFlags,
										  const VkImageCreateFlags			createFlags)
{
	DE_UNREF(deviceFeatures);
	DE_UNREF(formatProperties);
	DE_UNREF(createFlags);

	// Linear images can have arbitrary limitations
	if (imageTiling == VK_IMAGE_TILING_LINEAR)
		return false;

	// Support for other usages for compressed formats is optional
	if (isCompressedFormat(format) &&
		(usageFlags & ~(VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT)) != 0)
		return false;

	// Support for 1D, and sliced 3D compressed formats is optional
	if (isCompressedFormat(format) && (imageType == VK_IMAGE_TYPE_1D || imageType == VK_IMAGE_TYPE_3D))
		return false;

	// Support for 1D and 3D depth/stencil textures is optional
	if (isDepthStencilFormat(format) && (imageType == VK_IMAGE_TYPE_1D || imageType == VK_IMAGE_TYPE_3D))
		return false;

	DE_ASSERT(deviceFeatures.sparseBinding || (createFlags & (VK_IMAGE_CREATE_SPARSE_BINDING_BIT|VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)) == 0);
	DE_ASSERT(deviceFeatures.sparseResidencyAliased || (createFlags & VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) == 0);

	if (isYCbCrFormat(format) && (createFlags & (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)))
		return false;

	if (createFlags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)
	{
		if (isCompressedFormat(format))
			return false;

		if (isDepthStencilFormat(format))
			return false;

		if (!deIsPowerOfTwo32(mapVkFormat(format).getPixelSize()))
			return false;

		switch (imageType)
		{
			case VK_IMAGE_TYPE_2D:
				return (deviceFeatures.sparseResidencyImage2D == VK_TRUE);
			case VK_IMAGE_TYPE_3D:
				return (deviceFeatures.sparseResidencyImage3D == VK_TRUE);
			default:
				return false;
		}
	}

	return true;
}

VkSampleCountFlags getRequiredOptimalTilingSampleCounts (const VkPhysicalDeviceLimits&	deviceLimits,
														 const VkFormat					format,
														 const VkImageUsageFlags		usageFlags)
{
	if (isCompressedFormat(format))
		return VK_SAMPLE_COUNT_1_BIT;

	bool		hasDepthComp	= false;
	bool		hasStencilComp	= false;
	const bool	isYCbCr			= isYCbCrFormat(format);
	if (!isYCbCr)
	{
		const tcu::TextureFormat	tcuFormat		= mapVkFormat(format);
		hasDepthComp	= (tcuFormat.order == tcu::TextureFormat::D || tcuFormat.order == tcu::TextureFormat::DS);
		hasStencilComp	= (tcuFormat.order == tcu::TextureFormat::S || tcuFormat.order == tcu::TextureFormat::DS);
	}

	const bool						isColorFormat	= !hasDepthComp && !hasStencilComp;
	VkSampleCountFlags				sampleCounts	= ~(VkSampleCountFlags)0;

	DE_ASSERT((hasDepthComp || hasStencilComp) != isColorFormat);

	if ((usageFlags & VK_IMAGE_USAGE_STORAGE_BIT) != 0)
		sampleCounts &= deviceLimits.storageImageSampleCounts;

	if ((usageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) != 0)
	{
		if (hasDepthComp)
			sampleCounts &= deviceLimits.sampledImageDepthSampleCounts;

		if (hasStencilComp)
			sampleCounts &= deviceLimits.sampledImageStencilSampleCounts;

		if (isColorFormat)
		{
			if (isYCbCr)
				sampleCounts &= deviceLimits.sampledImageColorSampleCounts;
			else
			{
				const tcu::TextureFormat		tcuFormat	= mapVkFormat(format);
				const tcu::TextureChannelClass	chnClass	= tcu::getTextureChannelClass(tcuFormat.type);

				if (chnClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ||
					chnClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
					sampleCounts &= deviceLimits.sampledImageIntegerSampleCounts;
				else
					sampleCounts &= deviceLimits.sampledImageColorSampleCounts;
			}
		}
	}

	if ((usageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) != 0)
		sampleCounts &= deviceLimits.framebufferColorSampleCounts;

	if ((usageFlags & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)
	{
		if (hasDepthComp)
			sampleCounts &= deviceLimits.framebufferDepthSampleCounts;

		if (hasStencilComp)
			sampleCounts &= deviceLimits.framebufferStencilSampleCounts;
	}

	// If there is no usage flag set that would have corresponding device limit,
	// only VK_SAMPLE_COUNT_1_BIT is required.
	if (sampleCounts == ~(VkSampleCountFlags)0)
		sampleCounts &= VK_SAMPLE_COUNT_1_BIT;

	return sampleCounts;
}

struct ImageFormatPropertyCase
{
	typedef tcu::TestStatus (*Function) (Context& context, const VkFormat format, const VkImageType imageType, const VkImageTiling tiling);

	Function		testFunction;
	VkFormat		format;
	VkImageType		imageType;
	VkImageTiling	tiling;

	ImageFormatPropertyCase (Function testFunction_, VkFormat format_, VkImageType imageType_, VkImageTiling tiling_)
		: testFunction	(testFunction_)
		, format		(format_)
		, imageType		(imageType_)
		, tiling		(tiling_)
	{}

	ImageFormatPropertyCase (void)
		: testFunction	((Function)DE_NULL)
		, format		(VK_FORMAT_UNDEFINED)
		, imageType		(VK_IMAGE_TYPE_LAST)
		, tiling		(VK_IMAGE_TILING_LAST)
	{}
};

tcu::TestStatus imageFormatProperties (Context& context, const VkFormat format, const VkImageType imageType, const VkImageTiling tiling)
{
	if (isYCbCrFormat(format))
		// check if Ycbcr format enums are valid given the version and extensions
		checkYcbcrApiSupport(context);

	TestLog&						log					= context.getTestContext().getLog();
	const VkPhysicalDeviceFeatures&	deviceFeatures		= context.getDeviceFeatures();
	const VkPhysicalDeviceLimits&	deviceLimits		= context.getDeviceProperties().limits;
	const VkFormatProperties		formatProperties	= getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), format);
	const bool						hasKhrMaintenance1	= isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance1");

	const VkFormatFeatureFlags		supportedFeatures	= tiling == VK_IMAGE_TILING_LINEAR ? formatProperties.linearTilingFeatures : formatProperties.optimalTilingFeatures;
	const VkImageUsageFlags			usageFlagSet		= getValidImageUsageFlags(supportedFeatures, hasKhrMaintenance1);

	tcu::ResultCollector			results				(log, "ERROR: ");

	if (hasKhrMaintenance1 && (supportedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
	{
		results.check((supportedFeatures & (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT|VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) != 0,
					  "A sampled image format must have VK_FORMAT_FEATURE_TRANSFER_SRC_BIT and VK_FORMAT_FEATURE_TRANSFER_DST_BIT format feature flags set");
	}

	if (isYcbcrConversionSupported(context) && (format == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR || format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR))
	{
		VkFormatFeatureFlags requiredFeatures = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR | VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR;
		if (tiling == VK_IMAGE_TILING_OPTIMAL)
			requiredFeatures |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT_KHR;

		results.check((supportedFeatures & requiredFeatures) == requiredFeatures,
					  getFormatName(format) + string(" must support ") + de::toString(getFormatFeatureFlagsStr(requiredFeatures)));
	}

	for (VkImageUsageFlags curUsageFlags = 0; curUsageFlags <= usageFlagSet; curUsageFlags++)
	{
		if ((curUsageFlags & ~usageFlagSet) != 0 ||
			!isValidImageUsageFlagCombination(curUsageFlags))
			continue;

		const VkImageCreateFlags	createFlagSet		= getValidImageCreateFlags(deviceFeatures, format, supportedFeatures, imageType, curUsageFlags);

		for (VkImageCreateFlags curCreateFlags = 0; curCreateFlags <= createFlagSet; curCreateFlags++)
		{
			if ((curCreateFlags & ~createFlagSet) != 0 ||
				!isValidImageCreateFlagCombination(curCreateFlags))
				continue;

			const bool				isRequiredCombination	= isRequiredImageParameterCombination(deviceFeatures,
																								  format,
																								  formatProperties,
																								  imageType,
																								  tiling,
																								  curUsageFlags,
																								  curCreateFlags);
			VkImageFormatProperties	properties;
			VkResult				queryResult;

			log << TestLog::Message << "Testing " << getImageTypeStr(imageType) << ", "
									<< getImageTilingStr(tiling) << ", "
									<< getImageUsageFlagsStr(curUsageFlags) << ", "
									<< getImageCreateFlagsStr(curCreateFlags)
				<< TestLog::EndMessage;

			// Set return value to known garbage
			deMemset(&properties, 0xcd, sizeof(properties));

			queryResult = context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(context.getPhysicalDevice(),
																								format,
																								imageType,
																								tiling,
																								curUsageFlags,
																								curCreateFlags,
																								&properties);

			if (queryResult == VK_SUCCESS)
			{
				const deUint32	fullMipPyramidSize	= de::max(de::max(deLog2Ceil32(properties.maxExtent.width),
																	  deLog2Ceil32(properties.maxExtent.height)),
															  deLog2Ceil32(properties.maxExtent.depth)) + 1;

				log << TestLog::Message << properties << "\n" << TestLog::EndMessage;

				results.check(imageType != VK_IMAGE_TYPE_1D || (properties.maxExtent.width >= 1 && properties.maxExtent.height == 1 && properties.maxExtent.depth == 1), "Invalid dimensions for 1D image");
				results.check(imageType != VK_IMAGE_TYPE_2D || (properties.maxExtent.width >= 1 && properties.maxExtent.height >= 1 && properties.maxExtent.depth == 1), "Invalid dimensions for 2D image");
				results.check(imageType != VK_IMAGE_TYPE_3D || (properties.maxExtent.width >= 1 && properties.maxExtent.height >= 1 && properties.maxExtent.depth >= 1), "Invalid dimensions for 3D image");
				results.check(imageType != VK_IMAGE_TYPE_3D || properties.maxArrayLayers == 1, "Invalid maxArrayLayers for 3D image");

				if (tiling == VK_IMAGE_TILING_OPTIMAL && imageType == VK_IMAGE_TYPE_2D && !(curCreateFlags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
					 (supportedFeatures & (VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)))
				{
					const VkSampleCountFlags	requiredSampleCounts	= getRequiredOptimalTilingSampleCounts(deviceLimits, format, curUsageFlags);
					results.check((properties.sampleCounts & requiredSampleCounts) == requiredSampleCounts, "Required sample counts not supported");
				}
				else
					results.check(properties.sampleCounts == VK_SAMPLE_COUNT_1_BIT, "sampleCounts != VK_SAMPLE_COUNT_1_BIT");

				if (isRequiredCombination)
				{
					results.check(imageType != VK_IMAGE_TYPE_1D || (properties.maxExtent.width	>= deviceLimits.maxImageDimension1D),
								  "Reported dimensions smaller than device limits");
					results.check(imageType != VK_IMAGE_TYPE_2D || (properties.maxExtent.width	>= deviceLimits.maxImageDimension2D &&
																	properties.maxExtent.height	>= deviceLimits.maxImageDimension2D),
								  "Reported dimensions smaller than device limits");
					results.check(imageType != VK_IMAGE_TYPE_3D || (properties.maxExtent.width	>= deviceLimits.maxImageDimension3D &&
																	properties.maxExtent.height	>= deviceLimits.maxImageDimension3D &&
																	properties.maxExtent.depth	>= deviceLimits.maxImageDimension3D),
								  "Reported dimensions smaller than device limits");
					results.check((isYCbCrFormat(format) && (properties.maxMipLevels == 1)) || properties.maxMipLevels == fullMipPyramidSize,
					              "Invalid mip pyramid size");
					results.check((isYCbCrFormat(format) && (properties.maxArrayLayers == 1)) || imageType == VK_IMAGE_TYPE_3D ||
					              properties.maxArrayLayers >= deviceLimits.maxImageArrayLayers, "Invalid maxArrayLayers");
				}
				else
				{
					results.check(properties.maxMipLevels == 1 || properties.maxMipLevels == fullMipPyramidSize, "Invalid mip pyramid size");
					results.check(properties.maxArrayLayers >= 1, "Invalid maxArrayLayers");
				}

				results.check(properties.maxResourceSize >= (VkDeviceSize)MINIMUM_REQUIRED_IMAGE_RESOURCE_SIZE,
							  "maxResourceSize smaller than minimum required size");
			}
			else if (queryResult == VK_ERROR_FORMAT_NOT_SUPPORTED)
			{
				log << TestLog::Message << "Got VK_ERROR_FORMAT_NOT_SUPPORTED" << TestLog::EndMessage;

				if (isRequiredCombination)
					results.fail("VK_ERROR_FORMAT_NOT_SUPPORTED returned for required image parameter combination");

				// Specification requires that all fields are set to 0
				results.check(properties.maxExtent.width	== 0, "maxExtent.width != 0");
				results.check(properties.maxExtent.height	== 0, "maxExtent.height != 0");
				results.check(properties.maxExtent.depth	== 0, "maxExtent.depth != 0");
				results.check(properties.maxMipLevels		== 0, "maxMipLevels != 0");
				results.check(properties.maxArrayLayers		== 0, "maxArrayLayers != 0");
				results.check(properties.sampleCounts		== 0, "sampleCounts != 0");
				results.check(properties.maxResourceSize	== 0, "maxResourceSize != 0");
			}
			else
			{
				results.fail("Got unexpected error" + de::toString(queryResult));
			}
		}
	}

	return tcu::TestStatus(results.getResult(), results.getMessage());
}

// VK_KHR_get_physical_device_properties2

string toString (const VkPhysicalDevice16BitStorageFeatures& value)
{
	std::ostringstream	s;
	s << "VkPhysicalDevice16BitStorageFeatures = {\n";
	s << "\tsType = " << value.sType << '\n';
	s << "\tstorageBuffer16BitAccess = " << value.storageBuffer16BitAccess << '\n';
	s << "\tuniformAndStorageBuffer16BitAccess = " << value.uniformAndStorageBuffer16BitAccess << '\n';
	s << "\tstoragePushConstant16 = " << value.storagePushConstant16 << '\n';
	s << "\tstorageInputOutput16 = " << value.storageInputOutput16 << '\n';
	s << '}';
	return s.str();
}

string toString (const VkPhysicalDeviceFloatControlsPropertiesKHR& value)
{
	std::ostringstream	s;
	s << "VkPhysicalDeviceFloatControlsPropertiesKHR = {\n";
	s << "\tsType = " << value.sType << '\n';
	s << "\tseparateDenormSettings = " << value.separateDenormSettings << '\n';
	s << "\tseparateRoundingModeSettings = " << value.separateRoundingModeSettings << '\n';
	s << "\tshaderSignedZeroInfNanPreserveFloat16 = " << value.shaderSignedZeroInfNanPreserveFloat16 << '\n';
	s << "\tshaderSignedZeroInfNanPreserveFloat32 = " << value.shaderSignedZeroInfNanPreserveFloat32 << '\n';
	s << "\tshaderSignedZeroInfNanPreserveFloat64 = " << value.shaderSignedZeroInfNanPreserveFloat64 << '\n';
	s << "\tshaderDenormPreserveFloat16 = " << value.shaderDenormPreserveFloat16 << '\n';
	s << "\tshaderDenormPreserveFloat32 = " << value.shaderDenormPreserveFloat32 << '\n';
	s << "\tshaderDenormPreserveFloat64 = " << value.shaderDenormPreserveFloat64 << '\n';
	s << "\tshaderDenormFlushToZeroFloat16 = " << value.shaderDenormFlushToZeroFloat16 << '\n';
	s << "\tshaderDenormFlushToZeroFloat32 = " << value.shaderDenormFlushToZeroFloat32 << '\n';
	s << "\tshaderDenormFlushToZeroFloat64 = " << value.shaderDenormFlushToZeroFloat64 << '\n';
	s << "\tshaderRoundingModeRTEFloat16 = " << value.shaderRoundingModeRTEFloat16 << '\n';
	s << "\tshaderRoundingModeRTEFloat32 = " << value.shaderRoundingModeRTEFloat32 << '\n';
	s << "\tshaderRoundingModeRTEFloat64 = " << value.shaderRoundingModeRTEFloat64 << '\n';
	s << "\tshaderRoundingModeRTZFloat16 = " << value.shaderRoundingModeRTZFloat16 << '\n';
	s << "\tshaderRoundingModeRTZFloat32 = " << value.shaderRoundingModeRTZFloat32 << '\n';
	s << "\tshaderRoundingModeRTZFloat64 = " << value.shaderRoundingModeRTZFloat64 << '\n';
	s << '}';
	return s.str();
}

string toString (const VkPhysicalDeviceMultiviewFeatures& value)
{
	std::ostringstream	s;
	s << "VkPhysicalDeviceMultiviewFeatures = {\n";
	s << "\tsType = " << value.sType << '\n';
	s << "\tmultiview = " << value.multiview << '\n';
	s << "\tmultiviewGeometryShader = " << value.multiviewGeometryShader << '\n';
	s << "\tmultiviewTessellationShader = " << value.multiviewTessellationShader << '\n';
	s << '}';
	return s.str();
}

string toString (const VkPhysicalDeviceProtectedMemoryFeatures& value)
{
	std::ostringstream	s;
	s << "VkPhysicalDeviceProtectedMemoryFeatures = {\n";
	s << "\tsType = " << value.sType << '\n';
	s << "\tprotectedMemory = " << value.protectedMemory << '\n';
	s << '}';
	return s.str();
}

string toString (const VkPhysicalDeviceSamplerYcbcrConversionFeatures& value)
{
	std::ostringstream	s;
	s << "VkPhysicalDeviceSamplerYcbcrConversionFeatures = {\n";
	s << "\tsType = " << value.sType << '\n';
	s << "\tsamplerYcbcrConversion = " << value.samplerYcbcrConversion << '\n';
	s << '}';
	return s.str();
}

string toString (const VkPhysicalDeviceVariablePointerFeatures& value)
{
	std::ostringstream	s;
	s << "VkPhysicalDeviceVariablePointerFeatures = {\n";
	s << "\tsType = " << value.sType << '\n';
	s << "\tvariablePointersStorageBuffer = " << value.variablePointersStorageBuffer << '\n';
	s << "\tvariablePointers = " << value.variablePointers << '\n';
	s << '}';
	return s.str();
}

string toString(const VkPhysicalDevicePushDescriptorPropertiesKHR& value)
{
	std::ostringstream	s;
	s << "VkPhysicalDevicePushDescriptorPropertiesKHR = {\n";
	s << "\tsType = " << value.sType << '\n';
	s << "\tmaxPushDescriptors = " << value.maxPushDescriptors << '\n';
	s << '}';
	return s.str();
}

string toString(const VkPhysicalDeviceDepthStencilResolvePropertiesKHR& value)
{
	std::ostringstream	s;
	s << "VkPhysicalDeviceDepthStencilResolvePropertiesKHR = {\n";
	s << "\tsType = " << value.sType << '\n';
	s << "\tsupportedDepthResolveModes = " << value.supportedDepthResolveModes << '\n';
	s << "\tsupportedStencilResolveModes = " << value.supportedStencilResolveModes << '\n';
	s << "\tindependentResolveNone = " << value.independentResolveNone << '\n';
	s << "\tindependentResolve = " << value.independentResolve << '\n';
	s << '}';
	return s.str();
}

string toString(const VkPhysicalDeviceScalarBlockLayoutFeaturesEXT& value)
{
	std::ostringstream	s;
	s << "VkPhysicalDeviceScalarBlockLayoutFeaturesEXT = {\n";
	s << "\tsType = " << value.sType << '\n';
	s << "\tscalarBlockLayout = " << value.scalarBlockLayout << '\n';
	s << '}';
	return s.str();
}

bool checkExtension (vector<VkExtensionProperties>& properties, const char* extension)
{
	for (size_t ndx = 0; ndx < properties.size(); ++ndx)
	{
		if (strcmp(properties[ndx].extensionName, extension) == 0)
			return true;
	}
	return false;
}

tcu::TestStatus deviceFeatures2 (Context& context)
{
	const PlatformInterface&	vkp				= context.getPlatformInterface();
	const VkPhysicalDevice		physicalDevice	= context.getPhysicalDevice();
	const Unique<VkInstance>	instance		(createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_get_physical_device_properties2"));
	const InstanceDriver		vki				(vkp, *instance);
	TestLog&					log				= context.getTestContext().getLog();
	VkPhysicalDeviceFeatures	coreFeatures;
	VkPhysicalDeviceFeatures2	extFeatures;

	deMemset(&coreFeatures, 0xcd, sizeof(coreFeatures));
	deMemset(&extFeatures.features, 0xcd, sizeof(extFeatures.features));
	std::vector<std::string> instExtensions = context.getInstanceExtensions();

	extFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
	extFeatures.pNext = DE_NULL;

	vki.getPhysicalDeviceFeatures(physicalDevice, &coreFeatures);
	vki.getPhysicalDeviceFeatures2(physicalDevice, &extFeatures);

	TCU_CHECK(extFeatures.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2);
	TCU_CHECK(extFeatures.pNext == DE_NULL);

	if (deMemCmp(&coreFeatures, &extFeatures.features, sizeof(VkPhysicalDeviceFeatures)) != 0)
		TCU_FAIL("Mismatch between features reported by vkGetPhysicalDeviceFeatures and vkGetPhysicalDeviceFeatures2");

	log << TestLog::Message << extFeatures << TestLog::EndMessage;

	vector<VkExtensionProperties>	properties = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
	const bool khr_8bit_storage				= checkExtension(properties,"VK_KHR_8bit_storage");
	const bool ext_conditional_rendering	= checkExtension(properties,"VK_EXT_conditional_rendering");
	const bool scalar_block_layout			= checkExtension(properties,"VK_EXT_scalar_block_layout");
	bool khr_16bit_storage					= true;
	bool khr_multiview						= true;
	bool deviceProtectedMemory				= true;
	bool sampler_ycbcr_conversion			= true;
	bool variable_pointers					= true;
	if (getPhysicalDeviceProperties(vki, physicalDevice).apiVersion < VK_API_VERSION_1_1)
	{
		khr_16bit_storage = checkExtension(properties,"VK_KHR_16bit_storage");
		khr_multiview = checkExtension(properties,"VK_KHR_multiview");
		deviceProtectedMemory = false;
		sampler_ycbcr_conversion = checkExtension(properties,"VK_KHR_sampler_ycbcr_conversion");
		variable_pointers = checkExtension(properties,"VK_KHR_variable_pointers");
	}

	const int count = 2u;
	VkPhysicalDevice8BitStorageFeaturesKHR				device8BitStorageFeatures[count];
	VkPhysicalDeviceConditionalRenderingFeaturesEXT		deviceConditionalRenderingFeatures[count];
	VkPhysicalDevice16BitStorageFeatures				device16BitStorageFeatures[count];
	VkPhysicalDeviceMultiviewFeatures					deviceMultiviewFeatures[count];
	VkPhysicalDeviceProtectedMemoryFeatures				protectedMemoryFeatures[count];
	VkPhysicalDeviceSamplerYcbcrConversionFeatures		samplerYcbcrConversionFeatures[count];
	VkPhysicalDeviceVariablePointerFeatures				variablePointerFeatures[count];
	VkPhysicalDeviceScalarBlockLayoutFeaturesEXT		scalarBlockLayoutFeatures[count];

	for (int ndx = 0; ndx < count; ++ndx)
	{
		deMemset(&device8BitStorageFeatures[ndx],			0xFF*ndx, sizeof(VkPhysicalDevice8BitStorageFeaturesKHR));
		deMemset(&deviceConditionalRenderingFeatures[ndx],	0xFF*ndx, sizeof(VkPhysicalDeviceConditionalRenderingFeaturesEXT));
		deMemset(&device16BitStorageFeatures[ndx],			0xFF*ndx, sizeof(VkPhysicalDevice16BitStorageFeatures));
		deMemset(&deviceMultiviewFeatures[ndx],				0xFF*ndx, sizeof(VkPhysicalDeviceMultiviewFeatures));
		deMemset(&protectedMemoryFeatures[ndx],				0xFF*ndx, sizeof(VkPhysicalDeviceProtectedMemoryFeatures));
		deMemset(&samplerYcbcrConversionFeatures[ndx],		0xFF*ndx, sizeof(VkPhysicalDeviceSamplerYcbcrConversionFeatures));
		deMemset(&variablePointerFeatures[ndx],				0xFF*ndx, sizeof(VkPhysicalDeviceVariablePointerFeatures));
		deMemset(&scalarBlockLayoutFeatures[ndx],			0xFF*ndx, sizeof(VkPhysicalDeviceScalarBlockLayoutFeaturesEXT));

		device8BitStorageFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR;
		device8BitStorageFeatures[ndx].pNext = &deviceConditionalRenderingFeatures[ndx];

		deviceConditionalRenderingFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT;
		deviceConditionalRenderingFeatures[ndx].pNext = &device16BitStorageFeatures[ndx];

		device16BitStorageFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES;
		device16BitStorageFeatures[ndx].pNext = &deviceMultiviewFeatures[ndx];

		deviceMultiviewFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES;
		deviceMultiviewFeatures[ndx].pNext = &protectedMemoryFeatures[ndx];

		protectedMemoryFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES;
		protectedMemoryFeatures[ndx].pNext = &samplerYcbcrConversionFeatures[ndx];

		samplerYcbcrConversionFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
		samplerYcbcrConversionFeatures[ndx].pNext = &variablePointerFeatures[ndx];

		variablePointerFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES;
		variablePointerFeatures[ndx].pNext = &scalarBlockLayoutFeatures[ndx];

		scalarBlockLayoutFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT;
		scalarBlockLayoutFeatures[ndx].pNext = DE_NULL;

		deMemset(&extFeatures.features, 0xcd, sizeof(extFeatures.features));
		extFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
		extFeatures.pNext = &device8BitStorageFeatures[ndx];

		vki.getPhysicalDeviceFeatures2(physicalDevice, &extFeatures);
	}

	if ( khr_8bit_storage &&
		(device8BitStorageFeatures[0].storageBuffer8BitAccess				!= device8BitStorageFeatures[1].storageBuffer8BitAccess ||
		device8BitStorageFeatures[0].uniformAndStorageBuffer8BitAccess		!= device8BitStorageFeatures[1].uniformAndStorageBuffer8BitAccess ||
		device8BitStorageFeatures[0].storagePushConstant8					!= device8BitStorageFeatures[1].storagePushConstant8 )
		)
	{
		TCU_FAIL("Mismatch between VkPhysicalDevice8BitStorageFeatures");
	}

	if ( ext_conditional_rendering &&
		(deviceConditionalRenderingFeatures[0].conditionalRendering				!= deviceConditionalRenderingFeatures[1].conditionalRendering ||
		deviceConditionalRenderingFeatures[0].inheritedConditionalRendering		!= deviceConditionalRenderingFeatures[1].inheritedConditionalRendering )
		)
	{
		TCU_FAIL("Mismatch between VkPhysicalDeviceConditionalRenderingFeaturesEXT");
	}

	if ( khr_16bit_storage &&
		(device16BitStorageFeatures[0].storageBuffer16BitAccess				!= device16BitStorageFeatures[1].storageBuffer16BitAccess ||
		device16BitStorageFeatures[0].uniformAndStorageBuffer16BitAccess	!= device16BitStorageFeatures[1].uniformAndStorageBuffer16BitAccess ||
		device16BitStorageFeatures[0].storagePushConstant16					!= device16BitStorageFeatures[1].storagePushConstant16 ||
		device16BitStorageFeatures[0].storageInputOutput16					!= device16BitStorageFeatures[1].storageInputOutput16)
		)
	{
		TCU_FAIL("Mismatch between VkPhysicalDevice16BitStorageFeatures");
	}

	if (khr_multiview &&
		(deviceMultiviewFeatures[0].multiview					!= deviceMultiviewFeatures[1].multiview ||
		deviceMultiviewFeatures[0].multiviewGeometryShader		!= deviceMultiviewFeatures[1].multiviewGeometryShader ||
		deviceMultiviewFeatures[0].multiviewTessellationShader	!= deviceMultiviewFeatures[1].multiviewTessellationShader)
		)
	{
		TCU_FAIL("Mismatch between VkPhysicalDeviceMultiviewFeatures");
	}

	if (deviceProtectedMemory && protectedMemoryFeatures[0].protectedMemory != protectedMemoryFeatures[1].protectedMemory)
	{
		TCU_FAIL("Mismatch between VkPhysicalDeviceProtectedMemoryFeatures");
	}

	if (sampler_ycbcr_conversion && samplerYcbcrConversionFeatures[0].samplerYcbcrConversion != samplerYcbcrConversionFeatures[1].samplerYcbcrConversion)
	{
		TCU_FAIL("Mismatch between VkPhysicalDeviceSamplerYcbcrConversionFeatures");
	}

	if (variable_pointers &&
		(variablePointerFeatures[0].variablePointersStorageBuffer	!= variablePointerFeatures[1].variablePointersStorageBuffer ||
		variablePointerFeatures[0].variablePointers					!= variablePointerFeatures[1].variablePointers)
		)
	{
		TCU_FAIL("Mismatch between VkPhysicalDeviceVariablePointerFeatures");
	}
	if (scalar_block_layout &&
		(scalarBlockLayoutFeatures[0].scalarBlockLayout	!= scalarBlockLayoutFeatures[1].scalarBlockLayout))
	{
		TCU_FAIL("Mismatch between VkPhysicalDeviceScalarBlockLayoutFeaturesEXT");
	}
	if (khr_8bit_storage)
		log << TestLog::Message << device8BitStorageFeatures[0]		<< TestLog::EndMessage;
	if (ext_conditional_rendering)
		log << TestLog::Message << deviceConditionalRenderingFeatures[0]		<< TestLog::EndMessage;
	if (khr_16bit_storage)
		log << TestLog::Message << toString(device16BitStorageFeatures[0])		<< TestLog::EndMessage;
	if (khr_multiview)
		log << TestLog::Message << toString(deviceMultiviewFeatures[0])			<< TestLog::EndMessage;
	if (deviceProtectedMemory)
		log << TestLog::Message << toString(protectedMemoryFeatures[0])			<< TestLog::EndMessage;
	if (sampler_ycbcr_conversion)
		log << TestLog::Message << toString(samplerYcbcrConversionFeatures[0])	<< TestLog::EndMessage;
	if (variable_pointers)
		log << TestLog::Message << toString(variablePointerFeatures[0])			<< TestLog::EndMessage;
	if (scalar_block_layout)
		log << TestLog::Message << toString(scalarBlockLayoutFeatures[0])		<< TestLog::EndMessage;

	return tcu::TestStatus::pass("Querying device features succeeded");
}


string toString (const VkPhysicalDeviceIDProperties& value)
{
	std::ostringstream	s;
	s << "VkPhysicalDeviceIDProperties = {\n";
	s << "\tsType = " << value.sType << '\n';
	s << "\tdeviceUUID = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<deUint8>(DE_ARRAY_BEGIN(value.deviceUUID)), tcu::Format::HexIterator<deUint8>(DE_ARRAY_END(value.deviceUUID))) << '\n';
	s << "\tdriverUUID = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<deUint8>(DE_ARRAY_BEGIN(value.driverUUID)), tcu::Format::HexIterator<deUint8>(DE_ARRAY_END(value.driverUUID))) << '\n';
	s << "\tdeviceLUID = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<deUint8>(DE_ARRAY_BEGIN(value.deviceLUID)), tcu::Format::HexIterator<deUint8>(DE_ARRAY_END(value.deviceLUID))) << '\n';
	s << "\tdeviceNodeMask = " << value.deviceNodeMask << '\n';
	s << "\tdeviceLUIDValid = " << value.deviceLUIDValid << '\n';
	s << '}';
	return s.str();
}

string toString (const VkPhysicalDeviceMaintenance3Properties& value)
{
	std::ostringstream	s;
	s << "VkPhysicalDeviceMaintenance3Properties = {\n";
	s << "\tsType = " << value.sType << '\n';
	s << "\tmaxPerSetDescriptors = " << value.maxPerSetDescriptors << '\n';
	s << "\tmaxMemoryAllocationSize = " << value.maxMemoryAllocationSize << '\n';
	s << '}';
	return s.str();
}

string toString (const VkPhysicalDeviceMultiviewProperties& value)
{
	std::ostringstream	s;
	s << "VkPhysicalDeviceMultiviewProperties = {\n";
	s << "\tsType = " << value.sType << '\n';
	s << "\tmaxMultiviewViewCount = " << value.maxMultiviewViewCount << '\n';
	s << "\tmaxMultiviewInstanceIndex = " << value.maxMultiviewInstanceIndex << '\n';
	s << '}';
	return s.str();
}

string toString (const VkPhysicalDevicePointClippingProperties& value)
{
	std::ostringstream	s;
	s << "VkPhysicalDevicePointClippingProperties = {\n";
	s << "\tsType = " << value.sType << '\n';
	s << "\tpointClippingBehavior = " << value.pointClippingBehavior << '\n';
	s << '}';
	return s.str();
}

string toString (const VkPhysicalDeviceProtectedMemoryProperties& value)
{
	std::ostringstream	s;
	s << "VkPhysicalDeviceProtectedMemoryProperties = {\n";
	s << "\tsType = " << value.sType << '\n';
	s << "\tprotectedNoFault = " << value.protectedNoFault << '\n';
	s << '}';
	return s.str();
}


string toString (const VkPhysicalDeviceSubgroupProperties& value)
{
	std::ostringstream	s;
	s << "VkPhysicalDeviceSubgroupProperties = {\n";
	s << "\tsType = " << value.sType << '\n';
	s << "\tsubgroupSize = " << value.subgroupSize << '\n';
	s << "\tsupportedStages = " << getShaderStageFlagsStr(value.supportedStages) << '\n';
	s << "\tsupportedOperations = " << getSubgroupFeatureFlagsStr(value.supportedOperations) << '\n';
	s << "\tquadOperationsInAllStages = " << value.quadOperationsInAllStages << '\n';
	s << '}';
	return s.str();
}

tcu::TestStatus deviceProperties2 (Context& context)
{
	const PlatformInterface&		vkp				= context.getPlatformInterface();
	const VkPhysicalDevice			physicalDevice	= context.getPhysicalDevice();
	const Unique<VkInstance>		instance		(createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_get_physical_device_properties2"));
	const InstanceDriver			vki				(vkp, *instance);
	TestLog&						log				= context.getTestContext().getLog();
	VkPhysicalDeviceProperties		coreProperties;
	VkPhysicalDeviceProperties2		extProperties;

	extProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
	extProperties.pNext = DE_NULL;

	vki.getPhysicalDeviceProperties(physicalDevice, &coreProperties);
	vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);

	TCU_CHECK(extProperties.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2);
	TCU_CHECK(extProperties.pNext == DE_NULL);

	// We can't use memcmp() here because the structs may contain padding bytes that drivers may or may not
	// have written while writing the data and memcmp will compare them anyway, so we iterate through the
	// valid bytes for each field in the struct and compare only the valid bytes for each one.
	for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(s_physicalDevicePropertiesOffsetTable); propNdx++)
	{
		const size_t offset					= s_physicalDevicePropertiesOffsetTable[propNdx].offset;
		const size_t size					= s_physicalDevicePropertiesOffsetTable[propNdx].size;

		const deUint8* corePropertyBytes	= reinterpret_cast<deUint8*>(&coreProperties) + offset;
		const deUint8* extPropertyBytes		= reinterpret_cast<deUint8*>(&extProperties.properties) + offset;

		if (deMemCmp(corePropertyBytes, extPropertyBytes, size) != 0)
			TCU_FAIL("Mismatch between properties reported by vkGetPhysicalDeviceProperties and vkGetPhysicalDeviceProperties2");
	}

	log << TestLog::Message << extProperties.properties << TestLog::EndMessage;

	const int count = 2u;

	bool khr_external_memory_capabilities		= true;
	bool khr_multiview							= true;
	bool khr_maintenance2						= true;
	bool khr_maintenance3						= true;
	bool apiVersionSmallerThen_1_1				= (getPhysicalDeviceProperties(vki, physicalDevice).apiVersion < VK_API_VERSION_1_1);
	if (apiVersionSmallerThen_1_1)
	{
		vector<VkExtensionProperties> properties	= enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
		khr_external_memory_capabilities			= checkExtension(properties,"VK_KHR_external_memory_capabilities");
		khr_multiview								= checkExtension(properties,"VK_KHR_multiview");
		khr_maintenance2							= checkExtension(properties,"VK_KHR_maintenance2");
		khr_maintenance3							= checkExtension(properties,"VK_KHR_maintenance3");
	}

	VkPhysicalDeviceIDProperties				IDProperties[count];
	VkPhysicalDeviceMaintenance3Properties		maintenance3Properties[count];
	VkPhysicalDeviceMultiviewProperties			multiviewProperties[count];
	VkPhysicalDevicePointClippingProperties		pointClippingProperties[count];
	VkPhysicalDeviceProtectedMemoryProperties	protectedMemoryPropertiesKHR[count];
	VkPhysicalDeviceSubgroupProperties			subgroupProperties[count];

	for (int ndx = 0; ndx < count; ++ndx)
	{
		deMemset(&IDProperties[ndx],					0xFF*ndx, sizeof(VkPhysicalDeviceIDProperties				));
		deMemset(&maintenance3Properties[ndx],			0xFF*ndx, sizeof(VkPhysicalDeviceMaintenance3Properties		));
		deMemset(&multiviewProperties[ndx],				0xFF*ndx, sizeof(VkPhysicalDeviceMultiviewProperties		));
		deMemset(&pointClippingProperties[ndx],			0xFF*ndx, sizeof(VkPhysicalDevicePointClippingProperties	));
		deMemset(&protectedMemoryPropertiesKHR[ndx],	0xFF*ndx, sizeof(VkPhysicalDeviceProtectedMemoryProperties	));
		deMemset(&subgroupProperties[ndx],				0xFF*ndx, sizeof(VkPhysicalDeviceSubgroupProperties			));

		IDProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
		IDProperties[ndx].pNext = &maintenance3Properties[ndx];

		maintenance3Properties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES;
		maintenance3Properties[ndx].pNext = &multiviewProperties[ndx];

		multiviewProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES;
		multiviewProperties[ndx].pNext = &pointClippingProperties[ndx];

		pointClippingProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES;
		pointClippingProperties[ndx].pNext = &protectedMemoryPropertiesKHR[ndx];

		protectedMemoryPropertiesKHR[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES;
		protectedMemoryPropertiesKHR[ndx].pNext = &subgroupProperties[ndx];

		subgroupProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
		subgroupProperties[ndx].pNext = DE_NULL;

		extProperties.pNext = &IDProperties[ndx];

		vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);

		IDProperties[ndx].pNext						= DE_NULL;
		maintenance3Properties[ndx].pNext			= DE_NULL;
		multiviewProperties[ndx].pNext				= DE_NULL;
		pointClippingProperties[ndx].pNext			= DE_NULL;
		protectedMemoryPropertiesKHR[ndx].pNext		= DE_NULL;
		subgroupProperties[ndx].pNext				= DE_NULL;
	}

	if (khr_external_memory_capabilities)
	{
		if ((deMemCmp(IDProperties[0].deviceUUID, IDProperties[1].deviceUUID, VK_UUID_SIZE) != 0) ||
			(deMemCmp(IDProperties[0].driverUUID, IDProperties[1].driverUUID, VK_UUID_SIZE) != 0) ||
			(IDProperties[0].deviceLUIDValid	!= IDProperties[1].deviceLUIDValid))
		{
			TCU_FAIL("Mismatch between VkPhysicalDeviceIDProperties");
		}
		else if (IDProperties[0].deviceLUIDValid)
		{
			// If deviceLUIDValid is VK_FALSE, the contents of deviceLUID and deviceNodeMask are undefined
			// so thay can only be compared when deviceLUIDValid is VK_TRUE.
			if ((deMemCmp(IDProperties[0].deviceLUID, IDProperties[1].deviceLUID, VK_UUID_SIZE) != 0) ||
				(IDProperties[0].deviceNodeMask		!= IDProperties[1].deviceNodeMask))
			{
				TCU_FAIL("Mismatch between VkPhysicalDeviceIDProperties");
			}
		}
	}
	if (khr_maintenance3 &&
		((maintenance3Properties[0].maxPerSetDescriptors	!= maintenance3Properties[1].maxPerSetDescriptors) ||
		(maintenance3Properties[0].maxMemoryAllocationSize	!= maintenance3Properties[1].maxMemoryAllocationSize))
		)
	{
		TCU_FAIL("Mismatch between VkPhysicalDeviceMaintenance3Properties");
	}
	if (khr_multiview &&
		((multiviewProperties[0].maxMultiviewViewCount		!= multiviewProperties[1].maxMultiviewViewCount) ||
		(multiviewProperties[0].maxMultiviewInstanceIndex	!= multiviewProperties[1].maxMultiviewInstanceIndex))
		)
	{
		TCU_FAIL("Mismatch between VkPhysicalDeviceMultiviewProperties");
	}
	if (khr_maintenance2 &&
		(pointClippingProperties[0].pointClippingBehavior != pointClippingProperties[1].pointClippingBehavior))
	{
		TCU_FAIL("Mismatch between VkPhysicalDevicePointClippingProperties");
	}
	if (!apiVersionSmallerThen_1_1)
	{
		if(protectedMemoryPropertiesKHR[0].protectedNoFault != protectedMemoryPropertiesKHR[1].protectedNoFault)
		{
			TCU_FAIL("Mismatch between VkPhysicalDeviceProtectedMemoryProperties");
		}
		if ((subgroupProperties[0].subgroupSize					!= subgroupProperties[1].subgroupSize) ||
			(subgroupProperties[0].supportedStages				!= subgroupProperties[1].supportedStages) ||
			(subgroupProperties[0].supportedOperations			!= subgroupProperties[1].supportedOperations) ||
			(subgroupProperties[0].quadOperationsInAllStages	!= subgroupProperties[1].quadOperationsInAllStages))
		{
			TCU_FAIL("Mismatch between VkPhysicalDeviceSubgroupProperties");
		}
	}

	if (khr_external_memory_capabilities)
		log << TestLog::Message << toString(IDProperties[0])					<< TestLog::EndMessage;
	if (khr_maintenance3)
		log << TestLog::Message << toString(maintenance3Properties[0])			<< TestLog::EndMessage;
	if (khr_multiview)
		log << TestLog::Message << toString(multiviewProperties[0])				<< TestLog::EndMessage;
	if (khr_maintenance2)
		log << TestLog::Message << toString(pointClippingProperties[0])			<< TestLog::EndMessage;
	if (!apiVersionSmallerThen_1_1)
	{
		log << TestLog::Message << toString(protectedMemoryPropertiesKHR[0])	<< TestLog::EndMessage
			<< TestLog::Message << toString(subgroupProperties[0])				<< TestLog::EndMessage;
	}

	const vector<VkExtensionProperties>	extensions = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);

	if (isExtensionSupported(extensions, RequiredExtension("VK_KHR_push_descriptor")))
	{
		VkPhysicalDevicePushDescriptorPropertiesKHR		pushDescriptorProperties[count];

		for (int ndx = 0; ndx < count; ++ndx)
		{
			deMemset(&pushDescriptorProperties[ndx], 0, sizeof(VkPhysicalDevicePushDescriptorPropertiesKHR));

			pushDescriptorProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR;
			pushDescriptorProperties[ndx].pNext	= DE_NULL;

			extProperties.pNext = &pushDescriptorProperties[ndx];

			vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);

			pushDescriptorProperties[ndx].pNext = DE_NULL;
		}

		if (deMemCmp(&pushDescriptorProperties[0], &pushDescriptorProperties[1], sizeof(VkPhysicalDevicePushDescriptorPropertiesKHR)) != 0)
		{
			TCU_FAIL("Mismatch in vkGetPhysicalDeviceProperties2 in VkPhysicalDevicePushDescriptorPropertiesKHR ");
		}

		log << TestLog::Message << toString(pushDescriptorProperties[0]) << TestLog::EndMessage;

		if (pushDescriptorProperties[0].maxPushDescriptors < 32)
		{
			TCU_FAIL("VkPhysicalDevicePushDescriptorPropertiesKHR.maxPushDescriptors must be at least 32");
		}
	}
	if (isExtensionSupported(extensions, RequiredExtension("VK_KHR_shader_float_controls")))
	{
		VkPhysicalDeviceFloatControlsPropertiesKHR floatControlsProperties[count];

		for (int ndx = 0; ndx < count; ++ndx)
		{
			deMemset(&floatControlsProperties[ndx], 0xFF, sizeof(VkPhysicalDeviceFloatControlsPropertiesKHR));
			floatControlsProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR;
			floatControlsProperties[ndx].pNext = DE_NULL;

			extProperties.pNext = &floatControlsProperties[ndx];

			vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
		}

		if (deMemCmp(&floatControlsProperties[0], &floatControlsProperties[1], sizeof(VkPhysicalDeviceFloatControlsPropertiesKHR)) != 0)
		{
			TCU_FAIL("Mismatch in VkPhysicalDeviceFloatControlsPropertiesKHR");
		}

		log << TestLog::Message << toString(floatControlsProperties[0]) << TestLog::EndMessage;
	}

	if (isExtensionSupported(extensions, RequiredExtension("VK_KHR_depth_stencil_resolve")))
	{
		VkPhysicalDeviceDepthStencilResolvePropertiesKHR  dsResolveProperties[count];

		for (int ndx = 0; ndx < count; ++ndx)
		{
			deMemset(&dsResolveProperties[ndx], 0xFF, sizeof(VkPhysicalDeviceDepthStencilResolvePropertiesKHR));
			dsResolveProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR;
			dsResolveProperties[ndx].pNext = DE_NULL;

			extProperties.pNext = &dsResolveProperties[ndx];

			vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
		}

		if (deMemCmp(&dsResolveProperties[0], &dsResolveProperties[1], sizeof(VkPhysicalDeviceDepthStencilResolvePropertiesKHR)) != 0)
		{
			TCU_FAIL("Mismatch in VkPhysicalDeviceDepthStencilResolvePropertiesKHR");
		}

		log << TestLog::Message << toString(dsResolveProperties[0]) << TestLog::EndMessage;
	}

	return tcu::TestStatus::pass("Querying device properties succeeded");
}

string toString (const VkFormatProperties2& value)
{
	std::ostringstream	s;
	s << "VkFormatProperties2 = {\n";
	s << "\tsType = " << value.sType << '\n';
	s << "\tformatProperties = {\n";
	s << "\tlinearTilingFeatures = " << getFormatFeatureFlagsStr(value.formatProperties.linearTilingFeatures) << '\n';
	s << "\toptimalTilingFeatures = " << getFormatFeatureFlagsStr(value.formatProperties.optimalTilingFeatures) << '\n';
	s << "\tbufferFeatures = " << getFormatFeatureFlagsStr(value.formatProperties.bufferFeatures) << '\n';
	s << "\t}";
	s << "}";
	return s.str();
}

tcu::TestStatus deviceFormatProperties2 (Context& context)
{
	const PlatformInterface&		vkp				= context.getPlatformInterface();
	const VkPhysicalDevice			physicalDevice	= context.getPhysicalDevice();
	const Unique<VkInstance>		instance		(createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_get_physical_device_properties2"));
	const InstanceDriver			vki				(vkp, *instance);
	TestLog&						log				= context.getTestContext().getLog();

	for (int formatNdx = 0; formatNdx < VK_CORE_FORMAT_LAST; ++formatNdx)
	{
		const VkFormat			format			= (VkFormat)formatNdx;
		VkFormatProperties		coreProperties;
		VkFormatProperties2		extProperties;

		deMemset(&coreProperties, 0xcd, sizeof(VkFormatProperties));
		deMemset(&extProperties, 0xcd, sizeof(VkFormatProperties2));

		extProperties.sType	= VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
		extProperties.pNext = DE_NULL;

		vki.getPhysicalDeviceFormatProperties(physicalDevice, format, &coreProperties);
		vki.getPhysicalDeviceFormatProperties2(physicalDevice, format, &extProperties);

		TCU_CHECK(extProperties.sType == VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2);
		TCU_CHECK(extProperties.pNext == DE_NULL);

	if (deMemCmp(&coreProperties, &extProperties.formatProperties, sizeof(VkFormatProperties)) != 0)
		TCU_FAIL("Mismatch between format properties reported by vkGetPhysicalDeviceFormatProperties and vkGetPhysicalDeviceFormatProperties2");

	log << TestLog::Message << toString (extProperties) << TestLog::EndMessage;
	}

	return tcu::TestStatus::pass("Querying device format properties succeeded");
}

string toString (const VkQueueFamilyProperties2& value)
{
	std::ostringstream	s;
	s << "VkQueueFamilyProperties2 = {\n";
	s << "\tsType = " << value.sType << '\n';
	s << "\tqueueFamilyProperties = " << value.queueFamilyProperties << '\n';
	s << '}';
	return s.str();
}

tcu::TestStatus deviceQueueFamilyProperties2 (Context& context)
{
	const PlatformInterface&		vkp						= context.getPlatformInterface();
	const VkPhysicalDevice			physicalDevice			= context.getPhysicalDevice();
	const Unique<VkInstance>		instance				(createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_get_physical_device_properties2"));
	const InstanceDriver			vki						(vkp, *instance);
	TestLog&						log						= context.getTestContext().getLog();
	deUint32						numCoreQueueFamilies	= ~0u;
	deUint32						numExtQueueFamilies		= ~0u;

	vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numCoreQueueFamilies, DE_NULL);
	vki.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &numExtQueueFamilies, DE_NULL);

	TCU_CHECK_MSG(numCoreQueueFamilies == numExtQueueFamilies, "Different number of queue family properties reported");
	TCU_CHECK(numCoreQueueFamilies > 0);

	{
		std::vector<VkQueueFamilyProperties>		coreProperties	(numCoreQueueFamilies);
		std::vector<VkQueueFamilyProperties2>		extProperties	(numExtQueueFamilies);

		deMemset(&coreProperties[0], 0xcd, sizeof(VkQueueFamilyProperties)*numCoreQueueFamilies);
		deMemset(&extProperties[0], 0xcd, sizeof(VkQueueFamilyProperties2)*numExtQueueFamilies);

		for (size_t ndx = 0; ndx < extProperties.size(); ++ndx)
		{
			extProperties[ndx].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
			extProperties[ndx].pNext = DE_NULL;
		}

		vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numCoreQueueFamilies, &coreProperties[0]);
		vki.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &numExtQueueFamilies, &extProperties[0]);

		TCU_CHECK((size_t)numCoreQueueFamilies == coreProperties.size());
		TCU_CHECK((size_t)numExtQueueFamilies == extProperties.size());
		DE_ASSERT(numCoreQueueFamilies == numExtQueueFamilies);

		for (size_t ndx = 0; ndx < extProperties.size(); ++ndx)
		{
			TCU_CHECK(extProperties[ndx].sType == VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2);
			TCU_CHECK(extProperties[ndx].pNext == DE_NULL);

			if (deMemCmp(&coreProperties[ndx], &extProperties[ndx].queueFamilyProperties, sizeof(VkQueueFamilyProperties)) != 0)
				TCU_FAIL("Mismatch between format properties reported by vkGetPhysicalDeviceQueueFamilyProperties and vkGetPhysicalDeviceQueueFamilyProperties2");

			log << TestLog::Message << " queueFamilyNdx = " << ndx <<TestLog::EndMessage
			<< TestLog::Message << toString(extProperties[ndx]) << TestLog::EndMessage;
		}
	}

	return tcu::TestStatus::pass("Querying device queue family properties succeeded");
}

tcu::TestStatus deviceMemoryProperties2 (Context& context)
{
	const PlatformInterface&			vkp				= context.getPlatformInterface();
	const VkPhysicalDevice				physicalDevice	= context.getPhysicalDevice();
	const Unique<VkInstance>			instance		(createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_get_physical_device_properties2"));
	const InstanceDriver				vki				(vkp, *instance);
	TestLog&							log				= context.getTestContext().getLog();
	VkPhysicalDeviceMemoryProperties	coreProperties;
	VkPhysicalDeviceMemoryProperties2	extProperties;

	deMemset(&coreProperties, 0xcd, sizeof(VkPhysicalDeviceMemoryProperties));
	deMemset(&extProperties, 0xcd, sizeof(VkPhysicalDeviceMemoryProperties2));

	extProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
	extProperties.pNext = DE_NULL;

	vki.getPhysicalDeviceMemoryProperties(physicalDevice, &coreProperties);
	vki.getPhysicalDeviceMemoryProperties2(physicalDevice, &extProperties);

	TCU_CHECK(extProperties.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2);
	TCU_CHECK(extProperties.pNext == DE_NULL);

	if (deMemCmp(&coreProperties, &extProperties.memoryProperties, sizeof(VkPhysicalDeviceMemoryProperties)) != 0)
		TCU_FAIL("Mismatch between properties reported by vkGetPhysicalDeviceMemoryProperties and vkGetPhysicalDeviceMemoryProperties2");

	log << TestLog::Message << extProperties << TestLog::EndMessage;

	return tcu::TestStatus::pass("Querying device memory properties succeeded");
}

tcu::TestStatus imageFormatProperties2 (Context& context, const VkFormat format, const VkImageType imageType, const VkImageTiling tiling)
{
	if (isYCbCrFormat(format))
		// check if Ycbcr format enums are valid given the version and extensions
		checkYcbcrApiSupport(context);

	TestLog&						log				= context.getTestContext().getLog();

	const PlatformInterface&		vkp				= context.getPlatformInterface();
	const VkPhysicalDevice			physicalDevice	= context.getPhysicalDevice();
	const Unique<VkInstance>		instance		(createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_get_physical_device_properties2"));
	const InstanceDriver			vki				(vkp, *instance);

	const VkImageCreateFlags		ycbcrFlags		= isYCbCrFormat(format) ? (VkImageCreateFlags)VK_IMAGE_CREATE_DISJOINT_BIT_KHR : (VkImageCreateFlags)0u;
	const VkImageUsageFlags			allUsageFlags	= VK_IMAGE_USAGE_TRANSFER_SRC_BIT
													| VK_IMAGE_USAGE_TRANSFER_DST_BIT
													| VK_IMAGE_USAGE_SAMPLED_BIT
													| VK_IMAGE_USAGE_STORAGE_BIT
													| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
													| VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
													| VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
													| VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
	const VkImageCreateFlags		allCreateFlags	= VK_IMAGE_CREATE_SPARSE_BINDING_BIT
													| VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT
													| VK_IMAGE_CREATE_SPARSE_ALIASED_BIT
													| VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
													| VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT
													| ycbcrFlags;

	for (VkImageUsageFlags curUsageFlags = (VkImageUsageFlags)1; curUsageFlags <= allUsageFlags; curUsageFlags++)
	{
		for (VkImageCreateFlags curCreateFlags = 0; curCreateFlags <= allCreateFlags; curCreateFlags++)
		{
			const VkPhysicalDeviceImageFormatInfo2	imageFormatInfo	=
			{
				VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
				DE_NULL,
				format,
				imageType,
				tiling,
				curUsageFlags,
				curCreateFlags
			};

			VkImageFormatProperties						coreProperties;
			VkImageFormatProperties2					extProperties;
			VkResult									coreResult;
			VkResult									extResult;

			deMemset(&coreProperties, 0xcd, sizeof(VkImageFormatProperties));
			deMemset(&extProperties, 0xcd, sizeof(VkImageFormatProperties2));

			extProperties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
			extProperties.pNext = DE_NULL;

			coreResult	= vki.getPhysicalDeviceImageFormatProperties(physicalDevice, imageFormatInfo.format, imageFormatInfo.type, imageFormatInfo.tiling, imageFormatInfo.usage, imageFormatInfo.flags, &coreProperties);
			extResult	= vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &imageFormatInfo, &extProperties);

			TCU_CHECK(extProperties.sType == VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2);
			TCU_CHECK(extProperties.pNext == DE_NULL);

			if ((coreResult != extResult) ||
				(deMemCmp(&coreProperties, &extProperties.imageFormatProperties, sizeof(VkImageFormatProperties)) != 0))
			{
				log << TestLog::Message << "ERROR: device mismatch with query " << imageFormatInfo << TestLog::EndMessage
					<< TestLog::Message << "vkGetPhysicalDeviceImageFormatProperties() returned " << coreResult << ", " << coreProperties << TestLog::EndMessage
					<< TestLog::Message << "vkGetPhysicalDeviceImageFormatProperties2() returned " << extResult << ", " << extProperties << TestLog::EndMessage;
				TCU_FAIL("Mismatch between image format properties reported by vkGetPhysicalDeviceImageFormatProperties and vkGetPhysicalDeviceImageFormatProperties2");
			}
		}
	}

	return tcu::TestStatus::pass("Querying image format properties succeeded");
}

tcu::TestStatus sparseImageFormatProperties2 (Context& context, const VkFormat format, const VkImageType imageType, const VkImageTiling tiling)
{
	TestLog&						log				= context.getTestContext().getLog();

	const PlatformInterface&		vkp				= context.getPlatformInterface();
	const VkPhysicalDevice			physicalDevice	= context.getPhysicalDevice();
	const Unique<VkInstance>		instance		(createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_get_physical_device_properties2"));
	const InstanceDriver			vki				(vkp, *instance);

	const VkImageUsageFlags			allUsageFlags	= VK_IMAGE_USAGE_TRANSFER_SRC_BIT
													| VK_IMAGE_USAGE_TRANSFER_DST_BIT
													| VK_IMAGE_USAGE_SAMPLED_BIT
													| VK_IMAGE_USAGE_STORAGE_BIT
													| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
													| VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
													| VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
													| VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;

	for (deUint32 sampleCountBit = VK_SAMPLE_COUNT_1_BIT; sampleCountBit <= VK_SAMPLE_COUNT_64_BIT; sampleCountBit = (sampleCountBit << 1u))
	{
		for (VkImageUsageFlags curUsageFlags = (VkImageUsageFlags)1; curUsageFlags <= allUsageFlags; curUsageFlags++)
		{
			const VkPhysicalDeviceSparseImageFormatInfo2	imageFormatInfo	=
			{
				VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2,
				DE_NULL,
				format,
				imageType,
				(VkSampleCountFlagBits)sampleCountBit,
				curUsageFlags,
				tiling,
			};

			deUint32										numCoreProperties	= ~0u;
			deUint32										numExtProperties	= ~0u;

			// Query count
			vki.getPhysicalDeviceSparseImageFormatProperties(physicalDevice, imageFormatInfo.format, imageFormatInfo.type, imageFormatInfo.samples, imageFormatInfo.usage, imageFormatInfo.tiling, &numCoreProperties, DE_NULL);
			vki.getPhysicalDeviceSparseImageFormatProperties2(physicalDevice, &imageFormatInfo, &numExtProperties, DE_NULL);

			if (numCoreProperties != numExtProperties)
			{
				log << TestLog::Message << "ERROR: different number of properties reported for " << imageFormatInfo << TestLog::EndMessage;
				TCU_FAIL("Mismatch in reported property count");
			}

			if (numCoreProperties > 0)
			{
				std::vector<VkSparseImageFormatProperties>		coreProperties	(numCoreProperties);
				std::vector<VkSparseImageFormatProperties2>		extProperties	(numExtProperties);

				deMemset(&coreProperties[0], 0xcd, sizeof(VkSparseImageFormatProperties)*numCoreProperties);
				deMemset(&extProperties[0], 0xcd, sizeof(VkSparseImageFormatProperties2)*numExtProperties);

				for (deUint32 ndx = 0; ndx < numExtProperties; ++ndx)
				{
					extProperties[ndx].sType = VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2;
					extProperties[ndx].pNext = DE_NULL;
				}

				vki.getPhysicalDeviceSparseImageFormatProperties(physicalDevice, imageFormatInfo.format, imageFormatInfo.type, imageFormatInfo.samples, imageFormatInfo.usage, imageFormatInfo.tiling, &numCoreProperties, &coreProperties[0]);
				vki.getPhysicalDeviceSparseImageFormatProperties2(physicalDevice, &imageFormatInfo, &numExtProperties, &extProperties[0]);

				TCU_CHECK((size_t)numCoreProperties == coreProperties.size());
				TCU_CHECK((size_t)numExtProperties == extProperties.size());

				for (deUint32 ndx = 0; ndx < numCoreProperties; ++ndx)
				{
					TCU_CHECK(extProperties[ndx].sType == VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2);
					TCU_CHECK(extProperties[ndx].pNext == DE_NULL);

					if ((deMemCmp(&coreProperties[ndx], &extProperties[ndx].properties, sizeof(VkSparseImageFormatProperties)) != 0))
					{
						log << TestLog::Message << "ERROR: device mismatch with query " << imageFormatInfo << " property " << ndx << TestLog::EndMessage
							<< TestLog::Message << "vkGetPhysicalDeviceSparseImageFormatProperties() returned " << coreProperties[ndx] << TestLog::EndMessage
							<< TestLog::Message << "vkGetPhysicalDeviceSparseImageFormatProperties2() returned " << extProperties[ndx] << TestLog::EndMessage;
						TCU_FAIL("Mismatch between image format properties reported by vkGetPhysicalDeviceSparseImageFormatProperties and vkGetPhysicalDeviceSparseImageFormatProperties2");
					}
				}
			}
		}
	}

	return tcu::TestStatus::pass("Querying sparse image format properties succeeded");
}

tcu::TestStatus execImageFormatTest (Context& context, ImageFormatPropertyCase testCase)
{
	return testCase.testFunction(context, testCase.format, testCase.imageType, testCase.tiling);
}

void createImageFormatTypeTilingTests (tcu::TestCaseGroup* testGroup, ImageFormatPropertyCase params)
{
	DE_ASSERT(params.format == VK_FORMAT_UNDEFINED);

	static const struct
	{
		VkFormat								begin;
		VkFormat								end;
		ImageFormatPropertyCase					params;
	} s_formatRanges[] =
	{
		// core formats
		{ (VkFormat)(VK_FORMAT_UNDEFINED + 1),	VK_CORE_FORMAT_LAST,										params },

		// YCbCr formats
		{ VK_FORMAT_G8B8G8R8_422_UNORM_KHR,		(VkFormat)(VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR + 1),	params }
	};

	for (int rangeNdx = 0; rangeNdx < DE_LENGTH_OF_ARRAY(s_formatRanges); ++rangeNdx)
	{
		const VkFormat								rangeBegin		= s_formatRanges[rangeNdx].begin;
		const VkFormat								rangeEnd		= s_formatRanges[rangeNdx].end;

		for (VkFormat format = rangeBegin; format != rangeEnd; format = (VkFormat)(format+1))
		{
			const bool			isYCbCr		= isYCbCrFormat(format);
			const bool			isSparse	= (params.testFunction == sparseImageFormatProperties2);

			if (isYCbCr && isSparse)
				continue;

			if (isYCbCr && params.imageType != VK_IMAGE_TYPE_2D)
				continue;

			const char* const	enumName	= getFormatName(format);
			const string		caseName	= de::toLower(string(enumName).substr(10));

			params.format = format;

			addFunctionCase(testGroup, caseName, enumName, execImageFormatTest, params);
		}
	}
}

void createImageFormatTypeTests (tcu::TestCaseGroup* testGroup, ImageFormatPropertyCase params)
{
	DE_ASSERT(params.tiling == VK_IMAGE_TILING_LAST);

	testGroup->addChild(createTestGroup(testGroup->getTestContext(), "optimal",	"",	createImageFormatTypeTilingTests, ImageFormatPropertyCase(params.testFunction, VK_FORMAT_UNDEFINED, params.imageType, VK_IMAGE_TILING_OPTIMAL)));
	testGroup->addChild(createTestGroup(testGroup->getTestContext(), "linear",	"",	createImageFormatTypeTilingTests, ImageFormatPropertyCase(params.testFunction, VK_FORMAT_UNDEFINED, params.imageType, VK_IMAGE_TILING_LINEAR)));
}

void createImageFormatTests (tcu::TestCaseGroup* testGroup, ImageFormatPropertyCase::Function testFunction)
{
	testGroup->addChild(createTestGroup(testGroup->getTestContext(), "1d", "", createImageFormatTypeTests, ImageFormatPropertyCase(testFunction, VK_FORMAT_UNDEFINED, VK_IMAGE_TYPE_1D, VK_IMAGE_TILING_LAST)));
	testGroup->addChild(createTestGroup(testGroup->getTestContext(), "2d", "", createImageFormatTypeTests, ImageFormatPropertyCase(testFunction, VK_FORMAT_UNDEFINED, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_LAST)));
	testGroup->addChild(createTestGroup(testGroup->getTestContext(), "3d", "", createImageFormatTypeTests, ImageFormatPropertyCase(testFunction, VK_FORMAT_UNDEFINED, VK_IMAGE_TYPE_3D, VK_IMAGE_TILING_LAST)));
}


// Android CTS -specific tests

namespace android
{

void checkExtensions (tcu::ResultCollector& results, const set<string>& allowedExtensions, const vector<VkExtensionProperties>& reportedExtensions)
{
	for (vector<VkExtensionProperties>::const_iterator extension = reportedExtensions.begin(); extension != reportedExtensions.end(); ++extension)
	{
		const string	extensionName	(extension->extensionName);
		const bool		mustBeKnown		= de::beginsWith(extensionName, "VK_GOOGLE_")	||
										  de::beginsWith(extensionName, "VK_ANDROID_");

		if (mustBeKnown && !de::contains(allowedExtensions, extensionName))
			results.fail("Unknown extension: " + extensionName);
	}
}

tcu::TestStatus testNoUnknownExtensions (Context& context)
{
	TestLog&				log					= context.getTestContext().getLog();
	tcu::ResultCollector	results				(log);
	set<string>				allowedInstanceExtensions;
	set<string>				allowedDeviceExtensions;

	// All known extensions should be added to allowedExtensions:
	// allowedExtensions.insert("VK_GOOGLE_extension1");
	allowedDeviceExtensions.insert("VK_ANDROID_external_memory_android_hardware_buffer");
	allowedDeviceExtensions.insert("VK_GOOGLE_display_timing");

	// Instance extensions
	checkExtensions(results,
					allowedInstanceExtensions,
					enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL));

	// Extensions exposed by instance layers
	{
		const vector<VkLayerProperties>	layers	= enumerateInstanceLayerProperties(context.getPlatformInterface());

		for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
		{
			checkExtensions(results,
							allowedInstanceExtensions,
							enumerateInstanceExtensionProperties(context.getPlatformInterface(), layer->layerName));
		}
	}

	// Device extensions
	checkExtensions(results,
					allowedDeviceExtensions,
					enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), DE_NULL));

	// Extensions exposed by device layers
	{
		const vector<VkLayerProperties>	layers	= enumerateDeviceLayerProperties(context.getInstanceInterface(), context.getPhysicalDevice());

		for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
		{
			checkExtensions(results,
							allowedDeviceExtensions,
							enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), layer->layerName));
		}
	}

	return tcu::TestStatus(results.getResult(), results.getMessage());
}

tcu::TestStatus testNoLayers (Context& context)
{
	TestLog&				log		= context.getTestContext().getLog();
	tcu::ResultCollector	results	(log);

	{
		const vector<VkLayerProperties>	layers	= enumerateInstanceLayerProperties(context.getPlatformInterface());

		for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
			results.fail(string("Instance layer enumerated: ") + layer->layerName);
	}

	{
		const vector<VkLayerProperties>	layers	= enumerateDeviceLayerProperties(context.getInstanceInterface(), context.getPhysicalDevice());

		for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
			results.fail(string("Device layer enumerated: ") + layer->layerName);
	}

	return tcu::TestStatus(results.getResult(), results.getMessage());
}

tcu::TestStatus testMandatoryExtensions (Context& context)
{
	TestLog&				log		= context.getTestContext().getLog();
	tcu::ResultCollector	results	(log);

	// Instance extensions
	{
		static const char*					mandatoryExtensions[]	=
		{
			"VK_KHR_get_physical_device_properties2",
		};
		const vector<VkExtensionProperties>	extensions				= enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL);

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(mandatoryExtensions); ++ndx)
		{
			if (!isInstanceExtensionSupported(context.getUsedApiVersion(), extensions, RequiredExtension(mandatoryExtensions[ndx])))
				results.fail(string(mandatoryExtensions[ndx]) + " is not supported");
		}
	}

	// Device extensions
	{
		static const char*					mandatoryExtensions[]	=
		{
			"VK_KHR_maintenance1",
		};
		const vector<VkExtensionProperties>	extensions				= enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), DE_NULL);

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(mandatoryExtensions); ++ndx)
		{
			if (!isDeviceExtensionSupported(context.getUsedApiVersion(), extensions, RequiredExtension(mandatoryExtensions[ndx])))
				results.fail(string(mandatoryExtensions[ndx]) + " is not supported");
		}
	}

	return tcu::TestStatus(results.getResult(), results.getMessage());
}

} // android

} // anonymous

tcu::TestCaseGroup* createFeatureInfoTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup>	infoTests	(new tcu::TestCaseGroup(testCtx, "info", "Platform Information Tests"));

	{
		de::MovePtr<tcu::TestCaseGroup> instanceInfoTests	(new tcu::TestCaseGroup(testCtx, "instance", "Instance Information Tests"));

		addFunctionCase(instanceInfoTests.get(), "physical_devices",		"Physical devices",			enumeratePhysicalDevices);
		addFunctionCase(instanceInfoTests.get(), "physical_device_groups",	"Physical devices Groups",	enumeratePhysicalDeviceGroups);
		addFunctionCase(instanceInfoTests.get(), "layers",					"Layers",					enumerateInstanceLayers);
		addFunctionCase(instanceInfoTests.get(), "extensions",				"Extensions",				enumerateInstanceExtensions);

		infoTests->addChild(instanceInfoTests.release());
	}

	{
		de::MovePtr<tcu::TestCaseGroup> deviceInfoTests	(new tcu::TestCaseGroup(testCtx, "device", "Device Information Tests"));

		addFunctionCase(deviceInfoTests.get(), "features",					"Device Features",			deviceFeatures);
		addFunctionCase(deviceInfoTests.get(), "properties",				"Device Properties",		deviceProperties);
		addFunctionCase(deviceInfoTests.get(), "queue_family_properties",	"Queue family properties",	deviceQueueFamilyProperties);
		addFunctionCase(deviceInfoTests.get(), "memory_properties",			"Memory properties",		deviceMemoryProperties);
		addFunctionCase(deviceInfoTests.get(), "layers",					"Layers",					enumerateDeviceLayers);
		addFunctionCase(deviceInfoTests.get(), "extensions",				"Extensions",				enumerateDeviceExtensions);
		addFunctionCase(deviceInfoTests.get(), "no_khx_extensions",			"KHX extensions",			testNoKhxExtensions);

		infoTests->addChild(deviceInfoTests.release());
	}

	{
		de::MovePtr<tcu::TestCaseGroup> deviceGroupInfoTests(new tcu::TestCaseGroup(testCtx, "device_group", "Device Group Information Tests"));

		addFunctionCase(deviceGroupInfoTests.get(), "peer_memory_features",	"Device Group peer memory features",				deviceGroupPeerMemoryFeatures);

		infoTests->addChild(deviceGroupInfoTests.release());
	}

	infoTests->addChild(createTestGroup(testCtx, "format_properties",		"VkGetPhysicalDeviceFormatProperties() Tests",		createFormatTests));
	infoTests->addChild(createTestGroup(testCtx, "image_format_properties",	"VkGetPhysicalDeviceImageFormatProperties() Tests",	createImageFormatTests,	imageFormatProperties));

	{
		de::MovePtr<tcu::TestCaseGroup> extendedPropertiesTests (new tcu::TestCaseGroup(testCtx, "get_physical_device_properties2", "VK_KHR_get_physical_device_properties2"));

		addFunctionCase(extendedPropertiesTests.get(), "features",					"Extended Device Features",					deviceFeatures2);
		addFunctionCase(extendedPropertiesTests.get(), "properties",				"Extended Device Properties",				deviceProperties2);
		addFunctionCase(extendedPropertiesTests.get(), "format_properties",			"Extended Device Format Properties",		deviceFormatProperties2);
		addFunctionCase(extendedPropertiesTests.get(), "queue_family_properties",	"Extended Device Queue Family Properties",	deviceQueueFamilyProperties2);
		addFunctionCase(extendedPropertiesTests.get(), "memory_properties",			"Extended Device Memory Properties",		deviceMemoryProperties2);

		infoTests->addChild(extendedPropertiesTests.release());
	}

	infoTests->addChild(createTestGroup(testCtx, "image_format_properties2",		"VkGetPhysicalDeviceImageFormatProperties2() Tests",		createImageFormatTests, imageFormatProperties2));
	infoTests->addChild(createTestGroup(testCtx, "sparse_image_format_properties2",	"VkGetPhysicalDeviceSparseImageFormatProperties2() Tests",	createImageFormatTests, sparseImageFormatProperties2));

	{
		de::MovePtr<tcu::TestCaseGroup>	androidTests	(new tcu::TestCaseGroup(testCtx, "android", "Android CTS Tests"));

		addFunctionCase(androidTests.get(),	"mandatory_extensions",		"Test that all mandatory extensions are supported",	android::testMandatoryExtensions);
		addFunctionCase(androidTests.get(), "no_unknown_extensions",	"Test for unknown device or instance extensions",	android::testNoUnknownExtensions);
		addFunctionCase(androidTests.get(), "no_layers",				"Test that no layers are enumerated",				android::testNoLayers);

		infoTests->addChild(androidTests.release());
	}

	return infoTests.release();
}

} // api
} // vkt
