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