Merge vk-gl-cts/vulkan-cts-1.1.1 into vk-gl-cts/vulkan-cts-1.1.2
[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                 "VK_KHR_get_display_properties2",
717         };
718
719         checkKhrExtensions(results, extensions, DE_LENGTH_OF_ARRAY(s_allowedInstanceKhrExtensions), s_allowedInstanceKhrExtensions);
720         checkDuplicateExtensions(results, extensions);
721 }
722
723 void checkDeviceExtensions (tcu::ResultCollector& results, const vector<string>& extensions)
724 {
725         static const char* s_allowedDeviceKhrExtensions[] =
726         {
727                 "VK_KHR_swapchain",
728                 "VK_KHR_display_swapchain",
729                 "VK_KHR_sampler_mirror_clamp_to_edge",
730                 "VK_KHR_shader_draw_parameters",
731                 "VK_KHR_shader_float_controls",
732                 "VK_KHR_shader_float16_int8",
733                 "VK_KHR_maintenance1",
734                 "VK_KHR_push_descriptor",
735                 "VK_KHR_descriptor_update_template",
736                 "VK_KHR_incremental_present",
737                 "VK_KHR_shared_presentable_image",
738                 "VK_KHR_storage_buffer_storage_class",
739                 "VK_KHR_8bit_storage",
740                 "VK_KHR_16bit_storage",
741                 "VK_KHR_get_memory_requirements2",
742                 "VK_KHR_external_memory",
743                 "VK_KHR_external_memory_fd",
744                 "VK_KHR_external_memory_win32",
745                 "VK_KHR_external_semaphore",
746                 "VK_KHR_external_semaphore_fd",
747                 "VK_KHR_external_semaphore_win32",
748                 "VK_KHR_external_fence",
749                 "VK_KHR_external_fence_fd",
750                 "VK_KHR_external_fence_win32",
751                 "VK_KHR_win32_keyed_mutex",
752                 "VK_KHR_dedicated_allocation",
753                 "VK_KHR_variable_pointers",
754                 "VK_KHR_relaxed_block_layout",
755                 "VK_KHR_bind_memory2",
756                 "VK_KHR_maintenance2",
757                 "VK_KHR_image_format_list",
758                 "VK_KHR_sampler_ycbcr_conversion",
759                 "VK_KHR_device_group",
760                 "VK_KHR_multiview",
761                 "VK_KHR_maintenance3",
762                 "VK_KHR_draw_indirect_count",
763                 "VK_KHR_create_renderpass2",
764                 "VK_KHR_driver_properties",
765                 "VK_KHR_shader_atomic_int64",
766                 "VK_KHR_vulkan_memory_model",
767                 "VK_KHR_swapchain_mutable_format",
768         };
769
770         checkKhrExtensions(results, extensions, DE_LENGTH_OF_ARRAY(s_allowedDeviceKhrExtensions), s_allowedDeviceKhrExtensions);
771         checkDuplicateExtensions(results, extensions);
772 }
773
774 tcu::TestStatus enumerateInstanceLayers (Context& context)
775 {
776         TestLog&                                                log                                     = context.getTestContext().getLog();
777         tcu::ResultCollector                    results                         (log);
778         const vector<VkLayerProperties> properties                      = enumerateInstanceLayerProperties(context.getPlatformInterface());
779         vector<string>                                  layerNames;
780
781         for (size_t ndx = 0; ndx < properties.size(); ndx++)
782         {
783                 log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage;
784
785                 layerNames.push_back(properties[ndx].layerName);
786         }
787
788         checkDuplicateLayers(results, layerNames);
789         CheckEnumerateInstanceLayerPropertiesIncompleteResult()(context, results, layerNames.size());
790
791         return tcu::TestStatus(results.getResult(), results.getMessage());
792 }
793
794 tcu::TestStatus enumerateInstanceExtensions (Context& context)
795 {
796         TestLog&                                log             = context.getTestContext().getLog();
797         tcu::ResultCollector    results (log);
798
799         {
800                 const ScopedLogSection                          section         (log, "Global", "Global Extensions");
801                 const vector<VkExtensionProperties>     properties      = enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL);
802                 vector<string>                                          extensionNames;
803
804                 for (size_t ndx = 0; ndx < properties.size(); ndx++)
805                 {
806                         log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage;
807
808                         extensionNames.push_back(properties[ndx].extensionName);
809                 }
810
811                 checkInstanceExtensions(results, extensionNames);
812                 CheckEnumerateInstanceExtensionPropertiesIncompleteResult()(context, results, properties.size());
813         }
814
815         {
816                 const vector<VkLayerProperties> layers  = enumerateInstanceLayerProperties(context.getPlatformInterface());
817
818                 for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
819                 {
820                         const ScopedLogSection                          section                         (log, layer->layerName, string("Layer: ") + layer->layerName);
821                         const vector<VkExtensionProperties>     properties                      = enumerateInstanceExtensionProperties(context.getPlatformInterface(), layer->layerName);
822                         vector<string>                                          extensionNames;
823
824                         for (size_t extNdx = 0; extNdx < properties.size(); extNdx++)
825                         {
826                                 log << TestLog::Message << extNdx << ": " << properties[extNdx] << TestLog::EndMessage;
827
828                                 extensionNames.push_back(properties[extNdx].extensionName);
829                         }
830
831                         checkInstanceExtensions(results, extensionNames);
832                         CheckEnumerateInstanceExtensionPropertiesIncompleteResult(layer->layerName)(context, results, properties.size());
833                 }
834         }
835
836         return tcu::TestStatus(results.getResult(), results.getMessage());
837 }
838
839 tcu::TestStatus enumerateDeviceLayers (Context& context)
840 {
841         TestLog&                                                log                     = context.getTestContext().getLog();
842         tcu::ResultCollector                    results         (log);
843         const vector<VkLayerProperties> properties      = enumerateDeviceLayerProperties(context.getInstanceInterface(), context.getPhysicalDevice());
844         vector<string>                                  layerNames;
845
846         for (size_t ndx = 0; ndx < properties.size(); ndx++)
847         {
848                 log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage;
849
850                 layerNames.push_back(properties[ndx].layerName);
851         }
852
853         checkDuplicateLayers(results, layerNames);
854         CheckEnumerateDeviceLayerPropertiesIncompleteResult()(context, results, layerNames.size());
855
856         return tcu::TestStatus(results.getResult(), results.getMessage());
857 }
858
859 tcu::TestStatus enumerateDeviceExtensions (Context& context)
860 {
861         TestLog&                                log             = context.getTestContext().getLog();
862         tcu::ResultCollector    results (log);
863
864         {
865                 const ScopedLogSection                          section         (log, "Global", "Global Extensions");
866                 const vector<VkExtensionProperties>     properties      = enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), DE_NULL);
867                 vector<string>                                          extensionNames;
868
869                 for (size_t ndx = 0; ndx < properties.size(); ndx++)
870                 {
871                         log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage;
872
873                         extensionNames.push_back(properties[ndx].extensionName);
874                 }
875
876                 checkDeviceExtensions(results, extensionNames);
877                 CheckEnumerateDeviceExtensionPropertiesIncompleteResult()(context, results, properties.size());
878         }
879
880         {
881                 const vector<VkLayerProperties> layers  = enumerateDeviceLayerProperties(context.getInstanceInterface(), context.getPhysicalDevice());
882
883                 for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
884                 {
885                         const ScopedLogSection                          section         (log, layer->layerName, string("Layer: ") + layer->layerName);
886                         const vector<VkExtensionProperties>     properties      = enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), layer->layerName);
887                         vector<string>                                          extensionNames;
888
889                         for (size_t extNdx = 0; extNdx < properties.size(); extNdx++)
890                         {
891                                 log << TestLog::Message << extNdx << ": " << properties[extNdx] << TestLog::EndMessage;
892
893
894                                 extensionNames.push_back(properties[extNdx].extensionName);
895                         }
896
897                         checkDeviceExtensions(results, extensionNames);
898                         CheckEnumerateDeviceExtensionPropertiesIncompleteResult(layer->layerName)(context, results, properties.size());
899                 }
900         }
901
902         return tcu::TestStatus(results.getResult(), results.getMessage());
903 }
904
905 #define VK_SIZE_OF(STRUCT, MEMBER)                                      (sizeof(((STRUCT*)0)->MEMBER))
906 #define OFFSET_TABLE_ENTRY(STRUCT, MEMBER)                      { (size_t)DE_OFFSET_OF(STRUCT, MEMBER), VK_SIZE_OF(STRUCT, MEMBER) }
907
908 tcu::TestStatus deviceFeatures (Context& context)
909 {
910         using namespace ValidateQueryBits;
911
912         TestLog&                                                log                     = context.getTestContext().getLog();
913         VkPhysicalDeviceFeatures*               features;
914         deUint8                                                 buffer[sizeof(VkPhysicalDeviceFeatures) + GUARD_SIZE];
915
916         const QueryMemberTableEntry featureOffsetTable[] =
917         {
918                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, robustBufferAccess),
919                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, fullDrawIndexUint32),
920                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, imageCubeArray),
921                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, independentBlend),
922                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, geometryShader),
923                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, tessellationShader),
924                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sampleRateShading),
925                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, dualSrcBlend),
926                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, logicOp),
927                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, multiDrawIndirect),
928                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, drawIndirectFirstInstance),
929                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, depthClamp),
930                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, depthBiasClamp),
931                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, fillModeNonSolid),
932                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, depthBounds),
933                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, wideLines),
934                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, largePoints),
935                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, alphaToOne),
936                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, multiViewport),
937                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, samplerAnisotropy),
938                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, textureCompressionETC2),
939                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, textureCompressionASTC_LDR),
940                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, textureCompressionBC),
941                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, occlusionQueryPrecise),
942                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, pipelineStatisticsQuery),
943                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, vertexPipelineStoresAndAtomics),
944                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, fragmentStoresAndAtomics),
945                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderTessellationAndGeometryPointSize),
946                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderImageGatherExtended),
947                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderStorageImageExtendedFormats),
948                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderStorageImageMultisample),
949                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderStorageImageReadWithoutFormat),
950                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderStorageImageWriteWithoutFormat),
951                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderUniformBufferArrayDynamicIndexing),
952                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderSampledImageArrayDynamicIndexing),
953                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderStorageBufferArrayDynamicIndexing),
954                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderStorageImageArrayDynamicIndexing),
955                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderClipDistance),
956                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderCullDistance),
957                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderFloat64),
958                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderInt64),
959                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderInt16),
960                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderResourceResidency),
961                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, shaderResourceMinLod),
962                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseBinding),
963                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidencyBuffer),
964                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidencyImage2D),
965                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidencyImage3D),
966                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidency2Samples),
967                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidency4Samples),
968                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidency8Samples),
969                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidency16Samples),
970                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, sparseResidencyAliased),
971                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, variableMultisampleRate),
972                 OFFSET_TABLE_ENTRY(VkPhysicalDeviceFeatures, inheritedQueries),
973                 { 0, 0 }
974         };
975
976         deMemset(buffer, GUARD_VALUE, sizeof(buffer));
977         features = reinterpret_cast<VkPhysicalDeviceFeatures*>(buffer);
978
979         context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), features);
980
981         log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage
982                 << TestLog::Message << *features << TestLog::EndMessage;
983
984         // Requirements and dependencies
985         {
986                 if (!features->robustBufferAccess)
987                         return tcu::TestStatus::fail("robustBufferAccess is not supported");
988
989                 // multiViewport requires MultiViewport (SPIR-V capability) support, which depends on Geometry
990                 if (features->multiViewport && !features->geometryShader)
991                         return tcu::TestStatus::fail("multiViewport is supported but geometryShader is not");
992         }
993
994         for (int ndx = 0; ndx < GUARD_SIZE; ndx++)
995         {
996                 if (buffer[ndx + sizeof(VkPhysicalDeviceFeatures)] != GUARD_VALUE)
997                 {
998                         log << TestLog::Message << "deviceFeatures - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
999                         return tcu::TestStatus::fail("deviceFeatures buffer overflow");
1000                 }
1001         }
1002
1003         if (!validateInitComplete(context.getPhysicalDevice(), &InstanceInterface::getPhysicalDeviceFeatures, context.getInstanceInterface(), featureOffsetTable))
1004         {
1005                 log << TestLog::Message << "deviceFeatures - VkPhysicalDeviceFeatures not completely initialized" << TestLog::EndMessage;
1006                 return tcu::TestStatus::fail("deviceFeatures incomplete initialization");
1007         }
1008
1009         return tcu::TestStatus::pass("Query succeeded");
1010 }
1011
1012 static const ValidateQueryBits::QueryMemberTableEntry s_physicalDevicePropertiesOffsetTable[] =
1013 {
1014         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, apiVersion),
1015         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, driverVersion),
1016         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, vendorID),
1017         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, deviceID),
1018         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, deviceType),
1019         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, pipelineCacheUUID),
1020         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxImageDimension1D),
1021         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxImageDimension2D),
1022         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxImageDimension3D),
1023         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxImageDimensionCube),
1024         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxImageArrayLayers),
1025         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTexelBufferElements),
1026         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxUniformBufferRange),
1027         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxStorageBufferRange),
1028         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPushConstantsSize),
1029         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxMemoryAllocationCount),
1030         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxSamplerAllocationCount),
1031         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.bufferImageGranularity),
1032         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.sparseAddressSpaceSize),
1033         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxBoundDescriptorSets),
1034         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageDescriptorSamplers),
1035         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageDescriptorUniformBuffers),
1036         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageDescriptorStorageBuffers),
1037         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageDescriptorSampledImages),
1038         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageDescriptorStorageImages),
1039         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageDescriptorInputAttachments),
1040         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxPerStageResources),
1041         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetSamplers),
1042         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetUniformBuffers),
1043         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetUniformBuffersDynamic),
1044         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetStorageBuffers),
1045         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetStorageBuffersDynamic),
1046         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetSampledImages),
1047         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetStorageImages),
1048         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDescriptorSetInputAttachments),
1049         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxVertexInputAttributes),
1050         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxVertexInputBindings),
1051         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxVertexInputAttributeOffset),
1052         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxVertexInputBindingStride),
1053         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxVertexOutputComponents),
1054         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationGenerationLevel),
1055         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationPatchSize),
1056         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationControlPerVertexInputComponents),
1057         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationControlPerVertexOutputComponents),
1058         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationControlPerPatchOutputComponents),
1059         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationControlTotalOutputComponents),
1060         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationEvaluationInputComponents),
1061         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTessellationEvaluationOutputComponents),
1062         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxGeometryShaderInvocations),
1063         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxGeometryInputComponents),
1064         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxGeometryOutputComponents),
1065         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxGeometryOutputVertices),
1066         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxGeometryTotalOutputComponents),
1067         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFragmentInputComponents),
1068         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFragmentOutputAttachments),
1069         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFragmentDualSrcAttachments),
1070         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFragmentCombinedOutputResources),
1071         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxComputeSharedMemorySize),
1072         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxComputeWorkGroupCount[3]),
1073         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxComputeWorkGroupInvocations),
1074         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxComputeWorkGroupSize[3]),
1075         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.subPixelPrecisionBits),
1076         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.subTexelPrecisionBits),
1077         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.mipmapPrecisionBits),
1078         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDrawIndexedIndexValue),
1079         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxDrawIndirectCount),
1080         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxSamplerLodBias),
1081         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxSamplerAnisotropy),
1082         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxViewports),
1083         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxViewportDimensions[2]),
1084         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.viewportBoundsRange[2]),
1085         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.viewportSubPixelBits),
1086         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minMemoryMapAlignment),
1087         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minTexelBufferOffsetAlignment),
1088         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minUniformBufferOffsetAlignment),
1089         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minStorageBufferOffsetAlignment),
1090         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minTexelOffset),
1091         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTexelOffset),
1092         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minTexelGatherOffset),
1093         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxTexelGatherOffset),
1094         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.minInterpolationOffset),
1095         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxInterpolationOffset),
1096         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.subPixelInterpolationOffsetBits),
1097         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFramebufferWidth),
1098         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFramebufferHeight),
1099         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxFramebufferLayers),
1100         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.framebufferColorSampleCounts),
1101         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.framebufferDepthSampleCounts),
1102         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.framebufferStencilSampleCounts),
1103         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.framebufferNoAttachmentsSampleCounts),
1104         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxColorAttachments),
1105         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.sampledImageColorSampleCounts),
1106         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.sampledImageIntegerSampleCounts),
1107         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.sampledImageDepthSampleCounts),
1108         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.sampledImageStencilSampleCounts),
1109         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.storageImageSampleCounts),
1110         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxSampleMaskWords),
1111         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.timestampComputeAndGraphics),
1112         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.timestampPeriod),
1113         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxClipDistances),
1114         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxCullDistances),
1115         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.maxCombinedClipAndCullDistances),
1116         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.discreteQueuePriorities),
1117         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.pointSizeRange[2]),
1118         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.lineWidthRange[2]),
1119         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.pointSizeGranularity),
1120         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.lineWidthGranularity),
1121         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.strictLines),
1122         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.standardSampleLocations),
1123         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.optimalBufferCopyOffsetAlignment),
1124         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.optimalBufferCopyRowPitchAlignment),
1125         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, limits.nonCoherentAtomSize),
1126         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, sparseProperties.residencyStandard2DBlockShape),
1127         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, sparseProperties.residencyStandard2DMultisampleBlockShape),
1128         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, sparseProperties.residencyStandard3DBlockShape),
1129         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, sparseProperties.residencyAlignedMipSize),
1130         OFFSET_TABLE_ENTRY(VkPhysicalDeviceProperties, sparseProperties.residencyNonResidentStrict),
1131         { 0, 0 }
1132 };
1133
1134 tcu::TestStatus deviceProperties (Context& context)
1135 {
1136         using namespace ValidateQueryBits;
1137
1138         TestLog&                                                log                     = context.getTestContext().getLog();
1139         VkPhysicalDeviceProperties*             props;
1140         VkPhysicalDeviceFeatures                features;
1141         deUint8                                                 buffer[sizeof(VkPhysicalDeviceProperties) + GUARD_SIZE];
1142
1143         props = reinterpret_cast<VkPhysicalDeviceProperties*>(buffer);
1144         deMemset(props, GUARD_VALUE, sizeof(buffer));
1145
1146         context.getInstanceInterface().getPhysicalDeviceProperties(context.getPhysicalDevice(), props);
1147         context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), &features);
1148
1149         log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage
1150                 << TestLog::Message << *props << TestLog::EndMessage;
1151
1152         if (!validateFeatureLimits(props, &features, log))
1153                 return tcu::TestStatus::fail("deviceProperties - feature limits failed");
1154
1155         for (int ndx = 0; ndx < GUARD_SIZE; ndx++)
1156         {
1157                 if (buffer[ndx + sizeof(VkPhysicalDeviceProperties)] != GUARD_VALUE)
1158                 {
1159                         log << TestLog::Message << "deviceProperties - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
1160                         return tcu::TestStatus::fail("deviceProperties buffer overflow");
1161                 }
1162         }
1163
1164         if (!validateInitComplete(context.getPhysicalDevice(), &InstanceInterface::getPhysicalDeviceProperties, context.getInstanceInterface(), s_physicalDevicePropertiesOffsetTable))
1165         {
1166                 log << TestLog::Message << "deviceProperties - VkPhysicalDeviceProperties not completely initialized" << TestLog::EndMessage;
1167                 return tcu::TestStatus::fail("deviceProperties incomplete initialization");
1168         }
1169
1170         // Check if deviceName string is properly terminated.
1171         if (deStrnlen(props->deviceName, VK_MAX_PHYSICAL_DEVICE_NAME_SIZE) == VK_MAX_PHYSICAL_DEVICE_NAME_SIZE)
1172         {
1173                 log << TestLog::Message << "deviceProperties - VkPhysicalDeviceProperties deviceName not properly initialized" << TestLog::EndMessage;
1174                 return tcu::TestStatus::fail("deviceProperties incomplete initialization");
1175         }
1176
1177         {
1178                 const ApiVersion deviceVersion = unpackVersion(props->apiVersion);
1179                 const ApiVersion deqpVersion = unpackVersion(VK_API_VERSION_1_1);
1180
1181                 if (deviceVersion.majorNum != deqpVersion.majorNum)
1182                 {
1183                         log << TestLog::Message << "deviceProperties - API Major Version " << deviceVersion.majorNum << " is not valid" << TestLog::EndMessage;
1184                         return tcu::TestStatus::fail("deviceProperties apiVersion not valid");
1185                 }
1186
1187                 if (deviceVersion.minorNum > deqpVersion.minorNum)
1188                 {
1189                         log << TestLog::Message << "deviceProperties - API Minor Version " << deviceVersion.minorNum << " is not valid for this version of dEQP" << TestLog::EndMessage;
1190                         return tcu::TestStatus::fail("deviceProperties apiVersion not valid");
1191                 }
1192         }
1193
1194         return tcu::TestStatus::pass("DeviceProperites query succeeded");
1195 }
1196
1197 tcu::TestStatus deviceQueueFamilyProperties (Context& context)
1198 {
1199         TestLog&                                                                log                                     = context.getTestContext().getLog();
1200         const vector<VkQueueFamilyProperties>   queueProperties         = getPhysicalDeviceQueueFamilyProperties(context.getInstanceInterface(), context.getPhysicalDevice());
1201
1202         log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage;
1203
1204         for (size_t queueNdx = 0; queueNdx < queueProperties.size(); queueNdx++)
1205                 log << TestLog::Message << queueNdx << ": " << queueProperties[queueNdx] << TestLog::EndMessage;
1206
1207         return tcu::TestStatus::pass("Querying queue properties succeeded");
1208 }
1209
1210 tcu::TestStatus deviceMemoryProperties (Context& context)
1211 {
1212         TestLog&                                                        log                     = context.getTestContext().getLog();
1213         VkPhysicalDeviceMemoryProperties*       memProps;
1214         deUint8                                                         buffer[sizeof(VkPhysicalDeviceMemoryProperties) + GUARD_SIZE];
1215
1216         memProps = reinterpret_cast<VkPhysicalDeviceMemoryProperties*>(buffer);
1217         deMemset(buffer, GUARD_VALUE, sizeof(buffer));
1218
1219         context.getInstanceInterface().getPhysicalDeviceMemoryProperties(context.getPhysicalDevice(), memProps);
1220
1221         log << TestLog::Message << "device = " << context.getPhysicalDevice() << TestLog::EndMessage
1222                 << TestLog::Message << *memProps << TestLog::EndMessage;
1223
1224         for (deInt32 ndx = 0; ndx < GUARD_SIZE; ndx++)
1225         {
1226                 if (buffer[ndx + sizeof(VkPhysicalDeviceMemoryProperties)] != GUARD_VALUE)
1227                 {
1228                         log << TestLog::Message << "deviceMemoryProperties - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
1229                         return tcu::TestStatus::fail("deviceMemoryProperties buffer overflow");
1230                 }
1231         }
1232
1233         if (memProps->memoryHeapCount >= VK_MAX_MEMORY_HEAPS)
1234         {
1235                 log << TestLog::Message << "deviceMemoryProperties - HeapCount larger than " << (deUint32)VK_MAX_MEMORY_HEAPS << TestLog::EndMessage;
1236                 return tcu::TestStatus::fail("deviceMemoryProperties HeapCount too large");
1237         }
1238
1239         if (memProps->memoryHeapCount == 1)
1240         {
1241                 if ((memProps->memoryHeaps[0].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) == 0)
1242                 {
1243                         log << TestLog::Message << "deviceMemoryProperties - Single heap is not marked DEVICE_LOCAL" << TestLog::EndMessage;
1244                         return tcu::TestStatus::fail("deviceMemoryProperties invalid HeapFlags");
1245                 }
1246         }
1247
1248         const VkMemoryPropertyFlags validPropertyFlags[] =
1249         {
1250                 0,
1251                 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
1252                 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
1253                 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
1254                 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_CACHED_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
1255                 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
1256                 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
1257                 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_CACHED_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
1258                 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT|VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
1259         };
1260
1261         const VkMemoryPropertyFlags requiredPropertyFlags[] =
1262         {
1263                 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT|VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
1264         };
1265
1266         bool requiredFlagsFound[DE_LENGTH_OF_ARRAY(requiredPropertyFlags)];
1267         std::fill(DE_ARRAY_BEGIN(requiredFlagsFound), DE_ARRAY_END(requiredFlagsFound), false);
1268
1269         for (deUint32 memoryNdx = 0; memoryNdx < memProps->memoryTypeCount; memoryNdx++)
1270         {
1271                 bool validPropTypeFound = false;
1272
1273                 if (memProps->memoryTypes[memoryNdx].heapIndex >= memProps->memoryHeapCount)
1274                 {
1275                         log << TestLog::Message << "deviceMemoryProperties - heapIndex " << memProps->memoryTypes[memoryNdx].heapIndex << " larger than heapCount" << TestLog::EndMessage;
1276                         return tcu::TestStatus::fail("deviceMemoryProperties - invalid heapIndex");
1277                 }
1278
1279                 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;
1280
1281                 for (const VkMemoryPropertyFlags* requiredFlagsIterator = DE_ARRAY_BEGIN(requiredPropertyFlags); requiredFlagsIterator != DE_ARRAY_END(requiredPropertyFlags); requiredFlagsIterator++)
1282                         if ((memProps->memoryTypes[memoryNdx].propertyFlags & *requiredFlagsIterator) == *requiredFlagsIterator)
1283                                 requiredFlagsFound[requiredFlagsIterator - DE_ARRAY_BEGIN(requiredPropertyFlags)] = true;
1284
1285                 if (de::contains(DE_ARRAY_BEGIN(validPropertyFlags), DE_ARRAY_END(validPropertyFlags), memProps->memoryTypes[memoryNdx].propertyFlags & bitsToCheck))
1286                         validPropTypeFound = true;
1287
1288                 if (!validPropTypeFound)
1289                 {
1290                         log << TestLog::Message << "deviceMemoryProperties - propertyFlags "
1291                                 << memProps->memoryTypes[memoryNdx].propertyFlags << " not valid" << TestLog::EndMessage;
1292                         return tcu::TestStatus::fail("deviceMemoryProperties propertyFlags not valid");
1293                 }
1294
1295                 if (memProps->memoryTypes[memoryNdx].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
1296                 {
1297                         if ((memProps->memoryHeaps[memProps->memoryTypes[memoryNdx].heapIndex].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) == 0)
1298                         {
1299                                 log << TestLog::Message << "deviceMemoryProperties - DEVICE_LOCAL memory type references heap which is not DEVICE_LOCAL" << TestLog::EndMessage;
1300                                 return tcu::TestStatus::fail("deviceMemoryProperties inconsistent memoryType and HeapFlags");
1301                         }
1302                 }
1303                 else
1304                 {
1305                         if (memProps->memoryHeaps[memProps->memoryTypes[memoryNdx].heapIndex].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)
1306                         {
1307                                 log << TestLog::Message << "deviceMemoryProperties - non-DEVICE_LOCAL memory type references heap with is DEVICE_LOCAL" << TestLog::EndMessage;
1308                                 return tcu::TestStatus::fail("deviceMemoryProperties inconsistent memoryType and HeapFlags");
1309                         }
1310                 }
1311         }
1312
1313         bool* requiredFlagsFoundIterator = std::find(DE_ARRAY_BEGIN(requiredFlagsFound), DE_ARRAY_END(requiredFlagsFound), false);
1314         if (requiredFlagsFoundIterator != DE_ARRAY_END(requiredFlagsFound))
1315         {
1316                 DE_ASSERT(requiredFlagsFoundIterator - DE_ARRAY_BEGIN(requiredFlagsFound) <= DE_LENGTH_OF_ARRAY(requiredPropertyFlags));
1317                 log << TestLog::Message << "deviceMemoryProperties - required property flags "
1318                         << getMemoryPropertyFlagsStr(requiredPropertyFlags[requiredFlagsFoundIterator - DE_ARRAY_BEGIN(requiredFlagsFound)]) << " not found" << TestLog::EndMessage;
1319
1320                 return tcu::TestStatus::fail("deviceMemoryProperties propertyFlags not valid");
1321         }
1322
1323         return tcu::TestStatus::pass("Querying memory properties succeeded");
1324 }
1325
1326 tcu::TestStatus deviceGroupPeerMemoryFeatures (Context& context)
1327 {
1328         TestLog&                                                        log                                             = context.getTestContext().getLog();
1329         const PlatformInterface&                        vkp                                             = context.getPlatformInterface();
1330         const Unique<VkInstance>                        instance                                (createInstanceWithExtension(vkp, context.getUsedApiVersion(), "VK_KHR_device_group_creation"));
1331         const InstanceDriver                            vki                                             (vkp, *instance);
1332         const tcu::CommandLine&                         cmdLine                                 = context.getTestContext().getCommandLine();
1333         const deUint32                                          devGroupIdx                             = cmdLine.getVKDeviceGroupId() - 1;
1334         const deUint32                                          deviceIdx                               = vk::chooseDeviceIndex(context.getInstanceInterface(), *instance, cmdLine);
1335         const float                                                     queuePriority                   = 1.0f;
1336         VkPhysicalDeviceMemoryProperties        memProps;
1337         VkPeerMemoryFeatureFlags*                       peerMemFeatures;
1338         deUint8                                                         buffer                                  [sizeof(VkPeerMemoryFeatureFlags) + GUARD_SIZE];
1339         deUint32                                                        numPhysicalDevices              = 0;
1340         deUint32                                                        queueFamilyIndex                = 0;
1341
1342         const vector<VkPhysicalDeviceGroupProperties>           deviceGroupProps = enumeratePhysicalDeviceGroups(vki, *instance);
1343         std::vector<const char*>                                                        deviceExtensions;
1344         deviceExtensions.push_back("VK_KHR_device_group");
1345
1346         if (!isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_device_group"))
1347                 deviceExtensions.push_back("VK_KHR_device_group");
1348
1349         const std::vector<VkQueueFamilyProperties>      queueProps              = getPhysicalDeviceQueueFamilyProperties(vki, deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx]);
1350         for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
1351         {
1352                 if (queueProps[queueNdx].queueFlags & VK_QUEUE_GRAPHICS_BIT)
1353                         queueFamilyIndex = (deUint32)queueNdx;
1354         }
1355         const VkDeviceQueueCreateInfo           deviceQueueCreateInfo   =
1356         {
1357                 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,                     //type
1358                 DE_NULL,                                                                                        //pNext
1359                 (VkDeviceQueueCreateFlags)0u,                                           //flags
1360                 queueFamilyIndex,                                                                       //queueFamilyIndex;
1361                 1u,                                                                                                     //queueCount;
1362                 &queuePriority,                                                                         //pQueuePriorities;
1363         };
1364
1365         // Need atleast 2 devices for peer memory features
1366         numPhysicalDevices = deviceGroupProps[devGroupIdx].physicalDeviceCount;
1367         if (numPhysicalDevices < 2)
1368                 TCU_THROW(NotSupportedError, "Need a device Group with at least 2 physical devices.");
1369
1370         // Create device groups
1371         const VkDeviceGroupDeviceCreateInfo                                             deviceGroupInfo =
1372         {
1373                 VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO,      //stype
1374                 DE_NULL,                                                                                        //pNext
1375                 deviceGroupProps[devGroupIdx].physicalDeviceCount,      //physicalDeviceCount
1376                 deviceGroupProps[devGroupIdx].physicalDevices           //physicalDevices
1377         };
1378         const VkDeviceCreateInfo                                                                deviceCreateInfo =
1379         {
1380                 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,                                                   //sType;
1381                 &deviceGroupInfo,                                                                                               //pNext;
1382                 (VkDeviceCreateFlags)0u,                                                                                //flags
1383                 1,                                                                                                                              //queueRecordCount;
1384                 &deviceQueueCreateInfo,                                                                                 //pRequestedQueues;
1385                 0,                                                                                                                              //layerCount;
1386                 DE_NULL,                                                                                                                //ppEnabledLayerNames;
1387                 deUint32(deviceExtensions.size()),                                                              //extensionCount;
1388                 (deviceExtensions.empty() ? DE_NULL : &deviceExtensions[0]),    //ppEnabledExtensionNames;
1389                 DE_NULL,                                                                                                                //pEnabledFeatures;
1390         };
1391
1392         Move<VkDevice>          deviceGroup = createDevice(vkp, *instance, vki, deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx], &deviceCreateInfo);
1393         const DeviceDriver      vk      (vkp, *instance, *deviceGroup);
1394         context.getInstanceInterface().getPhysicalDeviceMemoryProperties(deviceGroupProps[devGroupIdx].physicalDevices[deviceIdx], &memProps);
1395
1396         peerMemFeatures = reinterpret_cast<VkPeerMemoryFeatureFlags*>(buffer);
1397         deMemset(buffer, GUARD_VALUE, sizeof(buffer));
1398
1399         for (deUint32 heapIndex = 0; heapIndex < memProps.memoryHeapCount; heapIndex++)
1400         {
1401                 for (deUint32 localDeviceIndex = 0; localDeviceIndex < numPhysicalDevices; localDeviceIndex++)
1402                 {
1403                         for (deUint32 remoteDeviceIndex = 0; remoteDeviceIndex < numPhysicalDevices; remoteDeviceIndex++)
1404                         {
1405                                 if (localDeviceIndex != remoteDeviceIndex)
1406                                 {
1407                                         vk.getDeviceGroupPeerMemoryFeatures(deviceGroup.get(), heapIndex, localDeviceIndex, remoteDeviceIndex, peerMemFeatures);
1408
1409                                         // Check guard
1410                                         for (deInt32 ndx = 0; ndx < GUARD_SIZE; ndx++)
1411                                         {
1412                                                 if (buffer[ndx + sizeof(VkPeerMemoryFeatureFlags)] != GUARD_VALUE)
1413                                                 {
1414                                                         log << TestLog::Message << "deviceGroupPeerMemoryFeatures - Guard offset " << ndx << " not valid" << TestLog::EndMessage;
1415                                                         return tcu::TestStatus::fail("deviceGroupPeerMemoryFeatures buffer overflow");
1416                                                 }
1417                                         }
1418
1419                                         VkPeerMemoryFeatureFlags requiredFlag = VK_PEER_MEMORY_FEATURE_COPY_DST_BIT;
1420                                         VkPeerMemoryFeatureFlags maxValidFlag = VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT|VK_PEER_MEMORY_FEATURE_COPY_DST_BIT|
1421                                                                                                                                 VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT|VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT;
1422                                         if ((!(*peerMemFeatures & requiredFlag)) ||
1423                                                 *peerMemFeatures > maxValidFlag)
1424                                                 return tcu::TestStatus::fail("deviceGroupPeerMemoryFeatures invalid flag");
1425
1426                                         log << TestLog::Message << "deviceGroup = " << deviceGroup.get() << TestLog::EndMessage
1427                                                 << TestLog::Message << "heapIndex = " << heapIndex << TestLog::EndMessage
1428                                                 << TestLog::Message << "localDeviceIndex = " << localDeviceIndex << TestLog::EndMessage
1429                                                 << TestLog::Message << "remoteDeviceIndex = " << remoteDeviceIndex << TestLog::EndMessage
1430                                                 << TestLog::Message << "PeerMemoryFeatureFlags = " << *peerMemFeatures << TestLog::EndMessage;
1431                                 }
1432                         } // remote device
1433                 } // local device
1434         } // heap Index
1435
1436         return tcu::TestStatus::pass("Querying deviceGroup peer memory features succeeded");
1437 }
1438
1439 // \todo [2016-01-22 pyry] Optimize by doing format -> flags mapping instead
1440
1441 VkFormatFeatureFlags getRequiredOptimalTilingFeatures (VkFormat format)
1442 {
1443         static const VkFormat s_requiredSampledImageBlitSrcFormats[] =
1444         {
1445                 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
1446                 VK_FORMAT_R5G6B5_UNORM_PACK16,
1447                 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
1448                 VK_FORMAT_R8_UNORM,
1449                 VK_FORMAT_R8_SNORM,
1450                 VK_FORMAT_R8_UINT,
1451                 VK_FORMAT_R8_SINT,
1452                 VK_FORMAT_R8G8_UNORM,
1453                 VK_FORMAT_R8G8_SNORM,
1454                 VK_FORMAT_R8G8_UINT,
1455                 VK_FORMAT_R8G8_SINT,
1456                 VK_FORMAT_R8G8B8A8_UNORM,
1457                 VK_FORMAT_R8G8B8A8_SNORM,
1458                 VK_FORMAT_R8G8B8A8_UINT,
1459                 VK_FORMAT_R8G8B8A8_SINT,
1460                 VK_FORMAT_R8G8B8A8_SRGB,
1461                 VK_FORMAT_B8G8R8A8_UNORM,
1462                 VK_FORMAT_B8G8R8A8_SRGB,
1463                 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1464                 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1465                 VK_FORMAT_A8B8G8R8_UINT_PACK32,
1466                 VK_FORMAT_A8B8G8R8_SINT_PACK32,
1467                 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
1468                 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1469                 VK_FORMAT_A2B10G10R10_UINT_PACK32,
1470                 VK_FORMAT_R16_UINT,
1471                 VK_FORMAT_R16_SINT,
1472                 VK_FORMAT_R16_SFLOAT,
1473                 VK_FORMAT_R16G16_UINT,
1474                 VK_FORMAT_R16G16_SINT,
1475                 VK_FORMAT_R16G16_SFLOAT,
1476                 VK_FORMAT_R16G16B16A16_UINT,
1477                 VK_FORMAT_R16G16B16A16_SINT,
1478                 VK_FORMAT_R16G16B16A16_SFLOAT,
1479                 VK_FORMAT_R32_UINT,
1480                 VK_FORMAT_R32_SINT,
1481                 VK_FORMAT_R32_SFLOAT,
1482                 VK_FORMAT_R32G32_UINT,
1483                 VK_FORMAT_R32G32_SINT,
1484                 VK_FORMAT_R32G32_SFLOAT,
1485                 VK_FORMAT_R32G32B32A32_UINT,
1486                 VK_FORMAT_R32G32B32A32_SINT,
1487                 VK_FORMAT_R32G32B32A32_SFLOAT,
1488                 VK_FORMAT_B10G11R11_UFLOAT_PACK32,
1489                 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
1490                 VK_FORMAT_D16_UNORM,
1491                 VK_FORMAT_D32_SFLOAT
1492         };
1493         static const VkFormat s_requiredSampledImageFilterLinearFormats[] =
1494         {
1495                 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
1496                 VK_FORMAT_R5G6B5_UNORM_PACK16,
1497                 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
1498                 VK_FORMAT_R8_UNORM,
1499                 VK_FORMAT_R8_SNORM,
1500                 VK_FORMAT_R8G8_UNORM,
1501                 VK_FORMAT_R8G8_SNORM,
1502                 VK_FORMAT_R8G8B8A8_UNORM,
1503                 VK_FORMAT_R8G8B8A8_SNORM,
1504                 VK_FORMAT_R8G8B8A8_SRGB,
1505                 VK_FORMAT_B8G8R8A8_UNORM,
1506                 VK_FORMAT_B8G8R8A8_SRGB,
1507                 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1508                 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1509                 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
1510                 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1511                 VK_FORMAT_R16_SFLOAT,
1512                 VK_FORMAT_R16G16_SFLOAT,
1513                 VK_FORMAT_R16G16B16A16_SFLOAT,
1514                 VK_FORMAT_B10G11R11_UFLOAT_PACK32,
1515                 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
1516         };
1517         static const VkFormat s_requiredStorageImageFormats[] =
1518         {
1519                 VK_FORMAT_R8G8B8A8_UNORM,
1520                 VK_FORMAT_R8G8B8A8_SNORM,
1521                 VK_FORMAT_R8G8B8A8_UINT,
1522                 VK_FORMAT_R8G8B8A8_SINT,
1523                 VK_FORMAT_R16G16B16A16_UINT,
1524                 VK_FORMAT_R16G16B16A16_SINT,
1525                 VK_FORMAT_R16G16B16A16_SFLOAT,
1526                 VK_FORMAT_R32_UINT,
1527                 VK_FORMAT_R32_SINT,
1528                 VK_FORMAT_R32_SFLOAT,
1529                 VK_FORMAT_R32G32_UINT,
1530                 VK_FORMAT_R32G32_SINT,
1531                 VK_FORMAT_R32G32_SFLOAT,
1532                 VK_FORMAT_R32G32B32A32_UINT,
1533                 VK_FORMAT_R32G32B32A32_SINT,
1534                 VK_FORMAT_R32G32B32A32_SFLOAT
1535         };
1536         static const VkFormat s_requiredStorageImageAtomicFormats[] =
1537         {
1538                 VK_FORMAT_R32_UINT,
1539                 VK_FORMAT_R32_SINT
1540         };
1541         static const VkFormat s_requiredColorAttachmentBlitDstFormats[] =
1542         {
1543                 VK_FORMAT_R5G6B5_UNORM_PACK16,
1544                 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
1545                 VK_FORMAT_R8_UNORM,
1546                 VK_FORMAT_R8_UINT,
1547                 VK_FORMAT_R8_SINT,
1548                 VK_FORMAT_R8G8_UNORM,
1549                 VK_FORMAT_R8G8_UINT,
1550                 VK_FORMAT_R8G8_SINT,
1551                 VK_FORMAT_R8G8B8A8_UNORM,
1552                 VK_FORMAT_R8G8B8A8_UINT,
1553                 VK_FORMAT_R8G8B8A8_SINT,
1554                 VK_FORMAT_R8G8B8A8_SRGB,
1555                 VK_FORMAT_B8G8R8A8_UNORM,
1556                 VK_FORMAT_B8G8R8A8_SRGB,
1557                 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1558                 VK_FORMAT_A8B8G8R8_UINT_PACK32,
1559                 VK_FORMAT_A8B8G8R8_SINT_PACK32,
1560                 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
1561                 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1562                 VK_FORMAT_A2B10G10R10_UINT_PACK32,
1563                 VK_FORMAT_R16_UINT,
1564                 VK_FORMAT_R16_SINT,
1565                 VK_FORMAT_R16_SFLOAT,
1566                 VK_FORMAT_R16G16_UINT,
1567                 VK_FORMAT_R16G16_SINT,
1568                 VK_FORMAT_R16G16_SFLOAT,
1569                 VK_FORMAT_R16G16B16A16_UINT,
1570                 VK_FORMAT_R16G16B16A16_SINT,
1571                 VK_FORMAT_R16G16B16A16_SFLOAT,
1572                 VK_FORMAT_R32_UINT,
1573                 VK_FORMAT_R32_SINT,
1574                 VK_FORMAT_R32_SFLOAT,
1575                 VK_FORMAT_R32G32_UINT,
1576                 VK_FORMAT_R32G32_SINT,
1577                 VK_FORMAT_R32G32_SFLOAT,
1578                 VK_FORMAT_R32G32B32A32_UINT,
1579                 VK_FORMAT_R32G32B32A32_SINT,
1580                 VK_FORMAT_R32G32B32A32_SFLOAT
1581         };
1582         static const VkFormat s_requiredColorAttachmentBlendFormats[] =
1583         {
1584                 VK_FORMAT_R5G6B5_UNORM_PACK16,
1585                 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
1586                 VK_FORMAT_R8_UNORM,
1587                 VK_FORMAT_R8G8_UNORM,
1588                 VK_FORMAT_R8G8B8A8_UNORM,
1589                 VK_FORMAT_R8G8B8A8_SRGB,
1590                 VK_FORMAT_B8G8R8A8_UNORM,
1591                 VK_FORMAT_B8G8R8A8_SRGB,
1592                 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1593                 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
1594                 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1595                 VK_FORMAT_R16_SFLOAT,
1596                 VK_FORMAT_R16G16_SFLOAT,
1597                 VK_FORMAT_R16G16B16A16_SFLOAT
1598         };
1599         static const VkFormat s_requiredDepthStencilAttachmentFormats[] =
1600         {
1601                 VK_FORMAT_D16_UNORM
1602         };
1603
1604         VkFormatFeatureFlags    flags   = (VkFormatFeatureFlags)0;
1605
1606         if (de::contains(DE_ARRAY_BEGIN(s_requiredSampledImageBlitSrcFormats), DE_ARRAY_END(s_requiredSampledImageBlitSrcFormats), format))
1607                 flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT|VK_FORMAT_FEATURE_BLIT_SRC_BIT;
1608
1609         if (de::contains(DE_ARRAY_BEGIN(s_requiredSampledImageFilterLinearFormats), DE_ARRAY_END(s_requiredSampledImageFilterLinearFormats), format))
1610                 flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
1611
1612         if (de::contains(DE_ARRAY_BEGIN(s_requiredStorageImageFormats), DE_ARRAY_END(s_requiredStorageImageFormats), format))
1613                 flags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
1614
1615         if (de::contains(DE_ARRAY_BEGIN(s_requiredStorageImageAtomicFormats), DE_ARRAY_END(s_requiredStorageImageAtomicFormats), format))
1616                 flags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT;
1617
1618         if (de::contains(DE_ARRAY_BEGIN(s_requiredColorAttachmentBlitDstFormats), DE_ARRAY_END(s_requiredColorAttachmentBlitDstFormats), format))
1619                 flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT|VK_FORMAT_FEATURE_BLIT_DST_BIT;
1620
1621         if (de::contains(DE_ARRAY_BEGIN(s_requiredColorAttachmentBlendFormats), DE_ARRAY_END(s_requiredColorAttachmentBlendFormats), format))
1622                 flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
1623
1624         if (de::contains(DE_ARRAY_BEGIN(s_requiredDepthStencilAttachmentFormats), DE_ARRAY_END(s_requiredDepthStencilAttachmentFormats), format))
1625                 flags |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
1626
1627         return flags;
1628 }
1629
1630 VkFormatFeatureFlags getRequiredOptimalExtendedTilingFeatures (Context& context, VkFormat format, VkFormatFeatureFlags queriedFlags)
1631 {
1632         VkFormatFeatureFlags    flags   = (VkFormatFeatureFlags)0;
1633
1634         // VK_EXT_sampler_filter_minmax:
1635         //      If filterMinmaxSingleComponentFormats is VK_TRUE, the following formats must
1636         //      support the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT feature with
1637         //      VK_IMAGE_TILING_OPTIMAL, if they support VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT.
1638
1639         static const VkFormat s_requiredSampledImageFilterMinMaxFormats[] =
1640         {
1641                 VK_FORMAT_R8_UNORM,
1642                 VK_FORMAT_R8_SNORM,
1643                 VK_FORMAT_R16_UNORM,
1644                 VK_FORMAT_R16_SNORM,
1645                 VK_FORMAT_R16_SFLOAT,
1646                 VK_FORMAT_R32_SFLOAT,
1647                 VK_FORMAT_D16_UNORM,
1648                 VK_FORMAT_X8_D24_UNORM_PACK32,
1649                 VK_FORMAT_D32_SFLOAT,
1650                 VK_FORMAT_D16_UNORM_S8_UINT,
1651                 VK_FORMAT_D24_UNORM_S8_UINT,
1652                 VK_FORMAT_D32_SFLOAT_S8_UINT,
1653         };
1654
1655         if ((queriedFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
1656         {
1657                 if (de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_EXT_sampler_filter_minmax"))
1658                 {
1659                         if (de::contains(DE_ARRAY_BEGIN(s_requiredSampledImageFilterMinMaxFormats), DE_ARRAY_END(s_requiredSampledImageFilterMinMaxFormats), format))
1660                         {
1661                                 VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT        physicalDeviceSamplerMinMaxProperties =
1662                                 {
1663                                         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT,
1664                                         DE_NULL,
1665                                         DE_FALSE,
1666                                         DE_FALSE
1667                                 };
1668
1669                                 {
1670                                         VkPhysicalDeviceProperties2             physicalDeviceProperties;
1671                                         physicalDeviceProperties.sType  = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1672                                         physicalDeviceProperties.pNext  = &physicalDeviceSamplerMinMaxProperties;
1673
1674                                         const InstanceInterface&                vk = context.getInstanceInterface();
1675                                         vk.getPhysicalDeviceProperties2(context.getPhysicalDevice(), &physicalDeviceProperties);
1676                                 }
1677
1678                                 if (physicalDeviceSamplerMinMaxProperties.filterMinmaxImageComponentMapping)
1679                                 {
1680                                         flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT;
1681                                 }
1682                         }
1683                 }
1684         }
1685         return flags;
1686 }
1687
1688 VkFormatFeatureFlags getRequiredBufferFeatures (VkFormat format)
1689 {
1690         static const VkFormat s_requiredVertexBufferFormats[] =
1691         {
1692                 VK_FORMAT_R8_UNORM,
1693                 VK_FORMAT_R8_SNORM,
1694                 VK_FORMAT_R8_UINT,
1695                 VK_FORMAT_R8_SINT,
1696                 VK_FORMAT_R8G8_UNORM,
1697                 VK_FORMAT_R8G8_SNORM,
1698                 VK_FORMAT_R8G8_UINT,
1699                 VK_FORMAT_R8G8_SINT,
1700                 VK_FORMAT_R8G8B8A8_UNORM,
1701                 VK_FORMAT_R8G8B8A8_SNORM,
1702                 VK_FORMAT_R8G8B8A8_UINT,
1703                 VK_FORMAT_R8G8B8A8_SINT,
1704                 VK_FORMAT_B8G8R8A8_UNORM,
1705                 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1706                 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1707                 VK_FORMAT_A8B8G8R8_UINT_PACK32,
1708                 VK_FORMAT_A8B8G8R8_SINT_PACK32,
1709                 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1710                 VK_FORMAT_R16_UNORM,
1711                 VK_FORMAT_R16_SNORM,
1712                 VK_FORMAT_R16_UINT,
1713                 VK_FORMAT_R16_SINT,
1714                 VK_FORMAT_R16_SFLOAT,
1715                 VK_FORMAT_R16G16_UNORM,
1716                 VK_FORMAT_R16G16_SNORM,
1717                 VK_FORMAT_R16G16_UINT,
1718                 VK_FORMAT_R16G16_SINT,
1719                 VK_FORMAT_R16G16_SFLOAT,
1720                 VK_FORMAT_R16G16B16A16_UNORM,
1721                 VK_FORMAT_R16G16B16A16_SNORM,
1722                 VK_FORMAT_R16G16B16A16_UINT,
1723                 VK_FORMAT_R16G16B16A16_SINT,
1724                 VK_FORMAT_R16G16B16A16_SFLOAT,
1725                 VK_FORMAT_R32_UINT,
1726                 VK_FORMAT_R32_SINT,
1727                 VK_FORMAT_R32_SFLOAT,
1728                 VK_FORMAT_R32G32_UINT,
1729                 VK_FORMAT_R32G32_SINT,
1730                 VK_FORMAT_R32G32_SFLOAT,
1731                 VK_FORMAT_R32G32B32_UINT,
1732                 VK_FORMAT_R32G32B32_SINT,
1733                 VK_FORMAT_R32G32B32_SFLOAT,
1734                 VK_FORMAT_R32G32B32A32_UINT,
1735                 VK_FORMAT_R32G32B32A32_SINT,
1736                 VK_FORMAT_R32G32B32A32_SFLOAT
1737         };
1738         static const VkFormat s_requiredUniformTexelBufferFormats[] =
1739         {
1740                 VK_FORMAT_R8_UNORM,
1741                 VK_FORMAT_R8_SNORM,
1742                 VK_FORMAT_R8_UINT,
1743                 VK_FORMAT_R8_SINT,
1744                 VK_FORMAT_R8G8_UNORM,
1745                 VK_FORMAT_R8G8_SNORM,
1746                 VK_FORMAT_R8G8_UINT,
1747                 VK_FORMAT_R8G8_SINT,
1748                 VK_FORMAT_R8G8B8A8_UNORM,
1749                 VK_FORMAT_R8G8B8A8_SNORM,
1750                 VK_FORMAT_R8G8B8A8_UINT,
1751                 VK_FORMAT_R8G8B8A8_SINT,
1752                 VK_FORMAT_B8G8R8A8_UNORM,
1753                 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1754                 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1755                 VK_FORMAT_A8B8G8R8_UINT_PACK32,
1756                 VK_FORMAT_A8B8G8R8_SINT_PACK32,
1757                 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1758                 VK_FORMAT_A2B10G10R10_UINT_PACK32,
1759                 VK_FORMAT_R16_UINT,
1760                 VK_FORMAT_R16_SINT,
1761                 VK_FORMAT_R16_SFLOAT,
1762                 VK_FORMAT_R16G16_UINT,
1763                 VK_FORMAT_R16G16_SINT,
1764                 VK_FORMAT_R16G16_SFLOAT,
1765                 VK_FORMAT_R16G16B16A16_UINT,
1766                 VK_FORMAT_R16G16B16A16_SINT,
1767                 VK_FORMAT_R16G16B16A16_SFLOAT,
1768                 VK_FORMAT_R32_UINT,
1769                 VK_FORMAT_R32_SINT,
1770                 VK_FORMAT_R32_SFLOAT,
1771                 VK_FORMAT_R32G32_UINT,
1772                 VK_FORMAT_R32G32_SINT,
1773                 VK_FORMAT_R32G32_SFLOAT,
1774                 VK_FORMAT_R32G32B32A32_UINT,
1775                 VK_FORMAT_R32G32B32A32_SINT,
1776                 VK_FORMAT_R32G32B32A32_SFLOAT,
1777                 VK_FORMAT_B10G11R11_UFLOAT_PACK32
1778         };
1779         static const VkFormat s_requiredStorageTexelBufferFormats[] =
1780         {
1781                 VK_FORMAT_R8G8B8A8_UNORM,
1782                 VK_FORMAT_R8G8B8A8_SNORM,
1783                 VK_FORMAT_R8G8B8A8_UINT,
1784                 VK_FORMAT_R8G8B8A8_SINT,
1785                 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1786                 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1787                 VK_FORMAT_A8B8G8R8_UINT_PACK32,
1788                 VK_FORMAT_A8B8G8R8_SINT_PACK32,
1789                 VK_FORMAT_R16G16B16A16_UINT,
1790                 VK_FORMAT_R16G16B16A16_SINT,
1791                 VK_FORMAT_R16G16B16A16_SFLOAT,
1792                 VK_FORMAT_R32_UINT,
1793                 VK_FORMAT_R32_SINT,
1794                 VK_FORMAT_R32_SFLOAT,
1795                 VK_FORMAT_R32G32_UINT,
1796                 VK_FORMAT_R32G32_SINT,
1797                 VK_FORMAT_R32G32_SFLOAT,
1798                 VK_FORMAT_R32G32B32A32_UINT,
1799                 VK_FORMAT_R32G32B32A32_SINT,
1800                 VK_FORMAT_R32G32B32A32_SFLOAT
1801         };
1802         static const VkFormat s_requiredStorageTexelBufferAtomicFormats[] =
1803         {
1804                 VK_FORMAT_R32_UINT,
1805                 VK_FORMAT_R32_SINT
1806         };
1807
1808         VkFormatFeatureFlags    flags   = (VkFormatFeatureFlags)0;
1809
1810         if (de::contains(DE_ARRAY_BEGIN(s_requiredVertexBufferFormats), DE_ARRAY_END(s_requiredVertexBufferFormats), format))
1811                 flags |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT;
1812
1813         if (de::contains(DE_ARRAY_BEGIN(s_requiredUniformTexelBufferFormats), DE_ARRAY_END(s_requiredUniformTexelBufferFormats), format))
1814                 flags |= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT;
1815
1816         if (de::contains(DE_ARRAY_BEGIN(s_requiredStorageTexelBufferFormats), DE_ARRAY_END(s_requiredStorageTexelBufferFormats), format))
1817                 flags |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT;
1818
1819         if (de::contains(DE_ARRAY_BEGIN(s_requiredStorageTexelBufferAtomicFormats), DE_ARRAY_END(s_requiredStorageTexelBufferAtomicFormats), format))
1820                 flags |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
1821
1822         return flags;
1823 }
1824
1825 tcu::TestStatus formatProperties (Context& context, VkFormat format)
1826 {
1827         TestLog&                                        log                                     = context.getTestContext().getLog();
1828         const VkFormatProperties        properties                      = getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), format);
1829         bool                                            allOk                           = true;
1830
1831         // \todo [2017-05-16 pyry] This should be extended to cover for example COLOR_ATTACHMENT for depth formats etc.
1832         // \todo [2017-05-18 pyry] Any other color conversion related features that can't be supported by regular formats?
1833         const VkFormatFeatureFlags      extOptimalFeatures      = getRequiredOptimalExtendedTilingFeatures(context, format, properties.optimalTilingFeatures);
1834
1835         const VkFormatFeatureFlags      notAllowedFeatures      = VK_FORMAT_FEATURE_DISJOINT_BIT;
1836
1837         const struct
1838         {
1839                 VkFormatFeatureFlags VkFormatProperties::*      field;
1840                 const char*                                                                     fieldName;
1841                 VkFormatFeatureFlags                                            requiredFeatures;
1842         } fields[] =
1843         {
1844                 { &VkFormatProperties::linearTilingFeatures,    "linearTilingFeatures",         (VkFormatFeatureFlags)0                                                                                 },
1845                 { &VkFormatProperties::optimalTilingFeatures,   "optimalTilingFeatures",        getRequiredOptimalTilingFeatures(format) | extOptimalFeatures   },
1846                 { &VkFormatProperties::bufferFeatures,                  "bufferFeatures",                       getRequiredBufferFeatures(format)                                                               }
1847         };
1848
1849         log << TestLog::Message << properties << TestLog::EndMessage;
1850
1851         for (int fieldNdx = 0; fieldNdx < DE_LENGTH_OF_ARRAY(fields); fieldNdx++)
1852         {
1853                 const char* const                               fieldName       = fields[fieldNdx].fieldName;
1854                 const VkFormatFeatureFlags              supported       = properties.*fields[fieldNdx].field;
1855                 const VkFormatFeatureFlags              required        = fields[fieldNdx].requiredFeatures;
1856
1857                 if ((supported & required) != required)
1858                 {
1859                         log << TestLog::Message << "ERROR in " << fieldName << ":\n"
1860                                                                         << "  required: " << getFormatFeatureFlagsStr(required) << "\n  "
1861                                                                         << "  missing: " << getFormatFeatureFlagsStr(~supported & required)
1862                                 << TestLog::EndMessage;
1863                         allOk = false;
1864                 }
1865
1866                 if ((supported & notAllowedFeatures) != 0)
1867                 {
1868                         log << TestLog::Message << "ERROR in " << fieldName << ":\n"
1869                                                                         << "  has: " << getFormatFeatureFlagsStr(supported & notAllowedFeatures)
1870                                 << TestLog::EndMessage;
1871                         allOk = false;
1872                 }
1873         }
1874
1875         if (allOk)
1876                 return tcu::TestStatus::pass("Query and validation passed");
1877         else
1878                 return tcu::TestStatus::fail("Required features not supported");
1879 }
1880
1881 VkPhysicalDeviceSamplerYcbcrConversionFeatures getPhysicalDeviceSamplerYcbcrConversionFeatures (const InstanceInterface& vk, VkPhysicalDevice physicalDevice)
1882 {
1883         VkPhysicalDeviceFeatures2                                               coreFeatures;
1884         VkPhysicalDeviceSamplerYcbcrConversionFeatures  ycbcrFeatures;
1885
1886         deMemset(&coreFeatures, 0, sizeof(coreFeatures));
1887         deMemset(&ycbcrFeatures, 0, sizeof(ycbcrFeatures));
1888
1889         coreFeatures.sType              = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1890         coreFeatures.pNext              = &ycbcrFeatures;
1891         ycbcrFeatures.sType             = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
1892
1893         vk.getPhysicalDeviceFeatures2(physicalDevice, &coreFeatures);
1894
1895         return ycbcrFeatures;
1896 }
1897
1898 void checkYcbcrApiSupport (Context& context)
1899 {
1900         // check if YCbcr API and are supported by implementation
1901
1902         // the support for formats and YCbCr may still be optional - see isYcbcrConversionSupported below
1903
1904         if (!vk::isCoreDeviceExtension(context.getUsedApiVersion(), "VK_KHR_sampler_ycbcr_conversion"))
1905         {
1906                 if (!vk::isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_sampler_ycbcr_conversion"))
1907                         TCU_THROW(NotSupportedError, "VK_KHR_sampler_ycbcr_conversion is not supported");
1908
1909                 // Hard dependency for ycbcr
1910                 TCU_CHECK(de::contains(context.getInstanceExtensions().begin(), context.getInstanceExtensions().end(), "VK_KHR_get_physical_device_properties2"));
1911         }
1912 }
1913
1914 bool isYcbcrConversionSupported (Context& context)
1915 {
1916         checkYcbcrApiSupport(context);
1917
1918         const VkPhysicalDeviceSamplerYcbcrConversionFeatures    ycbcrFeatures   = getPhysicalDeviceSamplerYcbcrConversionFeatures(context.getInstanceInterface(), context.getPhysicalDevice());
1919
1920         return (ycbcrFeatures.samplerYcbcrConversion == VK_TRUE);
1921 }
1922
1923 VkFormatFeatureFlags getAllowedYcbcrFormatFeatures (VkFormat format)
1924 {
1925         DE_ASSERT(isYCbCrFormat(format));
1926
1927         VkFormatFeatureFlags    flags   = (VkFormatFeatureFlags)0;
1928
1929         // all formats *may* support these
1930         flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
1931         flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
1932         flags |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT;
1933         flags |= VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
1934         flags |= VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT;
1935         flags |= VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT;
1936         flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT;
1937         flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT;
1938         flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT;
1939         flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT;
1940         flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT;
1941
1942         // multi-plane formats *may* support DISJOINT_BIT
1943         if (getPlaneCount(format) >= 2)
1944                 flags |= VK_FORMAT_FEATURE_DISJOINT_BIT;
1945
1946         if (isChromaSubsampled(format))
1947                 flags |= VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT;
1948
1949         return flags;
1950 }
1951
1952 tcu::TestStatus ycbcrFormatProperties (Context& context, VkFormat format)
1953 {
1954         DE_ASSERT(isYCbCrFormat(format));
1955         // check if Ycbcr format enums are valid given the version and extensions
1956         checkYcbcrApiSupport(context);
1957
1958         TestLog&                                        log                                             = context.getTestContext().getLog();
1959         const VkFormatProperties        properties                              = getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), format);
1960         bool                                            allOk                                   = true;
1961         const VkFormatFeatureFlags      allowedImageFeatures    = getAllowedYcbcrFormatFeatures(format);
1962
1963         const struct
1964         {
1965                 VkFormatFeatureFlags VkFormatProperties::*      field;
1966                 const char*                                                                     fieldName;
1967                 bool                                                                            requiredFeatures;
1968                 VkFormatFeatureFlags                                            allowedFeatures;
1969         } fields[] =
1970         {
1971                 { &VkFormatProperties::linearTilingFeatures,    "linearTilingFeatures",         false,  allowedImageFeatures    },
1972                 { &VkFormatProperties::optimalTilingFeatures,   "optimalTilingFeatures",        true,   allowedImageFeatures    },
1973                 { &VkFormatProperties::bufferFeatures,                  "bufferFeatures",                       false,  (VkFormatFeatureFlags)0 }
1974         };
1975         static const VkFormat           s_requiredBaseFormats[] =
1976         {
1977                 VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
1978                 VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM
1979         };
1980         const bool                                      isRequiredBaseFormat    = isYcbcrConversionSupported(context) &&
1981                                                                                                                   de::contains(DE_ARRAY_BEGIN(s_requiredBaseFormats), DE_ARRAY_END(s_requiredBaseFormats), format);
1982
1983         log << TestLog::Message << properties << TestLog::EndMessage;
1984
1985         for (int fieldNdx = 0; fieldNdx < DE_LENGTH_OF_ARRAY(fields); fieldNdx++)
1986         {
1987                 const char* const                               fieldName       = fields[fieldNdx].fieldName;
1988                 const VkFormatFeatureFlags              supported       = properties.*fields[fieldNdx].field;
1989                 const VkFormatFeatureFlags              allowed         = fields[fieldNdx].allowedFeatures;
1990
1991                 if (isRequiredBaseFormat && fields[fieldNdx].requiredFeatures)
1992                 {
1993                         const VkFormatFeatureFlags      required        = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
1994                                                                                                         | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT
1995                                                                                                         | VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
1996
1997                         if ((supported & required) != required)
1998                         {
1999                                 log << TestLog::Message << "ERROR in " << fieldName << ":\n"
2000                                                                                 << "  required: " << getFormatFeatureFlagsStr(required) << "\n  "
2001                                                                                 << "  missing: " << getFormatFeatureFlagsStr(~supported & required)
2002                                         << TestLog::EndMessage;
2003                                 allOk = false;
2004                         }
2005
2006                         if ((supported & (VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT | VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT)) == 0)
2007                         {
2008                                 log << TestLog::Message << "ERROR in " << fieldName << ":\n"
2009                                                                                 << "  Either VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT or VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT required"
2010                                         << TestLog::EndMessage;
2011                                 allOk = false;
2012                         }
2013                 }
2014
2015                 if ((supported & ~allowed) != 0)
2016                 {
2017                         log << TestLog::Message << "ERROR in " << fieldName << ":\n"
2018                                                                         << "  has: " << getFormatFeatureFlagsStr(supported & ~allowed)
2019                                 << TestLog::EndMessage;
2020                         allOk = false;
2021                 }
2022         }
2023
2024         if (allOk)
2025                 return tcu::TestStatus::pass("Query and validation passed");
2026         else
2027                 return tcu::TestStatus::fail("Required features not supported");
2028 }
2029
2030 bool optimalTilingFeaturesSupported (Context& context, VkFormat format, VkFormatFeatureFlags features)
2031 {
2032         const VkFormatProperties        properties      = getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), format);
2033
2034         return (properties.optimalTilingFeatures & features) == features;
2035 }
2036
2037 bool optimalTilingFeaturesSupportedForAll (Context& context, const VkFormat* begin, const VkFormat* end, VkFormatFeatureFlags features)
2038 {
2039         for (const VkFormat* cur = begin; cur != end; ++cur)
2040         {
2041                 if (!optimalTilingFeaturesSupported(context, *cur, features))
2042                         return false;
2043         }
2044
2045         return true;
2046 }
2047
2048 tcu::TestStatus testDepthStencilSupported (Context& context)
2049 {
2050         if (!optimalTilingFeaturesSupported(context, VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) &&
2051                 !optimalTilingFeaturesSupported(context, VK_FORMAT_D32_SFLOAT, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
2052                 return tcu::TestStatus::fail("Doesn't support one of VK_FORMAT_X8_D24_UNORM_PACK32 or VK_FORMAT_D32_SFLOAT");
2053
2054         if (!optimalTilingFeaturesSupported(context, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) &&
2055                 !optimalTilingFeaturesSupported(context, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
2056                 return tcu::TestStatus::fail("Doesn't support one of VK_FORMAT_D24_UNORM_S8_UINT or VK_FORMAT_D32_SFLOAT_S8_UINT");
2057
2058         return tcu::TestStatus::pass("Required depth/stencil formats supported");
2059 }
2060
2061 tcu::TestStatus testCompressedFormatsSupported (Context& context)
2062 {
2063         static const VkFormat s_allBcFormats[] =
2064         {
2065                 VK_FORMAT_BC1_RGB_UNORM_BLOCK,
2066                 VK_FORMAT_BC1_RGB_SRGB_BLOCK,
2067                 VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
2068                 VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
2069                 VK_FORMAT_BC2_UNORM_BLOCK,
2070                 VK_FORMAT_BC2_SRGB_BLOCK,
2071                 VK_FORMAT_BC3_UNORM_BLOCK,
2072                 VK_FORMAT_BC3_SRGB_BLOCK,
2073                 VK_FORMAT_BC4_UNORM_BLOCK,
2074                 VK_FORMAT_BC4_SNORM_BLOCK,
2075                 VK_FORMAT_BC5_UNORM_BLOCK,
2076                 VK_FORMAT_BC5_SNORM_BLOCK,
2077                 VK_FORMAT_BC6H_UFLOAT_BLOCK,
2078                 VK_FORMAT_BC6H_SFLOAT_BLOCK,
2079                 VK_FORMAT_BC7_UNORM_BLOCK,
2080                 VK_FORMAT_BC7_SRGB_BLOCK,
2081         };
2082         static const VkFormat s_allEtc2Formats[] =
2083         {
2084                 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
2085                 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
2086                 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
2087                 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
2088                 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
2089                 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
2090                 VK_FORMAT_EAC_R11_UNORM_BLOCK,
2091                 VK_FORMAT_EAC_R11_SNORM_BLOCK,
2092                 VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
2093                 VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
2094         };
2095         static const VkFormat s_allAstcLdrFormats[] =
2096         {
2097                 VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
2098                 VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
2099                 VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
2100                 VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
2101                 VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
2102                 VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
2103                 VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
2104                 VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
2105                 VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
2106                 VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
2107                 VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
2108                 VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
2109                 VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
2110                 VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
2111                 VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
2112                 VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
2113                 VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
2114                 VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
2115                 VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
2116                 VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
2117                 VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
2118                 VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
2119                 VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
2120                 VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
2121                 VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
2122                 VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
2123                 VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
2124                 VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
2125         };
2126
2127         static const struct
2128         {
2129                 const char*                                                                     setName;
2130                 const char*                                                                     featureName;
2131                 const VkBool32 VkPhysicalDeviceFeatures::*      feature;
2132                 const VkFormat*                                                         formatsBegin;
2133                 const VkFormat*                                                         formatsEnd;
2134         } s_compressedFormatSets[] =
2135         {
2136                 { "BC",                 "textureCompressionBC",                 &VkPhysicalDeviceFeatures::textureCompressionBC,                DE_ARRAY_BEGIN(s_allBcFormats),                 DE_ARRAY_END(s_allBcFormats)            },
2137                 { "ETC2",               "textureCompressionETC2",               &VkPhysicalDeviceFeatures::textureCompressionETC2,              DE_ARRAY_BEGIN(s_allEtc2Formats),               DE_ARRAY_END(s_allEtc2Formats)          },
2138                 { "ASTC LDR",   "textureCompressionASTC_LDR",   &VkPhysicalDeviceFeatures::textureCompressionASTC_LDR,  DE_ARRAY_BEGIN(s_allAstcLdrFormats),    DE_ARRAY_END(s_allAstcLdrFormats)       },
2139         };
2140
2141         TestLog&                                                log                                     = context.getTestContext().getLog();
2142         const VkPhysicalDeviceFeatures& features                        = context.getDeviceFeatures();
2143         int                                                             numSupportedSets        = 0;
2144         int                                                             numErrors                       = 0;
2145         int                                                             numWarnings                     = 0;
2146
2147         for (int setNdx = 0; setNdx < DE_LENGTH_OF_ARRAY(s_compressedFormatSets); ++setNdx)
2148         {
2149                 const char* const       setName                 = s_compressedFormatSets[setNdx].setName;
2150                 const char* const       featureName             = s_compressedFormatSets[setNdx].featureName;
2151                 const bool                      featureBitSet   = features.*s_compressedFormatSets[setNdx].feature == VK_TRUE;
2152                 const bool                      allSupported    = optimalTilingFeaturesSupportedForAll(context,
2153                                                                                                                                                                    s_compressedFormatSets[setNdx].formatsBegin,
2154                                                                                                                                                                    s_compressedFormatSets[setNdx].formatsEnd,
2155                                                                                                                                                                    VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);
2156
2157                 if (featureBitSet && !allSupported)
2158                 {
2159                         log << TestLog::Message << "ERROR: " << featureName << " = VK_TRUE but " << setName << " formats not supported" << TestLog::EndMessage;
2160                         numErrors += 1;
2161                 }
2162                 else if (allSupported && !featureBitSet)
2163                 {
2164                         log << TestLog::Message << "WARNING: " << setName << " formats supported but " << featureName << " = VK_FALSE" << TestLog::EndMessage;
2165                         numWarnings += 1;
2166                 }
2167
2168                 if (featureBitSet)
2169                 {
2170                         log << TestLog::Message << "All " << setName << " formats are supported" << TestLog::EndMessage;
2171                         numSupportedSets += 1;
2172                 }
2173                 else
2174                         log << TestLog::Message << setName << " formats are not supported" << TestLog::EndMessage;
2175         }
2176
2177         if (numSupportedSets == 0)
2178         {
2179                 log << TestLog::Message << "No compressed format sets supported" << TestLog::EndMessage;
2180                 numErrors += 1;
2181         }
2182
2183         if (numErrors > 0)
2184                 return tcu::TestStatus::fail("Compressed format support not valid");
2185         else if (numWarnings > 0)
2186                 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Found inconsistencies in compressed format support");
2187         else
2188                 return tcu::TestStatus::pass("Compressed texture format support is valid");
2189 }
2190
2191 void createFormatTests (tcu::TestCaseGroup* testGroup)
2192 {
2193         DE_STATIC_ASSERT(VK_FORMAT_UNDEFINED == 0);
2194
2195         static const struct
2196         {
2197                 VkFormat                                                                begin;
2198                 VkFormat                                                                end;
2199                 FunctionInstance1<VkFormat>::Function   testFunction;
2200         } s_formatRanges[] =
2201         {
2202                 // core formats
2203                 { (VkFormat)(VK_FORMAT_UNDEFINED+1),    VK_CORE_FORMAT_LAST,                                                                            formatProperties },
2204
2205                 // YCbCr formats
2206                 { VK_FORMAT_G8B8G8R8_422_UNORM,                 (VkFormat)(VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM+1),   ycbcrFormatProperties },
2207         };
2208
2209         for (int rangeNdx = 0; rangeNdx < DE_LENGTH_OF_ARRAY(s_formatRanges); ++rangeNdx)
2210         {
2211                 const VkFormat                                                          rangeBegin              = s_formatRanges[rangeNdx].begin;
2212                 const VkFormat                                                          rangeEnd                = s_formatRanges[rangeNdx].end;
2213                 const FunctionInstance1<VkFormat>::Function     testFunction    = s_formatRanges[rangeNdx].testFunction;
2214
2215                 for (VkFormat format = rangeBegin; format != rangeEnd; format = (VkFormat)(format+1))
2216                 {
2217                         const char* const       enumName        = getFormatName(format);
2218                         const string            caseName        = de::toLower(string(enumName).substr(10));
2219
2220                         addFunctionCase(testGroup, caseName, enumName, testFunction, format);
2221                 }
2222         }
2223
2224         addFunctionCase(testGroup, "depth_stencil",                     "",     testDepthStencilSupported);
2225         addFunctionCase(testGroup, "compressed_formats",        "",     testCompressedFormatsSupported);
2226 }
2227
2228 VkImageUsageFlags getValidImageUsageFlags (const VkFormatFeatureFlags supportedFeatures, const bool useKhrMaintenance1Semantics)
2229 {
2230         VkImageUsageFlags       flags   = (VkImageUsageFlags)0;
2231
2232         if (useKhrMaintenance1Semantics)
2233         {
2234                 if ((supportedFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) != 0)
2235                         flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
2236
2237                 if ((supportedFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT) != 0)
2238                         flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2239         }
2240         else
2241         {
2242                 // If format is supported at all, it must be valid transfer src+dst
2243                 if (supportedFeatures != 0)
2244                         flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2245         }
2246
2247         if ((supportedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
2248                 flags |= VK_IMAGE_USAGE_SAMPLED_BIT;
2249
2250         if ((supportedFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) != 0)
2251                 flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT|VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
2252
2253         if ((supportedFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)
2254                 flags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
2255
2256         if ((supportedFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) != 0)
2257                 flags |= VK_IMAGE_USAGE_STORAGE_BIT;
2258
2259         return flags;
2260 }
2261
2262 bool isValidImageUsageFlagCombination (VkImageUsageFlags usage)
2263 {
2264         if ((usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0)
2265         {
2266                 const VkImageUsageFlags         allowedFlags    = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
2267                                                                                                         | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
2268                                                                                                         | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
2269                                                                                                         | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
2270
2271                 // Only *_ATTACHMENT_BIT flags can be combined with TRANSIENT_ATTACHMENT_BIT
2272                 if ((usage & ~allowedFlags) != 0)
2273                         return false;
2274
2275                 // TRANSIENT_ATTACHMENT_BIT is not valid without COLOR_ or DEPTH_STENCIL_ATTACHMENT_BIT
2276                 if ((usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) == 0)
2277                         return false;
2278         }
2279
2280         return usage != 0;
2281 }
2282
2283 VkImageCreateFlags getValidImageCreateFlags (const VkPhysicalDeviceFeatures& deviceFeatures, VkFormat format, VkFormatFeatureFlags formatFeatures, VkImageType type, VkImageUsageFlags usage)
2284 {
2285         VkImageCreateFlags      flags   = (VkImageCreateFlags)0;
2286
2287         if ((usage & VK_IMAGE_USAGE_SAMPLED_BIT) != 0)
2288         {
2289                 flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
2290
2291                 if (type == VK_IMAGE_TYPE_2D && !isYCbCrFormat(format))
2292                 {
2293                         flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
2294                 }
2295         }
2296
2297         if (isYCbCrFormat(format) && getPlaneCount(format) > 1)
2298         {
2299                 if (formatFeatures & VK_FORMAT_FEATURE_DISJOINT_BIT_KHR)
2300                         flags |= VK_IMAGE_CREATE_DISJOINT_BIT_KHR;
2301         }
2302
2303         if ((usage & (VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_STORAGE_BIT)) != 0 &&
2304                 (usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) == 0)
2305         {
2306                 if (deviceFeatures.sparseBinding)
2307                         flags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT|VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT;
2308
2309                 if (deviceFeatures.sparseResidencyAliased)
2310                         flags |= VK_IMAGE_CREATE_SPARSE_ALIASED_BIT;
2311         }
2312
2313         return flags;
2314 }
2315
2316 bool isValidImageCreateFlagCombination (VkImageCreateFlags)
2317 {
2318         return true;
2319 }
2320
2321 bool isRequiredImageParameterCombination (const VkPhysicalDeviceFeatures&       deviceFeatures,
2322                                                                                   const VkFormat                                        format,
2323                                                                                   const VkFormatProperties&                     formatProperties,
2324                                                                                   const VkImageType                                     imageType,
2325                                                                                   const VkImageTiling                           imageTiling,
2326                                                                                   const VkImageUsageFlags                       usageFlags,
2327                                                                                   const VkImageCreateFlags                      createFlags)
2328 {
2329         DE_UNREF(deviceFeatures);
2330         DE_UNREF(formatProperties);
2331         DE_UNREF(createFlags);
2332
2333         // Linear images can have arbitrary limitations
2334         if (imageTiling == VK_IMAGE_TILING_LINEAR)
2335                 return false;
2336
2337         // Support for other usages for compressed formats is optional
2338         if (isCompressedFormat(format) &&
2339                 (usageFlags & ~(VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT)) != 0)
2340                 return false;
2341
2342         // Support for 1D, and sliced 3D compressed formats is optional
2343         if (isCompressedFormat(format) && (imageType == VK_IMAGE_TYPE_1D || imageType == VK_IMAGE_TYPE_3D))
2344                 return false;
2345
2346         // Support for 1D and 3D depth/stencil textures is optional
2347         if (isDepthStencilFormat(format) && (imageType == VK_IMAGE_TYPE_1D || imageType == VK_IMAGE_TYPE_3D))
2348                 return false;
2349
2350         DE_ASSERT(deviceFeatures.sparseBinding || (createFlags & (VK_IMAGE_CREATE_SPARSE_BINDING_BIT|VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)) == 0);
2351         DE_ASSERT(deviceFeatures.sparseResidencyAliased || (createFlags & VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) == 0);
2352
2353         if (isYCbCrFormat(format) && (createFlags & (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)))
2354                 return false;
2355
2356         if (createFlags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)
2357         {
2358                 if (isCompressedFormat(format))
2359                         return false;
2360
2361                 if (isDepthStencilFormat(format))
2362                         return false;
2363
2364                 if (!deIsPowerOfTwo32(mapVkFormat(format).getPixelSize()))
2365                         return false;
2366
2367                 switch (imageType)
2368                 {
2369                         case VK_IMAGE_TYPE_2D:
2370                                 return (deviceFeatures.sparseResidencyImage2D == VK_TRUE);
2371                         case VK_IMAGE_TYPE_3D:
2372                                 return (deviceFeatures.sparseResidencyImage3D == VK_TRUE);
2373                         default:
2374                                 return false;
2375                 }
2376         }
2377
2378         return true;
2379 }
2380
2381 VkSampleCountFlags getRequiredOptimalTilingSampleCounts (const VkPhysicalDeviceLimits&  deviceLimits,
2382                                                                                                                  const VkFormat                                 format,
2383                                                                                                                  const VkImageUsageFlags                usageFlags)
2384 {
2385         if (isCompressedFormat(format))
2386                 return VK_SAMPLE_COUNT_1_BIT;
2387
2388         bool            hasDepthComp    = false;
2389         bool            hasStencilComp  = false;
2390         const bool      isYCbCr                 = isYCbCrFormat(format);
2391         if (!isYCbCr)
2392         {
2393                 const tcu::TextureFormat        tcuFormat               = mapVkFormat(format);
2394                 hasDepthComp    = (tcuFormat.order == tcu::TextureFormat::D || tcuFormat.order == tcu::TextureFormat::DS);
2395                 hasStencilComp  = (tcuFormat.order == tcu::TextureFormat::S || tcuFormat.order == tcu::TextureFormat::DS);
2396         }
2397
2398         const bool                                              isColorFormat   = !hasDepthComp && !hasStencilComp;
2399         VkSampleCountFlags                              sampleCounts    = ~(VkSampleCountFlags)0;
2400
2401         DE_ASSERT((hasDepthComp || hasStencilComp) != isColorFormat);
2402
2403         if ((usageFlags & VK_IMAGE_USAGE_STORAGE_BIT) != 0)
2404                 sampleCounts &= deviceLimits.storageImageSampleCounts;
2405
2406         if ((usageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) != 0)
2407         {
2408                 if (hasDepthComp)
2409                         sampleCounts &= deviceLimits.sampledImageDepthSampleCounts;
2410
2411                 if (hasStencilComp)
2412                         sampleCounts &= deviceLimits.sampledImageStencilSampleCounts;
2413
2414                 if (isColorFormat)
2415                 {
2416                         if (isYCbCr)
2417                                 sampleCounts &= deviceLimits.sampledImageColorSampleCounts;
2418                         else
2419                         {
2420                                 const tcu::TextureFormat                tcuFormat       = mapVkFormat(format);
2421                                 const tcu::TextureChannelClass  chnClass        = tcu::getTextureChannelClass(tcuFormat.type);
2422
2423                                 if (chnClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ||
2424                                         chnClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
2425                                         sampleCounts &= deviceLimits.sampledImageIntegerSampleCounts;
2426                                 else
2427                                         sampleCounts &= deviceLimits.sampledImageColorSampleCounts;
2428                         }
2429                 }
2430         }
2431
2432         if ((usageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) != 0)
2433                 sampleCounts &= deviceLimits.framebufferColorSampleCounts;
2434
2435         if ((usageFlags & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)
2436         {
2437                 if (hasDepthComp)
2438                         sampleCounts &= deviceLimits.framebufferDepthSampleCounts;
2439
2440                 if (hasStencilComp)
2441                         sampleCounts &= deviceLimits.framebufferStencilSampleCounts;
2442         }
2443
2444         // If there is no usage flag set that would have corresponding device limit,
2445         // only VK_SAMPLE_COUNT_1_BIT is required.
2446         if (sampleCounts == ~(VkSampleCountFlags)0)
2447                 sampleCounts &= VK_SAMPLE_COUNT_1_BIT;
2448
2449         return sampleCounts;
2450 }
2451
2452 struct ImageFormatPropertyCase
2453 {
2454         typedef tcu::TestStatus (*Function) (Context& context, const VkFormat format, const VkImageType imageType, const VkImageTiling tiling);
2455
2456         Function                testFunction;
2457         VkFormat                format;
2458         VkImageType             imageType;
2459         VkImageTiling   tiling;
2460
2461         ImageFormatPropertyCase (Function testFunction_, VkFormat format_, VkImageType imageType_, VkImageTiling tiling_)
2462                 : testFunction  (testFunction_)
2463                 , format                (format_)
2464                 , imageType             (imageType_)
2465                 , tiling                (tiling_)
2466         {}
2467
2468         ImageFormatPropertyCase (void)
2469                 : testFunction  ((Function)DE_NULL)
2470                 , format                (VK_FORMAT_UNDEFINED)
2471                 , imageType             (VK_IMAGE_TYPE_LAST)
2472                 , tiling                (VK_IMAGE_TILING_LAST)
2473         {}
2474 };
2475
2476 tcu::TestStatus imageFormatProperties (Context& context, const VkFormat format, const VkImageType imageType, const VkImageTiling tiling)
2477 {
2478         if (isYCbCrFormat(format))
2479                 // check if Ycbcr format enums are valid given the version and extensions
2480                 checkYcbcrApiSupport(context);
2481
2482         TestLog&                                                log                                     = context.getTestContext().getLog();
2483         const VkPhysicalDeviceFeatures& deviceFeatures          = context.getDeviceFeatures();
2484         const VkPhysicalDeviceLimits&   deviceLimits            = context.getDeviceProperties().limits;
2485         const VkFormatProperties                formatProperties        = getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), format);
2486         const bool                                              hasKhrMaintenance1      = isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance1");
2487
2488         const VkFormatFeatureFlags              supportedFeatures       = tiling == VK_IMAGE_TILING_LINEAR ? formatProperties.linearTilingFeatures : formatProperties.optimalTilingFeatures;
2489         const VkImageUsageFlags                 usageFlagSet            = getValidImageUsageFlags(supportedFeatures, hasKhrMaintenance1);
2490
2491         tcu::ResultCollector                    results                         (log, "ERROR: ");
2492
2493         if (hasKhrMaintenance1 && (supportedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0)
2494         {
2495                 results.check((supportedFeatures & (VK_FORMAT_FEATURE_TRANSFER_SRC_BIT|VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) != 0,
2496                                           "A sampled image format must have VK_FORMAT_FEATURE_TRANSFER_SRC_BIT and VK_FORMAT_FEATURE_TRANSFER_DST_BIT format feature flags set");
2497         }
2498
2499         if (isYcbcrConversionSupported(context) && (format == VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR || format == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR))
2500         {
2501                 VkFormatFeatureFlags requiredFeatures = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR | VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR;
2502                 if (tiling == VK_IMAGE_TILING_OPTIMAL)
2503                         requiredFeatures |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT_KHR;
2504
2505                 results.check((supportedFeatures & requiredFeatures) == requiredFeatures,
2506                                           getFormatName(format) + string(" must support ") + de::toString(getFormatFeatureFlagsStr(requiredFeatures)));
2507         }
2508
2509         for (VkImageUsageFlags curUsageFlags = 0; curUsageFlags <= usageFlagSet; curUsageFlags++)
2510         {
2511                 if ((curUsageFlags & ~usageFlagSet) != 0 ||
2512                         !isValidImageUsageFlagCombination(curUsageFlags))
2513                         continue;
2514
2515                 const VkImageCreateFlags        createFlagSet           = getValidImageCreateFlags(deviceFeatures, format, supportedFeatures, imageType, curUsageFlags);
2516
2517                 for (VkImageCreateFlags curCreateFlags = 0; curCreateFlags <= createFlagSet; curCreateFlags++)
2518                 {
2519                         if ((curCreateFlags & ~createFlagSet) != 0 ||
2520                                 !isValidImageCreateFlagCombination(curCreateFlags))
2521                                 continue;
2522
2523                         const bool                              isRequiredCombination   = isRequiredImageParameterCombination(deviceFeatures,
2524                                                                                                                                                                                                   format,
2525                                                                                                                                                                                                   formatProperties,
2526                                                                                                                                                                                                   imageType,
2527                                                                                                                                                                                                   tiling,
2528                                                                                                                                                                                                   curUsageFlags,
2529                                                                                                                                                                                                   curCreateFlags);
2530                         VkImageFormatProperties properties;
2531                         VkResult                                queryResult;
2532
2533                         log << TestLog::Message << "Testing " << getImageTypeStr(imageType) << ", "
2534                                                                         << getImageTilingStr(tiling) << ", "
2535                                                                         << getImageUsageFlagsStr(curUsageFlags) << ", "
2536                                                                         << getImageCreateFlagsStr(curCreateFlags)
2537                                 << TestLog::EndMessage;
2538
2539                         // Set return value to known garbage
2540                         deMemset(&properties, 0xcd, sizeof(properties));
2541
2542                         queryResult = context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(context.getPhysicalDevice(),
2543                                                                                                                                                                                                 format,
2544                                                                                                                                                                                                 imageType,
2545                                                                                                                                                                                                 tiling,
2546                                                                                                                                                                                                 curUsageFlags,
2547                                                                                                                                                                                                 curCreateFlags,
2548                                                                                                                                                                                                 &properties);
2549
2550                         if (queryResult == VK_SUCCESS)
2551                         {
2552                                 const deUint32  fullMipPyramidSize      = de::max(de::max(deLog2Ceil32(properties.maxExtent.width),
2553                                                                                                                                           deLog2Ceil32(properties.maxExtent.height)),
2554                                                                                                                           deLog2Ceil32(properties.maxExtent.depth)) + 1;
2555
2556                                 log << TestLog::Message << properties << "\n" << TestLog::EndMessage;
2557
2558                                 results.check(imageType != VK_IMAGE_TYPE_1D || (properties.maxExtent.width >= 1 && properties.maxExtent.height == 1 && properties.maxExtent.depth == 1), "Invalid dimensions for 1D image");
2559                                 results.check(imageType != VK_IMAGE_TYPE_2D || (properties.maxExtent.width >= 1 && properties.maxExtent.height >= 1 && properties.maxExtent.depth == 1), "Invalid dimensions for 2D image");
2560                                 results.check(imageType != VK_IMAGE_TYPE_3D || (properties.maxExtent.width >= 1 && properties.maxExtent.height >= 1 && properties.maxExtent.depth >= 1), "Invalid dimensions for 3D image");
2561                                 results.check(imageType != VK_IMAGE_TYPE_3D || properties.maxArrayLayers == 1, "Invalid maxArrayLayers for 3D image");
2562
2563                                 if (tiling == VK_IMAGE_TILING_OPTIMAL && imageType == VK_IMAGE_TYPE_2D && !(curCreateFlags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
2564                                          (supportedFeatures & (VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)))
2565                                 {
2566                                         const VkSampleCountFlags        requiredSampleCounts    = getRequiredOptimalTilingSampleCounts(deviceLimits, format, curUsageFlags);
2567                                         results.check((properties.sampleCounts & requiredSampleCounts) == requiredSampleCounts, "Required sample counts not supported");
2568                                 }
2569                                 else
2570                                         results.check(properties.sampleCounts == VK_SAMPLE_COUNT_1_BIT, "sampleCounts != VK_SAMPLE_COUNT_1_BIT");
2571
2572                                 if (isRequiredCombination)
2573                                 {
2574                                         results.check(imageType != VK_IMAGE_TYPE_1D || (properties.maxExtent.width      >= deviceLimits.maxImageDimension1D),
2575                                                                   "Reported dimensions smaller than device limits");
2576                                         results.check(imageType != VK_IMAGE_TYPE_2D || (properties.maxExtent.width      >= deviceLimits.maxImageDimension2D &&
2577                                                                                                                                         properties.maxExtent.height     >= deviceLimits.maxImageDimension2D),
2578                                                                   "Reported dimensions smaller than device limits");
2579                                         results.check(imageType != VK_IMAGE_TYPE_3D || (properties.maxExtent.width      >= deviceLimits.maxImageDimension3D &&
2580                                                                                                                                         properties.maxExtent.height     >= deviceLimits.maxImageDimension3D &&
2581                                                                                                                                         properties.maxExtent.depth      >= deviceLimits.maxImageDimension3D),
2582                                                                   "Reported dimensions smaller than device limits");
2583                                         results.check((isYCbCrFormat(format) && (properties.maxMipLevels == 1)) || properties.maxMipLevels == fullMipPyramidSize,
2584                                                       "Invalid mip pyramid size");
2585                                         results.check((isYCbCrFormat(format) && (properties.maxArrayLayers == 1)) || imageType == VK_IMAGE_TYPE_3D ||
2586                                                       properties.maxArrayLayers >= deviceLimits.maxImageArrayLayers, "Invalid maxArrayLayers");
2587                                 }
2588                                 else
2589                                 {
2590                                         results.check(properties.maxMipLevels == 1 || properties.maxMipLevels == fullMipPyramidSize, "Invalid mip pyramid size");
2591                                         results.check(properties.maxArrayLayers >= 1, "Invalid maxArrayLayers");
2592                                 }
2593
2594                                 results.check(properties.maxResourceSize >= (VkDeviceSize)MINIMUM_REQUIRED_IMAGE_RESOURCE_SIZE,
2595                                                           "maxResourceSize smaller than minimum required size");
2596                         }
2597                         else if (queryResult == VK_ERROR_FORMAT_NOT_SUPPORTED)
2598                         {
2599                                 log << TestLog::Message << "Got VK_ERROR_FORMAT_NOT_SUPPORTED" << TestLog::EndMessage;
2600
2601                                 if (isRequiredCombination)
2602                                         results.fail("VK_ERROR_FORMAT_NOT_SUPPORTED returned for required image parameter combination");
2603
2604                                 // Specification requires that all fields are set to 0
2605                                 results.check(properties.maxExtent.width        == 0, "maxExtent.width != 0");
2606                                 results.check(properties.maxExtent.height       == 0, "maxExtent.height != 0");
2607                                 results.check(properties.maxExtent.depth        == 0, "maxExtent.depth != 0");
2608                                 results.check(properties.maxMipLevels           == 0, "maxMipLevels != 0");
2609                                 results.check(properties.maxArrayLayers         == 0, "maxArrayLayers != 0");
2610                                 results.check(properties.sampleCounts           == 0, "sampleCounts != 0");
2611                                 results.check(properties.maxResourceSize        == 0, "maxResourceSize != 0");
2612                         }
2613                         else
2614                         {
2615                                 results.fail("Got unexpected error" + de::toString(queryResult));
2616                         }
2617                 }
2618         }
2619
2620         return tcu::TestStatus(results.getResult(), results.getMessage());
2621 }
2622
2623 // VK_KHR_get_physical_device_properties2
2624
2625 Move<VkInstance> createInstanceWithExtension (const PlatformInterface& vkp, const char* extensionName, Context& context)
2626 {
2627         const vector<VkExtensionProperties>     instanceExts    = enumerateInstanceExtensionProperties(vkp, DE_NULL);
2628         vector<string>                                          enabledExts;
2629
2630         const deUint32                                          instanceVersion         = context.getUsedApiVersion();
2631
2632         if (!isCoreInstanceExtension(instanceVersion, extensionName))
2633         {
2634                 if (!isExtensionSupported(instanceExts, RequiredExtension(extensionName)))
2635                         TCU_THROW(NotSupportedError, (string(extensionName) + " is not supported").c_str());
2636                 else
2637                         enabledExts.push_back(extensionName);
2638         }
2639
2640         return createDefaultInstance(vkp, context.getUsedApiVersion(), vector<string>() /* layers */, enabledExts);
2641 }
2642
2643 string toString (const VkPhysicalDevice16BitStorageFeatures& value)
2644 {
2645         std::ostringstream      s;
2646         s << "VkPhysicalDevice16BitStorageFeatures = {\n";
2647         s << "\tsType = " << value.sType << '\n';
2648         s << "\tstorageBuffer16BitAccess = " << value.storageBuffer16BitAccess << '\n';
2649         s << "\tuniformAndStorageBuffer16BitAccess = " << value.uniformAndStorageBuffer16BitAccess << '\n';
2650         s << "\tstoragePushConstant16 = " << value.storagePushConstant16 << '\n';
2651         s << "\tstorageInputOutput16 = " << value.storageInputOutput16 << '\n';
2652         s << '}';
2653         return s.str();
2654 }
2655
2656 string toString (const VkPhysicalDeviceFloatControlsPropertiesKHR& value)
2657 {
2658         std::ostringstream      s;
2659         s << "VkPhysicalDeviceFloatControlsPropertiesKHR = {\n";
2660         s << "\tsType = " << value.sType << '\n';
2661         s << "\tseparateDenormSettings = " << value.separateDenormSettings << '\n';
2662         s << "\tseparateRoundingModeSettings = " << value.separateRoundingModeSettings << '\n';
2663         s << "\tshaderSignedZeroInfNanPreserveFloat16 = " << value.shaderSignedZeroInfNanPreserveFloat16 << '\n';
2664         s << "\tshaderSignedZeroInfNanPreserveFloat32 = " << value.shaderSignedZeroInfNanPreserveFloat32 << '\n';
2665         s << "\tshaderSignedZeroInfNanPreserveFloat64 = " << value.shaderSignedZeroInfNanPreserveFloat64 << '\n';
2666         s << "\tshaderDenormPreserveFloat16 = " << value.shaderDenormPreserveFloat16 << '\n';
2667         s << "\tshaderDenormPreserveFloat32 = " << value.shaderDenormPreserveFloat32 << '\n';
2668         s << "\tshaderDenormPreserveFloat64 = " << value.shaderDenormPreserveFloat64 << '\n';
2669         s << "\tshaderDenormFlushToZeroFloat16 = " << value.shaderDenormFlushToZeroFloat16 << '\n';
2670         s << "\tshaderDenormFlushToZeroFloat32 = " << value.shaderDenormFlushToZeroFloat32 << '\n';
2671         s << "\tshaderDenormFlushToZeroFloat64 = " << value.shaderDenormFlushToZeroFloat64 << '\n';
2672         s << "\tshaderRoundingModeRTEFloat16 = " << value.shaderRoundingModeRTEFloat16 << '\n';
2673         s << "\tshaderRoundingModeRTEFloat32 = " << value.shaderRoundingModeRTEFloat32 << '\n';
2674         s << "\tshaderRoundingModeRTEFloat64 = " << value.shaderRoundingModeRTEFloat64 << '\n';
2675         s << "\tshaderRoundingModeRTZFloat16 = " << value.shaderRoundingModeRTZFloat16 << '\n';
2676         s << "\tshaderRoundingModeRTZFloat32 = " << value.shaderRoundingModeRTZFloat32 << '\n';
2677         s << "\tshaderRoundingModeRTZFloat64 = " << value.shaderRoundingModeRTZFloat64 << '\n';
2678         s << '}';
2679         return s.str();
2680 }
2681
2682 string toString (const VkPhysicalDeviceMultiviewFeatures& value)
2683 {
2684         std::ostringstream      s;
2685         s << "VkPhysicalDeviceMultiviewFeatures = {\n";
2686         s << "\tsType = " << value.sType << '\n';
2687         s << "\tmultiview = " << value.multiview << '\n';
2688         s << "\tmultiviewGeometryShader = " << value.multiviewGeometryShader << '\n';
2689         s << "\tmultiviewTessellationShader = " << value.multiviewTessellationShader << '\n';
2690         s << '}';
2691         return s.str();
2692 }
2693
2694 string toString (const VkPhysicalDeviceProtectedMemoryFeatures& value)
2695 {
2696         std::ostringstream      s;
2697         s << "VkPhysicalDeviceProtectedMemoryFeatures = {\n";
2698         s << "\tsType = " << value.sType << '\n';
2699         s << "\tprotectedMemory = " << value.protectedMemory << '\n';
2700         s << '}';
2701         return s.str();
2702 }
2703
2704 string toString (const VkPhysicalDeviceSamplerYcbcrConversionFeatures& value)
2705 {
2706         std::ostringstream      s;
2707         s << "VkPhysicalDeviceSamplerYcbcrConversionFeatures = {\n";
2708         s << "\tsType = " << value.sType << '\n';
2709         s << "\tsamplerYcbcrConversion = " << value.samplerYcbcrConversion << '\n';
2710         s << '}';
2711         return s.str();
2712 }
2713
2714 string toString (const VkPhysicalDeviceVariablePointerFeatures& value)
2715 {
2716         std::ostringstream      s;
2717         s << "VkPhysicalDeviceVariablePointerFeatures = {\n";
2718         s << "\tsType = " << value.sType << '\n';
2719         s << "\tvariablePointersStorageBuffer = " << value.variablePointersStorageBuffer << '\n';
2720         s << "\tvariablePointers = " << value.variablePointers << '\n';
2721         s << '}';
2722         return s.str();
2723 }
2724
2725 string toString(const VkPhysicalDevicePushDescriptorPropertiesKHR& value)
2726 {
2727         std::ostringstream      s;
2728         s << "VkPhysicalDevicePushDescriptorPropertiesKHR = {\n";
2729         s << "\tsType = " << value.sType << '\n';
2730         s << "\tmaxPushDescriptors = " << value.maxPushDescriptors << '\n';
2731         s << '}';
2732         return s.str();
2733 }
2734
2735 string toString(const VkPhysicalDeviceScalarBlockLayoutFeaturesEXT& value)
2736 {
2737         std::ostringstream      s;
2738         s << "VkPhysicalDeviceScalarBlockLayoutFeaturesEXT = {\n";
2739         s << "\tsType = " << value.sType << '\n';
2740         s << "\tscalarBlockLayout = " << value.scalarBlockLayout << '\n';
2741         s << '}';
2742         return s.str();
2743 }
2744
2745 bool checkExtension (vector<VkExtensionProperties>& properties, const char* extension)
2746 {
2747         for (size_t ndx = 0; ndx < properties.size(); ++ndx)
2748         {
2749                 if (strcmp(properties[ndx].extensionName, extension) == 0)
2750                         return true;
2751         }
2752         return false;
2753 }
2754
2755 tcu::TestStatus deviceFeatures2 (Context& context)
2756 {
2757         const PlatformInterface&        vkp                             = context.getPlatformInterface();
2758         const VkPhysicalDevice          physicalDevice  = context.getPhysicalDevice();
2759         const Unique<VkInstance>        instance                (createInstanceWithExtension(vkp, "VK_KHR_get_physical_device_properties2", context));
2760         const InstanceDriver            vki                             (vkp, *instance);
2761         TestLog&                                        log                             = context.getTestContext().getLog();
2762         VkPhysicalDeviceFeatures        coreFeatures;
2763         VkPhysicalDeviceFeatures2       extFeatures;
2764
2765         deMemset(&coreFeatures, 0xcd, sizeof(coreFeatures));
2766         deMemset(&extFeatures.features, 0xcd, sizeof(extFeatures.features));
2767         std::vector<std::string> instExtensions = context.getInstanceExtensions();
2768
2769         extFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
2770         extFeatures.pNext = DE_NULL;
2771
2772         vki.getPhysicalDeviceFeatures(physicalDevice, &coreFeatures);
2773         vki.getPhysicalDeviceFeatures2(physicalDevice, &extFeatures);
2774
2775         TCU_CHECK(extFeatures.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2);
2776         TCU_CHECK(extFeatures.pNext == DE_NULL);
2777
2778         if (deMemCmp(&coreFeatures, &extFeatures.features, sizeof(VkPhysicalDeviceFeatures)) != 0)
2779                 TCU_FAIL("Mismatch between features reported by vkGetPhysicalDeviceFeatures and vkGetPhysicalDeviceFeatures2");
2780
2781         log << TestLog::Message << extFeatures << TestLog::EndMessage;
2782
2783         vector<VkExtensionProperties>   properties = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
2784         const bool khr_8bit_storage                             = checkExtension(properties,"VK_KHR_8bit_storage");
2785         const bool scalar_block_layout                  = checkExtension(properties,"VK_EXT_scalar_block_layout");
2786         bool khr_16bit_storage                                  = true;
2787         bool khr_multiview                                              = true;
2788         bool deviceProtectedMemory                              = true;
2789         bool sampler_ycbcr_conversion                   = true;
2790         bool variable_pointers                                  = true;
2791         if (getPhysicalDeviceProperties(vki, physicalDevice).apiVersion < VK_API_VERSION_1_1)
2792         {
2793                 khr_16bit_storage = checkExtension(properties,"VK_KHR_16bit_storage");
2794                 khr_multiview = checkExtension(properties,"VK_KHR_multiview");
2795                 deviceProtectedMemory = false;
2796                 sampler_ycbcr_conversion = checkExtension(properties,"VK_KHR_sampler_ycbcr_conversion");
2797                 variable_pointers = checkExtension(properties,"VK_KHR_variable_pointers");
2798         }
2799
2800         const int count = 2u;
2801         VkPhysicalDevice8BitStorageFeaturesKHR                          device8BitStorageFeatures[count];
2802         VkPhysicalDevice16BitStorageFeatures                            device16BitStorageFeatures[count];
2803         VkPhysicalDeviceMultiviewFeatures                                       deviceMultiviewFeatures[count];
2804         VkPhysicalDeviceProtectedMemoryFeatures                         protectedMemoryFeatures[count];
2805         VkPhysicalDeviceSamplerYcbcrConversionFeatures          samplerYcbcrConversionFeatures[count];
2806         VkPhysicalDeviceVariablePointerFeatures                         variablePointerFeatures[count];
2807         VkPhysicalDeviceScalarBlockLayoutFeaturesEXT            scalarBlockLayoutFeatures[count];
2808
2809         for (int ndx = 0; ndx < count; ++ndx)
2810         {
2811                 deMemset(&device8BitStorageFeatures[ndx],                       0xFF*ndx, sizeof(VkPhysicalDevice8BitStorageFeaturesKHR));
2812                 deMemset(&device16BitStorageFeatures[ndx],                      0xFF*ndx, sizeof(VkPhysicalDevice16BitStorageFeatures));
2813                 deMemset(&deviceMultiviewFeatures[ndx],                         0xFF*ndx, sizeof(VkPhysicalDeviceMultiviewFeatures));
2814                 deMemset(&protectedMemoryFeatures[ndx],                         0xFF*ndx, sizeof(VkPhysicalDeviceProtectedMemoryFeatures));
2815                 deMemset(&samplerYcbcrConversionFeatures[ndx],          0xFF*ndx, sizeof(VkPhysicalDeviceSamplerYcbcrConversionFeatures));
2816                 deMemset(&variablePointerFeatures[ndx],                         0xFF*ndx, sizeof(VkPhysicalDeviceVariablePointerFeatures));
2817                 deMemset(&scalarBlockLayoutFeatures[ndx],                       0xFF*ndx, sizeof(VkPhysicalDeviceScalarBlockLayoutFeaturesEXT));
2818
2819                 device8BitStorageFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR;
2820                 device8BitStorageFeatures[ndx].pNext = &device16BitStorageFeatures[ndx];
2821
2822                 device16BitStorageFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES;
2823                 device16BitStorageFeatures[ndx].pNext = &deviceMultiviewFeatures[ndx];
2824
2825                 deviceMultiviewFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES;
2826                 deviceMultiviewFeatures[ndx].pNext = &protectedMemoryFeatures[ndx];
2827
2828                 protectedMemoryFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES;
2829                 protectedMemoryFeatures[ndx].pNext = &samplerYcbcrConversionFeatures[ndx];
2830
2831                 samplerYcbcrConversionFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES;
2832                 samplerYcbcrConversionFeatures[ndx].pNext = &variablePointerFeatures[ndx];
2833
2834                 variablePointerFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES;
2835                 variablePointerFeatures[ndx].pNext = &scalarBlockLayoutFeatures[ndx];
2836
2837                 scalarBlockLayoutFeatures[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT;
2838                 scalarBlockLayoutFeatures[ndx].pNext = DE_NULL;
2839
2840                 deMemset(&extFeatures.features, 0xcd, sizeof(extFeatures.features));
2841                 extFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
2842                 extFeatures.pNext = &device8BitStorageFeatures[ndx];
2843
2844                 vki.getPhysicalDeviceFeatures2(physicalDevice, &extFeatures);
2845         }
2846
2847         if ( khr_8bit_storage &&
2848                 (device8BitStorageFeatures[0].storageBuffer8BitAccess                           != device8BitStorageFeatures[1].storageBuffer8BitAccess ||
2849                 device8BitStorageFeatures[0].uniformAndStorageBuffer8BitAccess          != device8BitStorageFeatures[1].uniformAndStorageBuffer8BitAccess ||
2850                 device8BitStorageFeatures[0].storagePushConstant8                                       != device8BitStorageFeatures[1].storagePushConstant8 )
2851                 )
2852         {
2853                 TCU_FAIL("Mismatch between VkPhysicalDevice8BitStorageFeatures");
2854         }
2855
2856         if ( khr_16bit_storage &&
2857                 (device16BitStorageFeatures[0].storageBuffer16BitAccess                         != device16BitStorageFeatures[1].storageBuffer16BitAccess ||
2858                 device16BitStorageFeatures[0].uniformAndStorageBuffer16BitAccess        != device16BitStorageFeatures[1].uniformAndStorageBuffer16BitAccess ||
2859                 device16BitStorageFeatures[0].storagePushConstant16                                     != device16BitStorageFeatures[1].storagePushConstant16 ||
2860                 device16BitStorageFeatures[0].storageInputOutput16                                      != device16BitStorageFeatures[1].storageInputOutput16)
2861                 )
2862         {
2863                 TCU_FAIL("Mismatch between VkPhysicalDevice16BitStorageFeatures");
2864         }
2865
2866         if (khr_multiview &&
2867                 (deviceMultiviewFeatures[0].multiview                                   != deviceMultiviewFeatures[1].multiview ||
2868                 deviceMultiviewFeatures[0].multiviewGeometryShader              != deviceMultiviewFeatures[1].multiviewGeometryShader ||
2869                 deviceMultiviewFeatures[0].multiviewTessellationShader  != deviceMultiviewFeatures[1].multiviewTessellationShader)
2870                 )
2871         {
2872                 TCU_FAIL("Mismatch between VkPhysicalDeviceMultiviewFeatures");
2873         }
2874
2875         if (deviceProtectedMemory && protectedMemoryFeatures[0].protectedMemory != protectedMemoryFeatures[1].protectedMemory)
2876         {
2877                 TCU_FAIL("Mismatch between VkPhysicalDeviceProtectedMemoryFeatures");
2878         }
2879
2880         if (sampler_ycbcr_conversion && samplerYcbcrConversionFeatures[0].samplerYcbcrConversion != samplerYcbcrConversionFeatures[1].samplerYcbcrConversion)
2881         {
2882                 TCU_FAIL("Mismatch between VkPhysicalDeviceSamplerYcbcrConversionFeatures");
2883         }
2884
2885         if (variable_pointers &&
2886                 (variablePointerFeatures[0].variablePointersStorageBuffer       != variablePointerFeatures[1].variablePointersStorageBuffer ||
2887                 variablePointerFeatures[0].variablePointers                                     != variablePointerFeatures[1].variablePointers)
2888                 )
2889         {
2890                 TCU_FAIL("Mismatch between VkPhysicalDeviceVariablePointerFeatures");
2891         }
2892         if (scalar_block_layout &&
2893                 (scalarBlockLayoutFeatures[0].scalarBlockLayout != scalarBlockLayoutFeatures[1].scalarBlockLayout))
2894         {
2895                 TCU_FAIL("Mismatch between VkPhysicalDeviceScalarBlockLayoutFeaturesEXT");
2896         }
2897         if (khr_8bit_storage)
2898                 log << TestLog::Message << device8BitStorageFeatures[0]         << TestLog::EndMessage;
2899         if (khr_16bit_storage)
2900                 log << TestLog::Message << toString(device16BitStorageFeatures[0])              << TestLog::EndMessage;
2901         if (khr_multiview)
2902                 log << TestLog::Message << toString(deviceMultiviewFeatures[0])                 << TestLog::EndMessage;
2903         if (deviceProtectedMemory)
2904                 log << TestLog::Message << toString(protectedMemoryFeatures[0])                 << TestLog::EndMessage;
2905         if (sampler_ycbcr_conversion)
2906                 log << TestLog::Message << toString(samplerYcbcrConversionFeatures[0])  << TestLog::EndMessage;
2907         if (variable_pointers)
2908                 log << TestLog::Message << toString(variablePointerFeatures[0])                 << TestLog::EndMessage;
2909         if (scalar_block_layout)
2910                 log << TestLog::Message << toString(scalarBlockLayoutFeatures[0])               << TestLog::EndMessage;
2911
2912         return tcu::TestStatus::pass("Querying device features succeeded");
2913 }
2914
2915
2916 string toString (const VkPhysicalDeviceIDProperties& value)
2917 {
2918         std::ostringstream      s;
2919         s << "VkPhysicalDeviceIDProperties = {\n";
2920         s << "\tsType = " << value.sType << '\n';
2921         s << "\tdeviceUUID = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<deUint8>(DE_ARRAY_BEGIN(value.deviceUUID)), tcu::Format::HexIterator<deUint8>(DE_ARRAY_END(value.deviceUUID))) << '\n';
2922         s << "\tdriverUUID = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<deUint8>(DE_ARRAY_BEGIN(value.driverUUID)), tcu::Format::HexIterator<deUint8>(DE_ARRAY_END(value.driverUUID))) << '\n';
2923         s << "\tdeviceLUID = " << '\n' << tcu::formatArray(tcu::Format::HexIterator<deUint8>(DE_ARRAY_BEGIN(value.deviceLUID)), tcu::Format::HexIterator<deUint8>(DE_ARRAY_END(value.deviceLUID))) << '\n';
2924         s << "\tdeviceNodeMask = " << value.deviceNodeMask << '\n';
2925         s << "\tdeviceLUIDValid = " << value.deviceLUIDValid << '\n';
2926         s << '}';
2927         return s.str();
2928 }
2929
2930 string toString (const VkPhysicalDeviceMaintenance3Properties& value)
2931 {
2932         std::ostringstream      s;
2933         s << "VkPhysicalDeviceMaintenance3Properties = {\n";
2934         s << "\tsType = " << value.sType << '\n';
2935         s << "\tmaxPerSetDescriptors = " << value.maxPerSetDescriptors << '\n';
2936         s << "\tmaxMemoryAllocationSize = " << value.maxMemoryAllocationSize << '\n';
2937         s << '}';
2938         return s.str();
2939 }
2940
2941 string toString (const VkPhysicalDeviceMultiviewProperties& value)
2942 {
2943         std::ostringstream      s;
2944         s << "VkPhysicalDeviceMultiviewProperties = {\n";
2945         s << "\tsType = " << value.sType << '\n';
2946         s << "\tmaxMultiviewViewCount = " << value.maxMultiviewViewCount << '\n';
2947         s << "\tmaxMultiviewInstanceIndex = " << value.maxMultiviewInstanceIndex << '\n';
2948         s << '}';
2949         return s.str();
2950 }
2951
2952 string toString (const VkPhysicalDevicePointClippingProperties& value)
2953 {
2954         std::ostringstream      s;
2955         s << "VkPhysicalDevicePointClippingProperties = {\n";
2956         s << "\tsType = " << value.sType << '\n';
2957         s << "\tpointClippingBehavior = " << value.pointClippingBehavior << '\n';
2958         s << '}';
2959         return s.str();
2960 }
2961
2962 string toString (const VkPhysicalDeviceProtectedMemoryProperties& value)
2963 {
2964         std::ostringstream      s;
2965         s << "VkPhysicalDeviceProtectedMemoryProperties = {\n";
2966         s << "\tsType = " << value.sType << '\n';
2967         s << "\tprotectedNoFault = " << value.protectedNoFault << '\n';
2968         s << '}';
2969         return s.str();
2970 }
2971
2972
2973 string toString (const VkPhysicalDeviceSubgroupProperties& value)
2974 {
2975         std::ostringstream      s;
2976         s << "VkPhysicalDeviceSubgroupProperties = {\n";
2977         s << "\tsType = " << value.sType << '\n';
2978         s << "\tsubgroupSize = " << value.subgroupSize << '\n';
2979         s << "\tsupportedStages = " << getShaderStageFlagsStr(value.supportedStages) << '\n';
2980         s << "\tsupportedOperations = " << getSubgroupFeatureFlagsStr(value.supportedOperations) << '\n';
2981         s << "\tquadOperationsInAllStages = " << value.quadOperationsInAllStages << '\n';
2982         s << '}';
2983         return s.str();
2984 }
2985
2986 tcu::TestStatus deviceProperties2 (Context& context)
2987 {
2988         const PlatformInterface&                vkp                             = context.getPlatformInterface();
2989         const VkPhysicalDevice                  physicalDevice  = context.getPhysicalDevice();
2990         const Unique<VkInstance>                instance                (createInstanceWithExtension(vkp, "VK_KHR_get_physical_device_properties2", context));
2991         const InstanceDriver                    vki                             (vkp, *instance);
2992         TestLog&                                                log                             = context.getTestContext().getLog();
2993         VkPhysicalDeviceProperties              coreProperties;
2994         VkPhysicalDeviceProperties2             extProperties;
2995
2996         extProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
2997         extProperties.pNext = DE_NULL;
2998
2999         vki.getPhysicalDeviceProperties(physicalDevice, &coreProperties);
3000         vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
3001
3002         TCU_CHECK(extProperties.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2);
3003         TCU_CHECK(extProperties.pNext == DE_NULL);
3004
3005         // We can't use memcmp() here because the structs may contain padding bytes that drivers may or may not
3006         // have written while writing the data and memcmp will compare them anyway, so we iterate through the
3007         // valid bytes for each field in the struct and compare only the valid bytes for each one.
3008         for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(s_physicalDevicePropertiesOffsetTable); propNdx++)
3009         {
3010                 const size_t offset                                     = s_physicalDevicePropertiesOffsetTable[propNdx].offset;
3011                 const size_t size                                       = s_physicalDevicePropertiesOffsetTable[propNdx].size;
3012
3013                 const deUint8* corePropertyBytes        = reinterpret_cast<deUint8*>(&coreProperties) + offset;
3014                 const deUint8* extPropertyBytes         = reinterpret_cast<deUint8*>(&extProperties.properties) + offset;
3015
3016                 if (deMemCmp(corePropertyBytes, extPropertyBytes, size) != 0)
3017                         TCU_FAIL("Mismatch between properties reported by vkGetPhysicalDeviceProperties and vkGetPhysicalDeviceProperties2");
3018         }
3019
3020         log << TestLog::Message << extProperties.properties << TestLog::EndMessage;
3021
3022         const int count = 2u;
3023
3024         if (getPhysicalDeviceProperties(vki, physicalDevice).apiVersion >= VK_API_VERSION_1_1)
3025         {
3026                 VkPhysicalDeviceIDProperties                                                            IDProperties[count];
3027                 VkPhysicalDeviceMaintenance3Properties                                          maintenance3Properties[count];
3028                 VkPhysicalDeviceMultiviewProperties                                                     multiviewProperties[count];
3029                 VkPhysicalDevicePointClippingProperties                                         pointClippingProperties[count];
3030                 VkPhysicalDeviceProtectedMemoryProperties                                       protectedMemoryPropertiesKHR[count];
3031                 VkPhysicalDeviceSubgroupProperties                                                      subgroupProperties[count];
3032
3033                 for (int ndx = 0; ndx < count; ++ndx)
3034                 {
3035
3036                         deMemset(&IDProperties[ndx],                                    0xFF, sizeof(VkPhysicalDeviceIDProperties                                               ));
3037                         deMemset(&maintenance3Properties[ndx],                  0xFF, sizeof(VkPhysicalDeviceMaintenance3Properties                             ));
3038                         deMemset(&multiviewProperties[ndx],                             0xFF, sizeof(VkPhysicalDeviceMultiviewProperties                                ));
3039                         deMemset(&pointClippingProperties[ndx],                 0xFF, sizeof(VkPhysicalDevicePointClippingProperties                    ));
3040                         deMemset(&protectedMemoryPropertiesKHR[ndx],    0xFF, sizeof(VkPhysicalDeviceProtectedMemoryProperties                  ));
3041                         deMemset(&subgroupProperties[ndx],                              0xFF, sizeof(VkPhysicalDeviceSubgroupProperties                                 ));
3042
3043
3044                         IDProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES;
3045                         IDProperties[ndx].pNext = &maintenance3Properties[ndx];
3046
3047                         maintenance3Properties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES;
3048                         maintenance3Properties[ndx].pNext = &multiviewProperties[ndx];
3049
3050                         multiviewProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES;
3051                         multiviewProperties[ndx].pNext = &pointClippingProperties[ndx];
3052
3053                         pointClippingProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES;
3054                         pointClippingProperties[ndx].pNext = &protectedMemoryPropertiesKHR[ndx];
3055
3056                         protectedMemoryPropertiesKHR[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES;
3057                         protectedMemoryPropertiesKHR[ndx].pNext = &subgroupProperties[ndx];
3058
3059                         subgroupProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
3060                         subgroupProperties[ndx].pNext = DE_NULL;
3061
3062                         extProperties.pNext = &IDProperties[ndx];
3063
3064                         vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
3065
3066                         IDProperties[ndx].pNext                                         = DE_NULL;
3067                         maintenance3Properties[ndx].pNext                       = DE_NULL;
3068                         multiviewProperties[ndx].pNext                          = DE_NULL;
3069                         pointClippingProperties[ndx].pNext                      = DE_NULL;
3070                         protectedMemoryPropertiesKHR[ndx].pNext         = DE_NULL;
3071                         subgroupProperties[ndx].pNext                           = DE_NULL;
3072                 }
3073
3074                 if (
3075                         deMemCmp(&IDProperties[0],                                      &IDProperties[1],                                       sizeof(VkPhysicalDeviceIDProperties     ))                                                      != 0 ||
3076                         deMemCmp(&maintenance3Properties[0],            &maintenance3Properties[1],                     sizeof(VkPhysicalDeviceMaintenance3Properties))                                 != 0 ||
3077                         deMemCmp(&multiviewProperties[0],                       &multiviewProperties[1],                        sizeof(VkPhysicalDeviceMultiviewProperties))                                    != 0 ||
3078                         deMemCmp(&pointClippingProperties[0],           &pointClippingProperties[1],            sizeof(VkPhysicalDevicePointClippingProperties))                                != 0 ||
3079                         deMemCmp(&protectedMemoryPropertiesKHR[0],      &protectedMemoryPropertiesKHR[1],       sizeof(VkPhysicalDeviceProtectedMemoryProperties))                              != 0 ||
3080                         deMemCmp(&subgroupProperties[0],                        &subgroupProperties[1],                         sizeof(VkPhysicalDeviceSubgroupProperties))                                             != 0
3081                         )
3082                 {
3083                         TCU_FAIL("Mismatch in vkGetPhysicalDeviceProperties2");
3084                 }
3085
3086                 log << TestLog::Message << toString(IDProperties[0])                            << TestLog::EndMessage
3087                 << TestLog::Message             << toString(maintenance3Properties[0])                  << TestLog::EndMessage
3088                 << TestLog::Message             << toString(multiviewProperties[0])                             << TestLog::EndMessage
3089                 << TestLog::Message             << toString(pointClippingProperties[0])                 << TestLog::EndMessage
3090                 << TestLog::Message             << toString(protectedMemoryPropertiesKHR[0])    << TestLog::EndMessage
3091                 << TestLog::Message             << toString(subgroupProperties[0])                              << TestLog::EndMessage;
3092         }
3093
3094         const vector<VkExtensionProperties>     extensions = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
3095
3096         if (isExtensionSupported(extensions, RequiredExtension("VK_KHR_push_descriptor")))
3097         {
3098                 VkPhysicalDevicePushDescriptorPropertiesKHR             pushDescriptorProperties[count];
3099
3100                 for (int ndx = 0; ndx < count; ++ndx)
3101                 {
3102                         deMemset(&pushDescriptorProperties[ndx], 0, sizeof(VkPhysicalDevicePushDescriptorPropertiesKHR));
3103
3104                         pushDescriptorProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR;
3105                         pushDescriptorProperties[ndx].pNext     = DE_NULL;
3106
3107                         extProperties.pNext = &pushDescriptorProperties[ndx];
3108
3109                         vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
3110
3111                         pushDescriptorProperties[ndx].pNext = DE_NULL;
3112                 }
3113
3114                 if (deMemCmp(&pushDescriptorProperties[0], &pushDescriptorProperties[1], sizeof(VkPhysicalDevicePushDescriptorPropertiesKHR)) != 0)
3115                 {
3116                         TCU_FAIL("Mismatch in vkGetPhysicalDeviceProperties2 in VkPhysicalDevicePushDescriptorPropertiesKHR ");
3117                 }
3118
3119                 log << TestLog::Message << toString(pushDescriptorProperties[0]) << TestLog::EndMessage;
3120
3121                 if (pushDescriptorProperties[0].maxPushDescriptors < 32)
3122                 {
3123                         TCU_FAIL("VkPhysicalDevicePushDescriptorPropertiesKHR.maxPushDescriptors must be at least 32");
3124                 }
3125         }
3126         if (isExtensionSupported(extensions, RequiredExtension("VK_KHR_shader_float_controls")))
3127         {
3128                 VkPhysicalDeviceFloatControlsPropertiesKHR floatControlsProperties[count];
3129
3130                 for (int ndx = 0; ndx < count; ++ndx)
3131                 {
3132                         deMemset(&floatControlsProperties[ndx], 0xFF, sizeof(VkPhysicalDeviceFloatControlsPropertiesKHR));
3133                         floatControlsProperties[ndx].sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR;
3134                         floatControlsProperties[ndx].pNext = DE_NULL;
3135
3136                         extProperties.pNext = &floatControlsProperties[ndx];
3137
3138                         vki.getPhysicalDeviceProperties2(physicalDevice, &extProperties);
3139                 }
3140
3141                 if (deMemCmp(&floatControlsProperties[0], &floatControlsProperties[1], sizeof(VkPhysicalDeviceFloatControlsPropertiesKHR)) != 0)
3142                 {
3143                         TCU_FAIL("Mismatch in VkPhysicalDeviceFloatControlsPropertiesKHR");
3144                 }
3145
3146                 log << TestLog::Message << toString(floatControlsProperties[0]) << TestLog::EndMessage;
3147         }
3148
3149         return tcu::TestStatus::pass("Querying device properties succeeded");
3150 }
3151
3152 string toString (const VkFormatProperties2& value)
3153 {
3154         std::ostringstream      s;
3155         s << "VkFormatProperties2 = {\n";
3156         s << "\tsType = " << value.sType << '\n';
3157         s << "\tformatProperties = {\n";
3158         s << "\tlinearTilingFeatures = " << getFormatFeatureFlagsStr(value.formatProperties.linearTilingFeatures) << '\n';
3159         s << "\toptimalTilingFeatures = " << getFormatFeatureFlagsStr(value.formatProperties.optimalTilingFeatures) << '\n';
3160         s << "\tbufferFeatures = " << getFormatFeatureFlagsStr(value.formatProperties.bufferFeatures) << '\n';
3161         s << "\t}";
3162         s << "}";
3163         return s.str();
3164 }
3165
3166 tcu::TestStatus deviceFormatProperties2 (Context& context)
3167 {
3168         const PlatformInterface&                vkp                             = context.getPlatformInterface();
3169         const VkPhysicalDevice                  physicalDevice  = context.getPhysicalDevice();
3170         const Unique<VkInstance>                instance                (createInstanceWithExtension(vkp, "VK_KHR_get_physical_device_properties2", context));
3171         const InstanceDriver                    vki                             (vkp, *instance);
3172         TestLog&                                                log                             = context.getTestContext().getLog();
3173
3174         for (int formatNdx = 0; formatNdx < VK_CORE_FORMAT_LAST; ++formatNdx)
3175         {
3176                 const VkFormat                  format                  = (VkFormat)formatNdx;
3177                 VkFormatProperties              coreProperties;
3178                 VkFormatProperties2             extProperties;
3179
3180                 deMemset(&coreProperties, 0xcd, sizeof(VkFormatProperties));
3181                 deMemset(&extProperties, 0xcd, sizeof(VkFormatProperties2));
3182
3183                 extProperties.sType     = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
3184                 extProperties.pNext = DE_NULL;
3185
3186                 vki.getPhysicalDeviceFormatProperties(physicalDevice, format, &coreProperties);
3187                 vki.getPhysicalDeviceFormatProperties2(physicalDevice, format, &extProperties);
3188
3189                 TCU_CHECK(extProperties.sType == VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2);
3190                 TCU_CHECK(extProperties.pNext == DE_NULL);
3191
3192         if (deMemCmp(&coreProperties, &extProperties.formatProperties, sizeof(VkFormatProperties)) != 0)
3193                 TCU_FAIL("Mismatch between format properties reported by vkGetPhysicalDeviceFormatProperties and vkGetPhysicalDeviceFormatProperties2");
3194
3195         log << TestLog::Message << toString (extProperties) << TestLog::EndMessage;
3196         }
3197
3198         return tcu::TestStatus::pass("Querying device format properties succeeded");
3199 }
3200
3201 string toString (const VkQueueFamilyProperties2& value)
3202 {
3203         std::ostringstream      s;
3204         s << "VkQueueFamilyProperties2 = {\n";
3205         s << "\tsType = " << value.sType << '\n';
3206         s << "\tqueueFamilyProperties = " << value.queueFamilyProperties << '\n';
3207         s << '}';
3208         return s.str();
3209 }
3210
3211 tcu::TestStatus deviceQueueFamilyProperties2 (Context& context)
3212 {
3213         const PlatformInterface&                vkp                                             = context.getPlatformInterface();
3214         const VkPhysicalDevice                  physicalDevice                  = context.getPhysicalDevice();
3215         const Unique<VkInstance>                instance                                (createInstanceWithExtension(vkp, "VK_KHR_get_physical_device_properties2", context));
3216         const InstanceDriver                    vki                                             (vkp, *instance);
3217         TestLog&                                                log                                             = context.getTestContext().getLog();
3218         deUint32                                                numCoreQueueFamilies    = ~0u;
3219         deUint32                                                numExtQueueFamilies             = ~0u;
3220
3221         vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numCoreQueueFamilies, DE_NULL);
3222         vki.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &numExtQueueFamilies, DE_NULL);
3223
3224         TCU_CHECK_MSG(numCoreQueueFamilies == numExtQueueFamilies, "Different number of queue family properties reported");
3225         TCU_CHECK(numCoreQueueFamilies > 0);
3226
3227         {
3228                 std::vector<VkQueueFamilyProperties>            coreProperties  (numCoreQueueFamilies);
3229                 std::vector<VkQueueFamilyProperties2>           extProperties   (numExtQueueFamilies);
3230
3231                 deMemset(&coreProperties[0], 0xcd, sizeof(VkQueueFamilyProperties)*numCoreQueueFamilies);
3232                 deMemset(&extProperties[0], 0xcd, sizeof(VkQueueFamilyProperties2)*numExtQueueFamilies);
3233
3234                 for (size_t ndx = 0; ndx < extProperties.size(); ++ndx)
3235                 {
3236                         extProperties[ndx].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
3237                         extProperties[ndx].pNext = DE_NULL;
3238                 }
3239
3240                 vki.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numCoreQueueFamilies, &coreProperties[0]);
3241                 vki.getPhysicalDeviceQueueFamilyProperties2(physicalDevice, &numExtQueueFamilies, &extProperties[0]);
3242
3243                 TCU_CHECK((size_t)numCoreQueueFamilies == coreProperties.size());
3244                 TCU_CHECK((size_t)numExtQueueFamilies == extProperties.size());
3245                 DE_ASSERT(numCoreQueueFamilies == numExtQueueFamilies);
3246
3247                 for (size_t ndx = 0; ndx < extProperties.size(); ++ndx)
3248                 {
3249                         TCU_CHECK(extProperties[ndx].sType == VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2);
3250                         TCU_CHECK(extProperties[ndx].pNext == DE_NULL);
3251
3252                         if (deMemCmp(&coreProperties[ndx], &extProperties[ndx].queueFamilyProperties, sizeof(VkQueueFamilyProperties)) != 0)
3253                                 TCU_FAIL("Mismatch between format properties reported by vkGetPhysicalDeviceQueueFamilyProperties and vkGetPhysicalDeviceQueueFamilyProperties2");
3254
3255                         log << TestLog::Message << " queueFamilyNdx = " << ndx <<TestLog::EndMessage
3256                         << TestLog::Message << toString(extProperties[ndx]) << TestLog::EndMessage;
3257                 }
3258         }
3259
3260         return tcu::TestStatus::pass("Querying device queue family properties succeeded");
3261 }
3262
3263 tcu::TestStatus deviceMemoryProperties2 (Context& context)
3264 {
3265         const PlatformInterface&                        vkp                             = context.getPlatformInterface();
3266         const VkPhysicalDevice                          physicalDevice  = context.getPhysicalDevice();
3267         const Unique<VkInstance>                        instance                (createInstanceWithExtension(vkp, "VK_KHR_get_physical_device_properties2", context));
3268         const InstanceDriver                            vki                             (vkp, *instance);
3269         TestLog&                                                        log                             = context.getTestContext().getLog();
3270         VkPhysicalDeviceMemoryProperties        coreProperties;
3271         VkPhysicalDeviceMemoryProperties2       extProperties;
3272
3273         deMemset(&coreProperties, 0xcd, sizeof(VkPhysicalDeviceMemoryProperties));
3274         deMemset(&extProperties, 0xcd, sizeof(VkPhysicalDeviceMemoryProperties2));
3275
3276         extProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2;
3277         extProperties.pNext = DE_NULL;
3278
3279         vki.getPhysicalDeviceMemoryProperties(physicalDevice, &coreProperties);
3280         vki.getPhysicalDeviceMemoryProperties2(physicalDevice, &extProperties);
3281
3282         TCU_CHECK(extProperties.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2);
3283         TCU_CHECK(extProperties.pNext == DE_NULL);
3284
3285         if (deMemCmp(&coreProperties, &extProperties.memoryProperties, sizeof(VkPhysicalDeviceMemoryProperties)) != 0)
3286                 TCU_FAIL("Mismatch between properties reported by vkGetPhysicalDeviceMemoryProperties and vkGetPhysicalDeviceMemoryProperties2");
3287
3288         log << TestLog::Message << extProperties << TestLog::EndMessage;
3289
3290         return tcu::TestStatus::pass("Querying device memory properties succeeded");
3291 }
3292
3293 tcu::TestStatus imageFormatProperties2 (Context& context, const VkFormat format, const VkImageType imageType, const VkImageTiling tiling)
3294 {
3295         if (isYCbCrFormat(format))
3296                 // check if Ycbcr format enums are valid given the version and extensions
3297                 checkYcbcrApiSupport(context);
3298
3299         TestLog&                                                log                             = context.getTestContext().getLog();
3300
3301         const PlatformInterface&                vkp                             = context.getPlatformInterface();
3302         const VkPhysicalDevice                  physicalDevice  = context.getPhysicalDevice();
3303         const Unique<VkInstance>                instance                (createInstanceWithExtension(vkp, "VK_KHR_get_physical_device_properties2", context));
3304         const InstanceDriver                    vki                             (vkp, *instance);
3305
3306         const VkImageUsageFlags                 ycbcrFlags              = isYCbCrFormat(format) ? (VkImageUsageFlags)VK_IMAGE_CREATE_DISJOINT_BIT_KHR : (VkImageUsageFlags)0u;
3307         const VkImageUsageFlags                 allUsageFlags   = VK_IMAGE_USAGE_TRANSFER_SRC_BIT
3308                                                                                                         | VK_IMAGE_USAGE_TRANSFER_DST_BIT
3309                                                                                                         | VK_IMAGE_USAGE_SAMPLED_BIT
3310                                                                                                         | VK_IMAGE_USAGE_STORAGE_BIT
3311                                                                                                         | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
3312                                                                                                         | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
3313                                                                                                         | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
3314                                                                                                         | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
3315         const VkImageCreateFlags                allCreateFlags  = VK_IMAGE_CREATE_SPARSE_BINDING_BIT
3316                                                                                                         | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT
3317                                                                                                         | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT
3318                                                                                                         | VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
3319                                                                                                         | VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT
3320                                                                                                         | ycbcrFlags;
3321
3322         for (VkImageUsageFlags curUsageFlags = (VkImageUsageFlags)1; curUsageFlags <= allUsageFlags; curUsageFlags++)
3323         {
3324                 for (VkImageCreateFlags curCreateFlags = 0; curCreateFlags <= allCreateFlags; curCreateFlags++)
3325                 {
3326                         const VkPhysicalDeviceImageFormatInfo2  imageFormatInfo =
3327                         {
3328                                 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
3329                                 DE_NULL,
3330                                 format,
3331                                 imageType,
3332                                 tiling,
3333                                 curUsageFlags,
3334                                 curCreateFlags
3335                         };
3336
3337                         VkImageFormatProperties                                         coreProperties;
3338                         VkImageFormatProperties2                                        extProperties;
3339                         VkResult                                                                        coreResult;
3340                         VkResult                                                                        extResult;
3341
3342                         deMemset(&coreProperties, 0xcd, sizeof(VkImageFormatProperties));
3343                         deMemset(&extProperties, 0xcd, sizeof(VkImageFormatProperties2));
3344
3345                         extProperties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
3346                         extProperties.pNext = DE_NULL;
3347
3348                         coreResult      = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, imageFormatInfo.format, imageFormatInfo.type, imageFormatInfo.tiling, imageFormatInfo.usage, imageFormatInfo.flags, &coreProperties);
3349                         extResult       = vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &imageFormatInfo, &extProperties);
3350
3351                         TCU_CHECK(extProperties.sType == VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2);
3352                         TCU_CHECK(extProperties.pNext == DE_NULL);
3353
3354                         if ((coreResult != extResult) ||
3355                                 (deMemCmp(&coreProperties, &extProperties.imageFormatProperties, sizeof(VkImageFormatProperties)) != 0))
3356                         {
3357                                 log << TestLog::Message << "ERROR: device mismatch with query " << imageFormatInfo << TestLog::EndMessage
3358                                         << TestLog::Message << "vkGetPhysicalDeviceImageFormatProperties() returned " << coreResult << ", " << coreProperties << TestLog::EndMessage
3359                                         << TestLog::Message << "vkGetPhysicalDeviceImageFormatProperties2() returned " << extResult << ", " << extProperties << TestLog::EndMessage;
3360                                 TCU_FAIL("Mismatch between image format properties reported by vkGetPhysicalDeviceImageFormatProperties and vkGetPhysicalDeviceImageFormatProperties2");
3361                         }
3362                 }
3363         }
3364
3365         return tcu::TestStatus::pass("Querying image format properties succeeded");
3366 }
3367
3368 tcu::TestStatus sparseImageFormatProperties2 (Context& context, const VkFormat format, const VkImageType imageType, const VkImageTiling tiling)
3369 {
3370         TestLog&                                                log                             = context.getTestContext().getLog();
3371
3372         const PlatformInterface&                vkp                             = context.getPlatformInterface();
3373         const VkPhysicalDevice                  physicalDevice  = context.getPhysicalDevice();
3374         const Unique<VkInstance>                instance                (createInstanceWithExtension(vkp, "VK_KHR_get_physical_device_properties2", context));
3375         const InstanceDriver                    vki                             (vkp, *instance);
3376
3377         const VkImageUsageFlags                 allUsageFlags   = VK_IMAGE_USAGE_TRANSFER_SRC_BIT
3378                                                                                                         | VK_IMAGE_USAGE_TRANSFER_DST_BIT
3379                                                                                                         | VK_IMAGE_USAGE_SAMPLED_BIT
3380                                                                                                         | VK_IMAGE_USAGE_STORAGE_BIT
3381                                                                                                         | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
3382                                                                                                         | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
3383                                                                                                         | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
3384                                                                                                         | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
3385
3386         for (deUint32 sampleCountBit = VK_SAMPLE_COUNT_1_BIT; sampleCountBit <= VK_SAMPLE_COUNT_64_BIT; sampleCountBit = (sampleCountBit << 1u))
3387         {
3388                 for (VkImageUsageFlags curUsageFlags = (VkImageUsageFlags)1; curUsageFlags <= allUsageFlags; curUsageFlags++)
3389                 {
3390                         const VkPhysicalDeviceSparseImageFormatInfo2    imageFormatInfo =
3391                         {
3392                                 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2,
3393                                 DE_NULL,
3394                                 format,
3395                                 imageType,
3396                                 (VkSampleCountFlagBits)sampleCountBit,
3397                                 curUsageFlags,
3398                                 tiling,
3399                         };
3400
3401                         deUint32                                                                                numCoreProperties       = ~0u;
3402                         deUint32                                                                                numExtProperties        = ~0u;
3403
3404                         // Query count
3405                         vki.getPhysicalDeviceSparseImageFormatProperties(physicalDevice, imageFormatInfo.format, imageFormatInfo.type, imageFormatInfo.samples, imageFormatInfo.usage, imageFormatInfo.tiling, &numCoreProperties, DE_NULL);
3406                         vki.getPhysicalDeviceSparseImageFormatProperties2(physicalDevice, &imageFormatInfo, &numExtProperties, DE_NULL);
3407
3408                         if (numCoreProperties != numExtProperties)
3409                         {
3410                                 log << TestLog::Message << "ERROR: different number of properties reported for " << imageFormatInfo << TestLog::EndMessage;
3411                                 TCU_FAIL("Mismatch in reported property count");
3412                         }
3413
3414                         if (numCoreProperties > 0)
3415                         {
3416                                 std::vector<VkSparseImageFormatProperties>              coreProperties  (numCoreProperties);
3417                                 std::vector<VkSparseImageFormatProperties2>             extProperties   (numExtProperties);
3418
3419                                 deMemset(&coreProperties[0], 0xcd, sizeof(VkSparseImageFormatProperties)*numCoreProperties);
3420                                 deMemset(&extProperties[0], 0xcd, sizeof(VkSparseImageFormatProperties2)*numExtProperties);
3421
3422                                 for (deUint32 ndx = 0; ndx < numExtProperties; ++ndx)
3423                                 {
3424                                         extProperties[ndx].sType = VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2;
3425                                         extProperties[ndx].pNext = DE_NULL;
3426                                 }
3427
3428                                 vki.getPhysicalDeviceSparseImageFormatProperties(physicalDevice, imageFormatInfo.format, imageFormatInfo.type, imageFormatInfo.samples, imageFormatInfo.usage, imageFormatInfo.tiling, &numCoreProperties, &coreProperties[0]);
3429                                 vki.getPhysicalDeviceSparseImageFormatProperties2(physicalDevice, &imageFormatInfo, &numExtProperties, &extProperties[0]);
3430
3431                                 TCU_CHECK((size_t)numCoreProperties == coreProperties.size());
3432                                 TCU_CHECK((size_t)numExtProperties == extProperties.size());
3433
3434                                 for (deUint32 ndx = 0; ndx < numCoreProperties; ++ndx)
3435                                 {
3436                                         TCU_CHECK(extProperties[ndx].sType == VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2);
3437                                         TCU_CHECK(extProperties[ndx].pNext == DE_NULL);
3438
3439                                         if ((deMemCmp(&coreProperties[ndx], &extProperties[ndx].properties, sizeof(VkSparseImageFormatProperties)) != 0))
3440                                         {
3441                                                 log << TestLog::Message << "ERROR: device mismatch with query " << imageFormatInfo << " property " << ndx << TestLog::EndMessage
3442                                                         << TestLog::Message << "vkGetPhysicalDeviceSparseImageFormatProperties() returned " << coreProperties[ndx] << TestLog::EndMessage
3443                                                         << TestLog::Message << "vkGetPhysicalDeviceSparseImageFormatProperties2() returned " << extProperties[ndx] << TestLog::EndMessage;
3444                                                 TCU_FAIL("Mismatch between image format properties reported by vkGetPhysicalDeviceSparseImageFormatProperties and vkGetPhysicalDeviceSparseImageFormatProperties2");
3445                                         }
3446                                 }
3447                         }
3448                 }
3449         }
3450
3451         return tcu::TestStatus::pass("Querying sparse image format properties succeeded");
3452 }
3453
3454 tcu::TestStatus execImageFormatTest (Context& context, ImageFormatPropertyCase testCase)
3455 {
3456         return testCase.testFunction(context, testCase.format, testCase.imageType, testCase.tiling);
3457 }
3458
3459 void createImageFormatTypeTilingTests (tcu::TestCaseGroup* testGroup, ImageFormatPropertyCase params)
3460 {
3461         DE_ASSERT(params.format == VK_FORMAT_UNDEFINED);
3462
3463         static const struct
3464         {
3465                 VkFormat                                                                begin;
3466                 VkFormat                                                                end;
3467                 ImageFormatPropertyCase                                 params;
3468         } s_formatRanges[] =
3469         {
3470                 // core formats
3471                 { (VkFormat)(VK_FORMAT_UNDEFINED + 1),  VK_CORE_FORMAT_LAST,                                                                            params },
3472
3473                 // YCbCr formats
3474                 { VK_FORMAT_G8B8G8R8_422_UNORM_KHR,             (VkFormat)(VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR + 1),     params }
3475         };
3476
3477         for (int rangeNdx = 0; rangeNdx < DE_LENGTH_OF_ARRAY(s_formatRanges); ++rangeNdx)
3478         {
3479                 const VkFormat                                                          rangeBegin              = s_formatRanges[rangeNdx].begin;
3480                 const VkFormat                                                          rangeEnd                = s_formatRanges[rangeNdx].end;
3481
3482                 for (VkFormat format = rangeBegin; format != rangeEnd; format = (VkFormat)(format+1))
3483                 {
3484                         const bool                      isYCbCr         = isYCbCrFormat(format);
3485                         const bool                      isSparse        = (params.testFunction == sparseImageFormatProperties2);
3486
3487                         if (isYCbCr && isSparse)
3488                                 continue;
3489
3490                         if (isYCbCr && params.imageType != VK_IMAGE_TYPE_2D)
3491                                 continue;
3492
3493                         const char* const       enumName        = getFormatName(format);
3494                         const string            caseName        = de::toLower(string(enumName).substr(10));
3495
3496                         params.format = format;
3497
3498                         addFunctionCase(testGroup, caseName, enumName, execImageFormatTest, params);
3499                 }
3500         }
3501 }
3502
3503 void createImageFormatTypeTests (tcu::TestCaseGroup* testGroup, ImageFormatPropertyCase params)
3504 {
3505         DE_ASSERT(params.tiling == VK_IMAGE_TILING_LAST);
3506
3507         testGroup->addChild(createTestGroup(testGroup->getTestContext(), "optimal",     "",     createImageFormatTypeTilingTests, ImageFormatPropertyCase(params.testFunction, VK_FORMAT_UNDEFINED, params.imageType, VK_IMAGE_TILING_OPTIMAL)));
3508         testGroup->addChild(createTestGroup(testGroup->getTestContext(), "linear",      "",     createImageFormatTypeTilingTests, ImageFormatPropertyCase(params.testFunction, VK_FORMAT_UNDEFINED, params.imageType, VK_IMAGE_TILING_LINEAR)));
3509 }
3510
3511 void createImageFormatTests (tcu::TestCaseGroup* testGroup, ImageFormatPropertyCase::Function testFunction)
3512 {
3513         testGroup->addChild(createTestGroup(testGroup->getTestContext(), "1d", "", createImageFormatTypeTests, ImageFormatPropertyCase(testFunction, VK_FORMAT_UNDEFINED, VK_IMAGE_TYPE_1D, VK_IMAGE_TILING_LAST)));
3514         testGroup->addChild(createTestGroup(testGroup->getTestContext(), "2d", "", createImageFormatTypeTests, ImageFormatPropertyCase(testFunction, VK_FORMAT_UNDEFINED, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_LAST)));
3515         testGroup->addChild(createTestGroup(testGroup->getTestContext(), "3d", "", createImageFormatTypeTests, ImageFormatPropertyCase(testFunction, VK_FORMAT_UNDEFINED, VK_IMAGE_TYPE_3D, VK_IMAGE_TILING_LAST)));
3516 }
3517
3518
3519 // Android CTS -specific tests
3520
3521 namespace android
3522 {
3523
3524 void checkExtensions (tcu::ResultCollector& results, const set<string>& allowedExtensions, const vector<VkExtensionProperties>& reportedExtensions)
3525 {
3526         for (vector<VkExtensionProperties>::const_iterator extension = reportedExtensions.begin(); extension != reportedExtensions.end(); ++extension)
3527         {
3528                 const string    extensionName   (extension->extensionName);
3529                 const bool              mustBeKnown             = de::beginsWith(extensionName, "VK_KHX_")              ||
3530                                                                                   de::beginsWith(extensionName, "VK_GOOGLE_")   ||
3531                                                                                   de::beginsWith(extensionName, "VK_ANDROID_");
3532
3533                 if (mustBeKnown && !de::contains(allowedExtensions, extensionName))
3534                         results.fail("Unknown extension: " + extensionName);
3535         }
3536 }
3537
3538 tcu::TestStatus testNoUnknownExtensions (Context& context)
3539 {
3540         TestLog&                                log                                     = context.getTestContext().getLog();
3541         tcu::ResultCollector    results                         (log);
3542         set<string>                             allowedInstanceExtensions;
3543         set<string>                             allowedDeviceExtensions;
3544
3545         // All known extensions should be added to allowedExtensions:
3546         // allowedExtensions.insert("VK_GOOGLE_extension1");
3547         allowedDeviceExtensions.insert("VK_ANDROID_external_memory_android_hardware_buffer");
3548         allowedDeviceExtensions.insert("VK_GOOGLE_display_timing");
3549
3550         // Instance extensions
3551         checkExtensions(results,
3552                                         allowedInstanceExtensions,
3553                                         enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL));
3554
3555         // Extensions exposed by instance layers
3556         {
3557                 const vector<VkLayerProperties> layers  = enumerateInstanceLayerProperties(context.getPlatformInterface());
3558
3559                 for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
3560                 {
3561                         checkExtensions(results,
3562                                                         allowedInstanceExtensions,
3563                                                         enumerateInstanceExtensionProperties(context.getPlatformInterface(), layer->layerName));
3564                 }
3565         }
3566
3567         // Device extensions
3568         checkExtensions(results,
3569                                         allowedDeviceExtensions,
3570                                         enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), DE_NULL));
3571
3572         // Extensions exposed by device layers
3573         {
3574                 const vector<VkLayerProperties> layers  = enumerateDeviceLayerProperties(context.getInstanceInterface(), context.getPhysicalDevice());
3575
3576                 for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
3577                 {
3578                         checkExtensions(results,
3579                                                         allowedDeviceExtensions,
3580                                                         enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), layer->layerName));
3581                 }
3582         }
3583
3584         return tcu::TestStatus(results.getResult(), results.getMessage());
3585 }
3586
3587 tcu::TestStatus testNoLayers (Context& context)
3588 {
3589         TestLog&                                log             = context.getTestContext().getLog();
3590         tcu::ResultCollector    results (log);
3591
3592         {
3593                 const vector<VkLayerProperties> layers  = enumerateInstanceLayerProperties(context.getPlatformInterface());
3594
3595                 for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
3596                         results.fail(string("Instance layer enumerated: ") + layer->layerName);
3597         }
3598
3599         {
3600                 const vector<VkLayerProperties> layers  = enumerateDeviceLayerProperties(context.getInstanceInterface(), context.getPhysicalDevice());
3601
3602                 for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer)
3603                         results.fail(string("Device layer enumerated: ") + layer->layerName);
3604         }
3605
3606         return tcu::TestStatus(results.getResult(), results.getMessage());
3607 }
3608
3609 tcu::TestStatus testMandatoryExtensions (Context& context)
3610 {
3611         TestLog&                                log             = context.getTestContext().getLog();
3612         tcu::ResultCollector    results (log);
3613
3614         // Instance extensions
3615         {
3616                 static const char*                                      mandatoryExtensions[]   =
3617                 {
3618                         "VK_KHR_get_physical_device_properties2",
3619                 };
3620                 const vector<VkExtensionProperties>     extensions                              = enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL);
3621
3622                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(mandatoryExtensions); ++ndx)
3623                 {
3624                         if (!isInstanceExtensionSupported(context.getUsedApiVersion(), extensions, RequiredExtension(mandatoryExtensions[ndx])))
3625                                 results.fail(string(mandatoryExtensions[ndx]) + " is not supported");
3626                 }
3627         }
3628
3629         // Device extensions
3630         {
3631                 static const char*                                      mandatoryExtensions[]   =
3632                 {
3633                         "VK_KHR_maintenance1",
3634                 };
3635                 const vector<VkExtensionProperties>     extensions                              = enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), DE_NULL);
3636
3637                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(mandatoryExtensions); ++ndx)
3638                 {
3639                         if (!isDeviceExtensionSupported(context.getUsedApiVersion(), extensions, RequiredExtension(mandatoryExtensions[ndx])))
3640                                 results.fail(string(mandatoryExtensions[ndx]) + " is not supported");
3641                 }
3642         }
3643
3644         return tcu::TestStatus(results.getResult(), results.getMessage());
3645 }
3646
3647 } // android
3648
3649 } // anonymous
3650
3651 tcu::TestCaseGroup* createFeatureInfoTests (tcu::TestContext& testCtx)
3652 {
3653         de::MovePtr<tcu::TestCaseGroup> infoTests       (new tcu::TestCaseGroup(testCtx, "info", "Platform Information Tests"));
3654
3655         {
3656                 de::MovePtr<tcu::TestCaseGroup> instanceInfoTests       (new tcu::TestCaseGroup(testCtx, "instance", "Instance Information Tests"));
3657
3658                 addFunctionCase(instanceInfoTests.get(), "physical_devices",            "Physical devices",                     enumeratePhysicalDevices);
3659                 addFunctionCase(instanceInfoTests.get(), "physical_device_groups",      "Physical devices Groups",      enumeratePhysicalDeviceGroups);
3660                 addFunctionCase(instanceInfoTests.get(), "layers",                                      "Layers",                                       enumerateInstanceLayers);
3661                 addFunctionCase(instanceInfoTests.get(), "extensions",                          "Extensions",                           enumerateInstanceExtensions);
3662
3663                 infoTests->addChild(instanceInfoTests.release());
3664         }
3665
3666         {
3667                 de::MovePtr<tcu::TestCaseGroup> deviceInfoTests (new tcu::TestCaseGroup(testCtx, "device", "Device Information Tests"));
3668
3669                 addFunctionCase(deviceInfoTests.get(), "features",                                      "Device Features",                      deviceFeatures);
3670                 addFunctionCase(deviceInfoTests.get(), "properties",                            "Device Properties",            deviceProperties);
3671                 addFunctionCase(deviceInfoTests.get(), "queue_family_properties",       "Queue family properties",      deviceQueueFamilyProperties);
3672                 addFunctionCase(deviceInfoTests.get(), "memory_properties",                     "Memory properties",            deviceMemoryProperties);
3673                 addFunctionCase(deviceInfoTests.get(), "layers",                                        "Layers",                                       enumerateDeviceLayers);
3674                 addFunctionCase(deviceInfoTests.get(), "extensions",                            "Extensions",                           enumerateDeviceExtensions);
3675
3676                 infoTests->addChild(deviceInfoTests.release());
3677         }
3678
3679         {
3680                 de::MovePtr<tcu::TestCaseGroup> deviceGroupInfoTests(new tcu::TestCaseGroup(testCtx, "device_group", "Device Group Information Tests"));
3681
3682                 addFunctionCase(deviceGroupInfoTests.get(), "peer_memory_features",     "Device Group peer memory features",                            deviceGroupPeerMemoryFeatures);
3683
3684                 infoTests->addChild(deviceGroupInfoTests.release());
3685         }
3686
3687         infoTests->addChild(createTestGroup(testCtx, "format_properties",               "VkGetPhysicalDeviceFormatProperties() Tests",          createFormatTests));
3688         infoTests->addChild(createTestGroup(testCtx, "image_format_properties", "VkGetPhysicalDeviceImageFormatProperties() Tests",     createImageFormatTests, imageFormatProperties));
3689
3690         {
3691                 de::MovePtr<tcu::TestCaseGroup> extendedPropertiesTests (new tcu::TestCaseGroup(testCtx, "get_physical_device_properties2", "VK_KHR_get_physical_device_properties2"));
3692
3693                 addFunctionCase(extendedPropertiesTests.get(), "features",                                      "Extended Device Features",                                     deviceFeatures2);
3694                 addFunctionCase(extendedPropertiesTests.get(), "properties",                            "Extended Device Properties",                           deviceProperties2);
3695                 addFunctionCase(extendedPropertiesTests.get(), "format_properties",                     "Extended Device Format Properties",            deviceFormatProperties2);
3696                 addFunctionCase(extendedPropertiesTests.get(), "queue_family_properties",       "Extended Device Queue Family Properties",      deviceQueueFamilyProperties2);
3697                 addFunctionCase(extendedPropertiesTests.get(), "memory_properties",                     "Extended Device Memory Properties",            deviceMemoryProperties2);
3698
3699                 infoTests->addChild(extendedPropertiesTests.release());
3700         }
3701
3702         infoTests->addChild(createTestGroup(testCtx, "image_format_properties2",                "VkGetPhysicalDeviceImageFormatProperties2() Tests",            createImageFormatTests, imageFormatProperties2));
3703         infoTests->addChild(createTestGroup(testCtx, "sparse_image_format_properties2", "VkGetPhysicalDeviceSparseImageFormatProperties2() Tests",      createImageFormatTests, sparseImageFormatProperties2));
3704
3705         {
3706                 de::MovePtr<tcu::TestCaseGroup> androidTests    (new tcu::TestCaseGroup(testCtx, "android", "Android CTS Tests"));
3707
3708                 addFunctionCase(androidTests.get(),     "mandatory_extensions",         "Test that all mandatory extensions are supported",     android::testMandatoryExtensions);
3709                 addFunctionCase(androidTests.get(), "no_unknown_extensions",    "Test for unknown device or instance extensions",       android::testNoUnknownExtensions);
3710                 addFunctionCase(androidTests.get(), "no_layers",                                "Test that no layers are enumerated",                           android::testNoLayers);
3711
3712                 infoTests->addChild(androidTests.release());
3713         }
3714
3715         return infoTests.release();
3716 }
3717
3718 } // api
3719 } // vkt