Whitelist VK_ANDROID_external_memory_android_hardware_buffer
[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 atleast 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                                                                                                         | VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT;
1920
1921                         if ((supported & required) != required)
1922                         {
1923                                 log << TestLog::Message << "ERROR in " << fieldName << ":\n"
1924                                                                                 << "  required: " << getFormatFeatureFlagsStr(required) << "\n  "
1925                                                                                 << "  missing: " << getFormatFeatureFlagsStr(~supported & required)
1926                                         << TestLog::EndMessage;
1927                                 allOk = false;
1928                         }
1929
1930                         if ((supported & (VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT | VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT)) == 0)
1931                         {
1932                                 log << TestLog::Message << "ERROR in " << fieldName << ":\n"
1933                                                                                 << "  Either VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT or VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT required"
1934                                         << TestLog::EndMessage;
1935                                 allOk = false;
1936                         }
1937                 }
1938
1939                 if ((supported & ~allowed) != 0)
1940                 {
1941                         log << TestLog::Message << "ERROR in " << fieldName << ":\n"
1942                                                                     << "  has: " << getFormatFeatureFlagsStr(supported & ~allowed)
1943                                 << TestLog::EndMessage;
1944                         allOk = false;
1945                 }
1946         }
1947
1948         if (allOk)
1949                 return tcu::TestStatus::pass("Query and validation passed");
1950         else
1951                 return tcu::TestStatus::fail("Required features not supported");
1952 }
1953
1954 bool optimalTilingFeaturesSupported (Context& context, VkFormat format, VkFormatFeatureFlags features)
1955 {
1956         const VkFormatProperties        properties      = getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), format);
1957
1958         return (properties.optimalTilingFeatures & features) == features;
1959 }
1960
1961 bool optimalTilingFeaturesSupportedForAll (Context& context, const VkFormat* begin, const VkFormat* end, VkFormatFeatureFlags features)
1962 {
1963         for (const VkFormat* cur = begin; cur != end; ++cur)
1964         {
1965                 if (!optimalTilingFeaturesSupported(context, *cur, features))
1966                         return false;
1967         }
1968
1969         return true;
1970 }
1971
1972 tcu::TestStatus testDepthStencilSupported (Context& context)
1973 {
1974         if (!optimalTilingFeaturesSupported(context, VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) &&
1975                 !optimalTilingFeaturesSupported(context, VK_FORMAT_D32_SFLOAT, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
1976                 return tcu::TestStatus::fail("Doesn't support one of VK_FORMAT_X8_D24_UNORM_PACK32 or VK_FORMAT_D32_SFLOAT");
1977
1978         if (!optimalTilingFeaturesSupported(context, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) &&
1979                 !optimalTilingFeaturesSupported(context, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
1980                 return tcu::TestStatus::fail("Doesn't support one of VK_FORMAT_D24_UNORM_S8_UINT or VK_FORMAT_D32_SFLOAT_S8_UINT");
1981
1982         return tcu::TestStatus::pass("Required depth/stencil formats supported");
1983 }
1984
1985 tcu::TestStatus testCompressedFormatsSupported (Context& context)
1986 {
1987         static const VkFormat s_allBcFormats[] =
1988         {
1989                 VK_FORMAT_BC1_RGB_UNORM_BLOCK,
1990                 VK_FORMAT_BC1_RGB_SRGB_BLOCK,
1991                 VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
1992                 VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
1993                 VK_FORMAT_BC2_UNORM_BLOCK,
1994                 VK_FORMAT_BC2_SRGB_BLOCK,
1995                 VK_FORMAT_BC3_UNORM_BLOCK,
1996                 VK_FORMAT_BC3_SRGB_BLOCK,
1997                 VK_FORMAT_BC4_UNORM_BLOCK,
1998                 VK_FORMAT_BC4_SNORM_BLOCK,
1999                 VK_FORMAT_BC5_UNORM_BLOCK,
2000                 VK_FORMAT_BC5_SNORM_BLOCK,
2001                 VK_FORMAT_BC6H_UFLOAT_BLOCK,
2002                 VK_FORMAT_BC6H_SFLOAT_BLOCK,
2003                 VK_FORMAT_BC7_UNORM_BLOCK,
2004                 VK_FORMAT_BC7_SRGB_BLOCK,
2005         };
2006         static const VkFormat s_allEtc2Formats[] =
2007         {
2008                 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
2009                 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
2010                 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
2011                 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
2012                 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
2013                 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
2014                 VK_FORMAT_EAC_R11_UNORM_BLOCK,
2015                 VK_FORMAT_EAC_R11_SNORM_BLOCK,
2016                 VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
2017                 VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
2018         };
2019         static const VkFormat s_allAstcLdrFormats[] =
2020         {
2021                 VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
2022                 VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
2023                 VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
2024                 VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
2025                 VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
2026                 VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
2027                 VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
2028                 VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
2029                 VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
2030                 VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
2031                 VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
2032                 VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
2033                 VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
2034                 VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
2035                 VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
2036                 VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
2037                 VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
2038                 VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
2039                 VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
2040                 VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
2041                 VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
2042                 VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
2043                 VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
2044                 VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
2045                 VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
2046                 VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
2047                 VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
2048                 VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
2049         };
2050
2051         static const struct
2052         {
2053                 const char*                                                                     setName;
2054                 const char*                                                                     featureName;
2055                 const VkBool32 VkPhysicalDeviceFeatures::*      feature;
2056                 const VkFormat*                                                         formatsBegin;
2057                 const VkFormat*                                                         formatsEnd;
2058         } s_compressedFormatSets[] =
2059         {
2060                 { "BC",                 "textureCompressionBC",                 &VkPhysicalDeviceFeatures::textureCompressionBC,                DE_ARRAY_BEGIN(s_allBcFormats),                 DE_ARRAY_END(s_allBcFormats)            },
2061                 { "ETC2",               "textureCompressionETC2",               &VkPhysicalDeviceFeatures::textureCompressionETC2,              DE_ARRAY_BEGIN(s_allEtc2Formats),               DE_ARRAY_END(s_allEtc2Formats)          },
2062                 { "ASTC LDR",   "textureCompressionASTC_LDR",   &VkPhysicalDeviceFeatures::textureCompressionASTC_LDR,  DE_ARRAY_BEGIN(s_allAstcLdrFormats),    DE_ARRAY_END(s_allAstcLdrFormats)       },
2063         };
2064
2065         TestLog&                                                log                                     = context.getTestContext().getLog();
2066         const VkPhysicalDeviceFeatures& features                        = context.getDeviceFeatures();
2067         int                                                             numSupportedSets        = 0;
2068         int                                                             numErrors                       = 0;
2069         int                                                             numWarnings                     = 0;
2070
2071         for (int setNdx = 0; setNdx < DE_LENGTH_OF_ARRAY(s_compressedFormatSets); ++setNdx)
2072         {
2073                 const char* const       setName                 = s_compressedFormatSets[setNdx].setName;
2074                 const char* const       featureName             = s_compressedFormatSets[setNdx].featureName;
2075                 const bool                      featureBitSet   = features.*s_compressedFormatSets[setNdx].feature == VK_TRUE;
2076                 const bool                      allSupported    = optimalTilingFeaturesSupportedForAll(context,
2077                                                                                                                                                                    s_compressedFormatSets[setNdx].formatsBegin,
2078                                                                                                                                                                    s_compressedFormatSets[setNdx].formatsEnd,
2079                                                                                                                                                                    VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);
2080
2081                 if (featureBitSet && !allSupported)
2082                 {
2083                         log << TestLog::Message << "ERROR: " << featureName << " = VK_TRUE but " << setName << " formats not supported" << TestLog::EndMessage;
2084                         numErrors += 1;
2085                 }
2086                 else if (allSupported && !featureBitSet)
2087                 {
2088                         log << TestLog::Message << "WARNING: " << setName << " formats supported but " << featureName << " = VK_FALSE" << TestLog::EndMessage;
2089                         numWarnings += 1;
2090                 }
2091
2092                 if (featureBitSet)
2093                 {
2094                         log << TestLog::Message << "All " << setName << " formats are supported" << TestLog::EndMessage;
2095                         numSupportedSets += 1;
2096                 }
2097                 else
2098                         log << TestLog::Message << setName << " formats are not supported" << TestLog::EndMessage;
2099         }
2100
2101         if (numSupportedSets == 0)
2102         {
2103                 log << TestLog::Message << "No compressed format sets supported" << TestLog::EndMessage;
2104                 numErrors += 1;
2105         }
2106
2107         if (numErrors > 0)
2108                 return tcu::TestStatus::fail("Compressed format support not valid");
2109         else if (numWarnings > 0)
2110                 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Found inconsistencies in compressed format support");
2111         else
2112                 return tcu::TestStatus::pass("Compressed texture format support is valid");
2113 }
2114
2115 void createFormatTests (tcu::TestCaseGroup* testGroup)
2116 {
2117         DE_STATIC_ASSERT(VK_FORMAT_UNDEFINED == 0);
2118
2119         static const struct
2120         {
2121                 VkFormat                                                                begin;
2122                 VkFormat                                                                end;
2123                 FunctionInstance1<VkFormat>::Function   testFunction;
2124         } s_formatRanges[] =
2125         {
2126                 // core formats
2127                 { (VkFormat)(VK_FORMAT_UNDEFINED+1),    VK_CORE_FORMAT_LAST,                                                                            formatProperties },
2128
2129                 // YCbCr formats
2130                 { VK_FORMAT_G8B8G8R8_422_UNORM,                 (VkFormat)(VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM+1),   ycbcrFormatProperties },
2131         };
2132
2133         for (int rangeNdx = 0; rangeNdx < DE_LENGTH_OF_ARRAY(s_formatRanges); ++rangeNdx)
2134         {
2135                 const VkFormat                                                          rangeBegin              = s_formatRanges[rangeNdx].begin;
2136                 const VkFormat                                                          rangeEnd                = s_formatRanges[rangeNdx].end;
2137                 const FunctionInstance1<VkFormat>::Function     testFunction    = s_formatRanges[rangeNdx].testFunction;
2138
2139                 for (VkFormat format = rangeBegin; format != rangeEnd; format = (VkFormat)(format+1))
2140                 {
2141                         const char* const       enumName        = getFormatName(format);
2142                         const string            caseName        = de::toLower(string(enumName).substr(10));
2143
2144                         addFunctionCase(testGroup, caseName, enumName, testFunction, format);
2145                 }
2146         }
2147
2148         addFunctionCase(testGroup, "depth_stencil",                     "",     testDepthStencilSupported);
2149         addFunctionCase(testGroup, "compressed_formats",        "",     testCompressedFormatsSupported);
2150 }
2151
2152 VkImageUsageFlags getValidImageUsageFlags (const VkFormatFeatureFlags supportedFeatures, const bool useKhrMaintenance1Semantics)
2153 {
2154         VkImageUsageFlags       flags   = (VkImageUsageFlags)0;
2155
2156         if (useKhrMaintenance1Semantics)
2157         {
2158                 if ((supportedFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) != 0)
2159                         flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2160
2161                 if ((supportedFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) != 0)
2162                         flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2163         }
2164         else
2165         {
2166                 // If format is supported at all, it must be valid transfer src+dst
2167                 if (supportedFeatures != 0)
2168                         flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2169         }
2170
2171         if ((supportedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
2172                 flags |= VK_IMAGE_USAGE_SAMPLED_BIT;
2173
2174         if ((supportedFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) != 0)
2175                 flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT|VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
2176
2177         if ((supportedFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)
2178                 flags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
2179
2180         if ((supportedFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0)
2181                 flags |= VK_IMAGE_USAGE_STORAGE_BIT;
2182
2183         return flags;
2184 }
2185
2186 bool isValidImageUsageFlagCombination (VkImageUsageFlags usage)
2187 {
2188         if ((usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0)
2189         {
2190                 const VkImageUsageFlags         allowedFlags    = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
2191                                                                                                         | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
2192                                                                                                         | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
2193                                                                                                         | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
2194
2195                 // Only *_ATTACHMENT_BIT flags can be combined with TRANSIENT_ATTACHMENT_BIT
2196                 if ((usage & ~allowedFlags) != 0)
2197                         return false;
2198
2199                 // TRANSIENT_ATTACHMENT_BIT is not valid without COLOR_ or DEPTH_STENCIL_ATTACHMENT_BIT
2200                 if ((usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) == 0)
2201                         return false;
2202         }
2203
2204         return usage != 0;
2205 }
2206
2207 VkImageCreateFlags getValidImageCreateFlags (const VkPhysicalDeviceFeatures& deviceFeatures, VkFormat, VkFormatFeatureFlags, VkImageType type, VkImageUsageFlags usage)
2208 {
2209         VkImageCreateFlags      flags   = (VkImageCreateFlags)0;
2210
2211         if ((usage & VK_IMAGE_USAGE_SAMPLED_BIT) != 0)
2212         {
2213                 flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
2214
2215                 if (type == VK_IMAGE_TYPE_2D)
2216                         flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
2217         }
2218
2219         if ((usage & (VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_STORAGE_BIT)) != 0 &&
2220                 (usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) == 0)
2221         {
2222                 if (deviceFeatures.sparseBinding)
2223                         flags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT|VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT;
2224
2225                 if (deviceFeatures.sparseResidencyAliased)
2226                         flags |= VK_IMAGE_CREATE_SPARSE_ALIASED_BIT;
2227         }
2228
2229         return flags;
2230 }
2231
2232 bool isValidImageCreateFlagCombination (VkImageCreateFlags)
2233 {
2234         return true;
2235 }
2236
2237 bool isRequiredImageParameterCombination (const VkPhysicalDeviceFeatures&       deviceFeatures,
2238                                                                                   const VkFormat                                        format,
2239                                                                                   const VkFormatProperties&                     formatProperties,
2240                                                                                   const VkImageType                                     imageType,
2241                                                                                   const VkImageTiling                           imageTiling,
2242                                                                                   const VkImageUsageFlags                       usageFlags,
2243                                                                                   const VkImageCreateFlags                      createFlags)
2244 {
2245         DE_UNREF(deviceFeatures);
2246         DE_UNREF(formatProperties);
2247         DE_UNREF(createFlags);
2248
2249         // Linear images can have arbitrary limitations
2250         if (imageTiling == VK_IMAGE_TILING_LINEAR)
2251                 return false;
2252
2253         // Support for other usages for compressed formats is optional
2254         if (isCompressedFormat(format) &&
2255                 (usageFlags & ~(VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT)) != 0)
2256                 return false;
2257
2258         // Support for 1D, and sliced 3D compressed formats is optional
2259         if (isCompressedFormat(format) && (imageType == VK_IMAGE_TYPE_1D || imageType == VK_IMAGE_TYPE_3D))
2260                 return false;
2261
2262         // Support for 1D and 3D depth/stencil textures is optional
2263         if (isDepthStencilFormat(format) && (imageType == VK_IMAGE_TYPE_1D || imageType == VK_IMAGE_TYPE_3D))
2264                 return false;
2265
2266         DE_ASSERT(deviceFeatures.sparseBinding || (createFlags & (VK_IMAGE_CREATE_SPARSE_BINDING_BIT|VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)) == 0);
2267         DE_ASSERT(deviceFeatures.sparseResidencyAliased || (createFlags & VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) == 0);
2268
2269         if (createFlags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)
2270         {
2271                 if (isCompressedFormat(format))
2272                         return false;
2273
2274                 if (isDepthStencilFormat(format))
2275                         return false;
2276
2277                 if (!deIsPowerOfTwo32(mapVkFormat(format).getPixelSize()))
2278                         return false;
2279
2280                 switch (imageType)
2281                 {
2282                         case VK_IMAGE_TYPE_2D:
2283                                 return (deviceFeatures.sparseResidencyImage2D == VK_TRUE);
2284                         case VK_IMAGE_TYPE_3D:
2285                                 return (deviceFeatures.sparseResidencyImage3D == VK_TRUE);
2286                         default:
2287                                 return false;
2288                 }
2289         }
2290
2291         return true;
2292 }
2293
2294 VkSampleCountFlags getRequiredOptimalTilingSampleCounts (const VkPhysicalDeviceLimits&  deviceLimits,
2295                                                                                                                  const VkFormat                                 format,
2296                                                                                                                  const VkImageUsageFlags                usageFlags)
2297 {
2298         if (!isCompressedFormat(format))
2299         {
2300                 const tcu::TextureFormat                tcuFormat               = mapVkFormat(format);
2301                 const bool                                              hasDepthComp    = (tcuFormat.order == tcu::TextureFormat::D || tcuFormat.order == tcu::TextureFormat::DS);
2302                 const bool                                              hasStencilComp  = (tcuFormat.order == tcu::TextureFormat::S || tcuFormat.order == tcu::TextureFormat::DS);
2303                 const bool                                              isColorFormat   = !hasDepthComp && !hasStencilComp;
2304                 VkSampleCountFlags                              sampleCounts    = ~(VkSampleCountFlags)0;
2305
2306                 DE_ASSERT((hasDepthComp || hasStencilComp) != isColorFormat);
2307
2308                 if ((usageFlags & VK_IMAGE_USAGE_STORAGE_BIT) != 0)
2309                         sampleCounts &= deviceLimits.storageImageSampleCounts;
2310
2311                 if ((usageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) != 0)
2312                 {
2313                         if (hasDepthComp)
2314                                 sampleCounts &= deviceLimits.sampledImageDepthSampleCounts;
2315
2316                         if (hasStencilComp)
2317                                 sampleCounts &= deviceLimits.sampledImageStencilSampleCounts;
2318
2319                         if (isColorFormat)
2320                         {
2321                                 const tcu::TextureChannelClass  chnClass        = tcu::getTextureChannelClass(tcuFormat.type);
2322
2323                                 if (chnClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ||
2324                                         chnClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
2325                                         sampleCounts &= deviceLimits.sampledImageIntegerSampleCounts;
2326                                 else
2327                                         sampleCounts &= deviceLimits.sampledImageColorSampleCounts;
2328                         }
2329                 }
2330
2331                 if ((usageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) != 0)
2332                         sampleCounts &= deviceLimits.framebufferColorSampleCounts;
2333
2334                 if ((usageFlags & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)
2335                 {
2336                         if (hasDepthComp)
2337                                 sampleCounts &= deviceLimits.framebufferDepthSampleCounts;
2338
2339                         if (hasStencilComp)
2340                                 sampleCounts &= deviceLimits.framebufferStencilSampleCounts;
2341                 }
2342
2343                 // If there is no usage flag set that would have corresponding device limit,
2344                 // only VK_SAMPLE_COUNT_1_BIT is required.
2345                 if (sampleCounts == ~(VkSampleCountFlags)0)
2346                         sampleCounts &= VK_SAMPLE_COUNT_1_BIT;
2347
2348                 return sampleCounts;
2349         }
2350         else
2351                 return VK_SAMPLE_COUNT_1_BIT;
2352 }
2353
2354 struct ImageFormatPropertyCase
2355 {
2356         typedef tcu::TestStatus (*Function) (Context& context, const VkFormat format, const VkImageType imageType, const VkImageTiling tiling);
2357
2358         Function                testFunction;
2359         VkFormat                format;
2360         VkImageType             imageType;
2361         VkImageTiling   tiling;
2362
2363         ImageFormatPropertyCase (Function testFunction_, VkFormat format_, VkImageType imageType_, VkImageTiling tiling_)
2364                 : testFunction  (testFunction_)
2365                 , format                (format_)
2366                 , imageType             (imageType_)
2367                 , tiling                (tiling_)
2368         {}
2369
2370         ImageFormatPropertyCase (void)
2371                 : testFunction  ((Function)DE_NULL)
2372                 , format                (VK_FORMAT_UNDEFINED)
2373                 , imageType             (VK_IMAGE_TYPE_LAST)
2374                 , tiling                (VK_IMAGE_TILING_LAST)
2375         {}
2376 };
2377
2378 tcu::TestStatus execImageFormatTest (Context& context, ImageFormatPropertyCase testCase)
2379 {
2380         return testCase.testFunction(context, testCase.format, testCase.imageType, testCase.tiling);
2381 }
2382
2383 void createImageFormatTypeTilingTests (tcu::TestCaseGroup* testGroup, ImageFormatPropertyCase params)
2384 {
2385         DE_ASSERT(params.format == VK_FORMAT_UNDEFINED);
2386
2387         for (deUint32 formatNdx = VK_FORMAT_UNDEFINED+1; formatNdx < VK_CORE_FORMAT_LAST; ++formatNdx)
2388         {
2389                 const VkFormat          format                  = (VkFormat)formatNdx;
2390                 const char* const       enumName                = getFormatName(format);
2391                 const string            caseName                = de::toLower(string(enumName).substr(10));
2392
2393                 params.format = format;
2394
2395                 addFunctionCase(testGroup, caseName, enumName, execImageFormatTest, params);
2396         }
2397 }
2398
2399 void createImageFormatTypeTests (tcu::TestCaseGroup* testGroup, ImageFormatPropertyCase params)
2400 {
2401         DE_ASSERT(params.tiling == VK_IMAGE_TILING_LAST);
2402
2403         testGroup->addChild(createTestGroup(testGroup->getTestContext(), "optimal",     "",     createImageFormatTypeTilingTests, ImageFormatPropertyCase(params.testFunction, VK_FORMAT_UNDEFINED, params.imageType, VK_IMAGE_TILING_OPTIMAL)));
2404         testGroup->addChild(createTestGroup(testGroup->getTestContext(), "linear",      "",     createImageFormatTypeTilingTests, ImageFormatPropertyCase(params.testFunction, VK_FORMAT_UNDEFINED, params.imageType, VK_IMAGE_TILING_LINEAR)));
2405 }
2406
2407 void createImageFormatTests (tcu::TestCaseGroup* testGroup, ImageFormatPropertyCase::Function testFunction)
2408 {
2409         testGroup->addChild(createTestGroup(testGroup->getTestContext(), "1d", "", createImageFormatTypeTests, ImageFormatPropertyCase(testFunction, VK_FORMAT_UNDEFINED, VK_IMAGE_TYPE_1D, VK_IMAGE_TILING_LAST)));
2410         testGroup->addChild(createTestGroup(testGroup->getTestContext(), "2d", "", createImageFormatTypeTests, ImageFormatPropertyCase(testFunction, VK_FORMAT_UNDEFINED, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_LAST)));
2411         testGroup->addChild(createTestGroup(testGroup->getTestContext(), "3d", "", createImageFormatTypeTests, ImageFormatPropertyCase(testFunction, VK_FORMAT_UNDEFINED, VK_IMAGE_TYPE_3D, VK_IMAGE_TILING_LAST)));
2412 }
2413
2414 tcu::TestStatus imageFormatProperties (Context& context, const VkFormat format, const VkImageType imageType, const VkImageTiling tiling)
2415 {
2416         TestLog&                                                log                                     = context.getTestContext().getLog();
2417         const VkPhysicalDeviceFeatures& deviceFeatures          = context.getDeviceFeatures();
2418         const VkPhysicalDeviceLimits&   deviceLimits            = context.getDeviceProperties().limits;
2419         const VkFormatProperties                formatProperties        = getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), format);
2420         const bool                                              hasKhrMaintenance1      = isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance1");
2421
2422         const VkFormatFeatureFlags              supportedFeatures       = tiling == VK_IMAGE_TILING_LINEAR ? formatProperties.linearTilingFeatures : formatProperties.optimalTilingFeatures;
2423         const VkImageUsageFlags                 usageFlagSet            = getValidImageUsageFlags(supportedFeatures, hasKhrMaintenance1);
2424
2425         tcu::ResultCollector                    results                         (log, "ERROR: ");
2426
2427         if (hasKhrMaintenance1 && (supportedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
2428         {
2429                 results.check((supportedFeatures & (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT|VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) != 0,
2430                                           "A sampled image format must have VK_FORMAT_FEATURE_TRANSFER_SRC_BIT and VK_FORMAT_FEATURE_TRANSFER_DST_BIT format feature flags set");
2431         }
2432
2433         for (VkImageUsageFlags curUsageFlags = 0; curUsageFlags <= usageFlagSet; curUsageFlags++)
2434         {
2435                 if ((curUsageFlags & ~usageFlagSet) != 0 ||
2436                         !isValidImageUsageFlagCombination(curUsageFlags))
2437                         continue;
2438
2439                 const VkImageCreateFlags        createFlagSet           = getValidImageCreateFlags(deviceFeatures, format, supportedFeatures, imageType, curUsageFlags);
2440
2441                 for (VkImageCreateFlags curCreateFlags = 0; curCreateFlags <= createFlagSet; curCreateFlags++)
2442                 {
2443                         if ((curCreateFlags & ~createFlagSet) != 0 ||
2444                                 !isValidImageCreateFlagCombination(curCreateFlags))
2445                                 continue;
2446
2447                         const bool                              isRequiredCombination   = isRequiredImageParameterCombination(deviceFeatures,
2448                                                                                                                                                                                                   format,
2449                                                                                                                                                                                                   formatProperties,
2450                                                                                                                                                                                                   imageType,
2451                                                                                                                                                                                                   tiling,
2452                                                                                                                                                                                                   curUsageFlags,
2453                                                                                                                                                                                                   curCreateFlags);
2454                         VkImageFormatProperties properties;
2455                         VkResult                                queryResult;
2456
2457                         log << TestLog::Message << "Testing " << getImageTypeStr(imageType) << ", "
2458                                                                         << getImageTilingStr(tiling) << ", "
2459                                                                         << getImageUsageFlagsStr(curUsageFlags) << ", "
2460                                                                         << getImageCreateFlagsStr(curCreateFlags)
2461                                 << TestLog::EndMessage;
2462
2463                         // Set return value to known garbage
2464                         deMemset(&properties, 0xcd, sizeof(properties));
2465
2466                         queryResult = context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(context.getPhysicalDevice(),
2467                                                                                                                                                                                                 format,
2468                                                                                                                                                                                                 imageType,
2469                                                                                                                                                                                                 tiling,
2470                                                                                                                                                                                                 curUsageFlags,
2471                                                                                                                                                                                                 curCreateFlags,
2472                                                                                                                                                                                                 &properties);
2473
2474                         if (queryResult == VK_SUCCESS)
2475                         {
2476                                 const deUint32  fullMipPyramidSize      = de::max(de::max(deLog2Ceil32(properties.maxExtent.width),
2477                                                                                                                                           deLog2Ceil32(properties.maxExtent.height)),
2478                                                                                                                           deLog2Ceil32(properties.maxExtent.depth)) + 1;
2479
2480                                 log << TestLog::Message << properties << "\n" << TestLog::EndMessage;
2481
2482                                 results.check(imageType != VK_IMAGE_TYPE_1D || (properties.maxExtent.width >= 1 && properties.maxExtent.height == 1 && properties.maxExtent.depth == 1), "Invalid dimensions for 1D image");
2483                                 results.check(imageType != VK_IMAGE_TYPE_2D || (properties.maxExtent.width >= 1 && properties.maxExtent.height >= 1 && properties.maxExtent.depth == 1), "Invalid dimensions for 2D image");
2484                                 results.check(imageType != VK_IMAGE_TYPE_3D || (properties.maxExtent.width >= 1 && properties.maxExtent.height >= 1 && properties.maxExtent.depth >= 1), "Invalid dimensions for 3D image");
2485                                 results.check(imageType != VK_IMAGE_TYPE_3D || properties.maxArrayLayers == 1, "Invalid maxArrayLayers for 3D image");
2486
2487                                 if (tiling == VK_IMAGE_TILING_OPTIMAL && imageType == VK_IMAGE_TYPE_2D && !(curCreateFlags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
2488                                          (supportedFeatures & (VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)))
2489                                 {
2490                                         const VkSampleCountFlags        requiredSampleCounts    = getRequiredOptimalTilingSampleCounts(deviceLimits, format, curUsageFlags);
2491                                         results.check((properties.sampleCounts & requiredSampleCounts) == requiredSampleCounts, "Required sample counts not supported");
2492                                 }
2493                                 else
2494                                         results.check(properties.sampleCounts == VK_SAMPLE_COUNT_1_BIT, "sampleCounts != VK_SAMPLE_COUNT_1_BIT");
2495
2496                                 if (isRequiredCombination)
2497                                 {
2498                                         results.check(imageType != VK_IMAGE_TYPE_1D || (properties.maxExtent.width      >= deviceLimits.maxImageDimension1D),
2499                                                                   "Reported dimensions smaller than device limits");
2500                                         results.check(imageType != VK_IMAGE_TYPE_2D || (properties.maxExtent.width      >= deviceLimits.maxImageDimension2D &&
2501                                                                                                                                         properties.maxExtent.height     >= deviceLimits.maxImageDimension2D),
2502                                                                   "Reported dimensions smaller than device limits");
2503                                         results.check(imageType != VK_IMAGE_TYPE_3D || (properties.maxExtent.width      >= deviceLimits.maxImageDimension3D &&
2504                                                                                                                                         properties.maxExtent.height     >= deviceLimits.maxImageDimension3D &&
2505                                                                                                                                         properties.maxExtent.depth      >= deviceLimits.maxImageDimension3D),
2506                                                                   "Reported dimensions smaller than device limits");
2507                                         results.check(properties.maxMipLevels == fullMipPyramidSize, "maxMipLevels is not full mip pyramid size");
2508                                         results.check(imageType == VK_IMAGE_TYPE_3D || properties.maxArrayLayers >= deviceLimits.maxImageArrayLayers,
2509                                                                   "maxArrayLayers smaller than device limits");
2510                                 }
2511                                 else
2512                                 {
2513                                         results.check(properties.maxMipLevels == 1 || properties.maxMipLevels == fullMipPyramidSize, "Invalid mip pyramid size");
2514                                         results.check(properties.maxArrayLayers >= 1, "Invalid maxArrayLayers");
2515                                 }
2516
2517                                 results.check(properties.maxResourceSize >= (VkDeviceSize)MINIMUM_REQUIRED_IMAGE_RESOURCE_SIZE,
2518                                                           "maxResourceSize smaller than minimum required size");
2519                         }
2520                         else if (queryResult == VK_ERROR_FORMAT_NOT_SUPPORTED)
2521                         {
2522                                 log << TestLog::Message << "Got VK_ERROR_FORMAT_NOT_SUPPORTED" << TestLog::EndMessage;
2523
2524                                 if (isRequiredCombination)
2525                                         results.fail("VK_ERROR_FORMAT_NOT_SUPPORTED returned for required image parameter combination");
2526
2527                                 // Specification requires that all fields are set to 0
2528                                 results.check(properties.maxExtent.width        == 0, "maxExtent.width != 0");
2529                                 results.check(properties.maxExtent.height       == 0, "maxExtent.height != 0");
2530                                 results.check(properties.maxExtent.depth        == 0, "maxExtent.depth != 0");
2531                                 results.check(properties.maxMipLevels           == 0, "maxMipLevels != 0");
2532                                 results.check(properties.maxArrayLayers         == 0, "maxArrayLayers != 0");
2533                                 results.check(properties.sampleCounts           == 0, "sampleCounts != 0");
2534                                 results.check(properties.maxResourceSize        == 0, "maxResourceSize != 0");
2535                         }
2536                         else
2537                         {
2538                                 results.fail("Got unexpected error" + de::toString(queryResult));
2539                         }
2540                 }
2541         }
2542
2543         return tcu::TestStatus(results.getResult(), results.getMessage());
2544 }
2545
2546 // VK_KHR_get_physical_device_properties2
2547
2548 Move<VkInstance> createInstanceWithExtension (const PlatformInterface& vkp, const char* extensionName, Context& context)
2549 {
2550         const vector<VkExtensionProperties>     instanceExts    = enumerateInstanceExtensionProperties(vkp, DE_NULL);
2551         vector<string>                                          enabledExts;
2552
2553         const deUint32                                          instanceVersion         = context.getUsedApiVersion();
2554
2555         if (!isCoreInstanceExtension(instanceVersion, extensionName))
2556         {
2557                 if (!isExtensionSupported(instanceExts, RequiredExtension(extensionName)))
2558                         TCU_THROW(NotSupportedError, (string(extensionName) + " is not supported").c_str());
2559                 else
2560                         enabledExts.push_back(extensionName);
2561         }
2562
2563         return createDefaultInstance(vkp, context.getUsedApiVersion(), vector<string>() /* layers */, enabledExts);
2564 }
2565
2566 string toString (const VkPhysicalDevice16BitStorageFeatures& value)
2567 {
2568         std::ostringstream      s;
2569         s << "VkPhysicalDevice16BitStorageFeatures = {\n";
2570         s << "\tsType = " << value.sType << '\n';
2571         s << "\tstorageBuffer16BitAccess = " << value.storageBuffer16BitAccess << '\n';
2572         s << "\tuniformAndStorageBuffer16BitAccess = " << value.uniformAndStorageBuffer16BitAccess << '\n';
2573         s << "\tstoragePushConstant16 = " << value.storagePushConstant16 << '\n';
2574         s << "\tstorageInputOutput16 = " << value.storageInputOutput16 << '\n';
2575         s << '}';
2576         return s.str();
2577 }
2578
2579 string toString (const VkPhysicalDeviceMultiviewFeatures& value)
2580 {
2581         std::ostringstream      s;
2582         s << "VkPhysicalDeviceMultiviewFeatures = {\n";
2583         s << "\tsType = " << value.sType << '\n';
2584         s << "\tmultiview = " << value.multiview << '\n';
2585         s << "\tmultiviewGeometryShader = " << value.multiviewGeometryShader << '\n';
2586         s << "\tmultiviewTessellationShader = " << value.multiviewTessellationShader << '\n';
2587         s << '}';
2588         return s.str();
2589 }
2590
2591 string toString (const VkPhysicalDeviceProtectedMemoryFeatures& value)
2592 {
2593         std::ostringstream      s;
2594         s << "VkPhysicalDeviceProtectedMemoryFeatures = {\n";
2595         s << "\tsType = " << value.sType << '\n';
2596         s << "\tprotectedMemory = " << value.protectedMemory << '\n';
2597         s << '}';
2598         return s.str();
2599 }
2600
2601 string toString (const VkPhysicalDeviceSamplerYcbcrConversionFeatures& value)
2602 {
2603         std::ostringstream      s;
2604         s << "VkPhysicalDeviceSamplerYcbcrConversionFeatures = {\n";
2605         s << "\tsType = " << value.sType << '\n';
2606         s << "\tsamplerYcbcrConversion = " << value.samplerYcbcrConversion << '\n';
2607         s << '}';
2608         return s.str();
2609 }
2610
2611 string toString (const VkPhysicalDeviceVariablePointerFeatures& value)
2612 {
2613         std::ostringstream      s;
2614         s << "VkPhysicalDeviceVariablePointerFeatures = {\n";
2615         s << "\tsType = " << value.sType << '\n';
2616         s << "\tvariablePointersStorageBuffer = " << value.variablePointersStorageBuffer << '\n';
2617         s << "\tvariablePointers = " << value.variablePointers << '\n';
2618         s << '}';
2619         return s.str();
2620 }
2621
2622 bool checkExtension (vector<VkExtensionProperties>& properties, const char* extension)
2623 {
2624         for (size_t ndx = 0; ndx < properties.size(); ++ndx)
2625         {
2626                 if (strcmp(properties[ndx].extensionName, extension) == 0)
2627                         return true;
2628         }
2629         return false;
2630 }
2631
2632 tcu::TestStatus deviceFeatures2 (Context& context)
2633 {
2634         const PlatformInterface&                        vkp                     = context.getPlatformInterface();
2635         const VkInstance                                        instance        (context.getInstance());
2636         const InstanceDriver                            vki                     (vkp, instance);
2637         const vector<VkPhysicalDevice>          devices         = enumeratePhysicalDevices(vki, instance);
2638         TestLog&                                                        log                     = context.getTestContext().getLog();
2639
2640         for (size_t deviceNdx = 0; deviceNdx < devices.size(); ++deviceNdx)
2641         {
2642                 VkPhysicalDeviceFeatures                coreFeatures;
2643                 VkPhysicalDeviceFeatures2               extFeatures;
2644
2645                 deMemset(&coreFeatures, 0xcd, sizeof(coreFeatures));
2646                 deMemset(&extFeatures.features, 0xcd, sizeof(extFeatures.features));
2647                 std::vector<std::string> instExtensions = context.getInstanceExtensions();
2648
2649                 extFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
2650                 extFeatures.pNext = DE_NULL;
2651
2652                 vki.getPhysicalDeviceFeatures(devices[deviceNdx], &coreFeatures);
2653                 vki.getPhysicalDeviceFeatures2(devices[deviceNdx], &extFeatures);
2654
2655                 TCU_CHECK(extFeatures.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2);
2656                 TCU_CHECK(extFeatures.pNext == DE_NULL);
2657
2658                 if (deMemCmp(&coreFeatures, &extFeatures.features, sizeof(VkPhysicalDeviceFeatures)) != 0)
2659                         TCU_FAIL("Mismatch between features reported by vkGetPhysicalDeviceFeatures and vkGetPhysicalDeviceFeatures2");
2660
2661                 log << TestLog::Message << "device = " << deviceNdx << TestLog::EndMessage
2662                 << TestLog::Message << extFeatures << TestLog::EndMessage;
2663
2664                 bool khr_16bit_storage                  = true;
2665                 bool khr_multiview                              = true;
2666                 bool deviceProtectedMemory              = true;
2667                 bool sampler_ycbcr_conversion   = true;
2668                 bool variable_pointers                  = true;
2669                 if (getPhysicalDeviceProperties(vki, devices[deviceNdx]).apiVersion < VK_API_VERSION_1_1)
2670                 {
2671                         vector<VkExtensionProperties> properties = enumerateDeviceExtensionProperties(vki, devices[deviceNdx], DE_NULL);
2672                         khr_16bit_storage = checkExtension(properties,"VK_KHR_16bit_storage");
2673                         khr_multiview = checkExtension(properties,"VK_KHR_multiview");
2674                         deviceProtectedMemory = false;
2675                         sampler_ycbcr_conversion = checkExtension(properties,"VK_KHR_sampler_ycbcr_conversion");
2676                         variable_pointers = checkExtension(properties,"VK_KHR_variable_pointers");
2677                 }
2678
2679                 const int count = 2u;
2680                 VkPhysicalDevice16BitStorageFeatures                            device16BitStorageFeatures[count];
2681                 VkPhysicalDeviceMultiviewFeatures                                       deviceMultiviewFeatures[count];
2682                 VkPhysicalDeviceProtectedMemoryFeatures                         protectedMemoryFeatures[count];
2683                 VkPhysicalDeviceSamplerYcbcrConversionFeatures          samplerYcbcrConversionFeatures[count];
2684                 VkPhysicalDeviceVariablePointerFeatures                         variablePointerFeatures[count];
2685
2686                 for (int ndx = 0; ndx < count; ++ndx)
2687                 {
2688                         deMemset(&device16BitStorageFeatures[ndx],              0xFF*ndx, sizeof(VkPhysicalDevice16BitStorageFeatures));
2689                         deMemset(&deviceMultiviewFeatures[ndx],                 0xFF*ndx, sizeof(VkPhysicalDeviceMultiviewFeatures));
2690                         deMemset(&protectedMemoryFeatures[ndx],                 0xFF*ndx, sizeof(VkPhysicalDeviceProtectedMemoryFeatures));
2691                         deMemset(&samplerYcbcrConversionFeatures[ndx],  0xFF*ndx, sizeof(VkPhysicalDeviceSamplerYcbcrConversionFeatures));
2692                         deMemset(&variablePointerFeatures[ndx],                 0xFF*ndx, sizeof(VkPhysicalDeviceVariablePointerFeatures));
2693
2694                         device16BitStorageFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES;
2695                         device16BitStorageFeatures[ndx].pNext = &deviceMultiviewFeatures[ndx];
2696
2697                         deviceMultiviewFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES;
2698                         deviceMultiviewFeatures[ndx].pNext = &protectedMemoryFeatures[ndx];
2699
2700                         protectedMemoryFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES;
2701                         protectedMemoryFeatures[ndx].pNext = &samplerYcbcrConversionFeatures[ndx];
2702
2703                         samplerYcbcrConversionFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
2704                         samplerYcbcrConversionFeatures[ndx].pNext = &variablePointerFeatures[ndx].sType;
2705
2706                         variablePointerFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES;
2707                         variablePointerFeatures[ndx].pNext = DE_NULL;
2708
2709                         deMemset(&extFeatures.features, 0xcd, sizeof(extFeatures.features));
2710                         extFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
2711                         extFeatures.pNext = &device16BitStorageFeatures[ndx];
2712
2713                         vki.getPhysicalDeviceFeatures2(devices[deviceNdx], &extFeatures);
2714                 }
2715
2716                 if ( khr_16bit_storage &&
2717                         (device16BitStorageFeatures[0].storageBuffer16BitAccess                         != device16BitStorageFeatures[1].storageBuffer16BitAccess ||
2718                         device16BitStorageFeatures[0].uniformAndStorageBuffer16BitAccess        != device16BitStorageFeatures[1].uniformAndStorageBuffer16BitAccess ||
2719                         device16BitStorageFeatures[0].storagePushConstant16                                     != device16BitStorageFeatures[1].storagePushConstant16 ||
2720                         device16BitStorageFeatures[0].storageInputOutput16                                      != device16BitStorageFeatures[1].storageInputOutput16)
2721                         )
2722                 {
2723                         TCU_FAIL("Mismatch between VkPhysicalDevice16BitStorageFeatures");
2724                 }
2725
2726                 if (khr_multiview &&
2727                         (deviceMultiviewFeatures[0].multiview                                   != deviceMultiviewFeatures[1].multiview ||
2728                         deviceMultiviewFeatures[0].multiviewGeometryShader              != deviceMultiviewFeatures[1].multiviewGeometryShader ||
2729                         deviceMultiviewFeatures[0].multiviewTessellationShader  != deviceMultiviewFeatures[1].multiviewTessellationShader)
2730                         )
2731                 {
2732                         TCU_FAIL("Mismatch between VkPhysicalDeviceMultiviewFeatures");
2733                 }
2734
2735                 if (deviceProtectedMemory && protectedMemoryFeatures[0].protectedMemory != protectedMemoryFeatures[1].protectedMemory)
2736                 {
2737                         TCU_FAIL("Mismatch between VkPhysicalDeviceProtectedMemoryFeatures");
2738                 }
2739
2740                 if (sampler_ycbcr_conversion && samplerYcbcrConversionFeatures[0].samplerYcbcrConversion != samplerYcbcrConversionFeatures[1].samplerYcbcrConversion)
2741                 {
2742                         TCU_FAIL("Mismatch between VkPhysicalDeviceSamplerYcbcrConversionFeatures");
2743                 }
2744
2745                 if (variable_pointers &&
2746                         (variablePointerFeatures[0].variablePointersStorageBuffer       != variablePointerFeatures[1].variablePointersStorageBuffer ||
2747                         variablePointerFeatures[0].variablePointers                                     != variablePointerFeatures[1].variablePointers)
2748                         )
2749                 {
2750                         TCU_FAIL("Mismatch between VkPhysicalDeviceVariablePointerFeatures");
2751                 }
2752                 if (khr_16bit_storage)
2753                         log << TestLog::Message << toString(device16BitStorageFeatures[0])              << TestLog::EndMessage;
2754                 if (khr_multiview)
2755                         log << TestLog::Message << toString(deviceMultiviewFeatures[0])                 << TestLog::EndMessage;
2756                 if (deviceProtectedMemory)
2757                         log << TestLog::Message << toString(protectedMemoryFeatures[0])                 << TestLog::EndMessage;
2758                 if (sampler_ycbcr_conversion)
2759                         log << TestLog::Message << toString(samplerYcbcrConversionFeatures[0])  << TestLog::EndMessage;
2760                 if(variable_pointers)
2761                         log << TestLog::Message << toString(variablePointerFeatures[0])                 << TestLog::EndMessage;
2762         }
2763         return tcu::TestStatus::pass("Querying device features succeeded");
2764 }
2765
2766
2767 string toString (const VkPhysicalDeviceIDProperties& value)
2768 {
2769         std::ostringstream      s;
2770         s << "VkPhysicalDeviceIDProperties = {\n";
2771         s << "\tsType = " << value.sType << '\n';
2772         s << "\tdeviceUUID = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<deUint8>(DE_ARRAY_BEGIN(value.deviceUUID)), tcu::Format::HexIterator<deUint8>(DE_ARRAY_END(value.deviceUUID))) << '\n';
2773         s << "\tdriverUUID = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<deUint8>(DE_ARRAY_BEGIN(value.driverUUID)), tcu::Format::HexIterator<deUint8>(DE_ARRAY_END(value.driverUUID))) << '\n';
2774         s << "\tdeviceLUID = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<deUint8>(DE_ARRAY_BEGIN(value.deviceLUID)), tcu::Format::HexIterator<deUint8>(DE_ARRAY_END(value.deviceLUID))) << '\n';
2775         s << "\tdeviceNodeMask = " << value.deviceNodeMask << '\n';
2776         s << "\tdeviceLUIDValid = " << value.deviceLUIDValid << '\n';
2777         s << '}';
2778         return s.str();
2779 }
2780
2781 string toString (const VkPhysicalDeviceMaintenance3Properties& value)
2782 {
2783         std::ostringstream      s;
2784         s << "VkPhysicalDeviceMaintenance3Properties = {\n";
2785         s << "\tsType = " << value.sType << '\n';
2786         s << "\tmaxPerSetDescriptors = " << value.maxPerSetDescriptors << '\n';
2787         s << "\tmaxMemoryAllocationSize = " << value.maxMemoryAllocationSize << '\n';
2788         s << '}';
2789         return s.str();
2790 }
2791
2792 string toString (const VkPhysicalDeviceMultiviewProperties& value)
2793 {
2794         std::ostringstream      s;
2795         s << "VkPhysicalDeviceMultiviewProperties = {\n";
2796         s << "\tsType = " << value.sType << '\n';
2797         s << "\tmaxMultiviewViewCount = " << value.maxMultiviewViewCount << '\n';
2798         s << "\tmaxMultiviewInstanceIndex = " << value.maxMultiviewInstanceIndex << '\n';
2799         s << '}';
2800         return s.str();
2801 }
2802
2803 string toString (const VkPhysicalDevicePointClippingProperties& value)
2804 {
2805         std::ostringstream      s;
2806         s << "VkPhysicalDevicePointClippingProperties = {\n";
2807         s << "\tsType = " << value.sType << '\n';
2808         s << "\tpointClippingBehavior = " << value.pointClippingBehavior << '\n';
2809         s << '}';
2810         return s.str();
2811 }
2812
2813 string toString (const VkPhysicalDeviceProtectedMemoryProperties& value)
2814 {
2815         std::ostringstream      s;
2816         s << "VkPhysicalDeviceProtectedMemoryProperties = {\n";
2817         s << "\tsType = " << value.sType << '\n';
2818         s << "\tprotectedNoFault = " << value.protectedNoFault << '\n';
2819         s << '}';
2820         return s.str();
2821 }
2822
2823
2824 string toString (const VkPhysicalDeviceSubgroupProperties& value)
2825 {
2826         std::ostringstream      s;
2827         s << "VkPhysicalDeviceSubgroupProperties = {\n";
2828         s << "\tsType = " << value.sType << '\n';
2829         s << "\tsubgroupSize = " << value.subgroupSize << '\n';
2830         s << "\tsupportedStages = " << getShaderStageFlagsStr(value.supportedStages) << '\n';
2831         s << "\tsupportedOperations = " << getSubgroupFeatureFlagsStr(value.supportedOperations) << '\n';
2832         s << "\tquadOperationsInAllStages = " << value.quadOperationsInAllStages << '\n';
2833         s << '}';
2834         return s.str();
2835 }
2836
2837 tcu::TestStatus deviceProperties2 (Context& context)
2838 {
2839         const PlatformInterface&                vkp                     = context.getPlatformInterface();
2840         const Unique<VkInstance>                instance        (createInstanceWithExtension(vkp, "VK_KHR_get_physical_device_properties2", context));
2841         const InstanceDriver                    vki                     (vkp, *instance);
2842         const vector<VkPhysicalDevice>  devices         = enumeratePhysicalDevices(vki, *instance);
2843         TestLog&                                                log                     = context.getTestContext().getLog();
2844
2845         for (size_t deviceNdx = 0; deviceNdx < devices.size(); ++deviceNdx)
2846         {
2847                 VkPhysicalDeviceProperties      coreProperties;
2848                 VkPhysicalDeviceProperties2     extProperties;
2849
2850                 extProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
2851                 extProperties.pNext = DE_NULL;
2852
2853                 vki.getPhysicalDeviceProperties(devices[deviceNdx], &coreProperties);
2854                 vki.getPhysicalDeviceProperties2(devices[deviceNdx], &extProperties);
2855
2856                 TCU_CHECK(extProperties.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2);
2857                 TCU_CHECK(extProperties.pNext == DE_NULL);
2858
2859                 // We can't use memcmp() here because the structs may contain padding bytes that drivers may or may not
2860                 // have written while writing the data and memcmp will compare them anyway, so we iterate through the
2861                 // valid bytes for each field in the struct and compare only the valid bytes for each one.
2862                 for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(s_physicalDevicePropertiesOffsetTable); propNdx++)
2863                 {
2864                         const size_t offset                                     = s_physicalDevicePropertiesOffsetTable[propNdx].offset;
2865                         const size_t size                                       = s_physicalDevicePropertiesOffsetTable[propNdx].size;
2866
2867                         const deUint8* corePropertyBytes        = reinterpret_cast<deUint8*>(&coreProperties) + offset;
2868                         const deUint8* extPropertyBytes         = reinterpret_cast<deUint8*>(&extProperties.properties) + offset;
2869
2870                         if (deMemCmp(corePropertyBytes, extPropertyBytes, size) != 0)
2871                                 TCU_FAIL("Mismatch between properties reported by vkGetPhysicalDeviceProperties and vkGetPhysicalDeviceProperties2");
2872                 }
2873
2874                 log << TestLog::Message << "device " << deviceNdx << TestLog::EndMessage
2875                         << TestLog::Message << extProperties.properties << TestLog::EndMessage;
2876
2877                 if (getPhysicalDeviceProperties(vki, devices[deviceNdx]).apiVersion >= VK_API_VERSION_1_1)
2878                 {
2879                         const int count = 2u;
2880                         VkPhysicalDeviceIDProperties                                                            IDProperties[count];
2881                         VkPhysicalDeviceMaintenance3Properties                                          maintenance3Properties[count];
2882                         VkPhysicalDeviceMultiviewProperties                                                     multiviewProperties[count];
2883                         VkPhysicalDevicePointClippingProperties                                         pointClippingProperties[count];
2884                         VkPhysicalDeviceProtectedMemoryProperties                                       protectedMemoryPropertiesKHR[count];
2885                         VkPhysicalDeviceSubgroupProperties                                                      subgroupProperties[count];
2886
2887                         for (int ndx = 0; ndx < count; ++ndx)
2888                         {
2889
2890                                 deMemset(&IDProperties[ndx],                                    0xFF, sizeof(VkPhysicalDeviceIDProperties                                               ));
2891                                 deMemset(&maintenance3Properties[ndx],                  0xFF, sizeof(VkPhysicalDeviceMaintenance3Properties                             ));
2892                                 deMemset(&multiviewProperties[ndx],                             0xFF, sizeof(VkPhysicalDeviceMultiviewProperties                                ));
2893                                 deMemset(&pointClippingProperties[ndx],                 0xFF, sizeof(VkPhysicalDevicePointClippingProperties                    ));
2894                                 deMemset(&protectedMemoryPropertiesKHR[ndx],    0xFF, sizeof(VkPhysicalDeviceProtectedMemoryProperties                  ));
2895                                 deMemset(&subgroupProperties[ndx],                              0xFF, sizeof(VkPhysicalDeviceSubgroupProperties                                 ));
2896
2897
2898                                 IDProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
2899                                 IDProperties[ndx].pNext = &maintenance3Properties[ndx];
2900
2901                                 maintenance3Properties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES;
2902                                 maintenance3Properties[ndx].pNext = &multiviewProperties[ndx];
2903
2904                                 multiviewProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES;
2905                                 multiviewProperties[ndx].pNext = &pointClippingProperties[ndx];
2906
2907                                 pointClippingProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES;
2908                                 pointClippingProperties[ndx].pNext = &protectedMemoryPropertiesKHR[ndx];
2909
2910                                 protectedMemoryPropertiesKHR[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES;
2911                                 protectedMemoryPropertiesKHR[ndx].pNext = &subgroupProperties[ndx];
2912
2913                                 subgroupProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
2914                                 subgroupProperties[ndx].pNext = DE_NULL;
2915
2916                                 extProperties.pNext = &IDProperties[ndx];
2917
2918                                 vki.getPhysicalDeviceProperties2(devices[deviceNdx], &extProperties);
2919
2920
2921                                 IDProperties[ndx].pNext                                         = DE_NULL;
2922                                 maintenance3Properties[ndx].pNext                       = DE_NULL;
2923                                 multiviewProperties[ndx].pNext                          = DE_NULL;
2924                                 pointClippingProperties[ndx].pNext                      = DE_NULL;
2925                                 protectedMemoryPropertiesKHR[ndx].pNext         = DE_NULL;
2926                                 subgroupProperties[ndx].pNext                           = DE_NULL;
2927                         }
2928
2929                         if (
2930                                 deMemCmp(&IDProperties[0],                                      &IDProperties[1],                                       sizeof(VkPhysicalDeviceIDProperties     ))                                                      != 0 ||
2931                                 deMemCmp(&maintenance3Properties[0],            &maintenance3Properties[1],                     sizeof(VkPhysicalDeviceMaintenance3Properties))                                 != 0 ||
2932                                 deMemCmp(&multiviewProperties[0],                       &multiviewProperties[1],                        sizeof(VkPhysicalDeviceMultiviewProperties))                                    != 0 ||
2933                                 deMemCmp(&pointClippingProperties[0],           &pointClippingProperties[1],            sizeof(VkPhysicalDevicePointClippingProperties))                                != 0 ||
2934                                 deMemCmp(&protectedMemoryPropertiesKHR[0],      &protectedMemoryPropertiesKHR[1],       sizeof(VkPhysicalDeviceProtectedMemoryProperties))                              != 0 ||
2935                                 deMemCmp(&subgroupProperties[0],                        &subgroupProperties[1],                         sizeof(VkPhysicalDeviceSubgroupProperties))                                             != 0
2936                                 )
2937                         {
2938                                 TCU_FAIL("Mismatch in vkGetPhysicalDeviceProperties2");
2939                         }
2940
2941                         log << TestLog::Message << toString(IDProperties[0])                            << TestLog::EndMessage
2942                         << TestLog::Message             << toString(maintenance3Properties[0])                  << TestLog::EndMessage
2943                         << TestLog::Message             << toString(multiviewProperties[0])                             << TestLog::EndMessage
2944                         << TestLog::Message             << toString(pointClippingProperties[0])                 << TestLog::EndMessage
2945                         << TestLog::Message             << toString(protectedMemoryPropertiesKHR[0])    << TestLog::EndMessage
2946                         << TestLog::Message             << toString(subgroupProperties[0])                              << TestLog::EndMessage;
2947                 }
2948         }
2949
2950         return tcu::TestStatus::pass("Querying device properties succeeded");
2951 }
2952
2953 string toString (const VkFormatProperties2& value)
2954 {
2955         std::ostringstream      s;
2956         s << "VkFormatProperties2 = {\n";
2957         s << "\tsType = " << value.sType << '\n';
2958         s << "\tformatProperties = {\n";
2959         s << "\tlinearTilingFeatures = " << getFormatFeatureFlagsStr(value.formatProperties.linearTilingFeatures) << '\n';
2960         s << "\toptimalTilingFeatures = " << getFormatFeatureFlagsStr(value.formatProperties.optimalTilingFeatures) << '\n';
2961         s << "\tbufferFeatures = " << getFormatFeatureFlagsStr(value.formatProperties.bufferFeatures) << '\n';
2962         s << "\t}";
2963         s << "}";
2964         return s.str();
2965 }
2966
2967 tcu::TestStatus deviceFormatProperties2 (Context& context)
2968 {
2969         const PlatformInterface&                vkp                     = context.getPlatformInterface();
2970         const Unique<VkInstance>                instance        (createInstanceWithExtension(vkp, "VK_KHR_get_physical_device_properties2", context));
2971         const InstanceDriver                    vki                     (vkp, *instance);
2972         const vector<VkPhysicalDevice>  devices         = enumeratePhysicalDevices(vki, *instance);
2973         TestLog&                                                log                     = context.getTestContext().getLog();
2974
2975         for (size_t deviceNdx = 0; deviceNdx < devices.size(); ++deviceNdx)
2976         {
2977                 const VkPhysicalDevice  physicalDevice  = devices[deviceNdx];
2978
2979                 for (int formatNdx = 0; formatNdx < VK_CORE_FORMAT_LAST; ++formatNdx)
2980                 {
2981                         const VkFormat                  format                  = (VkFormat)formatNdx;
2982                         VkFormatProperties              coreProperties;
2983                         VkFormatProperties2             extProperties;
2984
2985                         deMemset(&coreProperties, 0xcd, sizeof(VkFormatProperties));
2986                         deMemset(&extProperties, 0xcd, sizeof(VkFormatProperties2));
2987
2988                         extProperties.sType     = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
2989                         extProperties.pNext = DE_NULL;
2990
2991                         vki.getPhysicalDeviceFormatProperties(physicalDevice, format, &coreProperties);
2992                         vki.getPhysicalDeviceFormatProperties2(physicalDevice, format, &extProperties);
2993
2994                         TCU_CHECK(extProperties.sType == VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2);
2995                         TCU_CHECK(extProperties.pNext == DE_NULL);
2996
2997                 if (deMemCmp(&coreProperties, &extProperties.formatProperties, sizeof(VkFormatProperties)) != 0)
2998                         TCU_FAIL("Mismatch between format properties reported by vkGetPhysicalDeviceFormatProperties and vkGetPhysicalDeviceFormatProperties2");
2999
3000                 log << TestLog::Message << "device = " << deviceNdx << " VkFormat = " << format << TestLog::EndMessage
3001                         << TestLog::Message << toString (extProperties) << TestLog::EndMessage;
3002                 }
3003         }
3004
3005         return tcu::TestStatus::pass("Querying device format properties succeeded");
3006 }
3007
3008 string toString (const VkQueueFamilyProperties2& value)
3009 {
3010         std::ostringstream      s;
3011         s << "VkQueueFamilyProperties2 = {\n";
3012         s << "\tsType = " << value.sType << '\n';
3013         s << "\tqueueFamilyProperties = " << value.queueFamilyProperties << '\n';
3014         s << '}';
3015         return s.str();
3016 }
3017
3018 tcu::TestStatus deviceQueueFamilyProperties2 (Context& context)
3019 {
3020         const PlatformInterface&                vkp                     = context.getPlatformInterface();
3021         const Unique<VkInstance>                instance        (createInstanceWithExtension(vkp, "VK_KHR_get_physical_device_properties2", context));
3022         const InstanceDriver                    vki                     (vkp, *instance);
3023         const vector<VkPhysicalDevice>  devices         = enumeratePhysicalDevices(vki, *instance);
3024         TestLog&                                                log                     = context.getTestContext().getLog();
3025
3026         for (size_t deviceNdx = 0; deviceNdx < devices.size(); ++deviceNdx)
3027         {
3028                 const VkPhysicalDevice  physicalDevice                  = devices[deviceNdx];
3029                 deUint32                                numCoreQueueFamilies    = ~0u;
3030                 deUint32                                numExtQueueFamilies             = ~0u;
3031
3032                 vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numCoreQueueFamilies, DE_NULL);
3033                 vki.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &numExtQueueFamilies, DE_NULL);
3034
3035                 TCU_CHECK_MSG(numCoreQueueFamilies == numExtQueueFamilies, "Different number of queue family properties reported");
3036                 TCU_CHECK(numCoreQueueFamilies > 0);
3037
3038                 {
3039                         std::vector<VkQueueFamilyProperties>            coreProperties  (numCoreQueueFamilies);
3040                         std::vector<VkQueueFamilyProperties2>           extProperties   (numExtQueueFamilies);
3041
3042                         deMemset(&coreProperties[0], 0xcd, sizeof(VkQueueFamilyProperties)*numCoreQueueFamilies);
3043                         deMemset(&extProperties[0], 0xcd, sizeof(VkQueueFamilyProperties2)*numExtQueueFamilies);
3044
3045                         for (size_t ndx = 0; ndx < extProperties.size(); ++ndx)
3046                         {
3047                                 extProperties[ndx].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
3048                                 extProperties[ndx].pNext = DE_NULL;
3049                         }
3050
3051                         vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numCoreQueueFamilies, &coreProperties[0]);
3052                         vki.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &numExtQueueFamilies, &extProperties[0]);
3053
3054                         TCU_CHECK((size_t)numCoreQueueFamilies == coreProperties.size());
3055                         TCU_CHECK((size_t)numExtQueueFamilies == extProperties.size());
3056                         DE_ASSERT(numCoreQueueFamilies == numExtQueueFamilies);
3057
3058                         for (size_t ndx = 0; ndx < extProperties.size(); ++ndx)
3059                         {
3060                                 TCU_CHECK(extProperties[ndx].sType == VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2);
3061                                 TCU_CHECK(extProperties[ndx].pNext == DE_NULL);
3062
3063                                 if (deMemCmp(&coreProperties[ndx], &extProperties[ndx].queueFamilyProperties, sizeof(VkQueueFamilyProperties)) != 0)
3064                                         TCU_FAIL("Mismatch between format properties reported by vkGetPhysicalDeviceQueueFamilyProperties and vkGetPhysicalDeviceQueueFamilyProperties2");
3065
3066                                 log << TestLog::Message << "device = " << deviceNdx << " queueFamilyNdx = " << ndx <<TestLog::EndMessage
3067                                 << TestLog::Message << toString(extProperties[ndx]) << TestLog::EndMessage;
3068                         }
3069                 }
3070         }
3071
3072         return tcu::TestStatus::pass("Querying device queue family properties succeeded");
3073 }
3074
3075 tcu::TestStatus deviceMemoryProperties2 (Context& context)
3076 {
3077         const PlatformInterface&                vkp                     = context.getPlatformInterface();
3078         const Unique<VkInstance>                instance        (createInstanceWithExtension(vkp, "VK_KHR_get_physical_device_properties2", context));
3079         const InstanceDriver                    vki                     (vkp, *instance);
3080         const vector<VkPhysicalDevice>  devices         = enumeratePhysicalDevices(vki, *instance);
3081         TestLog&                                                log                     = context.getTestContext().getLog();
3082
3083         for (size_t deviceNdx = 0; deviceNdx < devices.size(); ++deviceNdx)
3084         {
3085                 VkPhysicalDeviceMemoryProperties        coreProperties;
3086                 VkPhysicalDeviceMemoryProperties2       extProperties;
3087
3088                 deMemset(&coreProperties, 0xcd, sizeof(VkPhysicalDeviceMemoryProperties));
3089                 deMemset(&extProperties, 0xcd, sizeof(VkPhysicalDeviceMemoryProperties2));
3090
3091                 extProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
3092                 extProperties.pNext = DE_NULL;
3093
3094                 vki.getPhysicalDeviceMemoryProperties(devices[deviceNdx], &coreProperties);
3095                 vki.getPhysicalDeviceMemoryProperties2(devices[deviceNdx], &extProperties);
3096
3097                 TCU_CHECK(extProperties.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2);
3098                 TCU_CHECK(extProperties.pNext == DE_NULL);
3099
3100                 if (deMemCmp(&coreProperties, &extProperties.memoryProperties, sizeof(VkPhysicalDeviceMemoryProperties)) != 0)
3101                         TCU_FAIL("Mismatch between properties reported by vkGetPhysicalDeviceMemoryProperties and vkGetPhysicalDeviceMemoryProperties2");
3102
3103                 log << TestLog::Message << "device = " << deviceNdx << TestLog::EndMessage
3104                         << TestLog::Message << extProperties << TestLog::EndMessage;
3105         }
3106
3107         return tcu::TestStatus::pass("Querying device memory properties succeeded");
3108 }
3109
3110 tcu::TestStatus imageFormatProperties2 (Context& context, const VkFormat format, const VkImageType imageType, const VkImageTiling tiling)
3111 {
3112         TestLog&                                                log                             = context.getTestContext().getLog();
3113
3114         const PlatformInterface&                vkp                             = context.getPlatformInterface();
3115         const Unique<VkInstance>                instance                (createInstanceWithExtension(vkp, "VK_KHR_get_physical_device_properties2", context));
3116         const InstanceDriver                    vki                             (vkp, *instance);
3117         const vector<VkPhysicalDevice>  devices                 = enumeratePhysicalDevices(vki, *instance);
3118
3119         const VkImageUsageFlags                 allUsageFlags   = VK_IMAGE_USAGE_TRANSFER_SRC_BIT
3120                                                                                                         | VK_IMAGE_USAGE_TRANSFER_DST_BIT
3121                                                                                                         | VK_IMAGE_USAGE_SAMPLED_BIT
3122                                                                                                         | VK_IMAGE_USAGE_STORAGE_BIT
3123                                                                                                         | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
3124                                                                                                         | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
3125                                                                                                         | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
3126                                                                                                         | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
3127         const VkImageCreateFlags                allCreateFlags  = VK_IMAGE_CREATE_SPARSE_BINDING_BIT
3128                                                                                                         | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT
3129                                                                                                         | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT
3130                                                                                                         | VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
3131                                                                                                         | VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
3132
3133         for (size_t deviceNdx = 0; deviceNdx < devices.size(); ++deviceNdx)
3134         {
3135                 const VkPhysicalDevice  physicalDevice  = devices[deviceNdx];
3136
3137                 for (VkImageUsageFlags curUsageFlags = (VkImageUsageFlags)1; curUsageFlags <= allUsageFlags; curUsageFlags++)
3138                 {
3139                         for (VkImageCreateFlags curCreateFlags = 0; curCreateFlags <= allCreateFlags; curCreateFlags++)
3140                         {
3141                                 const VkPhysicalDeviceImageFormatInfo2  imageFormatInfo =
3142                                 {
3143                                         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
3144                                         DE_NULL,
3145                                         format,
3146                                         imageType,
3147                                         tiling,
3148                                         curUsageFlags,
3149                                         curCreateFlags
3150                                 };
3151
3152                                 VkImageFormatProperties                                         coreProperties;
3153                                 VkImageFormatProperties2                                        extProperties;
3154                                 VkResult                                                                        coreResult;
3155                                 VkResult                                                                        extResult;
3156
3157                                 deMemset(&coreProperties, 0xcd, sizeof(VkImageFormatProperties));
3158                                 deMemset(&extProperties, 0xcd, sizeof(VkImageFormatProperties2));
3159
3160                                 extProperties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
3161                                 extProperties.pNext = DE_NULL;
3162
3163                                 coreResult      = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, imageFormatInfo.format, imageFormatInfo.type, imageFormatInfo.tiling, imageFormatInfo.usage, imageFormatInfo.flags, &coreProperties);
3164                                 extResult       = vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &imageFormatInfo, &extProperties);
3165
3166                                 TCU_CHECK(extProperties.sType == VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2);
3167                                 TCU_CHECK(extProperties.pNext == DE_NULL);
3168
3169                                 if ((coreResult != extResult) ||
3170                                         (deMemCmp(&coreProperties, &extProperties.imageFormatProperties, sizeof(VkImageFormatProperties)) != 0))
3171                                 {
3172                                         log << TestLog::Message << "ERROR: device " << deviceNdx << ": mismatch with query " << imageFormatInfo << TestLog::EndMessage
3173                                                 << TestLog::Message << "vkGetPhysicalDeviceImageFormatProperties() returned " << coreResult << ", " << coreProperties << TestLog::EndMessage
3174                                                 << TestLog::Message << "vkGetPhysicalDeviceImageFormatProperties2() returned " << extResult << ", " << extProperties << TestLog::EndMessage;
3175                                         TCU_FAIL("Mismatch between image format properties reported by vkGetPhysicalDeviceImageFormatProperties and vkGetPhysicalDeviceImageFormatProperties2");
3176                                 }
3177                         }
3178                 }
3179         }
3180
3181         return tcu::TestStatus::pass("Querying image format properties succeeded");
3182 }
3183
3184 tcu::TestStatus sparseImageFormatProperties2 (Context& context, const VkFormat format, const VkImageType imageType, const VkImageTiling tiling)
3185 {
3186         TestLog&                                                log                             = context.getTestContext().getLog();
3187
3188         const PlatformInterface&                vkp                             = context.getPlatformInterface();
3189         const Unique<VkInstance>                instance                (createInstanceWithExtension(vkp, "VK_KHR_get_physical_device_properties2", context));
3190         const InstanceDriver                    vki                             (vkp, *instance);
3191         const vector<VkPhysicalDevice>  devices                 = enumeratePhysicalDevices(vki, *instance);
3192
3193         const VkImageUsageFlags                 allUsageFlags   = VK_IMAGE_USAGE_TRANSFER_SRC_BIT
3194                                                                                                         | VK_IMAGE_USAGE_TRANSFER_DST_BIT
3195                                                                                                         | VK_IMAGE_USAGE_SAMPLED_BIT
3196                                                                                                         | VK_IMAGE_USAGE_STORAGE_BIT
3197                                                                                                         | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
3198                                                                                                         | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
3199                                                                                                         | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
3200                                                                                                         | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
3201
3202         for (size_t deviceNdx = 0; deviceNdx < devices.size(); ++deviceNdx)
3203         {
3204                 const VkPhysicalDevice  physicalDevice  = devices[deviceNdx];
3205
3206                 for (deUint32 sampleCountBit = VK_SAMPLE_COUNT_1_BIT; sampleCountBit <= VK_SAMPLE_COUNT_64_BIT; sampleCountBit = (sampleCountBit << 1u))
3207                 {
3208                         for (VkImageUsageFlags curUsageFlags = (VkImageUsageFlags)1; curUsageFlags <= allUsageFlags; curUsageFlags++)
3209                         {
3210                                 const VkPhysicalDeviceSparseImageFormatInfo2    imageFormatInfo =
3211                                 {
3212                                         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2,
3213                                         DE_NULL,
3214                                         format,
3215                                         imageType,
3216                                         (VkSampleCountFlagBits)sampleCountBit,
3217                                         curUsageFlags,
3218                                         tiling,
3219                                 };
3220
3221                                 deUint32                                                                                numCoreProperties       = ~0u;
3222                                 deUint32                                                                                numExtProperties        = ~0u;
3223
3224                                 // Query count
3225                                 vki.getPhysicalDeviceSparseImageFormatProperties(physicalDevice, imageFormatInfo.format, imageFormatInfo.type, imageFormatInfo.samples, imageFormatInfo.usage, imageFormatInfo.tiling, &numCoreProperties, DE_NULL);
3226                                 vki.getPhysicalDeviceSparseImageFormatProperties2(physicalDevice, &imageFormatInfo, &numExtProperties, DE_NULL);
3227
3228                                 if (numCoreProperties != numExtProperties)
3229                                 {
3230                                         log << TestLog::Message << "ERROR: device " << deviceNdx << ": different number of properties reported for " << imageFormatInfo << TestLog::EndMessage;
3231                                         TCU_FAIL("Mismatch in reported property count");
3232                                 }
3233
3234                                 if (numCoreProperties > 0)
3235                                 {
3236                                         std::vector<VkSparseImageFormatProperties>              coreProperties  (numCoreProperties);
3237                                         std::vector<VkSparseImageFormatProperties2>             extProperties   (numExtProperties);
3238
3239                                         deMemset(&coreProperties[0], 0xcd, sizeof(VkSparseImageFormatProperties)*numCoreProperties);
3240                                         deMemset(&extProperties[0], 0xcd, sizeof(VkSparseImageFormatProperties2)*numExtProperties);
3241
3242                                         for (deUint32 ndx = 0; ndx < numExtProperties; ++ndx)
3243                                         {
3244                                                 extProperties[ndx].sType = VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2;
3245                                                 extProperties[ndx].pNext = DE_NULL;
3246                                         }
3247
3248                                         vki.getPhysicalDeviceSparseImageFormatProperties(physicalDevice, imageFormatInfo.format, imageFormatInfo.type, imageFormatInfo.samples, imageFormatInfo.usage, imageFormatInfo.tiling, &numCoreProperties, &coreProperties[0]);
3249                                         vki.getPhysicalDeviceSparseImageFormatProperties2(physicalDevice, &imageFormatInfo, &numExtProperties, &extProperties[0]);
3250
3251                                         TCU_CHECK((size_t)numCoreProperties == coreProperties.size());
3252                                         TCU_CHECK((size_t)numExtProperties == extProperties.size());
3253
3254                                         for (deUint32 ndx = 0; ndx < numCoreProperties; ++ndx)
3255                                         {
3256                                                 TCU_CHECK(extProperties[ndx].sType == VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2);
3257                                                 TCU_CHECK(extProperties[ndx].pNext == DE_NULL);
3258
3259                                                 if ((deMemCmp(&coreProperties[ndx], &extProperties[ndx].properties, sizeof(VkSparseImageFormatProperties)) != 0))
3260                                                 {
3261                                                         log << TestLog::Message << "ERROR: device " << deviceNdx << ": mismatch with query " << imageFormatInfo << " property " << ndx << TestLog::EndMessage
3262                                                                 << TestLog::Message << "vkGetPhysicalDeviceSparseImageFormatProperties() returned " << coreProperties[ndx] << TestLog::EndMessage
3263                                                                 << TestLog::Message << "vkGetPhysicalDeviceSparseImageFormatProperties2() returned " << extProperties[ndx] << TestLog::EndMessage;
3264                                                         TCU_FAIL("Mismatch between image format properties reported by vkGetPhysicalDeviceSparseImageFormatProperties and vkGetPhysicalDeviceSparseImageFormatProperties2");
3265                                                 }
3266                                         }
3267                                 }
3268                         }
3269                 }
3270         }
3271
3272         return tcu::TestStatus::pass("Querying sparse image format properties succeeded");
3273 }
3274
3275 // Android CTS -specific tests
3276
3277 namespace android
3278 {
3279
3280 void checkExtensions (tcu::ResultCollector& results, const set<string>& allowedExtensions, const vector<VkExtensionProperties>& reportedExtensions)
3281 {
3282         for (vector<VkExtensionProperties>::const_iterator extension = reportedExtensions.begin(); extension != reportedExtensions.end(); ++extension)
3283         {
3284                 const string    extensionName   (extension->extensionName);
3285                 const bool              mustBeKnown             = de::beginsWith(extensionName, "VK_KHX_")              ||
3286                                                                                   de::beginsWith(extensionName, "VK_GOOGLE_")   ||
3287                                                                                   de::beginsWith(extensionName, "VK_ANDROID_");
3288
3289                 if (mustBeKnown && !de::contains(allowedExtensions, extensionName))
3290                         results.fail("Unknown extension: " + extensionName);
3291         }
3292 }
3293
3294 tcu::TestStatus testNoUnknownExtensions (Context& context)
3295 {
3296         TestLog&                                log                                     = context.getTestContext().getLog();
3297         tcu::ResultCollector    results                         (log);
3298         set<string>                             allowedInstanceExtensions;
3299         set<string>                             allowedDeviceExtensions;
3300
3301         // All known extensions should be added to allowedExtensions:
3302         // allowedExtensions.insert("VK_GOOGLE_extension1");
3303         allowedDeviceExtensions.insert("VK_ANDROID_external_memory_android_hardware_buffer");
3304         allowedDeviceExtensions.insert("VK_GOOGLE_display_timing");
3305
3306         // Instance extensions
3307         checkExtensions(results,
3308                                         allowedInstanceExtensions,
3309                                         enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL));
3310
3311         // Extensions exposed by instance layers
3312         {
3313                 const vector<VkLayerProperties> layers  = enumerateInstanceLayerProperties(context.getPlatformInterface());
3314
3315                 for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
3316                 {
3317                         checkExtensions(results,
3318                                                         allowedInstanceExtensions,
3319                                                         enumerateInstanceExtensionProperties(context.getPlatformInterface(), layer->layerName));
3320                 }
3321         }
3322
3323         // Device extensions
3324         checkExtensions(results,
3325                                         allowedDeviceExtensions,
3326                                         enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), DE_NULL));
3327
3328         // Extensions exposed by device layers
3329         {
3330                 const vector<VkLayerProperties> layers  = enumerateDeviceLayerProperties(context.getInstanceInterface(), context.getPhysicalDevice());
3331
3332                 for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
3333                 {
3334                         checkExtensions(results,
3335                                                         allowedDeviceExtensions,
3336                                                         enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), layer->layerName));
3337                 }
3338         }
3339
3340         return tcu::TestStatus(results.getResult(), results.getMessage());
3341 }
3342
3343 tcu::TestStatus testNoLayers (Context& context)
3344 {
3345         TestLog&                                log             = context.getTestContext().getLog();
3346         tcu::ResultCollector    results (log);
3347
3348         {
3349                 const vector<VkLayerProperties> layers  = enumerateInstanceLayerProperties(context.getPlatformInterface());
3350
3351                 for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
3352                         results.fail(string("Instance layer enumerated: ") + layer->layerName);
3353         }
3354
3355         {
3356                 const vector<VkLayerProperties> layers  = enumerateDeviceLayerProperties(context.getInstanceInterface(), context.getPhysicalDevice());
3357
3358                 for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
3359                         results.fail(string("Device layer enumerated: ") + layer->layerName);
3360         }
3361
3362         return tcu::TestStatus(results.getResult(), results.getMessage());
3363 }
3364
3365 tcu::TestStatus testMandatoryExtensions (Context& context)
3366 {
3367         TestLog&                                log             = context.getTestContext().getLog();
3368         tcu::ResultCollector    results (log);
3369
3370         // Instance extensions
3371         {
3372                 static const char*                                      mandatoryExtensions[]   =
3373                 {
3374                         "VK_KHR_get_physical_device_properties2",
3375                 };
3376                 const vector<VkExtensionProperties>     extensions                              = enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL);
3377
3378                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(mandatoryExtensions); ++ndx)
3379                 {
3380                         if (!isInstanceExtensionSupported(context.getUsedApiVersion(), extensions, RequiredExtension(mandatoryExtensions[ndx])))
3381                                 results.fail(string(mandatoryExtensions[ndx]) + " is not supported");
3382                 }
3383         }
3384
3385         // Device extensions
3386         {
3387                 static const char*                                      mandatoryExtensions[]   =
3388                 {
3389                         "VK_KHR_maintenance1",
3390                 };
3391                 const vector<VkExtensionProperties>     extensions                              = enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), DE_NULL);
3392
3393                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(mandatoryExtensions); ++ndx)
3394                 {
3395                         if (!isDeviceExtensionSupported(context.getUsedApiVersion(), extensions, RequiredExtension(mandatoryExtensions[ndx])))
3396                                 results.fail(string(mandatoryExtensions[ndx]) + " is not supported");
3397                 }
3398         }
3399
3400         return tcu::TestStatus(results.getResult(), results.getMessage());
3401 }
3402
3403 } // android
3404
3405 } // anonymous
3406
3407 tcu::TestCaseGroup* createFeatureInfoTests (tcu::TestContext& testCtx)
3408 {
3409         de::MovePtr<tcu::TestCaseGroup> infoTests       (new tcu::TestCaseGroup(testCtx, "info", "Platform Information Tests"));
3410
3411         {
3412                 de::MovePtr<tcu::TestCaseGroup> instanceInfoTests       (new tcu::TestCaseGroup(testCtx, "instance", "Instance Information Tests"));
3413
3414                 addFunctionCase(instanceInfoTests.get(), "physical_devices",            "Physical devices",                     enumeratePhysicalDevices);
3415                 addFunctionCase(instanceInfoTests.get(), "physical_device_groups",      "Physical devices Groups",      enumeratePhysicalDeviceGroups);
3416                 addFunctionCase(instanceInfoTests.get(), "layers",                                      "Layers",                                       enumerateInstanceLayers);
3417                 addFunctionCase(instanceInfoTests.get(), "extensions",                          "Extensions",                           enumerateInstanceExtensions);
3418
3419                 infoTests->addChild(instanceInfoTests.release());
3420         }
3421
3422         {
3423                 de::MovePtr<tcu::TestCaseGroup> deviceInfoTests (new tcu::TestCaseGroup(testCtx, "device", "Device Information Tests"));
3424
3425                 addFunctionCase(deviceInfoTests.get(), "features",                                      "Device Features",                      deviceFeatures);
3426                 addFunctionCase(deviceInfoTests.get(), "properties",                            "Device Properties",            deviceProperties);
3427                 addFunctionCase(deviceInfoTests.get(), "queue_family_properties",       "Queue family properties",      deviceQueueFamilyProperties);
3428                 addFunctionCase(deviceInfoTests.get(), "memory_properties",                     "Memory properties",            deviceMemoryProperties);
3429                 addFunctionCase(deviceInfoTests.get(), "layers",                                        "Layers",                                       enumerateDeviceLayers);
3430                 addFunctionCase(deviceInfoTests.get(), "extensions",                            "Extensions",                           enumerateDeviceExtensions);
3431
3432                 infoTests->addChild(deviceInfoTests.release());
3433         }
3434
3435         {
3436                 de::MovePtr<tcu::TestCaseGroup> deviceGroupInfoTests(new tcu::TestCaseGroup(testCtx, "device_group", "Device Group Information Tests"));
3437
3438                 addFunctionCase(deviceGroupInfoTests.get(), "peer_memory_features",     "Device Group peer memory features",                            deviceGroupPeerMemoryFeatures);
3439
3440                 infoTests->addChild(deviceGroupInfoTests.release());
3441         }
3442
3443         infoTests->addChild(createTestGroup(testCtx, "format_properties",               "VkGetPhysicalDeviceFormatProperties() Tests",          createFormatTests));
3444         infoTests->addChild(createTestGroup(testCtx, "image_format_properties", "VkGetPhysicalDeviceImageFormatProperties() Tests",     createImageFormatTests, imageFormatProperties));
3445
3446         {
3447                 de::MovePtr<tcu::TestCaseGroup> extendedPropertiesTests (new tcu::TestCaseGroup(testCtx, "get_physical_device_properties2", "VK_KHR_get_physical_device_properties2"));
3448
3449                 addFunctionCase(extendedPropertiesTests.get(), "features",                                      "Extended Device Features",                                     deviceFeatures2);
3450                 addFunctionCase(extendedPropertiesTests.get(), "properties",                            "Extended Device Properties",                           deviceProperties2);
3451                 addFunctionCase(extendedPropertiesTests.get(), "format_properties",                     "Extended Device Format Properties",            deviceFormatProperties2);
3452                 addFunctionCase(extendedPropertiesTests.get(), "queue_family_properties",       "Extended Device Queue Family Properties",      deviceQueueFamilyProperties2);
3453                 addFunctionCase(extendedPropertiesTests.get(), "memory_properties",                     "Extended Device Memory Properties",            deviceMemoryProperties2);
3454
3455                 infoTests->addChild(extendedPropertiesTests.release());
3456         }
3457
3458         infoTests->addChild(createTestGroup(testCtx, "image_format_properties2",                "VkGetPhysicalDeviceImageFormatProperties2() Tests",            createImageFormatTests, imageFormatProperties2));
3459         infoTests->addChild(createTestGroup(testCtx, "sparse_image_format_properties2", "VkGetPhysicalDeviceSparseImageFormatProperties2() Tests",      createImageFormatTests, sparseImageFormatProperties2));
3460
3461         {
3462                 de::MovePtr<tcu::TestCaseGroup> androidTests    (new tcu::TestCaseGroup(testCtx, "android", "Android CTS Tests"));
3463
3464                 addFunctionCase(androidTests.get(),     "mandatory_extensions",         "Test that all mandatory extensions are supported",     android::testMandatoryExtensions);
3465                 addFunctionCase(androidTests.get(), "no_unknown_extensions",    "Test for unknown device or instance extensions",       android::testNoUnknownExtensions);
3466                 addFunctionCase(androidTests.get(), "no_layers",                                "Test that no layers are enumerated",                           android::testNoLayers);
3467
3468                 infoTests->addChild(androidTests.release());
3469         }
3470
3471         return infoTests.release();
3472 }
3473
3474 } // api
3475 } // vkt