1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 Google Inc.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and/or associated documentation files (the
9 * "Materials"), to deal in the Materials without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Materials, and to
12 * permit persons to whom the Materials are furnished to do so, subject to
13 * the following conditions:
15 * The above copyright notice(s) and this permission notice shall be
16 * included in all copies or substantial portions of the Materials.
18 * The Materials are Confidential Information as defined by the
19 * Khronos Membership Agreement until designated non-confidential by
20 * Khronos, at which point this condition clause shall be removed.
22 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
26 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
32 * \brief Api Feature Query tests
33 *//*--------------------------------------------------------------------*/
35 #include "vktApiFeatureInfo.hpp"
37 #include "vktTestCaseUtil.hpp"
39 #include "vkPlatform.hpp"
40 #include "vkStrUtil.hpp"
42 #include "vkDeviceUtil.hpp"
43 #include "vkQueryUtil.hpp"
45 #include "tcuTestLog.hpp"
46 #include "tcuFormatUtil.hpp"
48 #include "deUniquePtr.hpp"
62 using tcu::ScopedLogSection;
66 GUARD_SIZE = 0x20, //!< Number of bytes to check
67 GUARD_VALUE = 0xcd, //!< Data pattern
72 LIMIT_FORMAT_SIGNED_INT,
73 LIMIT_FORMAT_UNSIGNED_INT,
75 LIMIT_FORMAT_DEVICE_SIZE,
88 #define LIMIT(_X_) DE_OFFSET_OF(VkPhysicalDeviceLimits, _X_),(char*)(#_X_)
89 #define FEATURE(_X_) DE_OFFSET_OF(VkPhysicalDeviceFeatures, _X_)
91 bool validateFeatureLimits(VkPhysicalDeviceProperties* properties, VkPhysicalDeviceFeatures* features, TestLog& log)
94 VkPhysicalDeviceLimits* limits = &properties->limits;
95 struct FeatureLimitTable
99 deUint32 uintVal; //!< Format is UNSIGNED_INT
100 deInt32 intVal; //!< Format is SIGNED_INT
101 deUint64 deviceSizeVal; //!< Format is DEVICE_SIZE
102 float floatVal; //!< Format is FLOAT
105 deInt32 unsuppTableNdx;
106 } featureLimitTable[] = //!< From gitlab.khronos.org/vulkan/vulkan.git:doc/specs/vulkan/chapters/features.txt@63b23f3bb3ecd211cd6e448e2001ce1088dacd35
108 { LIMIT(maxImageDimension1D), 4096, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
109 { LIMIT(maxImageDimension2D), 4096, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
110 { LIMIT(maxImageDimension3D), 256, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
111 { LIMIT(maxImageDimensionCube), 4096, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
112 { LIMIT(maxImageArrayLayers), 256, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
113 { LIMIT(maxTexelBufferElements), 65536, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
114 { LIMIT(maxUniformBufferRange), 16384, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
115 { LIMIT(maxPushConstantsSize), 128, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
116 { LIMIT(maxMemoryAllocationCount), 4096, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
117 { LIMIT(bufferImageGranularity), 0, 0, 131072, 0, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MAX, -1 },
118 { LIMIT(sparseAddressSpaceSize), 0, 0, 2UL*1024*1024*1024, 0, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1 },
119 { LIMIT(maxBoundDescriptorSets), 4, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
120 { LIMIT(maxPerStageDescriptorSamplers), 16, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
121 { LIMIT(maxPerStageDescriptorUniformBuffers), 12, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
122 { LIMIT(maxPerStageDescriptorStorageBuffers), 4, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
123 { LIMIT(maxPerStageDescriptorSampledImages), 16, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
124 { LIMIT(maxPerStageDescriptorStorageImages), 4, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
125 { LIMIT(maxPerStageDescriptorInputAttachments), 4, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
126 { LIMIT(maxDescriptorSetSamplers), 96, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
127 { LIMIT(maxDescriptorSetUniformBuffers), 72, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
128 { LIMIT(maxDescriptorSetUniformBuffersDynamic), 8, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
129 { LIMIT(maxDescriptorSetStorageBuffers), 24, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
130 { LIMIT(maxDescriptorSetStorageBuffersDynamic), 4, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
131 { LIMIT(maxDescriptorSetSampledImages), 96, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
132 { LIMIT(maxDescriptorSetStorageImages), 24, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
133 { LIMIT(maxVertexInputAttributes), 16, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
134 { LIMIT(maxVertexInputBindings), 16, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
135 { LIMIT(maxVertexInputAttributeOffset), 2047, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
136 { LIMIT(maxVertexInputBindingStride), 2048, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
137 { LIMIT(maxVertexOutputComponents), 64, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
138 { LIMIT(maxTessellationGenerationLevel), 64, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
139 { LIMIT(maxTessellationPatchSize), 32, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
140 { LIMIT(maxTessellationControlPerVertexInputComponents), 64, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
141 { LIMIT(maxTessellationControlPerVertexOutputComponents), 64, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
142 { LIMIT(maxTessellationControlPerPatchOutputComponents), 120, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
143 { LIMIT(maxTessellationControlTotalOutputComponents), 2048, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
144 { LIMIT(maxTessellationEvaluationInputComponents), 64, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
145 { LIMIT(maxTessellationEvaluationOutputComponents), 64, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
146 { LIMIT(maxGeometryShaderInvocations), 32, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
147 { LIMIT(maxGeometryInputComponents), 64, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
148 { LIMIT(maxGeometryOutputComponents), 64, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
149 { LIMIT(maxGeometryOutputVertices), 256, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
150 { LIMIT(maxGeometryTotalOutputComponents), 1024, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
151 { LIMIT(maxFragmentInputComponents), 64, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
152 { LIMIT(maxFragmentOutputAttachments), 4, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
153 { LIMIT(maxFragmentDualSrcAttachments), 1, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
154 { LIMIT(maxFragmentCombinedOutputResources), 4, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
155 { LIMIT(maxComputeSharedMemorySize), 16384, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
156 { LIMIT(maxComputeWorkGroupCount[0]), 65535, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
157 { LIMIT(maxComputeWorkGroupCount[1]), 65535, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
158 { LIMIT(maxComputeWorkGroupCount[2]), 65535, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
159 { LIMIT(maxComputeWorkGroupInvocations), 128, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
160 { LIMIT(maxComputeWorkGroupSize[0]), 128, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
161 { LIMIT(maxComputeWorkGroupSize[1]), 128, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
162 { LIMIT(maxComputeWorkGroupSize[2]), 64, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
163 { LIMIT(subPixelPrecisionBits), 4, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
164 { LIMIT(subTexelPrecisionBits), 4, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
165 { LIMIT(mipmapPrecisionBits), 4, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
166 { LIMIT(maxDrawIndexedIndexValue), (deUint32)~0, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
167 { LIMIT(maxDrawIndirectCount), 65535, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
168 { LIMIT(maxSamplerLodBias), 0, 0, 0, 2.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
169 { LIMIT(maxSamplerAnisotropy), 0, 0, 0, 16.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
170 { LIMIT(maxViewports), 16, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
171 { LIMIT(maxViewportDimensions[0]), 4096, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
172 { LIMIT(maxViewportDimensions[1]), 4096, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 },
173 { LIMIT(viewportBoundsRange[0]), 0, 0, 0, -8192, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 },
174 { LIMIT(viewportBoundsRange[1]), 0, 0, 0, 8191, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
175 { LIMIT(viewportSubPixelBits), 0, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
176 { LIMIT(minMemoryMapAlignment), 64, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
177 { LIMIT(minTexelBufferOffsetAlignment), 256, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MAX, -1 },
178 { LIMIT(minUniformBufferOffsetAlignment), 256, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MAX, -1 },
179 { LIMIT(minStorageBufferOffsetAlignment), 256, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MAX, -1 },
180 { LIMIT(minTexelOffset), 0, -8, 0, 0, LIMIT_FORMAT_SIGNED_INT, LIMIT_TYPE_MAX, -1 },
181 { LIMIT(maxTexelOffset), 7, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
182 { LIMIT(minTexelGatherOffset), 0, -8, 0, 0, LIMIT_FORMAT_SIGNED_INT, LIMIT_TYPE_MAX, -1 },
183 { LIMIT(maxTexelGatherOffset), 7, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
184 { LIMIT(minInterpolationOffset), 0, 0, 0, -0.5f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 },
185 { LIMIT(maxInterpolationOffset), 0, 0, 0, 0.5f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
186 { LIMIT(subPixelInterpolationOffsetBits), 4, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
187 { LIMIT(maxFramebufferWidth), 4096, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
188 { LIMIT(maxFramebufferHeight), 4096, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
189 { LIMIT(maxFramebufferLayers), 256, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
190 { LIMIT(maxColorAttachments), 4, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
191 { LIMIT(maxSampleMaskWords), 1, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
192 { LIMIT(maxClipDistances), 8, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
193 { LIMIT(maxCullDistances), 8, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
194 { LIMIT(maxCombinedClipAndCullDistances), 8, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 },
195 { LIMIT(pointSizeRange[0]), 0, 0, 0, 1.0, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 },
196 { LIMIT(pointSizeRange[1]), 0, 0, 0, 1.0, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
197 { LIMIT(pointSizeRange[0]), 0, 0, 0, 1.0, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 },
198 { LIMIT(pointSizeRange[1]), 0, 0, 0, 64.0, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
199 { LIMIT(lineWidthRange[0]), 0, 0, 0, 1.0, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 },
200 { LIMIT(lineWidthRange[1]), 0, 0, 0, 1.0, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
201 { LIMIT(lineWidthRange[0]), 0, 0, 0, 1.0, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 },
202 { LIMIT(lineWidthRange[1]), 0, 0, 0, 8.0, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 },
203 { LIMIT(pointSizeGranularity), 0, 0, 0, 1.0, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 },
204 { LIMIT(lineWidthGranularity), 0, 0, 0, 1.0, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 },
205 { LIMIT(nonCoherentAtomSize), 0, 0, 128, 0, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MAX, -1 },
208 struct UnsupportedFeatureLimitTable
210 deUint32 limitOffset;
212 deUint32 featureOffset;
213 deUint32 uintVal; //!< Format is UNSIGNED_INT
214 deInt32 intVal; //!< Format is SIGNED_INT
215 deUint64 deviceSizeVal; //!< Format is DEVICE_SIZE
216 float floatVal; //!< Format is FLOAT
217 } unsupportedFeatureTable[] =
219 { LIMIT(sparseAddressSpaceSize), FEATURE(sparseBinding), 0, 0, 0, 0 },
220 { LIMIT(maxTessellationGenerationLevel), FEATURE(tessellationShader), 0, 0, 0, 0 },
221 { LIMIT(maxTessellationPatchSize), FEATURE(tessellationShader), 0, 0, 0, 0 },
222 { LIMIT(maxTessellationControlPerVertexInputComponents), FEATURE(tessellationShader), 0, 0, 0, 0 },
223 { LIMIT(maxTessellationControlPerVertexOutputComponents), FEATURE(tessellationShader), 0, 0, 0, 0 },
224 { LIMIT(maxTessellationControlPerPatchOutputComponents), FEATURE(tessellationShader), 0, 0, 0, 0 },
225 { LIMIT(maxTessellationControlTotalOutputComponents), FEATURE(tessellationShader), 0, 0, 0, 0 },
226 { LIMIT(maxTessellationEvaluationInputComponents), FEATURE(tessellationShader), 0, 0, 0, 0 },
227 { LIMIT(maxTessellationEvaluationOutputComponents), FEATURE(tessellationShader), 0, 0, 0, 0 },
228 { LIMIT(maxGeometryShaderInvocations), FEATURE(geometryShader), 0, 0, 0, 0 },
229 { LIMIT(maxGeometryInputComponents), FEATURE(geometryShader), 0, 0, 0, 0 },
230 { LIMIT(maxGeometryOutputComponents), FEATURE(geometryShader), 0, 0, 0, 0 },
231 { LIMIT(maxGeometryOutputVertices), FEATURE(geometryShader), 0, 0, 0, 0 },
232 { LIMIT(maxGeometryTotalOutputComponents), FEATURE(geometryShader), 0, 0, 0, 0 },
233 { LIMIT(maxFragmentDualSrcAttachments), FEATURE(dualSrcBlend), 0, 0, 0, 0 },
234 { LIMIT(maxDrawIndexedIndexValue), FEATURE(fullDrawIndexUint32), (1<<24)-1, 0, 0, 0 },
235 { LIMIT(maxDrawIndirectCount), FEATURE(multiDrawIndirect), 1, 0, 0, 0 },
236 { LIMIT(maxSamplerAnisotropy), FEATURE(samplerAnisotropy), 1, 0, 0, 0 },
237 { LIMIT(maxViewports), FEATURE(multiViewport), 1, 0, 0, 0 },
238 { LIMIT(minTexelGatherOffset), FEATURE(shaderImageGatherExtended), 0, 0, 0, 0 },
239 { LIMIT(maxTexelGatherOffset), FEATURE(shaderImageGatherExtended), 0, 0, 0, 0 },
240 { LIMIT(minInterpolationOffset), FEATURE(sampleRateShading), 0, 0, 0, 0 },
241 { LIMIT(maxInterpolationOffset), FEATURE(sampleRateShading), 0, 0, 0, 0 },
242 { LIMIT(subPixelInterpolationOffsetBits), FEATURE(sampleRateShading), 0, 0, 0, 0 },
243 { LIMIT(storageImageSampleCounts), FEATURE(shaderStorageImageMultisample), 0, 0, 0, 0 },
244 { LIMIT(maxClipDistances), FEATURE(shaderClipDistance), 0, 0, 0, 0 },
245 { LIMIT(maxCullDistances), FEATURE(shaderClipDistance), 0, 0, 0, 0 },
246 { LIMIT(maxCombinedClipAndCullDistances), FEATURE(shaderClipDistance), 0, 0, 0, 0 },
247 { LIMIT(pointSizeRange[0]), FEATURE(largePoints), 0, 0, 0, 0 },
248 { LIMIT(pointSizeRange[1]), FEATURE(largePoints), 0, 0, 0, 1.0 },
249 { LIMIT(lineWidthRange[0]), FEATURE(wideLines), 0, 0, 0, 1.0 },
250 { LIMIT(pointSizeGranularity), FEATURE(largePoints), 0, 0, 0, 0 },
251 { LIMIT(lineWidthGranularity), FEATURE(wideLines), 0, 0, 0, 0 }
254 log << TestLog::Message << *limits << TestLog::EndMessage;
256 //!< First build a map from limit to unsupported table index
257 for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
259 for (deUint32 unsuppNdx = 0; unsuppNdx < DE_LENGTH_OF_ARRAY(unsupportedFeatureTable); unsuppNdx++)
261 if (unsupportedFeatureTable[unsuppNdx].limitOffset == featureLimitTable[ndx].offset)
263 featureLimitTable[ndx].unsuppTableNdx = unsuppNdx;
269 for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
271 switch (featureLimitTable[ndx].format)
273 case LIMIT_FORMAT_UNSIGNED_INT:
275 deUint32 limitToCheck = featureLimitTable[ndx].uintVal;
276 if (featureLimitTable[ndx].unsuppTableNdx != -1)
278 if (*((VkBool32*)((char*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)))
279 limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].uintVal;
282 if ( featureLimitTable[ndx].type == LIMIT_TYPE_MIN )
285 if (*((deUint32*)((char*)limits+featureLimitTable[ndx].offset)) < limitToCheck)
287 log << TestLog::Message << "limit Validation failed " << featureLimitTable[ndx].name
288 << " not valid-limit type MIN - actual is "
289 << *((deUint32*)((char*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
295 if (*((deUint32*)((char*)limits+featureLimitTable[ndx].offset)) > limitToCheck)
297 log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
298 << " not valid-limit type MAX - actual is "
299 << *((deUint32*)((char*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
306 case LIMIT_FORMAT_FLOAT:
308 float limitToCheck = featureLimitTable[ndx].floatVal;
309 if (featureLimitTable[ndx].unsuppTableNdx != -1)
311 if (*((VkBool32*)((char*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)))
312 limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].floatVal;
315 if ( featureLimitTable[ndx].type == LIMIT_TYPE_MIN )
317 if (*((float*)((char*)limits+featureLimitTable[ndx].offset)) < limitToCheck)
319 log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
320 << " not valid-limit type MIN - actual is "
321 << *((float*)((char*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
327 if (*((float*)((char*)limits+featureLimitTable[ndx].offset)) > limitToCheck)
329 log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
330 << " not valid-limit type MAX actual is "
331 << *((float*)((char*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
338 case LIMIT_FORMAT_SIGNED_INT:
340 deInt32 limitToCheck = featureLimitTable[ndx].intVal;
341 if (featureLimitTable[ndx].unsuppTableNdx != -1)
343 if (*((VkBool32*)((char*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)))
344 limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].intVal;
346 if (featureLimitTable[ndx].type == LIMIT_TYPE_MIN)
348 if (*((deInt32*)((char*)limits+featureLimitTable[ndx].offset)) < limitToCheck)
350 log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
351 << " not valid-limit type MIN actual is "
352 << *((deInt32*)((char*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
358 if (*((deInt32*)((char*)limits+featureLimitTable[ndx].offset)) > limitToCheck)
360 log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
361 << " not valid-limit type MAX actual is "
362 << *((deInt32*)((char*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
369 case LIMIT_FORMAT_DEVICE_SIZE:
371 deUint64 limitToCheck = featureLimitTable[ndx].deviceSizeVal;
372 if (featureLimitTable[ndx].unsuppTableNdx != -1)
374 if (*((VkBool32*)((char*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)))
375 limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].deviceSizeVal;
378 if ( featureLimitTable[ndx].type == LIMIT_TYPE_MIN )
380 if (*((deUint64*)((char*)limits+featureLimitTable[ndx].offset)) < limitToCheck)
382 log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
383 << " not valid-limit type MIN actual is "
384 << *((deUint64*)((char*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
390 if (*((deUint64*)((char*)limits+featureLimitTable[ndx].offset)) > limitToCheck)
392 log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name
393 << " not valid-limit type MAX actual is "
394 << *((deUint64*)((char*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage;
410 tcu::TestStatus enumeratePhysicalDevices (Context& context)
412 TestLog& log = context.getTestContext().getLog();
413 const vector<VkPhysicalDevice> devices = enumeratePhysicalDevices(context.getInstanceInterface(), context.getInstance());
415 log << TestLog::Integer("NumDevices", "Number of devices", "", QP_KEY_TAG_NONE, deInt64(devices.size()));
417 for (size_t ndx = 0; ndx < devices.size(); ndx++)
418 log << TestLog::Message << ndx << ": " << devices[ndx] << TestLog::EndMessage;
420 return tcu::TestStatus::pass("Enumerating devices succeeded");
423 tcu::TestStatus enumerateInstanceLayers (Context& context)
425 TestLog& log = context.getTestContext().getLog();
426 const vector<VkLayerProperties> properties = enumerateInstanceLayerProperties(context.getPlatformInterface());
428 for (size_t ndx = 0; ndx < properties.size(); ndx++)
429 log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage;
431 return tcu::TestStatus::pass("Enumerating layers succeeded");
434 tcu::TestStatus enumerateInstanceExtensions (Context& context)
436 TestLog& log = context.getTestContext().getLog();
439 const ScopedLogSection section (log, "Global", "Global Extensions");
440 const vector<VkExtensionProperties> properties = enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL);
442 for (size_t ndx = 0; ndx < properties.size(); ndx++)
443 log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage;
447 const vector<VkLayerProperties> layers = enumerateInstanceLayerProperties(context.getPlatformInterface());
449 for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
451 const ScopedLogSection section (log, layer->layerName, string("Layer: ") + layer->layerName);
452 const vector<VkExtensionProperties> properties = enumerateInstanceExtensionProperties(context.getPlatformInterface(), layer->layerName);
454 for (size_t extNdx = 0; extNdx < properties.size(); extNdx++)
455 log << TestLog::Message << extNdx << ": " << properties[extNdx] << TestLog::EndMessage;
459 return tcu::TestStatus::pass("Enumerating extensions succeeded");
462 tcu::TestStatus enumerateDeviceLayers (Context& context)
464 TestLog& log = context.getTestContext().getLog();
465 const vector<VkLayerProperties> properties = vk::enumerateDeviceLayerProperties(context.getInstanceInterface(), context.getPhysicalDevice());
467 for (size_t ndx = 0; ndx < properties.size(); ndx++)
468 log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage;
470 return tcu::TestStatus::pass("Enumerating layers succeeded");
473 tcu::TestStatus enumerateDeviceExtensions (Context& context)
475 TestLog& log = context.getTestContext().getLog();
478 const ScopedLogSection section (log, "Global", "Global Extensions");
479 const vector<VkExtensionProperties> properties = enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), DE_NULL);
481 for (size_t ndx = 0; ndx < properties.size(); ndx++)
482 log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage;
486 const vector<VkLayerProperties> layers = enumerateDeviceLayerProperties(context.getInstanceInterface(), context.getPhysicalDevice());
488 for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
490 const ScopedLogSection section (log, layer->layerName, string("Layer: ") + layer->layerName);
491 const vector<VkExtensionProperties> properties = enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), layer->layerName);
493 for (size_t extNdx = 0; extNdx < properties.size(); extNdx++)
494 log << TestLog::Message << extNdx << ": " << properties[extNdx] << TestLog::EndMessage;
498 return tcu::TestStatus::pass("Enumerating extensions succeeded");
501 tcu::TestStatus deviceFeatures (Context& context)
503 TestLog& log = context.getTestContext().getLog();
504 VkPhysicalDeviceFeatures* features;
505 deUint8 buffer[sizeof(VkPhysicalDeviceFeatures) + GUARD_SIZE];
507 deMemset(buffer, GUARD_VALUE, sizeof(buffer));
508 features = reinterpret_cast<VkPhysicalDeviceFeatures*>(buffer);
510 context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), features);
512 log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage
513 << TestLog::Message << *features << TestLog::EndMessage;
515 for (int ndx = 0; ndx < GUARD_SIZE; ndx++)
517 if (buffer[ndx + sizeof(VkPhysicalDeviceFeatures)] != GUARD_VALUE)
519 log << TestLog::Message << "deviceFeatures - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
520 return tcu::TestStatus::fail("deviceFeatures buffer overflow");
524 if (!validateInitComplete(context.getPhysicalDevice(), &InstanceInterface::getPhysicalDeviceFeatures, context.getInstanceInterface()))
526 log << TestLog::Message << "deviceFeatures - VkPhysicalDeviceFeatures not completely initialized" << TestLog::EndMessage;
527 return tcu::TestStatus::fail("deviceFeatures incomplete initialization");
530 return tcu::TestStatus::pass("Query succeeded");
533 tcu::TestStatus deviceProperties (Context& context)
535 TestLog& log = context.getTestContext().getLog();
536 VkPhysicalDeviceProperties* props;
537 VkPhysicalDeviceFeatures features;
538 deUint8 buffer[sizeof(VkPhysicalDeviceProperties) + GUARD_SIZE];
540 props = reinterpret_cast<VkPhysicalDeviceProperties*>(buffer);
541 deMemset(props, GUARD_VALUE, sizeof(buffer));
543 context.getInstanceInterface().getPhysicalDeviceProperties(context.getPhysicalDevice(), props);
544 context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), &features);
546 log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage
547 << TestLog::Message << *props << TestLog::EndMessage;
549 if (!validateFeatureLimits(props, &features, log))
550 return tcu::TestStatus::fail("deviceProperties - feature limits failed");
552 for (int ndx = 0; ndx < GUARD_SIZE; ndx++)
554 if (buffer[ndx + sizeof(VkPhysicalDeviceProperties)] != GUARD_VALUE)
556 log << TestLog::Message << "deviceProperties - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
557 return tcu::TestStatus::fail("deviceProperties buffer overflow");
561 if (!validateInitComplete(context.getPhysicalDevice(), &InstanceInterface::getPhysicalDeviceProperties, context.getInstanceInterface()))
563 log << TestLog::Message << "deviceProperties - VkPhysicalDeviceProperties not completely initialized" << TestLog::EndMessage;
564 return tcu::TestStatus::fail("deviceProperties incomplete initialization");
567 return tcu::TestStatus::pass("DeviceProperites query succeeded");
570 tcu::TestStatus deviceQueueFamilyProperties (Context& context)
572 TestLog& log = context.getTestContext().getLog();
573 const vector<VkQueueFamilyProperties> queueProperties = getPhysicalDeviceQueueFamilyProperties(context.getInstanceInterface(), context.getPhysicalDevice());
575 log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage;
577 for (size_t queueNdx = 0; queueNdx < queueProperties.size(); queueNdx++)
578 log << TestLog::Message << queueNdx << ": " << queueProperties[queueNdx] << TestLog::EndMessage;
580 return tcu::TestStatus::pass("Querying queue properties succeeded");
583 tcu::TestStatus deviceMemoryProperties (Context& context)
585 TestLog& log = context.getTestContext().getLog();
586 VkPhysicalDeviceMemoryProperties* memProps;
587 deUint8 buffer[sizeof(VkPhysicalDeviceMemoryProperties) + GUARD_SIZE];
589 memProps = reinterpret_cast<VkPhysicalDeviceMemoryProperties*>(buffer);
590 deMemset(buffer, GUARD_VALUE, sizeof(buffer));
592 context.getInstanceInterface().getPhysicalDeviceMemoryProperties(context.getPhysicalDevice(), memProps);
594 log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage
595 << TestLog::Message << *memProps << TestLog::EndMessage;
597 for (deInt32 ndx = 0; ndx < GUARD_SIZE; ndx++)
599 if (buffer[ndx + sizeof(VkPhysicalDeviceMemoryProperties)] != GUARD_VALUE)
601 log << TestLog::Message << "deviceMemoryProperties - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
602 return tcu::TestStatus::fail("deviceMemoryProperties buffer overflow");
606 return tcu::TestStatus::pass("Querying memory properties succeeded");
611 tcu::TestCaseGroup* createFeatureInfoTests (tcu::TestContext& testCtx)
613 de::MovePtr<tcu::TestCaseGroup> infoTests (new tcu::TestCaseGroup(testCtx, "info", "Platform Information Tests"));
616 de::MovePtr<tcu::TestCaseGroup> instanceInfoTests (new tcu::TestCaseGroup(testCtx, "instance", "Instance Information Tests"));
618 addFunctionCase(instanceInfoTests.get(), "physical_devices", "Physical devices", enumeratePhysicalDevices);
619 addFunctionCase(instanceInfoTests.get(), "layers", "Layers", enumerateInstanceLayers);
620 addFunctionCase(instanceInfoTests.get(), "extensions", "Extensions", enumerateInstanceExtensions);
622 infoTests->addChild(instanceInfoTests.release());
626 de::MovePtr<tcu::TestCaseGroup> deviceInfoTests (new tcu::TestCaseGroup(testCtx, "device", "Device Information Tests"));
628 addFunctionCase(deviceInfoTests.get(), "features", "Device Features", deviceFeatures);
629 addFunctionCase(deviceInfoTests.get(), "properties", "Device Properties", deviceProperties);
630 addFunctionCase(deviceInfoTests.get(), "queue_family_properties", "Queue family properties", deviceQueueFamilyProperties);
631 addFunctionCase(deviceInfoTests.get(), "memory_properties", "Memory properties", deviceMemoryProperties);
632 addFunctionCase(deviceInfoTests.get(), "layers", "Layers", enumerateDeviceLayers);
633 addFunctionCase(deviceInfoTests.get(), "extensions", "Extensions", enumerateDeviceExtensions);
635 infoTests->addChild(deviceInfoTests.release());
638 return infoTests.release();