• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
29 #include "vkPlatform.hpp"
30 #include "vkStrUtil.hpp"
31 #include "vkRef.hpp"
32 #include "vkRefUtil.hpp"
33 #include "vkDeviceUtil.hpp"
34 #include "vkQueryUtil.hpp"
35 #include "vkImageUtil.hpp"
36 #include "vkApiVersion.hpp"
37 
38 #include "tcuTestLog.hpp"
39 #include "tcuFormatUtil.hpp"
40 #include "tcuTextureUtil.hpp"
41 #include "tcuResultCollector.hpp"
42 #include "tcuCommandLine.hpp"
43 
44 #include "deUniquePtr.hpp"
45 #include "deString.h"
46 #include "deStringUtil.hpp"
47 #include "deSTLUtil.hpp"
48 #include "deMemory.h"
49 #include "deMath.h"
50 
51 #include <vector>
52 #include <set>
53 #include <string>
54 
55 namespace vkt
56 {
57 namespace api
58 {
59 namespace
60 {
61 
62 #include "vkApiExtensionDependencyInfo.inl"
63 
64 using namespace vk;
65 using std::vector;
66 using std::set;
67 using std::string;
68 using tcu::TestLog;
69 using tcu::ScopedLogSection;
70 
71 enum
72 {
73 	GUARD_SIZE								= 0x20,			//!< Number of bytes to check
74 	GUARD_VALUE								= 0xcd,			//!< Data pattern
75 };
76 
77 static const VkDeviceSize MINIMUM_REQUIRED_IMAGE_RESOURCE_SIZE =	(1LLU<<31);	//!< Minimum value for VkImageFormatProperties::maxResourceSize (2GiB)
78 
79 enum LimitFormat
80 {
81 	LIMIT_FORMAT_SIGNED_INT,
82 	LIMIT_FORMAT_UNSIGNED_INT,
83 	LIMIT_FORMAT_FLOAT,
84 	LIMIT_FORMAT_DEVICE_SIZE,
85 	LIMIT_FORMAT_BITMASK,
86 
87 	LIMIT_FORMAT_LAST
88 };
89 
90 enum LimitType
91 {
92 	LIMIT_TYPE_MIN,
93 	LIMIT_TYPE_MAX,
94 	LIMIT_TYPE_NONE,
95 
96 	LIMIT_TYPE_LAST
97 };
98 
99 #define LIMIT(_X_)		DE_OFFSET_OF(VkPhysicalDeviceLimits, _X_), (const char*)(#_X_)
100 #define FEATURE(_X_)	DE_OFFSET_OF(VkPhysicalDeviceFeatures, _X_)
101 
validateFeatureLimits(VkPhysicalDeviceProperties * properties,VkPhysicalDeviceFeatures * features,TestLog & log)102 bool validateFeatureLimits(VkPhysicalDeviceProperties* properties, VkPhysicalDeviceFeatures* features, TestLog& log)
103 {
104 	bool						limitsOk				= true;
105 	VkPhysicalDeviceLimits*		limits					= &properties->limits;
106 	deUint32					shaderStages			= 3;
107 	deUint32					maxPerStageResourcesMin	= deMin32(128,	limits->maxPerStageDescriptorUniformBuffers		+
108 																		limits->maxPerStageDescriptorStorageBuffers		+
109 																		limits->maxPerStageDescriptorSampledImages		+
110 																		limits->maxPerStageDescriptorStorageImages		+
111 																		limits->maxPerStageDescriptorInputAttachments	+
112 																		limits->maxColorAttachments);
113 
114 	if (features->tessellationShader)
115 	{
116 		shaderStages += 2;
117 	}
118 
119 	if (features->geometryShader)
120 	{
121 		shaderStages++;
122 	}
123 
124 	struct FeatureLimitTable
125 	{
126 		deUint32		offset;
127 		const char*		name;
128 		deUint32		uintVal;			//!< Format is UNSIGNED_INT
129 		deInt32			intVal;				//!< Format is SIGNED_INT
130 		deUint64		deviceSizeVal;		//!< Format is DEVICE_SIZE
131 		float			floatVal;			//!< Format is FLOAT
132 		LimitFormat		format;
133 		LimitType		type;
134 		deInt32			unsuppTableNdx;
135 	} featureLimitTable[] =   //!< Based on 1.0.28 Vulkan spec
136 	{
137 		{ LIMIT(maxImageDimension1D),								4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
138 		{ LIMIT(maxImageDimension2D),								4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
139 		{ LIMIT(maxImageDimension3D),								256, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
140 		{ LIMIT(maxImageDimensionCube),								4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
141 		{ LIMIT(maxImageArrayLayers),								256, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN   , -1 },
142 		{ LIMIT(maxTexelBufferElements),							65536, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
143 		{ LIMIT(maxUniformBufferRange),								16384, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
144 		{ LIMIT(maxStorageBufferRange),								134217728, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
145 		{ LIMIT(maxPushConstantsSize),								128, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
146 		{ LIMIT(maxMemoryAllocationCount),							4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
147 		{ LIMIT(maxSamplerAllocationCount),							4000, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
148 		{ LIMIT(bufferImageGranularity),							0, 0, 1, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1 },
149 		{ LIMIT(bufferImageGranularity),							0, 0, 131072, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MAX, -1 },
150 		{ LIMIT(sparseAddressSpaceSize),							0, 0, 2UL*1024*1024*1024, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1 },
151 		{ LIMIT(maxBoundDescriptorSets),							4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
152 		{ LIMIT(maxPerStageDescriptorSamplers),						16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
153 		{ LIMIT(maxPerStageDescriptorUniformBuffers),				12, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
154 		{ LIMIT(maxPerStageDescriptorStorageBuffers),				4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
155 		{ LIMIT(maxPerStageDescriptorSampledImages),				16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
156 		{ LIMIT(maxPerStageDescriptorStorageImages),				4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
157 		{ LIMIT(maxPerStageDescriptorInputAttachments),				4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
158 		{ LIMIT(maxPerStageResources),								maxPerStageResourcesMin, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
159 		{ LIMIT(maxDescriptorSetSamplers),							shaderStages * 16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
160 		{ LIMIT(maxDescriptorSetUniformBuffers),					shaderStages * 12, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
161 		{ LIMIT(maxDescriptorSetUniformBuffersDynamic),				8, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
162 		{ LIMIT(maxDescriptorSetStorageBuffers),					shaderStages * 4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
163 		{ LIMIT(maxDescriptorSetStorageBuffersDynamic),				4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
164 		{ LIMIT(maxDescriptorSetSampledImages),						shaderStages * 16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
165 		{ LIMIT(maxDescriptorSetStorageImages),						shaderStages * 4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
166 		{ LIMIT(maxDescriptorSetInputAttachments),					4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
167 		{ LIMIT(maxVertexInputAttributes),							16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
168 		{ LIMIT(maxVertexInputBindings),							16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
169 		{ LIMIT(maxVertexInputAttributeOffset),						2047, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
170 		{ LIMIT(maxVertexInputBindingStride),						2048, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
171 		{ LIMIT(maxVertexOutputComponents),							64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
172 		{ LIMIT(maxTessellationGenerationLevel),					64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
173 		{ LIMIT(maxTessellationPatchSize),							32, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
174 		{ LIMIT(maxTessellationControlPerVertexInputComponents),	64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
175 		{ LIMIT(maxTessellationControlPerVertexOutputComponents),	64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
176 		{ LIMIT(maxTessellationControlPerPatchOutputComponents),	120, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
177 		{ LIMIT(maxTessellationControlTotalOutputComponents),		2048, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
178 		{ LIMIT(maxTessellationEvaluationInputComponents),			64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
179 		{ LIMIT(maxTessellationEvaluationOutputComponents),			64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
180 		{ LIMIT(maxGeometryShaderInvocations),						32, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
181 		{ LIMIT(maxGeometryInputComponents),						64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
182 		{ LIMIT(maxGeometryOutputComponents),						64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
183 		{ LIMIT(maxGeometryOutputVertices),							256, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
184 		{ LIMIT(maxGeometryTotalOutputComponents),					1024, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
185 		{ LIMIT(maxFragmentInputComponents),						64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
186 		{ LIMIT(maxFragmentOutputAttachments),						4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
187 		{ LIMIT(maxFragmentDualSrcAttachments),						1, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
188 		{ LIMIT(maxFragmentCombinedOutputResources),				4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN  , -1 },
189 		{ LIMIT(maxComputeSharedMemorySize),						16384, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN   , -1 },
190 		{ LIMIT(maxComputeWorkGroupCount[0]),						65535, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN   , -1 },
191 		{ LIMIT(maxComputeWorkGroupCount[1]),						65535, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN   , -1 },
192 		{ LIMIT(maxComputeWorkGroupCount[2]),						65535,  0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN   , -1 },
193 		{ LIMIT(maxComputeWorkGroupInvocations),					128, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN    , -1 },
194 		{ LIMIT(maxComputeWorkGroupSize[0]),						128, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN    , -1 },
195 		{ LIMIT(maxComputeWorkGroupSize[1]),						128, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN    , -1 },
196 		{ LIMIT(maxComputeWorkGroupSize[2]),						64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN    , -1 },
197 		{ LIMIT(subPixelPrecisionBits),								4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN    , -1 },
198 		{ LIMIT(subTexelPrecisionBits),								4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN    , -1 },
199 		{ LIMIT(mipmapPrecisionBits),								4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN    , -1 },
200 		{ LIMIT(maxDrawIndexedIndexValue),							(deUint32)~0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
201 		{ LIMIT(maxDrawIndirectCount),								65535, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN    , -1 },
202 		{ LIMIT(maxSamplerLodBias),									0, 0, 0, 2.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
203 		{ LIMIT(maxSamplerAnisotropy),								0, 0, 0, 16.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
204 		{ LIMIT(maxViewports),										16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
205 		{ LIMIT(maxViewportDimensions[0]),							4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
206 		{ LIMIT(maxViewportDimensions[1]),							4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
207 		{ LIMIT(viewportBoundsRange[0]),							0, 0, 0, -8192.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 },
208 		{ LIMIT(viewportBoundsRange[1]),							0, 0, 0, 8191.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
209 		{ LIMIT(viewportSubPixelBits),								0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
210 		{ LIMIT(minMemoryMapAlignment),								64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
211 		{ LIMIT(minTexelBufferOffsetAlignment),						0, 0, 1, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1 },
212 		{ LIMIT(minTexelBufferOffsetAlignment),						0, 0, 256, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MAX, -1 },
213 		{ LIMIT(minUniformBufferOffsetAlignment),					0, 0, 1, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1 },
214 		{ LIMIT(minUniformBufferOffsetAlignment),					0, 0, 256, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MAX, -1 },
215 		{ LIMIT(minStorageBufferOffsetAlignment),					0, 0, 1, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1 },
216 		{ LIMIT(minStorageBufferOffsetAlignment),					0, 0, 256, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MAX, -1 },
217 		{ LIMIT(minTexelOffset),									0, -8, 0, 0.0f, LIMIT_FORMAT_SIGNED_INT, LIMIT_TYPE_MAX, -1 },
218 		{ LIMIT(maxTexelOffset),									7, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
219 		{ LIMIT(minTexelGatherOffset),								0, -8, 0, 0.0f, LIMIT_FORMAT_SIGNED_INT, LIMIT_TYPE_MAX, -1 },
220 		{ LIMIT(maxTexelGatherOffset),								7, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
221 		{ LIMIT(minInterpolationOffset),							0, 0, 0, -0.5f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 },
222 		{ LIMIT(maxInterpolationOffset),							0, 0, 0, 0.5f - (1.0f/deFloatPow(2.0f, (float)limits->subPixelInterpolationOffsetBits)), LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
223 		{ LIMIT(subPixelInterpolationOffsetBits),					4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
224 		{ LIMIT(maxFramebufferWidth),								4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
225 		{ LIMIT(maxFramebufferHeight),								4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
226 		{ LIMIT(maxFramebufferLayers),								0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
227 		{ LIMIT(framebufferColorSampleCounts),						VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 },
228 		{ LIMIT(framebufferDepthSampleCounts),						VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 },
229 		{ LIMIT(framebufferStencilSampleCounts),					VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 },
230 		{ LIMIT(framebufferNoAttachmentsSampleCounts),				VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 },
231 		{ LIMIT(maxColorAttachments),								4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
232 		{ LIMIT(sampledImageColorSampleCounts),						VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 },
233 		{ LIMIT(sampledImageIntegerSampleCounts),					VK_SAMPLE_COUNT_1_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 },
234 		{ LIMIT(sampledImageDepthSampleCounts),						VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 },
235 		{ LIMIT(sampledImageStencilSampleCounts),					VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 },
236 		{ LIMIT(storageImageSampleCounts),							VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 },
237 		{ LIMIT(maxSampleMaskWords),								1, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
238 		{ LIMIT(timestampComputeAndGraphics),						0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_NONE, -1 },
239 		{ LIMIT(timestampPeriod),									0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_NONE, -1 },
240 		{ LIMIT(maxClipDistances),									8, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
241 		{ LIMIT(maxCullDistances),									8, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
242 		{ LIMIT(maxCombinedClipAndCullDistances),					8, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
243 		{ LIMIT(discreteQueuePriorities),							2, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
244 		{ LIMIT(pointSizeRange[0]),									0, 0, 0, 0.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
245 		{ LIMIT(pointSizeRange[0]),									0, 0, 0, 1.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 },
246 		{ LIMIT(pointSizeRange[1]),									0, 0, 0, 64.0f - limits->pointSizeGranularity , LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
247 		{ LIMIT(lineWidthRange[0]),									0, 0, 0, 0.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
248 		{ LIMIT(lineWidthRange[0]),									0, 0, 0, 1.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 },
249 		{ LIMIT(lineWidthRange[1]),									0, 0, 0, 8.0f - limits->lineWidthGranularity, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
250 		{ LIMIT(pointSizeGranularity),								0, 0, 0, 1.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 },
251 		{ LIMIT(lineWidthGranularity),								0, 0, 0, 1.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 },
252 		{ LIMIT(strictLines),										0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_NONE, -1 },
253 		{ LIMIT(standardSampleLocations),							0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_NONE, -1 },
254 		{ LIMIT(optimalBufferCopyOffsetAlignment),					0, 0, 0, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_NONE, -1 },
255 		{ LIMIT(optimalBufferCopyRowPitchAlignment),				0, 0, 0, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_NONE, -1 },
256 		{ LIMIT(nonCoherentAtomSize),								0, 0, 1, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1 },
257 		{ LIMIT(nonCoherentAtomSize),								0, 0, 256, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MAX, -1 },
258 	};
259 
260 	const struct UnsupportedFeatureLimitTable
261 	{
262 		deUint32		limitOffset;
263 		const char*		name;
264 		deUint32		featureOffset;
265 		deUint32		uintVal;			//!< Format is UNSIGNED_INT
266 		deInt32			intVal;				//!< Format is SIGNED_INT
267 		deUint64		deviceSizeVal;		//!< Format is DEVICE_SIZE
268 		float			floatVal;			//!< Format is FLOAT
269 	} unsupportedFeatureTable[] =
270 	{
271 		{ LIMIT(sparseAddressSpaceSize),							FEATURE(sparseBinding),					0, 0, 0, 0.0f },
272 		{ LIMIT(maxTessellationGenerationLevel),					FEATURE(tessellationShader),			0, 0, 0, 0.0f },
273 		{ LIMIT(maxTessellationPatchSize),							FEATURE(tessellationShader),			0, 0, 0, 0.0f },
274 		{ LIMIT(maxTessellationControlPerVertexInputComponents),	FEATURE(tessellationShader),			0, 0, 0, 0.0f },
275 		{ LIMIT(maxTessellationControlPerVertexOutputComponents),	FEATURE(tessellationShader),			0, 0, 0, 0.0f },
276 		{ LIMIT(maxTessellationControlPerPatchOutputComponents),	FEATURE(tessellationShader),			0, 0, 0, 0.0f },
277 		{ LIMIT(maxTessellationControlTotalOutputComponents),		FEATURE(tessellationShader),			0, 0, 0, 0.0f },
278 		{ LIMIT(maxTessellationEvaluationInputComponents),			FEATURE(tessellationShader),			0, 0, 0, 0.0f },
279 		{ LIMIT(maxTessellationEvaluationOutputComponents),			FEATURE(tessellationShader),			0, 0, 0, 0.0f },
280 		{ LIMIT(maxGeometryShaderInvocations),						FEATURE(geometryShader),				0, 0, 0, 0.0f },
281 		{ LIMIT(maxGeometryInputComponents),						FEATURE(geometryShader),				0, 0, 0, 0.0f },
282 		{ LIMIT(maxGeometryOutputComponents),						FEATURE(geometryShader),				0, 0, 0, 0.0f },
283 		{ LIMIT(maxGeometryOutputVertices),							FEATURE(geometryShader),				0, 0, 0, 0.0f },
284 		{ LIMIT(maxGeometryTotalOutputComponents),					FEATURE(geometryShader),				0, 0, 0, 0.0f },
285 		{ LIMIT(maxFragmentDualSrcAttachments),						FEATURE(dualSrcBlend),					0, 0, 0, 0.0f },
286 		{ LIMIT(maxDrawIndexedIndexValue),							FEATURE(fullDrawIndexUint32),			(1<<24)-1, 0, 0, 0.0f },
287 		{ LIMIT(maxDrawIndirectCount),								FEATURE(multiDrawIndirect),				1, 0, 0, 0.0f },
288 		{ LIMIT(maxSamplerAnisotropy),								FEATURE(samplerAnisotropy),				1, 0, 0, 0.0f },
289 		{ LIMIT(maxViewports),										FEATURE(multiViewport),					1, 0, 0, 0.0f },
290 		{ LIMIT(minTexelGatherOffset),								FEATURE(shaderImageGatherExtended),		0, 0, 0, 0.0f },
291 		{ LIMIT(maxTexelGatherOffset),								FEATURE(shaderImageGatherExtended),		0, 0, 0, 0.0f },
292 		{ LIMIT(minInterpolationOffset),							FEATURE(sampleRateShading),				0, 0, 0, 0.0f },
293 		{ LIMIT(maxInterpolationOffset),							FEATURE(sampleRateShading),				0, 0, 0, 0.0f },
294 		{ LIMIT(subPixelInterpolationOffsetBits),					FEATURE(sampleRateShading),				0, 0, 0, 0.0f },
295 		{ LIMIT(storageImageSampleCounts),							FEATURE(shaderStorageImageMultisample),	VK_SAMPLE_COUNT_1_BIT, 0, 0, 0.0f },
296 		{ LIMIT(maxClipDistances),									FEATURE(shaderClipDistance),			0, 0, 0, 0.0f },
297 		{ LIMIT(maxCullDistances),									FEATURE(shaderClipDistance),			0, 0, 0, 0.0f },
298 		{ LIMIT(maxCombinedClipAndCullDistances),					FEATURE(shaderClipDistance),			0, 0, 0, 0.0f },
299 		{ LIMIT(pointSizeRange[0]),									FEATURE(largePoints),					0, 0, 0, 1.0f },
300 		{ LIMIT(pointSizeRange[1]),									FEATURE(largePoints),					0, 0, 0, 1.0f },
301 		{ LIMIT(lineWidthRange[0]),									FEATURE(wideLines),						0, 0, 0, 1.0f },
302 		{ LIMIT(lineWidthRange[1]),									FEATURE(wideLines),						0, 0, 0, 1.0f },
303 		{ LIMIT(pointSizeGranularity),								FEATURE(largePoints),					0, 0, 0, 0.0f },
304 		{ LIMIT(lineWidthGranularity),								FEATURE(wideLines),						0, 0, 0, 0.0f }
305 	};
306 
307 	log << TestLog::Message << *limits << TestLog::EndMessage;
308 
309 	//!< First build a map from limit to unsupported table index
310 	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
311 	{
312 		for (deUint32 unsuppNdx = 0; unsuppNdx < DE_LENGTH_OF_ARRAY(unsupportedFeatureTable); unsuppNdx++)
313 		{
314 			if (unsupportedFeatureTable[unsuppNdx].limitOffset == featureLimitTable[ndx].offset)
315 			{
316 				featureLimitTable[ndx].unsuppTableNdx = unsuppNdx;
317 				break;
318 			}
319 		}
320 	}
321 
322 	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
323 	{
324 		switch (featureLimitTable[ndx].format)
325 		{
326 			case LIMIT_FORMAT_UNSIGNED_INT:
327 			{
328 				deUint32 limitToCheck = featureLimitTable[ndx].uintVal;
329 				if (featureLimitTable[ndx].unsuppTableNdx != -1)
330 				{
331 					if (*((VkBool32*)((deUint8*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)) == VK_FALSE)
332 						limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].uintVal;
333 				}
334 
335 				if (featureLimitTable[ndx].type == LIMIT_TYPE_MIN)
336 				{
337 
338 					if (*((deUint32*)((deUint8*)limits+featureLimitTable[ndx].offset)) < limitToCheck)
339 					{
340 						log << TestLog::Message << "limit Validation failed " << featureLimitTable[ndx].name
341 							<< " not valid-limit type MIN - actual is "
342 							<< *((deUint32*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
343 						limitsOk = false;
344 					}
345 				}
346 				else if (featureLimitTable[ndx].type == LIMIT_TYPE_MAX)
347 				{
348 					if (*((deUint32*)((deUint8*)limits+featureLimitTable[ndx].offset)) > limitToCheck)
349 					{
350 						log << TestLog::Message << "limit validation failed,  " << featureLimitTable[ndx].name
351 							<< " not valid-limit type MAX - actual is "
352 							<< *((deUint32*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
353 						limitsOk = false;
354 					}
355 				}
356 				break;
357 			}
358 
359 			case LIMIT_FORMAT_FLOAT:
360 			{
361 				float limitToCheck = featureLimitTable[ndx].floatVal;
362 				if (featureLimitTable[ndx].unsuppTableNdx != -1)
363 				{
364 					if (*((VkBool32*)((deUint8*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)) == VK_FALSE)
365 						limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].floatVal;
366 				}
367 
368 				if (featureLimitTable[ndx].type == LIMIT_TYPE_MIN)
369 				{
370 					if (*((float*)((deUint8*)limits+featureLimitTable[ndx].offset)) < limitToCheck)
371 					{
372 						log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
373 							<< " not valid-limit type MIN - actual is "
374 							<< *((float*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
375 						limitsOk = false;
376 					}
377 				}
378 				else if (featureLimitTable[ndx].type == LIMIT_TYPE_MAX)
379 				{
380 					if (*((float*)((deUint8*)limits+featureLimitTable[ndx].offset)) > limitToCheck)
381 					{
382 						log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
383 							<< " not valid-limit type MAX actual is "
384 							<< *((float*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
385 						limitsOk = false;
386 					}
387 				}
388 				break;
389 			}
390 
391 			case LIMIT_FORMAT_SIGNED_INT:
392 			{
393 				deInt32 limitToCheck = featureLimitTable[ndx].intVal;
394 				if (featureLimitTable[ndx].unsuppTableNdx != -1)
395 				{
396 					if (*((VkBool32*)((deUint8*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)) == VK_FALSE)
397 						limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].intVal;
398 				}
399 				if (featureLimitTable[ndx].type == LIMIT_TYPE_MIN)
400 				{
401 					if (*((deInt32*)((deUint8*)limits+featureLimitTable[ndx].offset)) < limitToCheck)
402 					{
403 						log << TestLog::Message <<  "limit validation failed, " << featureLimitTable[ndx].name
404 							<< " not valid-limit type MIN actual is "
405 							<< *((deInt32*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
406 						limitsOk = false;
407 					}
408 				}
409 				else if (featureLimitTable[ndx].type == LIMIT_TYPE_MAX)
410 				{
411 					if (*((deInt32*)((deUint8*)limits+featureLimitTable[ndx].offset)) > limitToCheck)
412 					{
413 						log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
414 							<< " not valid-limit type MAX actual is "
415 							<< *((deInt32*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
416 						limitsOk = false;
417 					}
418 				}
419 				break;
420 			}
421 
422 			case LIMIT_FORMAT_DEVICE_SIZE:
423 			{
424 				deUint64 limitToCheck = featureLimitTable[ndx].deviceSizeVal;
425 				if (featureLimitTable[ndx].unsuppTableNdx != -1)
426 				{
427 					if (*((VkBool32*)((deUint8*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)) == VK_FALSE)
428 						limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].deviceSizeVal;
429 				}
430 
431 				if (featureLimitTable[ndx].type == LIMIT_TYPE_MIN)
432 				{
433 					if (*((deUint64*)((deUint8*)limits+featureLimitTable[ndx].offset)) < limitToCheck)
434 					{
435 						log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
436 							<< " not valid-limit type MIN actual is "
437 							<< *((deUint64*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
438 						limitsOk = false;
439 					}
440 				}
441 				else if (featureLimitTable[ndx].type == LIMIT_TYPE_MAX)
442 				{
443 					if (*((deUint64*)((deUint8*)limits+featureLimitTable[ndx].offset)) > limitToCheck)
444 					{
445 						log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
446 							<< " not valid-limit type MAX actual is "
447 							<< *((deUint64*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
448 						limitsOk = false;
449 					}
450 				}
451 				break;
452 			}
453 
454 			case LIMIT_FORMAT_BITMASK:
455 			{
456 				deUint32 limitToCheck = featureLimitTable[ndx].uintVal;
457 				if (featureLimitTable[ndx].unsuppTableNdx != -1)
458 				{
459 					if (*((VkBool32*)((deUint8*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)) == VK_FALSE)
460 						limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].uintVal;
461 				}
462 
463 				if (featureLimitTable[ndx].type == LIMIT_TYPE_MIN)
464 				{
465 					if ((*((deUint32*)((deUint8*)limits+featureLimitTable[ndx].offset)) & limitToCheck) != limitToCheck)
466 					{
467 						log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
468 							<< " not valid-limit type bitmask actual is "
469 							<< *((deUint64*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
470 						limitsOk = false;
471 					}
472 				}
473 				break;
474 			}
475 
476 			default:
477 				DE_ASSERT(0);
478 				limitsOk = false;
479 		}
480 	}
481 
482 	if (limits->maxFramebufferWidth > limits->maxViewportDimensions[0] ||
483 		limits->maxFramebufferHeight > limits->maxViewportDimensions[1])
484 	{
485 		log << TestLog::Message << "limit validation failed, maxFramebufferDimension of "
486 			<< "[" << limits->maxFramebufferWidth << ", " << limits->maxFramebufferHeight << "] "
487 			<< "is larger than maxViewportDimension of "
488 			<< "[" << limits->maxViewportDimensions[0] << ", " << limits->maxViewportDimensions[1] << "]" << TestLog::EndMessage;
489 		limitsOk = false;
490 	}
491 
492 	if (limits->viewportBoundsRange[0] > float(-2 * limits->maxViewportDimensions[0]))
493 	{
494 		log << TestLog::Message << "limit validation failed, viewPortBoundsRange[0] of " << limits->viewportBoundsRange[0]
495 			<< "is larger than -2*maxViewportDimension[0] of " << -2*limits->maxViewportDimensions[0] << TestLog::EndMessage;
496 		limitsOk = false;
497 	}
498 
499 	if (limits->viewportBoundsRange[1] < float(2 * limits->maxViewportDimensions[1] - 1))
500 	{
501 		log << TestLog::Message << "limit validation failed, viewportBoundsRange[1] of " << limits->viewportBoundsRange[1]
502 			<< "is less than 2*maxViewportDimension[1] of " << 2*limits->maxViewportDimensions[1] << TestLog::EndMessage;
503 		limitsOk = false;
504 	}
505 
506 	return limitsOk;
507 }
508 
509 template<typename T>
510 class CheckIncompleteResult
511 {
512 public:
~CheckIncompleteResult(void)513 	virtual			~CheckIncompleteResult	(void) {}
514 	virtual void	getResult				(Context& context, T* data) = 0;
515 
operator ()(Context & context,tcu::ResultCollector & results,const std::size_t expectedCompleteSize)516 	void operator() (Context& context, tcu::ResultCollector& results, const std::size_t expectedCompleteSize)
517 	{
518 		if (expectedCompleteSize == 0)
519 			return;
520 
521 		vector<T>		outputData	(expectedCompleteSize);
522 		const deUint32	usedSize	= static_cast<deUint32>(expectedCompleteSize / 3);
523 
524 		ValidateQueryBits::fillBits(outputData.begin(), outputData.end());	// unused entries should have this pattern intact
525 		m_count		= usedSize;
526 		m_result	= VK_SUCCESS;
527 
528 		getResult(context, &outputData[0]);									// update m_count and m_result
529 
530 		if (m_count != usedSize || m_result != VK_INCOMPLETE || !ValidateQueryBits::checkBits(outputData.begin() + m_count, outputData.end()))
531 			results.fail("Query didn't return VK_INCOMPLETE");
532 	}
533 
534 protected:
535 	deUint32	m_count;
536 	VkResult	m_result;
537 };
538 
539 struct CheckEnumeratePhysicalDevicesIncompleteResult : public CheckIncompleteResult<VkPhysicalDevice>
540 {
getResultvkt::api::__anon0f62d5780111::CheckEnumeratePhysicalDevicesIncompleteResult541 	void getResult (Context& context, VkPhysicalDevice* data)
542 	{
543 		m_result = context.getInstanceInterface().enumeratePhysicalDevices(context.getInstance(), &m_count, data);
544 	}
545 };
546 
547 struct CheckEnumeratePhysicalDeviceGroupsIncompleteResult : public CheckIncompleteResult<VkPhysicalDeviceGroupProperties>
548 {
getResultvkt::api::__anon0f62d5780111::CheckEnumeratePhysicalDeviceGroupsIncompleteResult549 	void getResult (Context& context, VkPhysicalDeviceGroupProperties* data)
550 	{
551 		m_result = context.getInstanceInterface().enumeratePhysicalDeviceGroups(context.getInstance(), &m_count, data);
552 	}
553 };
554 
555 struct CheckEnumerateInstanceLayerPropertiesIncompleteResult : public CheckIncompleteResult<VkLayerProperties>
556 {
getResultvkt::api::__anon0f62d5780111::CheckEnumerateInstanceLayerPropertiesIncompleteResult557 	void getResult (Context& context, VkLayerProperties* data)
558 	{
559 		m_result = context.getPlatformInterface().enumerateInstanceLayerProperties(&m_count, data);
560 	}
561 };
562 
563 struct CheckEnumerateDeviceLayerPropertiesIncompleteResult : public CheckIncompleteResult<VkLayerProperties>
564 {
getResultvkt::api::__anon0f62d5780111::CheckEnumerateDeviceLayerPropertiesIncompleteResult565 	void getResult (Context& context, VkLayerProperties* data)
566 	{
567 		m_result = context.getInstanceInterface().enumerateDeviceLayerProperties(context.getPhysicalDevice(), &m_count, data);
568 	}
569 };
570 
571 struct CheckEnumerateInstanceExtensionPropertiesIncompleteResult : public CheckIncompleteResult<VkExtensionProperties>
572 {
CheckEnumerateInstanceExtensionPropertiesIncompleteResultvkt::api::__anon0f62d5780111::CheckEnumerateInstanceExtensionPropertiesIncompleteResult573 	CheckEnumerateInstanceExtensionPropertiesIncompleteResult (std::string layerName = std::string()) : m_layerName(layerName) {}
574 
getResultvkt::api::__anon0f62d5780111::CheckEnumerateInstanceExtensionPropertiesIncompleteResult575 	void getResult (Context& context, VkExtensionProperties* data)
576 	{
577 		const char* pLayerName = (m_layerName.length() != 0 ? m_layerName.c_str() : DE_NULL);
578 		m_result = context.getPlatformInterface().enumerateInstanceExtensionProperties(pLayerName, &m_count, data);
579 	}
580 
581 private:
582 	const std::string	m_layerName;
583 };
584 
585 struct CheckEnumerateDeviceExtensionPropertiesIncompleteResult : public CheckIncompleteResult<VkExtensionProperties>
586 {
CheckEnumerateDeviceExtensionPropertiesIncompleteResultvkt::api::__anon0f62d5780111::CheckEnumerateDeviceExtensionPropertiesIncompleteResult587 	CheckEnumerateDeviceExtensionPropertiesIncompleteResult (std::string layerName = std::string()) : m_layerName(layerName) {}
588 
getResultvkt::api::__anon0f62d5780111::CheckEnumerateDeviceExtensionPropertiesIncompleteResult589 	void getResult (Context& context, VkExtensionProperties* data)
590 	{
591 		const char* pLayerName = (m_layerName.length() != 0 ? m_layerName.c_str() : DE_NULL);
592 		m_result = context.getInstanceInterface().enumerateDeviceExtensionProperties(context.getPhysicalDevice(), pLayerName, &m_count, data);
593 	}
594 
595 private:
596 	const std::string	m_layerName;
597 };
598 
enumeratePhysicalDevices(Context & context)599 tcu::TestStatus enumeratePhysicalDevices (Context& context)
600 {
601 	TestLog&						log		= context.getTestContext().getLog();
602 	tcu::ResultCollector			results	(log);
603 	const vector<VkPhysicalDevice>	devices	= enumeratePhysicalDevices(context.getInstanceInterface(), context.getInstance());
604 
605 	log << TestLog::Integer("NumDevices", "Number of devices", "", QP_KEY_TAG_NONE, deInt64(devices.size()));
606 
607 	for (size_t ndx = 0; ndx < devices.size(); ndx++)
608 		log << TestLog::Message << ndx << ": " << devices[ndx] << TestLog::EndMessage;
609 
610 	CheckEnumeratePhysicalDevicesIncompleteResult()(context, results, devices.size());
611 
612 	return tcu::TestStatus(results.getResult(), results.getMessage());
613 }
614 
enumeratePhysicalDeviceGroups(Context & context)615 tcu::TestStatus enumeratePhysicalDeviceGroups (Context& context)
616 {
617 	TestLog&											log				= context.getTestContext().getLog();
618 	tcu::ResultCollector								results			(log);
619 	const PlatformInterface&							vkp				= context.getPlatformInterface();
620 	const Unique<VkInstance>							instance		(createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_device_group_creation"));
621 	const InstanceDriver								vki				(vkp, *instance);
622 	const vector<VkPhysicalDeviceGroupProperties>		devicegroups	= enumeratePhysicalDeviceGroups(vki, *instance);
623 
624 	log << TestLog::Integer("NumDevices", "Number of device groups", "", QP_KEY_TAG_NONE, deInt64(devicegroups.size()));
625 
626 	for (size_t ndx = 0; ndx < devicegroups.size(); ndx++)
627 		log << TestLog::Message << ndx << ": " << devicegroups[ndx] << TestLog::EndMessage;
628 
629 	CheckEnumeratePhysicalDeviceGroupsIncompleteResult()(context, results, devicegroups.size());
630 
631 	return tcu::TestStatus(results.getResult(), results.getMessage());
632 }
633 
634 template<typename T>
collectDuplicates(set<T> & duplicates,const vector<T> & values)635 void collectDuplicates (set<T>& duplicates, const vector<T>& values)
636 {
637 	set<T> seen;
638 
639 	for (size_t ndx = 0; ndx < values.size(); ndx++)
640 	{
641 		const T& value = values[ndx];
642 
643 		if (!seen.insert(value).second)
644 			duplicates.insert(value);
645 	}
646 }
647 
checkDuplicates(tcu::ResultCollector & results,const char * what,const vector<string> & values)648 void checkDuplicates (tcu::ResultCollector& results, const char* what, const vector<string>& values)
649 {
650 	set<string> duplicates;
651 
652 	collectDuplicates(duplicates, values);
653 
654 	for (set<string>::const_iterator iter = duplicates.begin(); iter != duplicates.end(); ++iter)
655 	{
656 		std::ostringstream msg;
657 		msg << "Duplicate " << what << ": " << *iter;
658 		results.fail(msg.str());
659 	}
660 }
661 
checkDuplicateExtensions(tcu::ResultCollector & results,const vector<string> & extensions)662 void checkDuplicateExtensions (tcu::ResultCollector& results, const vector<string>& extensions)
663 {
664 	checkDuplicates(results, "extension", extensions);
665 }
666 
checkDuplicateLayers(tcu::ResultCollector & results,const vector<string> & layers)667 void checkDuplicateLayers (tcu::ResultCollector& results, const vector<string>& layers)
668 {
669 	checkDuplicates(results, "layer", layers);
670 }
671 
checkKhrExtensions(tcu::ResultCollector & results,const vector<string> & extensions,const int numAllowedKhrExtensions,const char * const * allowedKhrExtensions)672 void checkKhrExtensions (tcu::ResultCollector&		results,
673 						 const vector<string>&		extensions,
674 						 const int					numAllowedKhrExtensions,
675 						 const char* const*			allowedKhrExtensions)
676 {
677 	const set<string>	allowedExtSet		(allowedKhrExtensions, allowedKhrExtensions+numAllowedKhrExtensions);
678 
679 	for (vector<string>::const_iterator extIter = extensions.begin(); extIter != extensions.end(); ++extIter)
680 	{
681 		// Only Khronos-controlled extensions are checked
682 		if (de::beginsWith(*extIter, "VK_KHR_") &&
683 			!de::contains(allowedExtSet, *extIter))
684 		{
685 			results.fail("Unknown  extension " + *extIter);
686 		}
687 	}
688 }
689 
checkInstanceExtensions(tcu::ResultCollector & results,const vector<string> & extensions)690 void checkInstanceExtensions (tcu::ResultCollector& results, const vector<string>& extensions)
691 {
692 	static const char* s_allowedInstanceKhrExtensions[] =
693 	{
694 		"VK_KHR_surface",
695 		"VK_KHR_display",
696 		"VK_KHR_android_surface",
697 		"VK_KHR_mir_surface",
698 		"VK_KHR_wayland_surface",
699 		"VK_KHR_win32_surface",
700 		"VK_KHR_xcb_surface",
701 		"VK_KHR_xlib_surface",
702 		"VK_KHR_get_physical_device_properties2",
703 		"VK_KHR_get_surface_capabilities2",
704 		"VK_KHR_external_memory_capabilities",
705 		"VK_KHR_external_semaphore_capabilities",
706 		"VK_KHR_external_fence_capabilities",
707 		"VK_KHR_device_group_creation",
708 		"VK_KHR_get_display_properties2",
709 		"VK_KHR_surface_protected_capabilities",
710 	};
711 
712 	checkKhrExtensions(results, extensions, DE_LENGTH_OF_ARRAY(s_allowedInstanceKhrExtensions), s_allowedInstanceKhrExtensions);
713 	checkDuplicateExtensions(results, extensions);
714 }
715 
checkDeviceExtensions(tcu::ResultCollector & results,const vector<string> & extensions)716 void checkDeviceExtensions (tcu::ResultCollector& results, const vector<string>& extensions)
717 {
718 	static const char* s_allowedDeviceKhrExtensions[] =
719 	{
720 		"VK_KHR_swapchain",
721 		"VK_KHR_display_swapchain",
722 		"VK_KHR_sampler_mirror_clamp_to_edge",
723 		"VK_KHR_shader_draw_parameters",
724 		"VK_KHR_shader_float_controls",
725 		"VK_KHR_shader_float16_int8",
726 		"VK_KHR_maintenance1",
727 		"VK_KHR_push_descriptor",
728 		"VK_KHR_descriptor_update_template",
729 		"VK_KHR_incremental_present",
730 		"VK_KHR_shared_presentable_image",
731 		"VK_KHR_storage_buffer_storage_class",
732 		"VK_KHR_8bit_storage",
733 		"VK_KHR_16bit_storage",
734 		"VK_KHR_get_memory_requirements2",
735 		"VK_KHR_external_memory",
736 		"VK_KHR_external_memory_fd",
737 		"VK_KHR_external_memory_win32",
738 		"VK_KHR_external_semaphore",
739 		"VK_KHR_external_semaphore_fd",
740 		"VK_KHR_external_semaphore_win32",
741 		"VK_KHR_external_fence",
742 		"VK_KHR_external_fence_fd",
743 		"VK_KHR_external_fence_win32",
744 		"VK_KHR_win32_keyed_mutex",
745 		"VK_KHR_dedicated_allocation",
746 		"VK_KHR_variable_pointers",
747 		"VK_KHR_relaxed_block_layout",
748 		"VK_KHR_bind_memory2",
749 		"VK_KHR_maintenance2",
750 		"VK_KHR_image_format_list",
751 		"VK_KHR_sampler_ycbcr_conversion",
752 		"VK_KHR_device_group",
753 		"VK_KHR_multiview",
754 		"VK_KHR_maintenance3",
755 		"VK_KHR_draw_indirect_count",
756 		"VK_KHR_create_renderpass2",
757 		"VK_KHR_depth_stencil_resolve",
758 		"VK_KHR_driver_properties",
759 		"VK_KHR_swapchain_mutable_format",
760 		"VK_KHR_shader_atomic_int64",
761 		"VK_KHR_vulkan_memory_model",
762 		"VK_KHR_swapchain_mutable_format",
763 	};
764 
765 	checkKhrExtensions(results, extensions, DE_LENGTH_OF_ARRAY(s_allowedDeviceKhrExtensions), s_allowedDeviceKhrExtensions);
766 	checkDuplicateExtensions(results, extensions);
767 }
768 
checkInstanceExtensionDependencies(tcu::ResultCollector & results,int dependencyLength,const std::pair<const char *,const char * > * dependencies,const vector<VkExtensionProperties> & extensionProperties)769 void checkInstanceExtensionDependencies(tcu::ResultCollector& results,
770 										int dependencyLength,
771 										const std::pair<const char*, const char*>* dependencies,
772 										const vector<VkExtensionProperties>& extensionProperties)
773 {
774 	for (int ndx = 0; ndx < dependencyLength; ndx++)
775 	{
776 		if (isExtensionSupported(extensionProperties, RequiredExtension(dependencies[ndx].first)) &&
777 			!isExtensionSupported(extensionProperties, RequiredExtension(dependencies[ndx].second)))
778 		{
779 			results.fail("Extension " + string(dependencies[ndx].first) + " is missing dependency: " + string(dependencies[ndx].second));
780 		}
781 	}
782 }
783 
checkDeviceExtensionDependencies(tcu::ResultCollector & results,int dependencyLength,const std::pair<const char *,const char * > * dependencies,const vector<VkExtensionProperties> & instanceExtensionProperties,const vector<VkExtensionProperties> & deviceExtensionProperties)784 void checkDeviceExtensionDependencies(tcu::ResultCollector& results,
785 									  int dependencyLength,
786 									  const std::pair<const char*, const char*>* dependencies,
787 									  const vector<VkExtensionProperties>& instanceExtensionProperties,
788 									  const vector<VkExtensionProperties>& deviceExtensionProperties)
789 {
790 	for (int ndx = 0; ndx < dependencyLength; ndx++)
791 	{
792 		if (isExtensionSupported(deviceExtensionProperties, RequiredExtension(dependencies[ndx].first)) &&
793 			!isExtensionSupported(deviceExtensionProperties, RequiredExtension(dependencies[ndx].second)) &&
794 			!isExtensionSupported(instanceExtensionProperties, RequiredExtension(dependencies[ndx].second)))
795 		{
796 			results.fail("Extension " + string(dependencies[ndx].first) + " is missing dependency: " + string(dependencies[ndx].second));
797 		}
798 	}
799 }
800 
enumerateInstanceLayers(Context & context)801 tcu::TestStatus enumerateInstanceLayers (Context& context)
802 {
803 	TestLog&						log					= context.getTestContext().getLog();
804 	tcu::ResultCollector			results				(log);
805 	const vector<VkLayerProperties>	properties			= enumerateInstanceLayerProperties(context.getPlatformInterface());
806 	vector<string>					layerNames;
807 
808 	for (size_t ndx = 0; ndx < properties.size(); ndx++)
809 	{
810 		log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage;
811 
812 		layerNames.push_back(properties[ndx].layerName);
813 	}
814 
815 	checkDuplicateLayers(results, layerNames);
816 	CheckEnumerateInstanceLayerPropertiesIncompleteResult()(context, results, layerNames.size());
817 
818 	return tcu::TestStatus(results.getResult(), results.getMessage());
819 }
820 
enumerateInstanceExtensions(Context & context)821 tcu::TestStatus enumerateInstanceExtensions (Context& context)
822 {
823 	TestLog&				log		= context.getTestContext().getLog();
824 	tcu::ResultCollector	results	(log);
825 
826 	{
827 		const ScopedLogSection				section		(log, "Global", "Global Extensions");
828 		const vector<VkExtensionProperties>	properties	= enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL);
829 		vector<string>						extensionNames;
830 
831 		for (size_t ndx = 0; ndx < properties.size(); ndx++)
832 		{
833 			log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage;
834 
835 			extensionNames.push_back(properties[ndx].extensionName);
836 		}
837 
838 		checkInstanceExtensions(results, extensionNames);
839 		CheckEnumerateInstanceExtensionPropertiesIncompleteResult()(context, results, properties.size());
840 
841 		if (context.contextSupports(vk::ApiVersion(1, 1, 0)))
842 		{
843 			checkInstanceExtensionDependencies(results,
844 											   DE_LENGTH_OF_ARRAY(instanceExtensionDependencies_1_1),
845 											   instanceExtensionDependencies_1_1, properties);
846 		}
847 		else if (context.contextSupports(vk::ApiVersion(1, 0, 0)))
848 		{
849 			checkInstanceExtensionDependencies(results,
850 											   DE_LENGTH_OF_ARRAY(instanceExtensionDependencies_1_0),
851 											   instanceExtensionDependencies_1_0, properties);
852 		}
853 	}
854 
855 	{
856 		const vector<VkLayerProperties>	layers	= enumerateInstanceLayerProperties(context.getPlatformInterface());
857 
858 		for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
859 		{
860 			const ScopedLogSection				section				(log, layer->layerName, string("Layer: ") + layer->layerName);
861 			const vector<VkExtensionProperties>	properties			= enumerateInstanceExtensionProperties(context.getPlatformInterface(), layer->layerName);
862 			vector<string>						extensionNames;
863 
864 			for (size_t extNdx = 0; extNdx < properties.size(); extNdx++)
865 			{
866 				log << TestLog::Message << extNdx << ": " << properties[extNdx] << TestLog::EndMessage;
867 
868 				extensionNames.push_back(properties[extNdx].extensionName);
869 			}
870 
871 			checkInstanceExtensions(results, extensionNames);
872 			CheckEnumerateInstanceExtensionPropertiesIncompleteResult(layer->layerName)(context, results, properties.size());
873 		}
874 	}
875 
876 	return tcu::TestStatus(results.getResult(), results.getMessage());
877 }
878 
testNoKhxExtensions(Context & context)879 tcu::TestStatus testNoKhxExtensions (Context& context)
880 {
881 	VkPhysicalDevice			physicalDevice	= context.getPhysicalDevice();
882 	const PlatformInterface&	vkp				= context.getPlatformInterface();
883 	const InstanceInterface&	vki				= context.getInstanceInterface();
884 
885 	tcu::ResultCollector		results(context.getTestContext().getLog());
886 	bool						testSucceeded = true;
887 	deUint32					instanceExtensionsCount;
888 	deUint32					deviceExtensionsCount;
889 
890 	// grab number of instance and device extensions
891 	vkp.enumerateInstanceExtensionProperties(DE_NULL, &instanceExtensionsCount, DE_NULL);
892 	vki.enumerateDeviceExtensionProperties(physicalDevice, DE_NULL, &deviceExtensionsCount, DE_NULL);
893 	vector<VkExtensionProperties> extensionsProperties(instanceExtensionsCount + deviceExtensionsCount);
894 
895 	// grab instance and device extensions into single vector
896 	if (instanceExtensionsCount)
897 		vkp.enumerateInstanceExtensionProperties(DE_NULL, &instanceExtensionsCount, &extensionsProperties[0]);
898 	if (deviceExtensionsCount)
899 		vki.enumerateDeviceExtensionProperties(physicalDevice, DE_NULL, &deviceExtensionsCount, &extensionsProperties[instanceExtensionsCount]);
900 
901 	// iterate over all extensions and verify their names
902 	vector<VkExtensionProperties>::const_iterator extension = extensionsProperties.begin();
903 	while (extension != extensionsProperties.end())
904 	{
905 		// KHX author ID is no longer used, all KHX extensions have been promoted to KHR status
906 		std::string extensionName(extension->extensionName);
907 		bool caseFailed = de::beginsWith(extensionName, "VK_KHX_");
908 		if (caseFailed)
909 		{
910 			results.fail("Invalid extension name " + extensionName);
911 			testSucceeded = false;
912 		}
913 		++extension;
914 	}
915 
916 	if (testSucceeded)
917 		return tcu::TestStatus::pass("No extensions begining with \"VK_KHX\"");
918 	return tcu::TestStatus::fail("One or more extensions begins with \"VK_KHX\"");
919 }
920 
enumerateDeviceLayers(Context & context)921 tcu::TestStatus enumerateDeviceLayers (Context& context)
922 {
923 	TestLog&						log			= context.getTestContext().getLog();
924 	tcu::ResultCollector			results		(log);
925 	const vector<VkLayerProperties>	properties	= enumerateDeviceLayerProperties(context.getInstanceInterface(), context.getPhysicalDevice());
926 	vector<string>					layerNames;
927 
928 	for (size_t ndx = 0; ndx < properties.size(); ndx++)
929 	{
930 		log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage;
931 
932 		layerNames.push_back(properties[ndx].layerName);
933 	}
934 
935 	checkDuplicateLayers(results, layerNames);
936 	CheckEnumerateDeviceLayerPropertiesIncompleteResult()(context, results, layerNames.size());
937 
938 	return tcu::TestStatus(results.getResult(), results.getMessage());
939 }
940 
enumerateDeviceExtensions(Context & context)941 tcu::TestStatus enumerateDeviceExtensions (Context& context)
942 {
943 	TestLog&				log		= context.getTestContext().getLog();
944 	tcu::ResultCollector	results	(log);
945 
946 	{
947 		const ScopedLogSection				section						(log, "Global", "Global Extensions");
948 		const vector<VkExtensionProperties>	instanceExtensionProperties	= enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL);
949 		const vector<VkExtensionProperties>	deviceExtensionProperties	= enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), DE_NULL);
950 		vector<string>						deviceExtensionNames;
951 
952 		for (size_t ndx = 0; ndx < deviceExtensionProperties.size(); ndx++)
953 		{
954 			log << TestLog::Message << ndx << ": " << deviceExtensionProperties[ndx] << TestLog::EndMessage;
955 
956 			deviceExtensionNames.push_back(deviceExtensionProperties[ndx].extensionName);
957 		}
958 
959 		checkDeviceExtensions(results, deviceExtensionNames);
960 		CheckEnumerateDeviceExtensionPropertiesIncompleteResult()(context, results, deviceExtensionProperties.size());
961 
962 		if (context.contextSupports(vk::ApiVersion(1, 1, 0)))
963 		{
964 			checkDeviceExtensionDependencies(results,
965 											 DE_LENGTH_OF_ARRAY(deviceExtensionDependencies_1_1),
966 											 deviceExtensionDependencies_1_1,
967 											 instanceExtensionProperties,
968 											 deviceExtensionProperties);
969 		}
970 		else if (context.contextSupports(vk::ApiVersion(1, 0, 0)))
971 		{
972 			checkDeviceExtensionDependencies(results,
973 											 DE_LENGTH_OF_ARRAY(deviceExtensionDependencies_1_0),
974 											 deviceExtensionDependencies_1_0,
975 											 instanceExtensionProperties,
976 											 deviceExtensionProperties);
977 		}
978 	}
979 
980 	{
981 		const vector<VkLayerProperties>	layers	= enumerateDeviceLayerProperties(context.getInstanceInterface(), context.getPhysicalDevice());
982 
983 		for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
984 		{
985 			const ScopedLogSection				section		(log, layer->layerName, string("Layer: ") + layer->layerName);
986 			const vector<VkExtensionProperties>	properties	= enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), layer->layerName);
987 			vector<string>						extensionNames;
988 
989 			for (size_t extNdx = 0; extNdx < properties.size(); extNdx++)
990 			{
991 				log << TestLog::Message << extNdx << ": " << properties[extNdx] << TestLog::EndMessage;
992 
993 
994 				extensionNames.push_back(properties[extNdx].extensionName);
995 			}
996 
997 			checkDeviceExtensions(results, extensionNames);
998 			CheckEnumerateDeviceExtensionPropertiesIncompleteResult(layer->layerName)(context, results, properties.size());
999 		}
1000 	}
1001 
1002 	return tcu::TestStatus(results.getResult(), results.getMessage());
1003 }
1004 
1005 #define VK_SIZE_OF(STRUCT, MEMBER)					(sizeof(((STRUCT*)0)->MEMBER))
1006 #define OFFSET_TABLE_ENTRY(STRUCT, MEMBER)			{ (size_t)DE_OFFSET_OF(STRUCT, MEMBER), VK_SIZE_OF(STRUCT, MEMBER) }
1007 
deviceFeatures(Context & context)1008 tcu::TestStatus deviceFeatures (Context& context)
1009 {
1010 	using namespace ValidateQueryBits;
1011 
1012 	TestLog&						log			= context.getTestContext().getLog();
1013 	VkPhysicalDeviceFeatures*		features;
1014 	deUint8							buffer[sizeof(VkPhysicalDeviceFeatures) + GUARD_SIZE];
1015 
1016 	const QueryMemberTableEntry featureOffsetTable[] =
1017 	{
1018 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, robustBufferAccess),
1019 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, fullDrawIndexUint32),
1020 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, imageCubeArray),
1021 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, independentBlend),
1022 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, geometryShader),
1023 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, tessellationShader),
1024 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sampleRateShading),
1025 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, dualSrcBlend),
1026 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, logicOp),
1027 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, multiDrawIndirect),
1028 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, drawIndirectFirstInstance),
1029 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, depthClamp),
1030 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, depthBiasClamp),
1031 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, fillModeNonSolid),
1032 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, depthBounds),
1033 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, wideLines),
1034 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, largePoints),
1035 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, alphaToOne),
1036 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, multiViewport),
1037 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, samplerAnisotropy),
1038 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, textureCompressionETC2),
1039 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, textureCompressionASTC_LDR),
1040 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, textureCompressionBC),
1041 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, occlusionQueryPrecise),
1042 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, pipelineStatisticsQuery),
1043 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, vertexPipelineStoresAndAtomics),
1044 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, fragmentStoresAndAtomics),
1045 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderTessellationAndGeometryPointSize),
1046 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderImageGatherExtended),
1047 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderStorageImageExtendedFormats),
1048 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderStorageImageMultisample),
1049 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderStorageImageReadWithoutFormat),
1050 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderStorageImageWriteWithoutFormat),
1051 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderUniformBufferArrayDynamicIndexing),
1052 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderSampledImageArrayDynamicIndexing),
1053 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderStorageBufferArrayDynamicIndexing),
1054 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderStorageImageArrayDynamicIndexing),
1055 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderClipDistance),
1056 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderCullDistance),
1057 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderFloat64),
1058 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderInt64),
1059 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderInt16),
1060 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderResourceResidency),
1061 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderResourceMinLod),
1062 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseBinding),
1063 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidencyBuffer),
1064 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidencyImage2D),
1065 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidencyImage3D),
1066 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidency2Samples),
1067 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidency4Samples),
1068 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidency8Samples),
1069 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidency16Samples),
1070 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidencyAliased),
1071 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, variableMultisampleRate),
1072 		OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, inheritedQueries),
1073 		{ 0, 0 }
1074 	};
1075 
1076 	deMemset(buffer, GUARD_VALUE, sizeof(buffer));
1077 	features = reinterpret_cast<VkPhysicalDeviceFeatures*>(buffer);
1078 
1079 	context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), features);
1080 
1081 	log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage
1082 		<< TestLog::Message << *features << TestLog::EndMessage;
1083 
1084 	// Requirements and dependencies
1085 	{
1086 		if (!features->robustBufferAccess)
1087 			return tcu::TestStatus::fail("robustBufferAccess is not supported");
1088 
1089 		// multiViewport requires MultiViewport (SPIR-V capability) support, which depends on Geometry
1090 		if (features->multiViewport && !features->geometryShader)
1091 			return tcu::TestStatus::fail("multiViewport is supported but geometryShader is not");
1092 	}
1093 
1094 	for (int ndx = 0; ndx < GUARD_SIZE; ndx++)
1095 	{
1096 		if (buffer[ndx + sizeof(VkPhysicalDeviceFeatures)] != GUARD_VALUE)
1097 		{
1098 			log << TestLog::Message << "deviceFeatures - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
1099 			return tcu::TestStatus::fail("deviceFeatures buffer overflow");
1100 		}
1101 	}
1102 
1103 	if (!validateInitComplete(context.getPhysicalDevice(), &InstanceInterface::getPhysicalDeviceFeatures, context.getInstanceInterface(), featureOffsetTable))
1104 	{
1105 		log << TestLog::Message << "deviceFeatures - VkPhysicalDeviceFeatures not completely initialized" << TestLog::EndMessage;
1106 		return tcu::TestStatus::fail("deviceFeatures incomplete initialization");
1107 	}
1108 
1109 	return tcu::TestStatus::pass("Query succeeded");
1110 }
1111 
1112 static const ValidateQueryBits::QueryMemberTableEntry s_physicalDevicePropertiesOffsetTable[] =
1113 {
1114 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, apiVersion),
1115 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, driverVersion),
1116 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, vendorID),
1117 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, deviceID),
1118 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, deviceType),
1119 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, pipelineCacheUUID),
1120 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxImageDimension1D),
1121 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxImageDimension2D),
1122 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxImageDimension3D),
1123 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxImageDimensionCube),
1124 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxImageArrayLayers),
1125 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTexelBufferElements),
1126 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxUniformBufferRange),
1127 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxStorageBufferRange),
1128 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPushConstantsSize),
1129 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxMemoryAllocationCount),
1130 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxSamplerAllocationCount),
1131 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.bufferImageGranularity),
1132 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.sparseAddressSpaceSize),
1133 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxBoundDescriptorSets),
1134 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageDescriptorSamplers),
1135 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageDescriptorUniformBuffers),
1136 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageDescriptorStorageBuffers),
1137 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageDescriptorSampledImages),
1138 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageDescriptorStorageImages),
1139 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageDescriptorInputAttachments),
1140 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageResources),
1141 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetSamplers),
1142 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetUniformBuffers),
1143 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetUniformBuffersDynamic),
1144 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetStorageBuffers),
1145 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetStorageBuffersDynamic),
1146 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetSampledImages),
1147 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetStorageImages),
1148 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetInputAttachments),
1149 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxVertexInputAttributes),
1150 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxVertexInputBindings),
1151 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxVertexInputAttributeOffset),
1152 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxVertexInputBindingStride),
1153 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxVertexOutputComponents),
1154 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationGenerationLevel),
1155 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationPatchSize),
1156 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationControlPerVertexInputComponents),
1157 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationControlPerVertexOutputComponents),
1158 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationControlPerPatchOutputComponents),
1159 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationControlTotalOutputComponents),
1160 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationEvaluationInputComponents),
1161 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationEvaluationOutputComponents),
1162 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxGeometryShaderInvocations),
1163 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxGeometryInputComponents),
1164 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxGeometryOutputComponents),
1165 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxGeometryOutputVertices),
1166 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxGeometryTotalOutputComponents),
1167 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFragmentInputComponents),
1168 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFragmentOutputAttachments),
1169 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFragmentDualSrcAttachments),
1170 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFragmentCombinedOutputResources),
1171 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxComputeSharedMemorySize),
1172 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxComputeWorkGroupCount[3]),
1173 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxComputeWorkGroupInvocations),
1174 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxComputeWorkGroupSize[3]),
1175 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.subPixelPrecisionBits),
1176 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.subTexelPrecisionBits),
1177 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.mipmapPrecisionBits),
1178 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDrawIndexedIndexValue),
1179 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDrawIndirectCount),
1180 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxSamplerLodBias),
1181 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxSamplerAnisotropy),
1182 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxViewports),
1183 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxViewportDimensions[2]),
1184 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.viewportBoundsRange[2]),
1185 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.viewportSubPixelBits),
1186 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minMemoryMapAlignment),
1187 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minTexelBufferOffsetAlignment),
1188 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minUniformBufferOffsetAlignment),
1189 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minStorageBufferOffsetAlignment),
1190 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minTexelOffset),
1191 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTexelOffset),
1192 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minTexelGatherOffset),
1193 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTexelGatherOffset),
1194 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minInterpolationOffset),
1195 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxInterpolationOffset),
1196 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.subPixelInterpolationOffsetBits),
1197 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFramebufferWidth),
1198 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFramebufferHeight),
1199 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFramebufferLayers),
1200 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.framebufferColorSampleCounts),
1201 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.framebufferDepthSampleCounts),
1202 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.framebufferStencilSampleCounts),
1203 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.framebufferNoAttachmentsSampleCounts),
1204 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxColorAttachments),
1205 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.sampledImageColorSampleCounts),
1206 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.sampledImageIntegerSampleCounts),
1207 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.sampledImageDepthSampleCounts),
1208 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.sampledImageStencilSampleCounts),
1209 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.storageImageSampleCounts),
1210 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxSampleMaskWords),
1211 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.timestampComputeAndGraphics),
1212 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.timestampPeriod),
1213 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxClipDistances),
1214 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxCullDistances),
1215 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxCombinedClipAndCullDistances),
1216 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.discreteQueuePriorities),
1217 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.pointSizeRange[2]),
1218 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.lineWidthRange[2]),
1219 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.pointSizeGranularity),
1220 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.lineWidthGranularity),
1221 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.strictLines),
1222 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.standardSampleLocations),
1223 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.optimalBufferCopyOffsetAlignment),
1224 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.optimalBufferCopyRowPitchAlignment),
1225 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.nonCoherentAtomSize),
1226 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, sparseProperties.residencyStandard2DBlockShape),
1227 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, sparseProperties.residencyStandard2DMultisampleBlockShape),
1228 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, sparseProperties.residencyStandard3DBlockShape),
1229 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, sparseProperties.residencyAlignedMipSize),
1230 	OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, sparseProperties.residencyNonResidentStrict),
1231 	{ 0, 0 }
1232 };
1233 
deviceProperties(Context & context)1234 tcu::TestStatus deviceProperties (Context& context)
1235 {
1236 	using namespace ValidateQueryBits;
1237 
1238 	TestLog&						log			= context.getTestContext().getLog();
1239 	VkPhysicalDeviceProperties*		props;
1240 	VkPhysicalDeviceFeatures		features;
1241 	deUint8							buffer[sizeof(VkPhysicalDeviceProperties) + GUARD_SIZE];
1242 
1243 	props = reinterpret_cast<VkPhysicalDeviceProperties*>(buffer);
1244 	deMemset(props, GUARD_VALUE, sizeof(buffer));
1245 
1246 	context.getInstanceInterface().getPhysicalDeviceProperties(context.getPhysicalDevice(), props);
1247 	context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), &features);
1248 
1249 	log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage
1250 		<< TestLog::Message << *props << TestLog::EndMessage;
1251 
1252 	if (!validateFeatureLimits(props, &features, log))
1253 		return tcu::TestStatus::fail("deviceProperties - feature limits failed");
1254 
1255 	for (int ndx = 0; ndx < GUARD_SIZE; ndx++)
1256 	{
1257 		if (buffer[ndx + sizeof(VkPhysicalDeviceProperties)] != GUARD_VALUE)
1258 		{
1259 			log << TestLog::Message << "deviceProperties - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
1260 			return tcu::TestStatus::fail("deviceProperties buffer overflow");
1261 		}
1262 	}
1263 
1264 	if (!validateInitComplete(context.getPhysicalDevice(), &InstanceInterface::getPhysicalDeviceProperties, context.getInstanceInterface(), s_physicalDevicePropertiesOffsetTable))
1265 	{
1266 		log << TestLog::Message << "deviceProperties - VkPhysicalDeviceProperties not completely initialized" << TestLog::EndMessage;
1267 		return tcu::TestStatus::fail("deviceProperties incomplete initialization");
1268 	}
1269 
1270 	// Check if deviceName string is properly terminated.
1271 	if (deStrnlen(props->deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE) == VK_MAX_PHYSICAL_DEVICE_NAME_SIZE)
1272 	{
1273 		log << TestLog::Message << "deviceProperties - VkPhysicalDeviceProperties deviceName not properly initialized" << TestLog::EndMessage;
1274 		return tcu::TestStatus::fail("deviceProperties incomplete initialization");
1275 	}
1276 
1277 	{
1278 		const ApiVersion deviceVersion = unpackVersion(props->apiVersion);
1279 		const ApiVersion deqpVersion = unpackVersion(VK_API_VERSION_1_1);
1280 
1281 		if (deviceVersion.majorNum != deqpVersion.majorNum)
1282 		{
1283 			log << TestLog::Message << "deviceProperties - API Major Version " << deviceVersion.majorNum << " is not valid" << TestLog::EndMessage;
1284 			return tcu::TestStatus::fail("deviceProperties apiVersion not valid");
1285 		}
1286 
1287 		if (deviceVersion.minorNum > deqpVersion.minorNum)
1288 		{
1289 			log << TestLog::Message << "deviceProperties - API Minor Version " << deviceVersion.minorNum << " is not valid for this version of dEQP" << TestLog::EndMessage;
1290 			return tcu::TestStatus::fail("deviceProperties apiVersion not valid");
1291 		}
1292 	}
1293 
1294 	return tcu::TestStatus::pass("DeviceProperites query succeeded");
1295 }
1296 
deviceQueueFamilyProperties(Context & context)1297 tcu::TestStatus deviceQueueFamilyProperties (Context& context)
1298 {
1299 	TestLog&								log					= context.getTestContext().getLog();
1300 	const vector<VkQueueFamilyProperties>	queueProperties		= getPhysicalDeviceQueueFamilyProperties(context.getInstanceInterface(), context.getPhysicalDevice());
1301 
1302 	log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage;
1303 
1304 	for (size_t queueNdx = 0; queueNdx < queueProperties.size(); queueNdx++)
1305 		log << TestLog::Message << queueNdx << ": " << queueProperties[queueNdx] << TestLog::EndMessage;
1306 
1307 	return tcu::TestStatus::pass("Querying queue properties succeeded");
1308 }
1309 
deviceMemoryProperties(Context & context)1310 tcu::TestStatus deviceMemoryProperties (Context& context)
1311 {
1312 	TestLog&							log			= context.getTestContext().getLog();
1313 	VkPhysicalDeviceMemoryProperties*	memProps;
1314 	deUint8								buffer[sizeof(VkPhysicalDeviceMemoryProperties) + GUARD_SIZE];
1315 
1316 	memProps = reinterpret_cast<VkPhysicalDeviceMemoryProperties*>(buffer);
1317 	deMemset(buffer, GUARD_VALUE, sizeof(buffer));
1318 
1319 	context.getInstanceInterface().getPhysicalDeviceMemoryProperties(context.getPhysicalDevice(), memProps);
1320 
1321 	log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage
1322 		<< TestLog::Message << *memProps << TestLog::EndMessage;
1323 
1324 	for (deInt32 ndx = 0; ndx < GUARD_SIZE; ndx++)
1325 	{
1326 		if (buffer[ndx + sizeof(VkPhysicalDeviceMemoryProperties)] != GUARD_VALUE)
1327 		{
1328 			log << TestLog::Message << "deviceMemoryProperties - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
1329 			return tcu::TestStatus::fail("deviceMemoryProperties buffer overflow");
1330 		}
1331 	}
1332 
1333 	if (memProps->memoryHeapCount >= VK_MAX_MEMORY_HEAPS)
1334 	{
1335 		log << TestLog::Message << "deviceMemoryProperties - HeapCount larger than " << (deUint32)VK_MAX_MEMORY_HEAPS << TestLog::EndMessage;
1336 		return tcu::TestStatus::fail("deviceMemoryProperties HeapCount too large");
1337 	}
1338 
1339 	if (memProps->memoryHeapCount == 1)
1340 	{
1341 		if ((memProps->memoryHeaps[0].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) == 0)
1342 		{
1343 			log << TestLog::Message << "deviceMemoryProperties - Single heap is not marked DEVICE_LOCAL" << TestLog::EndMessage;
1344 			return tcu::TestStatus::fail("deviceMemoryProperties invalid HeapFlags");
1345 		}
1346 	}
1347 
1348 	const VkMemoryPropertyFlags validPropertyFlags[] =
1349 	{
1350 		0,
1351 		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
1352 		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
1353 		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
1354 		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_CACHED_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
1355 		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
1356 		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
1357 		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_CACHED_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
1358 		VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
1359 	};
1360 
1361 	const VkMemoryPropertyFlags requiredPropertyFlags[] =
1362 	{
1363 		VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
1364 	};
1365 
1366 	bool requiredFlagsFound[DE_LENGTH_OF_ARRAY(requiredPropertyFlags)];
1367 	std::fill(DE_ARRAY_BEGIN(requiredFlagsFound), DE_ARRAY_END(requiredFlagsFound), false);
1368 
1369 	for (deUint32 memoryNdx = 0; memoryNdx < memProps->memoryTypeCount; memoryNdx++)
1370 	{
1371 		bool validPropTypeFound = false;
1372 
1373 		if (memProps->memoryTypes[memoryNdx].heapIndex >= memProps->memoryHeapCount)
1374 		{
1375 			log << TestLog::Message << "deviceMemoryProperties - heapIndex " << memProps->memoryTypes[memoryNdx].heapIndex << " larger than heapCount" << TestLog::EndMessage;
1376 			return tcu::TestStatus::fail("deviceMemoryProperties - invalid heapIndex");
1377 		}
1378 
1379 		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;
1380 
1381 		for (const VkMemoryPropertyFlags* requiredFlagsIterator = DE_ARRAY_BEGIN(requiredPropertyFlags); requiredFlagsIterator != DE_ARRAY_END(requiredPropertyFlags); requiredFlagsIterator++)
1382 			if ((memProps->memoryTypes[memoryNdx].propertyFlags & *requiredFlagsIterator) == *requiredFlagsIterator)
1383 				requiredFlagsFound[requiredFlagsIterator - DE_ARRAY_BEGIN(requiredPropertyFlags)] = true;
1384 
1385 		if (de::contains(DE_ARRAY_BEGIN(validPropertyFlags), DE_ARRAY_END(validPropertyFlags), memProps->memoryTypes[memoryNdx].propertyFlags & bitsToCheck))
1386 			validPropTypeFound = true;
1387 
1388 		if (!validPropTypeFound)
1389 		{
1390 			log << TestLog::Message << "deviceMemoryProperties - propertyFlags "
1391 				<< memProps->memoryTypes[memoryNdx].propertyFlags << " not valid" << TestLog::EndMessage;
1392 			return tcu::TestStatus::fail("deviceMemoryProperties propertyFlags not valid");
1393 		}
1394 
1395 		if (memProps->memoryTypes[memoryNdx].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
1396 		{
1397 			if ((memProps->memoryHeaps[memProps->memoryTypes[memoryNdx].heapIndex].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) == 0)
1398 			{
1399 				log << TestLog::Message << "deviceMemoryProperties - DEVICE_LOCAL memory type references heap which is not DEVICE_LOCAL" << TestLog::EndMessage;
1400 				return tcu::TestStatus::fail("deviceMemoryProperties inconsistent memoryType and HeapFlags");
1401 			}
1402 		}
1403 		else
1404 		{
1405 			if (memProps->memoryHeaps[memProps->memoryTypes[memoryNdx].heapIndex].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)
1406 			{
1407 				log << TestLog::Message << "deviceMemoryProperties - non-DEVICE_LOCAL memory type references heap with is DEVICE_LOCAL" << TestLog::EndMessage;
1408 				return tcu::TestStatus::fail("deviceMemoryProperties inconsistent memoryType and HeapFlags");
1409 			}
1410 		}
1411 	}
1412 
1413 	bool* requiredFlagsFoundIterator = std::find(DE_ARRAY_BEGIN(requiredFlagsFound), DE_ARRAY_END(requiredFlagsFound), false);
1414 	if (requiredFlagsFoundIterator != DE_ARRAY_END(requiredFlagsFound))
1415 	{
1416 		DE_ASSERT(requiredFlagsFoundIterator - DE_ARRAY_BEGIN(requiredFlagsFound) <= DE_LENGTH_OF_ARRAY(requiredPropertyFlags));
1417 		log << TestLog::Message << "deviceMemoryProperties - required property flags "
1418 			<< getMemoryPropertyFlagsStr(requiredPropertyFlags[requiredFlagsFoundIterator - DE_ARRAY_BEGIN(requiredFlagsFound)]) << " not found" << TestLog::EndMessage;
1419 
1420 		return tcu::TestStatus::fail("deviceMemoryProperties propertyFlags not valid");
1421 	}
1422 
1423 	return tcu::TestStatus::pass("Querying memory properties succeeded");
1424 }
1425 
deviceGroupPeerMemoryFeatures(Context & context)1426 tcu::TestStatus deviceGroupPeerMemoryFeatures (Context& context)
1427 {
1428 	TestLog&							log						= context.getTestContext().getLog();
1429 	const PlatformInterface&			vkp						= context.getPlatformInterface();
1430 	const Unique<VkInstance>			instance				(createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_device_group_creation"));
1431 	const InstanceDriver				vki						(vkp, *instance);
1432 	const tcu::CommandLine&				cmdLine					= context.getTestContext().getCommandLine();
1433 	const deUint32						devGroupIdx				= cmdLine.getVKDeviceGroupId() - 1;
1434 	const deUint32						deviceIdx				= vk::chooseDeviceIndex(context.getInstanceInterface(), *instance, cmdLine);
1435 	const float							queuePriority			= 1.0f;
1436 	VkPhysicalDeviceMemoryProperties	memProps;
1437 	VkPeerMemoryFeatureFlags*			peerMemFeatures;
1438 	deUint8								buffer					[sizeof(VkPeerMemoryFeatureFlags) + GUARD_SIZE];
1439 	deUint32							numPhysicalDevices		= 0;
1440 	deUint32							queueFamilyIndex		= 0;
1441 
1442 	const vector<VkPhysicalDeviceGroupProperties>		deviceGroupProps = enumeratePhysicalDeviceGroups(vki, *instance);
1443 	std::vector<const char*>							deviceExtensions;
1444 	deviceExtensions.push_back("VK_KHR_device_group");
1445 
1446 	if (!isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_device_group"))
1447 		deviceExtensions.push_back("VK_KHR_device_group");
1448 
1449 	const std::vector<VkQueueFamilyProperties>	queueProps		= getPhysicalDeviceQueueFamilyProperties(vki, deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx]);
1450 	for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
1451 	{
1452 		if (queueProps[queueNdx].queueFlags & VK_QUEUE_GRAPHICS_BIT)
1453 			queueFamilyIndex = (deUint32)queueNdx;
1454 	}
1455 	const VkDeviceQueueCreateInfo		deviceQueueCreateInfo	=
1456 	{
1457 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,			//type
1458 		DE_NULL,											//pNext
1459 		(VkDeviceQueueCreateFlags)0u,						//flags
1460 		queueFamilyIndex,									//queueFamilyIndex;
1461 		1u,													//queueCount;
1462 		&queuePriority,										//pQueuePriorities;
1463 	};
1464 
1465 	// Need atleast 2 devices for peer memory features
1466 	numPhysicalDevices = deviceGroupProps[devGroupIdx].physicalDeviceCount;
1467 	if (numPhysicalDevices < 2)
1468 		TCU_THROW(NotSupportedError, "Need a device Group with at least 2 physical devices.");
1469 
1470 	// Create device groups
1471 	const VkDeviceGroupDeviceCreateInfo						deviceGroupInfo =
1472 	{
1473 		VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO,	//stype
1474 		DE_NULL,											//pNext
1475 		deviceGroupProps[devGroupIdx].physicalDeviceCount,	//physicalDeviceCount
1476 		deviceGroupProps[devGroupIdx].physicalDevices		//physicalDevices
1477 	};
1478 	const VkDeviceCreateInfo								deviceCreateInfo =
1479 	{
1480 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,							//sType;
1481 		&deviceGroupInfo,												//pNext;
1482 		(VkDeviceCreateFlags)0u,										//flags
1483 		1,																//queueRecordCount;
1484 		&deviceQueueCreateInfo,											//pRequestedQueues;
1485 		0,																//layerCount;
1486 		DE_NULL,														//ppEnabledLayerNames;
1487 		deUint32(deviceExtensions.size()),								//extensionCount;
1488 		(deviceExtensions.empty() ? DE_NULL : &deviceExtensions[0]),	//ppEnabledExtensionNames;
1489 		DE_NULL,														//pEnabledFeatures;
1490 	};
1491 
1492 	Move<VkDevice>		deviceGroup = createDevice(vkp, *instance, vki, deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx], &deviceCreateInfo);
1493 	const DeviceDriver	vk	(vkp, *instance, *deviceGroup);
1494 	context.getInstanceInterface().getPhysicalDeviceMemoryProperties(deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx], &memProps);
1495 
1496 	peerMemFeatures = reinterpret_cast<VkPeerMemoryFeatureFlags*>(buffer);
1497 	deMemset(buffer, GUARD_VALUE, sizeof(buffer));
1498 
1499 	for (deUint32 heapIndex = 0; heapIndex < memProps.memoryHeapCount; heapIndex++)
1500 	{
1501 		for (deUint32 localDeviceIndex = 0; localDeviceIndex < numPhysicalDevices; localDeviceIndex++)
1502 		{
1503 			for (deUint32 remoteDeviceIndex = 0; remoteDeviceIndex < numPhysicalDevices; remoteDeviceIndex++)
1504 			{
1505 				if (localDeviceIndex != remoteDeviceIndex)
1506 				{
1507 					vk.getDeviceGroupPeerMemoryFeatures(deviceGroup.get(), heapIndex, localDeviceIndex, remoteDeviceIndex, peerMemFeatures);
1508 
1509 					// Check guard
1510 					for (deInt32 ndx = 0; ndx < GUARD_SIZE; ndx++)
1511 					{
1512 						if (buffer[ndx + sizeof(VkPeerMemoryFeatureFlags)] != GUARD_VALUE)
1513 						{
1514 							log << TestLog::Message << "deviceGroupPeerMemoryFeatures - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
1515 							return tcu::TestStatus::fail("deviceGroupPeerMemoryFeatures buffer overflow");
1516 						}
1517 					}
1518 
1519 					VkPeerMemoryFeatureFlags requiredFlag = VK_PEER_MEMORY_FEATURE_COPY_DST_BIT;
1520 					VkPeerMemoryFeatureFlags maxValidFlag = VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT|VK_PEER_MEMORY_FEATURE_COPY_DST_BIT|
1521 																VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT|VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT;
1522 					if ((!(*peerMemFeatures & requiredFlag)) ||
1523 						*peerMemFeatures > maxValidFlag)
1524 						return tcu::TestStatus::fail("deviceGroupPeerMemoryFeatures invalid flag");
1525 
1526 					log << TestLog::Message << "deviceGroup = " << deviceGroup.get() << TestLog::EndMessage
1527 						<< TestLog::Message << "heapIndex = " << heapIndex << TestLog::EndMessage
1528 						<< TestLog::Message << "localDeviceIndex = " << localDeviceIndex << TestLog::EndMessage
1529 						<< TestLog::Message << "remoteDeviceIndex = " << remoteDeviceIndex << TestLog::EndMessage
1530 						<< TestLog::Message << "PeerMemoryFeatureFlags = " << *peerMemFeatures << TestLog::EndMessage;
1531 				}
1532 			} // remote device
1533 		} // local device
1534 	} // heap Index
1535 
1536 	return tcu::TestStatus::pass("Querying deviceGroup peer memory features succeeded");
1537 }
1538 
1539 // \todo [2016-01-22 pyry] Optimize by doing format -> flags mapping instead
1540 
getRequiredOptimalTilingFeatures(VkFormat format)1541 VkFormatFeatureFlags getRequiredOptimalTilingFeatures (VkFormat format)
1542 {
1543 	static const VkFormat s_requiredSampledImageBlitSrcFormats[] =
1544 	{
1545 		VK_FORMAT_B4G4R4A4_UNORM_PACK16,
1546 		VK_FORMAT_R5G6B5_UNORM_PACK16,
1547 		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
1548 		VK_FORMAT_R8_UNORM,
1549 		VK_FORMAT_R8_SNORM,
1550 		VK_FORMAT_R8_UINT,
1551 		VK_FORMAT_R8_SINT,
1552 		VK_FORMAT_R8G8_UNORM,
1553 		VK_FORMAT_R8G8_SNORM,
1554 		VK_FORMAT_R8G8_UINT,
1555 		VK_FORMAT_R8G8_SINT,
1556 		VK_FORMAT_R8G8B8A8_UNORM,
1557 		VK_FORMAT_R8G8B8A8_SNORM,
1558 		VK_FORMAT_R8G8B8A8_UINT,
1559 		VK_FORMAT_R8G8B8A8_SINT,
1560 		VK_FORMAT_R8G8B8A8_SRGB,
1561 		VK_FORMAT_B8G8R8A8_UNORM,
1562 		VK_FORMAT_B8G8R8A8_SRGB,
1563 		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1564 		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1565 		VK_FORMAT_A8B8G8R8_UINT_PACK32,
1566 		VK_FORMAT_A8B8G8R8_SINT_PACK32,
1567 		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
1568 		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1569 		VK_FORMAT_A2B10G10R10_UINT_PACK32,
1570 		VK_FORMAT_R16_UINT,
1571 		VK_FORMAT_R16_SINT,
1572 		VK_FORMAT_R16_SFLOAT,
1573 		VK_FORMAT_R16G16_UINT,
1574 		VK_FORMAT_R16G16_SINT,
1575 		VK_FORMAT_R16G16_SFLOAT,
1576 		VK_FORMAT_R16G16B16A16_UINT,
1577 		VK_FORMAT_R16G16B16A16_SINT,
1578 		VK_FORMAT_R16G16B16A16_SFLOAT,
1579 		VK_FORMAT_R32_UINT,
1580 		VK_FORMAT_R32_SINT,
1581 		VK_FORMAT_R32_SFLOAT,
1582 		VK_FORMAT_R32G32_UINT,
1583 		VK_FORMAT_R32G32_SINT,
1584 		VK_FORMAT_R32G32_SFLOAT,
1585 		VK_FORMAT_R32G32B32A32_UINT,
1586 		VK_FORMAT_R32G32B32A32_SINT,
1587 		VK_FORMAT_R32G32B32A32_SFLOAT,
1588 		VK_FORMAT_B10G11R11_UFLOAT_PACK32,
1589 		VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
1590 		VK_FORMAT_D16_UNORM,
1591 		VK_FORMAT_D32_SFLOAT
1592 	};
1593 	static const VkFormat s_requiredSampledImageFilterLinearFormats[] =
1594 	{
1595 		VK_FORMAT_B4G4R4A4_UNORM_PACK16,
1596 		VK_FORMAT_R5G6B5_UNORM_PACK16,
1597 		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
1598 		VK_FORMAT_R8_UNORM,
1599 		VK_FORMAT_R8_SNORM,
1600 		VK_FORMAT_R8G8_UNORM,
1601 		VK_FORMAT_R8G8_SNORM,
1602 		VK_FORMAT_R8G8B8A8_UNORM,
1603 		VK_FORMAT_R8G8B8A8_SNORM,
1604 		VK_FORMAT_R8G8B8A8_SRGB,
1605 		VK_FORMAT_B8G8R8A8_UNORM,
1606 		VK_FORMAT_B8G8R8A8_SRGB,
1607 		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1608 		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1609 		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
1610 		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1611 		VK_FORMAT_R16_SFLOAT,
1612 		VK_FORMAT_R16G16_SFLOAT,
1613 		VK_FORMAT_R16G16B16A16_SFLOAT,
1614 		VK_FORMAT_B10G11R11_UFLOAT_PACK32,
1615 		VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
1616 	};
1617 	static const VkFormat s_requiredStorageImageFormats[] =
1618 	{
1619 		VK_FORMAT_R8G8B8A8_UNORM,
1620 		VK_FORMAT_R8G8B8A8_SNORM,
1621 		VK_FORMAT_R8G8B8A8_UINT,
1622 		VK_FORMAT_R8G8B8A8_SINT,
1623 		VK_FORMAT_R16G16B16A16_UINT,
1624 		VK_FORMAT_R16G16B16A16_SINT,
1625 		VK_FORMAT_R16G16B16A16_SFLOAT,
1626 		VK_FORMAT_R32_UINT,
1627 		VK_FORMAT_R32_SINT,
1628 		VK_FORMAT_R32_SFLOAT,
1629 		VK_FORMAT_R32G32_UINT,
1630 		VK_FORMAT_R32G32_SINT,
1631 		VK_FORMAT_R32G32_SFLOAT,
1632 		VK_FORMAT_R32G32B32A32_UINT,
1633 		VK_FORMAT_R32G32B32A32_SINT,
1634 		VK_FORMAT_R32G32B32A32_SFLOAT
1635 	};
1636 	static const VkFormat s_requiredStorageImageAtomicFormats[] =
1637 	{
1638 		VK_FORMAT_R32_UINT,
1639 		VK_FORMAT_R32_SINT
1640 	};
1641 	static const VkFormat s_requiredColorAttachmentBlitDstFormats[] =
1642 	{
1643 		VK_FORMAT_R5G6B5_UNORM_PACK16,
1644 		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
1645 		VK_FORMAT_R8_UNORM,
1646 		VK_FORMAT_R8_UINT,
1647 		VK_FORMAT_R8_SINT,
1648 		VK_FORMAT_R8G8_UNORM,
1649 		VK_FORMAT_R8G8_UINT,
1650 		VK_FORMAT_R8G8_SINT,
1651 		VK_FORMAT_R8G8B8A8_UNORM,
1652 		VK_FORMAT_R8G8B8A8_UINT,
1653 		VK_FORMAT_R8G8B8A8_SINT,
1654 		VK_FORMAT_R8G8B8A8_SRGB,
1655 		VK_FORMAT_B8G8R8A8_UNORM,
1656 		VK_FORMAT_B8G8R8A8_SRGB,
1657 		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1658 		VK_FORMAT_A8B8G8R8_UINT_PACK32,
1659 		VK_FORMAT_A8B8G8R8_SINT_PACK32,
1660 		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
1661 		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1662 		VK_FORMAT_A2B10G10R10_UINT_PACK32,
1663 		VK_FORMAT_R16_UINT,
1664 		VK_FORMAT_R16_SINT,
1665 		VK_FORMAT_R16_SFLOAT,
1666 		VK_FORMAT_R16G16_UINT,
1667 		VK_FORMAT_R16G16_SINT,
1668 		VK_FORMAT_R16G16_SFLOAT,
1669 		VK_FORMAT_R16G16B16A16_UINT,
1670 		VK_FORMAT_R16G16B16A16_SINT,
1671 		VK_FORMAT_R16G16B16A16_SFLOAT,
1672 		VK_FORMAT_R32_UINT,
1673 		VK_FORMAT_R32_SINT,
1674 		VK_FORMAT_R32_SFLOAT,
1675 		VK_FORMAT_R32G32_UINT,
1676 		VK_FORMAT_R32G32_SINT,
1677 		VK_FORMAT_R32G32_SFLOAT,
1678 		VK_FORMAT_R32G32B32A32_UINT,
1679 		VK_FORMAT_R32G32B32A32_SINT,
1680 		VK_FORMAT_R32G32B32A32_SFLOAT
1681 	};
1682 	static const VkFormat s_requiredColorAttachmentBlendFormats[] =
1683 	{
1684 		VK_FORMAT_R5G6B5_UNORM_PACK16,
1685 		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
1686 		VK_FORMAT_R8_UNORM,
1687 		VK_FORMAT_R8G8_UNORM,
1688 		VK_FORMAT_R8G8B8A8_UNORM,
1689 		VK_FORMAT_R8G8B8A8_SRGB,
1690 		VK_FORMAT_B8G8R8A8_UNORM,
1691 		VK_FORMAT_B8G8R8A8_SRGB,
1692 		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1693 		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
1694 		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1695 		VK_FORMAT_R16_SFLOAT,
1696 		VK_FORMAT_R16G16_SFLOAT,
1697 		VK_FORMAT_R16G16B16A16_SFLOAT
1698 	};
1699 	static const VkFormat s_requiredDepthStencilAttachmentFormats[] =
1700 	{
1701 		VK_FORMAT_D16_UNORM
1702 	};
1703 
1704 	VkFormatFeatureFlags	flags	= (VkFormatFeatureFlags)0;
1705 
1706 	if (de::contains(DE_ARRAY_BEGIN(s_requiredSampledImageBlitSrcFormats), DE_ARRAY_END(s_requiredSampledImageBlitSrcFormats), format))
1707 		flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT|VK_FORMAT_FEATURE_BLIT_SRC_BIT;
1708 
1709 	if (de::contains(DE_ARRAY_BEGIN(s_requiredSampledImageFilterLinearFormats), DE_ARRAY_END(s_requiredSampledImageFilterLinearFormats), format))
1710 		flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
1711 
1712 	if (de::contains(DE_ARRAY_BEGIN(s_requiredStorageImageFormats), DE_ARRAY_END(s_requiredStorageImageFormats), format))
1713 		flags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
1714 
1715 	if (de::contains(DE_ARRAY_BEGIN(s_requiredStorageImageAtomicFormats), DE_ARRAY_END(s_requiredStorageImageAtomicFormats), format))
1716 		flags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT;
1717 
1718 	if (de::contains(DE_ARRAY_BEGIN(s_requiredColorAttachmentBlitDstFormats), DE_ARRAY_END(s_requiredColorAttachmentBlitDstFormats), format))
1719 		flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT|VK_FORMAT_FEATURE_BLIT_DST_BIT;
1720 
1721 	if (de::contains(DE_ARRAY_BEGIN(s_requiredColorAttachmentBlendFormats), DE_ARRAY_END(s_requiredColorAttachmentBlendFormats), format))
1722 		flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
1723 
1724 	if (de::contains(DE_ARRAY_BEGIN(s_requiredDepthStencilAttachmentFormats), DE_ARRAY_END(s_requiredDepthStencilAttachmentFormats), format))
1725 		flags |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
1726 
1727 	return flags;
1728 }
1729 
getRequiredOptimalExtendedTilingFeatures(Context & context,VkFormat format,VkFormatFeatureFlags queriedFlags)1730 VkFormatFeatureFlags getRequiredOptimalExtendedTilingFeatures (Context& context, VkFormat format, VkFormatFeatureFlags queriedFlags)
1731 {
1732 	VkFormatFeatureFlags	flags	= (VkFormatFeatureFlags)0;
1733 
1734 	// VK_EXT_sampler_filter_minmax:
1735 	//	If filterMinmaxSingleComponentFormats is VK_TRUE, the following formats must
1736 	//	support the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT feature with
1737 	//	VK_IMAGE_TILING_OPTIMAL, if they support VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT.
1738 
1739 	static const VkFormat s_requiredSampledImageFilterMinMaxFormats[] =
1740 	{
1741 		VK_FORMAT_R8_UNORM,
1742 		VK_FORMAT_R8_SNORM,
1743 		VK_FORMAT_R16_UNORM,
1744 		VK_FORMAT_R16_SNORM,
1745 		VK_FORMAT_R16_SFLOAT,
1746 		VK_FORMAT_R32_SFLOAT,
1747 		VK_FORMAT_D16_UNORM,
1748 		VK_FORMAT_X8_D24_UNORM_PACK32,
1749 		VK_FORMAT_D32_SFLOAT,
1750 		VK_FORMAT_D16_UNORM_S8_UINT,
1751 		VK_FORMAT_D24_UNORM_S8_UINT,
1752 		VK_FORMAT_D32_SFLOAT_S8_UINT,
1753 	};
1754 
1755 	if ((queriedFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
1756 	{
1757 		if (de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_EXT_sampler_filter_minmax"))
1758 		{
1759 			if (de::contains(DE_ARRAY_BEGIN(s_requiredSampledImageFilterMinMaxFormats), DE_ARRAY_END(s_requiredSampledImageFilterMinMaxFormats), format))
1760 			{
1761 				VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT	physicalDeviceSamplerMinMaxProperties =
1762 				{
1763 					VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT,
1764 					DE_NULL,
1765 					DE_FALSE,
1766 					DE_FALSE
1767 				};
1768 
1769 				{
1770 					VkPhysicalDeviceProperties2		physicalDeviceProperties;
1771 					physicalDeviceProperties.sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1772 					physicalDeviceProperties.pNext	= &physicalDeviceSamplerMinMaxProperties;
1773 
1774 					const InstanceInterface&		vk = context.getInstanceInterface();
1775 					vk.getPhysicalDeviceProperties2(context.getPhysicalDevice(), &physicalDeviceProperties);
1776 				}
1777 
1778 				if (physicalDeviceSamplerMinMaxProperties.filterMinmaxSingleComponentFormats)
1779 				{
1780 					flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT;
1781 				}
1782 			}
1783 		}
1784 	}
1785 	return flags;
1786 }
1787 
getRequiredBufferFeatures(VkFormat format)1788 VkFormatFeatureFlags getRequiredBufferFeatures (VkFormat format)
1789 {
1790 	static const VkFormat s_requiredVertexBufferFormats[] =
1791 	{
1792 		VK_FORMAT_R8_UNORM,
1793 		VK_FORMAT_R8_SNORM,
1794 		VK_FORMAT_R8_UINT,
1795 		VK_FORMAT_R8_SINT,
1796 		VK_FORMAT_R8G8_UNORM,
1797 		VK_FORMAT_R8G8_SNORM,
1798 		VK_FORMAT_R8G8_UINT,
1799 		VK_FORMAT_R8G8_SINT,
1800 		VK_FORMAT_R8G8B8A8_UNORM,
1801 		VK_FORMAT_R8G8B8A8_SNORM,
1802 		VK_FORMAT_R8G8B8A8_UINT,
1803 		VK_FORMAT_R8G8B8A8_SINT,
1804 		VK_FORMAT_B8G8R8A8_UNORM,
1805 		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1806 		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1807 		VK_FORMAT_A8B8G8R8_UINT_PACK32,
1808 		VK_FORMAT_A8B8G8R8_SINT_PACK32,
1809 		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1810 		VK_FORMAT_R16_UNORM,
1811 		VK_FORMAT_R16_SNORM,
1812 		VK_FORMAT_R16_UINT,
1813 		VK_FORMAT_R16_SINT,
1814 		VK_FORMAT_R16_SFLOAT,
1815 		VK_FORMAT_R16G16_UNORM,
1816 		VK_FORMAT_R16G16_SNORM,
1817 		VK_FORMAT_R16G16_UINT,
1818 		VK_FORMAT_R16G16_SINT,
1819 		VK_FORMAT_R16G16_SFLOAT,
1820 		VK_FORMAT_R16G16B16A16_UNORM,
1821 		VK_FORMAT_R16G16B16A16_SNORM,
1822 		VK_FORMAT_R16G16B16A16_UINT,
1823 		VK_FORMAT_R16G16B16A16_SINT,
1824 		VK_FORMAT_R16G16B16A16_SFLOAT,
1825 		VK_FORMAT_R32_UINT,
1826 		VK_FORMAT_R32_SINT,
1827 		VK_FORMAT_R32_SFLOAT,
1828 		VK_FORMAT_R32G32_UINT,
1829 		VK_FORMAT_R32G32_SINT,
1830 		VK_FORMAT_R32G32_SFLOAT,
1831 		VK_FORMAT_R32G32B32_UINT,
1832 		VK_FORMAT_R32G32B32_SINT,
1833 		VK_FORMAT_R32G32B32_SFLOAT,
1834 		VK_FORMAT_R32G32B32A32_UINT,
1835 		VK_FORMAT_R32G32B32A32_SINT,
1836 		VK_FORMAT_R32G32B32A32_SFLOAT
1837 	};
1838 	static const VkFormat s_requiredUniformTexelBufferFormats[] =
1839 	{
1840 		VK_FORMAT_R8_UNORM,
1841 		VK_FORMAT_R8_SNORM,
1842 		VK_FORMAT_R8_UINT,
1843 		VK_FORMAT_R8_SINT,
1844 		VK_FORMAT_R8G8_UNORM,
1845 		VK_FORMAT_R8G8_SNORM,
1846 		VK_FORMAT_R8G8_UINT,
1847 		VK_FORMAT_R8G8_SINT,
1848 		VK_FORMAT_R8G8B8A8_UNORM,
1849 		VK_FORMAT_R8G8B8A8_SNORM,
1850 		VK_FORMAT_R8G8B8A8_UINT,
1851 		VK_FORMAT_R8G8B8A8_SINT,
1852 		VK_FORMAT_B8G8R8A8_UNORM,
1853 		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1854 		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1855 		VK_FORMAT_A8B8G8R8_UINT_PACK32,
1856 		VK_FORMAT_A8B8G8R8_SINT_PACK32,
1857 		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1858 		VK_FORMAT_A2B10G10R10_UINT_PACK32,
1859 		VK_FORMAT_R16_UINT,
1860 		VK_FORMAT_R16_SINT,
1861 		VK_FORMAT_R16_SFLOAT,
1862 		VK_FORMAT_R16G16_UINT,
1863 		VK_FORMAT_R16G16_SINT,
1864 		VK_FORMAT_R16G16_SFLOAT,
1865 		VK_FORMAT_R16G16B16A16_UINT,
1866 		VK_FORMAT_R16G16B16A16_SINT,
1867 		VK_FORMAT_R16G16B16A16_SFLOAT,
1868 		VK_FORMAT_R32_UINT,
1869 		VK_FORMAT_R32_SINT,
1870 		VK_FORMAT_R32_SFLOAT,
1871 		VK_FORMAT_R32G32_UINT,
1872 		VK_FORMAT_R32G32_SINT,
1873 		VK_FORMAT_R32G32_SFLOAT,
1874 		VK_FORMAT_R32G32B32A32_UINT,
1875 		VK_FORMAT_R32G32B32A32_SINT,
1876 		VK_FORMAT_R32G32B32A32_SFLOAT,
1877 		VK_FORMAT_B10G11R11_UFLOAT_PACK32
1878 	};
1879 	static const VkFormat s_requiredStorageTexelBufferFormats[] =
1880 	{
1881 		VK_FORMAT_R8G8B8A8_UNORM,
1882 		VK_FORMAT_R8G8B8A8_SNORM,
1883 		VK_FORMAT_R8G8B8A8_UINT,
1884 		VK_FORMAT_R8G8B8A8_SINT,
1885 		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1886 		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1887 		VK_FORMAT_A8B8G8R8_UINT_PACK32,
1888 		VK_FORMAT_A8B8G8R8_SINT_PACK32,
1889 		VK_FORMAT_R16G16B16A16_UINT,
1890 		VK_FORMAT_R16G16B16A16_SINT,
1891 		VK_FORMAT_R16G16B16A16_SFLOAT,
1892 		VK_FORMAT_R32_UINT,
1893 		VK_FORMAT_R32_SINT,
1894 		VK_FORMAT_R32_SFLOAT,
1895 		VK_FORMAT_R32G32_UINT,
1896 		VK_FORMAT_R32G32_SINT,
1897 		VK_FORMAT_R32G32_SFLOAT,
1898 		VK_FORMAT_R32G32B32A32_UINT,
1899 		VK_FORMAT_R32G32B32A32_SINT,
1900 		VK_FORMAT_R32G32B32A32_SFLOAT
1901 	};
1902 	static const VkFormat s_requiredStorageTexelBufferAtomicFormats[] =
1903 	{
1904 		VK_FORMAT_R32_UINT,
1905 		VK_FORMAT_R32_SINT
1906 	};
1907 
1908 	VkFormatFeatureFlags	flags	= (VkFormatFeatureFlags)0;
1909 
1910 	if (de::contains(DE_ARRAY_BEGIN(s_requiredVertexBufferFormats), DE_ARRAY_END(s_requiredVertexBufferFormats), format))
1911 		flags |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT;
1912 
1913 	if (de::contains(DE_ARRAY_BEGIN(s_requiredUniformTexelBufferFormats), DE_ARRAY_END(s_requiredUniformTexelBufferFormats), format))
1914 		flags |= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT;
1915 
1916 	if (de::contains(DE_ARRAY_BEGIN(s_requiredStorageTexelBufferFormats), DE_ARRAY_END(s_requiredStorageTexelBufferFormats), format))
1917 		flags |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT;
1918 
1919 	if (de::contains(DE_ARRAY_BEGIN(s_requiredStorageTexelBufferAtomicFormats), DE_ARRAY_END(s_requiredStorageTexelBufferAtomicFormats), format))
1920 		flags |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
1921 
1922 	return flags;
1923 }
1924 
formatProperties(Context & context,VkFormat format)1925 tcu::TestStatus formatProperties (Context& context, VkFormat format)
1926 {
1927 	TestLog&					log					= context.getTestContext().getLog();
1928 	const VkFormatProperties	properties			= getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), format);
1929 	bool						allOk				= true;
1930 
1931 	// \todo [2017-05-16 pyry] This should be extended to cover for example COLOR_ATTACHMENT for depth formats etc.
1932 	// \todo [2017-05-18 pyry] Any other color conversion related features that can't be supported by regular formats?
1933 	const VkFormatFeatureFlags	extOptimalFeatures	= getRequiredOptimalExtendedTilingFeatures(context, format, properties.optimalTilingFeatures);
1934 
1935 	const VkFormatFeatureFlags	notAllowedFeatures	= VK_FORMAT_FEATURE_DISJOINT_BIT;
1936 
1937 	const struct
1938 	{
1939 		VkFormatFeatureFlags VkFormatProperties::*	field;
1940 		const char*									fieldName;
1941 		VkFormatFeatureFlags						requiredFeatures;
1942 	} fields[] =
1943 	{
1944 		{ &VkFormatProperties::linearTilingFeatures,	"linearTilingFeatures",		(VkFormatFeatureFlags)0											},
1945 		{ &VkFormatProperties::optimalTilingFeatures,	"optimalTilingFeatures",	getRequiredOptimalTilingFeatures(format) | extOptimalFeatures	},
1946 		{ &VkFormatProperties::bufferFeatures,			"bufferFeatures",			getRequiredBufferFeatures(format)								}
1947 	};
1948 
1949 	log << TestLog::Message << properties << TestLog::EndMessage;
1950 
1951 	for (int fieldNdx = 0; fieldNdx < DE_LENGTH_OF_ARRAY(fields); fieldNdx++)
1952 	{
1953 		const char* const				fieldName	= fields[fieldNdx].fieldName;
1954 		const VkFormatFeatureFlags		supported	= properties.*fields[fieldNdx].field;
1955 		const VkFormatFeatureFlags		required	= fields[fieldNdx].requiredFeatures;
1956 
1957 		if ((supported & required) != required)
1958 		{
1959 			log << TestLog::Message << "ERROR in " << fieldName << ":\n"
1960 									<< "  required: " << getFormatFeatureFlagsStr(required) << "\n  "
1961 									<< "  missing: " << getFormatFeatureFlagsStr(~supported & required)
1962 				<< TestLog::EndMessage;
1963 			allOk = false;
1964 		}
1965 
1966 		if ((supported & notAllowedFeatures) != 0)
1967 		{
1968 			log << TestLog::Message << "ERROR in " << fieldName << ":\n"
1969 									<< "  has: " << getFormatFeatureFlagsStr(supported & notAllowedFeatures)
1970 				<< TestLog::EndMessage;
1971 			allOk = false;
1972 		}
1973 	}
1974 
1975 	if (allOk)
1976 		return tcu::TestStatus::pass("Query and validation passed");
1977 	else
1978 		return tcu::TestStatus::fail("Required features not supported");
1979 }
1980 
getPhysicalDeviceSamplerYcbcrConversionFeatures(const InstanceInterface & vk,VkPhysicalDevice physicalDevice)1981 VkPhysicalDeviceSamplerYcbcrConversionFeatures getPhysicalDeviceSamplerYcbcrConversionFeatures (const InstanceInterface& vk, VkPhysicalDevice physicalDevice)
1982 {
1983 	VkPhysicalDeviceFeatures2						coreFeatures;
1984 	VkPhysicalDeviceSamplerYcbcrConversionFeatures	ycbcrFeatures;
1985 
1986 	deMemset(&coreFeatures, 0, sizeof(coreFeatures));
1987 	deMemset(&ycbcrFeatures, 0, sizeof(ycbcrFeatures));
1988 
1989 	coreFeatures.sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1990 	coreFeatures.pNext		= &ycbcrFeatures;
1991 	ycbcrFeatures.sType		= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
1992 
1993 	vk.getPhysicalDeviceFeatures2(physicalDevice, &coreFeatures);
1994 
1995 	return ycbcrFeatures;
1996 }
1997 
checkYcbcrApiSupport(Context & context)1998 void checkYcbcrApiSupport (Context& context)
1999 {
2000 	// check if YCbcr API and are supported by implementation
2001 
2002 	// the support for formats and YCbCr may still be optional - see isYcbcrConversionSupported below
2003 
2004 	if (!vk::isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_sampler_ycbcr_conversion"))
2005 	{
2006 		if (!vk::isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_sampler_ycbcr_conversion"))
2007 			TCU_THROW(NotSupportedError, "VK_KHR_sampler_ycbcr_conversion is not supported");
2008 
2009 		// Hard dependency for ycbcr
2010 		TCU_CHECK(de::contains(context.getInstanceExtensions().begin(), context.getInstanceExtensions().end(), "VK_KHR_get_physical_device_properties2"));
2011 	}
2012 }
2013 
isYcbcrConversionSupported(Context & context)2014 bool isYcbcrConversionSupported (Context& context)
2015 {
2016 	checkYcbcrApiSupport(context);
2017 
2018 	const VkPhysicalDeviceSamplerYcbcrConversionFeatures	ycbcrFeatures	= getPhysicalDeviceSamplerYcbcrConversionFeatures(context.getInstanceInterface(), context.getPhysicalDevice());
2019 
2020 	return (ycbcrFeatures.samplerYcbcrConversion == VK_TRUE);
2021 }
2022 
getAllowedYcbcrFormatFeatures(VkFormat format)2023 VkFormatFeatureFlags getAllowedYcbcrFormatFeatures (VkFormat format)
2024 {
2025 	DE_ASSERT(isYCbCrFormat(format));
2026 
2027 	VkFormatFeatureFlags	flags	= (VkFormatFeatureFlags)0;
2028 
2029 	// all formats *may* support these
2030 	flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
2031 	flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
2032 	flags |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT;
2033 	flags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
2034 	flags |= VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT;
2035 	flags |= VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT;
2036 	flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT;
2037 	flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT;
2038 	flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT;
2039 	flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT;
2040 	flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT;
2041 
2042 	// multi-plane formats *may* support DISJOINT_BIT
2043 	if (getPlaneCount(format) >= 2)
2044 		flags |= VK_FORMAT_FEATURE_DISJOINT_BIT;
2045 
2046 	if (isChromaSubsampled(format))
2047 		flags |= VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT;
2048 
2049 	return flags;
2050 }
2051 
ycbcrFormatProperties(Context & context,VkFormat format)2052 tcu::TestStatus ycbcrFormatProperties (Context& context, VkFormat format)
2053 {
2054 	DE_ASSERT(isYCbCrFormat(format));
2055 	// check if Ycbcr format enums are valid given the version and extensions
2056 	checkYcbcrApiSupport(context);
2057 
2058 	TestLog&					log						= context.getTestContext().getLog();
2059 	const VkFormatProperties	properties				= getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), format);
2060 	bool						allOk					= true;
2061 	const VkFormatFeatureFlags	allowedImageFeatures	= getAllowedYcbcrFormatFeatures(format);
2062 
2063 	const struct
2064 	{
2065 		VkFormatFeatureFlags VkFormatProperties::*	field;
2066 		const char*									fieldName;
2067 		bool										requiredFeatures;
2068 		VkFormatFeatureFlags						allowedFeatures;
2069 	} fields[] =
2070 	{
2071 		{ &VkFormatProperties::linearTilingFeatures,	"linearTilingFeatures",		false,	allowedImageFeatures	},
2072 		{ &VkFormatProperties::optimalTilingFeatures,	"optimalTilingFeatures",	true,	allowedImageFeatures	},
2073 		{ &VkFormatProperties::bufferFeatures,			"bufferFeatures",			false,	(VkFormatFeatureFlags)0	}
2074 	};
2075 	static const VkFormat		s_requiredBaseFormats[]	=
2076 	{
2077 		VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
2078 		VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM
2079 	};
2080 	const bool					isRequiredBaseFormat	= isYcbcrConversionSupported(context) &&
2081 														  de::contains(DE_ARRAY_BEGIN(s_requiredBaseFormats), DE_ARRAY_END(s_requiredBaseFormats), format);
2082 
2083 	log << TestLog::Message << properties << TestLog::EndMessage;
2084 
2085 	for (int fieldNdx = 0; fieldNdx < DE_LENGTH_OF_ARRAY(fields); fieldNdx++)
2086 	{
2087 		const char* const				fieldName	= fields[fieldNdx].fieldName;
2088 		const VkFormatFeatureFlags		supported	= properties.*fields[fieldNdx].field;
2089 		const VkFormatFeatureFlags		allowed		= fields[fieldNdx].allowedFeatures;
2090 
2091 		if (isRequiredBaseFormat && fields[fieldNdx].requiredFeatures)
2092 		{
2093 			const VkFormatFeatureFlags	required	= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
2094 													| VK_FORMAT_FEATURE_TRANSFER_SRC_BIT
2095 													| VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
2096 
2097 			if ((supported & required) != required)
2098 			{
2099 				log << TestLog::Message << "ERROR in " << fieldName << ":\n"
2100 										<< "  required: " << getFormatFeatureFlagsStr(required) << "\n  "
2101 										<< "  missing: " << getFormatFeatureFlagsStr(~supported & required)
2102 					<< TestLog::EndMessage;
2103 				allOk = false;
2104 			}
2105 
2106 			if ((supported & (VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT | VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT)) == 0)
2107 			{
2108 				log << TestLog::Message << "ERROR in " << fieldName << ":\n"
2109 										<< "  Either VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT or VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT required"
2110 					<< TestLog::EndMessage;
2111 				allOk = false;
2112 			}
2113 		}
2114 
2115 		if ((supported & ~allowed) != 0)
2116 		{
2117 			log << TestLog::Message << "ERROR in " << fieldName << ":\n"
2118 									<< "  has: " << getFormatFeatureFlagsStr(supported & ~allowed)
2119 				<< TestLog::EndMessage;
2120 			allOk = false;
2121 		}
2122 	}
2123 
2124 	if (allOk)
2125 		return tcu::TestStatus::pass("Query and validation passed");
2126 	else
2127 		return tcu::TestStatus::fail("Required features not supported");
2128 }
2129 
optimalTilingFeaturesSupported(Context & context,VkFormat format,VkFormatFeatureFlags features)2130 bool optimalTilingFeaturesSupported (Context& context, VkFormat format, VkFormatFeatureFlags features)
2131 {
2132 	const VkFormatProperties	properties	= getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), format);
2133 
2134 	return (properties.optimalTilingFeatures & features) == features;
2135 }
2136 
optimalTilingFeaturesSupportedForAll(Context & context,const VkFormat * begin,const VkFormat * end,VkFormatFeatureFlags features)2137 bool optimalTilingFeaturesSupportedForAll (Context& context, const VkFormat* begin, const VkFormat* end, VkFormatFeatureFlags features)
2138 {
2139 	for (const VkFormat* cur = begin; cur != end; ++cur)
2140 	{
2141 		if (!optimalTilingFeaturesSupported(context, *cur, features))
2142 			return false;
2143 	}
2144 
2145 	return true;
2146 }
2147 
testDepthStencilSupported(Context & context)2148 tcu::TestStatus testDepthStencilSupported (Context& context)
2149 {
2150 	if (!optimalTilingFeaturesSupported(context, VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) &&
2151 		!optimalTilingFeaturesSupported(context, VK_FORMAT_D32_SFLOAT, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
2152 		return tcu::TestStatus::fail("Doesn't support one of VK_FORMAT_X8_D24_UNORM_PACK32 or VK_FORMAT_D32_SFLOAT");
2153 
2154 	if (!optimalTilingFeaturesSupported(context, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) &&
2155 		!optimalTilingFeaturesSupported(context, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
2156 		return tcu::TestStatus::fail("Doesn't support one of VK_FORMAT_D24_UNORM_S8_UINT or VK_FORMAT_D32_SFLOAT_S8_UINT");
2157 
2158 	return tcu::TestStatus::pass("Required depth/stencil formats supported");
2159 }
2160 
testCompressedFormatsSupported(Context & context)2161 tcu::TestStatus testCompressedFormatsSupported (Context& context)
2162 {
2163 	static const VkFormat s_allBcFormats[] =
2164 	{
2165 		VK_FORMAT_BC1_RGB_UNORM_BLOCK,
2166 		VK_FORMAT_BC1_RGB_SRGB_BLOCK,
2167 		VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
2168 		VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
2169 		VK_FORMAT_BC2_UNORM_BLOCK,
2170 		VK_FORMAT_BC2_SRGB_BLOCK,
2171 		VK_FORMAT_BC3_UNORM_BLOCK,
2172 		VK_FORMAT_BC3_SRGB_BLOCK,
2173 		VK_FORMAT_BC4_UNORM_BLOCK,
2174 		VK_FORMAT_BC4_SNORM_BLOCK,
2175 		VK_FORMAT_BC5_UNORM_BLOCK,
2176 		VK_FORMAT_BC5_SNORM_BLOCK,
2177 		VK_FORMAT_BC6H_UFLOAT_BLOCK,
2178 		VK_FORMAT_BC6H_SFLOAT_BLOCK,
2179 		VK_FORMAT_BC7_UNORM_BLOCK,
2180 		VK_FORMAT_BC7_SRGB_BLOCK,
2181 	};
2182 	static const VkFormat s_allEtc2Formats[] =
2183 	{
2184 		VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
2185 		VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
2186 		VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
2187 		VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
2188 		VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
2189 		VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
2190 		VK_FORMAT_EAC_R11_UNORM_BLOCK,
2191 		VK_FORMAT_EAC_R11_SNORM_BLOCK,
2192 		VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
2193 		VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
2194 	};
2195 	static const VkFormat s_allAstcLdrFormats[] =
2196 	{
2197 		VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
2198 		VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
2199 		VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
2200 		VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
2201 		VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
2202 		VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
2203 		VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
2204 		VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
2205 		VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
2206 		VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
2207 		VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
2208 		VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
2209 		VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
2210 		VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
2211 		VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
2212 		VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
2213 		VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
2214 		VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
2215 		VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
2216 		VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
2217 		VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
2218 		VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
2219 		VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
2220 		VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
2221 		VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
2222 		VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
2223 		VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
2224 		VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
2225 	};
2226 
2227 	static const struct
2228 	{
2229 		const char*									setName;
2230 		const char*									featureName;
2231 		const VkBool32 VkPhysicalDeviceFeatures::*	feature;
2232 		const VkFormat*								formatsBegin;
2233 		const VkFormat*								formatsEnd;
2234 	} s_compressedFormatSets[] =
2235 	{
2236 		{ "BC",			"textureCompressionBC",			&VkPhysicalDeviceFeatures::textureCompressionBC,		DE_ARRAY_BEGIN(s_allBcFormats),			DE_ARRAY_END(s_allBcFormats)		},
2237 		{ "ETC2",		"textureCompressionETC2",		&VkPhysicalDeviceFeatures::textureCompressionETC2,		DE_ARRAY_BEGIN(s_allEtc2Formats),		DE_ARRAY_END(s_allEtc2Formats)		},
2238 		{ "ASTC LDR",	"textureCompressionASTC_LDR",	&VkPhysicalDeviceFeatures::textureCompressionASTC_LDR,	DE_ARRAY_BEGIN(s_allAstcLdrFormats),	DE_ARRAY_END(s_allAstcLdrFormats)	},
2239 	};
2240 
2241 	TestLog&						log					= context.getTestContext().getLog();
2242 	const VkPhysicalDeviceFeatures&	features			= context.getDeviceFeatures();
2243 	int								numSupportedSets	= 0;
2244 	int								numErrors			= 0;
2245 	int								numWarnings			= 0;
2246 
2247 	for (int setNdx = 0; setNdx < DE_LENGTH_OF_ARRAY(s_compressedFormatSets); ++setNdx)
2248 	{
2249 		const char* const	setName			= s_compressedFormatSets[setNdx].setName;
2250 		const char* const	featureName		= s_compressedFormatSets[setNdx].featureName;
2251 		const bool			featureBitSet	= features.*s_compressedFormatSets[setNdx].feature == VK_TRUE;
2252 		const bool			allSupported	= optimalTilingFeaturesSupportedForAll(context,
2253 																				   s_compressedFormatSets[setNdx].formatsBegin,
2254 																				   s_compressedFormatSets[setNdx].formatsEnd,
2255 																				   VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);
2256 
2257 		if (featureBitSet && !allSupported)
2258 		{
2259 			log << TestLog::Message << "ERROR: " << featureName << " = VK_TRUE but " << setName << " formats not supported" << TestLog::EndMessage;
2260 			numErrors += 1;
2261 		}
2262 		else if (allSupported && !featureBitSet)
2263 		{
2264 			log << TestLog::Message << "WARNING: " << setName << " formats supported but " << featureName << " = VK_FALSE" << TestLog::EndMessage;
2265 			numWarnings += 1;
2266 		}
2267 
2268 		if (featureBitSet)
2269 		{
2270 			log << TestLog::Message << "All " << setName << " formats are supported" << TestLog::EndMessage;
2271 			numSupportedSets += 1;
2272 		}
2273 		else
2274 			log << TestLog::Message << setName << " formats are not supported" << TestLog::EndMessage;
2275 	}
2276 
2277 	if (numSupportedSets == 0)
2278 	{
2279 		log << TestLog::Message << "No compressed format sets supported" << TestLog::EndMessage;
2280 		numErrors += 1;
2281 	}
2282 
2283 	if (numErrors > 0)
2284 		return tcu::TestStatus::fail("Compressed format support not valid");
2285 	else if (numWarnings > 0)
2286 		return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Found inconsistencies in compressed format support");
2287 	else
2288 		return tcu::TestStatus::pass("Compressed texture format support is valid");
2289 }
2290 
createFormatTests(tcu::TestCaseGroup * testGroup)2291 void createFormatTests (tcu::TestCaseGroup* testGroup)
2292 {
2293 	DE_STATIC_ASSERT(VK_FORMAT_UNDEFINED == 0);
2294 
2295 	static const struct
2296 	{
2297 		VkFormat								begin;
2298 		VkFormat								end;
2299 		FunctionInstance1<VkFormat>::Function	testFunction;
2300 	} s_formatRanges[] =
2301 	{
2302 		// core formats
2303 		{ (VkFormat)(VK_FORMAT_UNDEFINED+1),	VK_CORE_FORMAT_LAST,										formatProperties },
2304 
2305 		// YCbCr formats
2306 		{ VK_FORMAT_G8B8G8R8_422_UNORM,			(VkFormat)(VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM+1),	ycbcrFormatProperties },
2307 	};
2308 
2309 	for (int rangeNdx = 0; rangeNdx < DE_LENGTH_OF_ARRAY(s_formatRanges); ++rangeNdx)
2310 	{
2311 		const VkFormat								rangeBegin		= s_formatRanges[rangeNdx].begin;
2312 		const VkFormat								rangeEnd		= s_formatRanges[rangeNdx].end;
2313 		const FunctionInstance1<VkFormat>::Function	testFunction	= s_formatRanges[rangeNdx].testFunction;
2314 
2315 		for (VkFormat format = rangeBegin; format != rangeEnd; format = (VkFormat)(format+1))
2316 		{
2317 			const char* const	enumName	= getFormatName(format);
2318 			const string		caseName	= de::toLower(string(enumName).substr(10));
2319 
2320 			addFunctionCase(testGroup, caseName, enumName, testFunction, format);
2321 		}
2322 	}
2323 
2324 	addFunctionCase(testGroup, "depth_stencil",			"",	testDepthStencilSupported);
2325 	addFunctionCase(testGroup, "compressed_formats",	"",	testCompressedFormatsSupported);
2326 }
2327 
getValidImageUsageFlags(const VkFormatFeatureFlags supportedFeatures,const bool useKhrMaintenance1Semantics)2328 VkImageUsageFlags getValidImageUsageFlags (const VkFormatFeatureFlags supportedFeatures, const bool useKhrMaintenance1Semantics)
2329 {
2330 	VkImageUsageFlags	flags	= (VkImageUsageFlags)0;
2331 
2332 	if (useKhrMaintenance1Semantics)
2333 	{
2334 		if ((supportedFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) != 0)
2335 			flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2336 
2337 		if ((supportedFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) != 0)
2338 			flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2339 	}
2340 	else
2341 	{
2342 		// If format is supported at all, it must be valid transfer src+dst
2343 		if (supportedFeatures != 0)
2344 			flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2345 	}
2346 
2347 	if ((supportedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
2348 		flags |= VK_IMAGE_USAGE_SAMPLED_BIT;
2349 
2350 	if ((supportedFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) != 0)
2351 		flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT|VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
2352 
2353 	if ((supportedFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)
2354 		flags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
2355 
2356 	if ((supportedFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0)
2357 		flags |= VK_IMAGE_USAGE_STORAGE_BIT;
2358 
2359 	return flags;
2360 }
2361 
isValidImageUsageFlagCombination(VkImageUsageFlags usage)2362 bool isValidImageUsageFlagCombination (VkImageUsageFlags usage)
2363 {
2364 	if ((usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0)
2365 	{
2366 		const VkImageUsageFlags		allowedFlags	= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
2367 													| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
2368 													| VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
2369 													| VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
2370 
2371 		// Only *_ATTACHMENT_BIT flags can be combined with TRANSIENT_ATTACHMENT_BIT
2372 		if ((usage & ~allowedFlags) != 0)
2373 			return false;
2374 
2375 		// TRANSIENT_ATTACHMENT_BIT is not valid without COLOR_ or DEPTH_STENCIL_ATTACHMENT_BIT
2376 		if ((usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) == 0)
2377 			return false;
2378 	}
2379 
2380 	return usage != 0;
2381 }
2382 
getValidImageCreateFlags(const VkPhysicalDeviceFeatures & deviceFeatures,VkFormat format,VkFormatFeatureFlags formatFeatures,VkImageType type,VkImageUsageFlags usage)2383 VkImageCreateFlags getValidImageCreateFlags (const VkPhysicalDeviceFeatures& deviceFeatures, VkFormat format, VkFormatFeatureFlags formatFeatures, VkImageType type, VkImageUsageFlags usage)
2384 {
2385 	VkImageCreateFlags	flags	= (VkImageCreateFlags)0;
2386 
2387 	if ((usage & VK_IMAGE_USAGE_SAMPLED_BIT) != 0)
2388 	{
2389 		flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
2390 
2391 		if (type == VK_IMAGE_TYPE_2D && !isYCbCrFormat(format))
2392 		{
2393 			flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
2394 		}
2395 	}
2396 
2397 	if (isYCbCrFormat(format) && getPlaneCount(format) > 1)
2398 	{
2399 		if (formatFeatures & VK_FORMAT_FEATURE_DISJOINT_BIT_KHR)
2400 			flags |= VK_IMAGE_CREATE_DISJOINT_BIT_KHR;
2401 	}
2402 
2403 	if ((usage & (VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_STORAGE_BIT)) != 0 &&
2404 		(usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) == 0)
2405 	{
2406 		if (deviceFeatures.sparseBinding)
2407 			flags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT|VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT;
2408 
2409 		if (deviceFeatures.sparseResidencyAliased)
2410 			flags |= VK_IMAGE_CREATE_SPARSE_ALIASED_BIT;
2411 	}
2412 
2413 	return flags;
2414 }
2415 
isValidImageCreateFlagCombination(VkImageCreateFlags)2416 bool isValidImageCreateFlagCombination (VkImageCreateFlags)
2417 {
2418 	return true;
2419 }
2420 
isRequiredImageParameterCombination(const VkPhysicalDeviceFeatures & deviceFeatures,const VkFormat format,const VkFormatProperties & formatProperties,const VkImageType imageType,const VkImageTiling imageTiling,const VkImageUsageFlags usageFlags,const VkImageCreateFlags createFlags)2421 bool isRequiredImageParameterCombination (const VkPhysicalDeviceFeatures&	deviceFeatures,
2422 										  const VkFormat					format,
2423 										  const VkFormatProperties&			formatProperties,
2424 										  const VkImageType					imageType,
2425 										  const VkImageTiling				imageTiling,
2426 										  const VkImageUsageFlags			usageFlags,
2427 										  const VkImageCreateFlags			createFlags)
2428 {
2429 	DE_UNREF(deviceFeatures);
2430 	DE_UNREF(formatProperties);
2431 	DE_UNREF(createFlags);
2432 
2433 	// Linear images can have arbitrary limitations
2434 	if (imageTiling == VK_IMAGE_TILING_LINEAR)
2435 		return false;
2436 
2437 	// Support for other usages for compressed formats is optional
2438 	if (isCompressedFormat(format) &&
2439 		(usageFlags & ~(VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT)) != 0)
2440 		return false;
2441 
2442 	// Support for 1D, and sliced 3D compressed formats is optional
2443 	if (isCompressedFormat(format) && (imageType == VK_IMAGE_TYPE_1D || imageType == VK_IMAGE_TYPE_3D))
2444 		return false;
2445 
2446 	// Support for 1D and 3D depth/stencil textures is optional
2447 	if (isDepthStencilFormat(format) && (imageType == VK_IMAGE_TYPE_1D || imageType == VK_IMAGE_TYPE_3D))
2448 		return false;
2449 
2450 	DE_ASSERT(deviceFeatures.sparseBinding || (createFlags & (VK_IMAGE_CREATE_SPARSE_BINDING_BIT|VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)) == 0);
2451 	DE_ASSERT(deviceFeatures.sparseResidencyAliased || (createFlags & VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) == 0);
2452 
2453 	if (isYCbCrFormat(format) && (createFlags & (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)))
2454 		return false;
2455 
2456 	if (createFlags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)
2457 	{
2458 		if (isCompressedFormat(format))
2459 			return false;
2460 
2461 		if (isDepthStencilFormat(format))
2462 			return false;
2463 
2464 		if (!deIsPowerOfTwo32(mapVkFormat(format).getPixelSize()))
2465 			return false;
2466 
2467 		switch (imageType)
2468 		{
2469 			case VK_IMAGE_TYPE_2D:
2470 				return (deviceFeatures.sparseResidencyImage2D == VK_TRUE);
2471 			case VK_IMAGE_TYPE_3D:
2472 				return (deviceFeatures.sparseResidencyImage3D == VK_TRUE);
2473 			default:
2474 				return false;
2475 		}
2476 	}
2477 
2478 	return true;
2479 }
2480 
getRequiredOptimalTilingSampleCounts(const VkPhysicalDeviceLimits & deviceLimits,const VkFormat format,const VkImageUsageFlags usageFlags)2481 VkSampleCountFlags getRequiredOptimalTilingSampleCounts (const VkPhysicalDeviceLimits&	deviceLimits,
2482 														 const VkFormat					format,
2483 														 const VkImageUsageFlags		usageFlags)
2484 {
2485 	if (isCompressedFormat(format))
2486 		return VK_SAMPLE_COUNT_1_BIT;
2487 
2488 	bool		hasDepthComp	= false;
2489 	bool		hasStencilComp	= false;
2490 	const bool	isYCbCr			= isYCbCrFormat(format);
2491 	if (!isYCbCr)
2492 	{
2493 		const tcu::TextureFormat	tcuFormat		= mapVkFormat(format);
2494 		hasDepthComp	= (tcuFormat.order == tcu::TextureFormat::D || tcuFormat.order == tcu::TextureFormat::DS);
2495 		hasStencilComp	= (tcuFormat.order == tcu::TextureFormat::S || tcuFormat.order == tcu::TextureFormat::DS);
2496 	}
2497 
2498 	const bool						isColorFormat	= !hasDepthComp && !hasStencilComp;
2499 	VkSampleCountFlags				sampleCounts	= ~(VkSampleCountFlags)0;
2500 
2501 	DE_ASSERT((hasDepthComp || hasStencilComp) != isColorFormat);
2502 
2503 	if ((usageFlags & VK_IMAGE_USAGE_STORAGE_BIT) != 0)
2504 		sampleCounts &= deviceLimits.storageImageSampleCounts;
2505 
2506 	if ((usageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) != 0)
2507 	{
2508 		if (hasDepthComp)
2509 			sampleCounts &= deviceLimits.sampledImageDepthSampleCounts;
2510 
2511 		if (hasStencilComp)
2512 			sampleCounts &= deviceLimits.sampledImageStencilSampleCounts;
2513 
2514 		if (isColorFormat)
2515 		{
2516 			if (isYCbCr)
2517 				sampleCounts &= deviceLimits.sampledImageColorSampleCounts;
2518 			else
2519 			{
2520 				const tcu::TextureFormat		tcuFormat	= mapVkFormat(format);
2521 				const tcu::TextureChannelClass	chnClass	= tcu::getTextureChannelClass(tcuFormat.type);
2522 
2523 				if (chnClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ||
2524 					chnClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
2525 					sampleCounts &= deviceLimits.sampledImageIntegerSampleCounts;
2526 				else
2527 					sampleCounts &= deviceLimits.sampledImageColorSampleCounts;
2528 			}
2529 		}
2530 	}
2531 
2532 	if ((usageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) != 0)
2533 		sampleCounts &= deviceLimits.framebufferColorSampleCounts;
2534 
2535 	if ((usageFlags & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)
2536 	{
2537 		if (hasDepthComp)
2538 			sampleCounts &= deviceLimits.framebufferDepthSampleCounts;
2539 
2540 		if (hasStencilComp)
2541 			sampleCounts &= deviceLimits.framebufferStencilSampleCounts;
2542 	}
2543 
2544 	// If there is no usage flag set that would have corresponding device limit,
2545 	// only VK_SAMPLE_COUNT_1_BIT is required.
2546 	if (sampleCounts == ~(VkSampleCountFlags)0)
2547 		sampleCounts &= VK_SAMPLE_COUNT_1_BIT;
2548 
2549 	return sampleCounts;
2550 }
2551 
2552 struct ImageFormatPropertyCase
2553 {
2554 	typedef tcu::TestStatus (*Function) (Context& context, const VkFormat format, const VkImageType imageType, const VkImageTiling tiling);
2555 
2556 	Function		testFunction;
2557 	VkFormat		format;
2558 	VkImageType		imageType;
2559 	VkImageTiling	tiling;
2560 
ImageFormatPropertyCasevkt::api::__anon0f62d5780111::ImageFormatPropertyCase2561 	ImageFormatPropertyCase (Function testFunction_, VkFormat format_, VkImageType imageType_, VkImageTiling tiling_)
2562 		: testFunction	(testFunction_)
2563 		, format		(format_)
2564 		, imageType		(imageType_)
2565 		, tiling		(tiling_)
2566 	{}
2567 
ImageFormatPropertyCasevkt::api::__anon0f62d5780111::ImageFormatPropertyCase2568 	ImageFormatPropertyCase (void)
2569 		: testFunction	((Function)DE_NULL)
2570 		, format		(VK_FORMAT_UNDEFINED)
2571 		, imageType		(VK_IMAGE_TYPE_LAST)
2572 		, tiling		(VK_IMAGE_TILING_LAST)
2573 	{}
2574 };
2575 
imageFormatProperties(Context & context,const VkFormat format,const VkImageType imageType,const VkImageTiling tiling)2576 tcu::TestStatus imageFormatProperties (Context& context, const VkFormat format, const VkImageType imageType, const VkImageTiling tiling)
2577 {
2578 	if (isYCbCrFormat(format))
2579 		// check if Ycbcr format enums are valid given the version and extensions
2580 		checkYcbcrApiSupport(context);
2581 
2582 	TestLog&						log					= context.getTestContext().getLog();
2583 	const VkPhysicalDeviceFeatures&	deviceFeatures		= context.getDeviceFeatures();
2584 	const VkPhysicalDeviceLimits&	deviceLimits		= context.getDeviceProperties().limits;
2585 	const VkFormatProperties		formatProperties	= getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), format);
2586 	const bool						hasKhrMaintenance1	= isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance1");
2587 
2588 	const VkFormatFeatureFlags		supportedFeatures	= tiling == VK_IMAGE_TILING_LINEAR ? formatProperties.linearTilingFeatures : formatProperties.optimalTilingFeatures;
2589 	const VkImageUsageFlags			usageFlagSet		= getValidImageUsageFlags(supportedFeatures, hasKhrMaintenance1);
2590 
2591 	tcu::ResultCollector			results				(log, "ERROR: ");
2592 
2593 	if (hasKhrMaintenance1 && (supportedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
2594 	{
2595 		results.check((supportedFeatures & (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT|VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) != 0,
2596 					  "A sampled image format must have VK_FORMAT_FEATURE_TRANSFER_SRC_BIT and VK_FORMAT_FEATURE_TRANSFER_DST_BIT format feature flags set");
2597 	}
2598 
2599 	if (isYcbcrConversionSupported(context) && (format == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR || format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR))
2600 	{
2601 		VkFormatFeatureFlags requiredFeatures = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR | VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR;
2602 		if (tiling == VK_IMAGE_TILING_OPTIMAL)
2603 			requiredFeatures |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT_KHR;
2604 
2605 		results.check((supportedFeatures & requiredFeatures) == requiredFeatures,
2606 					  getFormatName(format) + string(" must support ") + de::toString(getFormatFeatureFlagsStr(requiredFeatures)));
2607 	}
2608 
2609 	for (VkImageUsageFlags curUsageFlags = 0; curUsageFlags <= usageFlagSet; curUsageFlags++)
2610 	{
2611 		if ((curUsageFlags & ~usageFlagSet) != 0 ||
2612 			!isValidImageUsageFlagCombination(curUsageFlags))
2613 			continue;
2614 
2615 		const VkImageCreateFlags	createFlagSet		= getValidImageCreateFlags(deviceFeatures, format, supportedFeatures, imageType, curUsageFlags);
2616 
2617 		for (VkImageCreateFlags curCreateFlags = 0; curCreateFlags <= createFlagSet; curCreateFlags++)
2618 		{
2619 			if ((curCreateFlags & ~createFlagSet) != 0 ||
2620 				!isValidImageCreateFlagCombination(curCreateFlags))
2621 				continue;
2622 
2623 			const bool				isRequiredCombination	= isRequiredImageParameterCombination(deviceFeatures,
2624 																								  format,
2625 																								  formatProperties,
2626 																								  imageType,
2627 																								  tiling,
2628 																								  curUsageFlags,
2629 																								  curCreateFlags);
2630 			VkImageFormatProperties	properties;
2631 			VkResult				queryResult;
2632 
2633 			log << TestLog::Message << "Testing " << getImageTypeStr(imageType) << ", "
2634 									<< getImageTilingStr(tiling) << ", "
2635 									<< getImageUsageFlagsStr(curUsageFlags) << ", "
2636 									<< getImageCreateFlagsStr(curCreateFlags)
2637 				<< TestLog::EndMessage;
2638 
2639 			// Set return value to known garbage
2640 			deMemset(&properties, 0xcd, sizeof(properties));
2641 
2642 			queryResult = context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(context.getPhysicalDevice(),
2643 																								format,
2644 																								imageType,
2645 																								tiling,
2646 																								curUsageFlags,
2647 																								curCreateFlags,
2648 																								&properties);
2649 
2650 			if (queryResult == VK_SUCCESS)
2651 			{
2652 				const deUint32	fullMipPyramidSize	= de::max(de::max(deLog2Ceil32(properties.maxExtent.width),
2653 																	  deLog2Ceil32(properties.maxExtent.height)),
2654 															  deLog2Ceil32(properties.maxExtent.depth)) + 1;
2655 
2656 				log << TestLog::Message << properties << "\n" << TestLog::EndMessage;
2657 
2658 				results.check(imageType != VK_IMAGE_TYPE_1D || (properties.maxExtent.width >= 1 && properties.maxExtent.height == 1 && properties.maxExtent.depth == 1), "Invalid dimensions for 1D image");
2659 				results.check(imageType != VK_IMAGE_TYPE_2D || (properties.maxExtent.width >= 1 && properties.maxExtent.height >= 1 && properties.maxExtent.depth == 1), "Invalid dimensions for 2D image");
2660 				results.check(imageType != VK_IMAGE_TYPE_3D || (properties.maxExtent.width >= 1 && properties.maxExtent.height >= 1 && properties.maxExtent.depth >= 1), "Invalid dimensions for 3D image");
2661 				results.check(imageType != VK_IMAGE_TYPE_3D || properties.maxArrayLayers == 1, "Invalid maxArrayLayers for 3D image");
2662 
2663 				if (tiling == VK_IMAGE_TILING_OPTIMAL && imageType == VK_IMAGE_TYPE_2D && !(curCreateFlags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
2664 					 (supportedFeatures & (VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)))
2665 				{
2666 					const VkSampleCountFlags	requiredSampleCounts	= getRequiredOptimalTilingSampleCounts(deviceLimits, format, curUsageFlags);
2667 					results.check((properties.sampleCounts & requiredSampleCounts) == requiredSampleCounts, "Required sample counts not supported");
2668 				}
2669 				else
2670 					results.check(properties.sampleCounts == VK_SAMPLE_COUNT_1_BIT, "sampleCounts != VK_SAMPLE_COUNT_1_BIT");
2671 
2672 				if (isRequiredCombination)
2673 				{
2674 					results.check(imageType != VK_IMAGE_TYPE_1D || (properties.maxExtent.width	>= deviceLimits.maxImageDimension1D),
2675 								  "Reported dimensions smaller than device limits");
2676 					results.check(imageType != VK_IMAGE_TYPE_2D || (properties.maxExtent.width	>= deviceLimits.maxImageDimension2D &&
2677 																	properties.maxExtent.height	>= deviceLimits.maxImageDimension2D),
2678 								  "Reported dimensions smaller than device limits");
2679 					results.check(imageType != VK_IMAGE_TYPE_3D || (properties.maxExtent.width	>= deviceLimits.maxImageDimension3D &&
2680 																	properties.maxExtent.height	>= deviceLimits.maxImageDimension3D &&
2681 																	properties.maxExtent.depth	>= deviceLimits.maxImageDimension3D),
2682 								  "Reported dimensions smaller than device limits");
2683 					results.check((isYCbCrFormat(format) && (properties.maxMipLevels == 1)) || properties.maxMipLevels == fullMipPyramidSize,
2684 					              "Invalid mip pyramid size");
2685 					results.check((isYCbCrFormat(format) && (properties.maxArrayLayers == 1)) || imageType == VK_IMAGE_TYPE_3D ||
2686 					              properties.maxArrayLayers >= deviceLimits.maxImageArrayLayers, "Invalid maxArrayLayers");
2687 				}
2688 				else
2689 				{
2690 					results.check(properties.maxMipLevels == 1 || properties.maxMipLevels == fullMipPyramidSize, "Invalid mip pyramid size");
2691 					results.check(properties.maxArrayLayers >= 1, "Invalid maxArrayLayers");
2692 				}
2693 
2694 				results.check(properties.maxResourceSize >= (VkDeviceSize)MINIMUM_REQUIRED_IMAGE_RESOURCE_SIZE,
2695 							  "maxResourceSize smaller than minimum required size");
2696 			}
2697 			else if (queryResult == VK_ERROR_FORMAT_NOT_SUPPORTED)
2698 			{
2699 				log << TestLog::Message << "Got VK_ERROR_FORMAT_NOT_SUPPORTED" << TestLog::EndMessage;
2700 
2701 				if (isRequiredCombination)
2702 					results.fail("VK_ERROR_FORMAT_NOT_SUPPORTED returned for required image parameter combination");
2703 
2704 				// Specification requires that all fields are set to 0
2705 				results.check(properties.maxExtent.width	== 0, "maxExtent.width != 0");
2706 				results.check(properties.maxExtent.height	== 0, "maxExtent.height != 0");
2707 				results.check(properties.maxExtent.depth	== 0, "maxExtent.depth != 0");
2708 				results.check(properties.maxMipLevels		== 0, "maxMipLevels != 0");
2709 				results.check(properties.maxArrayLayers		== 0, "maxArrayLayers != 0");
2710 				results.check(properties.sampleCounts		== 0, "sampleCounts != 0");
2711 				results.check(properties.maxResourceSize	== 0, "maxResourceSize != 0");
2712 			}
2713 			else
2714 			{
2715 				results.fail("Got unexpected error" + de::toString(queryResult));
2716 			}
2717 		}
2718 	}
2719 
2720 	return tcu::TestStatus(results.getResult(), results.getMessage());
2721 }
2722 
2723 // VK_KHR_get_physical_device_properties2
2724 
toString(const VkPhysicalDevice16BitStorageFeatures & value)2725 string toString (const VkPhysicalDevice16BitStorageFeatures& value)
2726 {
2727 	std::ostringstream	s;
2728 	s << "VkPhysicalDevice16BitStorageFeatures = {\n";
2729 	s << "\tsType = " << value.sType << '\n';
2730 	s << "\tstorageBuffer16BitAccess = " << value.storageBuffer16BitAccess << '\n';
2731 	s << "\tuniformAndStorageBuffer16BitAccess = " << value.uniformAndStorageBuffer16BitAccess << '\n';
2732 	s << "\tstoragePushConstant16 = " << value.storagePushConstant16 << '\n';
2733 	s << "\tstorageInputOutput16 = " << value.storageInputOutput16 << '\n';
2734 	s << '}';
2735 	return s.str();
2736 }
2737 
toString(const VkPhysicalDeviceFloatControlsPropertiesKHR & value)2738 string toString (const VkPhysicalDeviceFloatControlsPropertiesKHR& value)
2739 {
2740 	std::ostringstream	s;
2741 	s << "VkPhysicalDeviceFloatControlsPropertiesKHR = {\n";
2742 	s << "\tsType = " << value.sType << '\n';
2743 	s << "\tseparateDenormSettings = " << value.separateDenormSettings << '\n';
2744 	s << "\tseparateRoundingModeSettings = " << value.separateRoundingModeSettings << '\n';
2745 	s << "\tshaderSignedZeroInfNanPreserveFloat16 = " << value.shaderSignedZeroInfNanPreserveFloat16 << '\n';
2746 	s << "\tshaderSignedZeroInfNanPreserveFloat32 = " << value.shaderSignedZeroInfNanPreserveFloat32 << '\n';
2747 	s << "\tshaderSignedZeroInfNanPreserveFloat64 = " << value.shaderSignedZeroInfNanPreserveFloat64 << '\n';
2748 	s << "\tshaderDenormPreserveFloat16 = " << value.shaderDenormPreserveFloat16 << '\n';
2749 	s << "\tshaderDenormPreserveFloat32 = " << value.shaderDenormPreserveFloat32 << '\n';
2750 	s << "\tshaderDenormPreserveFloat64 = " << value.shaderDenormPreserveFloat64 << '\n';
2751 	s << "\tshaderDenormFlushToZeroFloat16 = " << value.shaderDenormFlushToZeroFloat16 << '\n';
2752 	s << "\tshaderDenormFlushToZeroFloat32 = " << value.shaderDenormFlushToZeroFloat32 << '\n';
2753 	s << "\tshaderDenormFlushToZeroFloat64 = " << value.shaderDenormFlushToZeroFloat64 << '\n';
2754 	s << "\tshaderRoundingModeRTEFloat16 = " << value.shaderRoundingModeRTEFloat16 << '\n';
2755 	s << "\tshaderRoundingModeRTEFloat32 = " << value.shaderRoundingModeRTEFloat32 << '\n';
2756 	s << "\tshaderRoundingModeRTEFloat64 = " << value.shaderRoundingModeRTEFloat64 << '\n';
2757 	s << "\tshaderRoundingModeRTZFloat16 = " << value.shaderRoundingModeRTZFloat16 << '\n';
2758 	s << "\tshaderRoundingModeRTZFloat32 = " << value.shaderRoundingModeRTZFloat32 << '\n';
2759 	s << "\tshaderRoundingModeRTZFloat64 = " << value.shaderRoundingModeRTZFloat64 << '\n';
2760 	s << '}';
2761 	return s.str();
2762 }
2763 
toString(const VkPhysicalDeviceMultiviewFeatures & value)2764 string toString (const VkPhysicalDeviceMultiviewFeatures& value)
2765 {
2766 	std::ostringstream	s;
2767 	s << "VkPhysicalDeviceMultiviewFeatures = {\n";
2768 	s << "\tsType = " << value.sType << '\n';
2769 	s << "\tmultiview = " << value.multiview << '\n';
2770 	s << "\tmultiviewGeometryShader = " << value.multiviewGeometryShader << '\n';
2771 	s << "\tmultiviewTessellationShader = " << value.multiviewTessellationShader << '\n';
2772 	s << '}';
2773 	return s.str();
2774 }
2775 
toString(const VkPhysicalDeviceProtectedMemoryFeatures & value)2776 string toString (const VkPhysicalDeviceProtectedMemoryFeatures& value)
2777 {
2778 	std::ostringstream	s;
2779 	s << "VkPhysicalDeviceProtectedMemoryFeatures = {\n";
2780 	s << "\tsType = " << value.sType << '\n';
2781 	s << "\tprotectedMemory = " << value.protectedMemory << '\n';
2782 	s << '}';
2783 	return s.str();
2784 }
2785 
toString(const VkPhysicalDeviceSamplerYcbcrConversionFeatures & value)2786 string toString (const VkPhysicalDeviceSamplerYcbcrConversionFeatures& value)
2787 {
2788 	std::ostringstream	s;
2789 	s << "VkPhysicalDeviceSamplerYcbcrConversionFeatures = {\n";
2790 	s << "\tsType = " << value.sType << '\n';
2791 	s << "\tsamplerYcbcrConversion = " << value.samplerYcbcrConversion << '\n';
2792 	s << '}';
2793 	return s.str();
2794 }
2795 
toString(const VkPhysicalDeviceVariablePointerFeatures & value)2796 string toString (const VkPhysicalDeviceVariablePointerFeatures& value)
2797 {
2798 	std::ostringstream	s;
2799 	s << "VkPhysicalDeviceVariablePointerFeatures = {\n";
2800 	s << "\tsType = " << value.sType << '\n';
2801 	s << "\tvariablePointersStorageBuffer = " << value.variablePointersStorageBuffer << '\n';
2802 	s << "\tvariablePointers = " << value.variablePointers << '\n';
2803 	s << '}';
2804 	return s.str();
2805 }
2806 
toString(const VkPhysicalDevicePushDescriptorPropertiesKHR & value)2807 string toString(const VkPhysicalDevicePushDescriptorPropertiesKHR& value)
2808 {
2809 	std::ostringstream	s;
2810 	s << "VkPhysicalDevicePushDescriptorPropertiesKHR = {\n";
2811 	s << "\tsType = " << value.sType << '\n';
2812 	s << "\tmaxPushDescriptors = " << value.maxPushDescriptors << '\n';
2813 	s << '}';
2814 	return s.str();
2815 }
2816 
toString(const VkPhysicalDeviceDepthStencilResolvePropertiesKHR & value)2817 string toString(const VkPhysicalDeviceDepthStencilResolvePropertiesKHR& value)
2818 {
2819 	std::ostringstream	s;
2820 	s << "VkPhysicalDeviceDepthStencilResolvePropertiesKHR = {\n";
2821 	s << "\tsType = " << value.sType << '\n';
2822 	s << "\tsupportedDepthResolveModes = " << value.supportedDepthResolveModes << '\n';
2823 	s << "\tsupportedStencilResolveModes = " << value.supportedStencilResolveModes << '\n';
2824 	s << "\tindependentResolveNone = " << value.independentResolveNone << '\n';
2825 	s << "\tindependentResolve = " << value.independentResolve << '\n';
2826 	s << '}';
2827 	return s.str();
2828 }
2829 
toString(const VkPhysicalDeviceScalarBlockLayoutFeaturesEXT & value)2830 string toString(const VkPhysicalDeviceScalarBlockLayoutFeaturesEXT& value)
2831 {
2832 	std::ostringstream	s;
2833 	s << "VkPhysicalDeviceScalarBlockLayoutFeaturesEXT = {\n";
2834 	s << "\tsType = " << value.sType << '\n';
2835 	s << "\tscalarBlockLayout = " << value.scalarBlockLayout << '\n';
2836 	s << '}';
2837 	return s.str();
2838 }
2839 
checkExtension(vector<VkExtensionProperties> & properties,const char * extension)2840 bool checkExtension (vector<VkExtensionProperties>& properties, const char* extension)
2841 {
2842 	for (size_t ndx = 0; ndx < properties.size(); ++ndx)
2843 	{
2844 		if (strcmp(properties[ndx].extensionName, extension) == 0)
2845 			return true;
2846 	}
2847 	return false;
2848 }
2849 
deviceFeatures2(Context & context)2850 tcu::TestStatus deviceFeatures2 (Context& context)
2851 {
2852 	const PlatformInterface&	vkp				= context.getPlatformInterface();
2853 	const VkPhysicalDevice		physicalDevice	= context.getPhysicalDevice();
2854 	const Unique<VkInstance>	instance		(createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_get_physical_device_properties2"));
2855 	const InstanceDriver		vki				(vkp, *instance);
2856 	TestLog&					log				= context.getTestContext().getLog();
2857 	VkPhysicalDeviceFeatures	coreFeatures;
2858 	VkPhysicalDeviceFeatures2	extFeatures;
2859 
2860 	deMemset(&coreFeatures, 0xcd, sizeof(coreFeatures));
2861 	deMemset(&extFeatures.features, 0xcd, sizeof(extFeatures.features));
2862 	std::vector<std::string> instExtensions = context.getInstanceExtensions();
2863 
2864 	extFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
2865 	extFeatures.pNext = DE_NULL;
2866 
2867 	vki.getPhysicalDeviceFeatures(physicalDevice, &coreFeatures);
2868 	vki.getPhysicalDeviceFeatures2(physicalDevice, &extFeatures);
2869 
2870 	TCU_CHECK(extFeatures.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2);
2871 	TCU_CHECK(extFeatures.pNext == DE_NULL);
2872 
2873 	if (deMemCmp(&coreFeatures, &extFeatures.features, sizeof(VkPhysicalDeviceFeatures)) != 0)
2874 		TCU_FAIL("Mismatch between features reported by vkGetPhysicalDeviceFeatures and vkGetPhysicalDeviceFeatures2");
2875 
2876 	log << TestLog::Message << extFeatures << TestLog::EndMessage;
2877 
2878 	vector<VkExtensionProperties>	properties = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
2879 	const bool khr_8bit_storage				= checkExtension(properties,"VK_KHR_8bit_storage");
2880 	const bool ext_conditional_rendering	= checkExtension(properties,"VK_EXT_conditional_rendering");
2881 	const bool scalar_block_layout			= checkExtension(properties,"VK_EXT_scalar_block_layout");
2882 	bool khr_16bit_storage					= true;
2883 	bool khr_multiview						= true;
2884 	bool deviceProtectedMemory				= true;
2885 	bool sampler_ycbcr_conversion			= true;
2886 	bool variable_pointers					= true;
2887 	if (getPhysicalDeviceProperties(vki, physicalDevice).apiVersion < VK_API_VERSION_1_1)
2888 	{
2889 		khr_16bit_storage = checkExtension(properties,"VK_KHR_16bit_storage");
2890 		khr_multiview = checkExtension(properties,"VK_KHR_multiview");
2891 		deviceProtectedMemory = false;
2892 		sampler_ycbcr_conversion = checkExtension(properties,"VK_KHR_sampler_ycbcr_conversion");
2893 		variable_pointers = checkExtension(properties,"VK_KHR_variable_pointers");
2894 	}
2895 
2896 	const int count = 2u;
2897 	VkPhysicalDevice8BitStorageFeaturesKHR				device8BitStorageFeatures[count];
2898 	VkPhysicalDeviceConditionalRenderingFeaturesEXT		deviceConditionalRenderingFeatures[count];
2899 	VkPhysicalDevice16BitStorageFeatures				device16BitStorageFeatures[count];
2900 	VkPhysicalDeviceMultiviewFeatures					deviceMultiviewFeatures[count];
2901 	VkPhysicalDeviceProtectedMemoryFeatures				protectedMemoryFeatures[count];
2902 	VkPhysicalDeviceSamplerYcbcrConversionFeatures		samplerYcbcrConversionFeatures[count];
2903 	VkPhysicalDeviceVariablePointerFeatures				variablePointerFeatures[count];
2904 	VkPhysicalDeviceScalarBlockLayoutFeaturesEXT		scalarBlockLayoutFeatures[count];
2905 
2906 	for (int ndx = 0; ndx < count; ++ndx)
2907 	{
2908 		deMemset(&device8BitStorageFeatures[ndx],			0xFF*ndx, sizeof(VkPhysicalDevice8BitStorageFeaturesKHR));
2909 		deMemset(&deviceConditionalRenderingFeatures[ndx],	0xFF*ndx, sizeof(VkPhysicalDeviceConditionalRenderingFeaturesEXT));
2910 		deMemset(&device16BitStorageFeatures[ndx],			0xFF*ndx, sizeof(VkPhysicalDevice16BitStorageFeatures));
2911 		deMemset(&deviceMultiviewFeatures[ndx],				0xFF*ndx, sizeof(VkPhysicalDeviceMultiviewFeatures));
2912 		deMemset(&protectedMemoryFeatures[ndx],				0xFF*ndx, sizeof(VkPhysicalDeviceProtectedMemoryFeatures));
2913 		deMemset(&samplerYcbcrConversionFeatures[ndx],		0xFF*ndx, sizeof(VkPhysicalDeviceSamplerYcbcrConversionFeatures));
2914 		deMemset(&variablePointerFeatures[ndx],				0xFF*ndx, sizeof(VkPhysicalDeviceVariablePointerFeatures));
2915 		deMemset(&scalarBlockLayoutFeatures[ndx],			0xFF*ndx, sizeof(VkPhysicalDeviceScalarBlockLayoutFeaturesEXT));
2916 
2917 		device8BitStorageFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR;
2918 		device8BitStorageFeatures[ndx].pNext = &deviceConditionalRenderingFeatures[ndx];
2919 
2920 		deviceConditionalRenderingFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT;
2921 		deviceConditionalRenderingFeatures[ndx].pNext = &device16BitStorageFeatures[ndx];
2922 
2923 		device16BitStorageFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES;
2924 		device16BitStorageFeatures[ndx].pNext = &deviceMultiviewFeatures[ndx];
2925 
2926 		deviceMultiviewFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES;
2927 		deviceMultiviewFeatures[ndx].pNext = &protectedMemoryFeatures[ndx];
2928 
2929 		protectedMemoryFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES;
2930 		protectedMemoryFeatures[ndx].pNext = &samplerYcbcrConversionFeatures[ndx];
2931 
2932 		samplerYcbcrConversionFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
2933 		samplerYcbcrConversionFeatures[ndx].pNext = &variablePointerFeatures[ndx];
2934 
2935 		variablePointerFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES;
2936 		variablePointerFeatures[ndx].pNext = &scalarBlockLayoutFeatures[ndx];
2937 
2938 		scalarBlockLayoutFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT;
2939 		scalarBlockLayoutFeatures[ndx].pNext = DE_NULL;
2940 
2941 		deMemset(&extFeatures.features, 0xcd, sizeof(extFeatures.features));
2942 		extFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
2943 		extFeatures.pNext = &device8BitStorageFeatures[ndx];
2944 
2945 		vki.getPhysicalDeviceFeatures2(physicalDevice, &extFeatures);
2946 	}
2947 
2948 	if ( khr_8bit_storage &&
2949 		(device8BitStorageFeatures[0].storageBuffer8BitAccess				!= device8BitStorageFeatures[1].storageBuffer8BitAccess ||
2950 		device8BitStorageFeatures[0].uniformAndStorageBuffer8BitAccess		!= device8BitStorageFeatures[1].uniformAndStorageBuffer8BitAccess ||
2951 		device8BitStorageFeatures[0].storagePushConstant8					!= device8BitStorageFeatures[1].storagePushConstant8 )
2952 		)
2953 	{
2954 		TCU_FAIL("Mismatch between VkPhysicalDevice8BitStorageFeatures");
2955 	}
2956 
2957 	if ( ext_conditional_rendering &&
2958 		(deviceConditionalRenderingFeatures[0].conditionalRendering				!= deviceConditionalRenderingFeatures[1].conditionalRendering ||
2959 		deviceConditionalRenderingFeatures[0].inheritedConditionalRendering		!= deviceConditionalRenderingFeatures[1].inheritedConditionalRendering )
2960 		)
2961 	{
2962 		TCU_FAIL("Mismatch between VkPhysicalDeviceConditionalRenderingFeaturesEXT");
2963 	}
2964 
2965 	if ( khr_16bit_storage &&
2966 		(device16BitStorageFeatures[0].storageBuffer16BitAccess				!= device16BitStorageFeatures[1].storageBuffer16BitAccess ||
2967 		device16BitStorageFeatures[0].uniformAndStorageBuffer16BitAccess	!= device16BitStorageFeatures[1].uniformAndStorageBuffer16BitAccess ||
2968 		device16BitStorageFeatures[0].storagePushConstant16					!= device16BitStorageFeatures[1].storagePushConstant16 ||
2969 		device16BitStorageFeatures[0].storageInputOutput16					!= device16BitStorageFeatures[1].storageInputOutput16)
2970 		)
2971 	{
2972 		TCU_FAIL("Mismatch between VkPhysicalDevice16BitStorageFeatures");
2973 	}
2974 
2975 	if (khr_multiview &&
2976 		(deviceMultiviewFeatures[0].multiview					!= deviceMultiviewFeatures[1].multiview ||
2977 		deviceMultiviewFeatures[0].multiviewGeometryShader		!= deviceMultiviewFeatures[1].multiviewGeometryShader ||
2978 		deviceMultiviewFeatures[0].multiviewTessellationShader	!= deviceMultiviewFeatures[1].multiviewTessellationShader)
2979 		)
2980 	{
2981 		TCU_FAIL("Mismatch between VkPhysicalDeviceMultiviewFeatures");
2982 	}
2983 
2984 	if (deviceProtectedMemory && protectedMemoryFeatures[0].protectedMemory != protectedMemoryFeatures[1].protectedMemory)
2985 	{
2986 		TCU_FAIL("Mismatch between VkPhysicalDeviceProtectedMemoryFeatures");
2987 	}
2988 
2989 	if (sampler_ycbcr_conversion && samplerYcbcrConversionFeatures[0].samplerYcbcrConversion != samplerYcbcrConversionFeatures[1].samplerYcbcrConversion)
2990 	{
2991 		TCU_FAIL("Mismatch between VkPhysicalDeviceSamplerYcbcrConversionFeatures");
2992 	}
2993 
2994 	if (variable_pointers &&
2995 		(variablePointerFeatures[0].variablePointersStorageBuffer	!= variablePointerFeatures[1].variablePointersStorageBuffer ||
2996 		variablePointerFeatures[0].variablePointers					!= variablePointerFeatures[1].variablePointers)
2997 		)
2998 	{
2999 		TCU_FAIL("Mismatch between VkPhysicalDeviceVariablePointerFeatures");
3000 	}
3001 	if (scalar_block_layout &&
3002 		(scalarBlockLayoutFeatures[0].scalarBlockLayout	!= scalarBlockLayoutFeatures[1].scalarBlockLayout))
3003 	{
3004 		TCU_FAIL("Mismatch between VkPhysicalDeviceScalarBlockLayoutFeaturesEXT");
3005 	}
3006 	if (khr_8bit_storage)
3007 		log << TestLog::Message << device8BitStorageFeatures[0]		<< TestLog::EndMessage;
3008 	if (ext_conditional_rendering)
3009 		log << TestLog::Message << deviceConditionalRenderingFeatures[0]		<< TestLog::EndMessage;
3010 	if (khr_16bit_storage)
3011 		log << TestLog::Message << toString(device16BitStorageFeatures[0])		<< TestLog::EndMessage;
3012 	if (khr_multiview)
3013 		log << TestLog::Message << toString(deviceMultiviewFeatures[0])			<< TestLog::EndMessage;
3014 	if (deviceProtectedMemory)
3015 		log << TestLog::Message << toString(protectedMemoryFeatures[0])			<< TestLog::EndMessage;
3016 	if (sampler_ycbcr_conversion)
3017 		log << TestLog::Message << toString(samplerYcbcrConversionFeatures[0])	<< TestLog::EndMessage;
3018 	if (variable_pointers)
3019 		log << TestLog::Message << toString(variablePointerFeatures[0])			<< TestLog::EndMessage;
3020 	if (scalar_block_layout)
3021 		log << TestLog::Message << toString(scalarBlockLayoutFeatures[0])		<< TestLog::EndMessage;
3022 
3023 	return tcu::TestStatus::pass("Querying device features succeeded");
3024 }
3025 
3026 
toString(const VkPhysicalDeviceIDProperties & value)3027 string toString (const VkPhysicalDeviceIDProperties& value)
3028 {
3029 	std::ostringstream	s;
3030 	s << "VkPhysicalDeviceIDProperties = {\n";
3031 	s << "\tsType = " << value.sType << '\n';
3032 	s << "\tdeviceUUID = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<deUint8>(DE_ARRAY_BEGIN(value.deviceUUID)), tcu::Format::HexIterator<deUint8>(DE_ARRAY_END(value.deviceUUID))) << '\n';
3033 	s << "\tdriverUUID = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<deUint8>(DE_ARRAY_BEGIN(value.driverUUID)), tcu::Format::HexIterator<deUint8>(DE_ARRAY_END(value.driverUUID))) << '\n';
3034 	s << "\tdeviceLUID = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<deUint8>(DE_ARRAY_BEGIN(value.deviceLUID)), tcu::Format::HexIterator<deUint8>(DE_ARRAY_END(value.deviceLUID))) << '\n';
3035 	s << "\tdeviceNodeMask = " << value.deviceNodeMask << '\n';
3036 	s << "\tdeviceLUIDValid = " << value.deviceLUIDValid << '\n';
3037 	s << '}';
3038 	return s.str();
3039 }
3040 
toString(const VkPhysicalDeviceMaintenance3Properties & value)3041 string toString (const VkPhysicalDeviceMaintenance3Properties& value)
3042 {
3043 	std::ostringstream	s;
3044 	s << "VkPhysicalDeviceMaintenance3Properties = {\n";
3045 	s << "\tsType = " << value.sType << '\n';
3046 	s << "\tmaxPerSetDescriptors = " << value.maxPerSetDescriptors << '\n';
3047 	s << "\tmaxMemoryAllocationSize = " << value.maxMemoryAllocationSize << '\n';
3048 	s << '}';
3049 	return s.str();
3050 }
3051 
toString(const VkPhysicalDeviceMultiviewProperties & value)3052 string toString (const VkPhysicalDeviceMultiviewProperties& value)
3053 {
3054 	std::ostringstream	s;
3055 	s << "VkPhysicalDeviceMultiviewProperties = {\n";
3056 	s << "\tsType = " << value.sType << '\n';
3057 	s << "\tmaxMultiviewViewCount = " << value.maxMultiviewViewCount << '\n';
3058 	s << "\tmaxMultiviewInstanceIndex = " << value.maxMultiviewInstanceIndex << '\n';
3059 	s << '}';
3060 	return s.str();
3061 }
3062 
toString(const VkPhysicalDevicePointClippingProperties & value)3063 string toString (const VkPhysicalDevicePointClippingProperties& value)
3064 {
3065 	std::ostringstream	s;
3066 	s << "VkPhysicalDevicePointClippingProperties = {\n";
3067 	s << "\tsType = " << value.sType << '\n';
3068 	s << "\tpointClippingBehavior = " << value.pointClippingBehavior << '\n';
3069 	s << '}';
3070 	return s.str();
3071 }
3072 
toString(const VkPhysicalDeviceProtectedMemoryProperties & value)3073 string toString (const VkPhysicalDeviceProtectedMemoryProperties& value)
3074 {
3075 	std::ostringstream	s;
3076 	s << "VkPhysicalDeviceProtectedMemoryProperties = {\n";
3077 	s << "\tsType = " << value.sType << '\n';
3078 	s << "\tprotectedNoFault = " << value.protectedNoFault << '\n';
3079 	s << '}';
3080 	return s.str();
3081 }
3082 
3083 
toString(const VkPhysicalDeviceSubgroupProperties & value)3084 string toString (const VkPhysicalDeviceSubgroupProperties& value)
3085 {
3086 	std::ostringstream	s;
3087 	s << "VkPhysicalDeviceSubgroupProperties = {\n";
3088 	s << "\tsType = " << value.sType << '\n';
3089 	s << "\tsubgroupSize = " << value.subgroupSize << '\n';
3090 	s << "\tsupportedStages = " << getShaderStageFlagsStr(value.supportedStages) << '\n';
3091 	s << "\tsupportedOperations = " << getSubgroupFeatureFlagsStr(value.supportedOperations) << '\n';
3092 	s << "\tquadOperationsInAllStages = " << value.quadOperationsInAllStages << '\n';
3093 	s << '}';
3094 	return s.str();
3095 }
3096 
deviceProperties2(Context & context)3097 tcu::TestStatus deviceProperties2 (Context& context)
3098 {
3099 	const PlatformInterface&		vkp				= context.getPlatformInterface();
3100 	const VkPhysicalDevice			physicalDevice	= context.getPhysicalDevice();
3101 	const Unique<VkInstance>		instance		(createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_get_physical_device_properties2"));
3102 	const InstanceDriver			vki				(vkp, *instance);
3103 	TestLog&						log				= context.getTestContext().getLog();
3104 	VkPhysicalDeviceProperties		coreProperties;
3105 	VkPhysicalDeviceProperties2		extProperties;
3106 
3107 	extProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
3108 	extProperties.pNext = DE_NULL;
3109 
3110 	vki.getPhysicalDeviceProperties(physicalDevice, &coreProperties);
3111 	vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
3112 
3113 	TCU_CHECK(extProperties.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2);
3114 	TCU_CHECK(extProperties.pNext == DE_NULL);
3115 
3116 	// We can't use memcmp() here because the structs may contain padding bytes that drivers may or may not
3117 	// have written while writing the data and memcmp will compare them anyway, so we iterate through the
3118 	// valid bytes for each field in the struct and compare only the valid bytes for each one.
3119 	for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(s_physicalDevicePropertiesOffsetTable); propNdx++)
3120 	{
3121 		const size_t offset					= s_physicalDevicePropertiesOffsetTable[propNdx].offset;
3122 		const size_t size					= s_physicalDevicePropertiesOffsetTable[propNdx].size;
3123 
3124 		const deUint8* corePropertyBytes	= reinterpret_cast<deUint8*>(&coreProperties) + offset;
3125 		const deUint8* extPropertyBytes		= reinterpret_cast<deUint8*>(&extProperties.properties) + offset;
3126 
3127 		if (deMemCmp(corePropertyBytes, extPropertyBytes, size) != 0)
3128 			TCU_FAIL("Mismatch between properties reported by vkGetPhysicalDeviceProperties and vkGetPhysicalDeviceProperties2");
3129 	}
3130 
3131 	log << TestLog::Message << extProperties.properties << TestLog::EndMessage;
3132 
3133 	const int count = 2u;
3134 
3135 	bool khr_external_memory_capabilities		= true;
3136 	bool khr_multiview							= true;
3137 	bool khr_maintenance2						= true;
3138 	bool khr_maintenance3						= true;
3139 	bool apiVersionSmallerThen_1_1				= (getPhysicalDeviceProperties(vki, physicalDevice).apiVersion < VK_API_VERSION_1_1);
3140 	if (apiVersionSmallerThen_1_1)
3141 	{
3142 		vector<VkExtensionProperties> properties	= enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
3143 		khr_external_memory_capabilities			= checkExtension(properties,"VK_KHR_external_memory_capabilities");
3144 		khr_multiview								= checkExtension(properties,"VK_KHR_multiview");
3145 		khr_maintenance2							= checkExtension(properties,"VK_KHR_maintenance2");
3146 		khr_maintenance3							= checkExtension(properties,"VK_KHR_maintenance3");
3147 	}
3148 
3149 	VkPhysicalDeviceIDProperties				IDProperties[count];
3150 	VkPhysicalDeviceMaintenance3Properties		maintenance3Properties[count];
3151 	VkPhysicalDeviceMultiviewProperties			multiviewProperties[count];
3152 	VkPhysicalDevicePointClippingProperties		pointClippingProperties[count];
3153 	VkPhysicalDeviceProtectedMemoryProperties	protectedMemoryPropertiesKHR[count];
3154 	VkPhysicalDeviceSubgroupProperties			subgroupProperties[count];
3155 
3156 	for (int ndx = 0; ndx < count; ++ndx)
3157 	{
3158 		deMemset(&IDProperties[ndx],					0xFF*ndx, sizeof(VkPhysicalDeviceIDProperties				));
3159 		deMemset(&maintenance3Properties[ndx],			0xFF*ndx, sizeof(VkPhysicalDeviceMaintenance3Properties		));
3160 		deMemset(&multiviewProperties[ndx],				0xFF*ndx, sizeof(VkPhysicalDeviceMultiviewProperties		));
3161 		deMemset(&pointClippingProperties[ndx],			0xFF*ndx, sizeof(VkPhysicalDevicePointClippingProperties	));
3162 		deMemset(&protectedMemoryPropertiesKHR[ndx],	0xFF*ndx, sizeof(VkPhysicalDeviceProtectedMemoryProperties	));
3163 		deMemset(&subgroupProperties[ndx],				0xFF*ndx, sizeof(VkPhysicalDeviceSubgroupProperties			));
3164 
3165 		IDProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
3166 		IDProperties[ndx].pNext = &maintenance3Properties[ndx];
3167 
3168 		maintenance3Properties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES;
3169 		maintenance3Properties[ndx].pNext = &multiviewProperties[ndx];
3170 
3171 		multiviewProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES;
3172 		multiviewProperties[ndx].pNext = &pointClippingProperties[ndx];
3173 
3174 		pointClippingProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES;
3175 		pointClippingProperties[ndx].pNext = &protectedMemoryPropertiesKHR[ndx];
3176 
3177 		protectedMemoryPropertiesKHR[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES;
3178 		protectedMemoryPropertiesKHR[ndx].pNext = &subgroupProperties[ndx];
3179 
3180 		subgroupProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
3181 		subgroupProperties[ndx].pNext = DE_NULL;
3182 
3183 		extProperties.pNext = &IDProperties[ndx];
3184 
3185 		vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
3186 
3187 		IDProperties[ndx].pNext						= DE_NULL;
3188 		maintenance3Properties[ndx].pNext			= DE_NULL;
3189 		multiviewProperties[ndx].pNext				= DE_NULL;
3190 		pointClippingProperties[ndx].pNext			= DE_NULL;
3191 		protectedMemoryPropertiesKHR[ndx].pNext		= DE_NULL;
3192 		subgroupProperties[ndx].pNext				= DE_NULL;
3193 	}
3194 
3195 	if (khr_external_memory_capabilities)
3196 	{
3197 		if ((deMemCmp(IDProperties[0].deviceUUID, IDProperties[1].deviceUUID, VK_UUID_SIZE) != 0) ||
3198 			(deMemCmp(IDProperties[0].driverUUID, IDProperties[1].driverUUID, VK_UUID_SIZE) != 0) ||
3199 			(IDProperties[0].deviceLUIDValid	!= IDProperties[1].deviceLUIDValid))
3200 		{
3201 			TCU_FAIL("Mismatch between VkPhysicalDeviceIDProperties");
3202 		}
3203 		else if (IDProperties[0].deviceLUIDValid)
3204 		{
3205 			// If deviceLUIDValid is VK_FALSE, the contents of deviceLUID and deviceNodeMask are undefined
3206 			// so thay can only be compared when deviceLUIDValid is VK_TRUE.
3207 			if ((deMemCmp(IDProperties[0].deviceLUID, IDProperties[1].deviceLUID, VK_UUID_SIZE) != 0) ||
3208 				(IDProperties[0].deviceNodeMask		!= IDProperties[1].deviceNodeMask))
3209 			{
3210 				TCU_FAIL("Mismatch between VkPhysicalDeviceIDProperties");
3211 			}
3212 		}
3213 	}
3214 	if (khr_maintenance3 &&
3215 		((maintenance3Properties[0].maxPerSetDescriptors	!= maintenance3Properties[1].maxPerSetDescriptors) ||
3216 		(maintenance3Properties[0].maxMemoryAllocationSize	!= maintenance3Properties[1].maxMemoryAllocationSize))
3217 		)
3218 	{
3219 		TCU_FAIL("Mismatch between VkPhysicalDeviceMaintenance3Properties");
3220 	}
3221 	if (khr_multiview &&
3222 		((multiviewProperties[0].maxMultiviewViewCount		!= multiviewProperties[1].maxMultiviewViewCount) ||
3223 		(multiviewProperties[0].maxMultiviewInstanceIndex	!= multiviewProperties[1].maxMultiviewInstanceIndex))
3224 		)
3225 	{
3226 		TCU_FAIL("Mismatch between VkPhysicalDeviceMultiviewProperties");
3227 	}
3228 	if (khr_maintenance2 &&
3229 		(pointClippingProperties[0].pointClippingBehavior != pointClippingProperties[1].pointClippingBehavior))
3230 	{
3231 		TCU_FAIL("Mismatch between VkPhysicalDevicePointClippingProperties");
3232 	}
3233 	if (!apiVersionSmallerThen_1_1)
3234 	{
3235 		if(protectedMemoryPropertiesKHR[0].protectedNoFault != protectedMemoryPropertiesKHR[1].protectedNoFault)
3236 		{
3237 			TCU_FAIL("Mismatch between VkPhysicalDeviceProtectedMemoryProperties");
3238 		}
3239 		if ((subgroupProperties[0].subgroupSize					!= subgroupProperties[1].subgroupSize) ||
3240 			(subgroupProperties[0].supportedStages				!= subgroupProperties[1].supportedStages) ||
3241 			(subgroupProperties[0].supportedOperations			!= subgroupProperties[1].supportedOperations) ||
3242 			(subgroupProperties[0].quadOperationsInAllStages	!= subgroupProperties[1].quadOperationsInAllStages))
3243 		{
3244 			TCU_FAIL("Mismatch between VkPhysicalDeviceSubgroupProperties");
3245 		}
3246 	}
3247 
3248 	if (khr_external_memory_capabilities)
3249 		log << TestLog::Message << toString(IDProperties[0])					<< TestLog::EndMessage;
3250 	if (khr_maintenance3)
3251 		log << TestLog::Message << toString(maintenance3Properties[0])			<< TestLog::EndMessage;
3252 	if (khr_multiview)
3253 		log << TestLog::Message << toString(multiviewProperties[0])				<< TestLog::EndMessage;
3254 	if (khr_maintenance2)
3255 		log << TestLog::Message << toString(pointClippingProperties[0])			<< TestLog::EndMessage;
3256 	if (!apiVersionSmallerThen_1_1)
3257 	{
3258 		log << TestLog::Message << toString(protectedMemoryPropertiesKHR[0])	<< TestLog::EndMessage
3259 			<< TestLog::Message << toString(subgroupProperties[0])				<< TestLog::EndMessage;
3260 	}
3261 
3262 	const vector<VkExtensionProperties>	extensions = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
3263 
3264 	if (isExtensionSupported(extensions, RequiredExtension("VK_KHR_push_descriptor")))
3265 	{
3266 		VkPhysicalDevicePushDescriptorPropertiesKHR		pushDescriptorProperties[count];
3267 
3268 		for (int ndx = 0; ndx < count; ++ndx)
3269 		{
3270 			deMemset(&pushDescriptorProperties[ndx], 0, sizeof(VkPhysicalDevicePushDescriptorPropertiesKHR));
3271 
3272 			pushDescriptorProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR;
3273 			pushDescriptorProperties[ndx].pNext	= DE_NULL;
3274 
3275 			extProperties.pNext = &pushDescriptorProperties[ndx];
3276 
3277 			vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
3278 
3279 			pushDescriptorProperties[ndx].pNext = DE_NULL;
3280 		}
3281 
3282 		if (deMemCmp(&pushDescriptorProperties[0], &pushDescriptorProperties[1], sizeof(VkPhysicalDevicePushDescriptorPropertiesKHR)) != 0)
3283 		{
3284 			TCU_FAIL("Mismatch in vkGetPhysicalDeviceProperties2 in VkPhysicalDevicePushDescriptorPropertiesKHR ");
3285 		}
3286 
3287 		log << TestLog::Message << toString(pushDescriptorProperties[0]) << TestLog::EndMessage;
3288 
3289 		if (pushDescriptorProperties[0].maxPushDescriptors < 32)
3290 		{
3291 			TCU_FAIL("VkPhysicalDevicePushDescriptorPropertiesKHR.maxPushDescriptors must be at least 32");
3292 		}
3293 	}
3294 	if (isExtensionSupported(extensions, RequiredExtension("VK_KHR_shader_float_controls")))
3295 	{
3296 		VkPhysicalDeviceFloatControlsPropertiesKHR floatControlsProperties[count];
3297 
3298 		for (int ndx = 0; ndx < count; ++ndx)
3299 		{
3300 			deMemset(&floatControlsProperties[ndx], 0xFF, sizeof(VkPhysicalDeviceFloatControlsPropertiesKHR));
3301 			floatControlsProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR;
3302 			floatControlsProperties[ndx].pNext = DE_NULL;
3303 
3304 			extProperties.pNext = &floatControlsProperties[ndx];
3305 
3306 			vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
3307 		}
3308 
3309 		if (deMemCmp(&floatControlsProperties[0], &floatControlsProperties[1], sizeof(VkPhysicalDeviceFloatControlsPropertiesKHR)) != 0)
3310 		{
3311 			TCU_FAIL("Mismatch in VkPhysicalDeviceFloatControlsPropertiesKHR");
3312 		}
3313 
3314 		log << TestLog::Message << toString(floatControlsProperties[0]) << TestLog::EndMessage;
3315 	}
3316 
3317 	if (isExtensionSupported(extensions, RequiredExtension("VK_KHR_depth_stencil_resolve")))
3318 	{
3319 		VkPhysicalDeviceDepthStencilResolvePropertiesKHR  dsResolveProperties[count];
3320 
3321 		for (int ndx = 0; ndx < count; ++ndx)
3322 		{
3323 			deMemset(&dsResolveProperties[ndx], 0xFF, sizeof(VkPhysicalDeviceDepthStencilResolvePropertiesKHR));
3324 			dsResolveProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR;
3325 			dsResolveProperties[ndx].pNext = DE_NULL;
3326 
3327 			extProperties.pNext = &dsResolveProperties[ndx];
3328 
3329 			vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
3330 		}
3331 
3332 		if (deMemCmp(&dsResolveProperties[0], &dsResolveProperties[1], sizeof(VkPhysicalDeviceDepthStencilResolvePropertiesKHR)) != 0)
3333 		{
3334 			TCU_FAIL("Mismatch in VkPhysicalDeviceDepthStencilResolvePropertiesKHR");
3335 		}
3336 
3337 		log << TestLog::Message << toString(dsResolveProperties[0]) << TestLog::EndMessage;
3338 	}
3339 
3340 	return tcu::TestStatus::pass("Querying device properties succeeded");
3341 }
3342 
toString(const VkFormatProperties2 & value)3343 string toString (const VkFormatProperties2& value)
3344 {
3345 	std::ostringstream	s;
3346 	s << "VkFormatProperties2 = {\n";
3347 	s << "\tsType = " << value.sType << '\n';
3348 	s << "\tformatProperties = {\n";
3349 	s << "\tlinearTilingFeatures = " << getFormatFeatureFlagsStr(value.formatProperties.linearTilingFeatures) << '\n';
3350 	s << "\toptimalTilingFeatures = " << getFormatFeatureFlagsStr(value.formatProperties.optimalTilingFeatures) << '\n';
3351 	s << "\tbufferFeatures = " << getFormatFeatureFlagsStr(value.formatProperties.bufferFeatures) << '\n';
3352 	s << "\t}";
3353 	s << "}";
3354 	return s.str();
3355 }
3356 
deviceFormatProperties2(Context & context)3357 tcu::TestStatus deviceFormatProperties2 (Context& context)
3358 {
3359 	const PlatformInterface&		vkp				= context.getPlatformInterface();
3360 	const VkPhysicalDevice			physicalDevice	= context.getPhysicalDevice();
3361 	const Unique<VkInstance>		instance		(createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_get_physical_device_properties2"));
3362 	const InstanceDriver			vki				(vkp, *instance);
3363 	TestLog&						log				= context.getTestContext().getLog();
3364 
3365 	for (int formatNdx = 0; formatNdx < VK_CORE_FORMAT_LAST; ++formatNdx)
3366 	{
3367 		const VkFormat			format			= (VkFormat)formatNdx;
3368 		VkFormatProperties		coreProperties;
3369 		VkFormatProperties2		extProperties;
3370 
3371 		deMemset(&coreProperties, 0xcd, sizeof(VkFormatProperties));
3372 		deMemset(&extProperties, 0xcd, sizeof(VkFormatProperties2));
3373 
3374 		extProperties.sType	= VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
3375 		extProperties.pNext = DE_NULL;
3376 
3377 		vki.getPhysicalDeviceFormatProperties(physicalDevice, format, &coreProperties);
3378 		vki.getPhysicalDeviceFormatProperties2(physicalDevice, format, &extProperties);
3379 
3380 		TCU_CHECK(extProperties.sType == VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2);
3381 		TCU_CHECK(extProperties.pNext == DE_NULL);
3382 
3383 	if (deMemCmp(&coreProperties, &extProperties.formatProperties, sizeof(VkFormatProperties)) != 0)
3384 		TCU_FAIL("Mismatch between format properties reported by vkGetPhysicalDeviceFormatProperties and vkGetPhysicalDeviceFormatProperties2");
3385 
3386 	log << TestLog::Message << toString (extProperties) << TestLog::EndMessage;
3387 	}
3388 
3389 	return tcu::TestStatus::pass("Querying device format properties succeeded");
3390 }
3391 
toString(const VkQueueFamilyProperties2 & value)3392 string toString (const VkQueueFamilyProperties2& value)
3393 {
3394 	std::ostringstream	s;
3395 	s << "VkQueueFamilyProperties2 = {\n";
3396 	s << "\tsType = " << value.sType << '\n';
3397 	s << "\tqueueFamilyProperties = " << value.queueFamilyProperties << '\n';
3398 	s << '}';
3399 	return s.str();
3400 }
3401 
deviceQueueFamilyProperties2(Context & context)3402 tcu::TestStatus deviceQueueFamilyProperties2 (Context& context)
3403 {
3404 	const PlatformInterface&		vkp						= context.getPlatformInterface();
3405 	const VkPhysicalDevice			physicalDevice			= context.getPhysicalDevice();
3406 	const Unique<VkInstance>		instance				(createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_get_physical_device_properties2"));
3407 	const InstanceDriver			vki						(vkp, *instance);
3408 	TestLog&						log						= context.getTestContext().getLog();
3409 	deUint32						numCoreQueueFamilies	= ~0u;
3410 	deUint32						numExtQueueFamilies		= ~0u;
3411 
3412 	vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numCoreQueueFamilies, DE_NULL);
3413 	vki.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &numExtQueueFamilies, DE_NULL);
3414 
3415 	TCU_CHECK_MSG(numCoreQueueFamilies == numExtQueueFamilies, "Different number of queue family properties reported");
3416 	TCU_CHECK(numCoreQueueFamilies > 0);
3417 
3418 	{
3419 		std::vector<VkQueueFamilyProperties>		coreProperties	(numCoreQueueFamilies);
3420 		std::vector<VkQueueFamilyProperties2>		extProperties	(numExtQueueFamilies);
3421 
3422 		deMemset(&coreProperties[0], 0xcd, sizeof(VkQueueFamilyProperties)*numCoreQueueFamilies);
3423 		deMemset(&extProperties[0], 0xcd, sizeof(VkQueueFamilyProperties2)*numExtQueueFamilies);
3424 
3425 		for (size_t ndx = 0; ndx < extProperties.size(); ++ndx)
3426 		{
3427 			extProperties[ndx].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
3428 			extProperties[ndx].pNext = DE_NULL;
3429 		}
3430 
3431 		vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numCoreQueueFamilies, &coreProperties[0]);
3432 		vki.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &numExtQueueFamilies, &extProperties[0]);
3433 
3434 		TCU_CHECK((size_t)numCoreQueueFamilies == coreProperties.size());
3435 		TCU_CHECK((size_t)numExtQueueFamilies == extProperties.size());
3436 		DE_ASSERT(numCoreQueueFamilies == numExtQueueFamilies);
3437 
3438 		for (size_t ndx = 0; ndx < extProperties.size(); ++ndx)
3439 		{
3440 			TCU_CHECK(extProperties[ndx].sType == VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2);
3441 			TCU_CHECK(extProperties[ndx].pNext == DE_NULL);
3442 
3443 			if (deMemCmp(&coreProperties[ndx], &extProperties[ndx].queueFamilyProperties, sizeof(VkQueueFamilyProperties)) != 0)
3444 				TCU_FAIL("Mismatch between format properties reported by vkGetPhysicalDeviceQueueFamilyProperties and vkGetPhysicalDeviceQueueFamilyProperties2");
3445 
3446 			log << TestLog::Message << " queueFamilyNdx = " << ndx <<TestLog::EndMessage
3447 			<< TestLog::Message << toString(extProperties[ndx]) << TestLog::EndMessage;
3448 		}
3449 	}
3450 
3451 	return tcu::TestStatus::pass("Querying device queue family properties succeeded");
3452 }
3453 
deviceMemoryProperties2(Context & context)3454 tcu::TestStatus deviceMemoryProperties2 (Context& context)
3455 {
3456 	const PlatformInterface&			vkp				= context.getPlatformInterface();
3457 	const VkPhysicalDevice				physicalDevice	= context.getPhysicalDevice();
3458 	const Unique<VkInstance>			instance		(createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_get_physical_device_properties2"));
3459 	const InstanceDriver				vki				(vkp, *instance);
3460 	TestLog&							log				= context.getTestContext().getLog();
3461 	VkPhysicalDeviceMemoryProperties	coreProperties;
3462 	VkPhysicalDeviceMemoryProperties2	extProperties;
3463 
3464 	deMemset(&coreProperties, 0xcd, sizeof(VkPhysicalDeviceMemoryProperties));
3465 	deMemset(&extProperties, 0xcd, sizeof(VkPhysicalDeviceMemoryProperties2));
3466 
3467 	extProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
3468 	extProperties.pNext = DE_NULL;
3469 
3470 	vki.getPhysicalDeviceMemoryProperties(physicalDevice, &coreProperties);
3471 	vki.getPhysicalDeviceMemoryProperties2(physicalDevice, &extProperties);
3472 
3473 	TCU_CHECK(extProperties.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2);
3474 	TCU_CHECK(extProperties.pNext == DE_NULL);
3475 
3476 	if (deMemCmp(&coreProperties, &extProperties.memoryProperties, sizeof(VkPhysicalDeviceMemoryProperties)) != 0)
3477 		TCU_FAIL("Mismatch between properties reported by vkGetPhysicalDeviceMemoryProperties and vkGetPhysicalDeviceMemoryProperties2");
3478 
3479 	log << TestLog::Message << extProperties << TestLog::EndMessage;
3480 
3481 	return tcu::TestStatus::pass("Querying device memory properties succeeded");
3482 }
3483 
imageFormatProperties2(Context & context,const VkFormat format,const VkImageType imageType,const VkImageTiling tiling)3484 tcu::TestStatus imageFormatProperties2 (Context& context, const VkFormat format, const VkImageType imageType, const VkImageTiling tiling)
3485 {
3486 	if (isYCbCrFormat(format))
3487 		// check if Ycbcr format enums are valid given the version and extensions
3488 		checkYcbcrApiSupport(context);
3489 
3490 	TestLog&						log				= context.getTestContext().getLog();
3491 
3492 	const PlatformInterface&		vkp				= context.getPlatformInterface();
3493 	const VkPhysicalDevice			physicalDevice	= context.getPhysicalDevice();
3494 	const Unique<VkInstance>		instance		(createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_get_physical_device_properties2"));
3495 	const InstanceDriver			vki				(vkp, *instance);
3496 
3497 	const VkImageCreateFlags		ycbcrFlags		= isYCbCrFormat(format) ? (VkImageCreateFlags)VK_IMAGE_CREATE_DISJOINT_BIT_KHR : (VkImageCreateFlags)0u;
3498 	const VkImageUsageFlags			allUsageFlags	= VK_IMAGE_USAGE_TRANSFER_SRC_BIT
3499 													| VK_IMAGE_USAGE_TRANSFER_DST_BIT
3500 													| VK_IMAGE_USAGE_SAMPLED_BIT
3501 													| VK_IMAGE_USAGE_STORAGE_BIT
3502 													| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
3503 													| VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
3504 													| VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
3505 													| VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
3506 	const VkImageCreateFlags		allCreateFlags	= VK_IMAGE_CREATE_SPARSE_BINDING_BIT
3507 													| VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT
3508 													| VK_IMAGE_CREATE_SPARSE_ALIASED_BIT
3509 													| VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
3510 													| VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT
3511 													| ycbcrFlags;
3512 
3513 	for (VkImageUsageFlags curUsageFlags = (VkImageUsageFlags)1; curUsageFlags <= allUsageFlags; curUsageFlags++)
3514 	{
3515 		for (VkImageCreateFlags curCreateFlags = 0; curCreateFlags <= allCreateFlags; curCreateFlags++)
3516 		{
3517 			const VkPhysicalDeviceImageFormatInfo2	imageFormatInfo	=
3518 			{
3519 				VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
3520 				DE_NULL,
3521 				format,
3522 				imageType,
3523 				tiling,
3524 				curUsageFlags,
3525 				curCreateFlags
3526 			};
3527 
3528 			VkImageFormatProperties						coreProperties;
3529 			VkImageFormatProperties2					extProperties;
3530 			VkResult									coreResult;
3531 			VkResult									extResult;
3532 
3533 			deMemset(&coreProperties, 0xcd, sizeof(VkImageFormatProperties));
3534 			deMemset(&extProperties, 0xcd, sizeof(VkImageFormatProperties2));
3535 
3536 			extProperties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
3537 			extProperties.pNext = DE_NULL;
3538 
3539 			coreResult	= vki.getPhysicalDeviceImageFormatProperties(physicalDevice, imageFormatInfo.format, imageFormatInfo.type, imageFormatInfo.tiling, imageFormatInfo.usage, imageFormatInfo.flags, &coreProperties);
3540 			extResult	= vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &imageFormatInfo, &extProperties);
3541 
3542 			TCU_CHECK(extProperties.sType == VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2);
3543 			TCU_CHECK(extProperties.pNext == DE_NULL);
3544 
3545 			if ((coreResult != extResult) ||
3546 				(deMemCmp(&coreProperties, &extProperties.imageFormatProperties, sizeof(VkImageFormatProperties)) != 0))
3547 			{
3548 				log << TestLog::Message << "ERROR: device mismatch with query " << imageFormatInfo << TestLog::EndMessage
3549 					<< TestLog::Message << "vkGetPhysicalDeviceImageFormatProperties() returned " << coreResult << ", " << coreProperties << TestLog::EndMessage
3550 					<< TestLog::Message << "vkGetPhysicalDeviceImageFormatProperties2() returned " << extResult << ", " << extProperties << TestLog::EndMessage;
3551 				TCU_FAIL("Mismatch between image format properties reported by vkGetPhysicalDeviceImageFormatProperties and vkGetPhysicalDeviceImageFormatProperties2");
3552 			}
3553 		}
3554 	}
3555 
3556 	return tcu::TestStatus::pass("Querying image format properties succeeded");
3557 }
3558 
sparseImageFormatProperties2(Context & context,const VkFormat format,const VkImageType imageType,const VkImageTiling tiling)3559 tcu::TestStatus sparseImageFormatProperties2 (Context& context, const VkFormat format, const VkImageType imageType, const VkImageTiling tiling)
3560 {
3561 	TestLog&						log				= context.getTestContext().getLog();
3562 
3563 	const PlatformInterface&		vkp				= context.getPlatformInterface();
3564 	const VkPhysicalDevice			physicalDevice	= context.getPhysicalDevice();
3565 	const Unique<VkInstance>		instance		(createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_get_physical_device_properties2"));
3566 	const InstanceDriver			vki				(vkp, *instance);
3567 
3568 	const VkImageUsageFlags			allUsageFlags	= VK_IMAGE_USAGE_TRANSFER_SRC_BIT
3569 													| VK_IMAGE_USAGE_TRANSFER_DST_BIT
3570 													| VK_IMAGE_USAGE_SAMPLED_BIT
3571 													| VK_IMAGE_USAGE_STORAGE_BIT
3572 													| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
3573 													| VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
3574 													| VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
3575 													| VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
3576 
3577 	for (deUint32 sampleCountBit = VK_SAMPLE_COUNT_1_BIT; sampleCountBit <= VK_SAMPLE_COUNT_64_BIT; sampleCountBit = (sampleCountBit << 1u))
3578 	{
3579 		for (VkImageUsageFlags curUsageFlags = (VkImageUsageFlags)1; curUsageFlags <= allUsageFlags; curUsageFlags++)
3580 		{
3581 			const VkPhysicalDeviceSparseImageFormatInfo2	imageFormatInfo	=
3582 			{
3583 				VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2,
3584 				DE_NULL,
3585 				format,
3586 				imageType,
3587 				(VkSampleCountFlagBits)sampleCountBit,
3588 				curUsageFlags,
3589 				tiling,
3590 			};
3591 
3592 			deUint32										numCoreProperties	= ~0u;
3593 			deUint32										numExtProperties	= ~0u;
3594 
3595 			// Query count
3596 			vki.getPhysicalDeviceSparseImageFormatProperties(physicalDevice, imageFormatInfo.format, imageFormatInfo.type, imageFormatInfo.samples, imageFormatInfo.usage, imageFormatInfo.tiling, &numCoreProperties, DE_NULL);
3597 			vki.getPhysicalDeviceSparseImageFormatProperties2(physicalDevice, &imageFormatInfo, &numExtProperties, DE_NULL);
3598 
3599 			if (numCoreProperties != numExtProperties)
3600 			{
3601 				log << TestLog::Message << "ERROR: different number of properties reported for " << imageFormatInfo << TestLog::EndMessage;
3602 				TCU_FAIL("Mismatch in reported property count");
3603 			}
3604 
3605 			if (numCoreProperties > 0)
3606 			{
3607 				std::vector<VkSparseImageFormatProperties>		coreProperties	(numCoreProperties);
3608 				std::vector<VkSparseImageFormatProperties2>		extProperties	(numExtProperties);
3609 
3610 				deMemset(&coreProperties[0], 0xcd, sizeof(VkSparseImageFormatProperties)*numCoreProperties);
3611 				deMemset(&extProperties[0], 0xcd, sizeof(VkSparseImageFormatProperties2)*numExtProperties);
3612 
3613 				for (deUint32 ndx = 0; ndx < numExtProperties; ++ndx)
3614 				{
3615 					extProperties[ndx].sType = VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2;
3616 					extProperties[ndx].pNext = DE_NULL;
3617 				}
3618 
3619 				vki.getPhysicalDeviceSparseImageFormatProperties(physicalDevice, imageFormatInfo.format, imageFormatInfo.type, imageFormatInfo.samples, imageFormatInfo.usage, imageFormatInfo.tiling, &numCoreProperties, &coreProperties[0]);
3620 				vki.getPhysicalDeviceSparseImageFormatProperties2(physicalDevice, &imageFormatInfo, &numExtProperties, &extProperties[0]);
3621 
3622 				TCU_CHECK((size_t)numCoreProperties == coreProperties.size());
3623 				TCU_CHECK((size_t)numExtProperties == extProperties.size());
3624 
3625 				for (deUint32 ndx = 0; ndx < numCoreProperties; ++ndx)
3626 				{
3627 					TCU_CHECK(extProperties[ndx].sType == VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2);
3628 					TCU_CHECK(extProperties[ndx].pNext == DE_NULL);
3629 
3630 					if ((deMemCmp(&coreProperties[ndx], &extProperties[ndx].properties, sizeof(VkSparseImageFormatProperties)) != 0))
3631 					{
3632 						log << TestLog::Message << "ERROR: device mismatch with query " << imageFormatInfo << " property " << ndx << TestLog::EndMessage
3633 							<< TestLog::Message << "vkGetPhysicalDeviceSparseImageFormatProperties() returned " << coreProperties[ndx] << TestLog::EndMessage
3634 							<< TestLog::Message << "vkGetPhysicalDeviceSparseImageFormatProperties2() returned " << extProperties[ndx] << TestLog::EndMessage;
3635 						TCU_FAIL("Mismatch between image format properties reported by vkGetPhysicalDeviceSparseImageFormatProperties and vkGetPhysicalDeviceSparseImageFormatProperties2");
3636 					}
3637 				}
3638 			}
3639 		}
3640 	}
3641 
3642 	return tcu::TestStatus::pass("Querying sparse image format properties succeeded");
3643 }
3644 
execImageFormatTest(Context & context,ImageFormatPropertyCase testCase)3645 tcu::TestStatus execImageFormatTest (Context& context, ImageFormatPropertyCase testCase)
3646 {
3647 	return testCase.testFunction(context, testCase.format, testCase.imageType, testCase.tiling);
3648 }
3649 
createImageFormatTypeTilingTests(tcu::TestCaseGroup * testGroup,ImageFormatPropertyCase params)3650 void createImageFormatTypeTilingTests (tcu::TestCaseGroup* testGroup, ImageFormatPropertyCase params)
3651 {
3652 	DE_ASSERT(params.format == VK_FORMAT_UNDEFINED);
3653 
3654 	static const struct
3655 	{
3656 		VkFormat								begin;
3657 		VkFormat								end;
3658 		ImageFormatPropertyCase					params;
3659 	} s_formatRanges[] =
3660 	{
3661 		// core formats
3662 		{ (VkFormat)(VK_FORMAT_UNDEFINED + 1),	VK_CORE_FORMAT_LAST,										params },
3663 
3664 		// YCbCr formats
3665 		{ VK_FORMAT_G8B8G8R8_422_UNORM_KHR,		(VkFormat)(VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR + 1),	params }
3666 	};
3667 
3668 	for (int rangeNdx = 0; rangeNdx < DE_LENGTH_OF_ARRAY(s_formatRanges); ++rangeNdx)
3669 	{
3670 		const VkFormat								rangeBegin		= s_formatRanges[rangeNdx].begin;
3671 		const VkFormat								rangeEnd		= s_formatRanges[rangeNdx].end;
3672 
3673 		for (VkFormat format = rangeBegin; format != rangeEnd; format = (VkFormat)(format+1))
3674 		{
3675 			const bool			isYCbCr		= isYCbCrFormat(format);
3676 			const bool			isSparse	= (params.testFunction == sparseImageFormatProperties2);
3677 
3678 			if (isYCbCr && isSparse)
3679 				continue;
3680 
3681 			if (isYCbCr && params.imageType != VK_IMAGE_TYPE_2D)
3682 				continue;
3683 
3684 			const char* const	enumName	= getFormatName(format);
3685 			const string		caseName	= de::toLower(string(enumName).substr(10));
3686 
3687 			params.format = format;
3688 
3689 			addFunctionCase(testGroup, caseName, enumName, execImageFormatTest, params);
3690 		}
3691 	}
3692 }
3693 
createImageFormatTypeTests(tcu::TestCaseGroup * testGroup,ImageFormatPropertyCase params)3694 void createImageFormatTypeTests (tcu::TestCaseGroup* testGroup, ImageFormatPropertyCase params)
3695 {
3696 	DE_ASSERT(params.tiling == VK_IMAGE_TILING_LAST);
3697 
3698 	testGroup->addChild(createTestGroup(testGroup->getTestContext(), "optimal",	"",	createImageFormatTypeTilingTests, ImageFormatPropertyCase(params.testFunction, VK_FORMAT_UNDEFINED, params.imageType, VK_IMAGE_TILING_OPTIMAL)));
3699 	testGroup->addChild(createTestGroup(testGroup->getTestContext(), "linear",	"",	createImageFormatTypeTilingTests, ImageFormatPropertyCase(params.testFunction, VK_FORMAT_UNDEFINED, params.imageType, VK_IMAGE_TILING_LINEAR)));
3700 }
3701 
createImageFormatTests(tcu::TestCaseGroup * testGroup,ImageFormatPropertyCase::Function testFunction)3702 void createImageFormatTests (tcu::TestCaseGroup* testGroup, ImageFormatPropertyCase::Function testFunction)
3703 {
3704 	testGroup->addChild(createTestGroup(testGroup->getTestContext(), "1d", "", createImageFormatTypeTests, ImageFormatPropertyCase(testFunction, VK_FORMAT_UNDEFINED, VK_IMAGE_TYPE_1D, VK_IMAGE_TILING_LAST)));
3705 	testGroup->addChild(createTestGroup(testGroup->getTestContext(), "2d", "", createImageFormatTypeTests, ImageFormatPropertyCase(testFunction, VK_FORMAT_UNDEFINED, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_LAST)));
3706 	testGroup->addChild(createTestGroup(testGroup->getTestContext(), "3d", "", createImageFormatTypeTests, ImageFormatPropertyCase(testFunction, VK_FORMAT_UNDEFINED, VK_IMAGE_TYPE_3D, VK_IMAGE_TILING_LAST)));
3707 }
3708 
3709 
3710 // Android CTS -specific tests
3711 
3712 namespace android
3713 {
3714 
checkExtensions(tcu::ResultCollector & results,const set<string> & allowedExtensions,const vector<VkExtensionProperties> & reportedExtensions)3715 void checkExtensions (tcu::ResultCollector& results, const set<string>& allowedExtensions, const vector<VkExtensionProperties>& reportedExtensions)
3716 {
3717 	for (vector<VkExtensionProperties>::const_iterator extension = reportedExtensions.begin(); extension != reportedExtensions.end(); ++extension)
3718 	{
3719 		const string	extensionName	(extension->extensionName);
3720 		const bool		mustBeKnown		= de::beginsWith(extensionName, "VK_GOOGLE_")	||
3721 										  de::beginsWith(extensionName, "VK_ANDROID_");
3722 
3723 		if (mustBeKnown && !de::contains(allowedExtensions, extensionName))
3724 			results.fail("Unknown extension: " + extensionName);
3725 	}
3726 }
3727 
testNoUnknownExtensions(Context & context)3728 tcu::TestStatus testNoUnknownExtensions (Context& context)
3729 {
3730 	TestLog&				log					= context.getTestContext().getLog();
3731 	tcu::ResultCollector	results				(log);
3732 	set<string>				allowedInstanceExtensions;
3733 	set<string>				allowedDeviceExtensions;
3734 
3735 	// All known extensions should be added to allowedExtensions:
3736 	// allowedExtensions.insert("VK_GOOGLE_extension1");
3737 	allowedDeviceExtensions.insert("VK_ANDROID_external_memory_android_hardware_buffer");
3738 	allowedDeviceExtensions.insert("VK_GOOGLE_display_timing");
3739 
3740 	// Instance extensions
3741 	checkExtensions(results,
3742 					allowedInstanceExtensions,
3743 					enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL));
3744 
3745 	// Extensions exposed by instance layers
3746 	{
3747 		const vector<VkLayerProperties>	layers	= enumerateInstanceLayerProperties(context.getPlatformInterface());
3748 
3749 		for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
3750 		{
3751 			checkExtensions(results,
3752 							allowedInstanceExtensions,
3753 							enumerateInstanceExtensionProperties(context.getPlatformInterface(), layer->layerName));
3754 		}
3755 	}
3756 
3757 	// Device extensions
3758 	checkExtensions(results,
3759 					allowedDeviceExtensions,
3760 					enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), DE_NULL));
3761 
3762 	// Extensions exposed by device layers
3763 	{
3764 		const vector<VkLayerProperties>	layers	= enumerateDeviceLayerProperties(context.getInstanceInterface(), context.getPhysicalDevice());
3765 
3766 		for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
3767 		{
3768 			checkExtensions(results,
3769 							allowedDeviceExtensions,
3770 							enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), layer->layerName));
3771 		}
3772 	}
3773 
3774 	return tcu::TestStatus(results.getResult(), results.getMessage());
3775 }
3776 
testNoLayers(Context & context)3777 tcu::TestStatus testNoLayers (Context& context)
3778 {
3779 	TestLog&				log		= context.getTestContext().getLog();
3780 	tcu::ResultCollector	results	(log);
3781 
3782 	{
3783 		const vector<VkLayerProperties>	layers	= enumerateInstanceLayerProperties(context.getPlatformInterface());
3784 
3785 		for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
3786 			results.fail(string("Instance layer enumerated: ") + layer->layerName);
3787 	}
3788 
3789 	{
3790 		const vector<VkLayerProperties>	layers	= enumerateDeviceLayerProperties(context.getInstanceInterface(), context.getPhysicalDevice());
3791 
3792 		for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
3793 			results.fail(string("Device layer enumerated: ") + layer->layerName);
3794 	}
3795 
3796 	return tcu::TestStatus(results.getResult(), results.getMessage());
3797 }
3798 
testMandatoryExtensions(Context & context)3799 tcu::TestStatus testMandatoryExtensions (Context& context)
3800 {
3801 	TestLog&				log		= context.getTestContext().getLog();
3802 	tcu::ResultCollector	results	(log);
3803 
3804 	// Instance extensions
3805 	{
3806 		static const char*					mandatoryExtensions[]	=
3807 		{
3808 			"VK_KHR_get_physical_device_properties2",
3809 		};
3810 		const vector<VkExtensionProperties>	extensions				= enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL);
3811 
3812 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(mandatoryExtensions); ++ndx)
3813 		{
3814 			if (!isInstanceExtensionSupported(context.getUsedApiVersion(), extensions, RequiredExtension(mandatoryExtensions[ndx])))
3815 				results.fail(string(mandatoryExtensions[ndx]) + " is not supported");
3816 		}
3817 	}
3818 
3819 	// Device extensions
3820 	{
3821 		static const char*					mandatoryExtensions[]	=
3822 		{
3823 			"VK_KHR_maintenance1",
3824 		};
3825 		const vector<VkExtensionProperties>	extensions				= enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), DE_NULL);
3826 
3827 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(mandatoryExtensions); ++ndx)
3828 		{
3829 			if (!isDeviceExtensionSupported(context.getUsedApiVersion(), extensions, RequiredExtension(mandatoryExtensions[ndx])))
3830 				results.fail(string(mandatoryExtensions[ndx]) + " is not supported");
3831 		}
3832 	}
3833 
3834 	return tcu::TestStatus(results.getResult(), results.getMessage());
3835 }
3836 
3837 } // android
3838 
3839 } // anonymous
3840 
createFeatureInfoTests(tcu::TestContext & testCtx)3841 tcu::TestCaseGroup* createFeatureInfoTests (tcu::TestContext& testCtx)
3842 {
3843 	de::MovePtr<tcu::TestCaseGroup>	infoTests	(new tcu::TestCaseGroup(testCtx, "info", "Platform Information Tests"));
3844 
3845 	{
3846 		de::MovePtr<tcu::TestCaseGroup> instanceInfoTests	(new tcu::TestCaseGroup(testCtx, "instance", "Instance Information Tests"));
3847 
3848 		addFunctionCase(instanceInfoTests.get(), "physical_devices",		"Physical devices",			enumeratePhysicalDevices);
3849 		addFunctionCase(instanceInfoTests.get(), "physical_device_groups",	"Physical devices Groups",	enumeratePhysicalDeviceGroups);
3850 		addFunctionCase(instanceInfoTests.get(), "layers",					"Layers",					enumerateInstanceLayers);
3851 		addFunctionCase(instanceInfoTests.get(), "extensions",				"Extensions",				enumerateInstanceExtensions);
3852 
3853 		infoTests->addChild(instanceInfoTests.release());
3854 	}
3855 
3856 	{
3857 		de::MovePtr<tcu::TestCaseGroup> deviceInfoTests	(new tcu::TestCaseGroup(testCtx, "device", "Device Information Tests"));
3858 
3859 		addFunctionCase(deviceInfoTests.get(), "features",					"Device Features",			deviceFeatures);
3860 		addFunctionCase(deviceInfoTests.get(), "properties",				"Device Properties",		deviceProperties);
3861 		addFunctionCase(deviceInfoTests.get(), "queue_family_properties",	"Queue family properties",	deviceQueueFamilyProperties);
3862 		addFunctionCase(deviceInfoTests.get(), "memory_properties",			"Memory properties",		deviceMemoryProperties);
3863 		addFunctionCase(deviceInfoTests.get(), "layers",					"Layers",					enumerateDeviceLayers);
3864 		addFunctionCase(deviceInfoTests.get(), "extensions",				"Extensions",				enumerateDeviceExtensions);
3865 		addFunctionCase(deviceInfoTests.get(), "no_khx_extensions",			"KHX extensions",			testNoKhxExtensions);
3866 
3867 		infoTests->addChild(deviceInfoTests.release());
3868 	}
3869 
3870 	{
3871 		de::MovePtr<tcu::TestCaseGroup> deviceGroupInfoTests(new tcu::TestCaseGroup(testCtx, "device_group", "Device Group Information Tests"));
3872 
3873 		addFunctionCase(deviceGroupInfoTests.get(), "peer_memory_features",	"Device Group peer memory features",				deviceGroupPeerMemoryFeatures);
3874 
3875 		infoTests->addChild(deviceGroupInfoTests.release());
3876 	}
3877 
3878 	infoTests->addChild(createTestGroup(testCtx, "format_properties",		"VkGetPhysicalDeviceFormatProperties() Tests",		createFormatTests));
3879 	infoTests->addChild(createTestGroup(testCtx, "image_format_properties",	"VkGetPhysicalDeviceImageFormatProperties() Tests",	createImageFormatTests,	imageFormatProperties));
3880 
3881 	{
3882 		de::MovePtr<tcu::TestCaseGroup> extendedPropertiesTests (new tcu::TestCaseGroup(testCtx, "get_physical_device_properties2", "VK_KHR_get_physical_device_properties2"));
3883 
3884 		addFunctionCase(extendedPropertiesTests.get(), "features",					"Extended Device Features",					deviceFeatures2);
3885 		addFunctionCase(extendedPropertiesTests.get(), "properties",				"Extended Device Properties",				deviceProperties2);
3886 		addFunctionCase(extendedPropertiesTests.get(), "format_properties",			"Extended Device Format Properties",		deviceFormatProperties2);
3887 		addFunctionCase(extendedPropertiesTests.get(), "queue_family_properties",	"Extended Device Queue Family Properties",	deviceQueueFamilyProperties2);
3888 		addFunctionCase(extendedPropertiesTests.get(), "memory_properties",			"Extended Device Memory Properties",		deviceMemoryProperties2);
3889 
3890 		infoTests->addChild(extendedPropertiesTests.release());
3891 	}
3892 
3893 	infoTests->addChild(createTestGroup(testCtx, "image_format_properties2",		"VkGetPhysicalDeviceImageFormatProperties2() Tests",		createImageFormatTests, imageFormatProperties2));
3894 	infoTests->addChild(createTestGroup(testCtx, "sparse_image_format_properties2",	"VkGetPhysicalDeviceSparseImageFormatProperties2() Tests",	createImageFormatTests, sparseImageFormatProperties2));
3895 
3896 	{
3897 		de::MovePtr<tcu::TestCaseGroup>	androidTests	(new tcu::TestCaseGroup(testCtx, "android", "Android CTS Tests"));
3898 
3899 		addFunctionCase(androidTests.get(),	"mandatory_extensions",		"Test that all mandatory extensions are supported",	android::testMandatoryExtensions);
3900 		addFunctionCase(androidTests.get(), "no_unknown_extensions",	"Test for unknown device or instance extensions",	android::testNoUnknownExtensions);
3901 		addFunctionCase(androidTests.get(), "no_layers",				"Test that no layers are enumerated",				android::testNoLayers);
3902 
3903 		infoTests->addChild(androidTests.release());
3904 	}
3905 
3906 	return infoTests.release();
3907 }
3908 
3909 } // api
3910 } // vkt
3911