Merge branch 'jekstrand_renderpass_transfer_bit_fix' into 'master'
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / api / vktApiFeatureInfo.cpp
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 Google Inc.
6  *
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:
14  *
15  * The above copyright notice(s) and this permission notice shall be
16  * included in all copies or substantial portions of the Materials.
17  *
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.
21  *
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.
29  *
30  *//*!
31  * \file
32  * \brief Api Feature Query tests
33  *//*--------------------------------------------------------------------*/
34
35 #include "vktApiFeatureInfo.hpp"
36
37 #include "vktTestCaseUtil.hpp"
38
39 #include "vkPlatform.hpp"
40 #include "vkStrUtil.hpp"
41 #include "vkRef.hpp"
42 #include "vkDeviceUtil.hpp"
43 #include "vkQueryUtil.hpp"
44
45 #include "tcuTestLog.hpp"
46 #include "tcuFormatUtil.hpp"
47
48 #include "deUniquePtr.hpp"
49 #include "deMemory.h"
50
51 namespace vkt
52 {
53 namespace api
54 {
55 namespace
56 {
57
58 using namespace vk;
59 using std::vector;
60 using std::string;
61 using tcu::TestLog;
62 using tcu::ScopedLogSection;
63
64 enum
65 {
66         GUARD_SIZE      = 0x20,                 //!< Number of bytes to check
67         GUARD_VALUE     = 0xcd,                 //!< Data pattern
68 };
69
70 enum LimitFormat
71 {
72         LIMIT_FORMAT_SIGNED_INT,
73         LIMIT_FORMAT_UNSIGNED_INT,
74         LIMIT_FORMAT_FLOAT,
75         LIMIT_FORMAT_DEVICE_SIZE,
76
77         LIMIT_FORMAT_LAST
78 };
79
80 enum LimitType
81 {
82         LIMIT_TYPE_MIN,
83         LIMIT_TYPE_MAX,
84
85         LIMIT_TYPE_LAST
86 };
87
88 #define LIMIT(_X_)              DE_OFFSET_OF(VkPhysicalDeviceLimits, _X_),(char*)(#_X_)
89 #define FEATURE(_X_)    DE_OFFSET_OF(VkPhysicalDeviceFeatures, _X_)
90
91 bool validateFeatureLimits(VkPhysicalDeviceProperties* properties, VkPhysicalDeviceFeatures* features, TestLog& log)
92 {
93         bool                                    limitsOk        = true;
94         VkPhysicalDeviceLimits* limits          = &properties->limits;
95         struct FeatureLimitTable
96         {
97                 deUint32                offset;
98                 char*                   name;
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
103                 LimitFormat             format;
104                 LimitType               type;
105                 deInt32                 unsuppTableNdx;
106         } featureLimitTable[] =   //!< From gitlab.khronos.org/vulkan/vulkan.git:doc/specs/vulkan/chapters/features.txt@63b23f3bb3ecd211cd6e448e2001ce1088dacd35
107         {
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 },
206         };
207
208         struct UnsupportedFeatureLimitTable
209         {
210                 deUint32                limitOffset;
211                 char*                   name;
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[] =
218         {
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 }
252         };
253
254         log << TestLog::Message << *limits << TestLog::EndMessage;
255
256         //!< First build a map from limit to unsupported table index
257         for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
258         {
259                 for (deUint32 unsuppNdx = 0; unsuppNdx < DE_LENGTH_OF_ARRAY(unsupportedFeatureTable); unsuppNdx++)
260                 {
261                         if (unsupportedFeatureTable[unsuppNdx].limitOffset == featureLimitTable[ndx].offset)
262                         {
263                                 featureLimitTable[ndx].unsuppTableNdx = unsuppNdx;
264                                 break;
265                         }
266                 }
267         }
268
269         for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++)
270         {
271                 switch (featureLimitTable[ndx].format)
272                 {
273                         case LIMIT_FORMAT_UNSIGNED_INT:
274                         {
275                                 deUint32 limitToCheck = featureLimitTable[ndx].uintVal;
276                                 if (featureLimitTable[ndx].unsuppTableNdx != -1)
277                                 {
278                                         if (*((VkBool32*)((char*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)) == VK_FALSE)
279                                                 limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].uintVal;
280                                 }
281
282                                 if ( featureLimitTable[ndx].type == LIMIT_TYPE_MIN )
283                                 {
284
285                                         if (*((deUint32*)((char*)limits+featureLimitTable[ndx].offset)) < limitToCheck)
286                                         {
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;
290                                                 limitsOk = false;
291                                         }
292                                 }
293                                 else
294                                 {
295                                         if (*((deUint32*)((char*)limits+featureLimitTable[ndx].offset)) > limitToCheck)
296                                         {
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;
300                                                 limitsOk = false;
301                                         }
302                                 }
303                                 break;
304                         }
305
306                         case LIMIT_FORMAT_FLOAT:
307                         {
308                                 float limitToCheck = featureLimitTable[ndx].floatVal;
309                                 if (featureLimitTable[ndx].unsuppTableNdx != -1)
310                                 {
311                                         if (*((VkBool32*)((char*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)) == VK_FALSE)
312                                                 limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].floatVal;
313                                 }
314
315                                 if ( featureLimitTable[ndx].type == LIMIT_TYPE_MIN )
316                                 {
317                                         if (*((float*)((char*)limits+featureLimitTable[ndx].offset)) < limitToCheck)
318                                         {
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;
322                                                 limitsOk = false;
323                                         }
324                                 }
325                                 else
326                                 {
327                                         if (*((float*)((char*)limits+featureLimitTable[ndx].offset)) > limitToCheck)
328                                         {
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;
332                                                 limitsOk = false;
333                                         }
334                                 }
335                                 break;
336                         }
337
338                         case LIMIT_FORMAT_SIGNED_INT:
339                         {
340                                 deInt32 limitToCheck = featureLimitTable[ndx].intVal;
341                                 if (featureLimitTable[ndx].unsuppTableNdx != -1)
342                                 {
343                                         if (*((VkBool32*)((char*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)) == VK_FALSE)
344                                                 limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].intVal;
345                                 }
346                                 if (featureLimitTable[ndx].type == LIMIT_TYPE_MIN)
347                                 {
348                                         if (*((deInt32*)((char*)limits+featureLimitTable[ndx].offset)) < limitToCheck)
349                                         {
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;
353                                                 limitsOk = false;
354                                         }
355                                 }
356                                 else
357                                 {
358                                         if (*((deInt32*)((char*)limits+featureLimitTable[ndx].offset)) > limitToCheck)
359                                         {
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;
363                                                 limitsOk = false;
364                                         }
365                                 }
366                                 break;
367                         }
368
369                         case LIMIT_FORMAT_DEVICE_SIZE:
370                         {
371                                 deUint64 limitToCheck = featureLimitTable[ndx].deviceSizeVal;
372                                 if (featureLimitTable[ndx].unsuppTableNdx != -1)
373                                 {
374                                         if (*((VkBool32*)((char*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)) == VK_FALSE)
375                                                 limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].deviceSizeVal;
376                                 }
377
378                                 if ( featureLimitTable[ndx].type == LIMIT_TYPE_MIN )
379                                 {
380                                         if (*((deUint64*)((char*)limits+featureLimitTable[ndx].offset)) < limitToCheck)
381                                         {
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;
385                                                 limitsOk = false;
386                                         }
387                                 }
388                                 else
389                                 {
390                                         if (*((deUint64*)((char*)limits+featureLimitTable[ndx].offset)) > limitToCheck)
391                                         {
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;
395                                                 limitsOk = false;
396                                         }
397                                 }
398                                 break;
399                         }
400
401                         default:
402                                 DE_ASSERT(0);
403                                 limitsOk = false;
404                 }
405         }
406
407         return limitsOk;
408 }
409
410 tcu::TestStatus enumeratePhysicalDevices (Context& context)
411 {
412         TestLog&                                                log             = context.getTestContext().getLog();
413         const vector<VkPhysicalDevice>  devices = enumeratePhysicalDevices(context.getInstanceInterface(), context.getInstance());
414
415         log << TestLog::Integer("NumDevices", "Number of devices", "", QP_KEY_TAG_NONE, deInt64(devices.size()));
416
417         for (size_t ndx = 0; ndx < devices.size(); ndx++)
418                 log << TestLog::Message << ndx << ": " << devices[ndx] << TestLog::EndMessage;
419
420         return tcu::TestStatus::pass("Enumerating devices succeeded");
421 }
422
423 tcu::TestStatus enumerateInstanceLayers (Context& context)
424 {
425         TestLog&                                                log                     = context.getTestContext().getLog();
426         const vector<VkLayerProperties> properties      = enumerateInstanceLayerProperties(context.getPlatformInterface());
427
428         for (size_t ndx = 0; ndx < properties.size(); ndx++)
429                 log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage;
430
431         return tcu::TestStatus::pass("Enumerating layers succeeded");
432 }
433
434 tcu::TestStatus enumerateInstanceExtensions (Context& context)
435 {
436         TestLog&        log             = context.getTestContext().getLog();
437
438         {
439                 const ScopedLogSection                          section         (log, "Global", "Global Extensions");
440                 const vector<VkExtensionProperties>     properties      = enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL);
441
442                 for (size_t ndx = 0; ndx < properties.size(); ndx++)
443                         log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage;
444         }
445
446         {
447                 const vector<VkLayerProperties> layers  = enumerateInstanceLayerProperties(context.getPlatformInterface());
448
449                 for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
450                 {
451                         const ScopedLogSection                          section         (log, layer->layerName, string("Layer: ") + layer->layerName);
452                         const vector<VkExtensionProperties>     properties      = enumerateInstanceExtensionProperties(context.getPlatformInterface(), layer->layerName);
453
454                         for (size_t extNdx = 0; extNdx < properties.size(); extNdx++)
455                                 log << TestLog::Message << extNdx << ": " << properties[extNdx] << TestLog::EndMessage;
456                 }
457         }
458
459         return tcu::TestStatus::pass("Enumerating extensions succeeded");
460 }
461
462 tcu::TestStatus enumerateDeviceLayers (Context& context)
463 {
464         TestLog&                                                log                     = context.getTestContext().getLog();
465         const vector<VkLayerProperties> properties      = vk::enumerateDeviceLayerProperties(context.getInstanceInterface(), context.getPhysicalDevice());
466
467         for (size_t ndx = 0; ndx < properties.size(); ndx++)
468                 log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage;
469
470         return tcu::TestStatus::pass("Enumerating layers succeeded");
471 }
472
473 tcu::TestStatus enumerateDeviceExtensions (Context& context)
474 {
475         TestLog&        log             = context.getTestContext().getLog();
476
477         {
478                 const ScopedLogSection                          section         (log, "Global", "Global Extensions");
479                 const vector<VkExtensionProperties>     properties      = enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), DE_NULL);
480
481                 for (size_t ndx = 0; ndx < properties.size(); ndx++)
482                         log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage;
483         }
484
485         {
486                 const vector<VkLayerProperties> layers  = enumerateDeviceLayerProperties(context.getInstanceInterface(), context.getPhysicalDevice());
487
488                 for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
489                 {
490                         const ScopedLogSection                          section         (log, layer->layerName, string("Layer: ") + layer->layerName);
491                         const vector<VkExtensionProperties>     properties      = enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), layer->layerName);
492
493                         for (size_t extNdx = 0; extNdx < properties.size(); extNdx++)
494                                 log << TestLog::Message << extNdx << ": " << properties[extNdx] << TestLog::EndMessage;
495                 }
496         }
497
498         return tcu::TestStatus::pass("Enumerating extensions succeeded");
499 }
500
501 tcu::TestStatus deviceFeatures (Context& context)
502 {
503         TestLog&                                                log                     = context.getTestContext().getLog();
504         VkPhysicalDeviceFeatures*               features;
505         deUint8                                                 buffer[sizeof(VkPhysicalDeviceFeatures) + GUARD_SIZE];
506
507         deMemset(buffer, GUARD_VALUE, sizeof(buffer));
508         features = reinterpret_cast<VkPhysicalDeviceFeatures*>(buffer);
509
510         context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), features);
511
512         log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage
513                 << TestLog::Message << *features << TestLog::EndMessage;
514
515         for (int ndx = 0; ndx < GUARD_SIZE; ndx++)
516         {
517                 if (buffer[ndx + sizeof(VkPhysicalDeviceFeatures)] != GUARD_VALUE)
518                 {
519                         log << TestLog::Message << "deviceFeatures - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
520                         return tcu::TestStatus::fail("deviceFeatures buffer overflow");
521                 }
522         }
523
524         if (!validateInitComplete(context.getPhysicalDevice(), &InstanceInterface::getPhysicalDeviceFeatures, context.getInstanceInterface()))
525         {
526                 log << TestLog::Message << "deviceFeatures - VkPhysicalDeviceFeatures not completely initialized" << TestLog::EndMessage;
527                 return tcu::TestStatus::fail("deviceFeatures incomplete initialization");
528         }
529
530         return tcu::TestStatus::pass("Query succeeded");
531 }
532
533 tcu::TestStatus deviceProperties (Context& context)
534 {
535         TestLog&                                                log                     = context.getTestContext().getLog();
536         VkPhysicalDeviceProperties*             props;
537         VkPhysicalDeviceFeatures                features;
538         deUint8                                                 buffer[sizeof(VkPhysicalDeviceProperties) + GUARD_SIZE];
539
540         props = reinterpret_cast<VkPhysicalDeviceProperties*>(buffer);
541         deMemset(props, GUARD_VALUE, sizeof(buffer));
542
543         context.getInstanceInterface().getPhysicalDeviceProperties(context.getPhysicalDevice(), props);
544         context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), &features);
545
546         log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage
547                 << TestLog::Message << *props << TestLog::EndMessage;
548
549         if (!validateFeatureLimits(props, &features, log))
550                 return tcu::TestStatus::fail("deviceProperties - feature limits failed");
551
552         for (int ndx = 0; ndx < GUARD_SIZE; ndx++)
553         {
554                 if (buffer[ndx + sizeof(VkPhysicalDeviceProperties)] != GUARD_VALUE)
555                 {
556                         log << TestLog::Message << "deviceProperties - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
557                         return tcu::TestStatus::fail("deviceProperties buffer overflow");
558                 }
559         }
560
561         if (!validateInitComplete(context.getPhysicalDevice(), &InstanceInterface::getPhysicalDeviceProperties, context.getInstanceInterface()))
562         {
563                 log << TestLog::Message << "deviceProperties - VkPhysicalDeviceProperties not completely initialized" << TestLog::EndMessage;
564                 return tcu::TestStatus::fail("deviceProperties incomplete initialization");
565         }
566
567         return tcu::TestStatus::pass("DeviceProperites query succeeded");
568 }
569
570 tcu::TestStatus deviceQueueFamilyProperties (Context& context)
571 {
572         TestLog&                                                                log                                     = context.getTestContext().getLog();
573         const vector<VkQueueFamilyProperties>   queueProperties         = getPhysicalDeviceQueueFamilyProperties(context.getInstanceInterface(), context.getPhysicalDevice());
574
575         log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage;
576
577         for (size_t queueNdx = 0; queueNdx < queueProperties.size(); queueNdx++)
578                 log << TestLog::Message << queueNdx << ": " << queueProperties[queueNdx] << TestLog::EndMessage;
579
580         return tcu::TestStatus::pass("Querying queue properties succeeded");
581 }
582
583 tcu::TestStatus deviceMemoryProperties (Context& context)
584 {
585         TestLog&                                                        log                     = context.getTestContext().getLog();
586         VkPhysicalDeviceMemoryProperties*       memProps;
587         deUint8                                                         buffer[sizeof(VkPhysicalDeviceMemoryProperties) + GUARD_SIZE];
588
589         memProps = reinterpret_cast<VkPhysicalDeviceMemoryProperties*>(buffer);
590         deMemset(buffer, GUARD_VALUE, sizeof(buffer));
591
592         context.getInstanceInterface().getPhysicalDeviceMemoryProperties(context.getPhysicalDevice(), memProps);
593
594         log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage
595                 << TestLog::Message << *memProps << TestLog::EndMessage;
596
597         for (deInt32 ndx = 0; ndx < GUARD_SIZE; ndx++)
598         {
599                 if (buffer[ndx + sizeof(VkPhysicalDeviceMemoryProperties)] != GUARD_VALUE)
600                 {
601                         log << TestLog::Message << "deviceMemoryProperties - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
602                         return tcu::TestStatus::fail("deviceMemoryProperties buffer overflow");
603                 }
604         }
605
606         return tcu::TestStatus::pass("Querying memory properties succeeded");
607 }
608
609 } // anonymous
610
611 tcu::TestCaseGroup* createFeatureInfoTests (tcu::TestContext& testCtx)
612 {
613         de::MovePtr<tcu::TestCaseGroup> infoTests       (new tcu::TestCaseGroup(testCtx, "info", "Platform Information Tests"));
614
615         {
616                 de::MovePtr<tcu::TestCaseGroup> instanceInfoTests       (new tcu::TestCaseGroup(testCtx, "instance", "Instance Information Tests"));
617
618                 addFunctionCase(instanceInfoTests.get(), "physical_devices",            "Physical devices",                     enumeratePhysicalDevices);
619                 addFunctionCase(instanceInfoTests.get(), "layers",                                      "Layers",                                       enumerateInstanceLayers);
620                 addFunctionCase(instanceInfoTests.get(), "extensions",                          "Extensions",                           enumerateInstanceExtensions);
621
622                 infoTests->addChild(instanceInfoTests.release());
623         }
624
625         {
626                 de::MovePtr<tcu::TestCaseGroup> deviceInfoTests (new tcu::TestCaseGroup(testCtx, "device", "Device Information Tests"));
627
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);
634
635                 infoTests->addChild(deviceInfoTests.release());
636         }
637
638         return infoTests.release();
639 }
640
641 } // api
642 } // vkt