1/*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 Google Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Api Feature Query tests
22 *//*--------------------------------------------------------------------*/
23
24#include "vktApiFeatureInfo.hpp"
25
26#include "vktTestCaseUtil.hpp"
27#include "vktTestGroupUtil.hpp"
28#include "vktCustomInstancesDevices.hpp"
29
30#include "vkPlatform.hpp"
31#include "vkStrUtil.hpp"
32#include "vkRef.hpp"
33#include "vkRefUtil.hpp"
34#include "vkDeviceUtil.hpp"
35#include "vkSafetyCriticalUtil.hpp"
36#include "vkQueryUtil.hpp"
37#include "vkImageUtil.hpp"
38#include "vkApiVersion.hpp"
39
40#include "tcuTestLog.hpp"
41#include "tcuFormatUtil.hpp"
42#include "tcuTextureUtil.hpp"
43#include "tcuResultCollector.hpp"
44#include "tcuCommandLine.hpp"
45
46#include "deUniquePtr.hpp"
47#include "deString.h"
48#include "deStringUtil.hpp"
49#include "deSTLUtil.hpp"
50#include "deMemory.h"
51#include "deMath.h"
52
53#include <vector>
54#include <set>
55#include <string>
56#include <limits>
57
58namespace vkt
59{
60namespace api
61{
62namespace
63{
64
65#include "vkApiExtensionDependencyInfo.inl"
66
67using namespace vk;
68using std::vector;
69using std::set;
70using std::string;
71using tcu::TestLog;
72using tcu::ScopedLogSection;
73
74const deUint32 DEUINT32_MAX = std::numeric_limits<deUint32>::max();
75
76enum
77{
78	GUARD_SIZE								= 0x20,			//!< Number of bytes to check
79	GUARD_VALUE								= 0xcd,			//!< Data pattern
80};
81
82static const VkDeviceSize MINIMUM_REQUIRED_IMAGE_RESOURCE_SIZE =	(1LLU<<31);	//!< Minimum value for VkImageFormatProperties::maxResourceSize (2GiB)
83
84enum LimitFormat
85{
86	LIMIT_FORMAT_SIGNED_INT,
87	LIMIT_FORMAT_UNSIGNED_INT,
88	LIMIT_FORMAT_FLOAT,
89	LIMIT_FORMAT_DEVICE_SIZE,
90	LIMIT_FORMAT_BITMASK,
91
92	LIMIT_FORMAT_LAST
93};
94
95enum LimitType
96{
97	LIMIT_TYPE_MIN,
98	LIMIT_TYPE_MAX,
99	LIMIT_TYPE_NONE,
100
101	LIMIT_TYPE_LAST
102};
103
104#define LIMIT(_X_)		DE_OFFSET_OF(VkPhysicalDeviceLimits, _X_), (const char*)(#_X_)
105#define FEATURE(_X_)	DE_OFFSET_OF(VkPhysicalDeviceFeatures, _X_)
106
107bool validateFeatureLimits(VkPhysicalDeviceProperties* properties, VkPhysicalDeviceFeatures* features, TestLog& log)
108{
109	bool						limitsOk				= true;
110	VkPhysicalDeviceLimits*		limits					= &properties->limits;
111	deUint32					shaderStages			= 3;
112	deUint32					maxPerStageResourcesMin	= deMin32(128,	limits->maxPerStageDescriptorUniformBuffers		+
113																		limits->maxPerStageDescriptorStorageBuffers		+
114																		limits->maxPerStageDescriptorSampledImages		+
115																		limits->maxPerStageDescriptorStorageImages		+
116																		limits->maxPerStageDescriptorInputAttachments	+
117																		limits->maxColorAttachments);
118
119	if (features->tessellationShader)
120	{
121		shaderStages += 2;
122	}
123
124	if (features->geometryShader)
125	{
126		shaderStages++;
127	}
128
129	struct FeatureLimitTable
130	{
131		deUint32		offset;
132		const char*		name;
133		deUint32		uintVal;			//!< Format is UNSIGNED_INT
134		deInt32			intVal;				//!< Format is SIGNED_INT
135		deUint64		deviceSizeVal;		//!< Format is DEVICE_SIZE
136		float			floatVal;			//!< Format is FLOAT
137		LimitFormat		format;
138		LimitType		type;
139		deInt32			unsuppTableNdx;
140		deBool			pot;
141	} featureLimitTable[] =   //!< Based on 1.0.28 Vulkan spec
142	{
143		{ LIMIT(maxImageDimension1D),								4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
144		{ LIMIT(maxImageDimension2D),								4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1, false },
145		{ LIMIT(maxImageDimension3D),								256, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
146		{ LIMIT(maxImageDimensionCube),								4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1, false },
147		{ LIMIT(maxImageArrayLayers),								256, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN   , -1, false },
148		{ LIMIT(maxTexelBufferElements),							65536, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
149		{ LIMIT(maxUniformBufferRange),								16384, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
150		{ LIMIT(maxStorageBufferRange),								134217728, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
151		{ LIMIT(maxPushConstantsSize),								128, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
152		{ LIMIT(maxMemoryAllocationCount),							4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1, false },
153		{ LIMIT(maxSamplerAllocationCount),							4000, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1, false },
154		{ LIMIT(bufferImageGranularity),							0, 0, 1, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1, false },
155		{ LIMIT(bufferImageGranularity),							0, 0, 131072, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MAX, -1, false },
156		{ LIMIT(sparseAddressSpaceSize),							0, 0, 2UL*1024*1024*1024, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1, false },
157		{ LIMIT(maxBoundDescriptorSets),							4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
158		{ LIMIT(maxPerStageDescriptorSamplers),						16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
159		{ LIMIT(maxPerStageDescriptorUniformBuffers),				12, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1, false },
160		{ LIMIT(maxPerStageDescriptorStorageBuffers),				4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1, false },
161		{ LIMIT(maxPerStageDescriptorSampledImages),				16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1, false },
162		{ LIMIT(maxPerStageDescriptorStorageImages),				4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1, false },
163		{ LIMIT(maxPerStageDescriptorInputAttachments),				4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1, false },
164		{ LIMIT(maxPerStageResources),								maxPerStageResourcesMin, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1, false },
165		{ LIMIT(maxDescriptorSetSamplers),							shaderStages * 16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
166		{ LIMIT(maxDescriptorSetUniformBuffers),					shaderStages * 12, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
167		{ LIMIT(maxDescriptorSetUniformBuffersDynamic),				8, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
168		{ LIMIT(maxDescriptorSetStorageBuffers),					shaderStages * 4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
169		{ LIMIT(maxDescriptorSetStorageBuffersDynamic),				4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
170		{ LIMIT(maxDescriptorSetSampledImages),						shaderStages * 16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
171		{ LIMIT(maxDescriptorSetStorageImages),						shaderStages * 4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
172		{ LIMIT(maxDescriptorSetInputAttachments),					4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
173		{ LIMIT(maxVertexInputAttributes),							16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
174		{ LIMIT(maxVertexInputBindings),							16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
175		{ LIMIT(maxVertexInputAttributeOffset),						2047, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
176		{ LIMIT(maxVertexInputBindingStride),						2048, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
177		{ LIMIT(maxVertexOutputComponents),							64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
178		{ LIMIT(maxTessellationGenerationLevel),					64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
179		{ LIMIT(maxTessellationPatchSize),							32, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1, false },
180		{ LIMIT(maxTessellationControlPerVertexInputComponents),	64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
181		{ LIMIT(maxTessellationControlPerVertexOutputComponents),	64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
182		{ LIMIT(maxTessellationControlPerPatchOutputComponents),	120, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
183		{ LIMIT(maxTessellationControlTotalOutputComponents),		2048, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
184		{ LIMIT(maxTessellationEvaluationInputComponents),			64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
185		{ LIMIT(maxTessellationEvaluationOutputComponents),			64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
186		{ LIMIT(maxGeometryShaderInvocations),						32, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
187		{ LIMIT(maxGeometryInputComponents),						64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
188		{ LIMIT(maxGeometryOutputComponents),						64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
189		{ LIMIT(maxGeometryOutputVertices),							256, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
190		{ LIMIT(maxGeometryTotalOutputComponents),					1024, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
191		{ LIMIT(maxFragmentInputComponents),						64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
192		{ LIMIT(maxFragmentOutputAttachments),						4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
193		{ LIMIT(maxFragmentDualSrcAttachments),						1, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
194		{ LIMIT(maxFragmentCombinedOutputResources),				4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1, false },
195		{ LIMIT(maxComputeSharedMemorySize),						16384, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN   , -1, false },
196		{ LIMIT(maxComputeWorkGroupCount[0]),						65535, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN   , -1, false },
197		{ LIMIT(maxComputeWorkGroupCount[1]),						65535, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN   , -1, false },
198		{ LIMIT(maxComputeWorkGroupCount[2]),						65535,  0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN   , -1, false },
199		{ LIMIT(maxComputeWorkGroupInvocations),					128, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN    , -1, false },
200		{ LIMIT(maxComputeWorkGroupSize[0]),						128, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN    , -1, false },
201		{ LIMIT(maxComputeWorkGroupSize[1]),						128, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN    , -1, false },
202		{ LIMIT(maxComputeWorkGroupSize[2]),						64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN    , -1, false },
203		{ LIMIT(subPixelPrecisionBits),								4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN    , -1, false },
204		{ LIMIT(subTexelPrecisionBits),								4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN    , -1, false },
205		{ LIMIT(mipmapPrecisionBits),								4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN    , -1, false },
206		{ LIMIT(maxDrawIndexedIndexValue),							(deUint32)~0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
207		{ LIMIT(maxDrawIndirectCount),								65535, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN    , -1, false },
208		{ LIMIT(maxSamplerLodBias),									0, 0, 0, 2.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1, false },
209		{ LIMIT(maxSamplerAnisotropy),								0, 0, 0, 16.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1, false },
210		{ LIMIT(maxViewports),										16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
211		{ LIMIT(maxViewportDimensions[0]),							4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1, false },
212		{ LIMIT(maxViewportDimensions[1]),							4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1, false },
213		{ LIMIT(viewportBoundsRange[0]),							0, 0, 0, -8192.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1, false },
214		{ LIMIT(viewportBoundsRange[1]),							0, 0, 0, 8191.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1, false },
215		{ LIMIT(viewportSubPixelBits),								0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
216		{ LIMIT(minMemoryMapAlignment),								64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, true },
217		{ LIMIT(minTexelBufferOffsetAlignment),						0, 0, 1, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1, true },
218		{ LIMIT(minTexelBufferOffsetAlignment),						0, 0, 256, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MAX, -1, true },
219		{ LIMIT(minUniformBufferOffsetAlignment),					0, 0, 1, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1, true },
220		{ LIMIT(minUniformBufferOffsetAlignment),					0, 0, 256, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MAX, -1, true },
221		{ LIMIT(minStorageBufferOffsetAlignment),					0, 0, 1, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1, true },
222		{ LIMIT(minStorageBufferOffsetAlignment),					0, 0, 256, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MAX, -1, true },
223		{ LIMIT(minTexelOffset),									0, -8, 0, 0.0f, LIMIT_FORMAT_SIGNED_INT, LIMIT_TYPE_MAX, -1, false },
224		{ LIMIT(maxTexelOffset),									7, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
225		{ LIMIT(minTexelGatherOffset),								0, -8, 0, 0.0f, LIMIT_FORMAT_SIGNED_INT, LIMIT_TYPE_MAX, -1, false },
226		{ LIMIT(maxTexelGatherOffset),								7, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
227		{ LIMIT(minInterpolationOffset),							0, 0, 0, -0.5f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1, false },
228		{ LIMIT(maxInterpolationOffset),							0, 0, 0, 0.5f - (1.0f/deFloatPow(2.0f, (float)limits->subPixelInterpolationOffsetBits)), LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1, false },
229		{ LIMIT(subPixelInterpolationOffsetBits),					4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
230		{ LIMIT(maxFramebufferWidth),								4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
231		{ LIMIT(maxFramebufferHeight),								4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
232		{ LIMIT(maxFramebufferLayers),								0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
233		{ LIMIT(framebufferColorSampleCounts),						VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1, false },
234		{ LIMIT(framebufferDepthSampleCounts),						VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1, false },
235		{ LIMIT(framebufferStencilSampleCounts),					VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1, false },
236		{ LIMIT(framebufferNoAttachmentsSampleCounts),				VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1, false },
237		{ LIMIT(maxColorAttachments),								4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
238		{ LIMIT(sampledImageColorSampleCounts),						VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1, false },
239		{ LIMIT(sampledImageIntegerSampleCounts),					VK_SAMPLE_COUNT_1_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1, false },
240		{ LIMIT(sampledImageDepthSampleCounts),						VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1, false },
241		{ LIMIT(sampledImageStencilSampleCounts),					VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1, false },
242		{ LIMIT(storageImageSampleCounts),							VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1, false },
243		{ LIMIT(maxSampleMaskWords),								1, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
244		{ LIMIT(timestampComputeAndGraphics),						0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_NONE, -1, false },
245		{ LIMIT(timestampPeriod),									0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_NONE, -1, false },
246		{ LIMIT(maxClipDistances),									8, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
247		{ LIMIT(maxCullDistances),									8, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
248		{ LIMIT(maxCombinedClipAndCullDistances),					8, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
249		{ LIMIT(discreteQueuePriorities),							2, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1, false },
250		{ LIMIT(pointSizeRange[0]),									0, 0, 0, 0.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1, false },
251		{ LIMIT(pointSizeRange[0]),									0, 0, 0, 1.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1, false },
252		{ LIMIT(pointSizeRange[1]),									0, 0, 0, 64.0f - limits->pointSizeGranularity , LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1, false },
253		{ LIMIT(lineWidthRange[0]),									0, 0, 0, 0.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1, false },
254		{ LIMIT(lineWidthRange[0]),									0, 0, 0, 1.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1, false },
255		{ LIMIT(lineWidthRange[1]),									0, 0, 0, 8.0f - limits->lineWidthGranularity, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1, false },
256		{ LIMIT(pointSizeGranularity),								0, 0, 0, 1.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1, false },
257		{ LIMIT(lineWidthGranularity),								0, 0, 0, 1.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1, false },
258		{ LIMIT(strictLines),										0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_NONE, -1, false },
259		{ LIMIT(standardSampleLocations),							0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_NONE, -1, false },
260		{ LIMIT(optimalBufferCopyOffsetAlignment),					0, 0, 0, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_NONE, -1, true },
261		{ LIMIT(optimalBufferCopyRowPitchAlignment),				0, 0, 0, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_NONE, -1, true },
262		{ LIMIT(nonCoherentAtomSize),								0, 0, 1, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1, true },
263		{ LIMIT(nonCoherentAtomSize),								0, 0, 256, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MAX, -1, true },
264	};
265
266	const struct UnsupportedFeatureLimitTable
267	{
268		deUint32		limitOffset;
269		const char*		name;
270		deUint32		featureOffset;
271		deUint32		uintVal;			//!< Format is UNSIGNED_INT
272		deInt32			intVal;				//!< Format is SIGNED_INT
273		deUint64		deviceSizeVal;		//!< Format is DEVICE_SIZE
274		float			floatVal;			//!< Format is FLOAT
275	} unsupportedFeatureTable[] =
276	{
277		{ LIMIT(sparseAddressSpaceSize),							FEATURE(sparseBinding),					0, 0, 0, 0.0f },
278		{ LIMIT(maxTessellationGenerationLevel),					FEATURE(tessellationShader),			0, 0, 0, 0.0f },
279		{ LIMIT(maxTessellationPatchSize),							FEATURE(tessellationShader),			0, 0, 0, 0.0f },
280		{ LIMIT(maxTessellationControlPerVertexInputComponents),	FEATURE(tessellationShader),			0, 0, 0, 0.0f },
281		{ LIMIT(maxTessellationControlPerVertexOutputComponents),	FEATURE(tessellationShader),			0, 0, 0, 0.0f },
282		{ LIMIT(maxTessellationControlPerPatchOutputComponents),	FEATURE(tessellationShader),			0, 0, 0, 0.0f },
283		{ LIMIT(maxTessellationControlTotalOutputComponents),		FEATURE(tessellationShader),			0, 0, 0, 0.0f },
284		{ LIMIT(maxTessellationEvaluationInputComponents),			FEATURE(tessellationShader),			0, 0, 0, 0.0f },
285		{ LIMIT(maxTessellationEvaluationOutputComponents),			FEATURE(tessellationShader),			0, 0, 0, 0.0f },
286		{ LIMIT(maxGeometryShaderInvocations),						FEATURE(geometryShader),				0, 0, 0, 0.0f },
287		{ LIMIT(maxGeometryInputComponents),						FEATURE(geometryShader),				0, 0, 0, 0.0f },
288		{ LIMIT(maxGeometryOutputComponents),						FEATURE(geometryShader),				0, 0, 0, 0.0f },
289		{ LIMIT(maxGeometryOutputVertices),							FEATURE(geometryShader),				0, 0, 0, 0.0f },
290		{ LIMIT(maxGeometryTotalOutputComponents),					FEATURE(geometryShader),				0, 0, 0, 0.0f },
291		{ LIMIT(maxFragmentDualSrcAttachments),						FEATURE(dualSrcBlend),					0, 0, 0, 0.0f },
292		{ LIMIT(maxDrawIndexedIndexValue),							FEATURE(fullDrawIndexUint32),			(1<<24)-1, 0, 0, 0.0f },
293		{ LIMIT(maxDrawIndirectCount),								FEATURE(multiDrawIndirect),				1, 0, 0, 0.0f },
294		{ LIMIT(maxSamplerAnisotropy),								FEATURE(samplerAnisotropy),				1, 0, 0, 0.0f },
295		{ LIMIT(maxViewports),										FEATURE(multiViewport),					1, 0, 0, 0.0f },
296		{ LIMIT(minTexelGatherOffset),								FEATURE(shaderImageGatherExtended),		0, 0, 0, 0.0f },
297		{ LIMIT(maxTexelGatherOffset),								FEATURE(shaderImageGatherExtended),		0, 0, 0, 0.0f },
298		{ LIMIT(minInterpolationOffset),							FEATURE(sampleRateShading),				0, 0, 0, 0.0f },
299		{ LIMIT(maxInterpolationOffset),							FEATURE(sampleRateShading),				0, 0, 0, 0.0f },
300		{ LIMIT(subPixelInterpolationOffsetBits),					FEATURE(sampleRateShading),				0, 0, 0, 0.0f },
301		{ LIMIT(storageImageSampleCounts),							FEATURE(shaderStorageImageMultisample),	VK_SAMPLE_COUNT_1_BIT, 0, 0, 0.0f },
302		{ LIMIT(maxClipDistances),									FEATURE(shaderClipDistance),			0, 0, 0, 0.0f },
303		{ LIMIT(maxCullDistances),									FEATURE(shaderCullDistance),			0, 0, 0, 0.0f },
304		{ LIMIT(maxCombinedClipAndCullDistances),					FEATURE(shaderClipDistance),			0, 0, 0, 0.0f },
305		{ LIMIT(pointSizeRange[0]),									FEATURE(largePoints),					0, 0, 0, 1.0f },
306		{ LIMIT(pointSizeRange[1]),									FEATURE(largePoints),					0, 0, 0, 1.0f },
307		{ LIMIT(lineWidthRange[0]),									FEATURE(wideLines),						0, 0, 0, 1.0f },
308		{ LIMIT(lineWidthRange[1]),									FEATURE(wideLines),						0, 0, 0, 1.0f },
309		{ LIMIT(pointSizeGranularity),								FEATURE(largePoints),					0, 0, 0, 0.0f },
310		{ LIMIT(lineWidthGranularity),								FEATURE(wideLines),						0, 0, 0, 0.0f }
311	};
312
313	log << TestLog::Message << *limits << TestLog::EndMessage;
314
315	//!< First build a map from limit to unsupported table index
316	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
317	{
318		for (deUint32 unsuppNdx = 0; unsuppNdx < DE_LENGTH_OF_ARRAY(unsupportedFeatureTable); unsuppNdx++)
319		{
320			if (unsupportedFeatureTable[unsuppNdx].limitOffset == featureLimitTable[ndx].offset)
321			{
322				featureLimitTable[ndx].unsuppTableNdx = unsuppNdx;
323				break;
324			}
325		}
326	}
327
328	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
329	{
330		switch (featureLimitTable[ndx].format)
331		{
332			case LIMIT_FORMAT_UNSIGNED_INT:
333			{
334				deUint32 limitToCheck = featureLimitTable[ndx].uintVal;
335				if (featureLimitTable[ndx].unsuppTableNdx != -1)
336				{
337					if (*((VkBool32*)((deUint8*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)) == VK_FALSE)
338						limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].uintVal;
339				}
340
341				if (featureLimitTable[ndx].pot)
342				{
343					if (*((deUint32*)((deUint8*)limits + featureLimitTable[ndx].offset)) == 0 || !deIntIsPow2(*((deUint32*)((deUint8*)limits + featureLimitTable[ndx].offset))))
344					{
345						log << TestLog::Message << "limit Validation failed " << featureLimitTable[ndx].name
346							<< " is not a power of two." << TestLog::EndMessage;
347						limitsOk = false;
348					}
349				}
350
351				if (featureLimitTable[ndx].type == LIMIT_TYPE_MIN)
352				{
353					if (*((deUint32*)((deUint8*)limits+featureLimitTable[ndx].offset)) < limitToCheck)
354					{
355						log << TestLog::Message << "limit Validation failed " << featureLimitTable[ndx].name
356							<< " not valid-limit type MIN - actual is "
357							<< *((deUint32*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
358						limitsOk = false;
359					}
360				}
361				else if (featureLimitTable[ndx].type == LIMIT_TYPE_MAX)
362				{
363					if (*((deUint32*)((deUint8*)limits+featureLimitTable[ndx].offset)) > limitToCheck)
364					{
365						log << TestLog::Message << "limit validation failed,  " << featureLimitTable[ndx].name
366							<< " not valid-limit type MAX - actual is "
367							<< *((deUint32*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
368						limitsOk = false;
369					}
370				}
371				break;
372			}
373
374			case LIMIT_FORMAT_FLOAT:
375			{
376				float limitToCheck = featureLimitTable[ndx].floatVal;
377				if (featureLimitTable[ndx].unsuppTableNdx != -1)
378				{
379					if (*((VkBool32*)((deUint8*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)) == VK_FALSE)
380						limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].floatVal;
381				}
382
383				if (featureLimitTable[ndx].type == LIMIT_TYPE_MIN)
384				{
385					if (*((float*)((deUint8*)limits+featureLimitTable[ndx].offset)) < limitToCheck)
386					{
387						log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
388							<< " not valid-limit type MIN - actual is "
389							<< *((float*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
390						limitsOk = false;
391					}
392				}
393				else if (featureLimitTable[ndx].type == LIMIT_TYPE_MAX)
394				{
395					if (*((float*)((deUint8*)limits+featureLimitTable[ndx].offset)) > limitToCheck)
396					{
397						log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
398							<< " not valid-limit type MAX actual is "
399							<< *((float*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
400						limitsOk = false;
401					}
402				}
403				break;
404			}
405
406			case LIMIT_FORMAT_SIGNED_INT:
407			{
408				deInt32 limitToCheck = featureLimitTable[ndx].intVal;
409				if (featureLimitTable[ndx].unsuppTableNdx != -1)
410				{
411					if (*((VkBool32*)((deUint8*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)) == VK_FALSE)
412						limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].intVal;
413				}
414				if (featureLimitTable[ndx].type == LIMIT_TYPE_MIN)
415				{
416					if (*((deInt32*)((deUint8*)limits+featureLimitTable[ndx].offset)) < limitToCheck)
417					{
418						log << TestLog::Message <<  "limit validation failed, " << featureLimitTable[ndx].name
419							<< " not valid-limit type MIN actual is "
420							<< *((deInt32*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
421						limitsOk = false;
422					}
423				}
424				else if (featureLimitTable[ndx].type == LIMIT_TYPE_MAX)
425				{
426					if (*((deInt32*)((deUint8*)limits+featureLimitTable[ndx].offset)) > limitToCheck)
427					{
428						log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
429							<< " not valid-limit type MAX actual is "
430							<< *((deInt32*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
431						limitsOk = false;
432					}
433				}
434				break;
435			}
436
437			case LIMIT_FORMAT_DEVICE_SIZE:
438			{
439				deUint64 limitToCheck = featureLimitTable[ndx].deviceSizeVal;
440				if (featureLimitTable[ndx].unsuppTableNdx != -1)
441				{
442					if (*((VkBool32*)((deUint8*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)) == VK_FALSE)
443						limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].deviceSizeVal;
444				}
445
446				if (featureLimitTable[ndx].type == LIMIT_TYPE_MIN)
447				{
448					if (*((deUint64*)((deUint8*)limits+featureLimitTable[ndx].offset)) < limitToCheck)
449					{
450						log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
451							<< " not valid-limit type MIN actual is "
452							<< *((deUint64*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
453						limitsOk = false;
454					}
455				}
456				else if (featureLimitTable[ndx].type == LIMIT_TYPE_MAX)
457				{
458					if (*((deUint64*)((deUint8*)limits+featureLimitTable[ndx].offset)) > limitToCheck)
459					{
460						log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
461							<< " not valid-limit type MAX actual is "
462							<< *((deUint64*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
463						limitsOk = false;
464					}
465				}
466				break;
467			}
468
469			case LIMIT_FORMAT_BITMASK:
470			{
471				deUint32 limitToCheck = featureLimitTable[ndx].uintVal;
472				if (featureLimitTable[ndx].unsuppTableNdx != -1)
473				{
474					if (*((VkBool32*)((deUint8*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)) == VK_FALSE)
475						limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].uintVal;
476				}
477
478				if (featureLimitTable[ndx].type == LIMIT_TYPE_MIN)
479				{
480					if ((*((deUint32*)((deUint8*)limits+featureLimitTable[ndx].offset)) & limitToCheck) != limitToCheck)
481					{
482						log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
483							<< " not valid-limit type bitmask actual is "
484							<< *((deUint64*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
485						limitsOk = false;
486					}
487				}
488				break;
489			}
490
491			default:
492				DE_ASSERT(0);
493				limitsOk = false;
494		}
495	}
496
497	if (limits->maxFramebufferWidth > limits->maxViewportDimensions[0] ||
498		limits->maxFramebufferHeight > limits->maxViewportDimensions[1])
499	{
500		log << TestLog::Message << "limit validation failed, maxFramebufferDimension of "
501			<< "[" << limits->maxFramebufferWidth << ", " << limits->maxFramebufferHeight << "] "
502			<< "is larger than maxViewportDimension of "
503			<< "[" << limits->maxViewportDimensions[0] << ", " << limits->maxViewportDimensions[1] << "]" << TestLog::EndMessage;
504		limitsOk = false;
505	}
506
507	if (limits->viewportBoundsRange[0] > float(-2 * limits->maxViewportDimensions[0]))
508	{
509		log << TestLog::Message << "limit validation failed, viewPortBoundsRange[0] of " << limits->viewportBoundsRange[0]
510			<< "is larger than -2*maxViewportDimension[0] of " << -2*limits->maxViewportDimensions[0] << TestLog::EndMessage;
511		limitsOk = false;
512	}
513
514	if (limits->viewportBoundsRange[1] < float(2 * limits->maxViewportDimensions[1] - 1))
515	{
516		log << TestLog::Message << "limit validation failed, viewportBoundsRange[1] of " << limits->viewportBoundsRange[1]
517			<< "is less than 2*maxViewportDimension[1] of " << 2*limits->maxViewportDimensions[1] << TestLog::EndMessage;
518		limitsOk = false;
519	}
520
521	return limitsOk;
522}
523
524template<deUint32 MAJOR, deUint32 MINOR>
525void checkApiVersionSupport(Context& context)
526{
527	if (!context.contextSupports(vk::ApiVersion(0, MAJOR, MINOR, 0)))
528		TCU_THROW(NotSupportedError, std::string("At least Vulkan ") + std::to_string(MAJOR) + "." + std::to_string(MINOR) + " required to run test");
529}
530
531typedef struct FeatureLimitTableItem_
532{
533	const void*		cond;
534	const char*		condName;
535	const void*		ptr;
536	const char*		name;
537	deUint32		uintVal;			//!< Format is UNSIGNED_INT
538	deInt32			intVal;				//!< Format is SIGNED_INT
539	deUint64		deviceSizeVal;		//!< Format is DEVICE_SIZE
540	float			floatVal;			//!< Format is FLOAT
541	LimitFormat		format;
542	LimitType		type;
543} FeatureLimitTableItem;
544
545template<typename T>
546bool validateNumericLimit (const T limitToCheck, const T reportedValue, const LimitType limitType, const char* limitName, TestLog& log)
547{
548	if (limitType == LIMIT_TYPE_MIN)
549	{
550		if (reportedValue < limitToCheck)
551		{
552			log << TestLog::Message << "Limit validation failed " << limitName
553				<< " reported value is " << reportedValue
554				<< " expected MIN " << limitToCheck
555				<< TestLog::EndMessage;
556
557			return false;
558		}
559
560		log << TestLog::Message << limitName
561			<< "=" << reportedValue
562			<< " (>=" << limitToCheck << ")"
563			<< TestLog::EndMessage;
564	}
565	else if (limitType == LIMIT_TYPE_MAX)
566	{
567		if (reportedValue > limitToCheck)
568		{
569			log << TestLog::Message << "Limit validation failed " << limitName
570				<< " reported value is " << reportedValue
571				<< " expected MAX " << limitToCheck
572				<< TestLog::EndMessage;
573
574			return false;
575		}
576
577		log << TestLog::Message << limitName
578			<< "=" << reportedValue
579			<< " (<=" << limitToCheck << ")"
580			<< TestLog::EndMessage;
581	}
582
583	return true;
584}
585
586template<typename T>
587bool validateBitmaskLimit (const T limitToCheck, const T reportedValue, const LimitType limitType, const char* limitName, TestLog& log)
588{
589	if (limitType == LIMIT_TYPE_MIN)
590	{
591		if ((reportedValue & limitToCheck) != limitToCheck)
592		{
593			log << TestLog::Message << "Limit validation failed " << limitName
594				<< " reported value is " << reportedValue
595				<< " expected MIN " << limitToCheck
596				<< TestLog::EndMessage;
597
598			return false;
599		}
600
601		log << TestLog::Message << limitName
602			<< "=" << tcu::toHex(reportedValue)
603			<< " (contains " << tcu::toHex(limitToCheck) << ")"
604			<< TestLog::EndMessage;
605	}
606
607	return true;
608}
609
610bool validateLimit (FeatureLimitTableItem limit, TestLog& log)
611{
612	if (*((VkBool32*)limit.cond) == DE_FALSE)
613	{
614		log << TestLog::Message
615			<< "Limit validation skipped '" << limit.name << "' due to "
616			<< limit.condName << " == false'"
617			<< TestLog::EndMessage;
618
619		return true;
620	}
621
622	switch (limit.format)
623	{
624		case LIMIT_FORMAT_UNSIGNED_INT:
625		{
626			const deUint32	limitToCheck	= limit.uintVal;
627			const deUint32	reportedValue	= *(deUint32*)limit.ptr;
628
629			return validateNumericLimit(limitToCheck, reportedValue, limit.type, limit.name, log);
630		}
631
632		case LIMIT_FORMAT_FLOAT:
633		{
634			const float		limitToCheck	= limit.floatVal;
635			const float		reportedValue	= *(float*)limit.ptr;
636
637			return validateNumericLimit(limitToCheck, reportedValue, limit.type, limit.name, log);
638		}
639
640		case LIMIT_FORMAT_SIGNED_INT:
641		{
642			const deInt32	limitToCheck	= limit.intVal;
643			const deInt32	reportedValue	= *(deInt32*)limit.ptr;
644
645			return validateNumericLimit(limitToCheck, reportedValue, limit.type, limit.name, log);
646		}
647
648		case LIMIT_FORMAT_DEVICE_SIZE:
649		{
650			const deUint64	limitToCheck	= limit.deviceSizeVal;
651			const deUint64	reportedValue	= *(deUint64*)limit.ptr;
652
653			return validateNumericLimit(limitToCheck, reportedValue, limit.type, limit.name, log);
654		}
655
656		case LIMIT_FORMAT_BITMASK:
657		{
658			const deUint32	limitToCheck	= limit.uintVal;
659			const deUint32	reportedValue	= *(deUint32*)limit.ptr;
660
661			return validateBitmaskLimit(limitToCheck, reportedValue, limit.type, limit.name, log);
662		}
663
664		default:
665			TCU_THROW(InternalError, "Unknown LimitFormat specified");
666	}
667}
668
669#ifdef PN
670#error PN defined
671#else
672#define PN(_X_)	&(_X_), (const char*)(#_X_)
673#endif
674
675#define LIM_MIN_UINT32(X)	deUint32(X),          0,               0,     0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN
676#define LIM_MAX_UINT32(X)	deUint32(X),          0,               0,     0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MAX
677#define LIM_NONE_UINT32		          0,          0,               0,     0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_NONE
678#define LIM_MIN_INT32(X)	          0, deInt32(X),               0,     0.0f, LIMIT_FORMAT_SIGNED_INT,   LIMIT_TYPE_MIN
679#define LIM_MAX_INT32(X)	          0, deInt32(X),               0,     0.0f, LIMIT_FORMAT_SIGNED_INT,   LIMIT_TYPE_MAX
680#define LIM_NONE_INT32		          0,          0,               0,     0.0f, LIMIT_FORMAT_SIGNED_INT,   LIMIT_TYPE_NONE
681#define LIM_MIN_DEVSIZE(X)	          0,          0, VkDeviceSize(X),     0.0f, LIMIT_FORMAT_DEVICE_SIZE,  LIMIT_TYPE_MIN
682#define LIM_MAX_DEVSIZE(X)	          0,          0, VkDeviceSize(X),     0.0f, LIMIT_FORMAT_DEVICE_SIZE,  LIMIT_TYPE_MAX
683#define LIM_NONE_DEVSIZE	          0,          0,               0,     0.0f, LIMIT_FORMAT_DEVICE_SIZE,  LIMIT_TYPE_NONE
684#define LIM_MIN_FLOAT(X)	          0,          0,               0, float(X), LIMIT_FORMAT_FLOAT,        LIMIT_TYPE_MIN
685#define LIM_MAX_FLOAT(X)	          0,          0,               0, float(X), LIMIT_FORMAT_FLOAT,        LIMIT_TYPE_MAX
686#define LIM_NONE_FLOAT		          0,          0,               0,     0.0f, LIMIT_FORMAT_FLOAT,        LIMIT_TYPE_NONE
687#define LIM_MIN_BITI32(X)	deUint32(X),          0,               0,     0.0f, LIMIT_FORMAT_BITMASK,      LIMIT_TYPE_MIN
688#define LIM_MAX_BITI32(X)	deUint32(X),          0,               0,     0.0f, LIMIT_FORMAT_BITMASK,      LIMIT_TYPE_MAX
689#define LIM_NONE_BITI32		          0,          0,               0,     0.0f, LIMIT_FORMAT_BITMASK,      LIMIT_TYPE_NONE
690
691tcu::TestStatus validateLimits12 (Context& context)
692{
693	const VkPhysicalDevice						physicalDevice			= context.getPhysicalDevice();
694	const InstanceInterface&					vki						= context.getInstanceInterface();
695	TestLog&									log						= context.getTestContext().getLog();
696	bool										limitsOk				= true;
697
698	const VkPhysicalDeviceFeatures2&			features2				= context.getDeviceFeatures2();
699	const VkPhysicalDeviceFeatures&				features				= features2.features;
700#ifdef CTS_USES_VULKANSC
701	const VkPhysicalDeviceVulkan11Features		features11				= getPhysicalDeviceVulkan11Features(vki, physicalDevice);
702#endif // CTS_USES_VULKANSC
703	const VkPhysicalDeviceVulkan12Features		features12				= getPhysicalDeviceVulkan12Features(vki, physicalDevice);
704
705	const VkPhysicalDeviceProperties2&			properties2				= context.getDeviceProperties2();
706	const VkPhysicalDeviceVulkan12Properties	vulkan12Properties		= getPhysicalDeviceVulkan12Properties(vki, physicalDevice);
707	const VkPhysicalDeviceVulkan11Properties	vulkan11Properties		= getPhysicalDeviceVulkan11Properties(vki, physicalDevice);
708#ifdef CTS_USES_VULKANSC
709	const VkPhysicalDeviceVulkanSC10Properties	vulkanSC10Properties	= getPhysicalDeviceVulkanSC10Properties(vki, physicalDevice);
710#endif // CTS_USES_VULKANSC
711	const VkPhysicalDeviceLimits&				limits					= properties2.properties.limits;
712
713	const VkBool32								checkAlways				= VK_TRUE;
714	const VkBool32								checkVulkan12Limit		= VK_TRUE;
715#ifdef CTS_USES_VULKANSC
716	const VkBool32								checkVulkanSC10Limit	= VK_TRUE;
717#endif // CTS_USES_VULKANSC
718
719	deUint32									shaderStages			= 3;
720	deUint32									maxPerStageResourcesMin	= deMin32(128,	limits.maxPerStageDescriptorUniformBuffers		+
721																						limits.maxPerStageDescriptorStorageBuffers		+
722																						limits.maxPerStageDescriptorSampledImages		+
723																						limits.maxPerStageDescriptorStorageImages		+
724																						limits.maxPerStageDescriptorInputAttachments	+
725																						limits.maxColorAttachments);
726	deUint32 maxFramebufferLayers = 256;
727
728	if (features.tessellationShader)
729	{
730		shaderStages += 2;
731	}
732
733	if (features.geometryShader)
734	{
735		shaderStages++;
736	}
737
738	// Vulkan SC
739#ifdef CTS_USES_VULKANSC
740	if (features.geometryShader == VK_FALSE && features12.shaderOutputLayer == VK_FALSE)
741	{
742		maxFramebufferLayers = 1;
743	}
744#endif // CTS_USES_VULKANSC
745
746	FeatureLimitTableItem featureLimitTable[] =
747	{
748		{ PN(checkAlways),								PN(limits.maxImageDimension1D),																	LIM_MIN_UINT32(4096) },
749		{ PN(checkAlways),								PN(limits.maxImageDimension2D),																	LIM_MIN_UINT32(4096) },
750		{ PN(checkAlways),								PN(limits.maxImageDimension3D),																	LIM_MIN_UINT32(256) },
751		{ PN(checkAlways),								PN(limits.maxImageDimensionCube),																LIM_MIN_UINT32(4096) },
752		{ PN(checkAlways),								PN(limits.maxImageArrayLayers),																	LIM_MIN_UINT32(256) },
753		{ PN(checkAlways),								PN(limits.maxTexelBufferElements),																LIM_MIN_UINT32(65536) },
754		{ PN(checkAlways),								PN(limits.maxUniformBufferRange),																LIM_MIN_UINT32(16384) },
755		{ PN(checkAlways),								PN(limits.maxStorageBufferRange),																LIM_MIN_UINT32((1<<27)) },
756		{ PN(checkAlways),								PN(limits.maxPushConstantsSize),																LIM_MIN_UINT32(128) },
757		{ PN(checkAlways),								PN(limits.maxMemoryAllocationCount),															LIM_MIN_UINT32(4096) },
758		{ PN(checkAlways),								PN(limits.maxSamplerAllocationCount),															LIM_MIN_UINT32(4000) },
759		{ PN(checkAlways),								PN(limits.bufferImageGranularity),																LIM_MIN_DEVSIZE(1) },
760		{ PN(checkAlways),								PN(limits.bufferImageGranularity),																LIM_MAX_DEVSIZE(131072) },
761		{ PN(features.sparseBinding),					PN(limits.sparseAddressSpaceSize),																LIM_MIN_DEVSIZE((1ull<<31)) },
762		{ PN(checkAlways),								PN(limits.maxBoundDescriptorSets),																LIM_MIN_UINT32(4) },
763		{ PN(checkAlways),								PN(limits.maxPerStageDescriptorSamplers),														LIM_MIN_UINT32(16) },
764		{ PN(checkAlways),								PN(limits.maxPerStageDescriptorUniformBuffers),													LIM_MIN_UINT32(12) },
765		{ PN(checkAlways),								PN(limits.maxPerStageDescriptorStorageBuffers),													LIM_MIN_UINT32(4) },
766		{ PN(checkAlways),								PN(limits.maxPerStageDescriptorSampledImages),													LIM_MIN_UINT32(16) },
767		{ PN(checkAlways),								PN(limits.maxPerStageDescriptorStorageImages),													LIM_MIN_UINT32(4) },
768		{ PN(checkAlways),								PN(limits.maxPerStageDescriptorInputAttachments),												LIM_MIN_UINT32(4) },
769		{ PN(checkAlways),								PN(limits.maxPerStageResources),																LIM_MIN_UINT32(maxPerStageResourcesMin) },
770		{ PN(checkAlways),								PN(limits.maxDescriptorSetSamplers),															LIM_MIN_UINT32(shaderStages * 16) },
771		{ PN(checkAlways),								PN(limits.maxDescriptorSetUniformBuffers),														LIM_MIN_UINT32(shaderStages * 12) },
772		{ PN(checkAlways),								PN(limits.maxDescriptorSetUniformBuffersDynamic),												LIM_MIN_UINT32(8) },
773		{ PN(checkAlways),								PN(limits.maxDescriptorSetStorageBuffers),														LIM_MIN_UINT32(shaderStages * 4) },
774		{ PN(checkAlways),								PN(limits.maxDescriptorSetStorageBuffersDynamic),												LIM_MIN_UINT32(4) },
775		{ PN(checkAlways),								PN(limits.maxDescriptorSetSampledImages),														LIM_MIN_UINT32(shaderStages * 16) },
776		{ PN(checkAlways),								PN(limits.maxDescriptorSetStorageImages),														LIM_MIN_UINT32(shaderStages * 4) },
777		{ PN(checkAlways),								PN(limits.maxDescriptorSetInputAttachments),													LIM_MIN_UINT32(4) },
778		{ PN(checkAlways),								PN(limits.maxVertexInputAttributes),															LIM_MIN_UINT32(16) },
779		{ PN(checkAlways),								PN(limits.maxVertexInputBindings),																LIM_MIN_UINT32(16) },
780		{ PN(checkAlways),								PN(limits.maxVertexInputAttributeOffset),														LIM_MIN_UINT32(2047) },
781		{ PN(checkAlways),								PN(limits.maxVertexInputBindingStride),															LIM_MIN_UINT32(2048) },
782		{ PN(checkAlways),								PN(limits.maxVertexOutputComponents),															LIM_MIN_UINT32(64) },
783		{ PN(features.tessellationShader),				PN(limits.maxTessellationGenerationLevel),														LIM_MIN_UINT32(64) },
784		{ PN(features.tessellationShader),				PN(limits.maxTessellationPatchSize),															LIM_MIN_UINT32(32) },
785		{ PN(features.tessellationShader),				PN(limits.maxTessellationControlPerVertexInputComponents),										LIM_MIN_UINT32(64) },
786		{ PN(features.tessellationShader),				PN(limits.maxTessellationControlPerVertexOutputComponents),										LIM_MIN_UINT32(64) },
787		{ PN(features.tessellationShader),				PN(limits.maxTessellationControlPerPatchOutputComponents),										LIM_MIN_UINT32(120) },
788		{ PN(features.tessellationShader),				PN(limits.maxTessellationControlTotalOutputComponents),											LIM_MIN_UINT32(2048) },
789		{ PN(features.tessellationShader),				PN(limits.maxTessellationEvaluationInputComponents),											LIM_MIN_UINT32(64) },
790		{ PN(features.tessellationShader),				PN(limits.maxTessellationEvaluationOutputComponents),											LIM_MIN_UINT32(64) },
791		{ PN(features.geometryShader),					PN(limits.maxGeometryShaderInvocations),														LIM_MIN_UINT32(32) },
792		{ PN(features.geometryShader),					PN(limits.maxGeometryInputComponents),															LIM_MIN_UINT32(64) },
793		{ PN(features.geometryShader),					PN(limits.maxGeometryOutputComponents),															LIM_MIN_UINT32(64) },
794		{ PN(features.geometryShader),					PN(limits.maxGeometryOutputVertices),															LIM_MIN_UINT32(256) },
795		{ PN(features.geometryShader),					PN(limits.maxGeometryTotalOutputComponents),													LIM_MIN_UINT32(1024) },
796		{ PN(checkAlways),								PN(limits.maxFragmentInputComponents),															LIM_MIN_UINT32(64) },
797		{ PN(checkAlways),								PN(limits.maxFragmentOutputAttachments),														LIM_MIN_UINT32(4) },
798		{ PN(features.dualSrcBlend),					PN(limits.maxFragmentDualSrcAttachments),														LIM_MIN_UINT32(1) },
799		{ PN(checkAlways),								PN(limits.maxFragmentCombinedOutputResources),													LIM_MIN_UINT32(4) },
800		{ PN(checkAlways),								PN(limits.maxComputeSharedMemorySize),															LIM_MIN_UINT32(16384) },
801		{ PN(checkAlways),								PN(limits.maxComputeWorkGroupCount[0]),															LIM_MIN_UINT32(65535) },
802		{ PN(checkAlways),								PN(limits.maxComputeWorkGroupCount[1]),															LIM_MIN_UINT32(65535) },
803		{ PN(checkAlways),								PN(limits.maxComputeWorkGroupCount[2]),															LIM_MIN_UINT32(65535) },
804		{ PN(checkAlways),								PN(limits.maxComputeWorkGroupInvocations),														LIM_MIN_UINT32(128) },
805		{ PN(checkAlways),								PN(limits.maxComputeWorkGroupSize[0]),															LIM_MIN_UINT32(128) },
806		{ PN(checkAlways),								PN(limits.maxComputeWorkGroupSize[1]),															LIM_MIN_UINT32(128) },
807		{ PN(checkAlways),								PN(limits.maxComputeWorkGroupSize[2]),															LIM_MIN_UINT32(64) },
808		{ PN(checkAlways),								PN(limits.subPixelPrecisionBits),																LIM_MIN_UINT32(4) },
809		{ PN(checkAlways),								PN(limits.subTexelPrecisionBits),																LIM_MIN_UINT32(4) },
810		{ PN(checkAlways),								PN(limits.mipmapPrecisionBits),																	LIM_MIN_UINT32(4) },
811		{ PN(features.fullDrawIndexUint32),				PN(limits.maxDrawIndexedIndexValue),															LIM_MIN_UINT32((deUint32)~0) },
812		{ PN(features.multiDrawIndirect),				PN(limits.maxDrawIndirectCount),																LIM_MIN_UINT32(65535) },
813		{ PN(checkAlways),								PN(limits.maxSamplerLodBias),																	LIM_MIN_FLOAT(2.0f) },
814		{ PN(features.samplerAnisotropy),				PN(limits.maxSamplerAnisotropy),																LIM_MIN_FLOAT(16.0f) },
815		{ PN(features.multiViewport),					PN(limits.maxViewports),																		LIM_MIN_UINT32(16) },
816		{ PN(checkAlways),								PN(limits.maxViewportDimensions[0]),															LIM_MIN_UINT32(4096) },
817		{ PN(checkAlways),								PN(limits.maxViewportDimensions[1]),															LIM_MIN_UINT32(4096) },
818		{ PN(checkAlways),								PN(limits.viewportBoundsRange[0]),																LIM_MAX_FLOAT(-8192.0f) },
819		{ PN(checkAlways),								PN(limits.viewportBoundsRange[1]),																LIM_MIN_FLOAT(8191.0f) },
820		{ PN(checkAlways),								PN(limits.viewportSubPixelBits),																LIM_MIN_UINT32(0) },
821		{ PN(checkAlways),								PN(limits.minMemoryMapAlignment),																LIM_MIN_UINT32(64) },
822		{ PN(checkAlways),								PN(limits.minTexelBufferOffsetAlignment),														LIM_MIN_DEVSIZE(1) },
823		{ PN(checkAlways),								PN(limits.minTexelBufferOffsetAlignment),														LIM_MAX_DEVSIZE(256) },
824		{ PN(checkAlways),								PN(limits.minUniformBufferOffsetAlignment),														LIM_MIN_DEVSIZE(1) },
825		{ PN(checkAlways),								PN(limits.minUniformBufferOffsetAlignment),														LIM_MAX_DEVSIZE(256) },
826		{ PN(checkAlways),								PN(limits.minStorageBufferOffsetAlignment),														LIM_MIN_DEVSIZE(1) },
827		{ PN(checkAlways),								PN(limits.minStorageBufferOffsetAlignment),														LIM_MAX_DEVSIZE(256) },
828		{ PN(checkAlways),								PN(limits.minTexelOffset),																		LIM_MAX_INT32(-8) },
829		{ PN(checkAlways),								PN(limits.maxTexelOffset),																		LIM_MIN_INT32(7) },
830		{ PN(features.shaderImageGatherExtended),		PN(limits.minTexelGatherOffset),																LIM_MAX_INT32(-8) },
831		{ PN(features.shaderImageGatherExtended),		PN(limits.maxTexelGatherOffset),																LIM_MIN_INT32(7) },
832		{ PN(features.sampleRateShading),				PN(limits.minInterpolationOffset),																LIM_MAX_FLOAT(-0.5f) },
833		{ PN(features.sampleRateShading),				PN(limits.maxInterpolationOffset),																LIM_MIN_FLOAT(0.5f - (1.0f/deFloatPow(2.0f, (float)limits.subPixelInterpolationOffsetBits))) },
834		{ PN(features.sampleRateShading),				PN(limits.subPixelInterpolationOffsetBits),														LIM_MIN_UINT32(4) },
835		{ PN(checkAlways),								PN(limits.maxFramebufferWidth),																	LIM_MIN_UINT32(4096) },
836		{ PN(checkAlways),								PN(limits.maxFramebufferHeight),																LIM_MIN_UINT32(4096) },
837		{ PN(checkAlways),								PN(limits.maxFramebufferLayers),																LIM_MIN_UINT32(maxFramebufferLayers) },
838		{ PN(checkAlways),								PN(limits.framebufferColorSampleCounts),														LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT) },
839		{ PN(checkVulkan12Limit),						PN(vulkan12Properties.framebufferIntegerColorSampleCounts),										LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT) },
840		{ PN(checkAlways),								PN(limits.framebufferDepthSampleCounts),														LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT) },
841		{ PN(checkAlways),								PN(limits.framebufferStencilSampleCounts),														LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT) },
842		{ PN(checkAlways),								PN(limits.framebufferNoAttachmentsSampleCounts),												LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT) },
843		{ PN(checkAlways),								PN(limits.maxColorAttachments),																	LIM_MIN_UINT32(4) },
844		{ PN(checkAlways),								PN(limits.sampledImageColorSampleCounts),														LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT) },
845		{ PN(checkAlways),								PN(limits.sampledImageIntegerSampleCounts),														LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT) },
846		{ PN(checkAlways),								PN(limits.sampledImageDepthSampleCounts),														LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT) },
847		{ PN(checkAlways),								PN(limits.sampledImageStencilSampleCounts),														LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT) },
848		{ PN(features.shaderStorageImageMultisample),	PN(limits.storageImageSampleCounts),															LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT) },
849		{ PN(checkAlways),								PN(limits.maxSampleMaskWords),																	LIM_MIN_UINT32(1) },
850		{ PN(checkAlways),								PN(limits.timestampComputeAndGraphics),															LIM_NONE_UINT32 },
851		{ PN(checkAlways),								PN(limits.timestampPeriod),																		LIM_NONE_UINT32 },
852		{ PN(features.shaderClipDistance),				PN(limits.maxClipDistances),																	LIM_MIN_UINT32(8) },
853		{ PN(features.shaderCullDistance),				PN(limits.maxCullDistances),																	LIM_MIN_UINT32(8) },
854		{ PN(features.shaderClipDistance),				PN(limits.maxCombinedClipAndCullDistances),														LIM_MIN_UINT32(8) },
855		{ PN(checkAlways),								PN(limits.discreteQueuePriorities),																LIM_MIN_UINT32(2) },
856		{ PN(features.largePoints),						PN(limits.pointSizeRange[0]),																	LIM_MIN_FLOAT(0.0f) },
857		{ PN(features.largePoints),						PN(limits.pointSizeRange[0]),																	LIM_MAX_FLOAT(1.0f) },
858		{ PN(features.largePoints),						PN(limits.pointSizeRange[1]),																	LIM_MIN_FLOAT(64.0f - limits.pointSizeGranularity) },
859		{ PN(features.wideLines),						PN(limits.lineWidthRange[0]),																	LIM_MIN_FLOAT(0.0f) },
860		{ PN(features.wideLines),						PN(limits.lineWidthRange[0]),																	LIM_MAX_FLOAT(1.0f) },
861		{ PN(features.wideLines),						PN(limits.lineWidthRange[1]),																	LIM_MIN_FLOAT(8.0f - limits.lineWidthGranularity) },
862		{ PN(features.largePoints),						PN(limits.pointSizeGranularity),																LIM_MIN_FLOAT(0.0f) },
863		{ PN(features.largePoints),						PN(limits.pointSizeGranularity),																LIM_MAX_FLOAT(1.0f) },
864		{ PN(features.wideLines),						PN(limits.lineWidthGranularity),																LIM_MIN_FLOAT(0.0f) },
865		{ PN(features.wideLines),						PN(limits.lineWidthGranularity),																LIM_MAX_FLOAT(1.0f) },
866		{ PN(checkAlways),								PN(limits.strictLines),																			LIM_NONE_UINT32 },
867		{ PN(checkAlways),								PN(limits.standardSampleLocations),																LIM_NONE_UINT32 },
868		{ PN(checkAlways),								PN(limits.optimalBufferCopyOffsetAlignment),													LIM_NONE_DEVSIZE },
869		{ PN(checkAlways),								PN(limits.optimalBufferCopyRowPitchAlignment),													LIM_NONE_DEVSIZE },
870		{ PN(checkAlways),								PN(limits.nonCoherentAtomSize),																	LIM_MIN_DEVSIZE(1) },
871		{ PN(checkAlways),								PN(limits.nonCoherentAtomSize),																	LIM_MAX_DEVSIZE(256) },
872
873		// VK_KHR_multiview
874#ifndef CTS_USES_VULKANSC
875		{ PN(checkVulkan12Limit),						PN(vulkan11Properties.maxMultiviewViewCount),													LIM_MIN_UINT32(6) },
876		{ PN(checkVulkan12Limit),						PN(vulkan11Properties.maxMultiviewInstanceIndex),												LIM_MIN_UINT32((1 << 27) - 1) },
877#else
878		{ PN(features11.multiview),						PN(vulkan11Properties.maxMultiviewViewCount),													LIM_MIN_UINT32(6) },
879		{ PN(features11.multiview),						PN(vulkan11Properties.maxMultiviewInstanceIndex),												LIM_MIN_UINT32((1 << 27) - 1) },
880#endif // CTS_USES_VULKANSC
881
882		// VK_KHR_maintenance3
883		{ PN(checkVulkan12Limit),						PN(vulkan11Properties.maxPerSetDescriptors),													LIM_MIN_UINT32(1024) },
884		{ PN(checkVulkan12Limit),						PN(vulkan11Properties.maxMemoryAllocationSize),													LIM_MIN_DEVSIZE(1<<30) },
885
886		// VK_EXT_descriptor_indexing
887		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxUpdateAfterBindDescriptorsInAllPools),									LIM_MIN_UINT32(500000) },
888		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindSamplers),							LIM_MIN_UINT32(500000) },
889		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindUniformBuffers),						LIM_MIN_UINT32(12) },
890		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindStorageBuffers),						LIM_MIN_UINT32(500000) },
891		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindSampledImages),						LIM_MIN_UINT32(500000) },
892		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindStorageImages),						LIM_MIN_UINT32(500000) },
893		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindInputAttachments),					LIM_MIN_UINT32(4) },
894		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageUpdateAfterBindResources),										LIM_MIN_UINT32(500000) },
895		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindSamplers),									LIM_MIN_UINT32(500000) },
896		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindUniformBuffers),							LIM_MIN_UINT32(shaderStages * 12) },
897		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic),					LIM_MIN_UINT32(8) },
898		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindStorageBuffers),							LIM_MIN_UINT32(500000) },
899		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic),					LIM_MIN_UINT32(4) },
900		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindSampledImages),							LIM_MIN_UINT32(500000) },
901		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindStorageImages),							LIM_MIN_UINT32(500000) },
902		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindInputAttachments),							LIM_MIN_UINT32(4) },
903		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindSamplers),							LIM_MIN_UINT32(limits.maxPerStageDescriptorSamplers) },
904		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindUniformBuffers),						LIM_MIN_UINT32(limits.maxPerStageDescriptorUniformBuffers) },
905		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindStorageBuffers),						LIM_MIN_UINT32(limits.maxPerStageDescriptorStorageBuffers) },
906		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindSampledImages),						LIM_MIN_UINT32(limits.maxPerStageDescriptorSampledImages) },
907		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindStorageImages),						LIM_MIN_UINT32(limits.maxPerStageDescriptorStorageImages) },
908		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindInputAttachments),					LIM_MIN_UINT32(limits.maxPerStageDescriptorInputAttachments) },
909		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxPerStageUpdateAfterBindResources),										LIM_MIN_UINT32(limits.maxPerStageResources) },
910		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindSamplers),									LIM_MIN_UINT32(limits.maxDescriptorSetSamplers) },
911		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindUniformBuffers),							LIM_MIN_UINT32(limits.maxDescriptorSetUniformBuffers) },
912		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic),					LIM_MIN_UINT32(limits.maxDescriptorSetUniformBuffersDynamic) },
913		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindStorageBuffers),							LIM_MIN_UINT32(limits.maxDescriptorSetStorageBuffers) },
914		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic),					LIM_MIN_UINT32(limits.maxDescriptorSetStorageBuffersDynamic) },
915		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindSampledImages),							LIM_MIN_UINT32(limits.maxDescriptorSetSampledImages) },
916		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindStorageImages),							LIM_MIN_UINT32(limits.maxDescriptorSetStorageImages) },
917		{ PN(features12.descriptorIndexing),			PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindInputAttachments),							LIM_MIN_UINT32(limits.maxDescriptorSetInputAttachments) },
918
919		// timelineSemaphore
920#ifndef CTS_USES_VULKANSC
921		{ PN(checkVulkan12Limit),						PN(vulkan12Properties.maxTimelineSemaphoreValueDifference),										LIM_MIN_DEVSIZE((1ull << 31) - 1) },
922#else
923		// VkPhysicalDeviceVulkan12Features::timelineSemaphore is optional in Vulkan SC
924		{ PN(features12.timelineSemaphore),				PN(vulkan12Properties.maxTimelineSemaphoreValueDifference),										LIM_MIN_DEVSIZE((1ull << 31) - 1) },
925#endif // CTS_USES_VULKANSC
926
927		// Vulkan SC
928#ifdef CTS_USES_VULKANSC
929		{ PN(checkVulkanSC10Limit),						PN(vulkanSC10Properties.maxRenderPassSubpasses),												LIM_MIN_UINT32(1) },
930		{ PN(checkVulkanSC10Limit),						PN(vulkanSC10Properties.maxRenderPassDependencies),												LIM_MIN_UINT32(18) },
931		{ PN(checkVulkanSC10Limit),						PN(vulkanSC10Properties.maxSubpassInputAttachments),											LIM_MIN_UINT32(0) },
932		{ PN(checkVulkanSC10Limit),						PN(vulkanSC10Properties.maxSubpassPreserveAttachments),											LIM_MIN_UINT32(0) },
933		{ PN(checkVulkanSC10Limit),						PN(vulkanSC10Properties.maxFramebufferAttachments),												LIM_MIN_UINT32(9) },
934		{ PN(checkVulkanSC10Limit),						PN(vulkanSC10Properties.maxDescriptorSetLayoutBindings),										LIM_MIN_UINT32(64) },
935		{ PN(checkVulkanSC10Limit),						PN(vulkanSC10Properties.maxQueryFaultCount),													LIM_MIN_UINT32(16) },
936		{ PN(checkVulkanSC10Limit),						PN(vulkanSC10Properties.maxCallbackFaultCount),													LIM_MIN_UINT32(1) },
937		{ PN(checkVulkanSC10Limit),						PN(vulkanSC10Properties.maxCommandPoolCommandBuffers),											LIM_MIN_UINT32(256) },
938		{ PN(checkVulkanSC10Limit),						PN(vulkanSC10Properties.maxCommandBufferSize),													LIM_MIN_UINT32(1048576) },
939#endif // CTS_USES_VULKANSC
940	};
941
942	log << TestLog::Message << limits << TestLog::EndMessage;
943
944	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
945		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
946
947	if (limits.maxFramebufferWidth > limits.maxViewportDimensions[0] ||
948		limits.maxFramebufferHeight > limits.maxViewportDimensions[1])
949	{
950		log << TestLog::Message << "limit validation failed, maxFramebufferDimension of "
951			<< "[" << limits.maxFramebufferWidth << ", " << limits.maxFramebufferHeight << "] "
952			<< "is larger than maxViewportDimension of "
953			<< "[" << limits.maxViewportDimensions[0] << ", " << limits.maxViewportDimensions[1] << "]" << TestLog::EndMessage;
954		limitsOk = false;
955	}
956
957	if (limits.viewportBoundsRange[0] > float(-2 * limits.maxViewportDimensions[0]))
958	{
959		log << TestLog::Message << "limit validation failed, viewPortBoundsRange[0] of " << limits.viewportBoundsRange[0]
960			<< "is larger than -2*maxViewportDimension[0] of " << -2*limits.maxViewportDimensions[0] << TestLog::EndMessage;
961		limitsOk = false;
962	}
963
964	if (limits.viewportBoundsRange[1] < float(2 * limits.maxViewportDimensions[1] - 1))
965	{
966		log << TestLog::Message << "limit validation failed, viewportBoundsRange[1] of " << limits.viewportBoundsRange[1]
967			<< "is less than 2*maxViewportDimension[1] of " << 2*limits.maxViewportDimensions[1] << TestLog::EndMessage;
968		limitsOk = false;
969	}
970
971	if (limitsOk)
972		return tcu::TestStatus::pass("pass");
973	else
974		return tcu::TestStatus::fail("fail");
975}
976
977#ifndef CTS_USES_VULKANSC
978
979void checkSupportKhrPushDescriptor (Context& context)
980{
981	context.requireDeviceFunctionality("VK_KHR_push_descriptor");
982}
983
984tcu::TestStatus validateLimitsKhrPushDescriptor (Context& context)
985{
986	const VkBool32										checkAlways					= VK_TRUE;
987	const VkPhysicalDevicePushDescriptorPropertiesKHR&	pushDescriptorPropertiesKHR	= context.getPushDescriptorProperties();
988	TestLog&											log							= context.getTestContext().getLog();
989	bool												limitsOk					= true;
990
991	FeatureLimitTableItem featureLimitTable[] =
992	{
993		{ PN(checkAlways),	PN(pushDescriptorPropertiesKHR.maxPushDescriptors),	LIM_MIN_UINT32(32) },
994	};
995
996	log << TestLog::Message << pushDescriptorPropertiesKHR << TestLog::EndMessage;
997
998	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
999		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
1000
1001	if (limitsOk)
1002		return tcu::TestStatus::pass("pass");
1003	else
1004		return tcu::TestStatus::fail("fail");
1005}
1006
1007#endif // CTS_USES_VULKANSC
1008
1009void checkSupportKhrMultiview (Context& context)
1010{
1011	context.requireDeviceFunctionality("VK_KHR_multiview");
1012}
1013
1014tcu::TestStatus validateLimitsKhrMultiview (Context& context)
1015{
1016	const VkBool32								checkAlways			= VK_TRUE;
1017	const VkPhysicalDeviceMultiviewProperties&	multiviewProperties	= context.getMultiviewProperties();
1018	TestLog&									log					= context.getTestContext().getLog();
1019	bool										limitsOk			= true;
1020
1021	FeatureLimitTableItem featureLimitTable[] =
1022	{
1023		// VK_KHR_multiview
1024		{ PN(checkAlways),	PN(multiviewProperties.maxMultiviewViewCount),		LIM_MIN_UINT32(6) },
1025		{ PN(checkAlways),	PN(multiviewProperties.maxMultiviewInstanceIndex),	LIM_MIN_UINT32((1<<27) - 1) },
1026	};
1027
1028	log << TestLog::Message << multiviewProperties << TestLog::EndMessage;
1029
1030	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
1031		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
1032
1033	if (limitsOk)
1034		return tcu::TestStatus::pass("pass");
1035	else
1036		return tcu::TestStatus::fail("fail");
1037}
1038
1039void checkSupportExtDiscardRectangles (Context& context)
1040{
1041	context.requireDeviceFunctionality("VK_EXT_discard_rectangles");
1042}
1043
1044tcu::TestStatus validateLimitsExtDiscardRectangles (Context& context)
1045{
1046	const VkBool32											checkAlways						= VK_TRUE;
1047	const VkPhysicalDeviceDiscardRectanglePropertiesEXT&	discardRectanglePropertiesEXT	= context.getDiscardRectanglePropertiesEXT();
1048	TestLog&												log								= context.getTestContext().getLog();
1049	bool													limitsOk						= true;
1050
1051	FeatureLimitTableItem featureLimitTable[] =
1052	{
1053		{ PN(checkAlways),	PN(discardRectanglePropertiesEXT.maxDiscardRectangles),	LIM_MIN_UINT32(4) },
1054	};
1055
1056	log << TestLog::Message << discardRectanglePropertiesEXT << TestLog::EndMessage;
1057
1058	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
1059		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
1060
1061	if (limitsOk)
1062		return tcu::TestStatus::pass("pass");
1063	else
1064		return tcu::TestStatus::fail("fail");
1065}
1066
1067void checkSupportExtSampleLocations (Context& context)
1068{
1069	context.requireDeviceFunctionality("VK_EXT_sample_locations");
1070}
1071
1072tcu::TestStatus validateLimitsExtSampleLocations (Context& context)
1073{
1074	const VkBool32										checkAlways						= VK_TRUE;
1075	const VkPhysicalDeviceSampleLocationsPropertiesEXT&	sampleLocationsPropertiesEXT	= context.getSampleLocationsPropertiesEXT();
1076	TestLog&											log								= context.getTestContext().getLog();
1077	bool												limitsOk						= true;
1078
1079	FeatureLimitTableItem featureLimitTable[] =
1080	{
1081		{ PN(checkAlways),	PN(sampleLocationsPropertiesEXT.sampleLocationSampleCounts),		LIM_MIN_BITI32(VK_SAMPLE_COUNT_4_BIT) },
1082		{ PN(checkAlways),	PN(sampleLocationsPropertiesEXT.maxSampleLocationGridSize.width),	LIM_MIN_FLOAT(0.0f) },
1083		{ PN(checkAlways),	PN(sampleLocationsPropertiesEXT.maxSampleLocationGridSize.height),	LIM_MIN_FLOAT(0.0f) },
1084		{ PN(checkAlways),	PN(sampleLocationsPropertiesEXT.sampleLocationCoordinateRange[0]),	LIM_MAX_FLOAT(0.0f) },
1085		{ PN(checkAlways),	PN(sampleLocationsPropertiesEXT.sampleLocationCoordinateRange[1]),	LIM_MIN_FLOAT(0.9375f) },
1086		{ PN(checkAlways),	PN(sampleLocationsPropertiesEXT.sampleLocationSubPixelBits),		LIM_MIN_UINT32(4) },
1087	};
1088
1089	log << TestLog::Message << sampleLocationsPropertiesEXT << TestLog::EndMessage;
1090
1091	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
1092		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
1093
1094	if (limitsOk)
1095		return tcu::TestStatus::pass("pass");
1096	else
1097		return tcu::TestStatus::fail("fail");
1098}
1099
1100void checkSupportExtExternalMemoryHost (Context& context)
1101{
1102	context.requireDeviceFunctionality("VK_EXT_external_memory_host");
1103}
1104
1105tcu::TestStatus validateLimitsExtExternalMemoryHost (Context& context)
1106{
1107	const VkBool32											checkAlways						= VK_TRUE;
1108	const VkPhysicalDeviceExternalMemoryHostPropertiesEXT&	externalMemoryHostPropertiesEXT	= context.getExternalMemoryHostPropertiesEXT();
1109	TestLog&												log								= context.getTestContext().getLog();
1110	bool													limitsOk						= true;
1111
1112	FeatureLimitTableItem featureLimitTable[] =
1113	{
1114		{ PN(checkAlways),	PN(externalMemoryHostPropertiesEXT.minImportedHostPointerAlignment),	LIM_MAX_DEVSIZE(65536) },
1115	};
1116
1117	log << TestLog::Message << externalMemoryHostPropertiesEXT << TestLog::EndMessage;
1118
1119	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
1120		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
1121
1122	if (limitsOk)
1123		return tcu::TestStatus::pass("pass");
1124	else
1125		return tcu::TestStatus::fail("fail");
1126}
1127
1128void checkSupportExtBlendOperationAdvanced (Context& context)
1129{
1130	context.requireDeviceFunctionality("VK_EXT_blend_operation_advanced");
1131}
1132
1133tcu::TestStatus validateLimitsExtBlendOperationAdvanced (Context& context)
1134{
1135	const VkBool32												checkAlways							= VK_TRUE;
1136	const VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT&	blendOperationAdvancedPropertiesEXT	= context.getBlendOperationAdvancedPropertiesEXT();
1137	TestLog&													log									= context.getTestContext().getLog();
1138	bool														limitsOk							= true;
1139
1140	FeatureLimitTableItem featureLimitTable[] =
1141	{
1142		{ PN(checkAlways),	PN(blendOperationAdvancedPropertiesEXT.advancedBlendMaxColorAttachments),	LIM_MIN_UINT32(1) },
1143	};
1144
1145	log << TestLog::Message << blendOperationAdvancedPropertiesEXT << TestLog::EndMessage;
1146
1147	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
1148		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
1149
1150	if (limitsOk)
1151		return tcu::TestStatus::pass("pass");
1152	else
1153		return tcu::TestStatus::fail("fail");
1154}
1155
1156void checkSupportKhrMaintenance3 (Context& context)
1157{
1158	context.requireDeviceFunctionality("VK_KHR_maintenance3");
1159}
1160
1161#ifndef CTS_USES_VULKANSC
1162void checkSupportKhrMaintenance4 (Context& context)
1163{
1164	context.requireDeviceFunctionality("VK_KHR_maintenance4");
1165}
1166#endif // CTS_USES_VULKANSC
1167
1168tcu::TestStatus validateLimitsKhrMaintenance3 (Context& context)
1169{
1170	const VkBool32									checkAlways				= VK_TRUE;
1171	const VkPhysicalDeviceMaintenance3Properties&	maintenance3Properties	= context.getMaintenance3Properties();
1172	TestLog&										log						= context.getTestContext().getLog();
1173	bool											limitsOk				= true;
1174
1175	FeatureLimitTableItem featureLimitTable[] =
1176	{
1177		{ PN(checkAlways),	PN(maintenance3Properties.maxPerSetDescriptors),	LIM_MIN_UINT32(1024) },
1178		{ PN(checkAlways),	PN(maintenance3Properties.maxMemoryAllocationSize),	LIM_MIN_DEVSIZE(1<<30) },
1179	};
1180
1181	log << TestLog::Message << maintenance3Properties << TestLog::EndMessage;
1182
1183	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
1184		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
1185
1186	if (limitsOk)
1187		return tcu::TestStatus::pass("pass");
1188	else
1189		return tcu::TestStatus::fail("fail");
1190}
1191
1192#ifndef CTS_USES_VULKANSC
1193tcu::TestStatus validateLimitsKhrMaintenance4 (Context& context)
1194{
1195	const VkBool32									checkAlways				= VK_TRUE;
1196	const VkPhysicalDeviceMaintenance4Properties&	maintenance4Properties	= context.getMaintenance4Properties();
1197	TestLog&										log						= context.getTestContext().getLog();
1198	bool											limitsOk				= true;
1199
1200	FeatureLimitTableItem featureLimitTable[] =
1201	{
1202		{ PN(checkAlways),	PN(maintenance4Properties.maxBufferSize),	LIM_MIN_DEVSIZE(1<<30) },
1203	};
1204
1205	log << TestLog::Message << maintenance4Properties << TestLog::EndMessage;
1206
1207	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
1208		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
1209
1210	if (limitsOk)
1211		return tcu::TestStatus::pass("pass");
1212	else
1213		return tcu::TestStatus::fail("fail");
1214}
1215#endif // CTS_USES_VULKANSC
1216
1217void checkSupportExtConservativeRasterization (Context& context)
1218{
1219	context.requireDeviceFunctionality("VK_EXT_conservative_rasterization");
1220}
1221
1222tcu::TestStatus validateLimitsExtConservativeRasterization (Context& context)
1223{
1224	const VkBool32													checkAlways								= VK_TRUE;
1225	const VkPhysicalDeviceConservativeRasterizationPropertiesEXT&	conservativeRasterizationPropertiesEXT	= context.getConservativeRasterizationPropertiesEXT();
1226	TestLog&														log										= context.getTestContext().getLog();
1227	bool															limitsOk								= true;
1228
1229	FeatureLimitTableItem featureLimitTable[] =
1230	{
1231		{ PN(checkAlways),	PN(conservativeRasterizationPropertiesEXT.primitiveOverestimationSize),					LIM_MIN_FLOAT(0.0f) },
1232		{ PN(checkAlways),	PN(conservativeRasterizationPropertiesEXT.maxExtraPrimitiveOverestimationSize),			LIM_MIN_FLOAT(0.0f) },
1233		{ PN(checkAlways),	PN(conservativeRasterizationPropertiesEXT.extraPrimitiveOverestimationSizeGranularity),	LIM_MIN_FLOAT(0.0f) },
1234	};
1235
1236	log << TestLog::Message << conservativeRasterizationPropertiesEXT << TestLog::EndMessage;
1237
1238	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
1239		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
1240
1241	if (limitsOk)
1242		return tcu::TestStatus::pass("pass");
1243	else
1244		return tcu::TestStatus::fail("fail");
1245}
1246
1247void checkSupportExtDescriptorIndexing (Context& context)
1248{
1249	const std::string&							requiredDeviceExtension		= "VK_EXT_descriptor_indexing";
1250
1251	if (!context.isDeviceFunctionalitySupported(requiredDeviceExtension))
1252		TCU_THROW(NotSupportedError, requiredDeviceExtension + " is not supported");
1253
1254	// Extension string is present, then extension is really supported and should have been added into chain in DefaultDevice properties and features
1255}
1256
1257tcu::TestStatus validateLimitsExtDescriptorIndexing (Context& context)
1258{
1259	const VkBool32											checkAlways						= VK_TRUE;
1260	const VkPhysicalDeviceProperties2&						properties2						= context.getDeviceProperties2();
1261	const VkPhysicalDeviceLimits&							limits							= properties2.properties.limits;
1262	const VkPhysicalDeviceDescriptorIndexingProperties&		descriptorIndexingProperties	= context.getDescriptorIndexingProperties();
1263	const VkPhysicalDeviceFeatures&							features						= context.getDeviceFeatures();
1264	const deUint32											tessellationShaderCount			= (features.tessellationShader) ? 2 : 0;
1265	const deUint32											geometryShaderCount				= (features.geometryShader) ? 1 : 0;
1266	const deUint32											shaderStages					= 3 + tessellationShaderCount + geometryShaderCount;
1267	TestLog&												log								= context.getTestContext().getLog();
1268	bool													limitsOk						= true;
1269
1270	FeatureLimitTableItem featureLimitTable[] =
1271	{
1272		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxUpdateAfterBindDescriptorsInAllPools),				LIM_MIN_UINT32(500000) },
1273		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxPerStageDescriptorUpdateAfterBindSamplers),			LIM_MIN_UINT32(500000) },
1274		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxPerStageDescriptorUpdateAfterBindUniformBuffers),	LIM_MIN_UINT32(12) },
1275		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxPerStageDescriptorUpdateAfterBindStorageBuffers),	LIM_MIN_UINT32(500000) },
1276		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxPerStageDescriptorUpdateAfterBindSampledImages),		LIM_MIN_UINT32(500000) },
1277		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxPerStageDescriptorUpdateAfterBindStorageImages),		LIM_MIN_UINT32(500000) },
1278		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxPerStageDescriptorUpdateAfterBindInputAttachments),	LIM_MIN_UINT32(4) },
1279		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxPerStageUpdateAfterBindResources),					LIM_MIN_UINT32(500000) },
1280		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindSamplers),				LIM_MIN_UINT32(500000) },
1281		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindUniformBuffers),			LIM_MIN_UINT32(shaderStages * 12) },
1282		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic),	LIM_MIN_UINT32(8) },
1283		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindStorageBuffers),			LIM_MIN_UINT32(500000) },
1284		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic),	LIM_MIN_UINT32(4) },
1285		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindSampledImages),			LIM_MIN_UINT32(500000) },
1286		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindStorageImages),			LIM_MIN_UINT32(500000) },
1287		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindInputAttachments),		LIM_MIN_UINT32(4) },
1288		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxPerStageDescriptorUpdateAfterBindSamplers),			LIM_MIN_UINT32(limits.maxPerStageDescriptorSamplers) },
1289		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxPerStageDescriptorUpdateAfterBindUniformBuffers),	LIM_MIN_UINT32(limits.maxPerStageDescriptorUniformBuffers) },
1290		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxPerStageDescriptorUpdateAfterBindStorageBuffers),	LIM_MIN_UINT32(limits.maxPerStageDescriptorStorageBuffers) },
1291		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxPerStageDescriptorUpdateAfterBindSampledImages),		LIM_MIN_UINT32(limits.maxPerStageDescriptorSampledImages) },
1292		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxPerStageDescriptorUpdateAfterBindStorageImages),		LIM_MIN_UINT32(limits.maxPerStageDescriptorStorageImages) },
1293		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxPerStageDescriptorUpdateAfterBindInputAttachments),	LIM_MIN_UINT32(limits.maxPerStageDescriptorInputAttachments) },
1294		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxPerStageUpdateAfterBindResources),					LIM_MIN_UINT32(limits.maxPerStageResources) },
1295		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindSamplers),				LIM_MIN_UINT32(limits.maxDescriptorSetSamplers) },
1296		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindUniformBuffers),			LIM_MIN_UINT32(limits.maxDescriptorSetUniformBuffers) },
1297		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic),	LIM_MIN_UINT32(limits.maxDescriptorSetUniformBuffersDynamic) },
1298		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindStorageBuffers),			LIM_MIN_UINT32(limits.maxDescriptorSetStorageBuffers) },
1299		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic),	LIM_MIN_UINT32(limits.maxDescriptorSetStorageBuffersDynamic) },
1300		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindSampledImages),			LIM_MIN_UINT32(limits.maxDescriptorSetSampledImages) },
1301		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindStorageImages),			LIM_MIN_UINT32(limits.maxDescriptorSetStorageImages) },
1302		{ PN(checkAlways),	PN(descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindInputAttachments),		LIM_MIN_UINT32(limits.maxDescriptorSetInputAttachments) },
1303	};
1304
1305	log << TestLog::Message << descriptorIndexingProperties << TestLog::EndMessage;
1306
1307	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
1308		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
1309
1310	if (limitsOk)
1311		return tcu::TestStatus::pass("pass");
1312	else
1313		return tcu::TestStatus::fail("fail");
1314}
1315
1316#ifndef CTS_USES_VULKANSC
1317
1318void checkSupportExtInlineUniformBlock (Context& context)
1319{
1320	context.requireDeviceFunctionality("VK_EXT_inline_uniform_block");
1321}
1322
1323tcu::TestStatus validateLimitsExtInlineUniformBlock (Context& context)
1324{
1325	const VkBool32											checkAlways						= VK_TRUE;
1326	const VkPhysicalDeviceInlineUniformBlockProperties&		inlineUniformBlockPropertiesEXT	= context.getInlineUniformBlockProperties();
1327	TestLog&												log								= context.getTestContext().getLog();
1328	bool													limitsOk						= true;
1329
1330	FeatureLimitTableItem featureLimitTable[] =
1331	{
1332		{ PN(checkAlways),	PN(inlineUniformBlockPropertiesEXT.maxInlineUniformBlockSize),									LIM_MIN_UINT32(256) },
1333		{ PN(checkAlways),	PN(inlineUniformBlockPropertiesEXT.maxPerStageDescriptorInlineUniformBlocks),					LIM_MIN_UINT32(4) },
1334		{ PN(checkAlways),	PN(inlineUniformBlockPropertiesEXT.maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks),	LIM_MIN_UINT32(4) },
1335		{ PN(checkAlways),	PN(inlineUniformBlockPropertiesEXT.maxDescriptorSetInlineUniformBlocks),						LIM_MIN_UINT32(4) },
1336		{ PN(checkAlways),	PN(inlineUniformBlockPropertiesEXT.maxDescriptorSetUpdateAfterBindInlineUniformBlocks),			LIM_MIN_UINT32(4) },
1337	};
1338
1339	log << TestLog::Message << inlineUniformBlockPropertiesEXT << TestLog::EndMessage;
1340
1341	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
1342		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
1343
1344	if (limitsOk)
1345		return tcu::TestStatus::pass("pass");
1346	else
1347		return tcu::TestStatus::fail("fail");
1348}
1349
1350#endif // CTS_USES_VULKANSC
1351
1352
1353void checkSupportExtVertexAttributeDivisor (Context& context)
1354{
1355	context.requireDeviceFunctionality("VK_EXT_vertex_attribute_divisor");
1356}
1357
1358tcu::TestStatus validateLimitsExtVertexAttributeDivisor (Context& context)
1359{
1360	const VkBool32												checkAlways							= VK_TRUE;
1361	const VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT&	vertexAttributeDivisorPropertiesEXT	= context.getVertexAttributeDivisorPropertiesEXT();
1362	TestLog&													log									= context.getTestContext().getLog();
1363	bool														limitsOk							= true;
1364
1365	FeatureLimitTableItem featureLimitTable[] =
1366	{
1367		{ PN(checkAlways),	PN(vertexAttributeDivisorPropertiesEXT.maxVertexAttribDivisor),	LIM_MIN_UINT32((1<<16) - 1) },
1368	};
1369
1370	log << TestLog::Message << vertexAttributeDivisorPropertiesEXT << TestLog::EndMessage;
1371
1372	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
1373		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
1374
1375	if (limitsOk)
1376		return tcu::TestStatus::pass("pass");
1377	else
1378		return tcu::TestStatus::fail("fail");
1379}
1380
1381#ifndef CTS_USES_VULKANSC
1382
1383void checkSupportNvMeshShader (Context& context)
1384{
1385	const std::string&							requiredDeviceExtension		= "VK_NV_mesh_shader";
1386
1387	if (!context.isDeviceFunctionalitySupported(requiredDeviceExtension))
1388		TCU_THROW(NotSupportedError, requiredDeviceExtension + " is not supported");
1389}
1390
1391tcu::TestStatus validateLimitsNvMeshShader (Context& context)
1392{
1393	const VkBool32							checkAlways				= VK_TRUE;
1394	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
1395	const InstanceInterface&				vki						= context.getInstanceInterface();
1396	TestLog&								log						= context.getTestContext().getLog();
1397	bool									limitsOk				= true;
1398	VkPhysicalDeviceMeshShaderPropertiesNV	meshShaderPropertiesNV	= initVulkanStructure();
1399	VkPhysicalDeviceProperties2				properties2				= initVulkanStructure(&meshShaderPropertiesNV);
1400
1401	vki.getPhysicalDeviceProperties2(physicalDevice, &properties2);
1402
1403	FeatureLimitTableItem featureLimitTable[] =
1404	{
1405		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxDrawMeshTasksCount),		LIM_MIN_UINT32(deUint32((1ull<<16) - 1)) },
1406		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxTaskWorkGroupInvocations),	LIM_MIN_UINT32(32) },
1407		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxTaskWorkGroupSize[0]),		LIM_MIN_UINT32(32) },
1408		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxTaskWorkGroupSize[1]),		LIM_MIN_UINT32(1) },
1409		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxTaskWorkGroupSize[2]),		LIM_MIN_UINT32(1) },
1410		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxTaskTotalMemorySize),		LIM_MIN_UINT32(16384) },
1411		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxTaskOutputCount),			LIM_MIN_UINT32((1<<16) - 1) },
1412		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxMeshWorkGroupInvocations),	LIM_MIN_UINT32(32) },
1413		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxMeshWorkGroupSize[0]),		LIM_MIN_UINT32(32) },
1414		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxMeshWorkGroupSize[1]),		LIM_MIN_UINT32(1) },
1415		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxMeshWorkGroupSize[2]),		LIM_MIN_UINT32(1) },
1416		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxMeshTotalMemorySize),		LIM_MIN_UINT32(16384) },
1417		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxMeshOutputVertices),		LIM_MIN_UINT32(256) },
1418		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxMeshOutputPrimitives),		LIM_MIN_UINT32(256) },
1419		{ PN(checkAlways),	PN(meshShaderPropertiesNV.maxMeshMultiviewViewCount),	LIM_MIN_UINT32(1) },
1420	};
1421
1422	log << TestLog::Message << meshShaderPropertiesNV << TestLog::EndMessage;
1423
1424	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
1425		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
1426
1427	if (limitsOk)
1428		return tcu::TestStatus::pass("pass");
1429	else
1430		return tcu::TestStatus::fail("fail");
1431}
1432
1433void checkSupportExtTransformFeedback (Context& context)
1434{
1435	context.requireDeviceFunctionality("VK_EXT_transform_feedback");
1436}
1437
1438tcu::TestStatus validateLimitsExtTransformFeedback (Context& context)
1439{
1440	const VkBool32											checkAlways						= VK_TRUE;
1441	const VkPhysicalDeviceTransformFeedbackPropertiesEXT&	transformFeedbackPropertiesEXT	= context.getTransformFeedbackPropertiesEXT();
1442	TestLog&												log								= context.getTestContext().getLog();
1443	bool													limitsOk						= true;
1444
1445	FeatureLimitTableItem featureLimitTable[] =
1446	{
1447		{ PN(checkAlways),	PN(transformFeedbackPropertiesEXT.maxTransformFeedbackStreams),				LIM_MIN_UINT32(1) },
1448		{ PN(checkAlways),	PN(transformFeedbackPropertiesEXT.maxTransformFeedbackBuffers),				LIM_MIN_UINT32(1) },
1449		{ PN(checkAlways),	PN(transformFeedbackPropertiesEXT.maxTransformFeedbackBufferSize),			LIM_MIN_DEVSIZE(1ull<<27) },
1450		{ PN(checkAlways),	PN(transformFeedbackPropertiesEXT.maxTransformFeedbackStreamDataSize),		LIM_MIN_UINT32(512) },
1451		{ PN(checkAlways),	PN(transformFeedbackPropertiesEXT.maxTransformFeedbackBufferDataSize),		LIM_MIN_UINT32(512) },
1452		{ PN(checkAlways),	PN(transformFeedbackPropertiesEXT.maxTransformFeedbackBufferDataStride),	LIM_MIN_UINT32(512) },
1453	};
1454
1455	log << TestLog::Message << transformFeedbackPropertiesEXT << TestLog::EndMessage;
1456
1457	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
1458		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
1459
1460	if (limitsOk)
1461		return tcu::TestStatus::pass("pass");
1462	else
1463		return tcu::TestStatus::fail("fail");
1464}
1465
1466void checkSupportExtFragmentDensityMap (Context& context)
1467{
1468	context.requireDeviceFunctionality("VK_EXT_fragment_density_map");
1469}
1470
1471tcu::TestStatus validateLimitsExtFragmentDensityMap (Context& context)
1472{
1473	const VkBool32											checkAlways						= VK_TRUE;
1474	const VkPhysicalDeviceFragmentDensityMapPropertiesEXT&	fragmentDensityMapPropertiesEXT	= context.getFragmentDensityMapPropertiesEXT();
1475	TestLog&												log								= context.getTestContext().getLog();
1476	bool													limitsOk						= true;
1477
1478	FeatureLimitTableItem featureLimitTable[] =
1479	{
1480		{ PN(checkAlways),	PN(fragmentDensityMapPropertiesEXT.minFragmentDensityTexelSize.width),							LIM_MIN_UINT32(1) },
1481		{ PN(checkAlways),	PN(fragmentDensityMapPropertiesEXT.minFragmentDensityTexelSize.height),							LIM_MIN_UINT32(1) },
1482		{ PN(checkAlways),	PN(fragmentDensityMapPropertiesEXT.maxFragmentDensityTexelSize.width),							LIM_MIN_UINT32(1) },
1483		{ PN(checkAlways),	PN(fragmentDensityMapPropertiesEXT.maxFragmentDensityTexelSize.height),							LIM_MIN_UINT32(1) },
1484	};
1485
1486	log << TestLog::Message << fragmentDensityMapPropertiesEXT << TestLog::EndMessage;
1487
1488	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
1489		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
1490
1491	if (limitsOk)
1492		return tcu::TestStatus::pass("pass");
1493	else
1494		return tcu::TestStatus::fail("fail");
1495}
1496
1497void checkSupportNvRayTracing (Context& context)
1498{
1499	const std::string&							requiredDeviceExtension		= "VK_NV_ray_tracing";
1500
1501	if (!context.isDeviceFunctionalitySupported(requiredDeviceExtension))
1502		TCU_THROW(NotSupportedError, requiredDeviceExtension + " is not supported");
1503}
1504
1505tcu::TestStatus validateLimitsNvRayTracing (Context& context)
1506{
1507	const VkBool32							checkAlways				= VK_TRUE;
1508	const VkPhysicalDevice					physicalDevice			= context.getPhysicalDevice();
1509	const InstanceInterface&				vki						= context.getInstanceInterface();
1510	TestLog&								log						= context.getTestContext().getLog();
1511	bool									limitsOk				= true;
1512	VkPhysicalDeviceRayTracingPropertiesNV	rayTracingPropertiesNV	= initVulkanStructure();
1513	VkPhysicalDeviceProperties2				properties2				= initVulkanStructure(&rayTracingPropertiesNV);
1514
1515	vki.getPhysicalDeviceProperties2(physicalDevice, &properties2);
1516
1517	FeatureLimitTableItem featureLimitTable[] =
1518	{
1519		{ PN(checkAlways),	PN(rayTracingPropertiesNV.shaderGroupHandleSize),					LIM_MIN_UINT32(16) },
1520		{ PN(checkAlways),	PN(rayTracingPropertiesNV.maxRecursionDepth),						LIM_MIN_UINT32(31) },
1521		{ PN(checkAlways),	PN(rayTracingPropertiesNV.shaderGroupBaseAlignment),				LIM_MIN_UINT32(64) },
1522		{ PN(checkAlways),	PN(rayTracingPropertiesNV.maxGeometryCount),						LIM_MIN_UINT32((1<<24) - 1) },
1523		{ PN(checkAlways),	PN(rayTracingPropertiesNV.maxInstanceCount),						LIM_MIN_UINT32((1<<24) - 1) },
1524		{ PN(checkAlways),	PN(rayTracingPropertiesNV.maxTriangleCount),						LIM_MIN_UINT32((1<<29) - 1) },
1525		{ PN(checkAlways),	PN(rayTracingPropertiesNV.maxDescriptorSetAccelerationStructures),	LIM_MIN_UINT32(16) },
1526	};
1527
1528	log << TestLog::Message << rayTracingPropertiesNV << TestLog::EndMessage;
1529
1530	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
1531		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
1532
1533	if (limitsOk)
1534		return tcu::TestStatus::pass("pass");
1535	else
1536		return tcu::TestStatus::fail("fail");
1537}
1538
1539#endif // CTS_USES_VULKANSC
1540
1541void checkSupportKhrTimelineSemaphore (Context& context)
1542{
1543	context.requireDeviceFunctionality("VK_KHR_timeline_semaphore");
1544}
1545
1546tcu::TestStatus validateLimitsKhrTimelineSemaphore (Context& context)
1547{
1548	const VkBool32											checkAlways						= VK_TRUE;
1549	const VkPhysicalDeviceTimelineSemaphoreProperties&		timelineSemaphoreProperties		= context.getTimelineSemaphoreProperties();
1550	bool													limitsOk						= true;
1551	TestLog&												log								= context.getTestContext().getLog();
1552
1553	FeatureLimitTableItem featureLimitTable[] =
1554	{
1555		{ PN(checkAlways),	PN(timelineSemaphoreProperties.maxTimelineSemaphoreValueDifference),	LIM_MIN_DEVSIZE((1ull<<31) - 1) },
1556	};
1557
1558	log << TestLog::Message << timelineSemaphoreProperties << TestLog::EndMessage;
1559
1560	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
1561		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
1562
1563	if (limitsOk)
1564		return tcu::TestStatus::pass("pass");
1565	else
1566		return tcu::TestStatus::fail("fail");
1567}
1568
1569void checkSupportExtLineRasterization (Context& context)
1570{
1571	context.requireDeviceFunctionality("VK_EXT_line_rasterization");
1572}
1573
1574tcu::TestStatus validateLimitsExtLineRasterization (Context& context)
1575{
1576	const VkBool32											checkAlways						= VK_TRUE;
1577	const VkPhysicalDeviceLineRasterizationPropertiesEXT&	lineRasterizationPropertiesEXT	= context.getLineRasterizationPropertiesEXT();
1578	TestLog&												log								= context.getTestContext().getLog();
1579	bool													limitsOk						= true;
1580
1581	FeatureLimitTableItem featureLimitTable[] =
1582	{
1583		{ PN(checkAlways),	PN(lineRasterizationPropertiesEXT.lineSubPixelPrecisionBits),	LIM_MIN_UINT32(4) },
1584	};
1585
1586	log << TestLog::Message << lineRasterizationPropertiesEXT << TestLog::EndMessage;
1587
1588	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
1589		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
1590
1591	if (limitsOk)
1592		return tcu::TestStatus::pass("pass");
1593	else
1594		return tcu::TestStatus::fail("fail");
1595}
1596
1597void checkSupportRobustness2 (Context& context)
1598{
1599	context.requireDeviceFunctionality("VK_EXT_robustness2");
1600}
1601
1602tcu::TestStatus validateLimitsRobustness2 (Context& context)
1603{
1604	const InstanceInterface&						vki							= context.getInstanceInterface();
1605	const VkPhysicalDevice							physicalDevice				= context.getPhysicalDevice();
1606	const VkPhysicalDeviceRobustness2PropertiesEXT&	robustness2PropertiesEXT	= context.getRobustness2PropertiesEXT();
1607	VkPhysicalDeviceRobustness2FeaturesEXT			robustness2Features			= initVulkanStructure();
1608	VkPhysicalDeviceFeatures2						features2					= initVulkanStructure(&robustness2Features);
1609
1610	vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
1611
1612	if (robustness2Features.robustBufferAccess2 && !features2.features.robustBufferAccess)
1613		return tcu::TestStatus::fail("If robustBufferAccess2 is enabled then robustBufferAccess must also be enabled");
1614
1615	if (robustness2PropertiesEXT.robustStorageBufferAccessSizeAlignment != 1 && robustness2PropertiesEXT.robustStorageBufferAccessSizeAlignment != 4)
1616		return tcu::TestStatus::fail("robustness2PropertiesEXT.robustStorageBufferAccessSizeAlignment value must be either 1 or 4.");
1617
1618	if (!de::inRange(robustness2PropertiesEXT.robustUniformBufferAccessSizeAlignment, (VkDeviceSize)1u, (VkDeviceSize)256u) || !deIsPowerOfTwo64(robustness2PropertiesEXT.robustUniformBufferAccessSizeAlignment))
1619		return tcu::TestStatus::fail("robustness2PropertiesEXT.robustUniformBufferAccessSizeAlignment must be a power of two in the range [1, 256]");
1620
1621	return tcu::TestStatus::pass("pass");
1622}
1623
1624#ifndef CTS_USES_VULKANSC
1625tcu::TestStatus validateLimitsMaxInlineUniformTotalSize (Context& context)
1626{
1627	const VkBool32								checkAlways			= VK_TRUE;
1628	const VkPhysicalDeviceVulkan13Properties&	vulkan13Properties	= context.getDeviceVulkan13Properties();
1629	bool										limitsOk			= true;
1630	TestLog&									log					= context.getTestContext().getLog();
1631
1632	FeatureLimitTableItem featureLimitTable[] =
1633	{
1634		{ PN(checkAlways),	PN(vulkan13Properties.maxInlineUniformTotalSize),	LIM_MIN_DEVSIZE(256) },
1635	};
1636
1637	log << TestLog::Message << vulkan13Properties << TestLog::EndMessage;
1638
1639	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
1640		limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk;
1641
1642	if (limitsOk)
1643		return tcu::TestStatus::pass("pass");
1644	else
1645		return tcu::TestStatus::fail("fail");
1646}
1647
1648tcu::TestStatus validateRoadmap2022(Context& context)
1649{
1650	if (context.getUsedApiVersion() < VK_API_VERSION_1_3)
1651		TCU_THROW(NotSupportedError, "Profile not supported");
1652
1653	const VkBool32	checkAlways				= VK_TRUE;
1654	VkBool32		oneOrMoreChecksFailed	= VK_FALSE;
1655	TestLog&		log						= context.getTestContext().getLog();
1656
1657	auto			vk10Features			= context.getDeviceFeatures();
1658	auto			vk11Features			= context.getDeviceVulkan11Features();
1659	auto			vk12Features			= context.getDeviceVulkan12Features();
1660
1661	const auto&		vk10Properties			= context.getDeviceProperties2();
1662	const auto&		vk11Properties			= context.getDeviceVulkan11Properties();
1663	const auto&		vk12Properties			= context.getDeviceVulkan12Properties();
1664	const auto&		vk13Properties			= context.getDeviceVulkan13Properties();
1665	const auto&		limits					= vk10Properties.properties.limits;
1666
1667	#define ROADMAP_FEATURE_ITEM(STRUC, FIELD) { &(STRUC), &(STRUC.FIELD), #STRUC "." #FIELD }
1668
1669	struct FeatureTable
1670	{
1671		void*		structPtr;
1672		VkBool32*	fieldPtr;
1673		const char*	fieldName;
1674	};
1675
1676	std::vector<FeatureTable> featureTable
1677	{
1678		// Vulkan 1.0 Features
1679		ROADMAP_FEATURE_ITEM(vk10Features, fullDrawIndexUint32),
1680		ROADMAP_FEATURE_ITEM(vk10Features, imageCubeArray),
1681		ROADMAP_FEATURE_ITEM(vk10Features, independentBlend),
1682		ROADMAP_FEATURE_ITEM(vk10Features, sampleRateShading),
1683		ROADMAP_FEATURE_ITEM(vk10Features, drawIndirectFirstInstance),
1684		ROADMAP_FEATURE_ITEM(vk10Features, depthClamp),
1685		ROADMAP_FEATURE_ITEM(vk10Features, depthBiasClamp),
1686		ROADMAP_FEATURE_ITEM(vk10Features, samplerAnisotropy),
1687		ROADMAP_FEATURE_ITEM(vk10Features, occlusionQueryPrecise),
1688		ROADMAP_FEATURE_ITEM(vk10Features, fragmentStoresAndAtomics),
1689		ROADMAP_FEATURE_ITEM(vk10Features, shaderStorageImageExtendedFormats),
1690		ROADMAP_FEATURE_ITEM(vk10Features, shaderUniformBufferArrayDynamicIndexing),
1691		ROADMAP_FEATURE_ITEM(vk10Features, shaderSampledImageArrayDynamicIndexing),
1692		ROADMAP_FEATURE_ITEM(vk10Features, shaderStorageBufferArrayDynamicIndexing),
1693		ROADMAP_FEATURE_ITEM(vk10Features, shaderStorageImageArrayDynamicIndexing),
1694
1695		// Vulkan 1.1 Features
1696		ROADMAP_FEATURE_ITEM(vk11Features, samplerYcbcrConversion),
1697
1698		// Vulkan 1.2 Features
1699		ROADMAP_FEATURE_ITEM(vk12Features, samplerMirrorClampToEdge),
1700		ROADMAP_FEATURE_ITEM(vk12Features, descriptorIndexing),
1701		ROADMAP_FEATURE_ITEM(vk12Features, shaderUniformTexelBufferArrayDynamicIndexing),
1702		ROADMAP_FEATURE_ITEM(vk12Features, shaderStorageTexelBufferArrayDynamicIndexing),
1703		ROADMAP_FEATURE_ITEM(vk12Features, shaderUniformBufferArrayNonUniformIndexing),
1704		ROADMAP_FEATURE_ITEM(vk12Features, shaderSampledImageArrayNonUniformIndexing),
1705		ROADMAP_FEATURE_ITEM(vk12Features, shaderStorageBufferArrayNonUniformIndexing),
1706		ROADMAP_FEATURE_ITEM(vk12Features, shaderStorageImageArrayNonUniformIndexing),
1707		ROADMAP_FEATURE_ITEM(vk12Features, shaderUniformTexelBufferArrayNonUniformIndexing),
1708		ROADMAP_FEATURE_ITEM(vk12Features, shaderStorageTexelBufferArrayNonUniformIndexing),
1709		ROADMAP_FEATURE_ITEM(vk12Features, descriptorBindingSampledImageUpdateAfterBind),
1710		ROADMAP_FEATURE_ITEM(vk12Features, descriptorBindingStorageImageUpdateAfterBind),
1711		ROADMAP_FEATURE_ITEM(vk12Features, descriptorBindingStorageBufferUpdateAfterBind),
1712		ROADMAP_FEATURE_ITEM(vk12Features, descriptorBindingUniformTexelBufferUpdateAfterBind),
1713		ROADMAP_FEATURE_ITEM(vk12Features, descriptorBindingStorageTexelBufferUpdateAfterBind),
1714		ROADMAP_FEATURE_ITEM(vk12Features, descriptorBindingUpdateUnusedWhilePending),
1715		ROADMAP_FEATURE_ITEM(vk12Features, descriptorBindingPartiallyBound),
1716		ROADMAP_FEATURE_ITEM(vk12Features, descriptorBindingVariableDescriptorCount),
1717		ROADMAP_FEATURE_ITEM(vk12Features, runtimeDescriptorArray),
1718		ROADMAP_FEATURE_ITEM(vk12Features, scalarBlockLayout),
1719	};
1720
1721	for (FeatureTable& testedFeature : featureTable)
1722	{
1723		if (!testedFeature.fieldPtr[0])
1724		{
1725			log << TestLog::Message
1726				<< "Feature " << testedFeature.fieldName << "is not supported"
1727				<< TestLog::EndMessage;
1728			oneOrMoreChecksFailed = VK_TRUE;
1729		}
1730	}
1731
1732	std::vector<FeatureLimitTableItem> featureLimitTable
1733	{
1734		// Vulkan 1.0 limits
1735		{ PN(checkAlways),		PN(limits.maxImageDimension1D),								LIM_MIN_UINT32(8192) },
1736		{ PN(checkAlways),		PN(limits.maxImageDimension2D),								LIM_MIN_UINT32(8192) },
1737		{ PN(checkAlways),		PN(limits.maxImageDimensionCube),							LIM_MIN_UINT32(8192) },
1738		{ PN(checkAlways),		PN(limits.maxImageArrayLayers),								LIM_MIN_UINT32(2048) },
1739		{ PN(checkAlways),		PN(limits.maxUniformBufferRange),							LIM_MIN_UINT32(65536) },
1740		{ PN(checkAlways),		PN(limits.bufferImageGranularity),							LIM_MAX_DEVSIZE(4096) },
1741		{ PN(checkAlways),		PN(limits.maxPerStageDescriptorSamplers),					LIM_MIN_UINT32(64) },
1742		{ PN(checkAlways),		PN(limits.maxPerStageDescriptorUniformBuffers),				LIM_MIN_UINT32(15) },
1743		{ PN(checkAlways),		PN(limits.maxPerStageDescriptorStorageBuffers),				LIM_MIN_UINT32(30) },
1744		{ PN(checkAlways),		PN(limits.maxPerStageDescriptorSampledImages),				LIM_MIN_UINT32(200) },
1745		{ PN(checkAlways),		PN(limits.maxPerStageDescriptorStorageImages),				LIM_MIN_UINT32(16) },
1746		{ PN(checkAlways),		PN(limits.maxPerStageResources),							LIM_MIN_UINT32(200) },
1747		{ PN(checkAlways),		PN(limits.maxDescriptorSetSamplers),						LIM_MIN_UINT32(576) },
1748		{ PN(checkAlways),		PN(limits.maxDescriptorSetUniformBuffers),					LIM_MIN_UINT32(90) },
1749		{ PN(checkAlways),		PN(limits.maxDescriptorSetStorageBuffers),					LIM_MIN_UINT32(96) },
1750		{ PN(checkAlways),		PN(limits.maxDescriptorSetSampledImages),					LIM_MIN_UINT32(1800) },
1751		{ PN(checkAlways),		PN(limits.maxDescriptorSetStorageImages),					LIM_MIN_UINT32(144) },
1752		{ PN(checkAlways),		PN(limits.maxFragmentCombinedOutputResources),				LIM_MIN_UINT32(16) },
1753		{ PN(checkAlways),		PN(limits.maxComputeWorkGroupInvocations),					LIM_MIN_UINT32(256) },
1754		{ PN(checkAlways),		PN(limits.maxComputeWorkGroupSize[0]),						LIM_MIN_UINT32(256) },
1755		{ PN(checkAlways),		PN(limits.maxComputeWorkGroupSize[1]),						LIM_MIN_UINT32(256) },
1756		{ PN(checkAlways),		PN(limits.maxComputeWorkGroupSize[2]),						LIM_MIN_UINT32(64) },
1757		{ PN(checkAlways),		PN(limits.subPixelPrecisionBits),							LIM_MIN_UINT32(8) },
1758		{ PN(checkAlways),		PN(limits.mipmapPrecisionBits),								LIM_MIN_UINT32(6) },
1759		{ PN(checkAlways),		PN(limits.maxSamplerLodBias),								LIM_MIN_FLOAT(14.0f) },
1760		{ PN(checkAlways),		PN(limits.pointSizeGranularity),							LIM_MAX_FLOAT(0.125f) },
1761		{ PN(checkAlways),		PN(limits.lineWidthGranularity),							LIM_MAX_FLOAT(0.5f) },
1762		{ PN(checkAlways),		PN(limits.standardSampleLocations),							LIM_MIN_UINT32(1) },
1763		{ PN(checkAlways),		PN(limits.maxColorAttachments),								LIM_MIN_UINT32(7) },
1764
1765		// Vulkan 1.1 limits
1766		{ PN(checkAlways),		PN(vk11Properties.subgroupSize),							LIM_MIN_UINT32(4) },
1767		{ PN(checkAlways),		PN(vk11Properties.subgroupSupportedStages),					LIM_MIN_UINT32(VK_SHADER_STAGE_COMPUTE_BIT|VK_SHADER_STAGE_FRAGMENT_BIT) },
1768		{ PN(checkAlways),		PN(vk11Properties.subgroupSupportedOperations),				LIM_MIN_UINT32(VK_SUBGROUP_FEATURE_BASIC_BIT|VK_SUBGROUP_FEATURE_VOTE_BIT|
1769																										   VK_SUBGROUP_FEATURE_ARITHMETIC_BIT|VK_SUBGROUP_FEATURE_BALLOT_BIT|
1770																										   VK_SUBGROUP_FEATURE_SHUFFLE_BIT|VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT|
1771																										   VK_SUBGROUP_FEATURE_QUAD_BIT) },
1772		// Vulkan 1.2 limits
1773		{ PN(checkAlways),		PN(vk12Properties.shaderSignedZeroInfNanPreserveFloat16),	LIM_MIN_UINT32(1) },
1774		{ PN(checkAlways),		PN(vk12Properties.shaderSignedZeroInfNanPreserveFloat32),	LIM_MIN_UINT32(1) },
1775
1776		// Vulkan 1.3 limits
1777		{ PN(checkAlways),		PN(vk13Properties.maxSubgroupSize),							LIM_MIN_UINT32(4) },
1778	};
1779
1780	for (const auto& featureLimit : featureLimitTable)
1781		oneOrMoreChecksFailed |= !validateLimit(featureLimit, log);
1782
1783	if (!context.isDeviceFunctionalitySupported("VK_KHR_global_priority"))
1784	{
1785		log << TestLog::Message
1786			<< "VK_KHR_global_priority is not supported"
1787			<< TestLog::EndMessage;
1788		oneOrMoreChecksFailed = VK_TRUE;
1789	}
1790
1791	if (oneOrMoreChecksFailed)
1792		TCU_THROW(NotSupportedError, "Profile not supported");
1793
1794	return tcu::TestStatus::pass("Profile supported");
1795}
1796#endif // CTS_USES_VULKANSC
1797
1798
1799void createTestDevice (Context& context, void* pNext, const char* const* ppEnabledExtensionNames, deUint32 enabledExtensionCount)
1800{
1801	const PlatformInterface&				platformInterface		= context.getPlatformInterface();
1802	const auto								validationEnabled		= context.getTestContext().getCommandLine().isValidationEnabled();
1803	const Unique<VkInstance>				instance				(createDefaultInstance(platformInterface, context.getUsedApiVersion(), context.getTestContext().getCommandLine()));
1804	const InstanceDriver					instanceDriver			(platformInterface, instance.get());
1805	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, instance.get(), context.getTestContext().getCommandLine());
1806	const deUint32							queueFamilyIndex		= 0;
1807	const deUint32							queueCount				= 1;
1808	const deUint32							queueIndex				= 0;
1809	const float								queuePriority			= 1.0f;
1810	const vector<VkQueueFamilyProperties>	queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
1811	const VkDeviceQueueCreateInfo			deviceQueueCreateInfo	=
1812	{
1813		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	//  VkStructureType				sType;
1814		DE_NULL,									//  const void*					pNext;
1815		(VkDeviceQueueCreateFlags)0u,				//  VkDeviceQueueCreateFlags	flags;
1816		queueFamilyIndex,							//  deUint32					queueFamilyIndex;
1817		queueCount,									//  deUint32					queueCount;
1818		&queuePriority,								//  const float*				pQueuePriorities;
1819	};
1820#ifdef CTS_USES_VULKANSC
1821	VkDeviceObjectReservationCreateInfo	memReservationInfo			= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
1822	memReservationInfo.pNext										= pNext;
1823	pNext															= &memReservationInfo;
1824
1825	VkPhysicalDeviceVulkanSC10Features	sc10Features				= createDefaultSC10Features();
1826	sc10Features.pNext												= pNext;
1827	pNext															= &sc10Features;
1828
1829	VkPipelineCacheCreateInfo			pcCI;
1830	std::vector<VkPipelinePoolSize>		poolSizes;
1831	if (context.getTestContext().getCommandLine().isSubProcess())
1832	{
1833		if (context.getResourceInterface()->getCacheDataSize() > 0)
1834		{
1835			pcCI =
1836			{
1837				VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,		// VkStructureType				sType;
1838				DE_NULL,											// const void*					pNext;
1839				VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
1840					VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT,	// VkPipelineCacheCreateFlags	flags;
1841				context.getResourceInterface()->getCacheDataSize(),	// deUintptr					initialDataSize;
1842				context.getResourceInterface()->getCacheData()		// const void*					pInitialData;
1843			};
1844			memReservationInfo.pipelineCacheCreateInfoCount		= 1;
1845			memReservationInfo.pPipelineCacheCreateInfos		= &pcCI;
1846		}
1847
1848		poolSizes							= context.getResourceInterface()->getPipelinePoolSizes();
1849		if (!poolSizes.empty())
1850		{
1851			memReservationInfo.pipelinePoolSizeCount			= deUint32(poolSizes.size());
1852			memReservationInfo.pPipelinePoolSizes				= poolSizes.data();
1853		}
1854	}
1855#endif // CTS_USES_VULKANSC
1856
1857	const VkDeviceCreateInfo				deviceCreateInfo		=
1858	{
1859		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,		//  VkStructureType					sType;
1860		pNext,										//  const void*						pNext;
1861		(VkDeviceCreateFlags)0u,					//  VkDeviceCreateFlags				flags;
1862		1,											//  deUint32						queueCreateInfoCount;
1863		&deviceQueueCreateInfo,						//  const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
1864		0,											//  deUint32						enabledLayerCount;
1865		DE_NULL,									//  const char* const*				ppEnabledLayerNames;
1866		enabledExtensionCount,						//  deUint32						enabledExtensionCount;
1867		ppEnabledExtensionNames,					//  const char* const*				ppEnabledExtensionNames;
1868		DE_NULL,									//  const VkPhysicalDeviceFeatures*	pEnabledFeatures;
1869	};
1870	const Unique<VkDevice>					device					(createCustomDevice(validationEnabled, platformInterface, *instance, instanceDriver, physicalDevice, &deviceCreateInfo));
1871	const DeviceDriver						deviceDriver			(platformInterface, instance.get(), device.get(), context.getUsedApiVersion());
1872	const VkQueue							queue					= getDeviceQueue(deviceDriver, *device,  queueFamilyIndex, queueIndex);
1873
1874	VK_CHECK(deviceDriver.queueWaitIdle(queue));
1875}
1876
1877void cleanVulkanStruct (void* structPtr, size_t structSize)
1878{
1879	struct StructureBase
1880	{
1881		VkStructureType		sType;
1882		void*				pNext;
1883	};
1884
1885	VkStructureType		sType = ((StructureBase*)structPtr)->sType;
1886
1887	deMemset(structPtr, 0, structSize);
1888
1889	((StructureBase*)structPtr)->sType = sType;
1890}
1891
1892template <deUint32 VK_API_VERSION>
1893tcu::TestStatus featureBitInfluenceOnDeviceCreate (Context& context)
1894{
1895#define FEATURE_TABLE_ITEM(CORE, EXT, FIELD, STR) { &(CORE), sizeof(CORE), &(CORE.FIELD), #CORE "." #FIELD, &(EXT), sizeof(EXT), &(EXT.FIELD), #EXT "." #FIELD, STR }
1896#define DEPENDENCY_DUAL_ITEM(CORE, EXT, FIELD, PARENT) { &(CORE.FIELD), &(CORE.PARENT) }, { &(EXT.FIELD), &(EXT.PARENT) }
1897#define DEPENDENCY_SINGLE_ITEM(CORE, FIELD, PARENT) { &(CORE.FIELD), &(CORE.PARENT) }
1898
1899	const VkPhysicalDevice									physicalDevice							= context.getPhysicalDevice();
1900	const InstanceInterface&								vki										= context.getInstanceInterface();
1901	TestLog&												log										= context.getTestContext().getLog();
1902	const std::vector<VkExtensionProperties>				deviceExtensionProperties				= enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
1903
1904	VkPhysicalDeviceFeatures2								features2								= initVulkanStructure();
1905
1906	VkPhysicalDeviceVulkan11Features						vulkan11Features						= initVulkanStructure();
1907	VkPhysicalDeviceVulkan12Features						vulkan12Features						= initVulkanStructure();
1908	VkPhysicalDevice16BitStorageFeatures					sixteenBitStorageFeatures				= initVulkanStructure();
1909	VkPhysicalDeviceMultiviewFeatures						multiviewFeatures						= initVulkanStructure();
1910	VkPhysicalDeviceVariablePointersFeatures				variablePointersFeatures				= initVulkanStructure();
1911	VkPhysicalDeviceProtectedMemoryFeatures					protectedMemoryFeatures					= initVulkanStructure();
1912	VkPhysicalDeviceSamplerYcbcrConversionFeatures			samplerYcbcrConversionFeatures			= initVulkanStructure();
1913	VkPhysicalDeviceShaderDrawParametersFeatures			shaderDrawParametersFeatures			= initVulkanStructure();
1914	VkPhysicalDevice8BitStorageFeatures						eightBitStorageFeatures					= initVulkanStructure();
1915	VkPhysicalDeviceShaderAtomicInt64Features				shaderAtomicInt64Features				= initVulkanStructure();
1916	VkPhysicalDeviceShaderFloat16Int8Features				shaderFloat16Int8Features				= initVulkanStructure();
1917	VkPhysicalDeviceDescriptorIndexingFeatures				descriptorIndexingFeatures				= initVulkanStructure();
1918	VkPhysicalDeviceScalarBlockLayoutFeatures				scalarBlockLayoutFeatures				= initVulkanStructure();
1919	VkPhysicalDeviceImagelessFramebufferFeatures			imagelessFramebufferFeatures			= initVulkanStructure();
1920	VkPhysicalDeviceUniformBufferStandardLayoutFeatures		uniformBufferStandardLayoutFeatures		= initVulkanStructure();
1921	VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures		shaderSubgroupExtendedTypesFeatures		= initVulkanStructure();
1922	VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures		separateDepthStencilLayoutsFeatures		= initVulkanStructure();
1923	VkPhysicalDeviceHostQueryResetFeatures					hostQueryResetFeatures					= initVulkanStructure();
1924	VkPhysicalDeviceTimelineSemaphoreFeatures				timelineSemaphoreFeatures				= initVulkanStructure();
1925	VkPhysicalDeviceBufferDeviceAddressFeatures				bufferDeviceAddressFeatures				= initVulkanStructure();
1926	VkPhysicalDeviceVulkanMemoryModelFeatures				vulkanMemoryModelFeatures				= initVulkanStructure();
1927
1928#ifndef CTS_USES_VULKANSC
1929	VkPhysicalDeviceVulkan13Features						vulkan13Features						= initVulkanStructure();
1930	VkPhysicalDeviceImageRobustnessFeatures					imageRobustnessFeatures					= initVulkanStructure();
1931	VkPhysicalDeviceInlineUniformBlockFeatures				inlineUniformBlockFeatures				= initVulkanStructure();
1932	VkPhysicalDevicePipelineCreationCacheControlFeatures	pipelineCreationCacheControlFeatures	= initVulkanStructure();
1933	VkPhysicalDevicePrivateDataFeatures						privateDataFeatures						= initVulkanStructure();
1934	VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures	shaderDemoteToHelperInvocationFeatures	= initVulkanStructure();
1935	VkPhysicalDeviceShaderTerminateInvocationFeatures		shaderTerminateInvocationFeatures		= initVulkanStructure();
1936	VkPhysicalDeviceSubgroupSizeControlFeatures				subgroupSizeControlFeatures				= initVulkanStructure();
1937	VkPhysicalDeviceSynchronization2Features				synchronization2Features				= initVulkanStructure();
1938	VkPhysicalDeviceTextureCompressionASTCHDRFeatures		textureCompressionASTCHDRFeatures		= initVulkanStructure();
1939	VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures	zeroInitializeWorkgroupMemoryFeatures	= initVulkanStructure();
1940	VkPhysicalDeviceDynamicRenderingFeatures				dynamicRenderingFeatures				= initVulkanStructure();
1941	VkPhysicalDeviceShaderIntegerDotProductFeatures			shaderIntegerDotProductFeatures			= initVulkanStructure();
1942	VkPhysicalDeviceMaintenance4Features					maintenance4Features					= initVulkanStructure();
1943#endif // CTS_USES_VULKANSC
1944
1945	struct UnusedExtensionFeatures
1946	{
1947		VkStructureType		sType;
1948		void*				pNext;
1949		VkBool32			descriptorIndexing;
1950		VkBool32			samplerFilterMinmax;
1951	} unusedExtensionFeatures;
1952
1953	struct FeatureTable
1954	{
1955		void*		coreStructPtr;
1956		size_t		coreStructSize;
1957		VkBool32*	coreFieldPtr;
1958		const char*	coreFieldName;
1959		void*		extStructPtr;
1960		size_t		extStructSize;
1961		VkBool32*	extFieldPtr;
1962		const char*	extFieldName;
1963		const char*	extString;
1964	};
1965	struct FeatureDependencyTable
1966	{
1967		VkBool32*	featurePtr;
1968		VkBool32*	dependOnPtr;
1969	};
1970
1971	std::vector<FeatureTable>			featureTable;
1972	std::vector<FeatureDependencyTable>	featureDependencyTable;
1973
1974	if (VK_API_VERSION == VK_API_VERSION_1_2)
1975	{
1976		featureTable =
1977		{
1978			FEATURE_TABLE_ITEM(vulkan11Features,	sixteenBitStorageFeatures,				storageBuffer16BitAccess,							"VK_KHR_16bit_storage"),
1979			FEATURE_TABLE_ITEM(vulkan11Features,	sixteenBitStorageFeatures,				uniformAndStorageBuffer16BitAccess,					"VK_KHR_16bit_storage"),
1980			FEATURE_TABLE_ITEM(vulkan11Features,	sixteenBitStorageFeatures,				storagePushConstant16,								"VK_KHR_16bit_storage"),
1981			FEATURE_TABLE_ITEM(vulkan11Features,	sixteenBitStorageFeatures,				storageInputOutput16,								"VK_KHR_16bit_storage"),
1982			FEATURE_TABLE_ITEM(vulkan11Features,	multiviewFeatures,						multiview,											"VK_KHR_multiview"),
1983			FEATURE_TABLE_ITEM(vulkan11Features,	multiviewFeatures,						multiviewGeometryShader,							"VK_KHR_multiview"),
1984			FEATURE_TABLE_ITEM(vulkan11Features,	multiviewFeatures,						multiviewTessellationShader,						"VK_KHR_multiview"),
1985			FEATURE_TABLE_ITEM(vulkan11Features,	variablePointersFeatures,				variablePointersStorageBuffer,						"VK_KHR_variable_pointers"),
1986			FEATURE_TABLE_ITEM(vulkan11Features,	variablePointersFeatures,				variablePointers,									"VK_KHR_variable_pointers"),
1987			FEATURE_TABLE_ITEM(vulkan11Features,	protectedMemoryFeatures,				protectedMemory,									DE_NULL),
1988			FEATURE_TABLE_ITEM(vulkan11Features,	samplerYcbcrConversionFeatures,			samplerYcbcrConversion,								"VK_KHR_sampler_ycbcr_conversion"),
1989			FEATURE_TABLE_ITEM(vulkan11Features,	shaderDrawParametersFeatures,			shaderDrawParameters,								DE_NULL),
1990			FEATURE_TABLE_ITEM(vulkan12Features,	eightBitStorageFeatures,				storageBuffer8BitAccess,							"VK_KHR_8bit_storage"),
1991			FEATURE_TABLE_ITEM(vulkan12Features,	eightBitStorageFeatures,				uniformAndStorageBuffer8BitAccess,					"VK_KHR_8bit_storage"),
1992			FEATURE_TABLE_ITEM(vulkan12Features,	eightBitStorageFeatures,				storagePushConstant8,								"VK_KHR_8bit_storage"),
1993			FEATURE_TABLE_ITEM(vulkan12Features,	shaderAtomicInt64Features,				shaderBufferInt64Atomics,							"VK_KHR_shader_atomic_int64"),
1994			FEATURE_TABLE_ITEM(vulkan12Features,	shaderAtomicInt64Features,				shaderSharedInt64Atomics,							"VK_KHR_shader_atomic_int64"),
1995			FEATURE_TABLE_ITEM(vulkan12Features,	shaderFloat16Int8Features,				shaderFloat16,										"VK_KHR_shader_float16_int8"),
1996			FEATURE_TABLE_ITEM(vulkan12Features,	shaderFloat16Int8Features,				shaderInt8,											"VK_KHR_shader_float16_int8"),
1997			FEATURE_TABLE_ITEM(vulkan12Features,	unusedExtensionFeatures,					descriptorIndexing,									DE_NULL),
1998			FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				shaderInputAttachmentArrayDynamicIndexing,			"VK_EXT_descriptor_indexing"),
1999			FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				shaderUniformTexelBufferArrayDynamicIndexing,		"VK_EXT_descriptor_indexing"),
2000			FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				shaderStorageTexelBufferArrayDynamicIndexing,		"VK_EXT_descriptor_indexing"),
2001			FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				shaderUniformBufferArrayNonUniformIndexing,			"VK_EXT_descriptor_indexing"),
2002			FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				shaderSampledImageArrayNonUniformIndexing,			"VK_EXT_descriptor_indexing"),
2003			FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				shaderStorageBufferArrayNonUniformIndexing,			"VK_EXT_descriptor_indexing"),
2004			FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				shaderStorageImageArrayNonUniformIndexing,			"VK_EXT_descriptor_indexing"),
2005			FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				shaderInputAttachmentArrayNonUniformIndexing,		"VK_EXT_descriptor_indexing"),
2006			FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				shaderUniformTexelBufferArrayNonUniformIndexing,	"VK_EXT_descriptor_indexing"),
2007			FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				shaderStorageTexelBufferArrayNonUniformIndexing,	"VK_EXT_descriptor_indexing"),
2008			FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				descriptorBindingUniformBufferUpdateAfterBind,		"VK_EXT_descriptor_indexing"),
2009			FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				descriptorBindingSampledImageUpdateAfterBind,		"VK_EXT_descriptor_indexing"),
2010			FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				descriptorBindingStorageImageUpdateAfterBind,		"VK_EXT_descriptor_indexing"),
2011			FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				descriptorBindingStorageBufferUpdateAfterBind,		"VK_EXT_descriptor_indexing"),
2012			FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				descriptorBindingUniformTexelBufferUpdateAfterBind,	"VK_EXT_descriptor_indexing"),
2013			FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				descriptorBindingStorageTexelBufferUpdateAfterBind,	"VK_EXT_descriptor_indexing"),
2014			FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				descriptorBindingUpdateUnusedWhilePending,			"VK_EXT_descriptor_indexing"),
2015			FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				descriptorBindingPartiallyBound,					"VK_EXT_descriptor_indexing"),
2016			FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				descriptorBindingVariableDescriptorCount,			"VK_EXT_descriptor_indexing"),
2017			FEATURE_TABLE_ITEM(vulkan12Features,	descriptorIndexingFeatures,				runtimeDescriptorArray,								"VK_EXT_descriptor_indexing"),
2018			FEATURE_TABLE_ITEM(vulkan12Features,	unusedExtensionFeatures,					samplerFilterMinmax,								"VK_EXT_sampler_filter_minmax"),
2019			FEATURE_TABLE_ITEM(vulkan12Features,	scalarBlockLayoutFeatures,				scalarBlockLayout,									"VK_EXT_scalar_block_layout"),
2020			FEATURE_TABLE_ITEM(vulkan12Features,	imagelessFramebufferFeatures,			imagelessFramebuffer,								"VK_KHR_imageless_framebuffer"),
2021			FEATURE_TABLE_ITEM(vulkan12Features,	uniformBufferStandardLayoutFeatures,	uniformBufferStandardLayout,						"VK_KHR_uniform_buffer_standard_layout"),
2022			FEATURE_TABLE_ITEM(vulkan12Features,	shaderSubgroupExtendedTypesFeatures,	shaderSubgroupExtendedTypes,						"VK_KHR_shader_subgroup_extended_types"),
2023			FEATURE_TABLE_ITEM(vulkan12Features,	separateDepthStencilLayoutsFeatures,	separateDepthStencilLayouts,						"VK_KHR_separate_depth_stencil_layouts"),
2024			FEATURE_TABLE_ITEM(vulkan12Features,	hostQueryResetFeatures,					hostQueryReset,										"VK_EXT_host_query_reset"),
2025			FEATURE_TABLE_ITEM(vulkan12Features,	timelineSemaphoreFeatures,				timelineSemaphore,									"VK_KHR_timeline_semaphore"),
2026			FEATURE_TABLE_ITEM(vulkan12Features,	bufferDeviceAddressFeatures,			bufferDeviceAddress,								"VK_EXT_buffer_device_address"),
2027			FEATURE_TABLE_ITEM(vulkan12Features,	bufferDeviceAddressFeatures,			bufferDeviceAddressCaptureReplay,					"VK_EXT_buffer_device_address"),
2028			FEATURE_TABLE_ITEM(vulkan12Features,	bufferDeviceAddressFeatures,			bufferDeviceAddressMultiDevice,						"VK_EXT_buffer_device_address"),
2029			FEATURE_TABLE_ITEM(vulkan12Features,	vulkanMemoryModelFeatures,				vulkanMemoryModel,									"VK_KHR_vulkan_memory_model"),
2030			FEATURE_TABLE_ITEM(vulkan12Features,	vulkanMemoryModelFeatures,				vulkanMemoryModelDeviceScope,						"VK_KHR_vulkan_memory_model"),
2031			FEATURE_TABLE_ITEM(vulkan12Features,	vulkanMemoryModelFeatures,				vulkanMemoryModelAvailabilityVisibilityChains,		"VK_KHR_vulkan_memory_model"),
2032		};
2033
2034		featureDependencyTable =
2035		{
2036			DEPENDENCY_DUAL_ITEM	(vulkan11Features,	multiviewFeatures,				multiviewGeometryShader,							multiview),
2037			DEPENDENCY_DUAL_ITEM	(vulkan11Features,	multiviewFeatures,				multiviewTessellationShader,						multiview),
2038			DEPENDENCY_DUAL_ITEM	(vulkan11Features,	variablePointersFeatures,		variablePointers,									variablePointersStorageBuffer),
2039			DEPENDENCY_DUAL_ITEM	(vulkan12Features,	bufferDeviceAddressFeatures,	bufferDeviceAddressCaptureReplay,					bufferDeviceAddress),
2040			DEPENDENCY_DUAL_ITEM	(vulkan12Features,	bufferDeviceAddressFeatures,	bufferDeviceAddressMultiDevice,						bufferDeviceAddress),
2041			DEPENDENCY_DUAL_ITEM	(vulkan12Features,	vulkanMemoryModelFeatures,		vulkanMemoryModelDeviceScope,						vulkanMemoryModel),
2042			DEPENDENCY_DUAL_ITEM	(vulkan12Features,	vulkanMemoryModelFeatures,		vulkanMemoryModelAvailabilityVisibilityChains,		vulkanMemoryModel),
2043		};
2044	}
2045#ifndef CTS_USES_VULKANSC
2046	else // if (VK_API_VERSION == VK_API_VERSION_1_3)
2047	{
2048		featureTable =
2049		{
2050			FEATURE_TABLE_ITEM(vulkan13Features,	imageRobustnessFeatures,				robustImageAccess,									"VK_EXT_image_robustness"),
2051			FEATURE_TABLE_ITEM(vulkan13Features,	inlineUniformBlockFeatures,				inlineUniformBlock,									"VK_EXT_inline_uniform_block"),
2052			FEATURE_TABLE_ITEM(vulkan13Features,	inlineUniformBlockFeatures,				descriptorBindingInlineUniformBlockUpdateAfterBind,	"VK_EXT_inline_uniform_block"),
2053			FEATURE_TABLE_ITEM(vulkan13Features,	pipelineCreationCacheControlFeatures,	pipelineCreationCacheControl,						"VK_EXT_pipeline_creation_cache_control"),
2054			FEATURE_TABLE_ITEM(vulkan13Features,	privateDataFeatures,					privateData,										"VK_EXT_private_data"),
2055			FEATURE_TABLE_ITEM(vulkan13Features,	shaderDemoteToHelperInvocationFeatures,	shaderDemoteToHelperInvocation,						"VK_EXT_shader_demote_to_helper_invocation"),
2056			FEATURE_TABLE_ITEM(vulkan13Features,	shaderTerminateInvocationFeatures,		shaderTerminateInvocation,							"VK_KHR_shader_terminate_invocation"),
2057			FEATURE_TABLE_ITEM(vulkan13Features,	subgroupSizeControlFeatures,			subgroupSizeControl,								"VK_EXT_subgroup_size_control"),
2058			FEATURE_TABLE_ITEM(vulkan13Features,	subgroupSizeControlFeatures,			computeFullSubgroups,								"VK_EXT_subgroup_size_control"),
2059			FEATURE_TABLE_ITEM(vulkan13Features,	synchronization2Features,				synchronization2,									"VK_KHR_synchronization2"),
2060			FEATURE_TABLE_ITEM(vulkan13Features,	textureCompressionASTCHDRFeatures,		textureCompressionASTC_HDR,							"VK_EXT_texture_compression_astc_hdr"),
2061			FEATURE_TABLE_ITEM(vulkan13Features,	zeroInitializeWorkgroupMemoryFeatures,	shaderZeroInitializeWorkgroupMemory,				"VK_KHR_zero_initialize_workgroup_memory"),
2062			FEATURE_TABLE_ITEM(vulkan13Features,	dynamicRenderingFeatures,				dynamicRendering,									"VK_KHR_dynamic_rendering"),
2063			FEATURE_TABLE_ITEM(vulkan13Features,	shaderIntegerDotProductFeatures,		shaderIntegerDotProduct,							"VK_KHR_shader_integer_dot_product"),
2064			FEATURE_TABLE_ITEM(vulkan13Features,	maintenance4Features,					maintenance4,										"VK_KHR_maintenance4"),
2065		};
2066	}
2067#endif // CTS_USES_VULKANSC
2068
2069	deMemset(&unusedExtensionFeatures, 0, sizeof(unusedExtensionFeatures));
2070
2071	for (FeatureTable&	testedFeature : featureTable)
2072	{
2073		VkBool32		coreFeatureState= DE_FALSE;
2074		VkBool32		extFeatureState	= DE_FALSE;
2075
2076		// Core test
2077		{
2078			void*		structPtr	= testedFeature.coreStructPtr;
2079			size_t		structSize	= testedFeature.coreStructSize;
2080			VkBool32*	featurePtr	= testedFeature.coreFieldPtr;
2081
2082			if (structPtr != &unusedExtensionFeatures)
2083				features2.pNext	= structPtr;
2084
2085			vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
2086
2087			coreFeatureState = featurePtr[0];
2088
2089			log << TestLog::Message
2090				<< "Feature status "
2091				<< testedFeature.coreFieldName << "=" << coreFeatureState
2092				<< TestLog::EndMessage;
2093
2094			if (coreFeatureState)
2095			{
2096				cleanVulkanStruct(structPtr, structSize);
2097
2098				featurePtr[0] = DE_TRUE;
2099
2100				for (FeatureDependencyTable featureDependency : featureDependencyTable)
2101					if (featureDependency.featurePtr == featurePtr)
2102						featureDependency.dependOnPtr[0] = DE_TRUE;
2103
2104				createTestDevice(context, &features2, DE_NULL, 0u);
2105			}
2106		}
2107
2108		// ext test
2109		{
2110			void*		structPtr		= testedFeature.extStructPtr;
2111			size_t		structSize		= testedFeature.extStructSize;
2112			VkBool32*	featurePtr		= testedFeature.extFieldPtr;
2113			const char*	extStringPtr	= testedFeature.extString;
2114
2115			if (structPtr != &unusedExtensionFeatures)
2116				features2.pNext	= structPtr;
2117
2118			if (extStringPtr == DE_NULL || isExtensionStructSupported(deviceExtensionProperties, RequiredExtension(extStringPtr)))
2119			{
2120				vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
2121
2122				extFeatureState = *featurePtr;
2123
2124				log << TestLog::Message
2125					<< "Feature status "
2126					<< testedFeature.extFieldName << "=" << extFeatureState
2127					<< TestLog::EndMessage;
2128
2129				if (extFeatureState)
2130				{
2131					cleanVulkanStruct(structPtr, structSize);
2132
2133					featurePtr[0] = DE_TRUE;
2134
2135					for (FeatureDependencyTable& featureDependency : featureDependencyTable)
2136						if (featureDependency.featurePtr == featurePtr)
2137							featureDependency.dependOnPtr[0] = DE_TRUE;
2138
2139					createTestDevice(context, &features2, &extStringPtr, (extStringPtr == DE_NULL) ? 0u : 1u );
2140				}
2141			}
2142		}
2143	}
2144
2145	return tcu::TestStatus::pass("pass");
2146}
2147
2148template<typename T>
2149class CheckIncompleteResult
2150{
2151public:
2152	virtual			~CheckIncompleteResult	(void) {}
2153	virtual void	getResult				(Context& context, T* data) = 0;
2154
2155	void operator() (Context& context, tcu::ResultCollector& results, const std::size_t expectedCompleteSize)
2156	{
2157		if (expectedCompleteSize == 0)
2158			return;
2159
2160		vector<T>		outputData	(expectedCompleteSize);
2161		const deUint32	usedSize	= static_cast<deUint32>(expectedCompleteSize / 3);
2162
2163		ValidateQueryBits::fillBits(outputData.begin(), outputData.end());	// unused entries should have this pattern intact
2164		m_count		= usedSize;
2165		m_result	= VK_SUCCESS;
2166
2167		getResult(context, &outputData[0]);									// update m_count and m_result
2168
2169		if (m_count != usedSize || m_result != VK_INCOMPLETE || !ValidateQueryBits::checkBits(outputData.begin() + m_count, outputData.end()))
2170			results.fail("Query didn't return VK_INCOMPLETE");
2171	}
2172
2173protected:
2174	deUint32	m_count;
2175	VkResult	m_result;
2176};
2177
2178struct CheckEnumeratePhysicalDevicesIncompleteResult : public CheckIncompleteResult<VkPhysicalDevice>
2179{
2180	void getResult (Context& context, VkPhysicalDevice* data)
2181	{
2182		m_result = context.getInstanceInterface().enumeratePhysicalDevices(context.getInstance(), &m_count, data);
2183	}
2184};
2185
2186struct CheckEnumeratePhysicalDeviceGroupsIncompleteResult : public CheckIncompleteResult<VkPhysicalDeviceGroupProperties>
2187{
2188	CheckEnumeratePhysicalDeviceGroupsIncompleteResult (const InstanceInterface& vki, const VkInstance instance)
2189		: m_vki			(vki)
2190		, m_instance	(instance)
2191		{}
2192
2193	void getResult (Context&, VkPhysicalDeviceGroupProperties* data)
2194	{
2195		for (uint32_t idx = 0u; idx < m_count; ++idx)
2196			data[idx] = initVulkanStructure();
2197		m_result = m_vki.enumeratePhysicalDeviceGroups(m_instance, &m_count, data);
2198	}
2199
2200protected:
2201	const InstanceInterface&	m_vki;
2202	const VkInstance			m_instance;
2203};
2204
2205struct CheckEnumerateInstanceLayerPropertiesIncompleteResult : public CheckIncompleteResult<VkLayerProperties>
2206{
2207	void getResult (Context& context, VkLayerProperties* data)
2208	{
2209		m_result = context.getPlatformInterface().enumerateInstanceLayerProperties(&m_count, data);
2210	}
2211};
2212
2213struct CheckEnumerateDeviceLayerPropertiesIncompleteResult : public CheckIncompleteResult<VkLayerProperties>
2214{
2215	void getResult (Context& context, VkLayerProperties* data)
2216	{
2217		m_result = context.getInstanceInterface().enumerateDeviceLayerProperties(context.getPhysicalDevice(), &m_count, data);
2218	}
2219};
2220
2221struct CheckEnumerateInstanceExtensionPropertiesIncompleteResult : public CheckIncompleteResult<VkExtensionProperties>
2222{
2223	CheckEnumerateInstanceExtensionPropertiesIncompleteResult (std::string layerName = std::string()) : m_layerName(layerName) {}
2224
2225	void getResult (Context& context, VkExtensionProperties* data)
2226	{
2227		const char* pLayerName = (m_layerName.length() != 0 ? m_layerName.c_str() : DE_NULL);
2228		m_result = context.getPlatformInterface().enumerateInstanceExtensionProperties(pLayerName, &m_count, data);
2229	}
2230
2231private:
2232	const std::string	m_layerName;
2233};
2234
2235struct CheckEnumerateDeviceExtensionPropertiesIncompleteResult : public CheckIncompleteResult<VkExtensionProperties>
2236{
2237	CheckEnumerateDeviceExtensionPropertiesIncompleteResult (std::string layerName = std::string()) : m_layerName(layerName) {}
2238
2239	void getResult (Context& context, VkExtensionProperties* data)
2240	{
2241		const char* pLayerName = (m_layerName.length() != 0 ? m_layerName.c_str() : DE_NULL);
2242		m_result = context.getInstanceInterface().enumerateDeviceExtensionProperties(context.getPhysicalDevice(), pLayerName, &m_count, data);
2243	}
2244
2245private:
2246	const std::string	m_layerName;
2247};
2248
2249tcu::TestStatus enumeratePhysicalDevices (Context& context)
2250{
2251	TestLog&						log		= context.getTestContext().getLog();
2252	tcu::ResultCollector			results	(log);
2253	const vector<VkPhysicalDevice>	devices	= enumeratePhysicalDevices(context.getInstanceInterface(), context.getInstance());
2254
2255	log << TestLog::Integer("NumDevices", "Number of devices", "", QP_KEY_TAG_NONE, deInt64(devices.size()));
2256
2257	for (size_t ndx = 0; ndx < devices.size(); ndx++)
2258		log << TestLog::Message << ndx << ": " << devices[ndx] << TestLog::EndMessage;
2259
2260	CheckEnumeratePhysicalDevicesIncompleteResult()(context, results, devices.size());
2261
2262	return tcu::TestStatus(results.getResult(), results.getMessage());
2263}
2264
2265tcu::TestStatus enumeratePhysicalDeviceGroups (Context& context)
2266{
2267	TestLog&											log				= context.getTestContext().getLog();
2268	tcu::ResultCollector								results			(log);
2269	CustomInstance										instance		(createCustomInstanceWithExtension(context, "VK_KHR_device_group_creation"));
2270	const InstanceDriver&								vki				(instance.getDriver());
2271	const vector<VkPhysicalDeviceGroupProperties>		devicegroups	= enumeratePhysicalDeviceGroups(vki, instance);
2272
2273	log << TestLog::Integer("NumDevices", "Number of device groups", "", QP_KEY_TAG_NONE, deInt64(devicegroups.size()));
2274
2275	for (size_t ndx = 0; ndx < devicegroups.size(); ndx++)
2276		log << TestLog::Message << ndx << ": " << devicegroups[ndx] << TestLog::EndMessage;
2277
2278	CheckEnumeratePhysicalDeviceGroupsIncompleteResult(vki, instance)(context, results, devicegroups.size());
2279
2280	instance.collectMessages();
2281	return tcu::TestStatus(results.getResult(), results.getMessage());
2282}
2283
2284template<typename T>
2285void collectDuplicates (set<T>& duplicates, const vector<T>& values)
2286{
2287	set<T> seen;
2288
2289	for (size_t ndx = 0; ndx < values.size(); ndx++)
2290	{
2291		const T& value = values[ndx];
2292
2293		if (!seen.insert(value).second)
2294			duplicates.insert(value);
2295	}
2296}
2297
2298void checkDuplicates (tcu::ResultCollector& results, const char* what, const vector<string>& values)
2299{
2300	set<string> duplicates;
2301
2302	collectDuplicates(duplicates, values);
2303
2304	for (set<string>::const_iterator iter = duplicates.begin(); iter != duplicates.end(); ++iter)
2305	{
2306		std::ostringstream msg;
2307		msg << "Duplicate " << what << ": " << *iter;
2308		results.fail(msg.str());
2309	}
2310}
2311
2312void checkDuplicateExtensions (tcu::ResultCollector& results, const vector<string>& extensions)
2313{
2314	checkDuplicates(results, "extension", extensions);
2315}
2316
2317void checkDuplicateLayers (tcu::ResultCollector& results, const vector<string>& layers)
2318{
2319	checkDuplicates(results, "layer", layers);
2320}
2321
2322void checkKhrExtensions (tcu::ResultCollector&		results,
2323						 const vector<string>&		extensions,
2324						 const int					numAllowedKhrExtensions,
2325						 const char* const*			allowedKhrExtensions)
2326{
2327	const set<string>	allowedExtSet		(allowedKhrExtensions, allowedKhrExtensions+numAllowedKhrExtensions);
2328
2329	for (vector<string>::const_iterator extIter = extensions.begin(); extIter != extensions.end(); ++extIter)
2330	{
2331		// Only Khronos-controlled extensions are checked
2332		if (de::beginsWith(*extIter, "VK_KHR_") &&
2333			!de::contains(allowedExtSet, *extIter))
2334		{
2335			results.fail("Unknown extension " + *extIter);
2336		}
2337	}
2338}
2339
2340void checkInstanceExtensions (tcu::ResultCollector& results, const vector<string>& extensions)
2341{
2342#include "vkInstanceExtensions.inl"
2343
2344	checkKhrExtensions(results, extensions, DE_LENGTH_OF_ARRAY(s_allowedInstanceKhrExtensions), s_allowedInstanceKhrExtensions);
2345	checkDuplicateExtensions(results, extensions);
2346}
2347
2348void checkDeviceExtensions (tcu::ResultCollector& results, const vector<string>& extensions)
2349{
2350#include "vkDeviceExtensions.inl"
2351
2352	checkKhrExtensions(results, extensions, DE_LENGTH_OF_ARRAY(s_allowedDeviceKhrExtensions), s_allowedDeviceKhrExtensions);
2353	checkDuplicateExtensions(results, extensions);
2354}
2355
2356#ifndef CTS_USES_VULKANSC
2357
2358void checkExtensionDependencies(tcu::ResultCollector&		results,
2359								const DependencyCheckVect&	dependencies,
2360								deUint32					versionMajor,
2361								deUint32					versionMinor,
2362								const ExtPropVect&			instanceExtensionProperties,
2363								const ExtPropVect&			deviceExtensionProperties)
2364{
2365	tcu::UVec2 v(versionMajor, versionMinor);
2366	for (const auto& dependency : dependencies)
2367	{
2368		// call function that will check all extension dependencies
2369		if (!dependency.second(v, instanceExtensionProperties, deviceExtensionProperties))
2370		{
2371			results.fail("Extension " + string(dependency.first) + " is missing dependency");
2372		}
2373	}
2374}
2375
2376#endif // CTS_USES_VULKANSC
2377
2378tcu::TestStatus enumerateInstanceLayers (Context& context)
2379{
2380	TestLog&						log					= context.getTestContext().getLog();
2381	tcu::ResultCollector			results				(log);
2382	const vector<VkLayerProperties>	properties			= enumerateInstanceLayerProperties(context.getPlatformInterface());
2383	vector<string>					layerNames;
2384
2385	for (size_t ndx = 0; ndx < properties.size(); ndx++)
2386	{
2387		log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage;
2388
2389		layerNames.push_back(properties[ndx].layerName);
2390	}
2391
2392	checkDuplicateLayers(results, layerNames);
2393	CheckEnumerateInstanceLayerPropertiesIncompleteResult()(context, results, layerNames.size());
2394
2395	return tcu::TestStatus(results.getResult(), results.getMessage());
2396}
2397
2398tcu::TestStatus enumerateInstanceExtensions (Context& context)
2399{
2400	TestLog&				log		= context.getTestContext().getLog();
2401	tcu::ResultCollector	results	(log);
2402
2403	{
2404		const ScopedLogSection				section		(log, "Global", "Global Extensions");
2405		const vector<VkExtensionProperties>	properties	= enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL);
2406		const vector<VkExtensionProperties>	unused;
2407		vector<string>						extensionNames;
2408
2409		for (size_t ndx = 0; ndx < properties.size(); ndx++)
2410		{
2411			log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage;
2412
2413			extensionNames.push_back(properties[ndx].extensionName);
2414		}
2415
2416		checkInstanceExtensions(results, extensionNames);
2417		CheckEnumerateInstanceExtensionPropertiesIncompleteResult()(context, results, properties.size());
2418
2419#ifndef CTS_USES_VULKANSC
2420		for (const auto& version : releasedApiVersions)
2421		{
2422			deUint32 apiVariant, versionMajor, versionMinor;
2423			std::tie(std::ignore, apiVariant, versionMajor, versionMinor) = version;
2424			if (context.contextSupports(vk::ApiVersion(apiVariant, versionMajor, versionMinor, 0)))
2425			{
2426				checkExtensionDependencies(results,
2427					instanceExtensionDependencies,
2428					versionMajor,
2429					versionMinor,
2430					properties,
2431					unused);
2432				break;
2433			}
2434		}
2435#endif // CTS_USES_VULKANSC
2436
2437	}
2438
2439	{
2440		const vector<VkLayerProperties>	layers	= enumerateInstanceLayerProperties(context.getPlatformInterface());
2441
2442		for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
2443		{
2444			const ScopedLogSection				section				(log, layer->layerName, string("Layer: ") + layer->layerName);
2445			const vector<VkExtensionProperties>	properties			= enumerateInstanceExtensionProperties(context.getPlatformInterface(), layer->layerName);
2446			vector<string>						extensionNames;
2447
2448			for (size_t extNdx = 0; extNdx < properties.size(); extNdx++)
2449			{
2450				log << TestLog::Message << extNdx << ": " << properties[extNdx] << TestLog::EndMessage;
2451
2452				extensionNames.push_back(properties[extNdx].extensionName);
2453			}
2454
2455			checkInstanceExtensions(results, extensionNames);
2456			CheckEnumerateInstanceExtensionPropertiesIncompleteResult(layer->layerName)(context, results, properties.size());
2457		}
2458	}
2459
2460	return tcu::TestStatus(results.getResult(), results.getMessage());
2461}
2462
2463tcu::TestStatus validateDeviceLevelEntryPointsFromInstanceExtensions(Context& context)
2464{
2465
2466#include "vkEntryPointValidation.inl"
2467
2468	TestLog&				log		(context.getTestContext().getLog());
2469	tcu::ResultCollector	results	(log);
2470	const DeviceInterface&	vk		(context.getDeviceInterface());
2471	const VkDevice			device	(context.getDevice());
2472
2473	for (const auto& keyValue : instExtDeviceFun)
2474	{
2475		const std::string& extensionName = keyValue.first;
2476		if (!context.isInstanceFunctionalitySupported(extensionName))
2477			continue;
2478
2479		for (const auto& deviceEntryPoint : keyValue.second)
2480		{
2481			if (!vk.getDeviceProcAddr(device, deviceEntryPoint.c_str()))
2482				results.fail("Missing " + deviceEntryPoint);
2483		}
2484	}
2485
2486	return tcu::TestStatus(results.getResult(), results.getMessage());
2487}
2488
2489tcu::TestStatus testNoKhxExtensions (Context& context)
2490{
2491	VkPhysicalDevice			physicalDevice	= context.getPhysicalDevice();
2492	const PlatformInterface&	vkp				= context.getPlatformInterface();
2493	const InstanceInterface&	vki				= context.getInstanceInterface();
2494
2495	tcu::ResultCollector		results(context.getTestContext().getLog());
2496	bool						testSucceeded = true;
2497	deUint32					instanceExtensionsCount;
2498	deUint32					deviceExtensionsCount;
2499
2500	// grab number of instance and device extensions
2501	vkp.enumerateInstanceExtensionProperties(DE_NULL, &instanceExtensionsCount, DE_NULL);
2502	vki.enumerateDeviceExtensionProperties(physicalDevice, DE_NULL, &deviceExtensionsCount, DE_NULL);
2503	vector<VkExtensionProperties> extensionsProperties(instanceExtensionsCount + deviceExtensionsCount);
2504
2505	// grab instance and device extensions into single vector
2506	if (instanceExtensionsCount)
2507		vkp.enumerateInstanceExtensionProperties(DE_NULL, &instanceExtensionsCount, &extensionsProperties[0]);
2508	if (deviceExtensionsCount)
2509		vki.enumerateDeviceExtensionProperties(physicalDevice, DE_NULL, &deviceExtensionsCount, &extensionsProperties[instanceExtensionsCount]);
2510
2511	// iterate over all extensions and verify their names
2512	vector<VkExtensionProperties>::const_iterator extension = extensionsProperties.begin();
2513	while (extension != extensionsProperties.end())
2514	{
2515		// KHX author ID is no longer used, all KHX extensions have been promoted to KHR status
2516		std::string extensionName(extension->extensionName);
2517		bool caseFailed = de::beginsWith(extensionName, "VK_KHX_");
2518		if (caseFailed)
2519		{
2520			results.fail("Invalid extension name " + extensionName);
2521			testSucceeded = false;
2522		}
2523		++extension;
2524	}
2525
2526	if (testSucceeded)
2527		return tcu::TestStatus::pass("No extensions begining with \"VK_KHX\"");
2528	return tcu::TestStatus::fail("One or more extensions begins with \"VK_KHX\"");
2529}
2530
2531tcu::TestStatus enumerateDeviceLayers (Context& context)
2532{
2533	TestLog&						log			= context.getTestContext().getLog();
2534	tcu::ResultCollector			results		(log);
2535	const vector<VkLayerProperties>	properties	= enumerateDeviceLayerProperties(context.getInstanceInterface(), context.getPhysicalDevice());
2536	vector<string>					layerNames;
2537
2538	for (size_t ndx = 0; ndx < properties.size(); ndx++)
2539	{
2540		log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage;
2541
2542		layerNames.push_back(properties[ndx].layerName);
2543	}
2544
2545	checkDuplicateLayers(results, layerNames);
2546	CheckEnumerateDeviceLayerPropertiesIncompleteResult()(context, results, layerNames.size());
2547
2548	return tcu::TestStatus(results.getResult(), results.getMessage());
2549}
2550
2551tcu::TestStatus enumerateDeviceExtensions (Context& context)
2552{
2553	TestLog&				log		= context.getTestContext().getLog();
2554	tcu::ResultCollector	results	(log);
2555
2556	{
2557		const ScopedLogSection				section						(log, "Global", "Global Extensions");
2558		const vector<VkExtensionProperties>	instanceExtensionProperties	= enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL);
2559		const vector<VkExtensionProperties>	deviceExtensionProperties	= enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), DE_NULL);
2560		vector<string>						deviceExtensionNames;
2561
2562		for (size_t ndx = 0; ndx < deviceExtensionProperties.size(); ndx++)
2563		{
2564			log << TestLog::Message << ndx << ": " << deviceExtensionProperties[ndx] << TestLog::EndMessage;
2565
2566			deviceExtensionNames.push_back(deviceExtensionProperties[ndx].extensionName);
2567		}
2568
2569		checkDeviceExtensions(results, deviceExtensionNames);
2570		CheckEnumerateDeviceExtensionPropertiesIncompleteResult()(context, results, deviceExtensionProperties.size());
2571
2572#ifndef CTS_USES_VULKANSC
2573		for (const auto& version : releasedApiVersions)
2574		{
2575			deUint32 apiVariant, versionMajor, versionMinor;
2576			std::tie(std::ignore, apiVariant, versionMajor, versionMinor) = version;
2577			if (context.contextSupports(vk::ApiVersion(apiVariant, versionMajor, versionMinor, 0)))
2578			{
2579				checkExtensionDependencies(results,
2580					deviceExtensionDependencies,
2581					versionMajor,
2582					versionMinor,
2583					instanceExtensionProperties,
2584					deviceExtensionProperties);
2585				break;
2586			}
2587		}
2588#endif // CTS_USES_VULKANSC
2589
2590	}
2591
2592	{
2593		const vector<VkLayerProperties>	layers	= enumerateDeviceLayerProperties(context.getInstanceInterface(), context.getPhysicalDevice());
2594
2595		for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
2596		{
2597			const ScopedLogSection				section		(log, layer->layerName, string("Layer: ") + layer->layerName);
2598			const vector<VkExtensionProperties>	properties	= enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), layer->layerName);
2599			vector<string>						extensionNames;
2600
2601			for (size_t extNdx = 0; extNdx < properties.size(); extNdx++)
2602			{
2603				log << TestLog::Message << extNdx << ": " << properties[extNdx] << TestLog::EndMessage;
2604
2605
2606				extensionNames.push_back(properties[extNdx].extensionName);
2607			}
2608
2609			checkDeviceExtensions(results, extensionNames);
2610			CheckEnumerateDeviceExtensionPropertiesIncompleteResult(layer->layerName)(context, results, properties.size());
2611		}
2612	}
2613
2614	return tcu::TestStatus(results.getResult(), results.getMessage());
2615}
2616
2617tcu::TestStatus extensionCoreVersions (Context& context)
2618{
2619	deUint32	major;
2620	deUint32	minor;
2621	const char*	extName;
2622
2623	auto&					log		= context.getTestContext().getLog();
2624	tcu::ResultCollector	results	(log);
2625
2626	const auto instanceExtensionProperties	= enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL);
2627	const auto deviceExtensionProperties	= enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), DE_NULL);
2628
2629	for (const auto& majorMinorName : extensionRequiredCoreVersion)
2630	{
2631		std::tie(major, minor, extName) = majorMinorName;
2632		const RequiredExtension reqExt (extName);
2633
2634		if ((isExtensionStructSupported(instanceExtensionProperties, reqExt) || isExtensionStructSupported(deviceExtensionProperties, reqExt)) &&
2635		    !context.contextSupports(vk::ApiVersion(0u, major, minor, 0u)))
2636		{
2637			results.fail("Required core version for " + std::string(extName) + " not met (" + de::toString(major) + "." + de::toString(minor) + ")");
2638		}
2639	}
2640
2641	return tcu::TestStatus(results.getResult(), results.getMessage());
2642}
2643
2644#define VK_SIZE_OF(STRUCT, MEMBER)					(sizeof(((STRUCT*)0)->MEMBER))
2645#define OFFSET_TABLE_ENTRY(STRUCT, MEMBER)			{ (size_t)DE_OFFSET_OF(STRUCT, MEMBER), VK_SIZE_OF(STRUCT, MEMBER) }
2646
2647tcu::TestStatus deviceFeatures (Context& context)
2648{
2649	using namespace ValidateQueryBits;
2650
2651	TestLog&						log			= context.getTestContext().getLog();
2652	VkPhysicalDeviceFeatures*		features;
2653	deUint8							buffer[sizeof(VkPhysicalDeviceFeatures) + GUARD_SIZE];
2654
2655	const QueryMemberTableEntry featureOffsetTable[] =
2656	{
2657		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, robustBufferAccess),
2658		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, fullDrawIndexUint32),
2659		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, imageCubeArray),
2660		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, independentBlend),
2661		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, geometryShader),
2662		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, tessellationShader),
2663		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sampleRateShading),
2664		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, dualSrcBlend),
2665		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, logicOp),
2666		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, multiDrawIndirect),
2667		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, drawIndirectFirstInstance),
2668		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, depthClamp),
2669		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, depthBiasClamp),
2670		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, fillModeNonSolid),
2671		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, depthBounds),
2672		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, wideLines),
2673		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, largePoints),
2674		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, alphaToOne),
2675		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, multiViewport),
2676		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, samplerAnisotropy),
2677		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, textureCompressionETC2),
2678		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, textureCompressionASTC_LDR),
2679		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, textureCompressionBC),
2680		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, occlusionQueryPrecise),
2681		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, pipelineStatisticsQuery),
2682		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, vertexPipelineStoresAndAtomics),
2683		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, fragmentStoresAndAtomics),
2684		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderTessellationAndGeometryPointSize),
2685		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderImageGatherExtended),
2686		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderStorageImageExtendedFormats),
2687		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderStorageImageMultisample),
2688		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderStorageImageReadWithoutFormat),
2689		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderStorageImageWriteWithoutFormat),
2690		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderUniformBufferArrayDynamicIndexing),
2691		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderSampledImageArrayDynamicIndexing),
2692		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderStorageBufferArrayDynamicIndexing),
2693		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderStorageImageArrayDynamicIndexing),
2694		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderClipDistance),
2695		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderCullDistance),
2696		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderFloat64),
2697		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderInt64),
2698		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderInt16),
2699		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderResourceResidency),
2700		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderResourceMinLod),
2701		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseBinding),
2702		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidencyBuffer),
2703		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidencyImage2D),
2704		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidencyImage3D),
2705		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidency2Samples),
2706		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidency4Samples),
2707		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidency8Samples),
2708		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidency16Samples),
2709		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidencyAliased),
2710		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, variableMultisampleRate),
2711		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, inheritedQueries),
2712		{ 0, 0 }
2713	};
2714
2715	deMemset(buffer, GUARD_VALUE, sizeof(buffer));
2716	features = reinterpret_cast<VkPhysicalDeviceFeatures*>(buffer);
2717
2718	context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), features);
2719
2720	log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage
2721		<< TestLog::Message << *features << TestLog::EndMessage;
2722
2723	// Requirements and dependencies
2724	{
2725		if (!features->robustBufferAccess)
2726			return tcu::TestStatus::fail("robustBufferAccess is not supported");
2727	}
2728
2729	for (int ndx = 0; ndx < GUARD_SIZE; ndx++)
2730	{
2731		if (buffer[ndx + sizeof(VkPhysicalDeviceFeatures)] != GUARD_VALUE)
2732		{
2733			log << TestLog::Message << "deviceFeatures - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
2734			return tcu::TestStatus::fail("deviceFeatures buffer overflow");
2735		}
2736	}
2737
2738	if (!validateInitComplete(context.getPhysicalDevice(), &InstanceInterface::getPhysicalDeviceFeatures, context.getInstanceInterface(), featureOffsetTable))
2739	{
2740		log << TestLog::Message << "deviceFeatures - VkPhysicalDeviceFeatures not completely initialized" << TestLog::EndMessage;
2741		return tcu::TestStatus::fail("deviceFeatures incomplete initialization");
2742	}
2743
2744	return tcu::TestStatus::pass("Query succeeded");
2745}
2746
2747static const ValidateQueryBits::QueryMemberTableEntry s_physicalDevicePropertiesOffsetTable[] =
2748{
2749	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, apiVersion),
2750	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, driverVersion),
2751	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, vendorID),
2752	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, deviceID),
2753	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, deviceType),
2754	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, pipelineCacheUUID),
2755	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxImageDimension1D),
2756	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxImageDimension2D),
2757	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxImageDimension3D),
2758	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxImageDimensionCube),
2759	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxImageArrayLayers),
2760	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTexelBufferElements),
2761	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxUniformBufferRange),
2762	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxStorageBufferRange),
2763	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPushConstantsSize),
2764	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxMemoryAllocationCount),
2765	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxSamplerAllocationCount),
2766	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.bufferImageGranularity),
2767	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.sparseAddressSpaceSize),
2768	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxBoundDescriptorSets),
2769	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageDescriptorSamplers),
2770	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageDescriptorUniformBuffers),
2771	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageDescriptorStorageBuffers),
2772	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageDescriptorSampledImages),
2773	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageDescriptorStorageImages),
2774	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageDescriptorInputAttachments),
2775	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageResources),
2776	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetSamplers),
2777	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetUniformBuffers),
2778	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetUniformBuffersDynamic),
2779	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetStorageBuffers),
2780	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetStorageBuffersDynamic),
2781	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetSampledImages),
2782	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetStorageImages),
2783	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetInputAttachments),
2784	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxVertexInputAttributes),
2785	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxVertexInputBindings),
2786	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxVertexInputAttributeOffset),
2787	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxVertexInputBindingStride),
2788	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxVertexOutputComponents),
2789	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationGenerationLevel),
2790	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationPatchSize),
2791	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationControlPerVertexInputComponents),
2792	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationControlPerVertexOutputComponents),
2793	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationControlPerPatchOutputComponents),
2794	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationControlTotalOutputComponents),
2795	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationEvaluationInputComponents),
2796	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationEvaluationOutputComponents),
2797	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxGeometryShaderInvocations),
2798	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxGeometryInputComponents),
2799	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxGeometryOutputComponents),
2800	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxGeometryOutputVertices),
2801	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxGeometryTotalOutputComponents),
2802	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFragmentInputComponents),
2803	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFragmentOutputAttachments),
2804	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFragmentDualSrcAttachments),
2805	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFragmentCombinedOutputResources),
2806	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxComputeSharedMemorySize),
2807	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxComputeWorkGroupCount[3]),
2808	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxComputeWorkGroupInvocations),
2809	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxComputeWorkGroupSize[3]),
2810	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.subPixelPrecisionBits),
2811	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.subTexelPrecisionBits),
2812	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.mipmapPrecisionBits),
2813	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDrawIndexedIndexValue),
2814	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDrawIndirectCount),
2815	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxSamplerLodBias),
2816	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxSamplerAnisotropy),
2817	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxViewports),
2818	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxViewportDimensions[2]),
2819	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.viewportBoundsRange[2]),
2820	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.viewportSubPixelBits),
2821	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minMemoryMapAlignment),
2822	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minTexelBufferOffsetAlignment),
2823	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minUniformBufferOffsetAlignment),
2824	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minStorageBufferOffsetAlignment),
2825	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minTexelOffset),
2826	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTexelOffset),
2827	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minTexelGatherOffset),
2828	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTexelGatherOffset),
2829	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minInterpolationOffset),
2830	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxInterpolationOffset),
2831	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.subPixelInterpolationOffsetBits),
2832	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFramebufferWidth),
2833	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFramebufferHeight),
2834	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFramebufferLayers),
2835	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.framebufferColorSampleCounts),
2836	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.framebufferDepthSampleCounts),
2837	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.framebufferStencilSampleCounts),
2838	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.framebufferNoAttachmentsSampleCounts),
2839	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxColorAttachments),
2840	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.sampledImageColorSampleCounts),
2841	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.sampledImageIntegerSampleCounts),
2842	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.sampledImageDepthSampleCounts),
2843	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.sampledImageStencilSampleCounts),
2844	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.storageImageSampleCounts),
2845	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxSampleMaskWords),
2846	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.timestampComputeAndGraphics),
2847	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.timestampPeriod),
2848	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxClipDistances),
2849	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxCullDistances),
2850	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxCombinedClipAndCullDistances),
2851	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.discreteQueuePriorities),
2852	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.pointSizeRange[2]),
2853	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.lineWidthRange[2]),
2854	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.pointSizeGranularity),
2855	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.lineWidthGranularity),
2856	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.strictLines),
2857	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.standardSampleLocations),
2858	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.optimalBufferCopyOffsetAlignment),
2859	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.optimalBufferCopyRowPitchAlignment),
2860	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.nonCoherentAtomSize),
2861	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, sparseProperties.residencyStandard2DBlockShape),
2862	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, sparseProperties.residencyStandard2DMultisampleBlockShape),
2863	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, sparseProperties.residencyStandard3DBlockShape),
2864	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, sparseProperties.residencyAlignedMipSize),
2865	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, sparseProperties.residencyNonResidentStrict),
2866	{ 0, 0 }
2867};
2868
2869tcu::TestStatus deviceProperties (Context& context)
2870{
2871	using namespace ValidateQueryBits;
2872
2873	TestLog&						log			= context.getTestContext().getLog();
2874	VkPhysicalDeviceProperties*		props;
2875	VkPhysicalDeviceFeatures		features;
2876	deUint8							buffer[sizeof(VkPhysicalDeviceProperties) + GUARD_SIZE];
2877
2878	props = reinterpret_cast<VkPhysicalDeviceProperties*>(buffer);
2879	deMemset(props, GUARD_VALUE, sizeof(buffer));
2880
2881	context.getInstanceInterface().getPhysicalDeviceProperties(context.getPhysicalDevice(), props);
2882	context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), &features);
2883
2884	log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage
2885		<< TestLog::Message << *props << TestLog::EndMessage;
2886
2887	if (!validateFeatureLimits(props, &features, log))
2888		return tcu::TestStatus::fail("deviceProperties - feature limits failed");
2889
2890	for (int ndx = 0; ndx < GUARD_SIZE; ndx++)
2891	{
2892		if (buffer[ndx + sizeof(VkPhysicalDeviceProperties)] != GUARD_VALUE)
2893		{
2894			log << TestLog::Message << "deviceProperties - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
2895			return tcu::TestStatus::fail("deviceProperties buffer overflow");
2896		}
2897	}
2898
2899	if (!validateInitComplete(context.getPhysicalDevice(), &InstanceInterface::getPhysicalDeviceProperties, context.getInstanceInterface(), s_physicalDevicePropertiesOffsetTable))
2900	{
2901		log << TestLog::Message << "deviceProperties - VkPhysicalDeviceProperties not completely initialized" << TestLog::EndMessage;
2902		return tcu::TestStatus::fail("deviceProperties incomplete initialization");
2903	}
2904
2905	// Check if deviceName string is properly terminated.
2906	if (deStrnlen(props->deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE) == VK_MAX_PHYSICAL_DEVICE_NAME_SIZE)
2907	{
2908		log << TestLog::Message << "deviceProperties - VkPhysicalDeviceProperties deviceName not properly initialized" << TestLog::EndMessage;
2909		return tcu::TestStatus::fail("deviceProperties incomplete initialization");
2910	}
2911
2912	{
2913		const ApiVersion deviceVersion = unpackVersion(props->apiVersion);
2914#ifndef CTS_USES_VULKANSC
2915		const ApiVersion deqpVersion = unpackVersion(VK_API_VERSION_1_3);
2916#else
2917		const ApiVersion deqpVersion = unpackVersion(VK_API_VERSION_1_2);
2918#endif // CTS_USES_VULKANSC
2919
2920		if (deviceVersion.majorNum != deqpVersion.majorNum)
2921		{
2922			log << TestLog::Message << "deviceProperties - API Major Version " << deviceVersion.majorNum << " is not valid" << TestLog::EndMessage;
2923			return tcu::TestStatus::fail("deviceProperties apiVersion not valid");
2924		}
2925
2926		if (deviceVersion.minorNum > deqpVersion.minorNum)
2927		{
2928			log << TestLog::Message << "deviceProperties - API Minor Version " << deviceVersion.minorNum << " is not valid for this version of dEQP" << TestLog::EndMessage;
2929			return tcu::TestStatus::fail("deviceProperties apiVersion not valid");
2930		}
2931	}
2932
2933	return tcu::TestStatus::pass("DeviceProperites query succeeded");
2934}
2935
2936tcu::TestStatus deviceQueueFamilyProperties (Context& context)
2937{
2938	TestLog&								log					= context.getTestContext().getLog();
2939	const vector<VkQueueFamilyProperties>	queueProperties		= getPhysicalDeviceQueueFamilyProperties(context.getInstanceInterface(), context.getPhysicalDevice());
2940
2941	log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage;
2942
2943	for (size_t queueNdx = 0; queueNdx < queueProperties.size(); queueNdx++)
2944		log << TestLog::Message << queueNdx << ": " << queueProperties[queueNdx] << TestLog::EndMessage;
2945
2946	return tcu::TestStatus::pass("Querying queue properties succeeded");
2947}
2948
2949tcu::TestStatus deviceMemoryProperties (Context& context)
2950{
2951	TestLog&							log			= context.getTestContext().getLog();
2952	VkPhysicalDeviceMemoryProperties*	memProps;
2953	deUint8								buffer[sizeof(VkPhysicalDeviceMemoryProperties) + GUARD_SIZE];
2954
2955	memProps = reinterpret_cast<VkPhysicalDeviceMemoryProperties*>(buffer);
2956	deMemset(buffer, GUARD_VALUE, sizeof(buffer));
2957
2958	context.getInstanceInterface().getPhysicalDeviceMemoryProperties(context.getPhysicalDevice(), memProps);
2959
2960	log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage
2961		<< TestLog::Message << *memProps << TestLog::EndMessage;
2962
2963	for (deInt32 ndx = 0; ndx < GUARD_SIZE; ndx++)
2964	{
2965		if (buffer[ndx + sizeof(VkPhysicalDeviceMemoryProperties)] != GUARD_VALUE)
2966		{
2967			log << TestLog::Message << "deviceMemoryProperties - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
2968			return tcu::TestStatus::fail("deviceMemoryProperties buffer overflow");
2969		}
2970	}
2971
2972	if (memProps->memoryHeapCount >= VK_MAX_MEMORY_HEAPS)
2973	{
2974		log << TestLog::Message << "deviceMemoryProperties - HeapCount larger than " << (deUint32)VK_MAX_MEMORY_HEAPS << TestLog::EndMessage;
2975		return tcu::TestStatus::fail("deviceMemoryProperties HeapCount too large");
2976	}
2977
2978	if (memProps->memoryHeapCount == 1)
2979	{
2980		if ((memProps->memoryHeaps[0].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) == 0)
2981		{
2982			log << TestLog::Message << "deviceMemoryProperties - Single heap is not marked DEVICE_LOCAL" << TestLog::EndMessage;
2983			return tcu::TestStatus::fail("deviceMemoryProperties invalid HeapFlags");
2984		}
2985	}
2986
2987	const VkMemoryPropertyFlags validPropertyFlags[] =
2988	{
2989		0,
2990		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
2991		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
2992		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
2993		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_CACHED_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
2994		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
2995		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
2996		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_CACHED_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
2997		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
2998	};
2999
3000	const VkMemoryPropertyFlags requiredPropertyFlags[] =
3001	{
3002		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
3003	};
3004
3005	bool requiredFlagsFound[DE_LENGTH_OF_ARRAY(requiredPropertyFlags)];
3006	std::fill(DE_ARRAY_BEGIN(requiredFlagsFound), DE_ARRAY_END(requiredFlagsFound), false);
3007
3008	for (deUint32 memoryNdx = 0; memoryNdx < memProps->memoryTypeCount; memoryNdx++)
3009	{
3010		bool validPropTypeFound = false;
3011
3012		if (memProps->memoryTypes[memoryNdx].heapIndex >= memProps->memoryHeapCount)
3013		{
3014			log << TestLog::Message << "deviceMemoryProperties - heapIndex " << memProps->memoryTypes[memoryNdx].heapIndex << " larger than heapCount" << TestLog::EndMessage;
3015			return tcu::TestStatus::fail("deviceMemoryProperties - invalid heapIndex");
3016		}
3017
3018		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;
3019
3020		for (const VkMemoryPropertyFlags* requiredFlagsIterator = DE_ARRAY_BEGIN(requiredPropertyFlags); requiredFlagsIterator != DE_ARRAY_END(requiredPropertyFlags); requiredFlagsIterator++)
3021			if ((memProps->memoryTypes[memoryNdx].propertyFlags & *requiredFlagsIterator) == *requiredFlagsIterator)
3022				requiredFlagsFound[requiredFlagsIterator - DE_ARRAY_BEGIN(requiredPropertyFlags)] = true;
3023
3024		if (de::contains(DE_ARRAY_BEGIN(validPropertyFlags), DE_ARRAY_END(validPropertyFlags), memProps->memoryTypes[memoryNdx].propertyFlags & bitsToCheck))
3025			validPropTypeFound = true;
3026
3027		if (!validPropTypeFound)
3028		{
3029			log << TestLog::Message << "deviceMemoryProperties - propertyFlags "
3030				<< memProps->memoryTypes[memoryNdx].propertyFlags << " not valid" << TestLog::EndMessage;
3031			return tcu::TestStatus::fail("deviceMemoryProperties propertyFlags not valid");
3032		}
3033
3034		if (memProps->memoryTypes[memoryNdx].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
3035		{
3036			if ((memProps->memoryHeaps[memProps->memoryTypes[memoryNdx].heapIndex].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) == 0)
3037			{
3038				log << TestLog::Message << "deviceMemoryProperties - DEVICE_LOCAL memory type references heap which is not DEVICE_LOCAL" << TestLog::EndMessage;
3039				return tcu::TestStatus::fail("deviceMemoryProperties inconsistent memoryType and HeapFlags");
3040			}
3041		}
3042		else
3043		{
3044			if (memProps->memoryHeaps[memProps->memoryTypes[memoryNdx].heapIndex].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)
3045			{
3046				log << TestLog::Message << "deviceMemoryProperties - non-DEVICE_LOCAL memory type references heap with is DEVICE_LOCAL" << TestLog::EndMessage;
3047				return tcu::TestStatus::fail("deviceMemoryProperties inconsistent memoryType and HeapFlags");
3048			}
3049		}
3050	}
3051
3052	bool* requiredFlagsFoundIterator = std::find(DE_ARRAY_BEGIN(requiredFlagsFound), DE_ARRAY_END(requiredFlagsFound), false);
3053	if (requiredFlagsFoundIterator != DE_ARRAY_END(requiredFlagsFound))
3054	{
3055		DE_ASSERT(requiredFlagsFoundIterator - DE_ARRAY_BEGIN(requiredFlagsFound) <= DE_LENGTH_OF_ARRAY(requiredPropertyFlags));
3056		log << TestLog::Message << "deviceMemoryProperties - required property flags "
3057			<< getMemoryPropertyFlagsStr(requiredPropertyFlags[requiredFlagsFoundIterator - DE_ARRAY_BEGIN(requiredFlagsFound)]) << " not found" << TestLog::EndMessage;
3058
3059		return tcu::TestStatus::fail("deviceMemoryProperties propertyFlags not valid");
3060	}
3061
3062	return tcu::TestStatus::pass("Querying memory properties succeeded");
3063}
3064
3065tcu::TestStatus deviceGroupPeerMemoryFeatures (Context& context)
3066{
3067	TestLog&							log						= context.getTestContext().getLog();
3068	const PlatformInterface&			vkp						= context.getPlatformInterface();
3069	const CustomInstance				instance				(createCustomInstanceWithExtension(context, "VK_KHR_device_group_creation"));
3070	const InstanceDriver&				vki						(instance.getDriver());
3071	const tcu::CommandLine&				cmdLine					= context.getTestContext().getCommandLine();
3072	const deUint32						devGroupIdx				= cmdLine.getVKDeviceGroupId() - 1;
3073	const deUint32						deviceIdx				= vk::chooseDeviceIndex(context.getInstanceInterface(), instance, cmdLine);
3074	const float							queuePriority			= 1.0f;
3075	const char*							deviceGroupExtName		= "VK_KHR_device_group";
3076	VkPhysicalDeviceMemoryProperties	memProps;
3077	VkPeerMemoryFeatureFlags*			peerMemFeatures;
3078	deUint8								buffer					[sizeof(VkPeerMemoryFeatureFlags) + GUARD_SIZE];
3079	deUint32							queueFamilyIndex		= 0;
3080
3081	const vector<VkPhysicalDeviceGroupProperties>		deviceGroupProps = enumeratePhysicalDeviceGroups(vki, instance);
3082	std::vector<const char*>							deviceExtensions;
3083
3084	if (static_cast<size_t>(devGroupIdx) >= deviceGroupProps.size())
3085	{
3086		std::ostringstream msg;
3087		msg << "Chosen device group index " << devGroupIdx << " too big: found " << deviceGroupProps.size() << " device groups";
3088		TCU_THROW(NotSupportedError, msg.str());
3089	}
3090
3091	const auto numPhysicalDevices = deviceGroupProps[devGroupIdx].physicalDeviceCount;
3092
3093	if (deviceIdx >= numPhysicalDevices)
3094	{
3095		std::ostringstream msg;
3096		msg << "Chosen device index " << deviceIdx << " too big: chosen device group " << devGroupIdx << " has " << numPhysicalDevices << " devices";
3097		TCU_THROW(NotSupportedError, msg.str());
3098	}
3099
3100	// Need at least 2 devices for peer memory features.
3101	if (numPhysicalDevices < 2)
3102		TCU_THROW(NotSupportedError, "Need a device group with at least 2 physical devices");
3103
3104	if (!isCoreDeviceExtension(context.getUsedApiVersion(), deviceGroupExtName))
3105		deviceExtensions.push_back(deviceGroupExtName);
3106
3107	const std::vector<VkQueueFamilyProperties>	queueProps		= getPhysicalDeviceQueueFamilyProperties(vki, deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx]);
3108	for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
3109	{
3110		if (queueProps[queueNdx].queueFlags & VK_QUEUE_GRAPHICS_BIT)
3111			queueFamilyIndex = (deUint32)queueNdx;
3112	}
3113	const VkDeviceQueueCreateInfo		deviceQueueCreateInfo	=
3114	{
3115		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,			//type
3116		DE_NULL,											//pNext
3117		(VkDeviceQueueCreateFlags)0u,						//flags
3118		queueFamilyIndex,									//queueFamilyIndex;
3119		1u,													//queueCount;
3120		&queuePriority,										//pQueuePriorities;
3121	};
3122
3123	// Create device groups
3124	VkDeviceGroupDeviceCreateInfo							deviceGroupInfo =
3125	{
3126		VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO,	//stype
3127		DE_NULL,											//pNext
3128		deviceGroupProps[devGroupIdx].physicalDeviceCount,	//physicalDeviceCount
3129		deviceGroupProps[devGroupIdx].physicalDevices		//physicalDevices
3130	};
3131
3132	void* pNext												= &deviceGroupInfo;
3133#ifdef CTS_USES_VULKANSC
3134	VkDeviceObjectReservationCreateInfo memReservationInfo	= context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
3135	memReservationInfo.pNext								= pNext;
3136	pNext													= &memReservationInfo;
3137
3138	VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
3139	sc10Features.pNext										= pNext;
3140	pNext													= &sc10Features;
3141
3142	VkPipelineCacheCreateInfo			pcCI;
3143	std::vector<VkPipelinePoolSize>		poolSizes;
3144	if (context.getTestContext().getCommandLine().isSubProcess())
3145	{
3146		if (context.getResourceInterface()->getCacheDataSize() > 0)
3147		{
3148			pcCI =
3149			{
3150				VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,		// VkStructureType				sType;
3151				DE_NULL,											// const void*					pNext;
3152				VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
3153					VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT,	// VkPipelineCacheCreateFlags	flags;
3154				context.getResourceInterface()->getCacheDataSize(),	// deUintptr					initialDataSize;
3155				context.getResourceInterface()->getCacheData()		// const void*					pInitialData;
3156			};
3157			memReservationInfo.pipelineCacheCreateInfoCount		= 1;
3158			memReservationInfo.pPipelineCacheCreateInfos		= &pcCI;
3159		}
3160
3161		poolSizes							= context.getResourceInterface()->getPipelinePoolSizes();
3162		if (!poolSizes.empty())
3163		{
3164			memReservationInfo.pipelinePoolSizeCount			= deUint32(poolSizes.size());
3165			memReservationInfo.pPipelinePoolSizes				= poolSizes.data();
3166		}
3167	}
3168#endif // CTS_USES_VULKANSC
3169
3170	const VkDeviceCreateInfo								deviceCreateInfo =
3171	{
3172		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,							//sType;
3173		pNext,															//pNext;
3174		(VkDeviceCreateFlags)0u,										//flags
3175		1,																//queueRecordCount;
3176		&deviceQueueCreateInfo,											//pRequestedQueues;
3177		0,																//layerCount;
3178		DE_NULL,														//ppEnabledLayerNames;
3179		deUint32(deviceExtensions.size()),								//extensionCount;
3180		de::dataOrNull(deviceExtensions),								//ppEnabledExtensionNames;
3181		DE_NULL,														//pEnabledFeatures;
3182	};
3183
3184	Move<VkDevice>		deviceGroup = createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), vkp, instance, vki, deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx], &deviceCreateInfo);
3185	const DeviceDriver	vk	(vkp, instance, *deviceGroup, context.getUsedApiVersion());
3186	context.getInstanceInterface().getPhysicalDeviceMemoryProperties(deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx], &memProps);
3187
3188	peerMemFeatures = reinterpret_cast<VkPeerMemoryFeatureFlags*>(buffer);
3189	deMemset(buffer, GUARD_VALUE, sizeof(buffer));
3190
3191	for (deUint32 heapIndex = 0; heapIndex < memProps.memoryHeapCount; heapIndex++)
3192	{
3193		for (deUint32 localDeviceIndex = 0; localDeviceIndex < numPhysicalDevices; localDeviceIndex++)
3194		{
3195			for (deUint32 remoteDeviceIndex = 0; remoteDeviceIndex < numPhysicalDevices; remoteDeviceIndex++)
3196			{
3197				if (localDeviceIndex != remoteDeviceIndex)
3198				{
3199					vk.getDeviceGroupPeerMemoryFeatures(deviceGroup.get(), heapIndex, localDeviceIndex, remoteDeviceIndex, peerMemFeatures);
3200
3201					// Check guard
3202					for (deInt32 ndx = 0; ndx < GUARD_SIZE; ndx++)
3203					{
3204						if (buffer[ndx + sizeof(VkPeerMemoryFeatureFlags)] != GUARD_VALUE)
3205						{
3206							log << TestLog::Message << "deviceGroupPeerMemoryFeatures - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
3207							return tcu::TestStatus::fail("deviceGroupPeerMemoryFeatures buffer overflow");
3208						}
3209					}
3210
3211					VkPeerMemoryFeatureFlags requiredFlag = VK_PEER_MEMORY_FEATURE_COPY_DST_BIT;
3212					VkPeerMemoryFeatureFlags maxValidFlag = VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT|VK_PEER_MEMORY_FEATURE_COPY_DST_BIT|
3213																VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT|VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT;
3214					if ((!(*peerMemFeatures & requiredFlag)) ||
3215						*peerMemFeatures > maxValidFlag)
3216						return tcu::TestStatus::fail("deviceGroupPeerMemoryFeatures invalid flag");
3217
3218					log << TestLog::Message << "deviceGroup = " << deviceGroup.get() << TestLog::EndMessage
3219						<< TestLog::Message << "heapIndex = " << heapIndex << TestLog::EndMessage
3220						<< TestLog::Message << "localDeviceIndex = " << localDeviceIndex << TestLog::EndMessage
3221						<< TestLog::Message << "remoteDeviceIndex = " << remoteDeviceIndex << TestLog::EndMessage
3222						<< TestLog::Message << "PeerMemoryFeatureFlags = " << *peerMemFeatures << TestLog::EndMessage;
3223				}
3224			} // remote device
3225		} // local device
3226	} // heap Index
3227
3228	return tcu::TestStatus::pass("Querying deviceGroup peer memory features succeeded");
3229}
3230
3231tcu::TestStatus deviceMemoryBudgetProperties (Context& context)
3232{
3233	TestLog&							log			= context.getTestContext().getLog();
3234	deUint8								buffer[sizeof(VkPhysicalDeviceMemoryBudgetPropertiesEXT) + GUARD_SIZE];
3235
3236	if (!context.isDeviceFunctionalitySupported("VK_EXT_memory_budget"))
3237		TCU_THROW(NotSupportedError, "VK_EXT_memory_budget is not supported");
3238
3239	VkPhysicalDeviceMemoryBudgetPropertiesEXT *budgetProps = reinterpret_cast<VkPhysicalDeviceMemoryBudgetPropertiesEXT *>(buffer);
3240	deMemset(buffer, GUARD_VALUE, sizeof(buffer));
3241
3242	budgetProps->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT;
3243	budgetProps->pNext = DE_NULL;
3244
3245	VkPhysicalDeviceMemoryProperties2	memProps;
3246	deMemset(&memProps, 0, sizeof(memProps));
3247	memProps.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
3248	memProps.pNext = budgetProps;
3249
3250	context.getInstanceInterface().getPhysicalDeviceMemoryProperties2(context.getPhysicalDevice(), &memProps);
3251
3252	log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage
3253		<< TestLog::Message << *budgetProps << TestLog::EndMessage;
3254
3255	for (deInt32 ndx = 0; ndx < GUARD_SIZE; ndx++)
3256	{
3257		if (buffer[ndx + sizeof(VkPhysicalDeviceMemoryBudgetPropertiesEXT)] != GUARD_VALUE)
3258		{
3259			log << TestLog::Message << "deviceMemoryBudgetProperties - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
3260			return tcu::TestStatus::fail("deviceMemoryBudgetProperties buffer overflow");
3261		}
3262	}
3263
3264	for (deUint32 i = 0; i < memProps.memoryProperties.memoryHeapCount; ++i)
3265	{
3266		if (budgetProps->heapBudget[i] == 0)
3267		{
3268			log << TestLog::Message << "deviceMemoryBudgetProperties - Supported heaps must report nonzero budget" << TestLog::EndMessage;
3269			return tcu::TestStatus::fail("deviceMemoryBudgetProperties invalid heap budget (zero)");
3270		}
3271		if (budgetProps->heapBudget[i] > memProps.memoryProperties.memoryHeaps[i].size)
3272		{
3273			log << TestLog::Message << "deviceMemoryBudgetProperties - Heap budget must be less than or equal to heap size" << TestLog::EndMessage;
3274			return tcu::TestStatus::fail("deviceMemoryBudgetProperties invalid heap budget (too large)");
3275		}
3276	}
3277
3278	for (deUint32 i = memProps.memoryProperties.memoryHeapCount; i < VK_MAX_MEMORY_HEAPS; ++i)
3279	{
3280		if (budgetProps->heapBudget[i] != 0 || budgetProps->heapUsage[i] != 0)
3281		{
3282			log << TestLog::Message << "deviceMemoryBudgetProperties - Unused heaps must report budget/usage of zero" << TestLog::EndMessage;
3283			return tcu::TestStatus::fail("deviceMemoryBudgetProperties invalid unused heaps");
3284		}
3285	}
3286
3287	return tcu::TestStatus::pass("Querying memory budget properties succeeded");
3288}
3289
3290namespace
3291{
3292
3293#include "vkMandatoryFeatures.inl"
3294
3295}
3296
3297tcu::TestStatus deviceMandatoryFeatures(Context& context)
3298{
3299	if ( checkMandatoryFeatures(context) )
3300		return tcu::TestStatus::pass("Passed");
3301	return tcu::TestStatus::fail("Not all mandatory features are supported ( see: vkspec.html#features-requirements )");
3302}
3303
3304VkFormatFeatureFlags getBaseRequiredOptimalTilingFeatures (VkFormat format)
3305{
3306	struct Formatpair
3307	{
3308		VkFormat				format;
3309		VkFormatFeatureFlags	flags;
3310	};
3311
3312	enum
3313	{
3314		SAIM = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT,
3315		BLSR = VK_FORMAT_FEATURE_BLIT_SRC_BIT,
3316		SIFL = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT,
3317		COAT = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT,
3318		BLDS = VK_FORMAT_FEATURE_BLIT_DST_BIT,
3319		CABL = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT,
3320		STIM = VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT,
3321		STIA = VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT,
3322		DSAT = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT,
3323		TRSR = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT,
3324		TRDS = VK_FORMAT_FEATURE_TRANSFER_DST_BIT
3325	};
3326
3327	static const Formatpair formatflags[] =
3328	{
3329		{ VK_FORMAT_B4G4R4A4_UNORM_PACK16,		SAIM | BLSR | TRSR | TRDS |               SIFL },
3330		{ VK_FORMAT_R5G6B5_UNORM_PACK16,		SAIM | BLSR | TRSR | TRDS | COAT | BLDS | SIFL |        CABL },
3331		{ VK_FORMAT_A1R5G5B5_UNORM_PACK16,		SAIM | BLSR | TRSR | TRDS | COAT | BLDS | SIFL |        CABL },
3332		{ VK_FORMAT_R8_UNORM,					SAIM | BLSR | TRSR | TRDS | COAT | BLDS | SIFL |        CABL },
3333		{ VK_FORMAT_R8_SNORM,					SAIM | BLSR | TRSR | TRDS |               SIFL },
3334		{ VK_FORMAT_R8_UINT,					SAIM | BLSR | TRSR | TRDS | COAT | BLDS },
3335		{ VK_FORMAT_R8_SINT,					SAIM | BLSR | TRSR | TRDS | COAT | BLDS },
3336		{ VK_FORMAT_R8G8_UNORM,					SAIM | BLSR | TRSR | TRDS | COAT | BLDS | SIFL |        CABL },
3337		{ VK_FORMAT_R8G8_SNORM,					SAIM | BLSR | TRSR | TRDS |               SIFL },
3338		{ VK_FORMAT_R8G8_UINT,					SAIM | BLSR | TRSR | TRDS | COAT | BLDS },
3339		{ VK_FORMAT_R8G8_SINT,					SAIM | BLSR | TRSR | TRDS | COAT | BLDS },
3340		{ VK_FORMAT_R8G8B8A8_UNORM,				SAIM | BLSR | TRSR | TRDS | COAT | BLDS | SIFL | STIM | CABL },
3341		{ VK_FORMAT_R8G8B8A8_SNORM,				SAIM | BLSR | TRSR | TRDS |               SIFL | STIM },
3342		{ VK_FORMAT_R8G8B8A8_UINT,				SAIM | BLSR | TRSR | TRDS | COAT | BLDS |        STIM },
3343		{ VK_FORMAT_R8G8B8A8_SINT,				SAIM | BLSR | TRSR | TRDS | COAT | BLDS |        STIM },
3344		{ VK_FORMAT_R8G8B8A8_SRGB,				SAIM | BLSR | TRSR | TRDS | COAT | BLDS | SIFL |        CABL },
3345		{ VK_FORMAT_B8G8R8A8_UNORM,				SAIM | BLSR | TRSR | TRDS | COAT | BLDS | SIFL |        CABL },
3346		{ VK_FORMAT_B8G8R8A8_SRGB,				SAIM | BLSR | TRSR | TRDS | COAT | BLDS | SIFL |        CABL },
3347		{ VK_FORMAT_A8B8G8R8_UNORM_PACK32,		SAIM | BLSR | TRSR | TRDS | COAT | BLDS | SIFL |        CABL },
3348		{ VK_FORMAT_A8B8G8R8_SNORM_PACK32,		SAIM | BLSR | TRSR | TRDS |               SIFL },
3349		{ VK_FORMAT_A8B8G8R8_UINT_PACK32,		SAIM | BLSR | TRSR | TRDS | COAT | BLDS },
3350		{ VK_FORMAT_A8B8G8R8_SINT_PACK32,		SAIM | BLSR | TRSR | TRDS | COAT | BLDS },
3351		{ VK_FORMAT_A8B8G8R8_SRGB_PACK32,		SAIM | BLSR | TRSR | TRDS | COAT | BLDS | SIFL |        CABL },
3352		{ VK_FORMAT_A2B10G10R10_UNORM_PACK32,	SAIM | BLSR | TRSR | TRDS | COAT | BLDS | SIFL |        CABL },
3353		{ VK_FORMAT_A2B10G10R10_UINT_PACK32,	SAIM | BLSR | TRSR | TRDS | COAT | BLDS },
3354		{ VK_FORMAT_R16_UINT,					SAIM | BLSR | TRSR | TRDS | COAT | BLDS },
3355		{ VK_FORMAT_R16_SINT,					SAIM | BLSR | TRSR | TRDS | COAT | BLDS },
3356		{ VK_FORMAT_R16_SFLOAT,					SAIM | BLSR | TRSR | TRDS | COAT | BLDS | SIFL |        CABL },
3357		{ VK_FORMAT_R16G16_UINT,				SAIM | BLSR | TRSR | TRDS | COAT | BLDS },
3358		{ VK_FORMAT_R16G16_SINT,				SAIM | BLSR | TRSR | TRDS | COAT | BLDS },
3359		{ VK_FORMAT_R16G16_SFLOAT,				SAIM | BLSR | TRSR | TRDS | COAT | BLDS | SIFL |        CABL },
3360		{ VK_FORMAT_R16G16B16A16_UINT,			SAIM | BLSR | TRSR | TRDS | COAT | BLDS |        STIM },
3361		{ VK_FORMAT_R16G16B16A16_SINT,			SAIM | BLSR | TRSR | TRDS | COAT | BLDS |        STIM },
3362		{ VK_FORMAT_R16G16B16A16_SFLOAT,		SAIM | BLSR | TRSR | TRDS | COAT | BLDS | SIFL | STIM | CABL },
3363		{ VK_FORMAT_R32_UINT,					SAIM | BLSR | TRSR | TRDS | COAT | BLDS |        STIM |        STIA },
3364		{ VK_FORMAT_R32_SINT,					SAIM | BLSR | TRSR | TRDS | COAT | BLDS |        STIM |        STIA },
3365		{ VK_FORMAT_R32_SFLOAT,					SAIM | BLSR | TRSR | TRDS | COAT | BLDS |        STIM },
3366		{ VK_FORMAT_R32G32_UINT,				SAIM | BLSR | TRSR | TRDS | COAT | BLDS |        STIM },
3367		{ VK_FORMAT_R32G32_SINT,				SAIM | BLSR | TRSR | TRDS | COAT | BLDS |        STIM },
3368		{ VK_FORMAT_R32G32_SFLOAT,				SAIM | BLSR | TRSR | TRDS | COAT | BLDS |        STIM },
3369		{ VK_FORMAT_R32G32B32A32_UINT,			SAIM | BLSR | TRSR | TRDS | COAT | BLDS |        STIM },
3370		{ VK_FORMAT_R32G32B32A32_SINT,			SAIM | BLSR | TRSR | TRDS | COAT | BLDS |        STIM },
3371		{ VK_FORMAT_R32G32B32A32_SFLOAT,		SAIM | BLSR | TRSR | TRDS | COAT | BLDS |        STIM },
3372		{ VK_FORMAT_B10G11R11_UFLOAT_PACK32,	SAIM | BLSR | TRSR | TRDS |               SIFL },
3373		{ VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,		SAIM | BLSR | TRSR | TRDS |               SIFL },
3374		{ VK_FORMAT_D16_UNORM,					SAIM | BLSR | TRSR | TRDS |                                           DSAT },
3375	};
3376
3377	size_t formatpairs = sizeof(formatflags) / sizeof(Formatpair);
3378
3379	for (unsigned int i = 0; i < formatpairs; i++)
3380		if (formatflags[i].format == format)
3381			return formatflags[i].flags;
3382	return 0;
3383}
3384
3385VkFormatFeatureFlags getRequiredOptimalExtendedTilingFeatures (Context& context, VkFormat format, VkFormatFeatureFlags queriedFlags)
3386{
3387	VkFormatFeatureFlags	flags	= (VkFormatFeatureFlags)0;
3388
3389	// VK_EXT_sampler_filter_minmax:
3390	//	If filterMinmaxSingleComponentFormats is VK_TRUE, the following formats must
3391	//	support the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT feature with
3392	//	VK_IMAGE_TILING_OPTIMAL, if they support VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT.
3393
3394	static const VkFormat s_requiredSampledImageFilterMinMaxFormats[] =
3395	{
3396		VK_FORMAT_R8_UNORM,
3397		VK_FORMAT_R8_SNORM,
3398		VK_FORMAT_R16_UNORM,
3399		VK_FORMAT_R16_SNORM,
3400		VK_FORMAT_R16_SFLOAT,
3401		VK_FORMAT_R32_SFLOAT,
3402		VK_FORMAT_D16_UNORM,
3403		VK_FORMAT_X8_D24_UNORM_PACK32,
3404		VK_FORMAT_D32_SFLOAT,
3405		VK_FORMAT_D16_UNORM_S8_UINT,
3406		VK_FORMAT_D24_UNORM_S8_UINT,
3407		VK_FORMAT_D32_SFLOAT_S8_UINT,
3408	};
3409
3410	if ((queriedFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
3411	{
3412		if (de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_EXT_sampler_filter_minmax"))
3413		{
3414			if (de::contains(DE_ARRAY_BEGIN(s_requiredSampledImageFilterMinMaxFormats), DE_ARRAY_END(s_requiredSampledImageFilterMinMaxFormats), format))
3415			{
3416				VkPhysicalDeviceSamplerFilterMinmaxProperties		physicalDeviceSamplerMinMaxProperties =
3417				{
3418					VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES,
3419					DE_NULL,
3420					DE_FALSE,
3421					DE_FALSE
3422				};
3423
3424				{
3425					VkPhysicalDeviceProperties2		physicalDeviceProperties;
3426					physicalDeviceProperties.sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
3427					physicalDeviceProperties.pNext	= &physicalDeviceSamplerMinMaxProperties;
3428
3429					const InstanceInterface&		vk = context.getInstanceInterface();
3430					vk.getPhysicalDeviceProperties2(context.getPhysicalDevice(), &physicalDeviceProperties);
3431				}
3432
3433				if (physicalDeviceSamplerMinMaxProperties.filterMinmaxSingleComponentFormats)
3434				{
3435					flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT;
3436				}
3437			}
3438		}
3439	}
3440
3441	// VK_EXT_filter_cubic:
3442	// If cubic filtering is supported, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT must be supported for the following image view types:
3443	// VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_VIEW_TYPE_2D_ARRAY
3444	static const VkFormat s_requiredSampledImageFilterCubicFormats[] =
3445	{
3446		VK_FORMAT_R4G4_UNORM_PACK8,
3447		VK_FORMAT_R4G4B4A4_UNORM_PACK16,
3448		VK_FORMAT_B4G4R4A4_UNORM_PACK16,
3449		VK_FORMAT_R5G6B5_UNORM_PACK16,
3450		VK_FORMAT_B5G6R5_UNORM_PACK16,
3451		VK_FORMAT_R5G5B5A1_UNORM_PACK16,
3452		VK_FORMAT_B5G5R5A1_UNORM_PACK16,
3453		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
3454		VK_FORMAT_R8_UNORM,
3455		VK_FORMAT_R8_SNORM,
3456		VK_FORMAT_R8_SRGB,
3457		VK_FORMAT_R8G8_UNORM,
3458		VK_FORMAT_R8G8_SNORM,
3459		VK_FORMAT_R8G8_SRGB,
3460		VK_FORMAT_R8G8B8_UNORM,
3461		VK_FORMAT_R8G8B8_SNORM,
3462		VK_FORMAT_R8G8B8_SRGB,
3463		VK_FORMAT_B8G8R8_UNORM,
3464		VK_FORMAT_B8G8R8_SNORM,
3465		VK_FORMAT_B8G8R8_SRGB,
3466		VK_FORMAT_R8G8B8A8_UNORM,
3467		VK_FORMAT_R8G8B8A8_SNORM,
3468		VK_FORMAT_R8G8B8A8_SRGB,
3469		VK_FORMAT_B8G8R8A8_UNORM,
3470		VK_FORMAT_B8G8R8A8_SNORM,
3471		VK_FORMAT_B8G8R8A8_SRGB,
3472		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
3473		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
3474		VK_FORMAT_A8B8G8R8_SRGB_PACK32
3475	};
3476
3477	static const VkFormat s_requiredSampledImageFilterCubicFormatsETC2[] =
3478	{
3479		VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
3480		VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
3481		VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
3482		VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
3483		VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
3484		VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK
3485	};
3486
3487	if ( (queriedFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0 && de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_EXT_filter_cubic") )
3488	{
3489		if ( de::contains(DE_ARRAY_BEGIN(s_requiredSampledImageFilterCubicFormats), DE_ARRAY_END(s_requiredSampledImageFilterCubicFormats), format) )
3490			flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT;
3491
3492		const auto& coreFeatures = context.getDeviceFeatures();
3493		if ( coreFeatures.textureCompressionETC2 && de::contains(DE_ARRAY_BEGIN(s_requiredSampledImageFilterCubicFormatsETC2), DE_ARRAY_END(s_requiredSampledImageFilterCubicFormatsETC2), format) )
3494			flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT;
3495	}
3496
3497	return flags;
3498}
3499
3500VkFormatFeatureFlags getRequiredBufferFeatures (VkFormat format)
3501{
3502	static const VkFormat s_requiredVertexBufferFormats[] =
3503	{
3504		VK_FORMAT_R8_UNORM,
3505		VK_FORMAT_R8_SNORM,
3506		VK_FORMAT_R8_UINT,
3507		VK_FORMAT_R8_SINT,
3508		VK_FORMAT_R8G8_UNORM,
3509		VK_FORMAT_R8G8_SNORM,
3510		VK_FORMAT_R8G8_UINT,
3511		VK_FORMAT_R8G8_SINT,
3512		VK_FORMAT_R8G8B8A8_UNORM,
3513		VK_FORMAT_R8G8B8A8_SNORM,
3514		VK_FORMAT_R8G8B8A8_UINT,
3515		VK_FORMAT_R8G8B8A8_SINT,
3516		VK_FORMAT_B8G8R8A8_UNORM,
3517		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
3518		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
3519		VK_FORMAT_A8B8G8R8_UINT_PACK32,
3520		VK_FORMAT_A8B8G8R8_SINT_PACK32,
3521		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
3522		VK_FORMAT_R16_UNORM,
3523		VK_FORMAT_R16_SNORM,
3524		VK_FORMAT_R16_UINT,
3525		VK_FORMAT_R16_SINT,
3526		VK_FORMAT_R16_SFLOAT,
3527		VK_FORMAT_R16G16_UNORM,
3528		VK_FORMAT_R16G16_SNORM,
3529		VK_FORMAT_R16G16_UINT,
3530		VK_FORMAT_R16G16_SINT,
3531		VK_FORMAT_R16G16_SFLOAT,
3532		VK_FORMAT_R16G16B16A16_UNORM,
3533		VK_FORMAT_R16G16B16A16_SNORM,
3534		VK_FORMAT_R16G16B16A16_UINT,
3535		VK_FORMAT_R16G16B16A16_SINT,
3536		VK_FORMAT_R16G16B16A16_SFLOAT,
3537		VK_FORMAT_R32_UINT,
3538		VK_FORMAT_R32_SINT,
3539		VK_FORMAT_R32_SFLOAT,
3540		VK_FORMAT_R32G32_UINT,
3541		VK_FORMAT_R32G32_SINT,
3542		VK_FORMAT_R32G32_SFLOAT,
3543		VK_FORMAT_R32G32B32_UINT,
3544		VK_FORMAT_R32G32B32_SINT,
3545		VK_FORMAT_R32G32B32_SFLOAT,
3546		VK_FORMAT_R32G32B32A32_UINT,
3547		VK_FORMAT_R32G32B32A32_SINT,
3548		VK_FORMAT_R32G32B32A32_SFLOAT
3549	};
3550	static const VkFormat s_requiredUniformTexelBufferFormats[] =
3551	{
3552		VK_FORMAT_R8_UNORM,
3553		VK_FORMAT_R8_SNORM,
3554		VK_FORMAT_R8_UINT,
3555		VK_FORMAT_R8_SINT,
3556		VK_FORMAT_R8G8_UNORM,
3557		VK_FORMAT_R8G8_SNORM,
3558		VK_FORMAT_R8G8_UINT,
3559		VK_FORMAT_R8G8_SINT,
3560		VK_FORMAT_R8G8B8A8_UNORM,
3561		VK_FORMAT_R8G8B8A8_SNORM,
3562		VK_FORMAT_R8G8B8A8_UINT,
3563		VK_FORMAT_R8G8B8A8_SINT,
3564		VK_FORMAT_B8G8R8A8_UNORM,
3565		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
3566		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
3567		VK_FORMAT_A8B8G8R8_UINT_PACK32,
3568		VK_FORMAT_A8B8G8R8_SINT_PACK32,
3569		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
3570		VK_FORMAT_A2B10G10R10_UINT_PACK32,
3571		VK_FORMAT_R16_UINT,
3572		VK_FORMAT_R16_SINT,
3573		VK_FORMAT_R16_SFLOAT,
3574		VK_FORMAT_R16G16_UINT,
3575		VK_FORMAT_R16G16_SINT,
3576		VK_FORMAT_R16G16_SFLOAT,
3577		VK_FORMAT_R16G16B16A16_UINT,
3578		VK_FORMAT_R16G16B16A16_SINT,
3579		VK_FORMAT_R16G16B16A16_SFLOAT,
3580		VK_FORMAT_R32_UINT,
3581		VK_FORMAT_R32_SINT,
3582		VK_FORMAT_R32_SFLOAT,
3583		VK_FORMAT_R32G32_UINT,
3584		VK_FORMAT_R32G32_SINT,
3585		VK_FORMAT_R32G32_SFLOAT,
3586		VK_FORMAT_R32G32B32A32_UINT,
3587		VK_FORMAT_R32G32B32A32_SINT,
3588		VK_FORMAT_R32G32B32A32_SFLOAT,
3589		VK_FORMAT_B10G11R11_UFLOAT_PACK32
3590	};
3591	static const VkFormat s_requiredStorageTexelBufferFormats[] =
3592	{
3593		VK_FORMAT_R8G8B8A8_UNORM,
3594		VK_FORMAT_R8G8B8A8_SNORM,
3595		VK_FORMAT_R8G8B8A8_UINT,
3596		VK_FORMAT_R8G8B8A8_SINT,
3597		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
3598		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
3599		VK_FORMAT_A8B8G8R8_UINT_PACK32,
3600		VK_FORMAT_A8B8G8R8_SINT_PACK32,
3601		VK_FORMAT_R16G16B16A16_UINT,
3602		VK_FORMAT_R16G16B16A16_SINT,
3603		VK_FORMAT_R16G16B16A16_SFLOAT,
3604		VK_FORMAT_R32_UINT,
3605		VK_FORMAT_R32_SINT,
3606		VK_FORMAT_R32_SFLOAT,
3607		VK_FORMAT_R32G32_UINT,
3608		VK_FORMAT_R32G32_SINT,
3609		VK_FORMAT_R32G32_SFLOAT,
3610		VK_FORMAT_R32G32B32A32_UINT,
3611		VK_FORMAT_R32G32B32A32_SINT,
3612		VK_FORMAT_R32G32B32A32_SFLOAT
3613	};
3614	static const VkFormat s_requiredStorageTexelBufferAtomicFormats[] =
3615	{
3616		VK_FORMAT_R32_UINT,
3617		VK_FORMAT_R32_SINT
3618	};
3619
3620	VkFormatFeatureFlags	flags	= (VkFormatFeatureFlags)0;
3621
3622	if (de::contains(DE_ARRAY_BEGIN(s_requiredVertexBufferFormats), DE_ARRAY_END(s_requiredVertexBufferFormats), format))
3623		flags |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT;
3624
3625	if (de::contains(DE_ARRAY_BEGIN(s_requiredUniformTexelBufferFormats), DE_ARRAY_END(s_requiredUniformTexelBufferFormats), format))
3626		flags |= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT;
3627
3628	if (de::contains(DE_ARRAY_BEGIN(s_requiredStorageTexelBufferFormats), DE_ARRAY_END(s_requiredStorageTexelBufferFormats), format))
3629		flags |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT;
3630
3631	if (de::contains(DE_ARRAY_BEGIN(s_requiredStorageTexelBufferAtomicFormats), DE_ARRAY_END(s_requiredStorageTexelBufferAtomicFormats), format))
3632		flags |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
3633
3634	return flags;
3635}
3636
3637VkPhysicalDeviceSamplerYcbcrConversionFeatures getPhysicalDeviceSamplerYcbcrConversionFeatures (const InstanceInterface& vk, VkPhysicalDevice physicalDevice)
3638{
3639	VkPhysicalDeviceFeatures2						coreFeatures;
3640	VkPhysicalDeviceSamplerYcbcrConversionFeatures	ycbcrFeatures;
3641
3642	deMemset(&coreFeatures, 0, sizeof(coreFeatures));
3643	deMemset(&ycbcrFeatures, 0, sizeof(ycbcrFeatures));
3644
3645	coreFeatures.sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
3646	coreFeatures.pNext		= &ycbcrFeatures;
3647	ycbcrFeatures.sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
3648
3649	vk.getPhysicalDeviceFeatures2(physicalDevice, &coreFeatures);
3650
3651	return ycbcrFeatures;
3652}
3653
3654void checkYcbcrApiSupport (Context& context)
3655{
3656	// check if YCbcr API and are supported by implementation
3657
3658	// the support for formats and YCbCr may still be optional - see isYcbcrConversionSupported below
3659
3660	if (!vk::isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_sampler_ycbcr_conversion"))
3661	{
3662		if (!context.isDeviceFunctionalitySupported("VK_KHR_sampler_ycbcr_conversion"))
3663			TCU_THROW(NotSupportedError, "VK_KHR_sampler_ycbcr_conversion is not supported");
3664
3665		// Hard dependency for ycbcr
3666		TCU_CHECK(de::contains(context.getInstanceExtensions().begin(), context.getInstanceExtensions().end(), "VK_KHR_get_physical_device_properties2"));
3667	}
3668}
3669
3670bool isYcbcrConversionSupported (Context& context)
3671{
3672	checkYcbcrApiSupport(context);
3673
3674	const VkPhysicalDeviceSamplerYcbcrConversionFeatures	ycbcrFeatures	= getPhysicalDeviceSamplerYcbcrConversionFeatures(context.getInstanceInterface(), context.getPhysicalDevice());
3675
3676	return (ycbcrFeatures.samplerYcbcrConversion == VK_TRUE);
3677}
3678
3679VkFormatFeatureFlags getRequiredYcbcrFormatFeatures (Context& context, VkFormat format)
3680{
3681	bool req = isYcbcrConversionSupported(context) && (	format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM ||
3682														format == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM);
3683
3684	const VkFormatFeatureFlags	required	= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
3685											| VK_FORMAT_FEATURE_TRANSFER_SRC_BIT
3686											| VK_FORMAT_FEATURE_TRANSFER_DST_BIT
3687											| VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT;
3688	return req ? required : (VkFormatFeatureFlags)0;
3689}
3690
3691VkFormatFeatureFlags getRequiredOptimalTilingFeatures (Context& context, VkFormat format)
3692{
3693	if (isYCbCrFormat(format))
3694		return getRequiredYcbcrFormatFeatures(context, format);
3695	else
3696	{
3697		VkFormatFeatureFlags ret = getBaseRequiredOptimalTilingFeatures(format);
3698
3699		// \todo [2017-05-16 pyry] This should be extended to cover for example COLOR_ATTACHMENT for depth formats etc.
3700		// \todo [2017-05-18 pyry] Any other color conversion related features that can't be supported by regular formats?
3701		ret |= getRequiredOptimalExtendedTilingFeatures(context, format, ret);
3702
3703		// Compressed formats have optional support for some features
3704		// TODO: Is this really correct? It looks like it should be checking the different compressed features
3705		if (isCompressedFormat(format) && (ret & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
3706			ret |=	VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
3707					VK_FORMAT_FEATURE_TRANSFER_DST_BIT |
3708					VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
3709					VK_FORMAT_FEATURE_BLIT_SRC_BIT;
3710
3711		return ret;
3712	}
3713}
3714
3715bool requiresYCbCrConversion(Context& context, VkFormat format)
3716{
3717#ifndef CTS_USES_VULKANSC
3718	if (format == VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16)
3719	{
3720		if (!context.isDeviceFunctionalitySupported("VK_EXT_rgba10x6_formats"))
3721			return true;
3722		VkPhysicalDeviceFeatures2						coreFeatures;
3723		VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT	rgba10x6features;
3724
3725		deMemset(&coreFeatures, 0, sizeof(coreFeatures));
3726		deMemset(&rgba10x6features, 0, sizeof(rgba10x6features));
3727
3728		coreFeatures.sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
3729		coreFeatures.pNext		= &rgba10x6features;
3730		rgba10x6features.sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RGBA10X6_FORMATS_FEATURES_EXT;
3731
3732		const InstanceInterface &vk = context.getInstanceInterface();
3733		vk.getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &coreFeatures);
3734
3735		return !rgba10x6features.formatRgba10x6WithoutYCbCrSampler;
3736	}
3737#else
3738	DE_UNREF(context);
3739#endif // CTS_USES_VULKANSC
3740
3741	return isYCbCrFormat(format) &&
3742			format != VK_FORMAT_R10X6_UNORM_PACK16 && format != VK_FORMAT_R10X6G10X6_UNORM_2PACK16 &&
3743			format != VK_FORMAT_R12X4_UNORM_PACK16 && format != VK_FORMAT_R12X4G12X4_UNORM_2PACK16;
3744}
3745
3746VkFormatFeatureFlags getAllowedOptimalTilingFeatures (Context &context, VkFormat format)
3747{
3748
3749	VkFormatFeatureFlags vulkanOnlyFeatureFlags = 0;
3750#ifndef CTS_USES_VULKANSC
3751	if (context.isDeviceFunctionalitySupported(VK_KHR_VIDEO_DECODE_QUEUE_EXTENSION_NAME))
3752		vulkanOnlyFeatureFlags |= VK_FORMAT_FEATURE_VIDEO_DECODE_DPB_BIT_KHR |
3753								  VK_FORMAT_FEATURE_VIDEO_DECODE_OUTPUT_BIT_KHR;
3754	if (context.isDeviceFunctionalitySupported(VK_KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME))
3755		vulkanOnlyFeatureFlags |= VK_FORMAT_FEATURE_VIDEO_ENCODE_INPUT_BIT_KHR |
3756							      VK_FORMAT_FEATURE_VIDEO_ENCODE_DPB_BIT_KHR;
3757#endif
3758
3759	// YCbCr formats only support a subset of format feature flags
3760	const VkFormatFeatureFlags ycbcrAllows =
3761		VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
3762		VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT |
3763		VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT |
3764		VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
3765		VK_FORMAT_FEATURE_TRANSFER_DST_BIT |
3766		VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT |
3767		VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT |
3768		VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT |
3769		VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT |
3770		VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT |
3771		VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT |
3772		VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT |
3773		VK_FORMAT_FEATURE_DISJOINT_BIT |
3774		vulkanOnlyFeatureFlags;
3775
3776	// By default everything is allowed.
3777	VkFormatFeatureFlags allow = (VkFormatFeatureFlags)~0u;
3778	// Formats for which SamplerYCbCrConversion is required may not support certain features.
3779	if (requiresYCbCrConversion(context, format))
3780		allow &= ycbcrAllows;
3781	// single-plane formats *may not* support DISJOINT_BIT
3782	if (!isYCbCrFormat(format) || getPlaneCount(format) == 1)
3783		allow &= ~VK_FORMAT_FEATURE_DISJOINT_BIT;
3784
3785	return allow;
3786}
3787
3788VkFormatFeatureFlags getAllowedBufferFeatures (Context &context, VkFormat format)
3789{
3790	// TODO: Do we allow non-buffer flags in the bufferFeatures?
3791	return requiresYCbCrConversion(context, format) ? (VkFormatFeatureFlags)0 : (VkFormatFeatureFlags)(~VK_FORMAT_FEATURE_DISJOINT_BIT);
3792}
3793
3794tcu::TestStatus formatProperties (Context& context, VkFormat format)
3795{
3796	// check if Ycbcr format enums are valid given the version and extensions
3797	if (isYCbCrFormat(format))
3798		checkYcbcrApiSupport(context);
3799
3800	TestLog&					log			= context.getTestContext().getLog();
3801	const VkFormatProperties	properties	= getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), format);
3802	const bool					apiVersion10WithoutKhrMaintenance1 = isApiVersionEqual(context.getUsedApiVersion(), VK_API_VERSION_1_0) && !context.isDeviceFunctionalitySupported("VK_KHR_maintenance1");
3803
3804	const VkFormatFeatureFlags reqImg	= getRequiredOptimalTilingFeatures(context, format);
3805	const VkFormatFeatureFlags reqBuf	= getRequiredBufferFeatures(format);
3806	const VkFormatFeatureFlags allowImg	= getAllowedOptimalTilingFeatures(context, format);
3807	const VkFormatFeatureFlags allowBuf	= getAllowedBufferFeatures(context, format);
3808	tcu::ResultCollector results (log, "ERROR: ");
3809
3810	const struct feature_req
3811	{
3812		const char*				fieldName;
3813		VkFormatFeatureFlags	supportedFeatures;
3814		VkFormatFeatureFlags	requiredFeatures;
3815		VkFormatFeatureFlags	allowedFeatures;
3816	} fields[] =
3817	{
3818		{ "linearTilingFeatures",	properties.linearTilingFeatures,	(VkFormatFeatureFlags)0,	allowImg },
3819		{ "optimalTilingFeatures",	properties.optimalTilingFeatures,	reqImg,						allowImg },
3820		{ "bufferFeatures",			properties.bufferFeatures,			reqBuf,						allowBuf }
3821	};
3822
3823	log << TestLog::Message << properties << TestLog::EndMessage;
3824
3825	for (int fieldNdx = 0; fieldNdx < DE_LENGTH_OF_ARRAY(fields); fieldNdx++)
3826	{
3827		const char* const			fieldName	= fields[fieldNdx].fieldName;
3828		VkFormatFeatureFlags		supported	= fields[fieldNdx].supportedFeatures;
3829		const VkFormatFeatureFlags	required	= fields[fieldNdx].requiredFeatures;
3830		const VkFormatFeatureFlags	allowed		= fields[fieldNdx].allowedFeatures;
3831
3832		if (apiVersion10WithoutKhrMaintenance1 && supported)
3833		{
3834			supported |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
3835		}
3836
3837		results.check((supported & required) == required, de::toString(fieldName) + ": required: " + de::toString(getFormatFeatureFlagsStr(required)) + "  missing: " + de::toString(getFormatFeatureFlagsStr(~supported & required)));
3838
3839		results.check((supported & ~allowed) == 0, de::toString(fieldName) + ": has: " + de::toString(getFormatFeatureFlagsStr(supported & ~allowed)));
3840
3841		if (((supported & VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT) != 0) &&
3842			((supported & VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT) == 0))
3843		{
3844			results.addResult(QP_TEST_RESULT_FAIL, de::toString(fieldName) + " supports VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT but not VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT");
3845		}
3846
3847		if (!isYCbCrFormat(format) && !isCompressedFormat(format)) {
3848			const tcu::TextureFormat tcuFormat = mapVkFormat(format);
3849			if (tcu::getNumUsedChannels(tcuFormat.order) != 1 && (supported & (VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT|VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT)) != 0)
3850			{
3851				results.addResult(QP_TEST_RESULT_QUALITY_WARNING, "VK_FORMAT_FEATURE_STORAGE_*_ATOMIC_BIT is only defined for single-component images");
3852			}
3853		}
3854	}
3855
3856	return tcu::TestStatus(results.getResult(), results.getMessage());
3857}
3858
3859bool optimalTilingFeaturesSupported (Context& context, VkFormat format, VkFormatFeatureFlags features)
3860{
3861	const VkFormatProperties	properties							= getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), format);
3862	const bool					apiVersion10WithoutKhrMaintenance1	= isApiVersionEqual(context.getUsedApiVersion(), VK_API_VERSION_1_0) && !context.isDeviceFunctionalitySupported("VK_KHR_maintenance1");
3863	VkFormatFeatureFlags		supported							= properties.optimalTilingFeatures;
3864
3865	if (apiVersion10WithoutKhrMaintenance1 && supported)
3866	{
3867		supported |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
3868	}
3869
3870	return (supported & features) == features;
3871}
3872
3873bool optimalTilingFeaturesSupportedForAll (Context& context, const VkFormat* begin, const VkFormat* end, VkFormatFeatureFlags features)
3874{
3875	for (const VkFormat* cur = begin; cur != end; ++cur)
3876	{
3877		if (!optimalTilingFeaturesSupported(context, *cur, features))
3878			return false;
3879	}
3880
3881	return true;
3882}
3883
3884tcu::TestStatus testDepthStencilSupported (Context& context)
3885{
3886	if (!optimalTilingFeaturesSupported(context, VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) &&
3887		!optimalTilingFeaturesSupported(context, VK_FORMAT_D32_SFLOAT, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
3888		return tcu::TestStatus::fail("Doesn't support one of VK_FORMAT_X8_D24_UNORM_PACK32 or VK_FORMAT_D32_SFLOAT");
3889
3890	if (!optimalTilingFeaturesSupported(context, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) &&
3891		!optimalTilingFeaturesSupported(context, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
3892		return tcu::TestStatus::fail("Doesn't support one of VK_FORMAT_D24_UNORM_S8_UINT or VK_FORMAT_D32_SFLOAT_S8_UINT");
3893
3894	return tcu::TestStatus::pass("Required depth/stencil formats supported");
3895}
3896
3897tcu::TestStatus testCompressedFormatsSupported (Context& context)
3898{
3899	static const VkFormat s_allBcFormats[] =
3900	{
3901		VK_FORMAT_BC1_RGB_UNORM_BLOCK,
3902		VK_FORMAT_BC1_RGB_SRGB_BLOCK,
3903		VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
3904		VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
3905		VK_FORMAT_BC2_UNORM_BLOCK,
3906		VK_FORMAT_BC2_SRGB_BLOCK,
3907		VK_FORMAT_BC3_UNORM_BLOCK,
3908		VK_FORMAT_BC3_SRGB_BLOCK,
3909		VK_FORMAT_BC4_UNORM_BLOCK,
3910		VK_FORMAT_BC4_SNORM_BLOCK,
3911		VK_FORMAT_BC5_UNORM_BLOCK,
3912		VK_FORMAT_BC5_SNORM_BLOCK,
3913		VK_FORMAT_BC6H_UFLOAT_BLOCK,
3914		VK_FORMAT_BC6H_SFLOAT_BLOCK,
3915		VK_FORMAT_BC7_UNORM_BLOCK,
3916		VK_FORMAT_BC7_SRGB_BLOCK,
3917	};
3918	static const VkFormat s_allEtc2Formats[] =
3919	{
3920		VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
3921		VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
3922		VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
3923		VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
3924		VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
3925		VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
3926		VK_FORMAT_EAC_R11_UNORM_BLOCK,
3927		VK_FORMAT_EAC_R11_SNORM_BLOCK,
3928		VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
3929		VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
3930	};
3931	static const VkFormat s_allAstcLdrFormats[] =
3932	{
3933		VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
3934		VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
3935		VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
3936		VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
3937		VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
3938		VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
3939		VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
3940		VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
3941		VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
3942		VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
3943		VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
3944		VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
3945		VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
3946		VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
3947		VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
3948		VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
3949		VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
3950		VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
3951		VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
3952		VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
3953		VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
3954		VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
3955		VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
3956		VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
3957		VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
3958		VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
3959		VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
3960		VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
3961	};
3962
3963	static const struct
3964	{
3965		const char*									setName;
3966		const char*									featureName;
3967		const VkBool32 VkPhysicalDeviceFeatures::*	feature;
3968		const VkFormat*								formatsBegin;
3969		const VkFormat*								formatsEnd;
3970	} s_compressedFormatSets[] =
3971	{
3972		{ "BC",			"textureCompressionBC",			&VkPhysicalDeviceFeatures::textureCompressionBC,		DE_ARRAY_BEGIN(s_allBcFormats),			DE_ARRAY_END(s_allBcFormats)		},
3973		{ "ETC2",		"textureCompressionETC2",		&VkPhysicalDeviceFeatures::textureCompressionETC2,		DE_ARRAY_BEGIN(s_allEtc2Formats),		DE_ARRAY_END(s_allEtc2Formats)		},
3974		{ "ASTC LDR",	"textureCompressionASTC_LDR",	&VkPhysicalDeviceFeatures::textureCompressionASTC_LDR,	DE_ARRAY_BEGIN(s_allAstcLdrFormats),	DE_ARRAY_END(s_allAstcLdrFormats)	},
3975	};
3976
3977	TestLog&						log					= context.getTestContext().getLog();
3978	const VkPhysicalDeviceFeatures&	features			= context.getDeviceFeatures();
3979	int								numSupportedSets	= 0;
3980	int								numErrors			= 0;
3981	int								numWarnings			= 0;
3982
3983	for (int setNdx = 0; setNdx < DE_LENGTH_OF_ARRAY(s_compressedFormatSets); ++setNdx)
3984	{
3985		const char* const			setName				= s_compressedFormatSets[setNdx].setName;
3986		const char* const			featureName			= s_compressedFormatSets[setNdx].featureName;
3987		const bool					featureBitSet		= features.*s_compressedFormatSets[setNdx].feature == VK_TRUE;
3988		const VkFormatFeatureFlags	requiredFeatures	=
3989			VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT |
3990			VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
3991		const bool			allSupported	= optimalTilingFeaturesSupportedForAll(context,
3992																				   s_compressedFormatSets[setNdx].formatsBegin,
3993																				   s_compressedFormatSets[setNdx].formatsEnd,
3994																				   requiredFeatures);
3995
3996		if (featureBitSet && !allSupported)
3997		{
3998			log << TestLog::Message << "ERROR: " << featureName << " = VK_TRUE but " << setName << " formats not supported" << TestLog::EndMessage;
3999			numErrors += 1;
4000		}
4001		else if (allSupported && !featureBitSet)
4002		{
4003			log << TestLog::Message << "WARNING: " << setName << " formats supported but " << featureName << " = VK_FALSE" << TestLog::EndMessage;
4004			numWarnings += 1;
4005		}
4006
4007		if (featureBitSet)
4008		{
4009			log << TestLog::Message << "All " << setName << " formats are supported" << TestLog::EndMessage;
4010			numSupportedSets += 1;
4011		}
4012		else
4013			log << TestLog::Message << setName << " formats are not supported" << TestLog::EndMessage;
4014	}
4015
4016	if (numSupportedSets == 0)
4017	{
4018		log << TestLog::Message << "No compressed format sets supported" << TestLog::EndMessage;
4019		numErrors += 1;
4020	}
4021
4022	if (numErrors > 0)
4023		return tcu::TestStatus::fail("Compressed format support not valid");
4024	else if (numWarnings > 0)
4025		return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Found inconsistencies in compressed format support");
4026	else
4027		return tcu::TestStatus::pass("Compressed texture format support is valid");
4028}
4029
4030void createFormatTests (tcu::TestCaseGroup* testGroup)
4031{
4032	DE_STATIC_ASSERT(VK_FORMAT_UNDEFINED == 0);
4033
4034	static const struct
4035	{
4036		VkFormat	begin;
4037		VkFormat	end;
4038	} s_formatRanges[] =
4039	{
4040		// core formats
4041		{ (VkFormat)(VK_FORMAT_UNDEFINED+1),		VK_CORE_FORMAT_LAST										},
4042
4043		// YCbCr formats
4044		{ VK_FORMAT_G8B8G8R8_422_UNORM,				(VkFormat)(VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM+1)	},
4045
4046		// YCbCr extended formats
4047		{ VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT,	(VkFormat)(VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT+1)	},
4048	};
4049
4050	for (int rangeNdx = 0; rangeNdx < DE_LENGTH_OF_ARRAY(s_formatRanges); ++rangeNdx)
4051	{
4052		const VkFormat								rangeBegin		= s_formatRanges[rangeNdx].begin;
4053		const VkFormat								rangeEnd		= s_formatRanges[rangeNdx].end;
4054
4055		for (VkFormat format = rangeBegin; format != rangeEnd; format = (VkFormat)(format+1))
4056		{
4057			const char* const	enumName	= getFormatName(format);
4058			const string		caseName	= de::toLower(string(enumName).substr(10));
4059
4060			addFunctionCase(testGroup, caseName, formatProperties, format);
4061		}
4062	}
4063
4064	addFunctionCase(testGroup, "depth_stencil",	testDepthStencilSupported);
4065	addFunctionCase(testGroup, "compressed_formats",	testCompressedFormatsSupported);
4066}
4067
4068VkImageUsageFlags getValidImageUsageFlags (const VkFormatFeatureFlags supportedFeatures, const bool useKhrMaintenance1Semantics)
4069{
4070	VkImageUsageFlags	flags	= (VkImageUsageFlags)0;
4071
4072	if (useKhrMaintenance1Semantics)
4073	{
4074		if ((supportedFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) != 0)
4075			flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
4076
4077		if ((supportedFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) != 0)
4078			flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4079	}
4080	else
4081	{
4082		// If format is supported at all, it must be valid transfer src+dst
4083		if (supportedFeatures != 0)
4084			flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT;
4085	}
4086
4087	if ((supportedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
4088		flags |= VK_IMAGE_USAGE_SAMPLED_BIT;
4089
4090	if ((supportedFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) != 0)
4091		flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT|VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
4092
4093	if ((supportedFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)
4094		flags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
4095
4096	if ((supportedFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0)
4097		flags |= VK_IMAGE_USAGE_STORAGE_BIT;
4098
4099	return flags;
4100}
4101
4102bool isValidImageUsageFlagCombination (VkImageUsageFlags usage)
4103{
4104	if ((usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0)
4105	{
4106		const VkImageUsageFlags		allowedFlags	= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
4107													| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
4108													| VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
4109													| VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
4110
4111		// Only *_ATTACHMENT_BIT flags can be combined with TRANSIENT_ATTACHMENT_BIT
4112		if ((usage & ~allowedFlags) != 0)
4113			return false;
4114
4115		// TRANSIENT_ATTACHMENT_BIT is not valid without COLOR_ or DEPTH_STENCIL_ATTACHMENT_BIT
4116		if ((usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) == 0)
4117			return false;
4118	}
4119
4120	return usage != 0;
4121}
4122
4123VkImageCreateFlags getValidImageCreateFlags (const VkPhysicalDeviceFeatures& deviceFeatures, VkFormat format, VkFormatFeatureFlags formatFeatures, VkImageType type, VkImageUsageFlags usage)
4124{
4125	VkImageCreateFlags	flags	= (VkImageCreateFlags)0;
4126
4127	if ((usage & VK_IMAGE_USAGE_SAMPLED_BIT) != 0)
4128	{
4129		flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
4130
4131		if (type == VK_IMAGE_TYPE_2D && !isYCbCrFormat(format))
4132		{
4133			flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
4134		}
4135	}
4136
4137	if (isYCbCrFormat(format) && getPlaneCount(format) > 1)
4138	{
4139		if (formatFeatures & VK_FORMAT_FEATURE_DISJOINT_BIT)
4140			flags |= VK_IMAGE_CREATE_DISJOINT_BIT;
4141	}
4142
4143	if ((usage & (VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_STORAGE_BIT)) != 0 &&
4144		(usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) == 0)
4145	{
4146		if (deviceFeatures.sparseBinding)
4147			flags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT|VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT;
4148
4149		if (deviceFeatures.sparseResidencyAliased)
4150			flags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT|VK_IMAGE_CREATE_SPARSE_ALIASED_BIT;
4151	}
4152
4153	return flags;
4154}
4155
4156bool isValidImageCreateFlagCombination (VkImageCreateFlags createFlags)
4157{
4158	bool isValid = true;
4159
4160	if (((createFlags & (VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT|VK_IMAGE_CREATE_SPARSE_ALIASED_BIT)) != 0) &&
4161		((createFlags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) == 0))
4162	{
4163		isValid = false;
4164	}
4165
4166	return isValid;
4167}
4168
4169bool isRequiredImageParameterCombination (const VkPhysicalDeviceFeatures&	deviceFeatures,
4170										  const VkFormat					format,
4171										  const VkFormatProperties&			formatProperties,
4172										  const VkImageType					imageType,
4173										  const VkImageTiling				imageTiling,
4174										  const VkImageUsageFlags			usageFlags,
4175										  const VkImageCreateFlags			createFlags)
4176{
4177	DE_UNREF(deviceFeatures);
4178	DE_UNREF(formatProperties);
4179	DE_UNREF(createFlags);
4180
4181	// Linear images can have arbitrary limitations
4182	if (imageTiling == VK_IMAGE_TILING_LINEAR)
4183		return false;
4184
4185	// Support for other usages for compressed formats is optional
4186	if (isCompressedFormat(format) &&
4187		(usageFlags & ~(VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT)) != 0)
4188		return false;
4189
4190	// Support for 1D, and sliced 3D compressed formats is optional
4191	if (isCompressedFormat(format) && (imageType == VK_IMAGE_TYPE_1D || imageType == VK_IMAGE_TYPE_3D))
4192		return false;
4193
4194	// Support for 1D and 3D depth/stencil textures is optional
4195	if (isDepthStencilFormat(format) && (imageType == VK_IMAGE_TYPE_1D || imageType == VK_IMAGE_TYPE_3D))
4196		return false;
4197
4198	DE_ASSERT(deviceFeatures.sparseBinding || (createFlags & (VK_IMAGE_CREATE_SPARSE_BINDING_BIT|VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)) == 0);
4199	DE_ASSERT(deviceFeatures.sparseResidencyAliased || (createFlags & VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) == 0);
4200
4201	if (isYCbCrFormat(format) && (createFlags & (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)))
4202		return false;
4203
4204	if (createFlags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)
4205	{
4206		if (isCompressedFormat(format))
4207			return false;
4208
4209		if (isDepthStencilFormat(format))
4210			return false;
4211
4212		if (!deIsPowerOfTwo32(mapVkFormat(format).getPixelSize()))
4213			return false;
4214
4215		switch (imageType)
4216		{
4217			case VK_IMAGE_TYPE_2D:
4218				return (deviceFeatures.sparseResidencyImage2D == VK_TRUE);
4219			case VK_IMAGE_TYPE_3D:
4220				return (deviceFeatures.sparseResidencyImage3D == VK_TRUE);
4221			default:
4222				return false;
4223		}
4224	}
4225
4226	return true;
4227}
4228
4229VkSampleCountFlags getRequiredOptimalTilingSampleCounts (const VkPhysicalDeviceLimits&	deviceLimits,
4230														 const VkFormat					format,
4231														 const VkImageUsageFlags		usageFlags)
4232{
4233	if (isCompressedFormat(format))
4234		return VK_SAMPLE_COUNT_1_BIT;
4235
4236	bool		hasDepthComp	= false;
4237	bool		hasStencilComp	= false;
4238	const bool	isYCbCr			= isYCbCrFormat(format);
4239	if (!isYCbCr)
4240	{
4241		const tcu::TextureFormat	tcuFormat		= mapVkFormat(format);
4242		hasDepthComp	= (tcuFormat.order == tcu::TextureFormat::D || tcuFormat.order == tcu::TextureFormat::DS);
4243		hasStencilComp	= (tcuFormat.order == tcu::TextureFormat::S || tcuFormat.order == tcu::TextureFormat::DS);
4244	}
4245
4246	const bool						isColorFormat	= !hasDepthComp && !hasStencilComp;
4247	VkSampleCountFlags				sampleCounts	= ~(VkSampleCountFlags)0;
4248
4249	DE_ASSERT((hasDepthComp || hasStencilComp) != isColorFormat);
4250
4251	if ((usageFlags & VK_IMAGE_USAGE_STORAGE_BIT) != 0)
4252		sampleCounts &= deviceLimits.storageImageSampleCounts;
4253
4254	if ((usageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) != 0)
4255	{
4256		if (hasDepthComp)
4257			sampleCounts &= deviceLimits.sampledImageDepthSampleCounts;
4258
4259		if (hasStencilComp)
4260			sampleCounts &= deviceLimits.sampledImageStencilSampleCounts;
4261
4262		if (isColorFormat)
4263		{
4264			if (isYCbCr)
4265				sampleCounts &= deviceLimits.sampledImageColorSampleCounts;
4266			else
4267			{
4268				const tcu::TextureFormat		tcuFormat	= mapVkFormat(format);
4269				const tcu::TextureChannelClass	chnClass	= tcu::getTextureChannelClass(tcuFormat.type);
4270
4271				if (chnClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ||
4272					chnClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
4273					sampleCounts &= deviceLimits.sampledImageIntegerSampleCounts;
4274				else
4275					sampleCounts &= deviceLimits.sampledImageColorSampleCounts;
4276			}
4277		}
4278	}
4279
4280	if ((usageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) != 0)
4281		sampleCounts &= deviceLimits.framebufferColorSampleCounts;
4282
4283	if ((usageFlags & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)
4284	{
4285		if (hasDepthComp)
4286			sampleCounts &= deviceLimits.framebufferDepthSampleCounts;
4287
4288		if (hasStencilComp)
4289			sampleCounts &= deviceLimits.framebufferStencilSampleCounts;
4290	}
4291
4292	// If there is no usage flag set that would have corresponding device limit,
4293	// only VK_SAMPLE_COUNT_1_BIT is required.
4294	if (sampleCounts == ~(VkSampleCountFlags)0)
4295		sampleCounts &= VK_SAMPLE_COUNT_1_BIT;
4296
4297	return sampleCounts;
4298}
4299
4300struct ImageFormatPropertyCase
4301{
4302	typedef tcu::TestStatus (*Function) (Context& context, const VkFormat format, const VkImageType imageType, const VkImageTiling tiling);
4303
4304	Function		testFunction;
4305	VkFormat		format;
4306	VkImageType		imageType;
4307	VkImageTiling	tiling;
4308
4309	ImageFormatPropertyCase (Function testFunction_, VkFormat format_, VkImageType imageType_, VkImageTiling tiling_)
4310		: testFunction	(testFunction_)
4311		, format		(format_)
4312		, imageType		(imageType_)
4313		, tiling		(tiling_)
4314	{}
4315
4316	ImageFormatPropertyCase (void)
4317		: testFunction	((Function)DE_NULL)
4318		, format		(VK_FORMAT_UNDEFINED)
4319		, imageType		(VK_CORE_IMAGE_TYPE_LAST)
4320		, tiling		(VK_CORE_IMAGE_TILING_LAST)
4321	{}
4322};
4323
4324tcu::TestStatus imageFormatProperties (Context& context, const VkFormat format, const VkImageType imageType, const VkImageTiling tiling)
4325{
4326	if (isYCbCrFormat(format))
4327		// check if Ycbcr format enums are valid given the version and extensions
4328		checkYcbcrApiSupport(context);
4329
4330	TestLog&						log					= context.getTestContext().getLog();
4331	const VkPhysicalDeviceFeatures&	deviceFeatures		= context.getDeviceFeatures();
4332	const VkPhysicalDeviceLimits&	deviceLimits		= context.getDeviceProperties().limits;
4333	const VkFormatProperties		formatProperties	= getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), format);
4334	const bool						hasKhrMaintenance1	= context.isDeviceFunctionalitySupported("VK_KHR_maintenance1");
4335
4336	const VkFormatFeatureFlags		supportedFeatures	= tiling == VK_IMAGE_TILING_LINEAR ? formatProperties.linearTilingFeatures : formatProperties.optimalTilingFeatures;
4337	const VkImageUsageFlags			usageFlagSet		= getValidImageUsageFlags(supportedFeatures, hasKhrMaintenance1);
4338
4339	tcu::ResultCollector			results				(log, "ERROR: ");
4340
4341	if (hasKhrMaintenance1 && (supportedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
4342	{
4343		results.check((supportedFeatures & (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT|VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) != 0,
4344					  "A sampled image format must have VK_FORMAT_FEATURE_TRANSFER_SRC_BIT and VK_FORMAT_FEATURE_TRANSFER_DST_BIT format feature flags set");
4345	}
4346
4347	if (isYcbcrConversionSupported(context) && (format == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM || format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM))
4348	{
4349		VkFormatFeatureFlags requiredFeatures = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
4350		if (tiling == VK_IMAGE_TILING_OPTIMAL)
4351			requiredFeatures |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT;
4352
4353		results.check((supportedFeatures & requiredFeatures) == requiredFeatures,
4354					  getFormatName(format) + string(" must support ") + de::toString(getFormatFeatureFlagsStr(requiredFeatures)));
4355	}
4356
4357	for (VkImageUsageFlags curUsageFlags = 0; curUsageFlags <= usageFlagSet; curUsageFlags++)
4358	{
4359		if ((curUsageFlags & ~usageFlagSet) != 0 ||
4360			!isValidImageUsageFlagCombination(curUsageFlags))
4361			continue;
4362
4363		const VkImageCreateFlags	createFlagSet		= getValidImageCreateFlags(deviceFeatures, format, supportedFeatures, imageType, curUsageFlags);
4364
4365		for (VkImageCreateFlags curCreateFlags = 0; curCreateFlags <= createFlagSet; curCreateFlags++)
4366		{
4367			if ((curCreateFlags & ~createFlagSet) != 0 ||
4368				!isValidImageCreateFlagCombination(curCreateFlags))
4369				continue;
4370
4371			const bool				isRequiredCombination	= isRequiredImageParameterCombination(deviceFeatures,
4372																								  format,
4373																								  formatProperties,
4374																								  imageType,
4375																								  tiling,
4376																								  curUsageFlags,
4377																								  curCreateFlags);
4378			VkImageFormatProperties	properties;
4379			VkResult				queryResult;
4380
4381			log << TestLog::Message << "Testing " << getImageTypeStr(imageType) << ", "
4382									<< getImageTilingStr(tiling) << ", "
4383									<< getImageUsageFlagsStr(curUsageFlags) << ", "
4384									<< getImageCreateFlagsStr(curCreateFlags)
4385				<< TestLog::EndMessage;
4386
4387			// Set return value to known garbage
4388			deMemset(&properties, 0xcd, sizeof(properties));
4389
4390			queryResult = context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(context.getPhysicalDevice(),
4391																								format,
4392																								imageType,
4393																								tiling,
4394																								curUsageFlags,
4395																								curCreateFlags,
4396																								&properties);
4397
4398			if (queryResult == VK_SUCCESS)
4399			{
4400				const deUint32	fullMipPyramidSize	= de::max(de::max(deLog2Floor32(properties.maxExtent.width),
4401																	  deLog2Floor32(properties.maxExtent.height)),
4402															  deLog2Floor32(properties.maxExtent.depth)) + 1;
4403
4404				log << TestLog::Message << properties << "\n" << TestLog::EndMessage;
4405
4406				results.check(imageType != VK_IMAGE_TYPE_1D || (properties.maxExtent.width >= 1 && properties.maxExtent.height == 1 && properties.maxExtent.depth == 1), "Invalid dimensions for 1D image");
4407				results.check(imageType != VK_IMAGE_TYPE_2D || (properties.maxExtent.width >= 1 && properties.maxExtent.height >= 1 && properties.maxExtent.depth == 1), "Invalid dimensions for 2D image");
4408				results.check(imageType != VK_IMAGE_TYPE_3D || (properties.maxExtent.width >= 1 && properties.maxExtent.height >= 1 && properties.maxExtent.depth >= 1), "Invalid dimensions for 3D image");
4409				results.check(imageType != VK_IMAGE_TYPE_3D || properties.maxArrayLayers == 1, "Invalid maxArrayLayers for 3D image");
4410
4411				if (tiling == VK_IMAGE_TILING_OPTIMAL && imageType == VK_IMAGE_TYPE_2D && !(curCreateFlags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
4412					 (supportedFeatures & (VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)))
4413				{
4414					const VkSampleCountFlags	requiredSampleCounts	= getRequiredOptimalTilingSampleCounts(deviceLimits, format, curUsageFlags);
4415					results.check((properties.sampleCounts & requiredSampleCounts) == requiredSampleCounts, "Required sample counts not supported");
4416				}
4417				else
4418					results.check(properties.sampleCounts == VK_SAMPLE_COUNT_1_BIT, "sampleCounts != VK_SAMPLE_COUNT_1_BIT");
4419
4420				if (isRequiredCombination)
4421				{
4422					results.check(imageType != VK_IMAGE_TYPE_1D || (properties.maxExtent.width	>= deviceLimits.maxImageDimension1D),
4423								  "Reported dimensions smaller than device limits");
4424					results.check(imageType != VK_IMAGE_TYPE_2D || (properties.maxExtent.width	>= deviceLimits.maxImageDimension2D &&
4425																	properties.maxExtent.height	>= deviceLimits.maxImageDimension2D),
4426								  "Reported dimensions smaller than device limits");
4427					results.check(imageType != VK_IMAGE_TYPE_3D || (properties.maxExtent.width	>= deviceLimits.maxImageDimension3D &&
4428																	properties.maxExtent.height	>= deviceLimits.maxImageDimension3D &&
4429																	properties.maxExtent.depth	>= deviceLimits.maxImageDimension3D),
4430								  "Reported dimensions smaller than device limits");
4431					results.check((isYCbCrFormat(format) && (properties.maxMipLevels == 1)) || properties.maxMipLevels == fullMipPyramidSize,
4432					              "Invalid mip pyramid size");
4433					results.check((isYCbCrFormat(format) && (properties.maxArrayLayers == 1)) || imageType == VK_IMAGE_TYPE_3D ||
4434					              properties.maxArrayLayers >= deviceLimits.maxImageArrayLayers, "Invalid maxArrayLayers");
4435				}
4436				else
4437				{
4438					results.check(properties.maxMipLevels == 1 || properties.maxMipLevels == fullMipPyramidSize, "Invalid mip pyramid size");
4439					results.check(properties.maxArrayLayers >= 1, "Invalid maxArrayLayers");
4440				}
4441
4442				results.check(properties.maxResourceSize >= (VkDeviceSize)MINIMUM_REQUIRED_IMAGE_RESOURCE_SIZE,
4443							  "maxResourceSize smaller than minimum required size");
4444			}
4445			else if (queryResult == VK_ERROR_FORMAT_NOT_SUPPORTED)
4446			{
4447				log << TestLog::Message << "Got VK_ERROR_FORMAT_NOT_SUPPORTED" << TestLog::EndMessage;
4448
4449				if (isRequiredCombination)
4450					results.fail("VK_ERROR_FORMAT_NOT_SUPPORTED returned for required image parameter combination");
4451
4452				// Specification requires that all fields are set to 0
4453				results.check(properties.maxExtent.width	== 0, "maxExtent.width != 0");
4454				results.check(properties.maxExtent.height	== 0, "maxExtent.height != 0");
4455				results.check(properties.maxExtent.depth	== 0, "maxExtent.depth != 0");
4456				results.check(properties.maxMipLevels		== 0, "maxMipLevels != 0");
4457				results.check(properties.maxArrayLayers		== 0, "maxArrayLayers != 0");
4458				results.check(properties.sampleCounts		== 0, "sampleCounts != 0");
4459				results.check(properties.maxResourceSize	== 0, "maxResourceSize != 0");
4460			}
4461			else
4462			{
4463				results.fail("Got unexpected error" + de::toString(queryResult));
4464			}
4465		}
4466	}
4467	return tcu::TestStatus(results.getResult(), results.getMessage());
4468}
4469
4470// VK_KHR_get_physical_device_properties2
4471
4472string toString(const VkPhysicalDevicePCIBusInfoPropertiesEXT& value)
4473{
4474	std::ostringstream  s;
4475	s << "VkPhysicalDevicePCIBusInfoPropertiesEXT = {\n";
4476	s << "\tsType = " << value.sType << '\n';
4477	s << "\tpciDomain = " << value.pciDomain << '\n';
4478	s << "\tpciBus = " << value.pciBus << '\n';
4479	s << "\tpciDevice = " << value.pciDevice << '\n';
4480	s << "\tpciFunction = " << value.pciFunction << '\n';
4481	s << '}';
4482	return s.str();
4483}
4484
4485bool checkExtension (vector<VkExtensionProperties>& properties, const char* extension)
4486{
4487	for (size_t ndx = 0; ndx < properties.size(); ++ndx)
4488	{
4489		if (strncmp(properties[ndx].extensionName, extension, VK_MAX_EXTENSION_NAME_SIZE) == 0)
4490			return true;
4491	}
4492	return false;
4493}
4494
4495#include "vkDeviceFeatures2.inl"
4496
4497tcu::TestStatus deviceFeatures2 (Context& context)
4498{
4499	const VkPhysicalDevice      physicalDevice = context.getPhysicalDevice();
4500	const CustomInstance		instance		(createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
4501	const InstanceDriver&		vki				(instance.getDriver());
4502	TestLog&					log				= context.getTestContext().getLog();
4503	VkPhysicalDeviceFeatures	coreFeatures;
4504	VkPhysicalDeviceFeatures2	extFeatures;
4505
4506	deMemset(&coreFeatures, 0xcd, sizeof(coreFeatures));
4507	deMemset(&extFeatures.features, 0xcd, sizeof(extFeatures.features));
4508	std::vector<std::string> instExtensions = context.getInstanceExtensions();
4509
4510	extFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
4511	extFeatures.pNext = DE_NULL;
4512
4513	vki.getPhysicalDeviceFeatures(physicalDevice, &coreFeatures);
4514	vki.getPhysicalDeviceFeatures2(physicalDevice, &extFeatures);
4515
4516	TCU_CHECK(extFeatures.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2);
4517	TCU_CHECK(extFeatures.pNext == DE_NULL);
4518
4519	if (deMemCmp(&coreFeatures, &extFeatures.features, sizeof(VkPhysicalDeviceFeatures)) != 0)
4520		TCU_FAIL("Mismatch between features reported by vkGetPhysicalDeviceFeatures and vkGetPhysicalDeviceFeatures2");
4521
4522	log << TestLog::Message << extFeatures << TestLog::EndMessage;
4523
4524	return tcu::TestStatus::pass("Querying device features succeeded");
4525}
4526
4527tcu::TestStatus deviceProperties2 (Context& context)
4528{
4529	const CustomInstance			instance		(createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
4530	const InstanceDriver&			vki				(instance.getDriver());
4531	const VkPhysicalDevice			physicalDevice	(chooseDevice(vki, instance, context.getTestContext().getCommandLine()));
4532	TestLog&						log				= context.getTestContext().getLog();
4533	VkPhysicalDeviceProperties		coreProperties;
4534	VkPhysicalDeviceProperties2		extProperties;
4535
4536	extProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
4537	extProperties.pNext = DE_NULL;
4538
4539	vki.getPhysicalDeviceProperties(physicalDevice, &coreProperties);
4540	vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
4541
4542	TCU_CHECK(extProperties.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2);
4543	TCU_CHECK(extProperties.pNext == DE_NULL);
4544
4545	// We can't use memcmp() here because the structs may contain padding bytes that drivers may or may not
4546	// have written while writing the data and memcmp will compare them anyway, so we iterate through the
4547	// valid bytes for each field in the struct and compare only the valid bytes for each one.
4548	for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(s_physicalDevicePropertiesOffsetTable); propNdx++)
4549	{
4550		const size_t offset					= s_physicalDevicePropertiesOffsetTable[propNdx].offset;
4551		const size_t size					= s_physicalDevicePropertiesOffsetTable[propNdx].size;
4552
4553		const deUint8* corePropertyBytes	= reinterpret_cast<deUint8*>(&coreProperties) + offset;
4554		const deUint8* extPropertyBytes		= reinterpret_cast<deUint8*>(&extProperties.properties) + offset;
4555
4556		if (deMemCmp(corePropertyBytes, extPropertyBytes, size) != 0)
4557			TCU_FAIL("Mismatch between properties reported by vkGetPhysicalDeviceProperties and vkGetPhysicalDeviceProperties2");
4558	}
4559
4560	log << TestLog::Message << extProperties.properties << TestLog::EndMessage;
4561
4562	const int count = 2u;
4563
4564	vector<VkExtensionProperties> properties		= enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
4565	const bool khr_external_fence_capabilities		= checkExtension(properties, "VK_KHR_external_fence_capabilities")		||	context.contextSupports(vk::ApiVersion(0, 1, 1, 0));
4566	const bool khr_external_memory_capabilities		= checkExtension(properties, "VK_KHR_external_memory_capabilities")		||	context.contextSupports(vk::ApiVersion(0, 1, 1, 0));
4567	const bool khr_external_semaphore_capabilities	= checkExtension(properties, "VK_KHR_external_semaphore_capabilities")	||	context.contextSupports(vk::ApiVersion(0, 1, 1, 0));
4568	const bool khr_multiview						= checkExtension(properties, "VK_KHR_multiview")						||	context.contextSupports(vk::ApiVersion(0, 1, 1, 0));
4569	const bool khr_device_protected_memory			=																			context.contextSupports(vk::ApiVersion(0, 1, 1, 0));
4570	const bool khr_device_subgroup					=																			context.contextSupports(vk::ApiVersion(0, 1, 1, 0));
4571	const bool khr_maintenance2						= checkExtension(properties, "VK_KHR_maintenance2")						||	context.contextSupports(vk::ApiVersion(0, 1, 1, 0));
4572	const bool khr_maintenance3						= checkExtension(properties, "VK_KHR_maintenance3")						||	context.contextSupports(vk::ApiVersion(0, 1, 1, 0));
4573	const bool khr_depth_stencil_resolve			= checkExtension(properties, "VK_KHR_depth_stencil_resolve")			||	context.contextSupports(vk::ApiVersion(0, 1, 2, 0));
4574	const bool khr_driver_properties				= checkExtension(properties, "VK_KHR_driver_properties")				||	context.contextSupports(vk::ApiVersion(0, 1, 2, 0));
4575	const bool khr_shader_float_controls			= checkExtension(properties, "VK_KHR_shader_float_controls")			||	context.contextSupports(vk::ApiVersion(0, 1, 2, 0));
4576	const bool khr_descriptor_indexing				= checkExtension(properties, "VK_EXT_descriptor_indexing")				||	context.contextSupports(vk::ApiVersion(0, 1, 2, 0));
4577	const bool khr_sampler_filter_minmax			= checkExtension(properties, "VK_EXT_sampler_filter_minmax")			||	context.contextSupports(vk::ApiVersion(0, 1, 2, 0));
4578#ifndef CTS_USES_VULKANSC
4579	const bool khr_acceleration_structure			= checkExtension(properties, "VK_KHR_acceleration_structure");
4580	const bool khr_integer_dot_product				= checkExtension(properties, "VK_KHR_shader_integer_dot_product")		||	context.contextSupports(vk::ApiVersion(0, 1, 3, 0));
4581	const bool khr_inline_uniform_block				= checkExtension(properties, "VK_EXT_inline_uniform_block")				||	context.contextSupports(vk::ApiVersion(0, 1, 3, 0));
4582	const bool khr_maintenance4						= checkExtension(properties, "VK_KHR_maintenance4")						||	context.contextSupports(vk::ApiVersion(0, 1, 3, 0));
4583	const bool khr_subgroup_size_control			= checkExtension(properties, "VK_EXT_subgroup_size_control")			||	context.contextSupports(vk::ApiVersion(0, 1, 3, 0));
4584	const bool khr_texel_buffer_alignment			= checkExtension(properties, "VK_EXT_texel_buffer_alignment")			||	context.contextSupports(vk::ApiVersion(0, 1, 3, 0));
4585#endif // CTS_USES_VULKANSC
4586
4587	VkPhysicalDeviceIDProperties							idProperties[count];
4588	VkPhysicalDeviceMultiviewProperties						multiviewProperties[count];
4589	VkPhysicalDeviceProtectedMemoryProperties				protectedMemoryPropertiesKHR[count];
4590	VkPhysicalDeviceSubgroupProperties						subgroupProperties[count];
4591	VkPhysicalDevicePointClippingProperties					pointClippingProperties[count];
4592	VkPhysicalDeviceMaintenance3Properties					maintenance3Properties[count];
4593	VkPhysicalDeviceDepthStencilResolveProperties			depthStencilResolveProperties[count];
4594	VkPhysicalDeviceDriverProperties						driverProperties[count];
4595	VkPhysicalDeviceFloatControlsProperties					floatControlsProperties[count];
4596	VkPhysicalDeviceDescriptorIndexingProperties			descriptorIndexingProperties[count];
4597	VkPhysicalDeviceSamplerFilterMinmaxProperties			samplerFilterMinmaxProperties[count];
4598#ifndef CTS_USES_VULKANSC
4599	VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR	integerDotProductProperties[count];
4600	VkPhysicalDeviceAccelerationStructurePropertiesKHR		accelerationStructureProperties[count];
4601	VkPhysicalDeviceInlineUniformBlockProperties			inlineUniformBlockProperties[count];
4602	VkPhysicalDeviceMaintenance4Properties					maintenance4Properties[count];
4603	VkPhysicalDeviceSubgroupSizeControlProperties			subgroupSizeControlProperties[count];
4604	VkPhysicalDeviceTexelBufferAlignmentProperties			texelBufferAlignmentProperties[count];
4605#endif // CTS_USES_VULKANSC
4606	for (int ndx = 0; ndx < count; ++ndx)
4607	{
4608		deMemset(&idProperties[ndx],					0xFF*ndx, sizeof(VkPhysicalDeviceIDProperties							));
4609		deMemset(&multiviewProperties[ndx],				0xFF*ndx, sizeof(VkPhysicalDeviceMultiviewProperties					));
4610		deMemset(&protectedMemoryPropertiesKHR[ndx],	0xFF*ndx, sizeof(VkPhysicalDeviceProtectedMemoryProperties				));
4611		deMemset(&subgroupProperties[ndx],				0xFF*ndx, sizeof(VkPhysicalDeviceSubgroupProperties						));
4612		deMemset(&pointClippingProperties[ndx],			0xFF*ndx, sizeof(VkPhysicalDevicePointClippingProperties				));
4613		deMemset(&maintenance3Properties[ndx],			0xFF*ndx, sizeof(VkPhysicalDeviceMaintenance3Properties					));
4614		deMemset(&depthStencilResolveProperties[ndx],	0xFF*ndx, sizeof(VkPhysicalDeviceDepthStencilResolveProperties			));
4615		deMemset(&driverProperties[ndx],				0xFF*ndx, sizeof(VkPhysicalDeviceDriverProperties						));
4616		deMemset(&floatControlsProperties[ndx],			0xFF*ndx, sizeof(VkPhysicalDeviceFloatControlsProperties				));
4617		deMemset(&descriptorIndexingProperties[ndx],	0xFF*ndx, sizeof(VkPhysicalDeviceDescriptorIndexingProperties			));
4618		deMemset(&samplerFilterMinmaxProperties[ndx],	0xFF*ndx, sizeof(VkPhysicalDeviceSamplerFilterMinmaxProperties			));
4619#ifndef CTS_USES_VULKANSC
4620		deMemset(&integerDotProductProperties[ndx],		0xFF*ndx, sizeof(VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR	));
4621		deMemset(&accelerationStructureProperties[ndx],	0xFF*ndx, sizeof(VkPhysicalDeviceAccelerationStructurePropertiesKHR	));
4622		deMemset(&inlineUniformBlockProperties[ndx],	0xFF*ndx, sizeof(VkPhysicalDeviceInlineUniformBlockProperties			));
4623		deMemset(&maintenance4Properties[ndx],			0xFF*ndx, sizeof(VkPhysicalDeviceMaintenance4Properties					));
4624		deMemset(&subgroupSizeControlProperties[ndx],	0xFF*ndx, sizeof(VkPhysicalDeviceSubgroupSizeControlProperties			));
4625		deMemset(&texelBufferAlignmentProperties[ndx],	0xFF*ndx, sizeof(VkPhysicalDeviceTexelBufferAlignmentProperties			));
4626#endif // CTS_USES_VULKANSC
4627
4628		void* prev = 0;
4629
4630		if (khr_external_fence_capabilities || khr_external_memory_capabilities || khr_external_semaphore_capabilities)
4631		{
4632			idProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
4633			idProperties[ndx].pNext = prev;
4634			prev = &idProperties[ndx];
4635		}
4636
4637		if (khr_multiview)
4638		{
4639			multiviewProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES;
4640			multiviewProperties[ndx].pNext = prev;
4641			prev = &multiviewProperties[ndx];
4642		}
4643
4644		if (khr_device_protected_memory)
4645		{
4646			protectedMemoryPropertiesKHR[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES;
4647			protectedMemoryPropertiesKHR[ndx].pNext = prev;
4648			prev = &protectedMemoryPropertiesKHR[ndx];
4649		}
4650
4651		if (khr_device_subgroup)
4652		{
4653			subgroupProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
4654			subgroupProperties[ndx].pNext = prev;
4655			prev = &subgroupProperties[ndx];
4656		}
4657
4658		if (khr_maintenance2)
4659		{
4660			pointClippingProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES;
4661			pointClippingProperties[ndx].pNext = prev;
4662			prev = &pointClippingProperties[ndx];
4663		}
4664
4665		if (khr_maintenance3)
4666		{
4667			maintenance3Properties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES;
4668			maintenance3Properties[ndx].pNext = prev;
4669			prev = &maintenance3Properties[ndx];
4670		}
4671
4672		if (khr_depth_stencil_resolve)
4673		{
4674			depthStencilResolveProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES;
4675			depthStencilResolveProperties[ndx].pNext = prev;
4676			prev = &depthStencilResolveProperties[ndx];
4677		}
4678
4679		if (khr_driver_properties)
4680		{
4681			driverProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
4682			driverProperties[ndx].pNext = prev;
4683			prev = &driverProperties[ndx];
4684		}
4685
4686		if (khr_shader_float_controls)
4687		{
4688			floatControlsProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES;
4689			floatControlsProperties[ndx].pNext = prev;
4690			prev = &floatControlsProperties[ndx];
4691		}
4692
4693		if (khr_descriptor_indexing)
4694		{
4695			descriptorIndexingProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES;
4696			descriptorIndexingProperties[ndx].pNext = prev;
4697			prev = &descriptorIndexingProperties[ndx];
4698		}
4699
4700		if (khr_sampler_filter_minmax)
4701		{
4702			samplerFilterMinmaxProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES;
4703			samplerFilterMinmaxProperties[ndx].pNext = prev;
4704			prev = &samplerFilterMinmaxProperties[ndx];
4705		}
4706
4707#ifndef CTS_USES_VULKANSC
4708		if (khr_integer_dot_product)
4709		{
4710			integerDotProductProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR;
4711			integerDotProductProperties[ndx].pNext = prev;
4712			prev = &integerDotProductProperties[ndx];
4713		}
4714
4715		if (khr_acceleration_structure)
4716		{
4717			accelerationStructureProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR;
4718			accelerationStructureProperties[ndx].pNext = prev;
4719			prev = &accelerationStructureProperties[ndx];
4720		}
4721
4722		if (khr_inline_uniform_block)
4723		{
4724			inlineUniformBlockProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES;
4725			inlineUniformBlockProperties[ndx].pNext = prev;
4726			prev = &inlineUniformBlockProperties[ndx];
4727		}
4728
4729		if (khr_maintenance4)
4730		{
4731			maintenance4Properties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES;
4732			maintenance4Properties[ndx].pNext = prev;
4733			prev = &maintenance4Properties[ndx];
4734		}
4735
4736		if (khr_subgroup_size_control)
4737		{
4738			subgroupSizeControlProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES;
4739			subgroupSizeControlProperties[ndx].pNext = prev;
4740			prev = &subgroupSizeControlProperties[ndx];
4741		}
4742
4743		if (khr_texel_buffer_alignment)
4744		{
4745			texelBufferAlignmentProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES;
4746			texelBufferAlignmentProperties[ndx].pNext = prev;
4747			prev = &texelBufferAlignmentProperties[ndx];
4748		}
4749#endif // CTS_USES_VULKANSC
4750
4751		if (prev == 0)
4752			TCU_THROW(NotSupportedError, "No supported structures found");
4753
4754		extProperties.pNext							= prev;
4755
4756		vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
4757	}
4758
4759	if (khr_external_fence_capabilities || khr_external_memory_capabilities || khr_external_semaphore_capabilities)
4760		log << TestLog::Message << idProperties[0]					<< TestLog::EndMessage;
4761	if (khr_multiview)
4762		log << TestLog::Message << multiviewProperties[0]			<< TestLog::EndMessage;
4763	if (khr_device_protected_memory)
4764		log << TestLog::Message << protectedMemoryPropertiesKHR[0]	<< TestLog::EndMessage;
4765	if (khr_device_subgroup)
4766		log << TestLog::Message << subgroupProperties[0]			<< TestLog::EndMessage;
4767	if (khr_maintenance2)
4768		log << TestLog::Message << pointClippingProperties[0]		<< TestLog::EndMessage;
4769	if (khr_maintenance3)
4770		log << TestLog::Message << maintenance3Properties[0]		<< TestLog::EndMessage;
4771	if (khr_depth_stencil_resolve)
4772		log << TestLog::Message << depthStencilResolveProperties[0] << TestLog::EndMessage;
4773	if (khr_driver_properties)
4774		log << TestLog::Message << driverProperties[0]				<< TestLog::EndMessage;
4775	if (khr_shader_float_controls)
4776		log << TestLog::Message << floatControlsProperties[0]		<< TestLog::EndMessage;
4777	if (khr_descriptor_indexing)
4778		log << TestLog::Message << descriptorIndexingProperties[0] << TestLog::EndMessage;
4779	if (khr_sampler_filter_minmax)
4780		log << TestLog::Message << samplerFilterMinmaxProperties[0] << TestLog::EndMessage;
4781#ifndef CTS_USES_VULKANSC
4782	if (khr_integer_dot_product)
4783		log << TestLog::Message << integerDotProductProperties[0] << TestLog::EndMessage;
4784	if (khr_acceleration_structure)
4785		log << TestLog::Message << accelerationStructureProperties[0] << TestLog::EndMessage;
4786	if (khr_inline_uniform_block)
4787		log << TestLog::Message << inlineUniformBlockProperties[0] << TestLog::EndMessage;
4788	if (khr_maintenance4)
4789		log << TestLog::Message << maintenance4Properties[0] << TestLog::EndMessage;
4790	if (khr_subgroup_size_control)
4791		log << TestLog::Message << subgroupSizeControlProperties[0] << TestLog::EndMessage;
4792	if (khr_texel_buffer_alignment)
4793		log << TestLog::Message << texelBufferAlignmentProperties[0] << TestLog::EndMessage;
4794#endif // CTS_USES_VULKANSC
4795
4796	if ( khr_external_fence_capabilities || khr_external_memory_capabilities || khr_external_semaphore_capabilities )
4797	{
4798		if ((deMemCmp(idProperties[0].deviceUUID, idProperties[1].deviceUUID, VK_UUID_SIZE) != 0) ||
4799			(deMemCmp(idProperties[0].driverUUID, idProperties[1].driverUUID, VK_UUID_SIZE) != 0) ||
4800			(idProperties[0].deviceLUIDValid	!= idProperties[1].deviceLUIDValid))
4801		{
4802			TCU_FAIL("Mismatch between VkPhysicalDeviceIDProperties");
4803		}
4804		else if (idProperties[0].deviceLUIDValid)
4805		{
4806			// If deviceLUIDValid is VK_FALSE, the contents of deviceLUID and deviceNodeMask are undefined
4807			// so thay can only be compared when deviceLUIDValid is VK_TRUE.
4808			if ((deMemCmp(idProperties[0].deviceLUID, idProperties[1].deviceLUID, VK_LUID_SIZE) != 0) ||
4809				(idProperties[0].deviceNodeMask		!= idProperties[1].deviceNodeMask))
4810			{
4811				TCU_FAIL("Mismatch between VkPhysicalDeviceIDProperties");
4812			}
4813		}
4814	}
4815	if (khr_multiview &&
4816		(multiviewProperties[0].maxMultiviewViewCount		!= multiviewProperties[1].maxMultiviewViewCount ||
4817		 multiviewProperties[0].maxMultiviewInstanceIndex	!= multiviewProperties[1].maxMultiviewInstanceIndex))
4818	{
4819		TCU_FAIL("Mismatch between VkPhysicalDeviceMultiviewProperties");
4820	}
4821	if (khr_device_protected_memory &&
4822		(protectedMemoryPropertiesKHR[0].protectedNoFault	!= protectedMemoryPropertiesKHR[1].protectedNoFault))
4823	{
4824		TCU_FAIL("Mismatch between VkPhysicalDeviceProtectedMemoryProperties");
4825	}
4826	if (khr_device_subgroup &&
4827		(subgroupProperties[0].subgroupSize					!= subgroupProperties[1].subgroupSize ||
4828		 subgroupProperties[0].supportedStages				!= subgroupProperties[1].supportedStages ||
4829		 subgroupProperties[0].supportedOperations			!= subgroupProperties[1].supportedOperations ||
4830		 subgroupProperties[0].quadOperationsInAllStages	!= subgroupProperties[1].quadOperationsInAllStages ))
4831	{
4832		TCU_FAIL("Mismatch between VkPhysicalDeviceSubgroupProperties");
4833	}
4834	if (khr_maintenance2 &&
4835		(pointClippingProperties[0].pointClippingBehavior	!= pointClippingProperties[1].pointClippingBehavior))
4836	{
4837		TCU_FAIL("Mismatch between VkPhysicalDevicePointClippingProperties");
4838	}
4839	if (khr_maintenance3 &&
4840		(maintenance3Properties[0].maxPerSetDescriptors		!= maintenance3Properties[1].maxPerSetDescriptors ||
4841		 maintenance3Properties[0].maxMemoryAllocationSize	!= maintenance3Properties[1].maxMemoryAllocationSize))
4842	{
4843		if (protectedMemoryPropertiesKHR[0].protectedNoFault != protectedMemoryPropertiesKHR[1].protectedNoFault)
4844		{
4845			TCU_FAIL("Mismatch between VkPhysicalDeviceProtectedMemoryProperties");
4846		}
4847		if ((subgroupProperties[0].subgroupSize					!= subgroupProperties[1].subgroupSize) ||
4848			(subgroupProperties[0].supportedStages				!= subgroupProperties[1].supportedStages) ||
4849			(subgroupProperties[0].supportedOperations			!= subgroupProperties[1].supportedOperations) ||
4850			(subgroupProperties[0].quadOperationsInAllStages	!= subgroupProperties[1].quadOperationsInAllStages))
4851		{
4852			TCU_FAIL("Mismatch between VkPhysicalDeviceSubgroupProperties");
4853		}
4854		TCU_FAIL("Mismatch between VkPhysicalDeviceMaintenance3Properties");
4855	}
4856	if (khr_depth_stencil_resolve &&
4857		(depthStencilResolveProperties[0].supportedDepthResolveModes	!= depthStencilResolveProperties[1].supportedDepthResolveModes ||
4858		 depthStencilResolveProperties[0].supportedStencilResolveModes	!= depthStencilResolveProperties[1].supportedStencilResolveModes ||
4859		 depthStencilResolveProperties[0].independentResolveNone		!= depthStencilResolveProperties[1].independentResolveNone ||
4860		 depthStencilResolveProperties[0].independentResolve			!= depthStencilResolveProperties[1].independentResolve))
4861	{
4862		TCU_FAIL("Mismatch between VkPhysicalDeviceDepthStencilResolveProperties");
4863	}
4864	if (khr_driver_properties &&
4865		(driverProperties[0].driverID												!= driverProperties[1].driverID ||
4866		 strncmp(driverProperties[0].driverName, driverProperties[1].driverName, VK_MAX_DRIVER_NAME_SIZE)	!= 0 ||
4867		 strncmp(driverProperties[0].driverInfo, driverProperties[1].driverInfo, VK_MAX_DRIVER_INFO_SIZE)		!= 0 ||
4868		 driverProperties[0].conformanceVersion.major								!= driverProperties[1].conformanceVersion.major ||
4869		 driverProperties[0].conformanceVersion.minor								!= driverProperties[1].conformanceVersion.minor ||
4870		 driverProperties[0].conformanceVersion.subminor							!= driverProperties[1].conformanceVersion.subminor ||
4871		 driverProperties[0].conformanceVersion.patch								!= driverProperties[1].conformanceVersion.patch))
4872	{
4873		TCU_FAIL("Mismatch between VkPhysicalDeviceDriverProperties");
4874	}
4875	if (khr_shader_float_controls &&
4876		(floatControlsProperties[0].denormBehaviorIndependence				!= floatControlsProperties[1].denormBehaviorIndependence ||
4877		 floatControlsProperties[0].roundingModeIndependence				!= floatControlsProperties[1].roundingModeIndependence ||
4878		 floatControlsProperties[0].shaderSignedZeroInfNanPreserveFloat16	!= floatControlsProperties[1].shaderSignedZeroInfNanPreserveFloat16 ||
4879		 floatControlsProperties[0].shaderSignedZeroInfNanPreserveFloat32	!= floatControlsProperties[1].shaderSignedZeroInfNanPreserveFloat32 ||
4880		 floatControlsProperties[0].shaderSignedZeroInfNanPreserveFloat64	!= floatControlsProperties[1].shaderSignedZeroInfNanPreserveFloat64 ||
4881		 floatControlsProperties[0].shaderDenormPreserveFloat16				!= floatControlsProperties[1].shaderDenormPreserveFloat16 ||
4882		 floatControlsProperties[0].shaderDenormPreserveFloat32				!= floatControlsProperties[1].shaderDenormPreserveFloat32 ||
4883		 floatControlsProperties[0].shaderDenormPreserveFloat64				!= floatControlsProperties[1].shaderDenormPreserveFloat64 ||
4884		 floatControlsProperties[0].shaderDenormFlushToZeroFloat16			!= floatControlsProperties[1].shaderDenormFlushToZeroFloat16 ||
4885		 floatControlsProperties[0].shaderDenormFlushToZeroFloat32			!= floatControlsProperties[1].shaderDenormFlushToZeroFloat32 ||
4886		 floatControlsProperties[0].shaderDenormFlushToZeroFloat64			!= floatControlsProperties[1].shaderDenormFlushToZeroFloat64 ||
4887		 floatControlsProperties[0].shaderRoundingModeRTEFloat16			!= floatControlsProperties[1].shaderRoundingModeRTEFloat16 ||
4888		 floatControlsProperties[0].shaderRoundingModeRTEFloat32			!= floatControlsProperties[1].shaderRoundingModeRTEFloat32 ||
4889		 floatControlsProperties[0].shaderRoundingModeRTEFloat64			!= floatControlsProperties[1].shaderRoundingModeRTEFloat64 ||
4890		 floatControlsProperties[0].shaderRoundingModeRTZFloat16			!= floatControlsProperties[1].shaderRoundingModeRTZFloat16 ||
4891		 floatControlsProperties[0].shaderRoundingModeRTZFloat32			!= floatControlsProperties[1].shaderRoundingModeRTZFloat32 ||
4892		 floatControlsProperties[0].shaderRoundingModeRTZFloat64			!= floatControlsProperties[1].shaderRoundingModeRTZFloat64 ))
4893	{
4894		TCU_FAIL("Mismatch between VkPhysicalDeviceFloatControlsProperties");
4895	}
4896	if (khr_descriptor_indexing &&
4897		(descriptorIndexingProperties[0].maxUpdateAfterBindDescriptorsInAllPools				!= descriptorIndexingProperties[1].maxUpdateAfterBindDescriptorsInAllPools ||
4898		 descriptorIndexingProperties[0].shaderUniformBufferArrayNonUniformIndexingNative		!= descriptorIndexingProperties[1].shaderUniformBufferArrayNonUniformIndexingNative ||
4899		 descriptorIndexingProperties[0].shaderSampledImageArrayNonUniformIndexingNative		!= descriptorIndexingProperties[1].shaderSampledImageArrayNonUniformIndexingNative ||
4900		 descriptorIndexingProperties[0].shaderStorageBufferArrayNonUniformIndexingNative		!= descriptorIndexingProperties[1].shaderStorageBufferArrayNonUniformIndexingNative ||
4901		 descriptorIndexingProperties[0].shaderStorageImageArrayNonUniformIndexingNative		!= descriptorIndexingProperties[1].shaderStorageImageArrayNonUniformIndexingNative ||
4902		 descriptorIndexingProperties[0].shaderInputAttachmentArrayNonUniformIndexingNative		!= descriptorIndexingProperties[1].shaderInputAttachmentArrayNonUniformIndexingNative ||
4903		 descriptorIndexingProperties[0].robustBufferAccessUpdateAfterBind						!= descriptorIndexingProperties[1].robustBufferAccessUpdateAfterBind ||
4904		 descriptorIndexingProperties[0].quadDivergentImplicitLod								!= descriptorIndexingProperties[1].quadDivergentImplicitLod ||
4905		 descriptorIndexingProperties[0].maxPerStageDescriptorUpdateAfterBindSamplers			!= descriptorIndexingProperties[1].maxPerStageDescriptorUpdateAfterBindSamplers ||
4906		 descriptorIndexingProperties[0].maxPerStageDescriptorUpdateAfterBindUniformBuffers		!= descriptorIndexingProperties[1].maxPerStageDescriptorUpdateAfterBindUniformBuffers ||
4907		 descriptorIndexingProperties[0].maxPerStageDescriptorUpdateAfterBindStorageBuffers		!= descriptorIndexingProperties[1].maxPerStageDescriptorUpdateAfterBindStorageBuffers ||
4908		 descriptorIndexingProperties[0].maxPerStageDescriptorUpdateAfterBindSampledImages		!= descriptorIndexingProperties[1].maxPerStageDescriptorUpdateAfterBindSampledImages ||
4909		 descriptorIndexingProperties[0].maxPerStageDescriptorUpdateAfterBindStorageImages		!= descriptorIndexingProperties[1].maxPerStageDescriptorUpdateAfterBindStorageImages ||
4910		 descriptorIndexingProperties[0].maxPerStageDescriptorUpdateAfterBindInputAttachments	!= descriptorIndexingProperties[1].maxPerStageDescriptorUpdateAfterBindInputAttachments ||
4911		 descriptorIndexingProperties[0].maxPerStageUpdateAfterBindResources					!= descriptorIndexingProperties[1].maxPerStageUpdateAfterBindResources ||
4912		 descriptorIndexingProperties[0].maxDescriptorSetUpdateAfterBindSamplers				!= descriptorIndexingProperties[1].maxDescriptorSetUpdateAfterBindSamplers ||
4913		 descriptorIndexingProperties[0].maxDescriptorSetUpdateAfterBindUniformBuffers			!= descriptorIndexingProperties[1].maxDescriptorSetUpdateAfterBindUniformBuffers ||
4914		 descriptorIndexingProperties[0].maxDescriptorSetUpdateAfterBindUniformBuffersDynamic	!= descriptorIndexingProperties[1].maxDescriptorSetUpdateAfterBindUniformBuffersDynamic ||
4915		 descriptorIndexingProperties[0].maxDescriptorSetUpdateAfterBindStorageBuffers			!= descriptorIndexingProperties[1].maxDescriptorSetUpdateAfterBindStorageBuffers ||
4916		 descriptorIndexingProperties[0].maxDescriptorSetUpdateAfterBindStorageBuffersDynamic	!= descriptorIndexingProperties[1].maxDescriptorSetUpdateAfterBindStorageBuffersDynamic ||
4917		 descriptorIndexingProperties[0].maxDescriptorSetUpdateAfterBindSampledImages			!= descriptorIndexingProperties[1].maxDescriptorSetUpdateAfterBindSampledImages ||
4918		 descriptorIndexingProperties[0].maxDescriptorSetUpdateAfterBindStorageImages			!= descriptorIndexingProperties[1].maxDescriptorSetUpdateAfterBindStorageImages ||
4919		 descriptorIndexingProperties[0].maxDescriptorSetUpdateAfterBindInputAttachments		!= descriptorIndexingProperties[1].maxDescriptorSetUpdateAfterBindInputAttachments ))
4920	{
4921		TCU_FAIL("Mismatch between VkPhysicalDeviceDescriptorIndexingProperties");
4922	}
4923	if (khr_sampler_filter_minmax &&
4924		(samplerFilterMinmaxProperties[0].filterMinmaxSingleComponentFormats	!= samplerFilterMinmaxProperties[1].filterMinmaxSingleComponentFormats ||
4925		 samplerFilterMinmaxProperties[0].filterMinmaxImageComponentMapping		!= samplerFilterMinmaxProperties[1].filterMinmaxImageComponentMapping))
4926	{
4927		TCU_FAIL("Mismatch between VkPhysicalDeviceSamplerFilterMinmaxProperties");
4928	}
4929
4930#ifndef CTS_USES_VULKANSC
4931
4932	if (khr_integer_dot_product &&
4933		(integerDotProductProperties[0].integerDotProduct8BitUnsignedAccelerated										!= integerDotProductProperties[1].integerDotProduct8BitUnsignedAccelerated ||
4934		 integerDotProductProperties[0].integerDotProduct8BitSignedAccelerated											!= integerDotProductProperties[1].integerDotProduct8BitSignedAccelerated ||
4935		 integerDotProductProperties[0].integerDotProduct8BitMixedSignednessAccelerated									!= integerDotProductProperties[1].integerDotProduct8BitMixedSignednessAccelerated ||
4936		 integerDotProductProperties[0].integerDotProduct4x8BitPackedUnsignedAccelerated								!= integerDotProductProperties[1].integerDotProduct4x8BitPackedUnsignedAccelerated ||
4937		 integerDotProductProperties[0].integerDotProduct4x8BitPackedSignedAccelerated									!= integerDotProductProperties[1].integerDotProduct4x8BitPackedSignedAccelerated ||
4938		 integerDotProductProperties[0].integerDotProduct4x8BitPackedMixedSignednessAccelerated							!= integerDotProductProperties[1].integerDotProduct4x8BitPackedMixedSignednessAccelerated ||
4939		 integerDotProductProperties[0].integerDotProduct16BitUnsignedAccelerated										!= integerDotProductProperties[1].integerDotProduct16BitUnsignedAccelerated ||
4940		 integerDotProductProperties[0].integerDotProduct16BitSignedAccelerated											!= integerDotProductProperties[1].integerDotProduct16BitSignedAccelerated ||
4941		 integerDotProductProperties[0].integerDotProduct16BitMixedSignednessAccelerated								!= integerDotProductProperties[1].integerDotProduct16BitMixedSignednessAccelerated ||
4942		 integerDotProductProperties[0].integerDotProduct32BitUnsignedAccelerated										!= integerDotProductProperties[1].integerDotProduct32BitUnsignedAccelerated ||
4943		 integerDotProductProperties[0].integerDotProduct32BitSignedAccelerated											!= integerDotProductProperties[1].integerDotProduct32BitSignedAccelerated ||
4944		 integerDotProductProperties[0].integerDotProduct32BitMixedSignednessAccelerated								!= integerDotProductProperties[1].integerDotProduct32BitMixedSignednessAccelerated ||
4945		 integerDotProductProperties[0].integerDotProduct64BitUnsignedAccelerated										!= integerDotProductProperties[1].integerDotProduct64BitUnsignedAccelerated ||
4946		 integerDotProductProperties[0].integerDotProduct64BitSignedAccelerated											!= integerDotProductProperties[1].integerDotProduct64BitSignedAccelerated ||
4947		 integerDotProductProperties[0].integerDotProduct64BitMixedSignednessAccelerated								!= integerDotProductProperties[1].integerDotProduct64BitMixedSignednessAccelerated ||
4948		 integerDotProductProperties[0].integerDotProductAccumulatingSaturating8BitUnsignedAccelerated					!= integerDotProductProperties[1].integerDotProductAccumulatingSaturating8BitUnsignedAccelerated ||
4949		 integerDotProductProperties[0].integerDotProductAccumulatingSaturating8BitSignedAccelerated					!= integerDotProductProperties[1].integerDotProductAccumulatingSaturating8BitSignedAccelerated ||
4950		 integerDotProductProperties[0].integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated			!= integerDotProductProperties[1].integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated ||
4951		 integerDotProductProperties[0].integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated			!= integerDotProductProperties[1].integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated ||
4952		 integerDotProductProperties[0].integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated			!= integerDotProductProperties[1].integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated ||
4953		 integerDotProductProperties[0].integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated	!= integerDotProductProperties[1].integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated ||
4954		 integerDotProductProperties[0].integerDotProductAccumulatingSaturating16BitUnsignedAccelerated					!= integerDotProductProperties[1].integerDotProductAccumulatingSaturating16BitUnsignedAccelerated ||
4955		 integerDotProductProperties[0].integerDotProductAccumulatingSaturating16BitSignedAccelerated					!= integerDotProductProperties[1].integerDotProductAccumulatingSaturating16BitSignedAccelerated ||
4956		 integerDotProductProperties[0].integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated			!= integerDotProductProperties[1].integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated ||
4957		 integerDotProductProperties[0].integerDotProductAccumulatingSaturating32BitUnsignedAccelerated					!= integerDotProductProperties[1].integerDotProductAccumulatingSaturating32BitUnsignedAccelerated ||
4958		 integerDotProductProperties[0].integerDotProductAccumulatingSaturating32BitSignedAccelerated					!= integerDotProductProperties[1].integerDotProductAccumulatingSaturating32BitSignedAccelerated ||
4959		 integerDotProductProperties[0].integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated			!= integerDotProductProperties[1].integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated ||
4960		 integerDotProductProperties[0].integerDotProductAccumulatingSaturating64BitUnsignedAccelerated					!= integerDotProductProperties[1].integerDotProductAccumulatingSaturating64BitUnsignedAccelerated ||
4961		 integerDotProductProperties[0].integerDotProductAccumulatingSaturating64BitSignedAccelerated					!= integerDotProductProperties[1].integerDotProductAccumulatingSaturating64BitSignedAccelerated ||
4962		 integerDotProductProperties[0].integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated			!= integerDotProductProperties[1].integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated))
4963	{
4964		TCU_FAIL("Mismatch between VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR");
4965	}
4966
4967	if (khr_texel_buffer_alignment)
4968	{
4969		if (texelBufferAlignmentProperties[0].storageTexelBufferOffsetAlignmentBytes		!= texelBufferAlignmentProperties[1].storageTexelBufferOffsetAlignmentBytes ||
4970			texelBufferAlignmentProperties[0].storageTexelBufferOffsetSingleTexelAlignment	!= texelBufferAlignmentProperties[1].storageTexelBufferOffsetSingleTexelAlignment ||
4971			texelBufferAlignmentProperties[0].uniformTexelBufferOffsetAlignmentBytes		!= texelBufferAlignmentProperties[1].uniformTexelBufferOffsetAlignmentBytes ||
4972			texelBufferAlignmentProperties[0].uniformTexelBufferOffsetSingleTexelAlignment	!= texelBufferAlignmentProperties[1].uniformTexelBufferOffsetSingleTexelAlignment)
4973		{
4974			TCU_FAIL("Mismatch between VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT");
4975		}
4976
4977		if (texelBufferAlignmentProperties[0].storageTexelBufferOffsetAlignmentBytes == 0 || !deIntIsPow2((int)texelBufferAlignmentProperties[0].storageTexelBufferOffsetAlignmentBytes))
4978		{
4979			TCU_FAIL("limit Validation failed storageTexelBufferOffsetAlignmentBytes is not a power of two.");
4980		}
4981
4982		if (texelBufferAlignmentProperties[0].uniformTexelBufferOffsetAlignmentBytes == 0 || !deIntIsPow2((int)texelBufferAlignmentProperties[0].uniformTexelBufferOffsetAlignmentBytes))
4983		{
4984			TCU_FAIL("limit Validation failed uniformTexelBufferOffsetAlignmentBytes is not a power of two.");
4985		}
4986	}
4987
4988	if (khr_inline_uniform_block &&
4989		(inlineUniformBlockProperties[0].maxInlineUniformBlockSize									!= inlineUniformBlockProperties[1].maxInlineUniformBlockSize ||
4990		 inlineUniformBlockProperties[0].maxPerStageDescriptorInlineUniformBlocks					!= inlineUniformBlockProperties[1].maxPerStageDescriptorInlineUniformBlocks ||
4991		 inlineUniformBlockProperties[0].maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks	!= inlineUniformBlockProperties[1].maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks ||
4992		 inlineUniformBlockProperties[0].maxDescriptorSetInlineUniformBlocks						!= inlineUniformBlockProperties[1].maxDescriptorSetInlineUniformBlocks ||
4993		 inlineUniformBlockProperties[0].maxDescriptorSetUpdateAfterBindInlineUniformBlocks			!= inlineUniformBlockProperties[1].maxDescriptorSetUpdateAfterBindInlineUniformBlocks))
4994	{
4995		TCU_FAIL("Mismatch between VkPhysicalDeviceInlineUniformBlockProperties");
4996	}
4997	if (khr_maintenance4 &&
4998		(maintenance4Properties[0].maxBufferSize	!= maintenance4Properties[1].maxBufferSize))
4999	{
5000		TCU_FAIL("Mismatch between VkPhysicalDeviceMaintenance4Properties");
5001	}
5002	if (khr_subgroup_size_control &&
5003		(subgroupSizeControlProperties[0].minSubgroupSize				!= subgroupSizeControlProperties[1].minSubgroupSize ||
5004		 subgroupSizeControlProperties[0].maxSubgroupSize				!= subgroupSizeControlProperties[1].maxSubgroupSize ||
5005		 subgroupSizeControlProperties[0].maxComputeWorkgroupSubgroups	!= subgroupSizeControlProperties[1].maxComputeWorkgroupSubgroups ||
5006		 subgroupSizeControlProperties[0].requiredSubgroupSizeStages		!= subgroupSizeControlProperties[1].requiredSubgroupSizeStages))
5007	{
5008		TCU_FAIL("Mismatch between VkPhysicalDeviceSubgroupSizeControlProperties");
5009	}
5010
5011	if (khr_acceleration_structure)
5012	{
5013		if (accelerationStructureProperties[0].maxGeometryCount												!= accelerationStructureProperties[1].maxGeometryCount ||
5014			accelerationStructureProperties[0].maxInstanceCount												!= accelerationStructureProperties[1].maxInstanceCount ||
5015			accelerationStructureProperties[0].maxPrimitiveCount											!= accelerationStructureProperties[1].maxPrimitiveCount ||
5016			accelerationStructureProperties[0].maxPerStageDescriptorAccelerationStructures					!= accelerationStructureProperties[1].maxPerStageDescriptorAccelerationStructures ||
5017			accelerationStructureProperties[0].maxPerStageDescriptorUpdateAfterBindAccelerationStructures	!= accelerationStructureProperties[1].maxPerStageDescriptorUpdateAfterBindAccelerationStructures ||
5018			accelerationStructureProperties[0].maxDescriptorSetAccelerationStructures						!= accelerationStructureProperties[1].maxDescriptorSetAccelerationStructures ||
5019			accelerationStructureProperties[0].maxDescriptorSetUpdateAfterBindAccelerationStructures		!= accelerationStructureProperties[1].maxDescriptorSetUpdateAfterBindAccelerationStructures ||
5020			accelerationStructureProperties[0].minAccelerationStructureScratchOffsetAlignment				!= accelerationStructureProperties[1].minAccelerationStructureScratchOffsetAlignment)
5021		{
5022			TCU_FAIL("Mismatch between VkPhysicalDeviceAccelerationStructurePropertiesKHR");
5023		}
5024
5025		if (accelerationStructureProperties[0].minAccelerationStructureScratchOffsetAlignment == 0 || !deIntIsPow2(accelerationStructureProperties[0].minAccelerationStructureScratchOffsetAlignment))
5026		{
5027			TCU_FAIL("limit Validation failed minAccelerationStructureScratchOffsetAlignment is not a power of two.");
5028		}
5029	}
5030
5031	if (isExtensionStructSupported(properties, RequiredExtension("VK_KHR_push_descriptor")))
5032	{
5033		VkPhysicalDevicePushDescriptorPropertiesKHR		pushDescriptorProperties[count];
5034
5035		for (int ndx = 0; ndx < count; ++ndx)
5036		{
5037			deMemset(&pushDescriptorProperties[ndx], 0xFF * ndx, sizeof(VkPhysicalDevicePushDescriptorPropertiesKHR));
5038
5039			pushDescriptorProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR;
5040			pushDescriptorProperties[ndx].pNext	= DE_NULL;
5041
5042			extProperties.pNext = &pushDescriptorProperties[ndx];
5043
5044			vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
5045
5046			pushDescriptorProperties[ndx].pNext = DE_NULL;
5047		}
5048
5049		log << TestLog::Message << pushDescriptorProperties[0] << TestLog::EndMessage;
5050
5051		if ( pushDescriptorProperties[0].maxPushDescriptors != pushDescriptorProperties[1].maxPushDescriptors )
5052		{
5053			TCU_FAIL("Mismatch between VkPhysicalDevicePushDescriptorPropertiesKHR ");
5054		}
5055		if (pushDescriptorProperties[0].maxPushDescriptors < 32)
5056		{
5057			TCU_FAIL("VkPhysicalDevicePushDescriptorPropertiesKHR.maxPushDescriptors must be at least 32");
5058		}
5059	}
5060
5061	if (isExtensionStructSupported(properties, RequiredExtension("VK_KHR_performance_query")))
5062	{
5063		VkPhysicalDevicePerformanceQueryPropertiesKHR performanceQueryProperties[count];
5064
5065		for (int ndx = 0; ndx < count; ++ndx)
5066		{
5067			deMemset(&performanceQueryProperties[ndx], 0xFF * ndx, sizeof(VkPhysicalDevicePerformanceQueryPropertiesKHR));
5068			performanceQueryProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_PROPERTIES_KHR;
5069			performanceQueryProperties[ndx].pNext = DE_NULL;
5070
5071			extProperties.pNext = &performanceQueryProperties[ndx];
5072
5073			vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
5074		}
5075
5076		log << TestLog::Message << performanceQueryProperties[0] << TestLog::EndMessage;
5077
5078		if (performanceQueryProperties[0].allowCommandBufferQueryCopies != performanceQueryProperties[1].allowCommandBufferQueryCopies)
5079		{
5080			TCU_FAIL("Mismatch between VkPhysicalDevicePerformanceQueryPropertiesKHR");
5081		}
5082	}
5083
5084#endif // CTS_USES_VULKANSC
5085
5086	if (isExtensionStructSupported(properties, RequiredExtension("VK_EXT_pci_bus_info", 2, 2)))
5087	{
5088		VkPhysicalDevicePCIBusInfoPropertiesEXT pciBusInfoProperties[count];
5089
5090		for (int ndx = 0; ndx < count; ++ndx)
5091		{
5092			// Each PCI device is identified by an 8-bit domain number, 5-bit
5093			// device number and 3-bit function number[1][2].
5094			//
5095			// In addition, because PCI systems can be interconnected and
5096			// divided in segments, Linux assigns a 16-bit number to the device
5097			// as the "domain". In Windows, the segment or domain is stored in
5098			// the higher 24-bit section of the bus number.
5099			//
5100			// This means the maximum unsigned 32-bit integer for these members
5101			// are invalid values and should change after querying properties.
5102			//
5103			// [1] https://en.wikipedia.org/wiki/PCI_configuration_space
5104			// [2] PCI Express Base Specification Revision 3.0, section 2.2.4.2.
5105			deMemset(pciBusInfoProperties + ndx, 0xFF * ndx, sizeof(pciBusInfoProperties[ndx]));
5106			pciBusInfoProperties[ndx].pciDomain   = DEUINT32_MAX;
5107			pciBusInfoProperties[ndx].pciBus      = DEUINT32_MAX;
5108			pciBusInfoProperties[ndx].pciDevice   = DEUINT32_MAX;
5109			pciBusInfoProperties[ndx].pciFunction = DEUINT32_MAX;
5110
5111			pciBusInfoProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT;
5112			pciBusInfoProperties[ndx].pNext = DE_NULL;
5113
5114			extProperties.pNext = pciBusInfoProperties + ndx;
5115			vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
5116		}
5117
5118		log << TestLog::Message << toString(pciBusInfoProperties[0]) << TestLog::EndMessage;
5119
5120		if (pciBusInfoProperties[0].pciDomain	!= pciBusInfoProperties[1].pciDomain ||
5121			pciBusInfoProperties[0].pciBus		!= pciBusInfoProperties[1].pciBus ||
5122			pciBusInfoProperties[0].pciDevice	!= pciBusInfoProperties[1].pciDevice ||
5123			pciBusInfoProperties[0].pciFunction	!= pciBusInfoProperties[1].pciFunction)
5124		{
5125			TCU_FAIL("Mismatch between VkPhysicalDevicePCIBusInfoPropertiesEXT");
5126		}
5127		if (pciBusInfoProperties[0].pciDomain   == DEUINT32_MAX ||
5128		    pciBusInfoProperties[0].pciBus      == DEUINT32_MAX ||
5129		    pciBusInfoProperties[0].pciDevice   == DEUINT32_MAX ||
5130		    pciBusInfoProperties[0].pciFunction == DEUINT32_MAX)
5131		{
5132			TCU_FAIL("Invalid information in VkPhysicalDevicePCIBusInfoPropertiesEXT");
5133		}
5134	}
5135
5136#ifndef CTS_USES_VULKANSC
5137	if (isExtensionStructSupported(properties, RequiredExtension("VK_KHR_portability_subset")))
5138	{
5139		VkPhysicalDevicePortabilitySubsetPropertiesKHR portabilitySubsetProperties[count];
5140
5141		for (int ndx = 0; ndx < count; ++ndx)
5142		{
5143			deMemset(&portabilitySubsetProperties[ndx], 0xFF * ndx, sizeof(VkPhysicalDevicePortabilitySubsetPropertiesKHR));
5144			portabilitySubsetProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_KHR;
5145			portabilitySubsetProperties[ndx].pNext = DE_NULL;
5146
5147			extProperties.pNext = &portabilitySubsetProperties[ndx];
5148
5149			vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
5150		}
5151
5152		log << TestLog::Message << portabilitySubsetProperties[0] << TestLog::EndMessage;
5153
5154		if (portabilitySubsetProperties[0].minVertexInputBindingStrideAlignment != portabilitySubsetProperties[1].minVertexInputBindingStrideAlignment)
5155		{
5156			TCU_FAIL("Mismatch between VkPhysicalDevicePortabilitySubsetPropertiesKHR");
5157		}
5158
5159		if (portabilitySubsetProperties[0].minVertexInputBindingStrideAlignment == 0 || !deIntIsPow2(portabilitySubsetProperties[0].minVertexInputBindingStrideAlignment))
5160		{
5161			TCU_FAIL("limit Validation failed minVertexInputBindingStrideAlignment is not a power of two.");
5162		}
5163	}
5164#endif // CTS_USES_VULKANSC
5165
5166	return tcu::TestStatus::pass("Querying device properties succeeded");
5167}
5168
5169string toString (const VkFormatProperties2& value)
5170{
5171	std::ostringstream	s;
5172	s << "VkFormatProperties2 = {\n";
5173	s << "\tsType = " << value.sType << '\n';
5174	s << "\tformatProperties = {\n";
5175	s << "\tlinearTilingFeatures = " << getFormatFeatureFlagsStr(value.formatProperties.linearTilingFeatures) << '\n';
5176	s << "\toptimalTilingFeatures = " << getFormatFeatureFlagsStr(value.formatProperties.optimalTilingFeatures) << '\n';
5177	s << "\tbufferFeatures = " << getFormatFeatureFlagsStr(value.formatProperties.bufferFeatures) << '\n';
5178	s << "\t}";
5179	s << "}";
5180	return s.str();
5181}
5182
5183tcu::TestStatus deviceFormatProperties2 (Context& context)
5184{
5185	const CustomInstance			instance		(createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
5186	const InstanceDriver&			vki				(instance.getDriver());
5187	const VkPhysicalDevice			physicalDevice	(chooseDevice(vki, instance, context.getTestContext().getCommandLine()));
5188	TestLog&						log				= context.getTestContext().getLog();
5189
5190	for (int formatNdx = 0; formatNdx < VK_CORE_FORMAT_LAST; ++formatNdx)
5191	{
5192		const VkFormat			format			= (VkFormat)formatNdx;
5193		VkFormatProperties		coreProperties;
5194		VkFormatProperties2		extProperties;
5195
5196		deMemset(&coreProperties, 0xcd, sizeof(VkFormatProperties));
5197		deMemset(&extProperties, 0xcd, sizeof(VkFormatProperties2));
5198
5199		extProperties.sType	= VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
5200		extProperties.pNext = DE_NULL;
5201
5202		vki.getPhysicalDeviceFormatProperties(physicalDevice, format, &coreProperties);
5203		vki.getPhysicalDeviceFormatProperties2(physicalDevice, format, &extProperties);
5204
5205		TCU_CHECK(extProperties.sType == VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2);
5206		TCU_CHECK(extProperties.pNext == DE_NULL);
5207
5208		if (deMemCmp(&coreProperties, &extProperties.formatProperties, sizeof(VkFormatProperties)) != 0)
5209			TCU_FAIL("Mismatch between format properties reported by vkGetPhysicalDeviceFormatProperties and vkGetPhysicalDeviceFormatProperties2");
5210
5211		log << TestLog::Message << toString (extProperties) << TestLog::EndMessage;
5212	}
5213
5214	return tcu::TestStatus::pass("Querying device format properties succeeded");
5215}
5216
5217tcu::TestStatus deviceQueueFamilyProperties2 (Context& context)
5218{
5219	const CustomInstance			instance				(createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
5220	const InstanceDriver&			vki						(instance.getDriver());
5221	const VkPhysicalDevice			physicalDevice	(chooseDevice(vki, instance, context.getTestContext().getCommandLine()));
5222	TestLog&						log						= context.getTestContext().getLog();
5223	deUint32						numCoreQueueFamilies	= ~0u;
5224	deUint32						numExtQueueFamilies		= ~0u;
5225
5226	vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numCoreQueueFamilies, DE_NULL);
5227	vki.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &numExtQueueFamilies, DE_NULL);
5228
5229	TCU_CHECK_MSG(numCoreQueueFamilies == numExtQueueFamilies, "Different number of queue family properties reported");
5230	TCU_CHECK(numCoreQueueFamilies > 0);
5231
5232	{
5233		std::vector<VkQueueFamilyProperties>		coreProperties	(numCoreQueueFamilies);
5234		std::vector<VkQueueFamilyProperties2>		extProperties	(numExtQueueFamilies);
5235
5236		deMemset(&coreProperties[0], 0xcd, sizeof(VkQueueFamilyProperties)*numCoreQueueFamilies);
5237		deMemset(&extProperties[0], 0xcd, sizeof(VkQueueFamilyProperties2)*numExtQueueFamilies);
5238
5239		for (size_t ndx = 0; ndx < extProperties.size(); ++ndx)
5240		{
5241			extProperties[ndx].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
5242			extProperties[ndx].pNext = DE_NULL;
5243		}
5244
5245		vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numCoreQueueFamilies, &coreProperties[0]);
5246		vki.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &numExtQueueFamilies, &extProperties[0]);
5247
5248		TCU_CHECK((size_t)numCoreQueueFamilies == coreProperties.size());
5249		TCU_CHECK((size_t)numExtQueueFamilies == extProperties.size());
5250		DE_ASSERT(numCoreQueueFamilies == numExtQueueFamilies);
5251
5252		for (size_t ndx = 0; ndx < extProperties.size(); ++ndx)
5253		{
5254			TCU_CHECK(extProperties[ndx].sType == VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2);
5255			TCU_CHECK(extProperties[ndx].pNext == DE_NULL);
5256
5257			if (deMemCmp(&coreProperties[ndx], &extProperties[ndx].queueFamilyProperties, sizeof(VkQueueFamilyProperties)) != 0)
5258				TCU_FAIL("Mismatch between format properties reported by vkGetPhysicalDeviceQueueFamilyProperties and vkGetPhysicalDeviceQueueFamilyProperties2");
5259
5260			log << TestLog::Message << " queueFamilyNdx = " << ndx <<TestLog::EndMessage
5261			<< TestLog::Message << extProperties[ndx] << TestLog::EndMessage;
5262		}
5263	}
5264
5265	return tcu::TestStatus::pass("Querying device queue family properties succeeded");
5266}
5267
5268tcu::TestStatus deviceMemoryProperties2 (Context& context)
5269{
5270	const CustomInstance				instance		(createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
5271	const InstanceDriver&				vki				(instance.getDriver());
5272	const VkPhysicalDevice				physicalDevice	(chooseDevice(vki, instance, context.getTestContext().getCommandLine()));
5273	TestLog&							log				= context.getTestContext().getLog();
5274	VkPhysicalDeviceMemoryProperties	coreProperties;
5275	VkPhysicalDeviceMemoryProperties2	extProperties;
5276
5277	deMemset(&coreProperties, 0xcd, sizeof(VkPhysicalDeviceMemoryProperties));
5278	deMemset(&extProperties, 0xcd, sizeof(VkPhysicalDeviceMemoryProperties2));
5279
5280	extProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
5281	extProperties.pNext = DE_NULL;
5282
5283	vki.getPhysicalDeviceMemoryProperties(physicalDevice, &coreProperties);
5284	vki.getPhysicalDeviceMemoryProperties2(physicalDevice, &extProperties);
5285
5286	TCU_CHECK(extProperties.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2);
5287	TCU_CHECK(extProperties.pNext == DE_NULL);
5288
5289	if (coreProperties.memoryTypeCount != extProperties.memoryProperties.memoryTypeCount)
5290		TCU_FAIL("Mismatch between memoryTypeCount reported by vkGetPhysicalDeviceMemoryProperties and vkGetPhysicalDeviceMemoryProperties2");
5291	if (coreProperties.memoryHeapCount != extProperties.memoryProperties.memoryHeapCount)
5292		TCU_FAIL("Mismatch between memoryHeapCount reported by vkGetPhysicalDeviceMemoryProperties and vkGetPhysicalDeviceMemoryProperties2");
5293	for (deUint32 i = 0; i < coreProperties.memoryTypeCount; i++) {
5294		const VkMemoryType *coreType = &coreProperties.memoryTypes[i];
5295		const VkMemoryType *extType = &extProperties.memoryProperties.memoryTypes[i];
5296		if (coreType->propertyFlags != extType->propertyFlags || coreType->heapIndex != extType->heapIndex)
5297			TCU_FAIL("Mismatch between memoryTypes reported by vkGetPhysicalDeviceMemoryProperties and vkGetPhysicalDeviceMemoryProperties2");
5298	}
5299	for (deUint32 i = 0; i < coreProperties.memoryHeapCount; i++) {
5300		const VkMemoryHeap *coreHeap = &coreProperties.memoryHeaps[i];
5301		const VkMemoryHeap *extHeap = &extProperties.memoryProperties.memoryHeaps[i];
5302		if (coreHeap->size != extHeap->size || coreHeap->flags != extHeap->flags)
5303			TCU_FAIL("Mismatch between memoryHeaps reported by vkGetPhysicalDeviceMemoryProperties and vkGetPhysicalDeviceMemoryProperties2");
5304	}
5305
5306	log << TestLog::Message << extProperties << TestLog::EndMessage;
5307
5308	return tcu::TestStatus::pass("Querying device memory properties succeeded");
5309}
5310
5311tcu::TestStatus deviceFeaturesVulkan12 (Context& context)
5312{
5313	using namespace ValidateQueryBits;
5314
5315	const QueryMemberTableEntry			feature11OffsetTable[] =
5316	{
5317		// VkPhysicalDevice16BitStorageFeatures
5318		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Features, storageBuffer16BitAccess),
5319		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Features, uniformAndStorageBuffer16BitAccess),
5320		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Features, storagePushConstant16),
5321		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Features, storageInputOutput16),
5322
5323		// VkPhysicalDeviceMultiviewFeatures
5324		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Features, multiview),
5325		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Features, multiviewGeometryShader),
5326		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Features, multiviewTessellationShader),
5327
5328		// VkPhysicalDeviceVariablePointersFeatures
5329		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Features, variablePointersStorageBuffer),
5330		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Features, variablePointers),
5331
5332		// VkPhysicalDeviceProtectedMemoryFeatures
5333		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Features, protectedMemory),
5334
5335		// VkPhysicalDeviceSamplerYcbcrConversionFeatures
5336		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Features, samplerYcbcrConversion),
5337
5338		// VkPhysicalDeviceShaderDrawParametersFeatures
5339		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Features, shaderDrawParameters),
5340		{ 0, 0 }
5341	};
5342	const QueryMemberTableEntry			feature12OffsetTable[] =
5343	{
5344		// None
5345		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, samplerMirrorClampToEdge),
5346		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, drawIndirectCount),
5347
5348		// VkPhysicalDevice8BitStorageFeatures
5349		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, storageBuffer8BitAccess),
5350		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, uniformAndStorageBuffer8BitAccess),
5351		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, storagePushConstant8),
5352
5353		// VkPhysicalDeviceShaderAtomicInt64Features
5354		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderBufferInt64Atomics),
5355		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderSharedInt64Atomics),
5356
5357		// VkPhysicalDeviceShaderFloat16Int8Features
5358		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderFloat16),
5359		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderInt8),
5360
5361		// VkPhysicalDeviceDescriptorIndexingFeatures
5362		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, descriptorIndexing),
5363		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderInputAttachmentArrayDynamicIndexing),
5364		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderUniformTexelBufferArrayDynamicIndexing),
5365		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderStorageTexelBufferArrayDynamicIndexing),
5366		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderUniformBufferArrayNonUniformIndexing),
5367		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderSampledImageArrayNonUniformIndexing),
5368		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderStorageBufferArrayNonUniformIndexing),
5369		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderStorageImageArrayNonUniformIndexing),
5370		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderInputAttachmentArrayNonUniformIndexing),
5371		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderUniformTexelBufferArrayNonUniformIndexing),
5372		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderStorageTexelBufferArrayNonUniformIndexing),
5373		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, descriptorBindingUniformBufferUpdateAfterBind),
5374		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, descriptorBindingSampledImageUpdateAfterBind),
5375		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, descriptorBindingStorageImageUpdateAfterBind),
5376		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, descriptorBindingStorageBufferUpdateAfterBind),
5377		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, descriptorBindingUniformTexelBufferUpdateAfterBind),
5378		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, descriptorBindingStorageTexelBufferUpdateAfterBind),
5379		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, descriptorBindingUpdateUnusedWhilePending),
5380		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, descriptorBindingPartiallyBound),
5381		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, descriptorBindingVariableDescriptorCount),
5382		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, runtimeDescriptorArray),
5383
5384		// None
5385		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, samplerFilterMinmax),
5386
5387		// VkPhysicalDeviceScalarBlockLayoutFeatures
5388		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, scalarBlockLayout),
5389
5390		// VkPhysicalDeviceImagelessFramebufferFeatures
5391		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, imagelessFramebuffer),
5392
5393		// VkPhysicalDeviceUniformBufferStandardLayoutFeatures
5394		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, uniformBufferStandardLayout),
5395
5396		// VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures
5397		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderSubgroupExtendedTypes),
5398
5399		// VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures
5400		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, separateDepthStencilLayouts),
5401
5402		// VkPhysicalDeviceHostQueryResetFeatures
5403		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, hostQueryReset),
5404
5405		// VkPhysicalDeviceTimelineSemaphoreFeatures
5406		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, timelineSemaphore),
5407
5408		// VkPhysicalDeviceBufferDeviceAddressFeatures
5409		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, bufferDeviceAddress),
5410		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, bufferDeviceAddressCaptureReplay),
5411		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, bufferDeviceAddressMultiDevice),
5412
5413		// VkPhysicalDeviceVulkanMemoryModelFeatures
5414		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, vulkanMemoryModel),
5415		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, vulkanMemoryModelDeviceScope),
5416		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, vulkanMemoryModelAvailabilityVisibilityChains),
5417
5418		// None
5419		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderOutputViewportIndex),
5420		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, shaderOutputLayer),
5421		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Features, subgroupBroadcastDynamicId),
5422		{ 0, 0 }
5423	};
5424	TestLog&											log										= context.getTestContext().getLog();
5425	const CustomInstance								instance								(createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
5426	const InstanceDriver&								vki										= instance.getDriver();
5427	const VkPhysicalDevice								physicalDevice							(chooseDevice(vki, instance, context.getTestContext().getCommandLine()));
5428	const deUint32										vulkan11FeaturesBufferSize				= sizeof(VkPhysicalDeviceVulkan11Features) + GUARD_SIZE;
5429	const deUint32										vulkan12FeaturesBufferSize				= sizeof(VkPhysicalDeviceVulkan12Features) + GUARD_SIZE;
5430	VkPhysicalDeviceFeatures2							extFeatures;
5431	deUint8												buffer11a[vulkan11FeaturesBufferSize];
5432	deUint8												buffer11b[vulkan11FeaturesBufferSize];
5433	deUint8												buffer12a[vulkan12FeaturesBufferSize];
5434	deUint8												buffer12b[vulkan12FeaturesBufferSize];
5435	const int											count									= 2u;
5436	VkPhysicalDeviceVulkan11Features*					vulkan11Features[count]					= { (VkPhysicalDeviceVulkan11Features*)(buffer11a), (VkPhysicalDeviceVulkan11Features*)(buffer11b)};
5437	VkPhysicalDeviceVulkan12Features*					vulkan12Features[count]					= { (VkPhysicalDeviceVulkan12Features*)(buffer12a), (VkPhysicalDeviceVulkan12Features*)(buffer12b)};
5438
5439	if (!context.contextSupports(vk::ApiVersion(0, 1, 2, 0)))
5440		TCU_THROW(NotSupportedError, "At least Vulkan 1.2 required to run test");
5441
5442	deMemset(buffer11b, GUARD_VALUE, sizeof(buffer11b));
5443	deMemset(buffer12a, GUARD_VALUE, sizeof(buffer12a));
5444	deMemset(buffer12b, GUARD_VALUE, sizeof(buffer12b));
5445	deMemset(buffer11a, GUARD_VALUE, sizeof(buffer11a));
5446
5447	// Validate all fields initialized
5448	for (int ndx = 0; ndx < count; ++ndx)
5449	{
5450		deMemset(&extFeatures.features, 0x00, sizeof(extFeatures.features));
5451		extFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
5452		extFeatures.pNext = vulkan11Features[ndx];
5453
5454		deMemset(vulkan11Features[ndx], 0xFF * ndx, sizeof(VkPhysicalDeviceVulkan11Features));
5455		vulkan11Features[ndx]->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
5456		vulkan11Features[ndx]->pNext = vulkan12Features[ndx];
5457
5458		deMemset(vulkan12Features[ndx], 0xFF * ndx, sizeof(VkPhysicalDeviceVulkan12Features));
5459		vulkan12Features[ndx]->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
5460		vulkan12Features[ndx]->pNext = DE_NULL;
5461
5462		vki.getPhysicalDeviceFeatures2(physicalDevice, &extFeatures);
5463	}
5464
5465	log << TestLog::Message << *vulkan11Features[0] << TestLog::EndMessage;
5466	log << TestLog::Message << *vulkan12Features[0] << TestLog::EndMessage;
5467
5468	if (!validateStructsWithGuard(feature11OffsetTable, vulkan11Features, GUARD_VALUE, GUARD_SIZE))
5469	{
5470		log << TestLog::Message << "deviceFeatures - VkPhysicalDeviceVulkan11Features initialization failure" << TestLog::EndMessage;
5471
5472		return tcu::TestStatus::fail("VkPhysicalDeviceVulkan11Features initialization failure");
5473	}
5474
5475	if (!validateStructsWithGuard(feature12OffsetTable, vulkan12Features, GUARD_VALUE, GUARD_SIZE))
5476	{
5477		log << TestLog::Message << "deviceFeatures - VkPhysicalDeviceVulkan12Features initialization failure" << TestLog::EndMessage;
5478
5479		return tcu::TestStatus::fail("VkPhysicalDeviceVulkan12Features initialization failure");
5480	}
5481
5482	return tcu::TestStatus::pass("Querying Vulkan 1.2 device features succeeded");
5483}
5484
5485#ifndef CTS_USES_VULKANSC
5486tcu::TestStatus deviceFeaturesVulkan13 (Context& context)
5487{
5488	using namespace ValidateQueryBits;
5489
5490	const QueryMemberTableEntry			feature13OffsetTable[] =
5491	{
5492		// VkPhysicalDeviceImageRobustnessFeatures
5493		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Features, robustImageAccess),
5494
5495		// VkPhysicalDeviceInlineUniformBlockFeatures
5496		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Features, inlineUniformBlock),
5497		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Features, descriptorBindingInlineUniformBlockUpdateAfterBind),
5498
5499		// VkPhysicalDevicePipelineCreationCacheControlFeatures
5500		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Features, pipelineCreationCacheControl),
5501
5502		// VkPhysicalDevicePrivateDataFeatures
5503		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Features, privateData),
5504
5505		// VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures
5506		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Features, shaderDemoteToHelperInvocation),
5507
5508		// VkPhysicalDeviceShaderTerminateInvocationFeatures
5509		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Features, shaderTerminateInvocation),
5510
5511		// VkPhysicalDeviceSubgroupSizeControlFeatures
5512		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Features, subgroupSizeControl),
5513		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Features, computeFullSubgroups),
5514
5515		// VkPhysicalDeviceSynchronization2Features
5516		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Features, synchronization2),
5517
5518		// VkPhysicalDeviceTextureCompressionASTCHDRFeatures
5519		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Features, textureCompressionASTC_HDR),
5520
5521		// VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures
5522		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Features, shaderZeroInitializeWorkgroupMemory),
5523
5524		// VkPhysicalDeviceDynamicRenderingFeatures
5525		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Features, dynamicRendering),
5526
5527		// VkPhysicalDeviceShaderIntegerDotProductFeatures
5528		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Features, shaderIntegerDotProduct),
5529
5530		// VkPhysicalDeviceMaintenance4Features
5531		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Features, maintenance4),
5532		{ 0, 0 }
5533	};
5534	TestLog&											log										= context.getTestContext().getLog();
5535	const VkPhysicalDevice								physicalDevice							= context.getPhysicalDevice();
5536	const CustomInstance								instance								(createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
5537	const InstanceDriver&								vki										= instance.getDriver();
5538	const deUint32										vulkan13FeaturesBufferSize				= sizeof(VkPhysicalDeviceVulkan13Features) + GUARD_SIZE;
5539	VkPhysicalDeviceFeatures2							extFeatures;
5540	deUint8												buffer13a[vulkan13FeaturesBufferSize];
5541	deUint8												buffer13b[vulkan13FeaturesBufferSize];
5542	const int											count									= 2u;
5543	VkPhysicalDeviceVulkan13Features*					vulkan13Features[count]					= { (VkPhysicalDeviceVulkan13Features*)(buffer13a), (VkPhysicalDeviceVulkan13Features*)(buffer13b)};
5544
5545	if (!context.contextSupports(vk::ApiVersion(0, 1, 3, 0)))
5546		TCU_THROW(NotSupportedError, "At least Vulkan 1.3 required to run test");
5547
5548	deMemset(buffer13a, GUARD_VALUE, sizeof(buffer13a));
5549	deMemset(buffer13b, GUARD_VALUE, sizeof(buffer13b));
5550
5551	// Validate all fields initialized
5552	for (int ndx = 0; ndx < count; ++ndx)
5553	{
5554		deMemset(&extFeatures.features, 0x00, sizeof(extFeatures.features));
5555		extFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
5556		extFeatures.pNext = vulkan13Features[ndx];
5557
5558		deMemset(vulkan13Features[ndx], 0xFF * ndx, sizeof(VkPhysicalDeviceVulkan13Features));
5559		vulkan13Features[ndx]->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES;
5560		vulkan13Features[ndx]->pNext = DE_NULL;
5561
5562		vki.getPhysicalDeviceFeatures2(physicalDevice, &extFeatures);
5563	}
5564
5565	log << TestLog::Message << *vulkan13Features[0] << TestLog::EndMessage;
5566
5567	if (!validateStructsWithGuard(feature13OffsetTable, vulkan13Features, GUARD_VALUE, GUARD_SIZE))
5568	{
5569		log << TestLog::Message << "deviceFeatures - VkPhysicalDeviceVulkan13Features initialization failure" << TestLog::EndMessage;
5570
5571		return tcu::TestStatus::fail("VkPhysicalDeviceVulkan13Features initialization failure");
5572	}
5573
5574	return tcu::TestStatus::pass("Querying Vulkan 1.3 device features succeeded");
5575}
5576#endif // CTS_USES_VULKANSC
5577
5578tcu::TestStatus devicePropertiesVulkan12 (Context& context)
5579{
5580	using namespace ValidateQueryBits;
5581
5582	const QueryMemberTableEntry			properties11OffsetTable[] =
5583	{
5584		// VkPhysicalDeviceIDProperties
5585		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, deviceUUID),
5586		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, driverUUID),
5587		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, deviceLUID),
5588		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, deviceNodeMask),
5589		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, deviceLUIDValid),
5590
5591		// VkPhysicalDeviceSubgroupProperties
5592		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, subgroupSize),
5593		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, subgroupSupportedStages),
5594		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, subgroupSupportedOperations),
5595		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, subgroupQuadOperationsInAllStages),
5596
5597		// VkPhysicalDevicePointClippingProperties
5598		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, pointClippingBehavior),
5599
5600		// VkPhysicalDeviceMultiviewProperties
5601		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, maxMultiviewViewCount),
5602		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, maxMultiviewInstanceIndex),
5603
5604		// VkPhysicalDeviceProtectedMemoryProperties
5605		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, protectedNoFault),
5606
5607		// VkPhysicalDeviceMaintenance3Properties
5608		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, maxPerSetDescriptors),
5609		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan11Properties, maxMemoryAllocationSize),
5610		{ 0, 0 }
5611	};
5612	const QueryMemberTableEntry			properties12OffsetTable[] =
5613	{
5614		// VkPhysicalDeviceDriverProperties
5615		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, driverID),
5616		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, conformanceVersion),
5617
5618		// VkPhysicalDeviceFloatControlsProperties
5619		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, denormBehaviorIndependence),
5620		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, roundingModeIndependence),
5621		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderSignedZeroInfNanPreserveFloat16),
5622		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderSignedZeroInfNanPreserveFloat32),
5623		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderSignedZeroInfNanPreserveFloat64),
5624		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderDenormPreserveFloat16),
5625		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderDenormPreserveFloat32),
5626		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderDenormPreserveFloat64),
5627		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderDenormFlushToZeroFloat16),
5628		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderDenormFlushToZeroFloat32),
5629		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderDenormFlushToZeroFloat64),
5630		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderRoundingModeRTEFloat16),
5631		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderRoundingModeRTEFloat32),
5632		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderRoundingModeRTEFloat64),
5633		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderRoundingModeRTZFloat16),
5634		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderRoundingModeRTZFloat32),
5635		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderRoundingModeRTZFloat64),
5636
5637		// VkPhysicalDeviceDescriptorIndexingProperties
5638		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxUpdateAfterBindDescriptorsInAllPools),
5639		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderUniformBufferArrayNonUniformIndexingNative),
5640		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderSampledImageArrayNonUniformIndexingNative),
5641		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderStorageBufferArrayNonUniformIndexingNative),
5642		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderStorageImageArrayNonUniformIndexingNative),
5643		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, shaderInputAttachmentArrayNonUniformIndexingNative),
5644		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, robustBufferAccessUpdateAfterBind),
5645		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, quadDivergentImplicitLod),
5646		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxPerStageDescriptorUpdateAfterBindSamplers),
5647		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxPerStageDescriptorUpdateAfterBindUniformBuffers),
5648		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxPerStageDescriptorUpdateAfterBindStorageBuffers),
5649		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxPerStageDescriptorUpdateAfterBindSampledImages),
5650		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxPerStageDescriptorUpdateAfterBindStorageImages),
5651		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxPerStageDescriptorUpdateAfterBindInputAttachments),
5652		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxPerStageUpdateAfterBindResources),
5653		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxDescriptorSetUpdateAfterBindSamplers),
5654		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxDescriptorSetUpdateAfterBindUniformBuffers),
5655		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxDescriptorSetUpdateAfterBindUniformBuffersDynamic),
5656		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxDescriptorSetUpdateAfterBindStorageBuffers),
5657		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxDescriptorSetUpdateAfterBindStorageBuffersDynamic),
5658		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxDescriptorSetUpdateAfterBindSampledImages),
5659		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxDescriptorSetUpdateAfterBindStorageImages),
5660		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxDescriptorSetUpdateAfterBindInputAttachments),
5661
5662		// VkPhysicalDeviceDepthStencilResolveProperties
5663		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, supportedDepthResolveModes),
5664		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, supportedStencilResolveModes),
5665		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, independentResolveNone),
5666		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, independentResolve),
5667
5668		// VkPhysicalDeviceSamplerFilterMinmaxProperties
5669		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, filterMinmaxSingleComponentFormats),
5670		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, filterMinmaxImageComponentMapping),
5671
5672		// VkPhysicalDeviceTimelineSemaphoreProperties
5673		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, maxTimelineSemaphoreValueDifference),
5674
5675		// None
5676		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan12Properties, framebufferIntegerColorSampleCounts),
5677		{ 0, 0 }
5678	};
5679	TestLog&										log											= context.getTestContext().getLog();
5680	const CustomInstance							instance									(createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
5681	const InstanceDriver&							vki											= instance.getDriver();
5682	const VkPhysicalDevice							physicalDevice								(chooseDevice(vki, instance, context.getTestContext().getCommandLine()));
5683	const deUint32									vulkan11PropertiesBufferSize				= sizeof(VkPhysicalDeviceVulkan11Properties) + GUARD_SIZE;
5684	const deUint32									vulkan12PropertiesBufferSize				= sizeof(VkPhysicalDeviceVulkan12Properties) + GUARD_SIZE;
5685	VkPhysicalDeviceProperties2						extProperties;
5686	deUint8											buffer11a[vulkan11PropertiesBufferSize];
5687	deUint8											buffer11b[vulkan11PropertiesBufferSize];
5688	deUint8											buffer12a[vulkan12PropertiesBufferSize];
5689	deUint8											buffer12b[vulkan12PropertiesBufferSize];
5690	const int										count										= 2u;
5691	VkPhysicalDeviceVulkan11Properties*				vulkan11Properties[count]					= { (VkPhysicalDeviceVulkan11Properties*)(buffer11a), (VkPhysicalDeviceVulkan11Properties*)(buffer11b)};
5692	VkPhysicalDeviceVulkan12Properties*				vulkan12Properties[count]					= { (VkPhysicalDeviceVulkan12Properties*)(buffer12a), (VkPhysicalDeviceVulkan12Properties*)(buffer12b)};
5693
5694	if (!context.contextSupports(vk::ApiVersion(0, 1, 2, 0)))
5695		TCU_THROW(NotSupportedError, "At least Vulkan 1.2 required to run test");
5696
5697	deMemset(buffer11a, GUARD_VALUE, sizeof(buffer11a));
5698	deMemset(buffer11b, GUARD_VALUE, sizeof(buffer11b));
5699	deMemset(buffer12a, GUARD_VALUE, sizeof(buffer12a));
5700	deMemset(buffer12b, GUARD_VALUE, sizeof(buffer12b));
5701
5702	for (int ndx = 0; ndx < count; ++ndx)
5703	{
5704		deMemset(&extProperties.properties, 0x00, sizeof(extProperties.properties));
5705		extProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
5706		extProperties.pNext = vulkan11Properties[ndx];
5707
5708		deMemset(vulkan11Properties[ndx], 0xFF * ndx, sizeof(VkPhysicalDeviceVulkan11Properties));
5709		vulkan11Properties[ndx]->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES;
5710		vulkan11Properties[ndx]->pNext = vulkan12Properties[ndx];
5711
5712		deMemset(vulkan12Properties[ndx], 0xFF * ndx, sizeof(VkPhysicalDeviceVulkan12Properties));
5713		vulkan12Properties[ndx]->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES;
5714		vulkan12Properties[ndx]->pNext = DE_NULL;
5715
5716		vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
5717	}
5718
5719	log << TestLog::Message << *vulkan11Properties[0] << TestLog::EndMessage;
5720	log << TestLog::Message << *vulkan12Properties[0] << TestLog::EndMessage;
5721
5722	if (!validateStructsWithGuard(properties11OffsetTable, vulkan11Properties, GUARD_VALUE, GUARD_SIZE))
5723	{
5724		log << TestLog::Message << "deviceProperties - VkPhysicalDeviceVulkan11Properties initialization failure" << TestLog::EndMessage;
5725
5726		return tcu::TestStatus::fail("VkPhysicalDeviceVulkan11Properties initialization failure");
5727	}
5728
5729	if (!validateStructsWithGuard(properties12OffsetTable, vulkan12Properties, GUARD_VALUE, GUARD_SIZE) ||
5730		strncmp(vulkan12Properties[0]->driverName, vulkan12Properties[1]->driverName, VK_MAX_DRIVER_NAME_SIZE) != 0 ||
5731		strncmp(vulkan12Properties[0]->driverInfo, vulkan12Properties[1]->driverInfo, VK_MAX_DRIVER_INFO_SIZE) != 0 )
5732	{
5733		log << TestLog::Message << "deviceProperties - VkPhysicalDeviceVulkan12Properties initialization failure" << TestLog::EndMessage;
5734
5735		return tcu::TestStatus::fail("VkPhysicalDeviceVulkan12Properties initialization failure");
5736	}
5737
5738	return tcu::TestStatus::pass("Querying Vulkan 1.2 device properties succeeded");
5739}
5740
5741#ifndef CTS_USES_VULKANSC
5742tcu::TestStatus devicePropertiesVulkan13 (Context& context)
5743{
5744	using namespace ValidateQueryBits;
5745
5746	const QueryMemberTableEntry			properties13OffsetTable[] =
5747	{
5748		// VkPhysicalDeviceSubgroupSizeControlProperties
5749		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, minSubgroupSize),
5750		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, maxSubgroupSize),
5751		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, maxComputeWorkgroupSubgroups),
5752		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, requiredSubgroupSizeStages),
5753
5754		// VkPhysicalDeviceInlineUniformBlockProperties
5755		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, maxInlineUniformBlockSize),
5756		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, maxPerStageDescriptorInlineUniformBlocks),
5757		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks),
5758		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, maxDescriptorSetInlineUniformBlocks),
5759		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, maxDescriptorSetUpdateAfterBindInlineUniformBlocks),
5760
5761		// None
5762		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, maxInlineUniformTotalSize),
5763
5764		// VkPhysicalDeviceShaderIntegerDotProductProperties
5765		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProduct8BitUnsignedAccelerated),
5766		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProduct8BitSignedAccelerated),
5767		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProduct8BitMixedSignednessAccelerated),
5768		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProduct4x8BitPackedUnsignedAccelerated),
5769		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProduct4x8BitPackedSignedAccelerated),
5770		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProduct4x8BitPackedMixedSignednessAccelerated),
5771		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProduct16BitUnsignedAccelerated),
5772		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProduct16BitSignedAccelerated),
5773		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProduct16BitMixedSignednessAccelerated),
5774		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProduct32BitUnsignedAccelerated),
5775		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProduct32BitSignedAccelerated),
5776		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProduct32BitMixedSignednessAccelerated),
5777		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProduct64BitUnsignedAccelerated),
5778		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProduct64BitSignedAccelerated),
5779		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProduct64BitMixedSignednessAccelerated),
5780		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProductAccumulatingSaturating8BitUnsignedAccelerated),
5781		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProductAccumulatingSaturating8BitSignedAccelerated),
5782		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated),
5783		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated),
5784		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated),
5785		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated),
5786		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProductAccumulatingSaturating16BitUnsignedAccelerated),
5787		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProductAccumulatingSaturating16BitSignedAccelerated),
5788		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated),
5789		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProductAccumulatingSaturating32BitUnsignedAccelerated),
5790		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProductAccumulatingSaturating32BitSignedAccelerated),
5791		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated),
5792		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProductAccumulatingSaturating64BitUnsignedAccelerated),
5793		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProductAccumulatingSaturating64BitSignedAccelerated),
5794		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated),
5795
5796		// VkPhysicalDeviceTexelBufferAlignmentProperties
5797		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, storageTexelBufferOffsetAlignmentBytes),
5798		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, storageTexelBufferOffsetSingleTexelAlignment),
5799		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, uniformTexelBufferOffsetAlignmentBytes),
5800		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, uniformTexelBufferOffsetSingleTexelAlignment),
5801
5802		// VkPhysicalDeviceMaintenance4Properties
5803		OFFSET_TABLE_ENTRY(VkPhysicalDeviceVulkan13Properties, maxBufferSize),
5804		{ 0, 0 }
5805	};
5806
5807	TestLog&										log											= context.getTestContext().getLog();
5808	const VkPhysicalDevice							physicalDevice								= context.getPhysicalDevice();
5809	const CustomInstance							instance									(createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
5810	const InstanceDriver&							vki											= instance.getDriver();
5811	const deUint32									vulkan13PropertiesBufferSize				= sizeof(VkPhysicalDeviceVulkan13Properties) + GUARD_SIZE;
5812	VkPhysicalDeviceProperties2						extProperties;
5813	deUint8											buffer13a[vulkan13PropertiesBufferSize];
5814	deUint8											buffer13b[vulkan13PropertiesBufferSize];
5815	const int										count										= 2u;
5816	VkPhysicalDeviceVulkan13Properties*				vulkan13Properties[count]					= { (VkPhysicalDeviceVulkan13Properties*)(buffer13a), (VkPhysicalDeviceVulkan13Properties*)(buffer13b)};
5817
5818	if (!context.contextSupports(vk::ApiVersion(0, 1, 3, 0)))
5819		TCU_THROW(NotSupportedError, "At least Vulkan 1.3 required to run test");
5820
5821	deMemset(buffer13a, GUARD_VALUE, sizeof(buffer13a));
5822	deMemset(buffer13b, GUARD_VALUE, sizeof(buffer13b));
5823
5824	for (int ndx = 0; ndx < count; ++ndx)
5825	{
5826		deMemset(&extProperties.properties, 0x00, sizeof(extProperties.properties));
5827		extProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
5828		extProperties.pNext = vulkan13Properties[ndx];
5829
5830		deMemset(vulkan13Properties[ndx], 0xFF * ndx, sizeof(VkPhysicalDeviceVulkan13Properties));
5831		vulkan13Properties[ndx]->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES;
5832		vulkan13Properties[ndx]->pNext = DE_NULL;
5833
5834		vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
5835	}
5836
5837	log << TestLog::Message << *vulkan13Properties[0] << TestLog::EndMessage;
5838
5839	if (!validateStructsWithGuard(properties13OffsetTable, vulkan13Properties, GUARD_VALUE, GUARD_SIZE))
5840	{
5841		log << TestLog::Message << "deviceProperties - VkPhysicalDeviceVulkan13Properties initialization failure" << TestLog::EndMessage;
5842
5843		return tcu::TestStatus::fail("VkPhysicalDeviceVulkan13Properties initialization failure");
5844	}
5845
5846	return tcu::TestStatus::pass("Querying Vulkan 1.3 device properties succeeded");
5847}
5848#endif // CTS_USES_VULKANSC
5849
5850tcu::TestStatus deviceFeatureExtensionsConsistencyVulkan12(Context& context)
5851{
5852	TestLog&											log										= context.getTestContext().getLog();
5853	const CustomInstance								instance								(createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
5854	const InstanceDriver&								vki										= instance.getDriver();
5855	const VkPhysicalDevice								physicalDevice							(chooseDevice(vki, instance, context.getTestContext().getCommandLine()));
5856
5857	if (!context.contextSupports(vk::ApiVersion(0, 1, 2, 0)))
5858		TCU_THROW(NotSupportedError, "At least Vulkan 1.2 required to run test");
5859
5860	VkPhysicalDeviceVulkan12Features					vulkan12Features						= initVulkanStructure();
5861	VkPhysicalDeviceVulkan11Features					vulkan11Features						= initVulkanStructure(&vulkan12Features);
5862	VkPhysicalDeviceFeatures2							extFeatures								= initVulkanStructure(&vulkan11Features);
5863
5864	vki.getPhysicalDeviceFeatures2(physicalDevice, &extFeatures);
5865
5866	log << TestLog::Message << vulkan11Features << TestLog::EndMessage;
5867	log << TestLog::Message << vulkan12Features << TestLog::EndMessage;
5868
5869	// Validate if proper VkPhysicalDeviceVulkanXXFeatures fields are set when corresponding extensions are present
5870	std::pair<std::pair<const char*,const char*>, VkBool32> extensions2validate[] =
5871	{
5872		{ { "VK_KHR_sampler_mirror_clamp_to_edge",	"VkPhysicalDeviceVulkan12Features.samplerMirrorClampToEdge" },	vulkan12Features.samplerMirrorClampToEdge },
5873		{ { "VK_KHR_draw_indirect_count",			"VkPhysicalDeviceVulkan12Features.drawIndirectCount" },			vulkan12Features.drawIndirectCount },
5874		{ { "VK_EXT_descriptor_indexing",			"VkPhysicalDeviceVulkan12Features.descriptorIndexing" },		vulkan12Features.descriptorIndexing },
5875		{ { "VK_EXT_sampler_filter_minmax",			"VkPhysicalDeviceVulkan12Features.samplerFilterMinmax" },		vulkan12Features.samplerFilterMinmax },
5876		{ { "VK_EXT_shader_viewport_index_layer",	"VkPhysicalDeviceVulkan12Features.shaderOutputViewportIndex" },	vulkan12Features.shaderOutputViewportIndex },
5877		{ { "VK_EXT_shader_viewport_index_layer",	"VkPhysicalDeviceVulkan12Features.shaderOutputLayer" },			vulkan12Features.shaderOutputLayer }
5878	};
5879	vector<VkExtensionProperties> extensionProperties = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
5880	for (const auto& ext : extensions2validate)
5881		if (checkExtension(extensionProperties, ext.first.first) && !ext.second)
5882			TCU_FAIL(string("Mismatch between extension ") + ext.first.first + " and " + ext.first.second);
5883
5884	// collect all extension features
5885	{
5886		VkPhysicalDevice16BitStorageFeatures				device16BitStorageFeatures				= initVulkanStructure();
5887		VkPhysicalDeviceMultiviewFeatures					deviceMultiviewFeatures					= initVulkanStructure(&device16BitStorageFeatures);
5888		VkPhysicalDeviceProtectedMemoryFeatures				protectedMemoryFeatures					= initVulkanStructure(&deviceMultiviewFeatures);
5889		VkPhysicalDeviceSamplerYcbcrConversionFeatures		samplerYcbcrConversionFeatures			= initVulkanStructure(&protectedMemoryFeatures);
5890		VkPhysicalDeviceShaderDrawParametersFeatures		shaderDrawParametersFeatures			= initVulkanStructure(&samplerYcbcrConversionFeatures);
5891		VkPhysicalDeviceVariablePointersFeatures			variablePointerFeatures					= initVulkanStructure(&shaderDrawParametersFeatures);
5892		VkPhysicalDevice8BitStorageFeatures					device8BitStorageFeatures				= initVulkanStructure(&variablePointerFeatures);
5893		VkPhysicalDeviceShaderAtomicInt64Features			shaderAtomicInt64Features				= initVulkanStructure(&device8BitStorageFeatures);
5894		VkPhysicalDeviceShaderFloat16Int8Features			shaderFloat16Int8Features				= initVulkanStructure(&shaderAtomicInt64Features);
5895		VkPhysicalDeviceDescriptorIndexingFeatures			descriptorIndexingFeatures				= initVulkanStructure(&shaderFloat16Int8Features);
5896		VkPhysicalDeviceScalarBlockLayoutFeatures			scalarBlockLayoutFeatures				= initVulkanStructure(&descriptorIndexingFeatures);
5897		VkPhysicalDeviceImagelessFramebufferFeatures		imagelessFramebufferFeatures			= initVulkanStructure(&scalarBlockLayoutFeatures);
5898		VkPhysicalDeviceUniformBufferStandardLayoutFeatures	uniformBufferStandardLayoutFeatures		= initVulkanStructure(&imagelessFramebufferFeatures);
5899		VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures	shaderSubgroupExtendedTypesFeatures		= initVulkanStructure(&uniformBufferStandardLayoutFeatures);
5900		VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures	separateDepthStencilLayoutsFeatures		= initVulkanStructure(&shaderSubgroupExtendedTypesFeatures);
5901		VkPhysicalDeviceHostQueryResetFeatures				hostQueryResetFeatures					= initVulkanStructure(&separateDepthStencilLayoutsFeatures);
5902		VkPhysicalDeviceTimelineSemaphoreFeatures			timelineSemaphoreFeatures				= initVulkanStructure(&hostQueryResetFeatures);
5903		VkPhysicalDeviceBufferDeviceAddressFeatures			bufferDeviceAddressFeatures				= initVulkanStructure(&timelineSemaphoreFeatures);
5904		VkPhysicalDeviceVulkanMemoryModelFeatures			vulkanMemoryModelFeatures				= initVulkanStructure(&bufferDeviceAddressFeatures);
5905		extFeatures = initVulkanStructure(&vulkanMemoryModelFeatures);
5906
5907		vki.getPhysicalDeviceFeatures2(physicalDevice, &extFeatures);
5908
5909		log << TestLog::Message << extFeatures << TestLog::EndMessage;
5910		log << TestLog::Message << device16BitStorageFeatures << TestLog::EndMessage;
5911		log << TestLog::Message << deviceMultiviewFeatures << TestLog::EndMessage;
5912		log << TestLog::Message << protectedMemoryFeatures << TestLog::EndMessage;
5913		log << TestLog::Message << samplerYcbcrConversionFeatures << TestLog::EndMessage;
5914		log << TestLog::Message << shaderDrawParametersFeatures << TestLog::EndMessage;
5915		log << TestLog::Message << variablePointerFeatures << TestLog::EndMessage;
5916		log << TestLog::Message << device8BitStorageFeatures << TestLog::EndMessage;
5917		log << TestLog::Message << shaderAtomicInt64Features << TestLog::EndMessage;
5918		log << TestLog::Message << shaderFloat16Int8Features << TestLog::EndMessage;
5919		log << TestLog::Message << descriptorIndexingFeatures << TestLog::EndMessage;
5920		log << TestLog::Message << scalarBlockLayoutFeatures << TestLog::EndMessage;
5921		log << TestLog::Message << imagelessFramebufferFeatures << TestLog::EndMessage;
5922		log << TestLog::Message << uniformBufferStandardLayoutFeatures << TestLog::EndMessage;
5923		log << TestLog::Message << shaderSubgroupExtendedTypesFeatures << TestLog::EndMessage;
5924		log << TestLog::Message << separateDepthStencilLayoutsFeatures << TestLog::EndMessage;
5925		log << TestLog::Message << hostQueryResetFeatures << TestLog::EndMessage;
5926		log << TestLog::Message << timelineSemaphoreFeatures << TestLog::EndMessage;
5927		log << TestLog::Message << bufferDeviceAddressFeatures << TestLog::EndMessage;
5928		log << TestLog::Message << vulkanMemoryModelFeatures << TestLog::EndMessage;
5929
5930		if ((	device16BitStorageFeatures.storageBuffer16BitAccess				!= vulkan11Features.storageBuffer16BitAccess ||
5931				device16BitStorageFeatures.uniformAndStorageBuffer16BitAccess	!= vulkan11Features.uniformAndStorageBuffer16BitAccess ||
5932				device16BitStorageFeatures.storagePushConstant16				!= vulkan11Features.storagePushConstant16 ||
5933				device16BitStorageFeatures.storageInputOutput16					!= vulkan11Features.storageInputOutput16 ))
5934		{
5935			TCU_FAIL("Mismatch between VkPhysicalDevice16BitStorageFeatures and VkPhysicalDeviceVulkan11Features");
5936		}
5937
5938		if ((	deviceMultiviewFeatures.multiview					!= vulkan11Features.multiview ||
5939				deviceMultiviewFeatures.multiviewGeometryShader		!= vulkan11Features.multiviewGeometryShader ||
5940				deviceMultiviewFeatures.multiviewTessellationShader	!= vulkan11Features.multiviewTessellationShader ))
5941		{
5942			TCU_FAIL("Mismatch between VkPhysicalDeviceMultiviewFeatures and VkPhysicalDeviceVulkan11Features");
5943		}
5944
5945		if (	(protectedMemoryFeatures.protectedMemory	!= vulkan11Features.protectedMemory ))
5946		{
5947			TCU_FAIL("Mismatch between VkPhysicalDeviceProtectedMemoryFeatures and VkPhysicalDeviceVulkan11Features");
5948		}
5949
5950		if (	(samplerYcbcrConversionFeatures.samplerYcbcrConversion	!= vulkan11Features.samplerYcbcrConversion ))
5951		{
5952			TCU_FAIL("Mismatch between VkPhysicalDeviceSamplerYcbcrConversionFeatures and VkPhysicalDeviceVulkan11Features");
5953		}
5954
5955		if (	(shaderDrawParametersFeatures.shaderDrawParameters	!= vulkan11Features.shaderDrawParameters ))
5956		{
5957			TCU_FAIL("Mismatch between VkPhysicalDeviceShaderDrawParametersFeatures and VkPhysicalDeviceVulkan11Features");
5958		}
5959
5960		if ((	variablePointerFeatures.variablePointersStorageBuffer	!= vulkan11Features.variablePointersStorageBuffer ||
5961				variablePointerFeatures.variablePointers				!= vulkan11Features.variablePointers))
5962		{
5963			TCU_FAIL("Mismatch between VkPhysicalDeviceVariablePointersFeatures and VkPhysicalDeviceVulkan11Features");
5964		}
5965
5966		if ((	device8BitStorageFeatures.storageBuffer8BitAccess			!= vulkan12Features.storageBuffer8BitAccess ||
5967				device8BitStorageFeatures.uniformAndStorageBuffer8BitAccess	!= vulkan12Features.uniformAndStorageBuffer8BitAccess ||
5968				device8BitStorageFeatures.storagePushConstant8				!= vulkan12Features.storagePushConstant8 ))
5969		{
5970			TCU_FAIL("Mismatch between VkPhysicalDevice8BitStorageFeatures and VkPhysicalDeviceVulkan12Features");
5971		}
5972
5973		if ((	shaderAtomicInt64Features.shaderBufferInt64Atomics != vulkan12Features.shaderBufferInt64Atomics ||
5974				shaderAtomicInt64Features.shaderSharedInt64Atomics != vulkan12Features.shaderSharedInt64Atomics ))
5975		{
5976			TCU_FAIL("Mismatch between VkPhysicalDeviceShaderAtomicInt64Features and VkPhysicalDeviceVulkan12Features");
5977		}
5978
5979		if ((	shaderFloat16Int8Features.shaderFloat16	!= vulkan12Features.shaderFloat16 ||
5980				shaderFloat16Int8Features.shaderInt8		!= vulkan12Features.shaderInt8 ))
5981		{
5982			TCU_FAIL("Mismatch between VkPhysicalDeviceShaderFloat16Int8Features and VkPhysicalDeviceVulkan12Features");
5983		}
5984
5985		if ((vulkan12Features.descriptorIndexing) &&
5986			(	descriptorIndexingFeatures.shaderInputAttachmentArrayDynamicIndexing			!= vulkan12Features.shaderInputAttachmentArrayDynamicIndexing ||
5987				descriptorIndexingFeatures.shaderUniformTexelBufferArrayDynamicIndexing			!= vulkan12Features.shaderUniformTexelBufferArrayDynamicIndexing ||
5988				descriptorIndexingFeatures.shaderStorageTexelBufferArrayDynamicIndexing			!= vulkan12Features.shaderStorageTexelBufferArrayDynamicIndexing ||
5989				descriptorIndexingFeatures.shaderUniformBufferArrayNonUniformIndexing			!= vulkan12Features.shaderUniformBufferArrayNonUniformIndexing ||
5990				descriptorIndexingFeatures.shaderSampledImageArrayNonUniformIndexing			!= vulkan12Features.shaderSampledImageArrayNonUniformIndexing ||
5991				descriptorIndexingFeatures.shaderStorageBufferArrayNonUniformIndexing			!= vulkan12Features.shaderStorageBufferArrayNonUniformIndexing ||
5992				descriptorIndexingFeatures.shaderStorageImageArrayNonUniformIndexing			!= vulkan12Features.shaderStorageImageArrayNonUniformIndexing ||
5993				descriptorIndexingFeatures.shaderInputAttachmentArrayNonUniformIndexing			!= vulkan12Features.shaderInputAttachmentArrayNonUniformIndexing ||
5994				descriptorIndexingFeatures.shaderUniformTexelBufferArrayNonUniformIndexing		!= vulkan12Features.shaderUniformTexelBufferArrayNonUniformIndexing ||
5995				descriptorIndexingFeatures.shaderStorageTexelBufferArrayNonUniformIndexing		!= vulkan12Features.shaderStorageTexelBufferArrayNonUniformIndexing ||
5996				descriptorIndexingFeatures.descriptorBindingUniformBufferUpdateAfterBind		!= vulkan12Features.descriptorBindingUniformBufferUpdateAfterBind ||
5997				descriptorIndexingFeatures.descriptorBindingSampledImageUpdateAfterBind			!= vulkan12Features.descriptorBindingSampledImageUpdateAfterBind ||
5998				descriptorIndexingFeatures.descriptorBindingStorageImageUpdateAfterBind			!= vulkan12Features.descriptorBindingStorageImageUpdateAfterBind ||
5999				descriptorIndexingFeatures.descriptorBindingStorageBufferUpdateAfterBind		!= vulkan12Features.descriptorBindingStorageBufferUpdateAfterBind ||
6000				descriptorIndexingFeatures.descriptorBindingUniformTexelBufferUpdateAfterBind	!= vulkan12Features.descriptorBindingUniformTexelBufferUpdateAfterBind ||
6001				descriptorIndexingFeatures.descriptorBindingStorageTexelBufferUpdateAfterBind	!= vulkan12Features.descriptorBindingStorageTexelBufferUpdateAfterBind ||
6002				descriptorIndexingFeatures.descriptorBindingUpdateUnusedWhilePending			!= vulkan12Features.descriptorBindingUpdateUnusedWhilePending ||
6003				descriptorIndexingFeatures.descriptorBindingPartiallyBound						!= vulkan12Features.descriptorBindingPartiallyBound ||
6004				descriptorIndexingFeatures.descriptorBindingVariableDescriptorCount				!= vulkan12Features.descriptorBindingVariableDescriptorCount ||
6005				descriptorIndexingFeatures.runtimeDescriptorArray								!= vulkan12Features.runtimeDescriptorArray ))
6006		{
6007			TCU_FAIL("Mismatch between VkPhysicalDeviceDescriptorIndexingFeatures and VkPhysicalDeviceVulkan12Features");
6008		}
6009
6010		if ((	scalarBlockLayoutFeatures.scalarBlockLayout != vulkan12Features.scalarBlockLayout ))
6011		{
6012			TCU_FAIL("Mismatch between VkPhysicalDeviceScalarBlockLayoutFeatures and VkPhysicalDeviceVulkan12Features");
6013		}
6014
6015		if ((	imagelessFramebufferFeatures.imagelessFramebuffer != vulkan12Features.imagelessFramebuffer ))
6016		{
6017			TCU_FAIL("Mismatch between VkPhysicalDeviceImagelessFramebufferFeatures and VkPhysicalDeviceVulkan12Features");
6018		}
6019
6020		if ((	uniformBufferStandardLayoutFeatures.uniformBufferStandardLayout != vulkan12Features.uniformBufferStandardLayout ))
6021		{
6022			TCU_FAIL("Mismatch between VkPhysicalDeviceUniformBufferStandardLayoutFeatures and VkPhysicalDeviceVulkan12Features");
6023		}
6024
6025		if ((	shaderSubgroupExtendedTypesFeatures.shaderSubgroupExtendedTypes != vulkan12Features.shaderSubgroupExtendedTypes ))
6026		{
6027			TCU_FAIL("Mismatch between VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures and VkPhysicalDeviceVulkan12Features");
6028		}
6029
6030		if ((	separateDepthStencilLayoutsFeatures.separateDepthStencilLayouts != vulkan12Features.separateDepthStencilLayouts ))
6031		{
6032			TCU_FAIL("Mismatch between VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures and VkPhysicalDeviceVulkan12Features");
6033		}
6034
6035		if ((	hostQueryResetFeatures.hostQueryReset != vulkan12Features.hostQueryReset ))
6036		{
6037			TCU_FAIL("Mismatch between VkPhysicalDeviceHostQueryResetFeatures and VkPhysicalDeviceVulkan12Features");
6038		}
6039
6040		if ((	timelineSemaphoreFeatures.timelineSemaphore != vulkan12Features.timelineSemaphore ))
6041		{
6042			TCU_FAIL("Mismatch between VkPhysicalDeviceTimelineSemaphoreFeatures and VkPhysicalDeviceVulkan12Features");
6043		}
6044
6045		if ((	bufferDeviceAddressFeatures.bufferDeviceAddress					!= vulkan12Features.bufferDeviceAddress ||
6046				bufferDeviceAddressFeatures.bufferDeviceAddressCaptureReplay	!= vulkan12Features.bufferDeviceAddressCaptureReplay ||
6047				bufferDeviceAddressFeatures.bufferDeviceAddressMultiDevice		!= vulkan12Features.bufferDeviceAddressMultiDevice ))
6048		{
6049			TCU_FAIL("Mismatch between VkPhysicalDeviceBufferDeviceAddressFeatures and VkPhysicalDeviceVulkan12Features");
6050		}
6051
6052		if ((	vulkanMemoryModelFeatures.vulkanMemoryModel								!= vulkan12Features.vulkanMemoryModel ||
6053				vulkanMemoryModelFeatures.vulkanMemoryModelDeviceScope					!= vulkan12Features.vulkanMemoryModelDeviceScope ||
6054				vulkanMemoryModelFeatures.vulkanMemoryModelAvailabilityVisibilityChains	!= vulkan12Features.vulkanMemoryModelAvailabilityVisibilityChains ))
6055		{
6056			TCU_FAIL("Mismatch between VkPhysicalDeviceVulkanMemoryModelFeatures and VkPhysicalDeviceVulkan12Features");
6057		}
6058	}
6059
6060	return tcu::TestStatus::pass("Vulkan 1.2 device features are consistent with extensions");
6061}
6062
6063#ifndef CTS_USES_VULKANSC
6064tcu::TestStatus deviceFeatureExtensionsConsistencyVulkan13(Context& context)
6065{
6066	TestLog&							log					= context.getTestContext().getLog();
6067	const VkPhysicalDevice				physicalDevice		= context.getPhysicalDevice();
6068	const CustomInstance				instance			= createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2");
6069	const InstanceDriver&				vki					= instance.getDriver();
6070
6071	if (!context.contextSupports(vk::ApiVersion(0, 1, 3, 0)))
6072		TCU_THROW(NotSupportedError, "At least Vulkan 1.3 required to run test");
6073
6074	VkPhysicalDeviceVulkan13Features					vulkan13Features				= initVulkanStructure();
6075	VkPhysicalDeviceFeatures2							extFeatures						= initVulkanStructure(&vulkan13Features);
6076
6077	vki.getPhysicalDeviceFeatures2(physicalDevice, &extFeatures);
6078
6079	log << TestLog::Message << vulkan13Features << TestLog::EndMessage;
6080
6081	// Validate if required VkPhysicalDeviceVulkan13Features fields are set
6082	std::pair<const char*, VkBool32> features2validate[]
6083	{
6084		{ { "VkPhysicalDeviceVulkan13Features.robustImageAccess" },										vulkan13Features.robustImageAccess },
6085		{ { "VkPhysicalDeviceVulkan13Features.inlineUniformBlock" },									vulkan13Features.inlineUniformBlock },
6086		{ { "VkPhysicalDeviceVulkan13Features.pipelineCreationCacheControl" },							vulkan13Features.pipelineCreationCacheControl },
6087		{ { "VkPhysicalDeviceVulkan13Features.privateData" },											vulkan13Features.privateData },
6088		{ { "VkPhysicalDeviceVulkan13Features.shaderDemoteToHelperInvocation" },						vulkan13Features.shaderDemoteToHelperInvocation },
6089		{ { "VkPhysicalDeviceVulkan13Features.shaderTerminateInvocation" },								vulkan13Features.shaderTerminateInvocation },
6090		{ { "VkPhysicalDeviceVulkan13Features.subgroupSizeControl" },									vulkan13Features.subgroupSizeControl },
6091		{ { "VkPhysicalDeviceVulkan13Features.computeFullSubgroups" },									vulkan13Features.computeFullSubgroups },
6092		{ { "VkPhysicalDeviceVulkan13Features.synchronization2" },										vulkan13Features.synchronization2 },
6093		{ { "VkPhysicalDeviceVulkan13Features.shaderZeroInitializeWorkgroupMemory" },					vulkan13Features.shaderZeroInitializeWorkgroupMemory },
6094		{ { "VkPhysicalDeviceVulkan13Features.dynamicRendering" },										vulkan13Features.dynamicRendering },
6095		{ { "VkPhysicalDeviceVulkan13Features.shaderIntegerDotProduct" },								vulkan13Features.shaderIntegerDotProduct },
6096		{ { "VkPhysicalDeviceVulkan13Features.maintenance4" },											vulkan13Features.maintenance4 },
6097	};
6098	for (const auto& feature : features2validate)
6099	{
6100		if (!feature.second)
6101			TCU_FAIL(string("Required feature ") + feature.first + " is not set");
6102	}
6103
6104	// collect all extension features
6105	{
6106		VkPhysicalDeviceImageRobustnessFeatures					imageRobustnessFeatures					= initVulkanStructure();
6107		VkPhysicalDeviceInlineUniformBlockFeatures				inlineUniformBlockFeatures				= initVulkanStructure(&imageRobustnessFeatures);
6108		VkPhysicalDevicePipelineCreationCacheControlFeatures	pipelineCreationCacheControlFeatures	= initVulkanStructure(&inlineUniformBlockFeatures);
6109		VkPhysicalDevicePrivateDataFeatures						privateDataFeatures						= initVulkanStructure(&pipelineCreationCacheControlFeatures);
6110		VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures	shaderDemoteToHelperInvocationFeatures	= initVulkanStructure(&privateDataFeatures);
6111		VkPhysicalDeviceShaderTerminateInvocationFeatures		shaderTerminateInvocationFeatures		= initVulkanStructure(&shaderDemoteToHelperInvocationFeatures);
6112		VkPhysicalDeviceSubgroupSizeControlFeatures				subgroupSizeControlFeatures				= initVulkanStructure(&shaderTerminateInvocationFeatures);
6113		VkPhysicalDeviceSynchronization2Features				synchronization2Features				= initVulkanStructure(&subgroupSizeControlFeatures);
6114		VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures	zeroInitializeWorkgroupMemoryFeatures	= initVulkanStructure(&synchronization2Features);
6115		VkPhysicalDeviceDynamicRenderingFeatures				dynamicRenderingFeatures				= initVulkanStructure(&zeroInitializeWorkgroupMemoryFeatures);
6116		VkPhysicalDeviceShaderIntegerDotProductFeatures			shaderIntegerDotProductFeatures			= initVulkanStructure(&dynamicRenderingFeatures);
6117		VkPhysicalDeviceMaintenance4Features					maintenance4Features					= initVulkanStructure(&shaderIntegerDotProductFeatures);
6118
6119		// those two structures are part of extensions promoted in vk1.2 but now in 1.3 have required features
6120		VkPhysicalDeviceVulkanMemoryModelFeatures				vulkanMemoryModelFeatures				= initVulkanStructure(&maintenance4Features);
6121		VkPhysicalDeviceBufferDeviceAddressFeatures				bufferDeviceAddressFeatures				= initVulkanStructure(&vulkanMemoryModelFeatures);
6122
6123		extFeatures = initVulkanStructure(&bufferDeviceAddressFeatures);
6124
6125		vki.getPhysicalDeviceFeatures2(physicalDevice, &extFeatures);
6126
6127		log << TestLog::Message << extFeatures << TestLog::EndMessage;
6128		log << TestLog::Message << imageRobustnessFeatures << TestLog::EndMessage;
6129		log << TestLog::Message << inlineUniformBlockFeatures << TestLog::EndMessage;
6130		log << TestLog::Message << pipelineCreationCacheControlFeatures << TestLog::EndMessage;
6131		log << TestLog::Message << privateDataFeatures << TestLog::EndMessage;
6132		log << TestLog::Message << shaderDemoteToHelperInvocationFeatures << TestLog::EndMessage;
6133		log << TestLog::Message << shaderTerminateInvocationFeatures << TestLog::EndMessage;
6134		log << TestLog::Message << subgroupSizeControlFeatures << TestLog::EndMessage;
6135		log << TestLog::Message << synchronization2Features << TestLog::EndMessage;
6136		log << TestLog::Message << zeroInitializeWorkgroupMemoryFeatures << TestLog::EndMessage;
6137		log << TestLog::Message << dynamicRenderingFeatures << TestLog::EndMessage;
6138		log << TestLog::Message << shaderIntegerDotProductFeatures << TestLog::EndMessage;
6139		log << TestLog::Message << maintenance4Features << TestLog::EndMessage;
6140
6141		if (imageRobustnessFeatures.robustImageAccess != vulkan13Features.robustImageAccess)
6142			TCU_FAIL("Mismatch between VkPhysicalDeviceImageRobustnessFeatures and VkPhysicalDeviceVulkan13Features");
6143
6144		if ((inlineUniformBlockFeatures.inlineUniformBlock != vulkan13Features.inlineUniformBlock) ||
6145			(inlineUniformBlockFeatures.descriptorBindingInlineUniformBlockUpdateAfterBind != vulkan13Features.descriptorBindingInlineUniformBlockUpdateAfterBind))
6146		{
6147			TCU_FAIL("Mismatch between VkPhysicalDeviceInlineUniformBlockFeatures and VkPhysicalDeviceVulkan13Features");
6148		}
6149
6150		if (pipelineCreationCacheControlFeatures.pipelineCreationCacheControl != vulkan13Features.pipelineCreationCacheControl)
6151			TCU_FAIL("Mismatch between VkPhysicalDevicePipelineCreationCacheControlFeatures and VkPhysicalDeviceVulkan13Features");
6152
6153		if (privateDataFeatures.privateData != vulkan13Features.privateData)
6154			TCU_FAIL("Mismatch between VkPhysicalDevicePrivateDataFeatures and VkPhysicalDeviceVulkan13Features");
6155
6156		if (shaderDemoteToHelperInvocationFeatures.shaderDemoteToHelperInvocation != vulkan13Features.shaderDemoteToHelperInvocation)
6157			TCU_FAIL("Mismatch between VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures and VkPhysicalDeviceVulkan13Features");
6158
6159		if (shaderTerminateInvocationFeatures.shaderTerminateInvocation != vulkan13Features.shaderTerminateInvocation)
6160			TCU_FAIL("Mismatch between VkPhysicalDeviceShaderTerminateInvocationFeatures and VkPhysicalDeviceVulkan13Features");
6161
6162		if ((subgroupSizeControlFeatures.subgroupSizeControl != vulkan13Features.subgroupSizeControl) ||
6163			(subgroupSizeControlFeatures.computeFullSubgroups != vulkan13Features.computeFullSubgroups))
6164		{
6165			TCU_FAIL("Mismatch between VkPhysicalDeviceSubgroupSizeControlFeatures and VkPhysicalDeviceVulkan13Features");
6166		}
6167
6168		if (synchronization2Features.synchronization2 != vulkan13Features.synchronization2)
6169			TCU_FAIL("Mismatch between VkPhysicalDeviceSynchronization2Features and VkPhysicalDeviceVulkan13Features");
6170
6171		if (zeroInitializeWorkgroupMemoryFeatures.shaderZeroInitializeWorkgroupMemory != vulkan13Features.shaderZeroInitializeWorkgroupMemory)
6172			TCU_FAIL("Mismatch between VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures and VkPhysicalDeviceVulkan13Features");
6173
6174		if (dynamicRenderingFeatures.dynamicRendering != vulkan13Features.dynamicRendering)
6175			TCU_FAIL("Mismatch between VkPhysicalDeviceDynamicRenderingFeatures and VkPhysicalDeviceVulkan13Features");
6176
6177		if (shaderIntegerDotProductFeatures.shaderIntegerDotProduct != vulkan13Features.shaderIntegerDotProduct)
6178			TCU_FAIL("Mismatch between VkPhysicalDeviceShaderIntegerDotProductFeatures and VkPhysicalDeviceVulkan13Features");
6179
6180		if (maintenance4Features.maintenance4 != vulkan13Features.maintenance4)
6181			TCU_FAIL("Mismatch between VkPhysicalDeviceMaintenance4Features and VkPhysicalDeviceVulkan13Features");
6182
6183		// check required features from extensions that were promoted in earlier vulkan version
6184		if (!vulkanMemoryModelFeatures.vulkanMemoryModel)
6185			TCU_FAIL("vulkanMemoryModel feature from VkPhysicalDeviceVulkanMemoryModelFeatures is required");
6186		if (!vulkanMemoryModelFeatures.vulkanMemoryModelDeviceScope)
6187			TCU_FAIL("vulkanMemoryModelDeviceScope feature from VkPhysicalDeviceVulkanMemoryModelFeatures is required");
6188		if (!bufferDeviceAddressFeatures.bufferDeviceAddress)
6189			TCU_FAIL("bufferDeviceAddress feature from VkPhysicalDeviceBufferDeviceAddressFeatures is required");
6190	}
6191
6192	return tcu::TestStatus::pass("Vulkan 1.3 device features are consistent with extensions");
6193}
6194#endif // CTS_USES_VULKANSC
6195
6196tcu::TestStatus devicePropertyExtensionsConsistencyVulkan12(Context& context)
6197{
6198	TestLog&										log											= context.getTestContext().getLog();
6199	const CustomInstance							instance									(createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
6200	const InstanceDriver&							vki											= instance.getDriver();
6201	const VkPhysicalDevice							physicalDevice								(chooseDevice(vki, instance, context.getTestContext().getCommandLine()));
6202
6203	if (!context.contextSupports(vk::ApiVersion(0, 1, 2, 0)))
6204		TCU_THROW(NotSupportedError, "At least Vulkan 1.2 required to run test");
6205
6206	VkPhysicalDeviceVulkan12Properties				vulkan12Properties							= initVulkanStructure();
6207	VkPhysicalDeviceVulkan11Properties				vulkan11Properties							= initVulkanStructure(&vulkan12Properties);
6208	VkPhysicalDeviceProperties2						extProperties								= initVulkanStructure(&vulkan11Properties);
6209
6210	vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
6211
6212	log << TestLog::Message << vulkan11Properties << TestLog::EndMessage;
6213	log << TestLog::Message << vulkan12Properties << TestLog::EndMessage;
6214
6215	// Validate all fields initialized matching to extension structures
6216	{
6217		VkPhysicalDeviceIDProperties					idProperties								= initVulkanStructure();
6218		VkPhysicalDeviceSubgroupProperties				subgroupProperties							= initVulkanStructure(&idProperties);
6219		VkPhysicalDevicePointClippingProperties			pointClippingProperties						= initVulkanStructure(&subgroupProperties);
6220		VkPhysicalDeviceMultiviewProperties				multiviewProperties							= initVulkanStructure(&pointClippingProperties);
6221		VkPhysicalDeviceProtectedMemoryProperties		protectedMemoryPropertiesKHR				= initVulkanStructure(&multiviewProperties);
6222		VkPhysicalDeviceMaintenance3Properties			maintenance3Properties						= initVulkanStructure(&protectedMemoryPropertiesKHR);
6223		VkPhysicalDeviceDriverProperties				driverProperties							= initVulkanStructure(&maintenance3Properties);
6224		VkPhysicalDeviceFloatControlsProperties			floatControlsProperties						= initVulkanStructure(&driverProperties);
6225		VkPhysicalDeviceDescriptorIndexingProperties	descriptorIndexingProperties				= initVulkanStructure(&floatControlsProperties);
6226		VkPhysicalDeviceDepthStencilResolveProperties	depthStencilResolveProperties				= initVulkanStructure(&descriptorIndexingProperties);
6227		VkPhysicalDeviceSamplerFilterMinmaxProperties	samplerFilterMinmaxProperties				= initVulkanStructure(&depthStencilResolveProperties);
6228		VkPhysicalDeviceTimelineSemaphoreProperties		timelineSemaphoreProperties					= initVulkanStructure(&samplerFilterMinmaxProperties);
6229		extProperties = initVulkanStructure(&timelineSemaphoreProperties);
6230
6231		vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
6232
6233		if ((deMemCmp(idProperties.deviceUUID, vulkan11Properties.deviceUUID, VK_UUID_SIZE) != 0) ||
6234			(deMemCmp(idProperties.driverUUID, vulkan11Properties.driverUUID, VK_UUID_SIZE) != 0) ||
6235			(idProperties.deviceLUIDValid != vulkan11Properties.deviceLUIDValid))
6236		{
6237			TCU_FAIL("Mismatch between VkPhysicalDeviceIDProperties and VkPhysicalDeviceVulkan11Properties");
6238		}
6239		else if (idProperties.deviceLUIDValid)
6240		{
6241			// If deviceLUIDValid is VK_FALSE, the contents of deviceLUID and deviceNodeMask are undefined
6242			// so thay can only be compared when deviceLUIDValid is VK_TRUE.
6243			if ((deMemCmp(idProperties.deviceLUID, vulkan11Properties.deviceLUID, VK_LUID_SIZE) != 0) ||
6244				(idProperties.deviceNodeMask != vulkan11Properties.deviceNodeMask))
6245			{
6246				TCU_FAIL("Mismatch between VkPhysicalDeviceIDProperties and VkPhysicalDeviceVulkan11Properties");
6247			}
6248		}
6249
6250		if ((subgroupProperties.subgroupSize				!= vulkan11Properties.subgroupSize ||
6251			 subgroupProperties.supportedStages				!= vulkan11Properties.subgroupSupportedStages ||
6252			 subgroupProperties.supportedOperations			!= vulkan11Properties.subgroupSupportedOperations ||
6253			 subgroupProperties.quadOperationsInAllStages	!= vulkan11Properties.subgroupQuadOperationsInAllStages))
6254		{
6255			TCU_FAIL("Mismatch between VkPhysicalDeviceSubgroupProperties and VkPhysicalDeviceVulkan11Properties");
6256		}
6257
6258		if ((pointClippingProperties.pointClippingBehavior	!= vulkan11Properties.pointClippingBehavior))
6259		{
6260			TCU_FAIL("Mismatch between VkPhysicalDevicePointClippingProperties and VkPhysicalDeviceVulkan11Properties");
6261		}
6262
6263		if ((multiviewProperties.maxMultiviewViewCount		!= vulkan11Properties.maxMultiviewViewCount ||
6264			 multiviewProperties.maxMultiviewInstanceIndex	!= vulkan11Properties.maxMultiviewInstanceIndex))
6265		{
6266			TCU_FAIL("Mismatch between VkPhysicalDeviceMultiviewProperties and VkPhysicalDeviceVulkan11Properties");
6267		}
6268
6269		if ((protectedMemoryPropertiesKHR.protectedNoFault	!= vulkan11Properties.protectedNoFault))
6270		{
6271			TCU_FAIL("Mismatch between VkPhysicalDeviceProtectedMemoryProperties and VkPhysicalDeviceVulkan11Properties");
6272		}
6273
6274		if ((maintenance3Properties.maxPerSetDescriptors	!= vulkan11Properties.maxPerSetDescriptors ||
6275			 maintenance3Properties.maxMemoryAllocationSize	!= vulkan11Properties.maxMemoryAllocationSize))
6276		{
6277			TCU_FAIL("Mismatch between VkPhysicalDeviceMaintenance3Properties and VkPhysicalDeviceVulkan11Properties");
6278		}
6279
6280		if ((driverProperties.driverID												!= vulkan12Properties.driverID ||
6281			 strncmp(driverProperties.driverName, vulkan12Properties.driverName, VK_MAX_DRIVER_NAME_SIZE)	!= 0 ||
6282			 strncmp(driverProperties.driverInfo, vulkan12Properties.driverInfo, VK_MAX_DRIVER_INFO_SIZE)	!= 0 ||
6283			 driverProperties.conformanceVersion.major								!= vulkan12Properties.conformanceVersion.major ||
6284			 driverProperties.conformanceVersion.minor								!= vulkan12Properties.conformanceVersion.minor ||
6285			 driverProperties.conformanceVersion.subminor							!= vulkan12Properties.conformanceVersion.subminor ||
6286			 driverProperties.conformanceVersion.patch								!= vulkan12Properties.conformanceVersion.patch))
6287		{
6288			TCU_FAIL("Mismatch between VkPhysicalDeviceDriverProperties and VkPhysicalDeviceVulkan12Properties");
6289		}
6290
6291		if ((floatControlsProperties.denormBehaviorIndependence				!= vulkan12Properties.denormBehaviorIndependence ||
6292			 floatControlsProperties.roundingModeIndependence				!= vulkan12Properties.roundingModeIndependence ||
6293			 floatControlsProperties.shaderSignedZeroInfNanPreserveFloat16	!= vulkan12Properties.shaderSignedZeroInfNanPreserveFloat16 ||
6294			 floatControlsProperties.shaderSignedZeroInfNanPreserveFloat32	!= vulkan12Properties.shaderSignedZeroInfNanPreserveFloat32 ||
6295			 floatControlsProperties.shaderSignedZeroInfNanPreserveFloat64	!= vulkan12Properties.shaderSignedZeroInfNanPreserveFloat64 ||
6296			 floatControlsProperties.shaderDenormPreserveFloat16			!= vulkan12Properties.shaderDenormPreserveFloat16 ||
6297			 floatControlsProperties.shaderDenormPreserveFloat32			!= vulkan12Properties.shaderDenormPreserveFloat32 ||
6298			 floatControlsProperties.shaderDenormPreserveFloat64			!= vulkan12Properties.shaderDenormPreserveFloat64 ||
6299			 floatControlsProperties.shaderDenormFlushToZeroFloat16			!= vulkan12Properties.shaderDenormFlushToZeroFloat16 ||
6300			 floatControlsProperties.shaderDenormFlushToZeroFloat32			!= vulkan12Properties.shaderDenormFlushToZeroFloat32 ||
6301			 floatControlsProperties.shaderDenormFlushToZeroFloat64			!= vulkan12Properties.shaderDenormFlushToZeroFloat64 ||
6302			 floatControlsProperties.shaderRoundingModeRTEFloat16			!= vulkan12Properties.shaderRoundingModeRTEFloat16 ||
6303			 floatControlsProperties.shaderRoundingModeRTEFloat32			!= vulkan12Properties.shaderRoundingModeRTEFloat32 ||
6304			 floatControlsProperties.shaderRoundingModeRTEFloat64			!= vulkan12Properties.shaderRoundingModeRTEFloat64 ||
6305			 floatControlsProperties.shaderRoundingModeRTZFloat16			!= vulkan12Properties.shaderRoundingModeRTZFloat16 ||
6306			 floatControlsProperties.shaderRoundingModeRTZFloat32			!= vulkan12Properties.shaderRoundingModeRTZFloat32 ||
6307			 floatControlsProperties.shaderRoundingModeRTZFloat64			!= vulkan12Properties.shaderRoundingModeRTZFloat64 ))
6308		{
6309			TCU_FAIL("Mismatch between VkPhysicalDeviceFloatControlsProperties and VkPhysicalDeviceVulkan12Properties");
6310		}
6311
6312		if ((descriptorIndexingProperties.maxUpdateAfterBindDescriptorsInAllPools				!= vulkan12Properties.maxUpdateAfterBindDescriptorsInAllPools ||
6313			 descriptorIndexingProperties.shaderUniformBufferArrayNonUniformIndexingNative		!= vulkan12Properties.shaderUniformBufferArrayNonUniformIndexingNative ||
6314			 descriptorIndexingProperties.shaderSampledImageArrayNonUniformIndexingNative		!= vulkan12Properties.shaderSampledImageArrayNonUniformIndexingNative ||
6315			 descriptorIndexingProperties.shaderStorageBufferArrayNonUniformIndexingNative		!= vulkan12Properties.shaderStorageBufferArrayNonUniformIndexingNative ||
6316			 descriptorIndexingProperties.shaderStorageImageArrayNonUniformIndexingNative		!= vulkan12Properties.shaderStorageImageArrayNonUniformIndexingNative ||
6317			 descriptorIndexingProperties.shaderInputAttachmentArrayNonUniformIndexingNative	!= vulkan12Properties.shaderInputAttachmentArrayNonUniformIndexingNative ||
6318			 descriptorIndexingProperties.robustBufferAccessUpdateAfterBind						!= vulkan12Properties.robustBufferAccessUpdateAfterBind ||
6319			 descriptorIndexingProperties.quadDivergentImplicitLod								!= vulkan12Properties.quadDivergentImplicitLod ||
6320			 descriptorIndexingProperties.maxPerStageDescriptorUpdateAfterBindSamplers			!= vulkan12Properties.maxPerStageDescriptorUpdateAfterBindSamplers ||
6321			 descriptorIndexingProperties.maxPerStageDescriptorUpdateAfterBindUniformBuffers	!= vulkan12Properties.maxPerStageDescriptorUpdateAfterBindUniformBuffers ||
6322			 descriptorIndexingProperties.maxPerStageDescriptorUpdateAfterBindStorageBuffers	!= vulkan12Properties.maxPerStageDescriptorUpdateAfterBindStorageBuffers ||
6323			 descriptorIndexingProperties.maxPerStageDescriptorUpdateAfterBindSampledImages		!= vulkan12Properties.maxPerStageDescriptorUpdateAfterBindSampledImages ||
6324			 descriptorIndexingProperties.maxPerStageDescriptorUpdateAfterBindStorageImages		!= vulkan12Properties.maxPerStageDescriptorUpdateAfterBindStorageImages ||
6325			 descriptorIndexingProperties.maxPerStageDescriptorUpdateAfterBindInputAttachments	!= vulkan12Properties.maxPerStageDescriptorUpdateAfterBindInputAttachments ||
6326			 descriptorIndexingProperties.maxPerStageUpdateAfterBindResources					!= vulkan12Properties.maxPerStageUpdateAfterBindResources ||
6327			 descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindSamplers				!= vulkan12Properties.maxDescriptorSetUpdateAfterBindSamplers ||
6328			 descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindUniformBuffers			!= vulkan12Properties.maxDescriptorSetUpdateAfterBindUniformBuffers ||
6329			 descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic	!= vulkan12Properties.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic ||
6330			 descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindStorageBuffers			!= vulkan12Properties.maxDescriptorSetUpdateAfterBindStorageBuffers ||
6331			 descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic	!= vulkan12Properties.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic ||
6332			 descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindSampledImages			!= vulkan12Properties.maxDescriptorSetUpdateAfterBindSampledImages ||
6333			 descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindStorageImages			!= vulkan12Properties.maxDescriptorSetUpdateAfterBindStorageImages ||
6334			 descriptorIndexingProperties.maxDescriptorSetUpdateAfterBindInputAttachments		!= vulkan12Properties.maxDescriptorSetUpdateAfterBindInputAttachments ))
6335		{
6336			TCU_FAIL("Mismatch between VkPhysicalDeviceDescriptorIndexingProperties and VkPhysicalDeviceVulkan12Properties");
6337		}
6338
6339		if ((depthStencilResolveProperties.supportedDepthResolveModes	!= vulkan12Properties.supportedDepthResolveModes ||
6340			 depthStencilResolveProperties.supportedStencilResolveModes	!= vulkan12Properties.supportedStencilResolveModes ||
6341			 depthStencilResolveProperties.independentResolveNone		!= vulkan12Properties.independentResolveNone ||
6342			 depthStencilResolveProperties.independentResolve			!= vulkan12Properties.independentResolve))
6343		{
6344			TCU_FAIL("Mismatch between VkPhysicalDeviceDepthStencilResolveProperties and VkPhysicalDeviceVulkan12Properties");
6345		}
6346
6347		if ((samplerFilterMinmaxProperties.filterMinmaxSingleComponentFormats	!= vulkan12Properties.filterMinmaxSingleComponentFormats ||
6348			 samplerFilterMinmaxProperties.filterMinmaxImageComponentMapping	!= vulkan12Properties.filterMinmaxImageComponentMapping))
6349		{
6350			TCU_FAIL("Mismatch between VkPhysicalDeviceSamplerFilterMinmaxProperties and VkPhysicalDeviceVulkan12Properties");
6351		}
6352
6353		if ((timelineSemaphoreProperties.maxTimelineSemaphoreValueDifference	!= vulkan12Properties.maxTimelineSemaphoreValueDifference))
6354		{
6355			TCU_FAIL("Mismatch between VkPhysicalDeviceTimelineSemaphoreProperties and VkPhysicalDeviceVulkan12Properties");
6356		}
6357	}
6358
6359	return tcu::TestStatus::pass("Vulkan 1.2 device properties are consistent with extension properties");
6360}
6361
6362#ifndef CTS_USES_VULKANSC
6363tcu::TestStatus devicePropertyExtensionsConsistencyVulkan13(Context& context)
6364{
6365	TestLog&					log					= context.getTestContext().getLog();
6366	const VkPhysicalDevice		physicalDevice		= context.getPhysicalDevice();
6367	const CustomInstance		instance			= createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2");
6368	const InstanceDriver&		vki					= instance.getDriver();
6369
6370	if (!context.contextSupports(vk::ApiVersion(0, 1, 3, 0)))
6371		TCU_THROW(NotSupportedError, "At least Vulkan 1.3 required to run test");
6372
6373	VkPhysicalDeviceVulkan13Properties		vulkan13Properties		= initVulkanStructure();
6374	VkPhysicalDeviceProperties2				extProperties			= initVulkanStructure(&vulkan13Properties);
6375
6376	vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
6377
6378	log << TestLog::Message << vulkan13Properties << TestLog::EndMessage;
6379
6380	// Validate all fields initialized matching to extension structures
6381	{
6382		VkPhysicalDeviceSubgroupSizeControlProperties		subgroupSizeControlProperties		= initVulkanStructure();
6383		VkPhysicalDeviceInlineUniformBlockProperties		inlineUniformBlockProperties		= initVulkanStructure(&subgroupSizeControlProperties);
6384		VkPhysicalDeviceShaderIntegerDotProductProperties	shaderIntegerDotProductProperties	= initVulkanStructure(&inlineUniformBlockProperties);
6385		VkPhysicalDeviceTexelBufferAlignmentProperties		texelBufferAlignmentProperties		= initVulkanStructure(&shaderIntegerDotProductProperties);
6386		VkPhysicalDeviceMaintenance4Properties				maintenance4Properties				= initVulkanStructure(&texelBufferAlignmentProperties);
6387		extProperties = initVulkanStructure(&maintenance4Properties);
6388
6389		vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
6390
6391		if (subgroupSizeControlProperties.minSubgroupSize				!= vulkan13Properties.minSubgroupSize ||
6392			subgroupSizeControlProperties.maxSubgroupSize				!= vulkan13Properties.maxSubgroupSize ||
6393			subgroupSizeControlProperties.maxComputeWorkgroupSubgroups	!= vulkan13Properties.maxComputeWorkgroupSubgroups ||
6394			subgroupSizeControlProperties.requiredSubgroupSizeStages	!= vulkan13Properties.requiredSubgroupSizeStages)
6395		{
6396			TCU_FAIL("Mismatch between VkPhysicalDeviceSubgroupSizeControlProperties and VkPhysicalDeviceVulkan13Properties");
6397		}
6398
6399		if (inlineUniformBlockProperties.maxInlineUniformBlockSize									!= vulkan13Properties.maxInlineUniformBlockSize ||
6400			inlineUniformBlockProperties.maxPerStageDescriptorInlineUniformBlocks					!= vulkan13Properties.maxPerStageDescriptorInlineUniformBlocks ||
6401			inlineUniformBlockProperties.maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks	!= vulkan13Properties.maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks ||
6402			inlineUniformBlockProperties.maxDescriptorSetInlineUniformBlocks						!= vulkan13Properties.maxDescriptorSetInlineUniformBlocks ||
6403			inlineUniformBlockProperties.maxDescriptorSetUpdateAfterBindInlineUniformBlocks			!= vulkan13Properties.maxDescriptorSetUpdateAfterBindInlineUniformBlocks)
6404		{
6405			TCU_FAIL("Mismatch between VkPhysicalDeviceInlineUniformBlockProperties and VkPhysicalDeviceVulkan13Properties");
6406		}
6407
6408		if (shaderIntegerDotProductProperties.integerDotProduct8BitUnsignedAccelerated											!= vulkan13Properties.integerDotProduct8BitUnsignedAccelerated ||
6409			shaderIntegerDotProductProperties.integerDotProduct8BitSignedAccelerated											!= vulkan13Properties.integerDotProduct8BitSignedAccelerated ||
6410			shaderIntegerDotProductProperties.integerDotProduct8BitMixedSignednessAccelerated									!= vulkan13Properties.integerDotProduct8BitMixedSignednessAccelerated ||
6411			shaderIntegerDotProductProperties.integerDotProduct4x8BitPackedUnsignedAccelerated									!= vulkan13Properties.integerDotProduct4x8BitPackedUnsignedAccelerated ||
6412			shaderIntegerDotProductProperties.integerDotProduct4x8BitPackedSignedAccelerated									!= vulkan13Properties.integerDotProduct4x8BitPackedSignedAccelerated ||
6413			shaderIntegerDotProductProperties.integerDotProduct4x8BitPackedMixedSignednessAccelerated							!= vulkan13Properties.integerDotProduct4x8BitPackedMixedSignednessAccelerated ||
6414			shaderIntegerDotProductProperties.integerDotProduct16BitUnsignedAccelerated											!= vulkan13Properties.integerDotProduct16BitUnsignedAccelerated ||
6415			shaderIntegerDotProductProperties.integerDotProduct16BitSignedAccelerated											!= vulkan13Properties.integerDotProduct16BitSignedAccelerated ||
6416			shaderIntegerDotProductProperties.integerDotProduct16BitMixedSignednessAccelerated									!= vulkan13Properties.integerDotProduct16BitMixedSignednessAccelerated ||
6417			shaderIntegerDotProductProperties.integerDotProduct32BitUnsignedAccelerated											!= vulkan13Properties.integerDotProduct32BitUnsignedAccelerated ||
6418			shaderIntegerDotProductProperties.integerDotProduct32BitSignedAccelerated											!= vulkan13Properties.integerDotProduct32BitSignedAccelerated ||
6419			shaderIntegerDotProductProperties.integerDotProduct32BitMixedSignednessAccelerated									!= vulkan13Properties.integerDotProduct32BitMixedSignednessAccelerated ||
6420			shaderIntegerDotProductProperties.integerDotProduct64BitUnsignedAccelerated											!= vulkan13Properties.integerDotProduct64BitUnsignedAccelerated ||
6421			shaderIntegerDotProductProperties.integerDotProduct64BitSignedAccelerated											!= vulkan13Properties.integerDotProduct64BitSignedAccelerated ||
6422			shaderIntegerDotProductProperties.integerDotProduct64BitMixedSignednessAccelerated									!= vulkan13Properties.integerDotProduct64BitMixedSignednessAccelerated ||
6423			shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating8BitUnsignedAccelerated					!= vulkan13Properties.integerDotProductAccumulatingSaturating8BitUnsignedAccelerated ||
6424			shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating8BitSignedAccelerated						!= vulkan13Properties.integerDotProductAccumulatingSaturating8BitSignedAccelerated ||
6425			shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated				!= vulkan13Properties.integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated ||
6426			shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated			!= vulkan13Properties.integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated ||
6427			shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated				!= vulkan13Properties.integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated ||
6428			shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated		!= vulkan13Properties.integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated ||
6429			shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating16BitUnsignedAccelerated					!= vulkan13Properties.integerDotProductAccumulatingSaturating16BitUnsignedAccelerated ||
6430			shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating16BitSignedAccelerated						!= vulkan13Properties.integerDotProductAccumulatingSaturating16BitSignedAccelerated ||
6431			shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated			!= vulkan13Properties.integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated ||
6432			shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating32BitUnsignedAccelerated					!= vulkan13Properties.integerDotProductAccumulatingSaturating32BitUnsignedAccelerated ||
6433			shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating32BitSignedAccelerated						!= vulkan13Properties.integerDotProductAccumulatingSaturating32BitSignedAccelerated ||
6434			shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated			!= vulkan13Properties.integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated ||
6435			shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating64BitUnsignedAccelerated					!= vulkan13Properties.integerDotProductAccumulatingSaturating64BitUnsignedAccelerated ||
6436			shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating64BitSignedAccelerated						!= vulkan13Properties.integerDotProductAccumulatingSaturating64BitSignedAccelerated ||
6437			shaderIntegerDotProductProperties.integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated			!= vulkan13Properties.integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated)
6438		{
6439			TCU_FAIL("Mismatch between VkPhysicalDeviceShaderIntegerDotProductProperties and VkPhysicalDeviceVulkan13Properties");
6440		}
6441
6442		if (texelBufferAlignmentProperties.storageTexelBufferOffsetAlignmentBytes		!= vulkan13Properties.storageTexelBufferOffsetAlignmentBytes ||
6443			texelBufferAlignmentProperties.storageTexelBufferOffsetSingleTexelAlignment	!= vulkan13Properties.storageTexelBufferOffsetSingleTexelAlignment ||
6444			texelBufferAlignmentProperties.uniformTexelBufferOffsetAlignmentBytes		!= vulkan13Properties.uniformTexelBufferOffsetAlignmentBytes ||
6445			texelBufferAlignmentProperties.uniformTexelBufferOffsetSingleTexelAlignment	!= vulkan13Properties.uniformTexelBufferOffsetSingleTexelAlignment)
6446		{
6447			TCU_FAIL("Mismatch between VkPhysicalDeviceTexelBufferAlignmentProperties and VkPhysicalDeviceVulkan13Properties");
6448		}
6449
6450		if (maintenance4Properties.maxBufferSize != vulkan13Properties.maxBufferSize)
6451		{
6452			TCU_FAIL("Mismatch between VkPhysicalDeviceMaintenance4Properties and VkPhysicalDeviceVulkan13Properties");
6453		}
6454	}
6455
6456	return tcu::TestStatus::pass("Vulkan 1.3 device properties are consistent with extension properties");
6457}
6458#endif // CTS_USES_VULKANSC
6459
6460tcu::TestStatus imageFormatProperties2 (Context& context, const VkFormat format, const VkImageType imageType, const VkImageTiling tiling)
6461{
6462	if (isYCbCrFormat(format))
6463		// check if Ycbcr format enums are valid given the version and extensions
6464		checkYcbcrApiSupport(context);
6465
6466	TestLog&						log				= context.getTestContext().getLog();
6467
6468	const CustomInstance			instance		(createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
6469	const InstanceDriver&			vki				(instance.getDriver());
6470	const VkPhysicalDevice			physicalDevice	(chooseDevice(vki, instance, context.getTestContext().getCommandLine()));
6471
6472	const VkImageCreateFlags		ycbcrFlags		= isYCbCrFormat(format) ? (VkImageCreateFlags)VK_IMAGE_CREATE_DISJOINT_BIT : (VkImageCreateFlags)0u;
6473	const VkImageUsageFlags			allUsageFlags	= VK_IMAGE_USAGE_TRANSFER_SRC_BIT
6474													| VK_IMAGE_USAGE_TRANSFER_DST_BIT
6475													| VK_IMAGE_USAGE_SAMPLED_BIT
6476													| VK_IMAGE_USAGE_STORAGE_BIT
6477													| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
6478													| VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
6479													| VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
6480													| VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
6481	const VkImageCreateFlags		allCreateFlags	= VK_IMAGE_CREATE_SPARSE_BINDING_BIT
6482													| VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT
6483													| VK_IMAGE_CREATE_SPARSE_ALIASED_BIT
6484													| VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
6485													| VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT
6486													| ycbcrFlags;
6487
6488	for (VkImageUsageFlags curUsageFlags = (VkImageUsageFlags)1; curUsageFlags <= allUsageFlags; curUsageFlags++)
6489	{
6490		if (!isValidImageUsageFlagCombination(curUsageFlags))
6491			continue;
6492
6493		for (VkImageCreateFlags curCreateFlags = 0; curCreateFlags <= allCreateFlags; curCreateFlags++)
6494		{
6495			const VkPhysicalDeviceImageFormatInfo2	imageFormatInfo	=
6496			{
6497				VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
6498				DE_NULL,
6499				format,
6500				imageType,
6501				tiling,
6502				curUsageFlags,
6503				curCreateFlags
6504			};
6505
6506			VkImageFormatProperties						coreProperties;
6507			VkImageFormatProperties2					extProperties;
6508			VkResult									coreResult;
6509			VkResult									extResult;
6510
6511			deMemset(&coreProperties, 0xcd, sizeof(VkImageFormatProperties));
6512			deMemset(&extProperties, 0xcd, sizeof(VkImageFormatProperties2));
6513
6514			extProperties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
6515			extProperties.pNext = DE_NULL;
6516
6517			coreResult	= vki.getPhysicalDeviceImageFormatProperties(physicalDevice, imageFormatInfo.format, imageFormatInfo.type, imageFormatInfo.tiling, imageFormatInfo.usage, imageFormatInfo.flags, &coreProperties);
6518			extResult	= vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &imageFormatInfo, &extProperties);
6519
6520			TCU_CHECK(extProperties.sType == VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2);
6521			TCU_CHECK(extProperties.pNext == DE_NULL);
6522
6523			if ((coreResult != extResult) ||
6524				(deMemCmp(&coreProperties, &extProperties.imageFormatProperties, sizeof(VkImageFormatProperties)) != 0))
6525			{
6526				log << TestLog::Message << "ERROR: device mismatch with query " << imageFormatInfo << TestLog::EndMessage
6527					<< TestLog::Message << "vkGetPhysicalDeviceImageFormatProperties() returned " << coreResult << ", " << coreProperties << TestLog::EndMessage
6528					<< TestLog::Message << "vkGetPhysicalDeviceImageFormatProperties2() returned " << extResult << ", " << extProperties << TestLog::EndMessage;
6529				TCU_FAIL("Mismatch between image format properties reported by vkGetPhysicalDeviceImageFormatProperties and vkGetPhysicalDeviceImageFormatProperties2");
6530			}
6531		}
6532	}
6533
6534	return tcu::TestStatus::pass("Querying image format properties succeeded");
6535}
6536
6537#ifndef CTS_USES_VULKANSC
6538tcu::TestStatus sparseImageFormatProperties2 (Context& context, const VkFormat format, const VkImageType imageType, const VkImageTiling tiling)
6539{
6540	TestLog&						log				= context.getTestContext().getLog();
6541
6542	const CustomInstance			instance		(createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2"));
6543	const InstanceDriver&			vki				(instance.getDriver());
6544	const VkPhysicalDevice			physicalDevice	(chooseDevice(vki, instance, context.getTestContext().getCommandLine()));
6545
6546	const VkImageUsageFlags			allUsageFlags	= VK_IMAGE_USAGE_TRANSFER_SRC_BIT
6547													| VK_IMAGE_USAGE_TRANSFER_DST_BIT
6548													| VK_IMAGE_USAGE_SAMPLED_BIT
6549													| VK_IMAGE_USAGE_STORAGE_BIT
6550													| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
6551													| VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
6552													| VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
6553													| VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
6554
6555	for (deUint32 sampleCountBit = VK_SAMPLE_COUNT_1_BIT; sampleCountBit <= VK_SAMPLE_COUNT_64_BIT; sampleCountBit = (sampleCountBit << 1u))
6556	{
6557		for (VkImageUsageFlags curUsageFlags = (VkImageUsageFlags)1; curUsageFlags <= allUsageFlags; curUsageFlags++)
6558		{
6559			if (!isValidImageUsageFlagCombination(curUsageFlags))
6560				continue;
6561
6562			const VkPhysicalDeviceSparseImageFormatInfo2	imageFormatInfo	=
6563			{
6564				VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2,
6565				DE_NULL,
6566				format,
6567				imageType,
6568				(VkSampleCountFlagBits)sampleCountBit,
6569				curUsageFlags,
6570				tiling,
6571			};
6572
6573			deUint32	numCoreProperties	= 0u;
6574			deUint32	numExtProperties	= 0u;
6575
6576			// Query count
6577			vki.getPhysicalDeviceSparseImageFormatProperties(physicalDevice, imageFormatInfo.format, imageFormatInfo.type, imageFormatInfo.samples, imageFormatInfo.usage, imageFormatInfo.tiling, &numCoreProperties, DE_NULL);
6578			vki.getPhysicalDeviceSparseImageFormatProperties2(physicalDevice, &imageFormatInfo, &numExtProperties, DE_NULL);
6579
6580			if (numCoreProperties != numExtProperties)
6581			{
6582				log << TestLog::Message << "ERROR: different number of properties reported for " << imageFormatInfo << TestLog::EndMessage;
6583				TCU_FAIL("Mismatch in reported property count");
6584			}
6585
6586			if (!context.getDeviceFeatures().sparseBinding)
6587			{
6588				// There is no support for sparse binding, getPhysicalDeviceSparseImageFormatProperties* MUST report no properties
6589				// Only have to check one of the entrypoints as a mismatch in count is already caught.
6590				if (numCoreProperties > 0)
6591				{
6592					log << TestLog::Message << "ERROR: device does not support sparse binding but claims support for " << numCoreProperties << " properties in vkGetPhysicalDeviceSparseImageFormatProperties with parameters " << imageFormatInfo << TestLog::EndMessage;
6593					TCU_FAIL("Claimed format properties inconsistent with overall sparseBinding feature");
6594				}
6595			}
6596
6597			if (numCoreProperties > 0)
6598			{
6599				std::vector<VkSparseImageFormatProperties>		coreProperties	(numCoreProperties);
6600				std::vector<VkSparseImageFormatProperties2>		extProperties	(numExtProperties);
6601
6602				deMemset(&coreProperties[0], 0xcd, sizeof(VkSparseImageFormatProperties)*numCoreProperties);
6603				deMemset(&extProperties[0], 0xcd, sizeof(VkSparseImageFormatProperties2)*numExtProperties);
6604
6605				for (deUint32 ndx = 0; ndx < numExtProperties; ++ndx)
6606				{
6607					extProperties[ndx].sType = VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2;
6608					extProperties[ndx].pNext = DE_NULL;
6609				}
6610
6611				vki.getPhysicalDeviceSparseImageFormatProperties(physicalDevice, imageFormatInfo.format, imageFormatInfo.type, imageFormatInfo.samples, imageFormatInfo.usage, imageFormatInfo.tiling, &numCoreProperties, &coreProperties[0]);
6612				vki.getPhysicalDeviceSparseImageFormatProperties2(physicalDevice, &imageFormatInfo, &numExtProperties, &extProperties[0]);
6613
6614				TCU_CHECK((size_t)numCoreProperties == coreProperties.size());
6615				TCU_CHECK((size_t)numExtProperties == extProperties.size());
6616
6617				for (deUint32 ndx = 0; ndx < numCoreProperties; ++ndx)
6618				{
6619					TCU_CHECK(extProperties[ndx].sType == VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2);
6620					TCU_CHECK(extProperties[ndx].pNext == DE_NULL);
6621
6622					if ((deMemCmp(&coreProperties[ndx], &extProperties[ndx].properties, sizeof(VkSparseImageFormatProperties)) != 0))
6623					{
6624						log << TestLog::Message << "ERROR: device mismatch with query " << imageFormatInfo << " property " << ndx << TestLog::EndMessage
6625							<< TestLog::Message << "vkGetPhysicalDeviceSparseImageFormatProperties() returned " << coreProperties[ndx] << TestLog::EndMessage
6626							<< TestLog::Message << "vkGetPhysicalDeviceSparseImageFormatProperties2() returned " << extProperties[ndx] << TestLog::EndMessage;
6627						TCU_FAIL("Mismatch between image format properties reported by vkGetPhysicalDeviceSparseImageFormatProperties and vkGetPhysicalDeviceSparseImageFormatProperties2");
6628					}
6629				}
6630			}
6631		}
6632	}
6633
6634	return tcu::TestStatus::pass("Querying sparse image format properties succeeded");
6635}
6636#endif // CTS_USES_VULKANSC
6637
6638tcu::TestStatus execImageFormatTest (Context& context, ImageFormatPropertyCase testCase)
6639{
6640	return testCase.testFunction(context, testCase.format, testCase.imageType, testCase.tiling);
6641}
6642
6643void createImageFormatTypeTilingTests (tcu::TestCaseGroup* testGroup, ImageFormatPropertyCase params)
6644{
6645	DE_ASSERT(params.format == VK_FORMAT_UNDEFINED);
6646
6647	static const struct
6648	{
6649		VkFormat								begin;
6650		VkFormat								end;
6651		ImageFormatPropertyCase					params;
6652	} s_formatRanges[] =
6653	{
6654		// core formats
6655		{ (VkFormat)(VK_FORMAT_UNDEFINED + 1),		VK_CORE_FORMAT_LAST,										params },
6656
6657		// YCbCr formats
6658		{ VK_FORMAT_G8B8G8R8_422_UNORM,				(VkFormat)(VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM + 1),	params },
6659
6660		// YCbCr extended formats
6661		{ VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT,	(VkFormat)(VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT+1),	params },
6662	};
6663
6664	for (int rangeNdx = 0; rangeNdx < DE_LENGTH_OF_ARRAY(s_formatRanges); ++rangeNdx)
6665	{
6666		const VkFormat								rangeBegin		= s_formatRanges[rangeNdx].begin;
6667		const VkFormat								rangeEnd		= s_formatRanges[rangeNdx].end;
6668
6669		for (VkFormat format = rangeBegin; format != rangeEnd; format = (VkFormat)(format+1))
6670		{
6671			const bool			isYCbCr		= isYCbCrFormat(format);
6672#ifndef CTS_USES_VULKANSC
6673			const bool			isSparse = (params.testFunction == sparseImageFormatProperties2);
6674#else
6675			const bool			isSparse = false;
6676#endif // CTS_USES_VULKANSC
6677
6678			if (isYCbCr && isSparse)
6679				continue;
6680
6681			if (isYCbCr && params.imageType != VK_IMAGE_TYPE_2D)
6682				continue;
6683
6684			const char* const	enumName	= getFormatName(format);
6685			const string		caseName	= de::toLower(string(enumName).substr(10));
6686
6687			params.format = format;
6688
6689			addFunctionCase(testGroup, caseName, execImageFormatTest, params);
6690		}
6691	}
6692}
6693
6694void createImageFormatTypeTests (tcu::TestCaseGroup* testGroup, ImageFormatPropertyCase params)
6695{
6696	DE_ASSERT(params.tiling == VK_CORE_IMAGE_TILING_LAST);
6697
6698	testGroup->addChild(createTestGroup(testGroup->getTestContext(), "optimal",	createImageFormatTypeTilingTests, ImageFormatPropertyCase(params.testFunction, VK_FORMAT_UNDEFINED, params.imageType, VK_IMAGE_TILING_OPTIMAL)));
6699	testGroup->addChild(createTestGroup(testGroup->getTestContext(), "linear",	createImageFormatTypeTilingTests, ImageFormatPropertyCase(params.testFunction, VK_FORMAT_UNDEFINED, params.imageType, VK_IMAGE_TILING_LINEAR)));
6700}
6701
6702void createImageFormatTests (tcu::TestCaseGroup* testGroup, ImageFormatPropertyCase::Function testFunction)
6703{
6704	testGroup->addChild(createTestGroup(testGroup->getTestContext(), "1d", createImageFormatTypeTests, ImageFormatPropertyCase(testFunction, VK_FORMAT_UNDEFINED, VK_IMAGE_TYPE_1D, VK_CORE_IMAGE_TILING_LAST)));
6705	testGroup->addChild(createTestGroup(testGroup->getTestContext(), "2d", createImageFormatTypeTests, ImageFormatPropertyCase(testFunction, VK_FORMAT_UNDEFINED, VK_IMAGE_TYPE_2D, VK_CORE_IMAGE_TILING_LAST)));
6706	testGroup->addChild(createTestGroup(testGroup->getTestContext(), "3d", createImageFormatTypeTests, ImageFormatPropertyCase(testFunction, VK_FORMAT_UNDEFINED, VK_IMAGE_TYPE_3D, VK_CORE_IMAGE_TILING_LAST)));
6707}
6708
6709
6710// Android CTS -specific tests
6711
6712namespace android
6713{
6714
6715void checkSupportAndroid (Context&)
6716{
6717#if (DE_OS != DE_OS_ANDROID)
6718	TCU_THROW(NotSupportedError, "Test is only for Android");
6719#endif
6720}
6721
6722void checkExtensions (tcu::ResultCollector& results, const set<string>& allowedExtensions, const vector<VkExtensionProperties>& reportedExtensions)
6723{
6724	for (vector<VkExtensionProperties>::const_iterator extension = reportedExtensions.begin(); extension != reportedExtensions.end(); ++extension)
6725	{
6726		const string	extensionName	(extension->extensionName);
6727		const bool		mustBeKnown		= de::beginsWith(extensionName, "VK_GOOGLE_")	||
6728										  de::beginsWith(extensionName, "VK_ANDROID_");
6729
6730		if (mustBeKnown && !de::contains(allowedExtensions, extensionName))
6731			results.fail("Unknown extension: " + extensionName);
6732	}
6733}
6734
6735tcu::TestStatus testNoUnknownExtensions (Context& context)
6736{
6737	TestLog&				log					= context.getTestContext().getLog();
6738	tcu::ResultCollector	results				(log);
6739	set<string>				allowedInstanceExtensions;
6740	set<string>				allowedDeviceExtensions;
6741
6742	// All known extensions should be added to allowedExtensions:
6743	// allowedExtensions.insert("VK_GOOGLE_extension1");
6744	allowedDeviceExtensions.insert("VK_ANDROID_external_memory_android_hardware_buffer");
6745	allowedDeviceExtensions.insert("VK_GOOGLE_display_timing");
6746	allowedDeviceExtensions.insert("VK_GOOGLE_decorate_string");
6747	allowedDeviceExtensions.insert("VK_GOOGLE_hlsl_functionality1");
6748	allowedDeviceExtensions.insert("VK_GOOGLE_user_type");
6749	allowedInstanceExtensions.insert("VK_GOOGLE_surfaceless_query");
6750
6751	// Instance extensions
6752	checkExtensions(results,
6753					allowedInstanceExtensions,
6754					enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL));
6755
6756	// Extensions exposed by instance layers
6757	{
6758		const vector<VkLayerProperties>	layers	= enumerateInstanceLayerProperties(context.getPlatformInterface());
6759
6760		for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
6761		{
6762			checkExtensions(results,
6763							allowedInstanceExtensions,
6764							enumerateInstanceExtensionProperties(context.getPlatformInterface(), layer->layerName));
6765		}
6766	}
6767
6768	// Device extensions
6769	checkExtensions(results,
6770					allowedDeviceExtensions,
6771					enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), DE_NULL));
6772
6773	// Extensions exposed by device layers
6774	{
6775		const vector<VkLayerProperties>	layers	= enumerateDeviceLayerProperties(context.getInstanceInterface(), context.getPhysicalDevice());
6776
6777		for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
6778		{
6779			checkExtensions(results,
6780							allowedDeviceExtensions,
6781							enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), layer->layerName));
6782		}
6783	}
6784
6785	return tcu::TestStatus(results.getResult(), results.getMessage());
6786}
6787
6788tcu::TestStatus testNoLayers (Context& context)
6789{
6790	TestLog&				log		= context.getTestContext().getLog();
6791	tcu::ResultCollector	results	(log);
6792
6793	{
6794		const vector<VkLayerProperties>	layers	= enumerateInstanceLayerProperties(context.getPlatformInterface());
6795
6796		for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
6797			results.fail(string("Instance layer enumerated: ") + layer->layerName);
6798	}
6799
6800	{
6801		const vector<VkLayerProperties>	layers	= enumerateDeviceLayerProperties(context.getInstanceInterface(), context.getPhysicalDevice());
6802
6803		for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
6804			results.fail(string("Device layer enumerated: ") + layer->layerName);
6805	}
6806
6807	return tcu::TestStatus(results.getResult(), results.getMessage());
6808}
6809
6810tcu::TestStatus testMandatoryExtensions (Context& context)
6811{
6812	TestLog&				log		= context.getTestContext().getLog();
6813	tcu::ResultCollector	results	(log);
6814
6815	// Instance extensions
6816	{
6817		static const string mandatoryExtensions[]	=
6818		{
6819			"VK_KHR_get_physical_device_properties2",
6820		};
6821
6822		for (const auto &ext : mandatoryExtensions)
6823		{
6824			if (!context.isInstanceFunctionalitySupported(ext))
6825				results.fail(ext + " is not supported");
6826		}
6827	}
6828
6829	// Device extensions
6830	{
6831		static const string mandatoryExtensions[] =
6832		{
6833			"VK_KHR_maintenance1",
6834		};
6835
6836		for (const auto &ext : mandatoryExtensions)
6837		{
6838			if (!context.isDeviceFunctionalitySupported(ext))
6839				results.fail(ext + " is not supported");
6840		}
6841	}
6842
6843	return tcu::TestStatus(results.getResult(), results.getMessage());
6844}
6845
6846} // android
6847
6848} // anonymous
6849
6850static inline void addFunctionCaseInNewSubgroup (
6851	tcu::TestContext&			testCtx,
6852	tcu::TestCaseGroup*			group,
6853	const std::string&			subgroupName,
6854	FunctionInstance0::Function	testFunc)
6855{
6856	de::MovePtr<tcu::TestCaseGroup>	subgroup(new tcu::TestCaseGroup(testCtx, subgroupName.c_str()));
6857	addFunctionCase(subgroup.get(), "basic", testFunc);
6858	group->addChild(subgroup.release());
6859}
6860
6861tcu::TestCaseGroup* createFeatureInfoTests (tcu::TestContext& testCtx)
6862{
6863	de::MovePtr<tcu::TestCaseGroup>	infoTests	(new tcu::TestCaseGroup(testCtx, "info"));
6864
6865	infoTests->addChild(createTestGroup(testCtx, "format_properties",		createFormatTests));
6866	infoTests->addChild(createTestGroup(testCtx, "image_format_properties",	createImageFormatTests,	imageFormatProperties));
6867
6868	{
6869		de::MovePtr<tcu::TestCaseGroup> extCoreVersionGrp (new tcu::TestCaseGroup(testCtx, "extension_core_versions"));
6870
6871		addFunctionCase(extCoreVersionGrp.get(), "extension_core_versions", extensionCoreVersions);
6872
6873		infoTests->addChild(extCoreVersionGrp.release());
6874	}
6875
6876	{
6877		de::MovePtr<tcu::TestCaseGroup> extendedPropertiesTests (new tcu::TestCaseGroup(testCtx, "get_physical_device_properties2"));
6878
6879		{
6880			de::MovePtr<tcu::TestCaseGroup>	subgroup(new tcu::TestCaseGroup(testCtx, "features", ""));
6881			// Extended Device Features
6882			addFunctionCase(subgroup.get(), "core", deviceFeatures2);
6883			addSeparateFeatureTests(subgroup.get());
6884			extendedPropertiesTests->addChild(subgroup.release());
6885		}
6886		addFunctionCaseInNewSubgroup(testCtx, extendedPropertiesTests.get(), "properties",				deviceProperties2);
6887		addFunctionCaseInNewSubgroup(testCtx, extendedPropertiesTests.get(), "format_properties",			deviceFormatProperties2);
6888		addFunctionCaseInNewSubgroup(testCtx, extendedPropertiesTests.get(), "queue_family_properties",	deviceQueueFamilyProperties2);
6889		addFunctionCaseInNewSubgroup(testCtx, extendedPropertiesTests.get(), "memory_properties",			deviceMemoryProperties2);
6890
6891		infoTests->addChild(extendedPropertiesTests.release());
6892	}
6893
6894	{
6895		// Vulkan 1.2 related tests
6896		de::MovePtr<tcu::TestCaseGroup> extendedPropertiesTests (new tcu::TestCaseGroup(testCtx, "vulkan1p2"));
6897
6898		addFunctionCase(extendedPropertiesTests.get(), "features",							deviceFeaturesVulkan12);
6899		addFunctionCase(extendedPropertiesTests.get(), "properties",						devicePropertiesVulkan12);
6900		addFunctionCase(extendedPropertiesTests.get(), "feature_extensions_consistency",	deviceFeatureExtensionsConsistencyVulkan12);
6901		addFunctionCase(extendedPropertiesTests.get(), "property_extensions_consistency",	devicePropertyExtensionsConsistencyVulkan12);
6902		addFunctionCase(extendedPropertiesTests.get(), "feature_bits_influence",			checkApiVersionSupport<1,2>, featureBitInfluenceOnDeviceCreate<VK_API_VERSION_1_2>);
6903
6904		infoTests->addChild(extendedPropertiesTests.release());
6905	}
6906
6907#ifndef CTS_USES_VULKANSC
6908	{
6909		de::MovePtr<tcu::TestCaseGroup> extendedPropertiesTests (new tcu::TestCaseGroup(testCtx, "vulkan1p3", "Vulkan 1.3 related tests"));
6910
6911		addFunctionCase(extendedPropertiesTests.get(), "features",							deviceFeaturesVulkan13);
6912		addFunctionCase(extendedPropertiesTests.get(), "properties",						devicePropertiesVulkan13);
6913		addFunctionCase(extendedPropertiesTests.get(), "feature_extensions_consistency",	deviceFeatureExtensionsConsistencyVulkan13);
6914		addFunctionCase(extendedPropertiesTests.get(), "property_extensions_consistency",	devicePropertyExtensionsConsistencyVulkan13);
6915		addFunctionCase(extendedPropertiesTests.get(), "feature_bits_influence",			checkApiVersionSupport<1, 3>, featureBitInfluenceOnDeviceCreate<VK_API_VERSION_1_3>);
6916
6917		infoTests->addChild(extendedPropertiesTests.release());
6918	}
6919#endif // CTS_USES_VULKANSC
6920
6921	{
6922		de::MovePtr<tcu::TestCaseGroup> limitsValidationTests (new tcu::TestCaseGroup(testCtx, "vulkan1p2_limits_validation", "Vulkan 1.2 and core extensions limits validation"));
6923
6924		addFunctionCase(limitsValidationTests.get(), "general",							checkApiVersionSupport<1, 2>,				validateLimits12);
6925#ifndef CTS_USES_VULKANSC
6926		// Removed from Vulkan SC test set: VK_KHR_push_descriptor extension removed from Vulkan SC
6927		addFunctionCase(limitsValidationTests.get(), "khr_push_descriptor",				checkSupportKhrPushDescriptor,				validateLimitsKhrPushDescriptor);
6928#endif // CTS_USES_VULKANSC
6929		addFunctionCase(limitsValidationTests.get(), "khr_multiview",					checkSupportKhrMultiview,					validateLimitsKhrMultiview);
6930		addFunctionCase(limitsValidationTests.get(), "ext_discard_rectangles",			checkSupportExtDiscardRectangles,			validateLimitsExtDiscardRectangles);
6931		addFunctionCase(limitsValidationTests.get(), "ext_sample_locations",			checkSupportExtSampleLocations,				validateLimitsExtSampleLocations);
6932		addFunctionCase(limitsValidationTests.get(), "ext_external_memory_host",		checkSupportExtExternalMemoryHost,			validateLimitsExtExternalMemoryHost);
6933		addFunctionCase(limitsValidationTests.get(), "ext_blend_operation_advanced",	checkSupportExtBlendOperationAdvanced,		validateLimitsExtBlendOperationAdvanced);
6934		addFunctionCase(limitsValidationTests.get(), "khr_maintenance_3",				checkSupportKhrMaintenance3,				validateLimitsKhrMaintenance3);
6935		addFunctionCase(limitsValidationTests.get(), "ext_conservative_rasterization",	checkSupportExtConservativeRasterization,	validateLimitsExtConservativeRasterization);
6936		addFunctionCase(limitsValidationTests.get(), "ext_descriptor_indexing",			checkSupportExtDescriptorIndexing,			validateLimitsExtDescriptorIndexing);
6937#ifndef CTS_USES_VULKANSC
6938		// Removed from Vulkan SC test set: VK_EXT_inline_uniform_block extension removed from Vulkan SC
6939		addFunctionCase(limitsValidationTests.get(), "ext_inline_uniform_block",		checkSupportExtInlineUniformBlock,			validateLimitsExtInlineUniformBlock);
6940#endif // CTS_USES_VULKANSC
6941		addFunctionCase(limitsValidationTests.get(), "ext_vertex_attribute_divisor",	checkSupportExtVertexAttributeDivisor,		validateLimitsExtVertexAttributeDivisor);
6942#ifndef CTS_USES_VULKANSC
6943		// Removed from Vulkan SC test set: extensions VK_NV_mesh_shader, VK_EXT_transform_feedback, VK_EXT_fragment_density_map, VK_NV_ray_tracing extension removed from Vulkan SC
6944		addFunctionCase(limitsValidationTests.get(), "nv_mesh_shader",					checkSupportNvMeshShader,					validateLimitsNvMeshShader);
6945		addFunctionCase(limitsValidationTests.get(), "ext_transform_feedback",			checkSupportExtTransformFeedback,			validateLimitsExtTransformFeedback);
6946		addFunctionCase(limitsValidationTests.get(), "fragment_density_map",			checkSupportExtFragmentDensityMap,			validateLimitsExtFragmentDensityMap);
6947		addFunctionCase(limitsValidationTests.get(), "nv_ray_tracing",					checkSupportNvRayTracing,					validateLimitsNvRayTracing);
6948#endif
6949		addFunctionCase(limitsValidationTests.get(), "timeline_semaphore",				checkSupportKhrTimelineSemaphore,			validateLimitsKhrTimelineSemaphore);
6950		addFunctionCase(limitsValidationTests.get(), "ext_line_rasterization",			checkSupportExtLineRasterization,			validateLimitsExtLineRasterization);
6951		addFunctionCase(limitsValidationTests.get(), "robustness2",						checkSupportRobustness2,					validateLimitsRobustness2);
6952
6953		infoTests->addChild(limitsValidationTests.release());
6954	}
6955
6956	{
6957		de::MovePtr<tcu::TestCaseGroup> limitsValidationTests(new tcu::TestCaseGroup(testCtx, "vulkan1p3_limits_validation", "Vulkan 1.3 and core extensions limits validation"));
6958
6959#ifndef CTS_USES_VULKANSC
6960		addFunctionCase(limitsValidationTests.get(), "khr_maintenance4",				checkSupportKhrMaintenance4,				validateLimitsKhrMaintenance4);
6961		addFunctionCase(limitsValidationTests.get(), "max_inline_uniform_total_size",	checkApiVersionSupport<1, 3>,				validateLimitsMaxInlineUniformTotalSize);
6962#endif // CTS_USES_VULKANSC
6963
6964		infoTests->addChild(limitsValidationTests.release());
6965	}
6966
6967	infoTests->addChild(createTestGroup(testCtx, "image_format_properties2",		createImageFormatTests, imageFormatProperties2));
6968#ifndef CTS_USES_VULKANSC
6969	infoTests->addChild(createTestGroup(testCtx, "sparse_image_format_properties2",	createImageFormatTests, sparseImageFormatProperties2));
6970
6971	{
6972		de::MovePtr<tcu::TestCaseGroup> profilesValidationTests(new tcu::TestCaseGroup(testCtx, "profiles"));
6973
6974		// Limits and features check for roadmap 2022
6975		addFunctionCase(profilesValidationTests.get(), "roadmap_2022", checkApiVersionSupport<1, 3>, validateRoadmap2022);
6976
6977		infoTests->addChild(profilesValidationTests.release());
6978	}
6979#endif // CTS_USES_VULKANSC
6980
6981	{
6982		de::MovePtr<tcu::TestCaseGroup>	androidTests	(new tcu::TestCaseGroup(testCtx, "android", "Android CTS Tests"));
6983
6984		// Test that all mandatory extensions are supported
6985		addFunctionCase(androidTests.get(),	"mandatory_extensions", android::checkSupportAndroid,	android::testMandatoryExtensions);
6986		// Test for unknown device or instance extensions
6987		addFunctionCase(androidTests.get(), "no_unknown_extensions", android::checkSupportAndroid,	android::testNoUnknownExtensions);
6988		// Test that no layers are enumerated
6989		addFunctionCase(androidTests.get(), "no_layers", android::checkSupportAndroid,	android::testNoLayers);
6990
6991		infoTests->addChild(androidTests.release());
6992	}
6993
6994	return infoTests.release();
6995}
6996
6997void createFeatureInfoInstanceTests(tcu::TestCaseGroup* testGroup)
6998{
6999	addFunctionCase(testGroup, "physical_devices",						enumeratePhysicalDevices);
7000	addFunctionCase(testGroup, "physical_device_groups",				enumeratePhysicalDeviceGroups);
7001	addFunctionCase(testGroup, "instance_layers",								enumerateInstanceLayers);
7002	addFunctionCase(testGroup, "instance_extensions",							enumerateInstanceExtensions);
7003	addFunctionCase(testGroup, "instance_extension_device_functions",	validateDeviceLevelEntryPointsFromInstanceExtensions);
7004}
7005
7006void createFeatureInfoDeviceTests(tcu::TestCaseGroup* testGroup)
7007{
7008	addFunctionCase(testGroup, "device_features",						deviceFeatures);
7009	addFunctionCase(testGroup, "device_properties",					deviceProperties);
7010	addFunctionCase(testGroup, "device_queue_family_properties",				deviceQueueFamilyProperties);
7011	addFunctionCase(testGroup, "device_memory_properties",					deviceMemoryProperties);
7012	addFunctionCase(testGroup, "device_layers",								enumerateDeviceLayers);
7013	addFunctionCase(testGroup, "device_extensions",							enumerateDeviceExtensions);
7014	addFunctionCase(testGroup, "device_no_khx_extensions",						testNoKhxExtensions);
7015	addFunctionCase(testGroup, "device_memory_budget",						deviceMemoryBudgetProperties);
7016	addFunctionCase(testGroup, "device_mandatory_features",					deviceMandatoryFeatures);
7017}
7018
7019void createFeatureInfoDeviceGroupTests(tcu::TestCaseGroup* testGroup)
7020{
7021	addFunctionCase(testGroup, "device_group_peer_memory_features",	deviceGroupPeerMemoryFeatures);
7022}
7023
7024} // api
7025} // vkt
7026