Merge vk-gl-cts/vulkan-cts-1.1.4 into vk-gl-cts/vulkan-cts-1.1.5
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / pipeline / vktPipelineExecutablePropertiesTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2019 The Khronos Group Inc.
6  * Copyright (c) 2019 Intel Corporation.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief VK_KHR_pipeline_executable_properties
23  *
24  * These tests creates compute and graphics pipelines with a variety of
25  * stages both with and without a pipeline cache and exercise the new
26  * queries provided by VK_KHR_pipeline_executable_properties.
27  *
28  * For each query type, it asserts that the query works and doesn't crash
29  * and returns consistent results:
30  *
31  *  - The tests assert that the same set of pipeline executables is
32  *    reported regardless of whether or not a pipeline cache is used.
33  *
34  *  - For each pipeline executable, the tests assert that the same set of
35  *    statistics is returned regardless of whether or not a pipeline cache
36  *    is used.
37  *
38  *  - For each pipeline executable, the tests assert that the same set of
39  *    statistics is returned regardless of whether or not
40  *    CAPTURE_INTERNAL_REPRESENTATIONS_BIT is set.
41  *
42  *  - For each pipeline executable, the tests assert that the same set of
43  *    internal representations is returned regardless of whether or not a
44  *    pipeline cache is used.
45  *
46  *  - For each string returned (statistic names, etc.) the tests assert
47  *    that the string is NULL terminated.
48  *
49  *  - For each statistic, the tests compare the results of the two
50  *    compilations and report any differences.  (Statistics differing
51  *    between two compilations is not considered a failure.)
52  *
53  *  - For each binary internal representation, the tests attempt to assert
54  *    that the amount of data returned by the implementation matches the
55  *    amount the implementation claims.  (It's impossible to exactly do
56  *    this but the tests give it a good try.)
57  *
58  * All of the returned data is recorded in the output file.
59  *
60  *//*--------------------------------------------------------------------*/
61
62 #include "vktPipelineExecutablePropertiesTests.hpp"
63 #include "vktPipelineVertexUtil.hpp"
64 #include "vktTestCase.hpp"
65 #include "vktTestCaseUtil.hpp"
66 #include "vkMemUtil.hpp"
67 #include "vkBuilderUtil.hpp"
68 #include "vkRefUtil.hpp"
69 #include "vkTypeUtil.hpp"
70 #include "vkObjUtil.hpp"
71 #include "tcuTestLog.hpp"
72
73 #include <sstream>
74 #include <vector>
75
76 namespace vkt
77 {
78 namespace pipeline
79 {
80
81 using namespace vk;
82
83 namespace
84 {
85 enum
86 {
87         VK_MAX_SHADER_STAGES = 6,
88 };
89
90 enum
91 {
92         PIPELINE_CACHE_NDX_INITIAL = 0,
93         PIPELINE_CACHE_NDX_CACHED = 1,
94         PIPELINE_CACHE_NDX_COUNT,
95 };
96
97 // helper functions
98
99 std::string getShaderFlagStr (const VkShaderStageFlagBits       shader,
100                                                           bool                                                  isDescription)
101 {
102         std::ostringstream desc;
103         switch(shader)
104         {
105                 case VK_SHADER_STAGE_VERTEX_BIT:
106                 {
107                         desc << ((isDescription) ? "vertex" : "vertex_stage");
108                         break;
109                 }
110                 case VK_SHADER_STAGE_FRAGMENT_BIT:
111                 {
112                         desc << ((isDescription) ? "fragment" : "fragment_stage");
113                         break;
114                 }
115                 case VK_SHADER_STAGE_GEOMETRY_BIT:
116                 {
117                         desc << ((isDescription) ? "geometry" : "geometry_stage");
118                         break;
119                 }
120                 case VK_SHADER_STAGE_COMPUTE_BIT:
121                 {
122                         desc << ((isDescription) ? "compute" : "compute_stage");
123                         break;
124                 }
125                 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
126                 {
127                         desc << ((isDescription) ? "tessellation control" : "tessellation_control_stage");
128                         break;
129                 }
130                 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
131                 {
132                         desc << ((isDescription) ? "tessellation evaluation" : "tessellation_evaluation_stage");
133                         break;
134                 }
135           default:
136                 desc << "unknown shader stage!";
137                 DE_FATAL("Unknown shader Stage!");
138                 break;
139         };
140
141         return desc.str();
142 }
143
144 std::string getShaderFlagsStr (const VkShaderStageFlags flags)
145 {
146         std::ostringstream stream;
147         bool empty = true;
148         for (deUint32 b = 0; b < 8 * sizeof(flags); b++)
149         {
150                 if (flags & (1u << b))
151                 {
152                         if (empty)
153                         {
154                                 empty = false;
155                         }
156                         else
157                         {
158                                 stream << ", ";
159                         }
160
161                         stream << getShaderFlagStr((VkShaderStageFlagBits)(1u << b), true);
162                 }
163         }
164
165         if (empty)
166         {
167                 stream << "none";
168         }
169
170         return stream.str();
171 }
172
173 // helper classes
174 class ExecutablePropertiesTestParam
175 {
176 public:
177                                                                 ExecutablePropertiesTestParam   (const VkShaderStageFlagBits*   shaders,
178                                                                                                                                  deUint32                                               count,
179                                                                                                                                  deBool                                                 testStatistics,
180                                                                                                                                  deBool                                                 testInternalRepresentations);
181         virtual                                         ~ExecutablePropertiesTestParam  (void);
182         virtual const std::string       generateTestName                                (void)                  const;
183         virtual const std::string       generateTestDescription                 (void)                  const;
184         VkShaderStageFlagBits           getShaderFlag                                   (deUint32 ndx)  const   { return m_shaders[ndx]; }
185         deUint32                                        getShaderCount                                  (void)                  const   { return (deUint32)m_shaderCount; }
186         deBool                                          getTestStatistics                               (void)                  const   { return m_testStatistics; }
187         deBool                                          getTestInternalRepresentations  (void)                  const   { return m_testInternalRepresentations; }
188
189 protected:
190         VkShaderStageFlagBits           m_shaders[VK_MAX_SHADER_STAGES];
191         size_t                                          m_shaderCount;
192         bool                                            m_testStatistics;
193         bool                                            m_testInternalRepresentations;
194 };
195
196 ExecutablePropertiesTestParam::ExecutablePropertiesTestParam (const VkShaderStageFlagBits* shaders, deUint32 count, deBool testStatistics, deBool testInternalRepresentations)
197 {
198         DE_ASSERT(count <= VK_MAX_SHADER_STAGES);
199         for (deUint32 ndx = 0; ndx < count; ndx++)
200                 m_shaders[ndx] = shaders[ndx];
201         m_shaderCount                                   = count;
202         m_testStatistics                                = testStatistics;
203         m_testInternalRepresentations   = testInternalRepresentations;
204 }
205
206 ExecutablePropertiesTestParam::~ExecutablePropertiesTestParam (void)
207 {
208 }
209
210 const std::string ExecutablePropertiesTestParam::generateTestName (void) const
211 {
212         std::string result(getShaderFlagStr(m_shaders[0], false));
213
214         for(deUint32 ndx = 1; ndx < m_shaderCount; ndx++)
215         {
216                 result += '_' + getShaderFlagStr(m_shaders[ndx], false);
217         }
218
219         if (m_testStatistics)
220         {
221                 result += "_statistics";
222         }
223
224         if (m_testInternalRepresentations)
225         {
226                 result += "_internal_representations";
227         }
228
229         return result;
230 }
231
232 const std::string ExecutablePropertiesTestParam::generateTestDescription (void) const
233 {
234         std::string result;
235         if (m_testStatistics)
236         {
237                 result += "Get pipeline executable statistics";
238                 if (m_testInternalRepresentations)
239                 {
240                         result += " and internal representations";
241                 }
242         }
243         else if (m_testInternalRepresentations)
244         {
245                 result += "Get pipeline executable internal representations";
246         }
247         else
248         {
249                 result += "Get pipeline executable properties";
250         }
251
252         result += " with " + getShaderFlagStr(m_shaders[0], true);
253
254         return result;
255 }
256
257 class SimpleGraphicsPipelineBuilder
258 {
259 public:
260                                                         SimpleGraphicsPipelineBuilder   (Context&                                               context);
261                                                         ~SimpleGraphicsPipelineBuilder  (void) { }
262         void                                    bindShaderStage                                 (VkShaderStageFlagBits                  stage,
263                                                                                                                          const char*                                    sourceName,
264                                                                                                                          const char*                                    entryName);
265         void                                    enableTessellationStage                 (deUint32                                               patchControlPoints);
266         VkPipeline                              buildPipeline                                   (tcu::UVec2                                             renderSize,
267                                                                                                                          VkRenderPass                                   renderPass,
268                                                                                                                          VkPipelineCache                                cache,
269                                                                                                                          VkPipelineLayout                               pipelineLayout,
270                                                                                                                          VkPipelineCreateFlags                  flags);
271         void                                    resetBuilder                                    (void);
272
273 protected:
274         Context&                                                        m_context;
275
276         Move<VkShaderModule>                            m_shaderModules[VK_MAX_SHADER_STAGES];
277         deUint32                                                        m_shaderStageCount;
278         VkPipelineShaderStageCreateInfo m_shaderStageInfo[VK_MAX_SHADER_STAGES];
279
280         deUint32                                                        m_patchControlPoints;
281 };
282
283 SimpleGraphicsPipelineBuilder::SimpleGraphicsPipelineBuilder (Context& context)
284         : m_context(context)
285 {
286         m_patchControlPoints = 0;
287         m_shaderStageCount   = 0;
288 }
289
290 void SimpleGraphicsPipelineBuilder::resetBuilder (void)
291 {
292         m_shaderStageCount = 0;
293 }
294
295 void SimpleGraphicsPipelineBuilder::bindShaderStage (VkShaderStageFlagBits      stage,
296                                                                                                          const char*                    sourceName,
297                                                                                                          const char*                    entryName)
298 {
299         const DeviceInterface&  vk                      = m_context.getDeviceInterface();
300         const VkDevice                  vkDevice        = m_context.getDevice();
301
302         // Create shader module
303         deUint32*                               code            = (deUint32*)m_context.getBinaryCollection().get(sourceName).getBinary();
304         deUint32                                codeSize        = (deUint32)m_context.getBinaryCollection().get(sourceName).getSize();
305
306         const VkShaderModuleCreateInfo moduleCreateInfo =
307         {
308                 VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,                            // VkStructureType                              sType;
309                 DE_NULL,                                                                                                        // const void*                                  pNext;
310                 0u,                                                                                                                     // VkShaderModuleCreateFlags    flags;
311                 codeSize,                                                                                                       // deUintptr                                    codeSize;
312                 code,                                                                                                           // const deUint32*                              pCode;
313         };
314
315         m_shaderModules[m_shaderStageCount] = createShaderModule(vk, vkDevice, &moduleCreateInfo);
316
317         // Prepare shader stage info
318         m_shaderStageInfo[m_shaderStageCount].sType                             = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
319         m_shaderStageInfo[m_shaderStageCount].pNext                             = DE_NULL;
320         m_shaderStageInfo[m_shaderStageCount].flags                             = 0u;
321         m_shaderStageInfo[m_shaderStageCount].stage                             = stage;
322         m_shaderStageInfo[m_shaderStageCount].module                            = *m_shaderModules[m_shaderStageCount];
323         m_shaderStageInfo[m_shaderStageCount].pName                             = entryName;
324         m_shaderStageInfo[m_shaderStageCount].pSpecializationInfo       = DE_NULL;
325
326         m_shaderStageCount++;
327 }
328
329 VkPipeline SimpleGraphicsPipelineBuilder::buildPipeline (tcu::UVec2 renderSize, VkRenderPass renderPass, VkPipelineCache cache,
330                                                                                                                  VkPipelineLayout pipelineLayout, VkPipelineCreateFlags flags)
331 {
332         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
333         const VkDevice                          vkDevice                        = m_context.getDevice();
334
335         // Create pipeline
336         const VkVertexInputBindingDescription vertexInputBindingDescription =
337         {
338                 0u,                                                                     // deUint32                             binding;
339                 sizeof(Vertex4RGBA),                            // deUint32                             strideInBytes;
340                 VK_VERTEX_INPUT_RATE_VERTEX,            // VkVertexInputRate    inputRate;
341         };
342
343         const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
344         {
345                 {
346                         0u,                                                                     // deUint32 location;
347                         0u,                                                                     // deUint32 binding;
348                         VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat format;
349                         0u                                                                      // deUint32 offsetInBytes;
350                 },
351                 {
352                         1u,                                                                     // deUint32 location;
353                         0u,                                                                     // deUint32 binding;
354                         VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat format;
355                         DE_OFFSET_OF(Vertex4RGBA, color),       // deUint32 offsetInBytes;
356                 }
357         };
358
359         const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
360         {
361                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                                                      sType;
362                 DE_NULL,                                                                                                                // const void*                                                          pNext;
363                 0u,                                                                                                                             // VkPipelineVertexInputStateCreateFlags        flags;
364                 1u,                                                                                                                             // deUint32                                                                     vertexBindingDescriptionCount;
365                 &vertexInputBindingDescription,                                                                 // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
366                 2u,                                                                                                                             // deUint32                                                                     vertexAttributeDescriptionCount;
367                 vertexInputAttributeDescriptions,                                                               // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
368         };
369
370         const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
371         {
372                 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                                      sType;
373                 DE_NULL,                                                                                                                // const void*                                                          pNext;
374                 0u,                                                                                                                             // VkPipelineInputAssemblyStateCreateFlags      flags;
375                 (m_patchControlPoints == 0 ? VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
376                                                                    : VK_PRIMITIVE_TOPOLOGY_PATCH_LIST), // VkPrimitiveTopology                                          topology;
377                 VK_FALSE,                                                                                                               // VkBool32                                                                     primitiveRestartEnable;
378         };
379
380         const VkViewport        viewport        = makeViewport(renderSize);
381         const VkRect2D          scissor = makeRect2D(renderSize);
382
383         const VkPipelineViewportStateCreateInfo viewportStateParams =
384         {
385                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,                  // VkStructureType                                              sType;
386                 DE_NULL,                                                                                                                // const void*                                                  pNext;
387                 0u,                                                                                                                             // VkPipelineViewportStateCreateFlags   flags;
388                 1u,                                                                                                                             // deUint32                                                             viewportCount;
389                 &viewport,                                                                                                              // const VkViewport*                                    pViewports;
390                 1u,                                                                                                                             // deUint32                                                             scissorCount;
391                 &scissor                                                                                                                // const VkRect2D*                                              pScissors;
392         };
393
394         const VkPipelineRasterizationStateCreateInfo rasterStateParams =
395         {
396                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
397                 DE_NULL,                                                                                                                // const void*                                                          pNext;
398                 0u,                                                                                                                             // VkPipelineRasterizationStateCreateFlags      flags;
399                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthClampEnable;
400                 VK_FALSE,                                                                                                               // VkBool32                                                                     rasterizerDiscardEnable;
401                 VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
402                 VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                      cullMode;
403                 VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
404                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
405                 0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
406                 0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
407                 0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
408                 1.0f,                                                                                                                   // float                                                                        lineWidth;
409         };
410
411         const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
412         {
413                 VK_FALSE,                                                                                                               // VkBool32             blendEnable;
414                 VK_BLEND_FACTOR_ONE,                                                                                    // VkBlendFactor        srcColorBlendFactor;
415                 VK_BLEND_FACTOR_ZERO,                                                                                   // VkBlendFactor        dstColorBlendFactor;
416                 VK_BLEND_OP_ADD,                                                                                                // VkBlendOp            colorBlendOp;
417                 VK_BLEND_FACTOR_ONE,                                                                                    // VkBlendFactor        srcAlphaBlendFactor;
418                 VK_BLEND_FACTOR_ZERO,                                                                                   // VkBlendFactor        dstAlphaBlendFactor;
419                 VK_BLEND_OP_ADD,                                                                                                // VkBlendOp            alphaBlendOp;
420                 VK_COLOR_COMPONENT_R_BIT |
421                 VK_COLOR_COMPONENT_G_BIT |
422                 VK_COLOR_COMPONENT_B_BIT |
423                 VK_COLOR_COMPONENT_A_BIT                                                                                // VkColorComponentFlags    colorWriteMask;
424         };
425
426         const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
427         {
428                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
429                 DE_NULL,                                                                                                        // const void*                                                                  pNext;
430                 0u,                                                                                                                     // VkPipelineColorBlendStateCreateFlags                 flags;
431                 VK_FALSE,                                                                                                       // VkBool32                                                                             logicOpEnable;
432                 VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
433                 1u,                                                                                                                     // deUint32                                                                             attachmentCount;
434                 &colorBlendAttachmentState,                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
435                 { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConst[4];
436         };
437
438         const VkPipelineMultisampleStateCreateInfo  multisampleStateParams      =
439         {
440                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
441                 DE_NULL,                                                                                                        // const void*                                                          pNext;
442                 0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
443                 VK_SAMPLE_COUNT_1_BIT,                                                                          // VkSampleCountFlagBits                                        rasterizationSamples;
444                 VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable;
445                 0.0f,                                                                                                           // float                                                                        minSampleShading;
446                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
447                 VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
448                 VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToOneEnable;
449         };
450
451         VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
452         {
453                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType                                                  sType;
454                 DE_NULL,                                                                                                        // const void*                                                          pNext;
455                 0u,                                                                                                                     // VkPipelineDepthStencilStateCreateFlags       flags;
456                 VK_TRUE,                                                                                                        // VkBool32                                                                     depthTestEnable;
457                 VK_TRUE,                                                                                                        // VkBool32                                                                     depthWriteEnable;
458                 VK_COMPARE_OP_LESS_OR_EQUAL,                                                            // VkCompareOp                                                          depthCompareOp;
459                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthBoundsTestEnable;
460                 VK_FALSE,                                                                                                       // VkBool32                                                                     stencilTestEnable;
461                 // VkStencilOpState front;
462                 {
463                         VK_STENCIL_OP_KEEP,             // VkStencilOp  failOp;
464                         VK_STENCIL_OP_KEEP,             // VkStencilOp  passOp;
465                         VK_STENCIL_OP_KEEP,             // VkStencilOp  depthFailOp;
466                         VK_COMPARE_OP_NEVER,    // VkCompareOp  compareOp;
467                         0u,                                             // deUint32             compareMask;
468                         0u,                                             // deUint32             writeMask;
469                         0u,                                             // deUint32             reference;
470                 },
471                 // VkStencilOpState back;
472                 {
473                         VK_STENCIL_OP_KEEP,             // VkStencilOp  failOp;
474                         VK_STENCIL_OP_KEEP,             // VkStencilOp  passOp;
475                         VK_STENCIL_OP_KEEP,             // VkStencilOp  depthFailOp;
476                         VK_COMPARE_OP_NEVER,    // VkCompareOp  compareOp;
477                         0u,                                             // deUint32             compareMask;
478                         0u,                                             // deUint32             writeMask;
479                         0u,                                             // deUint32             reference;
480                 },
481                 0.0f,                                                                                                           // float                                                                        minDepthBounds;
482                 1.0f,                                                                                                           // float                                                                        maxDepthBounds;
483         };
484
485         const VkPipelineTessellationStateCreateInfo tessStateCreateInfo =
486         {
487                 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,      // VkStructureType                                                      sType;
488                 DE_NULL,                                                                                                        // const void*                                                          pNext;
489                 0u,                                                                                                                     // VkPipelineTesselationStateCreateFlags        flags;
490                 m_patchControlPoints,                                                                           // deUint32                                                                     patchControlPoints;
491         };
492         const VkPipelineTessellationStateCreateInfo* pTessCreateInfo = (m_patchControlPoints > 0)
493                                                                                                                                   ? &tessStateCreateInfo
494                                                                                                                                   : DE_NULL;
495
496         const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
497         {
498                 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
499                 DE_NULL,                                                                                        // const void*                                                                          pNext;
500                 flags,                                                                                          // VkPipelineCreateFlags                                                        flags;
501                 m_shaderStageCount,                                                                     // deUint32                                                                                     stageCount;
502                 m_shaderStageInfo,                                                                      // const VkPipelineShaderStageCreateInfo*                       pStages;
503                 &vertexInputStateParams,                                                        // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
504                 &inputAssemblyStateParams,                                                      // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
505                 pTessCreateInfo,                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
506                 &viewportStateParams,                                                           // const VkPipelineViewportStateCreateInfo*                     pViewportState;
507                 &rasterStateParams,                                                                     // const VkPipelineRasterizationStateCreateInfo*        pRasterState;
508                 &multisampleStateParams,                                                        // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
509                 &depthStencilStateParams,                                                       // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
510                 &colorBlendStateParams,                                                         // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
511                 (const VkPipelineDynamicStateCreateInfo*)DE_NULL,       // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
512                 pipelineLayout,                                                                         // VkPipelineLayout                                                                     layout;
513                 renderPass,                                                                                     // VkRenderPass                                                                         renderPass;
514                 0u,                                                                                                     // deUint32                                                                                     subpass;
515                 DE_NULL,                                                                                        // VkPipeline                                                                           basePipelineHandle;
516                 0,                                                                                                      // deInt32                                                                                      basePipelineIndex;
517         };
518         VkPipeline pipeline;
519         vk.createGraphicsPipelines(vkDevice, cache, 1u, &graphicsPipelineParams, DE_NULL, &pipeline);
520         return pipeline;
521 }
522
523 void SimpleGraphicsPipelineBuilder::enableTessellationStage (deUint32 patchControlPoints)
524 {
525         m_patchControlPoints = patchControlPoints;
526 }
527
528 template <class Test>
529 vkt::TestCase* newTestCase (tcu::TestContext&           testContext,
530                                                         const ExecutablePropertiesTestParam*    testParam)
531 {
532         return new Test(testContext,
533                                         testParam->generateTestName().c_str(),
534                                         testParam->generateTestDescription().c_str(),
535                                         testParam);
536 }
537
538 // Test Classes
539 class ExecutablePropertiesTest : public vkt::TestCase
540 {
541 public:
542                                                         ExecutablePropertiesTest(tcu::TestContext&              testContext,
543                                                                                    const std::string&           name,
544                                                                                    const std::string&           description,
545                                                                                    const ExecutablePropertiesTestParam* param)
546                                                                 : vkt::TestCase (testContext, name, description)
547                                                                 , m_param (*param)
548                                                                 { }
549         virtual                                 ~ExecutablePropertiesTest (void) { }
550 protected:
551         const ExecutablePropertiesTestParam     m_param;
552 };
553
554 class ExecutablePropertiesTestInstance : public vkt::TestInstance
555 {
556 public:
557                                                         ExecutablePropertiesTestInstance                        (Context&                               context,
558                                                                                                                          const ExecutablePropertiesTestParam*   param);
559         virtual                                 ~ExecutablePropertiesTestInstance                       (void);
560         virtual tcu::TestStatus iterate                                                 (void);
561 protected:
562         virtual tcu::TestStatus verifyStatistics                                (deUint32 binaryNdx);
563         virtual tcu::TestStatus verifyInternalRepresentations   (deUint32 binaryNdx);
564         virtual tcu::TestStatus verifyTestResult                                (void);
565 protected:
566         const ExecutablePropertiesTestParam*    m_param;
567
568         Move<VkPipelineCache>   m_cache;
569         deBool                                  m_extensions;
570
571         VkPipeline                              m_pipeline[PIPELINE_CACHE_NDX_COUNT];
572 };
573
574 ExecutablePropertiesTestInstance::ExecutablePropertiesTestInstance (Context&                                    context,
575                                                                                                 const ExecutablePropertiesTestParam*    param)
576         : TestInstance          (context)
577         , m_param                       (param)
578         , m_extensions          (m_context.requireDeviceExtension("VK_KHR_pipeline_executable_properties"))
579 {
580         const DeviceInterface&  vk                              = m_context.getDeviceInterface();
581         const VkDevice                  vkDevice                = m_context.getDevice();
582
583         const VkPipelineCacheCreateInfo pipelineCacheCreateInfo =
584         {
585                 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,                   // VkStructureType                              sType;
586                 DE_NULL,                                                                                                // const void*                                  pNext;
587                 0u,                                                                                                             // VkPipelineCacheCreateFlags   flags;
588                 0u,                                                                                                             // deUintptr                                    initialDataSize;
589                 DE_NULL,                                                                                                // const void*                                  pInitialData;
590         };
591
592         m_cache = createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo);
593 }
594
595 ExecutablePropertiesTestInstance::~ExecutablePropertiesTestInstance (void)
596 {
597 }
598
599 tcu::TestStatus ExecutablePropertiesTestInstance::iterate (void)
600 {
601         return verifyTestResult();
602 }
603
604 bool
605 checkString(const char *string, size_t size)
606 {
607         size_t i = 0;
608         for (; i < size; i++)
609         {
610                 if (string[i] == 0)
611                 {
612                         break;
613                 }
614         }
615
616         // The string needs to be non-empty and null terminated
617         if (i == 0 || i >= size)
618         {
619                 return false;
620         }
621
622         // The rest of the string should be zero
623         for (; i < size; i++)
624         {
625                 if (string[i] != 0)
626                 {
627                         return false;
628                 }
629         }
630
631         return true;
632 }
633
634 tcu::TestStatus ExecutablePropertiesTestInstance::verifyStatistics (deUint32 executableNdx)
635 {
636         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
637         const VkDevice                          vkDevice        = m_context.getDevice();
638         tcu::TestLog                            &log            = m_context.getTestContext().getLog();
639
640         std::vector<VkPipelineExecutableStatisticKHR> statistics[PIPELINE_CACHE_NDX_COUNT];
641
642         for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
643         {
644                 const VkPipelineExecutableInfoKHR pipelineExecutableInfo =
645                 {
646                         VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR, // VkStructureType                                      sType;
647                         DE_NULL,                                                                                // const void*                                          pNext;
648                         m_pipeline[ndx],                                                                // VkPipeline                                           pipeline;
649                         executableNdx,                                                                  // uint32_t                                                     executableIndex;
650                 };
651
652                 deUint32 statisticCount = 0;
653                 VK_CHECK(vk.getPipelineExecutableStatisticsKHR(vkDevice, &pipelineExecutableInfo, &statisticCount, DE_NULL));
654
655                 if (statisticCount == 0)
656                 {
657                         continue;
658                 }
659
660                 statistics[ndx].resize(statisticCount);
661                 for (deUint32 statNdx = 0; statNdx < statisticCount; statNdx++)
662                 {
663                         deMemset(&statistics[ndx][statNdx], 0, sizeof(statistics[ndx][statNdx]));
664                         statistics[ndx][statNdx].sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR;
665                         statistics[ndx][statNdx].pNext = DE_NULL;
666                 }
667                 VK_CHECK(vk.getPipelineExecutableStatisticsKHR(vkDevice, &pipelineExecutableInfo, &statisticCount, &statistics[ndx][0]));
668
669                 for (deUint32 statNdx = 0; statNdx < statisticCount; statNdx++)
670                 {
671                         if (!checkString(statistics[ndx][statNdx].name, DE_LENGTH_OF_ARRAY(statistics[ndx][statNdx].name)))
672                         {
673                                 return tcu::TestStatus::fail("Invalid statistic name string");
674                         }
675
676                         for (deUint32 otherNdx = 0; otherNdx < statNdx; otherNdx++)
677                         {
678                                 if (deMemCmp(statistics[ndx][statNdx].name, statistics[ndx][otherNdx].name,
679                                                          DE_LENGTH_OF_ARRAY(statistics[ndx][statNdx].name)) == 0)
680                                 {
681                                         return tcu::TestStatus::fail("Statistic name string not unique within the executable");
682                                 }
683                         }
684
685                         if (!checkString(statistics[ndx][statNdx].description, DE_LENGTH_OF_ARRAY(statistics[ndx][statNdx].description)))
686                         {
687                                 return tcu::TestStatus::fail("Invalid statistic description string");
688                         }
689
690                         if (statistics[ndx][statNdx].format == VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR)
691                         {
692                                 if (statistics[ndx][statNdx].value.b32 != VK_TRUE && statistics[ndx][statNdx].value.b32 != VK_FALSE)
693                                 {
694                                         return tcu::TestStatus::fail("Boolean statistic is neither VK_TRUE nor VK_FALSE");
695                                 }
696                         }
697                 }
698         }
699
700         if (statistics[0].size() != statistics[1].size())
701         {
702                 return tcu::TestStatus::fail("Identical pipelines have different numbers of statistics");
703         }
704
705         if (statistics[0].size() == 0)
706         {
707                 return tcu::TestStatus::pass("No statistics reported");
708         }
709
710         // Both compiles had better have specified the same infos
711         for (deUint32 statNdx0 = 0; statNdx0 < statistics[0].size(); statNdx0++)
712         {
713                 deUint32 statNdx1 = 0;
714                 for (; statNdx1 < statistics[1].size(); statNdx1++)
715                 {
716                         if (deMemCmp(statistics[0][statNdx0].name, statistics[1][statNdx1].name,
717                                                  DE_LENGTH_OF_ARRAY(statistics[0][statNdx0].name)) == 0)
718                         {
719                                 break;
720                         }
721                 }
722                 if (statNdx1 >= statistics[1].size())
723                 {
724                         return tcu::TestStatus::fail("Identical pipelines have different statistics");
725                 }
726
727                 if (deMemCmp(statistics[0][statNdx0].description, statistics[1][statNdx1].description,
728                                          DE_LENGTH_OF_ARRAY(statistics[0][statNdx0].description)) != 0)
729                 {
730                         return tcu::TestStatus::fail("Invalid binary description string");
731                 }
732
733                 if (statistics[0][statNdx0].format != statistics[1][statNdx1].format)
734                 {
735                         return tcu::TestStatus::fail("Identical pipelines have statistics with different formats");
736                 }
737
738                 switch (statistics[0][statNdx0].format)
739                 {
740                         case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR:
741                         {
742                                 bool match = statistics[0][statNdx0].value.b32 == statistics[1][statNdx1].value.b32;
743                                 log << tcu::TestLog::Message
744                                         << statistics[0][statNdx0].name << ": "
745                                         << (statistics[0][statNdx0].value.b32 ? "VK_TRUE" : "VK_FALSE")
746                                         << (match ? "" : " (non-deterministic)")
747                                         << " (" << statistics[0][statNdx0].description << ")"
748                                         << tcu::TestLog::EndMessage;
749                                 break;
750                         }
751                         case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_INT64_KHR:
752                         {
753                                 bool match = statistics[0][statNdx0].value.i64 == statistics[1][statNdx1].value.i64;
754                                 log << tcu::TestLog::Message
755                                         << statistics[0][statNdx0].name << ": "
756                                         << statistics[0][statNdx0].value.i64
757                                         << (match ? "" : " (non-deterministic)")
758                                         << " (" << statistics[0][statNdx0].description << ")"
759                                         << tcu::TestLog::EndMessage;
760                                 break;
761                         }
762                         case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR:
763                         {
764                                 bool match = statistics[0][statNdx0].value.u64 == statistics[1][statNdx1].value.u64;
765                                 log << tcu::TestLog::Message
766                                         << statistics[0][statNdx0].name << ": "
767                                         << statistics[0][statNdx0].value.u64
768                                         << (match ? "" : " (non-deterministic)")
769                                         << " (" << statistics[0][statNdx0].description << ")"
770                                         << tcu::TestLog::EndMessage;
771                                 break;
772                         }
773                         case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_FLOAT64_KHR:
774                         {
775                                 bool match = statistics[0][statNdx0].value.f64 == statistics[1][statNdx1].value.f64;
776                                 log << tcu::TestLog::Message
777                                         << statistics[0][statNdx0].name << ": "
778                                         << statistics[0][statNdx0].value.f64
779                                         << (match ? "" : " (non-deterministic)")
780                                         << " (" << statistics[0][statNdx0].description << ")"
781                                         << tcu::TestLog::EndMessage;
782                                 break;
783                         }
784                         default:
785                                 return tcu::TestStatus::fail("Invalid statistic format");
786                 }
787         }
788
789         return tcu::TestStatus::pass("Pass");
790 }
791
792 tcu::TestStatus ExecutablePropertiesTestInstance::verifyInternalRepresentations (deUint32 executableNdx)
793 {
794         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
795         const VkDevice                          vkDevice        = m_context.getDevice();
796         tcu::TestLog                            &log            = m_context.getTestContext().getLog();
797
798         // We only care about internal representations on the second pipeline.
799         // We still compile twice to ensure that we still get the right thing
800         // even if the pipeline is hot in the cache.
801         const VkPipelineExecutableInfoKHR pipelineExecutableInfo =
802         {
803                 VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR, // VkStructureType                                      sType;
804                 DE_NULL,                                                                                // const void*                                          pNext;
805                 m_pipeline[1],                                                                  // VkPipeline                                           pipeline;
806                 executableNdx,                                                                  // uint32_t                                                     executableIndex;
807         };
808
809         std::vector<VkPipelineExecutableInternalRepresentationKHR> irs;
810         std::vector<std::vector<deUint8>> irDatas;
811
812         deUint32 irCount = 0;
813         VK_CHECK(vk.getPipelineExecutableInternalRepresentationsKHR(vkDevice, &pipelineExecutableInfo, &irCount, DE_NULL));
814
815         if (irCount == 0)
816         {
817                 return tcu::TestStatus::pass("No internal representations reported");
818         }
819
820         irs.resize(irCount);
821         irDatas.resize(irCount);
822         for (deUint32 irNdx = 0; irNdx < irCount; irNdx++)
823         {
824                 deMemset(&irs[irNdx], 0, sizeof(irs[irNdx]));
825                 irs[irNdx].sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR;
826                 irs[irNdx].pNext = DE_NULL;
827         }
828         VK_CHECK(vk.getPipelineExecutableInternalRepresentationsKHR(vkDevice, &pipelineExecutableInfo, &irCount, &irs[0]));
829
830         for (deUint32 irNdx = 0; irNdx < irCount; irNdx++)
831         {
832                 if (!checkString(irs[irNdx].name, DE_LENGTH_OF_ARRAY(irs[irNdx].name)))
833                 {
834                         return tcu::TestStatus::fail("Invalid internal representation name string");
835                 }
836
837                 for (deUint32 otherNdx = 0; otherNdx < irNdx; otherNdx++)
838                 {
839                         if (deMemCmp(irs[irNdx].name, irs[otherNdx].name,
840                                                  DE_LENGTH_OF_ARRAY(irs[irNdx].name)) == 0)
841                         {
842                                 return tcu::TestStatus::fail("Internal representation name string not unique within the executable");
843                         }
844                 }
845
846                 if (!checkString(irs[irNdx].description, DE_LENGTH_OF_ARRAY(irs[irNdx].description)))
847                 {
848                         return tcu::TestStatus::fail("Invalid binary description string");
849                 }
850
851                 if (irs[irNdx].dataSize == 0)
852                 {
853                         return tcu::TestStatus::fail("Internal representation has no data");
854                 }
855
856                 irDatas[irNdx].resize(irs[irNdx].dataSize);
857                 irs[irNdx].pData = &irDatas[irNdx][0];
858                 if (irs[irNdx].isText)
859                 {
860                         // For binary data the size is important.  We check that the
861                         // implementation fills the whole buffer by filling it with
862                         // garbage first and then looking for that same garbage later.
863                         for (size_t i = 0; i < irs[irNdx].dataSize; i++)
864                         {
865                                 irDatas[irNdx][i] = (deUint8)(37 * (17 + i));
866                         }
867                 }
868         }
869
870         VK_CHECK(vk.getPipelineExecutableInternalRepresentationsKHR(vkDevice, &pipelineExecutableInfo, &irCount, &irs[0]));
871
872         for (deUint32 irNdx = 0; irNdx < irCount; irNdx++)
873         {
874                 if (irs[irNdx].isText)
875                 {
876                         if (!checkString((char *)irs[irNdx].pData, irs[irNdx].dataSize))
877                         {
878                                 return tcu::TestStatus::fail("Textual internal representation isn't a valid string");
879                         }
880                         log << tcu::TestLog::Section(irs[irNdx].name, irs[irNdx].description)
881                                 << tcu::LogKernelSource((char *)irs[irNdx].pData)
882                                 << tcu::TestLog::EndSection;
883                 }
884                 else
885                 {
886                         size_t maxMatchingChunkSize = 0;
887                         size_t matchingChunkSize = 0;
888                         for (size_t i = 0; i < irs[irNdx].dataSize; i++)
889                         {
890                                 if (irDatas[irNdx][i] == (deUint8)(37 * (17 + i)))
891                                 {
892                                         matchingChunkSize++;
893                                         if (matchingChunkSize > maxMatchingChunkSize)
894                                         {
895                                                 maxMatchingChunkSize = matchingChunkSize;
896                                         }
897                                 }
898                                 else
899                                 {
900                                         matchingChunkSize = 0;
901                                 }
902                         }
903
904                         // 64 bytes of our random data still being in the buffer probably
905                         // isn't a coincidence
906                         if (matchingChunkSize == irs[irNdx].dataSize || matchingChunkSize >= 64)
907                         {
908                                 return tcu::TestStatus::fail("Implementation didn't fill the whole internal representation data buffer");
909                         }
910
911                         log << tcu::TestLog::Section(irs[irNdx].name, irs[irNdx].description)
912                                 << tcu::TestLog::Message << "Received " << irs[irNdx].dataSize << "B of binary data" << tcu::TestLog::EndMessage
913                                 << tcu::TestLog::EndSection;
914                 }
915         }
916
917         return tcu::TestStatus::pass("Pass");
918 }
919
920 tcu::TestStatus ExecutablePropertiesTestInstance::verifyTestResult (void)
921 {
922         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
923         const VkDevice                          vkDevice        = m_context.getDevice();
924         tcu::TestLog                            &log            = m_context.getTestContext().getLog();
925
926         std::vector<VkPipelineExecutablePropertiesKHR> props[PIPELINE_CACHE_NDX_COUNT];
927
928         for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
929         {
930                 const VkPipelineInfoKHR pipelineInfo =
931                 {
932                         VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR,    // VkStructureType                                      sType;
933                         DE_NULL,                                                                // const void*                                          pNext;
934                         m_pipeline[ndx],                                                // VkPipeline                                           pipeline;
935
936                 };
937                 deUint32 executableCount = 0;
938                 VK_CHECK(vk.getPipelineExecutablePropertiesKHR(vkDevice, &pipelineInfo, &executableCount, DE_NULL));
939
940                 if (executableCount == 0)
941                 {
942                         continue;
943                 }
944
945                 props[ndx].resize(executableCount);
946                 for (deUint32 execNdx = 0; execNdx < executableCount; execNdx++)
947                 {
948                         deMemset(&props[ndx][execNdx], 0, sizeof(props[ndx][execNdx]));
949                         props[ndx][execNdx].sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_PROPERTIES_KHR;
950                         props[ndx][execNdx].pNext = DE_NULL;
951                 }
952                 VK_CHECK(vk.getPipelineExecutablePropertiesKHR(vkDevice, &pipelineInfo, &executableCount, &props[ndx][0]));
953
954                 for (deUint32 execNdx = 0; execNdx < executableCount; execNdx++)
955                 {
956                         if (!checkString(props[ndx][execNdx].name, DE_LENGTH_OF_ARRAY(props[ndx][execNdx].name)))
957                         {
958                                 return tcu::TestStatus::fail("Invalid binary name string");
959                         }
960
961                         for (deUint32 otherNdx = 0; otherNdx < execNdx; otherNdx++)
962                         {
963                                 if (deMemCmp(props[ndx][execNdx].name, props[ndx][otherNdx].name,
964                                                          DE_LENGTH_OF_ARRAY(props[ndx][execNdx].name)) == 0)
965                                 {
966                                         return tcu::TestStatus::fail("Binary name string not unique within the pipeline");
967                                 }
968                         }
969
970                         if (!checkString(props[ndx][execNdx].description, DE_LENGTH_OF_ARRAY(props[ndx][execNdx].description)))
971                         {
972                                 return tcu::TestStatus::fail("Invalid binary description string");
973                         }
974
975                         // Check that the binary only contains stages actually used to
976                         // compile the pipeline
977                         VkShaderStageFlags stages = props[ndx][execNdx].stages;
978                         for (deUint32 stageNdx = 0; stageNdx < m_param->getShaderCount(); stageNdx++)
979                         {
980                                 stages &= ~m_param->getShaderFlag(stageNdx);
981                         }
982                         if (stages != 0)
983                         {
984                                 return tcu::TestStatus::fail("Binary uses unprovided stage");
985                         }
986                 }
987         }
988
989         if (props[0].size() != props[1].size())
990         {
991                 return tcu::TestStatus::fail("Identical pipelines have different numbers of props");
992         }
993
994         if (props[0].size() == 0)
995         {
996                 return tcu::TestStatus::pass("No executables reported");
997         }
998
999         // Both compiles had better have specified the same infos
1000         for (deUint32 execNdx0 = 0; execNdx0 < props[0].size(); execNdx0++)
1001         {
1002                 deUint32 execNdx1 = 0;
1003                 for (; execNdx1 < props[1].size(); execNdx1++)
1004                 {
1005                         if (deMemCmp(props[0][execNdx0].name, props[1][execNdx1].name,
1006                                                  DE_LENGTH_OF_ARRAY(props[0][execNdx0].name)) == 0)
1007                         {
1008                                 break;
1009                         }
1010                 }
1011                 if (execNdx1 >= props[1].size())
1012                 {
1013                         return tcu::TestStatus::fail("Identical pipelines have different sets of executables");
1014                 }
1015
1016                 if (deMemCmp(props[0][execNdx0].description, props[1][execNdx1].description,
1017                                          DE_LENGTH_OF_ARRAY(props[0][execNdx0].description)) != 0)
1018                 {
1019                         return tcu::TestStatus::fail("Same binary has different descriptions");
1020                 }
1021
1022                 if (props[0][execNdx0].stages != props[1][execNdx1].stages)
1023                 {
1024                         return tcu::TestStatus::fail("Same binary has different stages");
1025                 }
1026
1027                 if (props[0][execNdx0].subgroupSize != props[1][execNdx1].subgroupSize)
1028                 {
1029                         return tcu::TestStatus::fail("Same binary has different subgroup sizes");
1030                 }
1031         }
1032
1033         log << tcu::TestLog::Section("Binaries", "Binaries reported for this pipeline");
1034         log << tcu::TestLog::Message << "Pipeline reported " << props[0].size() << " props" << tcu::TestLog::EndMessage;
1035
1036         tcu::TestStatus status = tcu::TestStatus::pass("Pass");
1037         for (deUint32 execNdx = 0; execNdx < props[0].size(); execNdx++)
1038         {
1039                 log << tcu::TestLog::Section(props[0][execNdx].name, props[0][execNdx].description);
1040                 log << tcu::TestLog::Message << "Name: " << props[0][execNdx].name << tcu::TestLog::EndMessage;
1041                 log << tcu::TestLog::Message << "Description: " << props[0][execNdx].description << tcu::TestLog::EndMessage;
1042                 log << tcu::TestLog::Message << "Stages: " << getShaderFlagsStr(props[0][execNdx].stages) << tcu::TestLog::EndMessage;
1043                 log << tcu::TestLog::Message << "Subgroup Size: " << props[0][execNdx].subgroupSize << tcu::TestLog::EndMessage;
1044
1045                 if (m_param->getTestStatistics())
1046                 {
1047                         status = verifyStatistics(execNdx);
1048                         if (status.getCode() != QP_TEST_RESULT_PASS)
1049                         {
1050                                 log << tcu::TestLog::EndSection;
1051                                 break;
1052                         }
1053                 }
1054
1055                 if (m_param->getTestInternalRepresentations())
1056                 {
1057                         status = verifyInternalRepresentations(execNdx);
1058                         if (status.getCode() != QP_TEST_RESULT_PASS)
1059                         {
1060                                 log << tcu::TestLog::EndSection;
1061                                 break;
1062                         }
1063                 }
1064
1065                 log << tcu::TestLog::EndSection;
1066         }
1067
1068         log << tcu::TestLog::EndSection;
1069
1070         return status;
1071 }
1072
1073 class GraphicsExecutablePropertiesTest : public ExecutablePropertiesTest
1074 {
1075 public:
1076                                                         GraphicsExecutablePropertiesTest        (tcu::TestContext&              testContext,
1077                                                                                                          const std::string&     name,
1078                                                                                                          const std::string&     description,
1079                                                                                                          const ExecutablePropertiesTestParam*   param)
1080                                                                 : ExecutablePropertiesTest (testContext, name, description, param)
1081                                                                 { }
1082         virtual                                 ~GraphicsExecutablePropertiesTest       (void) { }
1083         virtual void                    initPrograms            (SourceCollections&     programCollection) const;
1084         virtual TestInstance*   createInstance          (Context&                               context) const;
1085 };
1086
1087 class GraphicsExecutablePropertiesTestInstance : public ExecutablePropertiesTestInstance
1088 {
1089 public:
1090                                                         GraphicsExecutablePropertiesTestInstance        (Context&                               context,
1091                                                                                                                          const ExecutablePropertiesTestParam*   param);
1092         virtual                                 ~GraphicsExecutablePropertiesTestInstance       (void);
1093 protected:
1094         const tcu::UVec2                                        m_renderSize;
1095         const VkFormat                                          m_colorFormat;
1096         const VkFormat                                          m_depthFormat;
1097         Move<VkPipelineLayout>                          m_pipelineLayout;
1098
1099         SimpleGraphicsPipelineBuilder           m_pipelineBuilder;
1100         SimpleGraphicsPipelineBuilder           m_missPipelineBuilder;
1101         Move<VkRenderPass>                                      m_renderPass;
1102 };
1103
1104 void GraphicsExecutablePropertiesTest::initPrograms (SourceCollections& programCollection) const
1105 {
1106         for (deUint32 shaderNdx = 0; shaderNdx < m_param.getShaderCount(); shaderNdx++)
1107         {
1108                 switch(m_param.getShaderFlag(shaderNdx))
1109                 {
1110                 case VK_SHADER_STAGE_VERTEX_BIT:
1111                         programCollection.glslSources.add("color_vert") << glu::VertexSource(
1112                                                 "#version 310 es\n"
1113                                                 "layout(location = 0) in vec4 position;\n"
1114                                                 "layout(location = 1) in vec4 color;\n"
1115                                                 "layout(location = 0) out highp vec4 vtxColor;\n"
1116                                                 "void main (void)\n"
1117                                                 "{\n"
1118                                                 "  gl_Position = position;\n"
1119                                                 "  vtxColor = color;\n"
1120                                                 "}\n");
1121                                         break;
1122                 case VK_SHADER_STAGE_FRAGMENT_BIT:
1123                         programCollection.glslSources.add("color_frag") << glu::FragmentSource(
1124                                                 "#version 310 es\n"
1125                                                 "layout(location = 0) in highp vec4 vtxColor;\n"
1126                                                 "layout(location = 0) out highp vec4 fragColor;\n"
1127                                                 "void main (void)\n"
1128                                                 "{\n"
1129                                                 "  fragColor = vtxColor;\n"
1130                                                 "}\n");
1131                         break;
1132
1133                 case VK_SHADER_STAGE_GEOMETRY_BIT:
1134                         programCollection.glslSources.add("dummy_geo") << glu::GeometrySource(
1135                                                 "#version 450 \n"
1136                                                 "layout(triangles) in;\n"
1137                                                 "layout(triangle_strip, max_vertices = 3) out;\n"
1138                                                 "layout(location = 0) in highp vec4 in_vtxColor[];\n"
1139                                                 "layout(location = 0) out highp vec4 vtxColor;\n"
1140                                                 "out gl_PerVertex { vec4 gl_Position; float gl_PointSize; };\n"
1141                                                 "in gl_PerVertex { vec4 gl_Position; float gl_PointSize; } gl_in[];\n"
1142                                                 "void main (void)\n"
1143                                                 "{\n"
1144                                                 "  for(int ndx=0; ndx<3; ndx++)\n"
1145                                                 "  {\n"
1146                                                 "    gl_Position = gl_in[ndx].gl_Position;\n"
1147                                                 "    gl_PointSize = gl_in[ndx].gl_PointSize;\n"
1148                                                 "    vtxColor    = in_vtxColor[ndx];\n"
1149                                                 "    EmitVertex();\n"
1150                                                 "  }\n"
1151                                                 "  EndPrimitive();\n"
1152                                                 "}\n");
1153                         break;
1154
1155                 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
1156                         programCollection.glslSources.add("basic_tcs") << glu::TessellationControlSource(
1157                                                 "#version 450 \n"
1158                                                 "layout(vertices = 3) out;\n"
1159                                                 "layout(location = 0) in highp vec4 color[];\n"
1160                                                 "layout(location = 0) out highp vec4 vtxColor[];\n"
1161                                                 "out gl_PerVertex { vec4 gl_Position; float gl_PointSize; } gl_out[3];\n"
1162                                                 "in gl_PerVertex { vec4 gl_Position; float gl_PointSize; } gl_in[gl_MaxPatchVertices];\n"
1163                                                 "void main()\n"
1164                                                 "{\n"
1165                                                 "  gl_TessLevelOuter[0] = 4.0;\n"
1166                                                 "  gl_TessLevelOuter[1] = 4.0;\n"
1167                                                 "  gl_TessLevelOuter[2] = 4.0;\n"
1168                                                 "  gl_TessLevelInner[0] = 4.0;\n"
1169                                                 "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1170                                                 "  gl_out[gl_InvocationID].gl_PointSize = gl_in[gl_InvocationID].gl_PointSize;\n"
1171                                                 "  vtxColor[gl_InvocationID] = color[gl_InvocationID];\n"
1172                                                 "}\n");
1173                                         break;
1174
1175                                 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
1176                                         programCollection.glslSources.add("basic_tes") << glu::TessellationEvaluationSource(
1177                                                 "#version 450 \n"
1178                                                 "layout(triangles, fractional_even_spacing, ccw) in;\n"
1179                                                 "layout(location = 0) in highp vec4 colors[];\n"
1180                                                 "layout(location = 0) out highp vec4 vtxColor;\n"
1181                                                 "out gl_PerVertex { vec4 gl_Position; float gl_PointSize; };\n"
1182                                                 "in gl_PerVertex { vec4 gl_Position; float gl_PointSize; } gl_in[gl_MaxPatchVertices];\n"
1183                                                 "void main() \n"
1184                                                 "{\n"
1185                                                 "  float u = gl_TessCoord.x;\n"
1186                                                 "  float v = gl_TessCoord.y;\n"
1187                                                 "  float w = gl_TessCoord.z;\n"
1188                                                 "  vec4 pos = vec4(0);\n"
1189                                                 "  vec4 color = vec4(0);\n"
1190                                                 "  pos.xyz += u * gl_in[0].gl_Position.xyz;\n"
1191                                                 "  color.xyz += u * colors[0].xyz;\n"
1192                                                 "  pos.xyz += v * gl_in[1].gl_Position.xyz;\n"
1193                                                 "  color.xyz += v * colors[1].xyz;\n"
1194                                                 "  pos.xyz += w * gl_in[2].gl_Position.xyz;\n"
1195                                                 "  color.xyz += w * colors[2].xyz;\n"
1196                                                 "  pos.w = 1.0;\n"
1197                                                 "  color.w = 1.0;\n"
1198                                                 "  gl_Position = pos;\n"
1199                                                 "  gl_PointSize = gl_in[0].gl_PointSize;"
1200                                                 "  vtxColor = color;\n"
1201                                                 "}\n");
1202                                         break;
1203
1204                                 default:
1205                                         DE_FATAL("Unknown Shader Stage!");
1206                                         break;
1207                 };
1208         }
1209 }
1210
1211 TestInstance* GraphicsExecutablePropertiesTest::createInstance (Context& context) const
1212 {
1213         return new GraphicsExecutablePropertiesTestInstance(context, &m_param);
1214 }
1215
1216 GraphicsExecutablePropertiesTestInstance::GraphicsExecutablePropertiesTestInstance (Context&                                    context,
1217                                                                                                                                 const ExecutablePropertiesTestParam*    param)
1218         : ExecutablePropertiesTestInstance              (context, param)
1219         , m_renderSize                  (32u, 32u)
1220         , m_colorFormat                 (VK_FORMAT_R8G8B8A8_UNORM)
1221         , m_depthFormat                 (VK_FORMAT_D16_UNORM)
1222         , m_pipelineBuilder             (context)
1223         , m_missPipelineBuilder (context)
1224 {
1225         const DeviceInterface&  vk                              = m_context.getDeviceInterface();
1226         const VkDevice                  vkDevice                = m_context.getDevice();
1227
1228         // Create pipeline layout
1229         {
1230                 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1231                 {
1232                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                                      sType;
1233                         DE_NULL,                                                                                        // const void*                                          pNext;
1234                         0u,                                                                                                     // VkPipelineLayoutCreateFlags          flags;
1235                         0u,                                                                                                     // deUint32                                                     setLayoutCount;
1236                         DE_NULL,                                                                                        // const VkDescriptorSetLayout*         pSetLayouts;
1237                         0u,                                                                                                     // deUint32                                                     pushConstantRangeCount;
1238                         DE_NULL                                                                                         // const VkPushConstantRange*           pPushConstantRanges;
1239                 };
1240
1241                 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1242         }
1243
1244         // Create render pass
1245         m_renderPass = makeRenderPass(vk, vkDevice, m_colorFormat, m_depthFormat);
1246
1247         // Bind shader stages
1248
1249         VkPhysicalDeviceFeatures        features = m_context.getDeviceFeatures();
1250         for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
1251         {
1252                 for (deUint32 shaderNdx = 0; shaderNdx < m_param->getShaderCount(); shaderNdx++)
1253                 {
1254                         switch(m_param->getShaderFlag(shaderNdx))
1255                         {
1256                         case VK_SHADER_STAGE_VERTEX_BIT:
1257                                 m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_VERTEX_BIT, "color_vert", "main");
1258                                 break;
1259                         case VK_SHADER_STAGE_FRAGMENT_BIT:
1260                                 m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_FRAGMENT_BIT, "color_frag", "main");
1261                                 break;
1262                         case VK_SHADER_STAGE_GEOMETRY_BIT:
1263                                 if (features.geometryShader == VK_FALSE)
1264                                 {
1265                                         TCU_THROW(NotSupportedError, "Geometry Shader Not Supported");
1266                                 }
1267                                 else
1268                                 {
1269                                         m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_GEOMETRY_BIT, "dummy_geo", "main");
1270                                 }
1271                                 break;
1272                         case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
1273                                 if (features.tessellationShader == VK_FALSE)
1274                                 {
1275                                         TCU_THROW(NotSupportedError, "Tessellation Not Supported");
1276                                 }
1277                                 else
1278                                 {
1279                                         m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "basic_tcs", "main");
1280                                         m_pipelineBuilder.enableTessellationStage(3);
1281                                 }
1282                                 break;
1283                         case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
1284                                 if (features.tessellationShader == VK_FALSE)
1285                                 {
1286                                         TCU_THROW(NotSupportedError, "Tessellation Not Supported");
1287                                 }
1288                                 else
1289                                 {
1290                                         m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "basic_tes", "main");
1291                                         m_pipelineBuilder.enableTessellationStage(3);
1292                                 }
1293                                 break;
1294                         default:
1295                                 DE_FATAL("Unknown Shader Stage!");
1296                                 break;
1297                         };
1298
1299                 }
1300
1301                 VkPipelineCreateFlags flags = 0;
1302                 if (param->getTestStatistics())
1303                 {
1304                         flags |= VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR;
1305                 }
1306
1307                 // Only check gather internal representations on the second
1308                 // pipeline.  This way, it's more obvious if they failed to capture
1309                 // due to the pipeline being cached.
1310                 if (ndx == PIPELINE_CACHE_NDX_CACHED && param->getTestInternalRepresentations())
1311                 {
1312                         flags |= VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR;
1313                 }
1314
1315                 m_pipeline[ndx] = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass, *m_cache, *m_pipelineLayout, flags);
1316                 m_pipelineBuilder.resetBuilder();
1317         }
1318 }
1319
1320 GraphicsExecutablePropertiesTestInstance::~GraphicsExecutablePropertiesTestInstance (void)
1321 {
1322 }
1323
1324 class ComputeExecutablePropertiesTest : public ExecutablePropertiesTest
1325 {
1326 public:
1327                                                         ComputeExecutablePropertiesTest (tcu::TestContext&              testContext,
1328                                                                                                          const std::string&             name,
1329                                                                                                          const std::string&             description,
1330                                                                                                          const ExecutablePropertiesTestParam*   param)
1331                                                                 : ExecutablePropertiesTest      (testContext, name, description, param)
1332                                                                 { }
1333         virtual                                 ~ComputeExecutablePropertiesTest        (void) { }
1334         virtual void                    initPrograms                    (SourceCollections&     programCollection) const;
1335         virtual TestInstance*   createInstance                  (Context&                               context) const;
1336 };
1337
1338 class ComputeExecutablePropertiesTestInstance : public ExecutablePropertiesTestInstance
1339 {
1340 public:
1341                                                         ComputeExecutablePropertiesTestInstance (Context&                               context,
1342                                                                                                                          const ExecutablePropertiesTestParam*   param);
1343         virtual                                 ~ComputeExecutablePropertiesTestInstance        (void);
1344 protected:
1345         void                                    buildDescriptorSets                             (deUint32 ndx);
1346         void                                    buildShader                                             (deUint32 ndx);
1347         void                                    buildPipeline                                   (deUint32 ndx);
1348 protected:
1349         Move<VkBuffer>                                  m_inputBuf;
1350         de::MovePtr<Allocation>         m_inputBufferAlloc;
1351         Move<VkShaderModule>                    m_computeShaderModule[PIPELINE_CACHE_NDX_COUNT];
1352
1353         Move<VkBuffer>                                  m_outputBuf[PIPELINE_CACHE_NDX_COUNT];
1354         de::MovePtr<Allocation>         m_outputBufferAlloc[PIPELINE_CACHE_NDX_COUNT];
1355
1356         Move<VkDescriptorPool>                  m_descriptorPool[PIPELINE_CACHE_NDX_COUNT];
1357         Move<VkDescriptorSetLayout>     m_descriptorSetLayout[PIPELINE_CACHE_NDX_COUNT];
1358         Move<VkDescriptorSet>                   m_descriptorSet[PIPELINE_CACHE_NDX_COUNT];
1359
1360         Move<VkPipelineLayout>                  m_pipelineLayout[PIPELINE_CACHE_NDX_COUNT];
1361 };
1362
1363 void ComputeExecutablePropertiesTest::initPrograms (SourceCollections& programCollection) const
1364 {
1365         programCollection.glslSources.add("basic_compute") << glu::ComputeSource(
1366                 "#version 310 es\n"
1367                 "layout(local_size_x = 1) in;\n"
1368                 "layout(std430) buffer;\n"
1369                 "layout(binding = 0) readonly buffer Input0\n"
1370                 "{\n"
1371                 "  vec4 elements[];\n"
1372                 "} input_data0;\n"
1373                 "layout(binding = 1) writeonly buffer Output\n"
1374                 "{\n"
1375                 "  vec4 elements[];\n"
1376                 "} output_data;\n"
1377                 "void main()\n"
1378                 "{\n"
1379                 "  uint ident = gl_GlobalInvocationID.x;\n"
1380                 "  output_data.elements[ident] = input_data0.elements[ident] * input_data0.elements[ident];\n"
1381                 "}");
1382 }
1383
1384 TestInstance* ComputeExecutablePropertiesTest::createInstance (Context& context) const
1385 {
1386         return new ComputeExecutablePropertiesTestInstance(context, &m_param);
1387 }
1388
1389 void ComputeExecutablePropertiesTestInstance::buildDescriptorSets (deUint32 ndx)
1390 {
1391         const DeviceInterface&  vk                              = m_context.getDeviceInterface();
1392         const VkDevice                  vkDevice                = m_context.getDevice();
1393
1394         // Create descriptor set layout
1395         DescriptorSetLayoutBuilder descLayoutBuilder;
1396         for (deUint32 bindingNdx = 0u; bindingNdx < 2u; bindingNdx++)
1397                 descLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
1398         m_descriptorSetLayout[ndx] = descLayoutBuilder.build(vk, vkDevice);
1399 }
1400
1401 void ComputeExecutablePropertiesTestInstance::buildShader (deUint32 ndx)
1402 {
1403         const DeviceInterface&  vk                              = m_context.getDeviceInterface();
1404         const VkDevice                  vkDevice                = m_context.getDevice();
1405
1406         // Create compute shader
1407         VkShaderModuleCreateInfo shaderModuleCreateInfo =
1408         {
1409                 VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,                                                                    // VkStructureType                              sType;
1410                 DE_NULL,                                                                                                                                                // const void*                                  pNext;
1411                 0u,                                                                                                                                                             // VkShaderModuleCreateFlags    flags;
1412                 m_context.getBinaryCollection().get("basic_compute").getSize(),                                 // deUintptr                                    codeSize;
1413                 (deUint32*)m_context.getBinaryCollection().get("basic_compute").getBinary(),    // const deUint32*                              pCode;
1414         };
1415         m_computeShaderModule[ndx] = createShaderModule(vk, vkDevice, &shaderModuleCreateInfo);
1416 }
1417
1418 void ComputeExecutablePropertiesTestInstance::buildPipeline (deUint32 ndx)
1419 {
1420         const DeviceInterface&  vk                               = m_context.getDeviceInterface();
1421         const VkDevice                  vkDevice                 = m_context.getDevice();
1422
1423         // Create compute pipeline layout
1424         const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
1425         {
1426                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,                                  // VkStructureType                                      sType;
1427                 DE_NULL,                                                                                                                // const void*                                          pNext;
1428                 0u,                                                                                                                             // VkPipelineLayoutCreateFlags          flags;
1429                 1u,                                                                                                                             // deUint32                                                     setLayoutCount;
1430                 &m_descriptorSetLayout[ndx].get(),                                                              // const VkDescriptorSetLayout*         pSetLayouts;
1431                 0u,                                                                                                                             // deUint32                                                     pushConstantRangeCount;
1432                 DE_NULL,                                                                                                                // const VkPushConstantRange*           pPushConstantRanges;
1433         };
1434
1435         m_pipelineLayout[ndx] = createPipelineLayout(vk, vkDevice, &pipelineLayoutCreateInfo);
1436
1437         const VkPipelineShaderStageCreateInfo stageCreateInfo =
1438         {
1439                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,                    // VkStructureType                                      sType;
1440                 DE_NULL,                                                                                                                // const void*                                          pNext;
1441                 0u,                                                                                                                             // VkPipelineShaderStageCreateFlags     flags;
1442                 VK_SHADER_STAGE_COMPUTE_BIT,                                                                    // VkShaderStageFlagBits                        stage;
1443                 *m_computeShaderModule[ndx],                                                                    // VkShaderModule                                       module;
1444                 "main",                                                                                                                 // const char*                                          pName;
1445                 DE_NULL,                                                                                                                // const VkSpecializationInfo*          pSpecializationInfo;
1446         };
1447
1448         VkPipelineCreateFlags flags = 0;
1449         if (m_param->getTestStatistics())
1450         {
1451                 flags |= VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR;
1452         }
1453
1454         // Only check gather internal representations on the second
1455         // pipeline.  This way, it's more obvious if they failed to capture
1456         // due to the pipeline being cached.
1457         if (ndx == PIPELINE_CACHE_NDX_CACHED && m_param->getTestInternalRepresentations())
1458         {
1459                 flags |= VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR;
1460         }
1461
1462         const VkComputePipelineCreateInfo pipelineCreateInfo =
1463         {
1464                 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,                         // VkStructureType                                      sType;
1465                 DE_NULL,                                                                                                        // const void*                                          pNext;
1466                 flags,                                                                                                          // VkPipelineCreateFlags                        flags;
1467                 stageCreateInfo,                                                                                        // VkPipelineShaderStageCreateInfo      stage;
1468                 *m_pipelineLayout[ndx],                                                                         // VkPipelineLayout                                     layout;
1469                 (VkPipeline)0,                                                                                          // VkPipeline                                           basePipelineHandle;
1470                 0u,                                                                                                                     // deInt32                                                      basePipelineIndex;
1471         };
1472
1473         vk.createComputePipelines(vkDevice, *m_cache, 1u, &pipelineCreateInfo, DE_NULL, &m_pipeline[ndx]);
1474 }
1475
1476 ComputeExecutablePropertiesTestInstance::ComputeExecutablePropertiesTestInstance (Context&                              context,
1477                                                                                                         const ExecutablePropertiesTestParam*    param)
1478         : ExecutablePropertiesTestInstance (context, param)
1479 {
1480         for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
1481         {
1482                 buildDescriptorSets(ndx);
1483                 buildShader(ndx);
1484                 buildPipeline(ndx);
1485         }
1486 }
1487
1488 ComputeExecutablePropertiesTestInstance::~ComputeExecutablePropertiesTestInstance (void)
1489 {
1490 }
1491
1492 } // anonymous
1493
1494 tcu::TestCaseGroup* createExecutablePropertiesTests (tcu::TestContext& testCtx)
1495 {
1496
1497         de::MovePtr<tcu::TestCaseGroup> binaryInfoTests (new tcu::TestCaseGroup(testCtx, "executable_properties", "pipeline binary statistics tests"));
1498
1499         // Graphics Pipeline Tests
1500         {
1501                 de::MovePtr<tcu::TestCaseGroup> graphicsTests (new tcu::TestCaseGroup(testCtx, "graphics", "Test pipeline binary info with graphics pipeline."));
1502
1503                 const VkShaderStageFlagBits testParamShaders0[] =
1504                 {
1505                         VK_SHADER_STAGE_VERTEX_BIT,
1506                         VK_SHADER_STAGE_FRAGMENT_BIT,
1507                 };
1508                 const VkShaderStageFlagBits testParamShaders1[] =
1509                 {
1510                         VK_SHADER_STAGE_VERTEX_BIT,
1511                         VK_SHADER_STAGE_GEOMETRY_BIT,
1512                         VK_SHADER_STAGE_FRAGMENT_BIT,
1513                 };
1514                 const VkShaderStageFlagBits testParamShaders2[] =
1515                 {
1516                         VK_SHADER_STAGE_VERTEX_BIT,
1517                         VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
1518                         VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
1519                         VK_SHADER_STAGE_FRAGMENT_BIT,
1520                 };
1521                 const ExecutablePropertiesTestParam testParams[] =
1522                 {
1523                         ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE, DE_FALSE),
1524                         ExecutablePropertiesTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), DE_FALSE, DE_FALSE),
1525                         ExecutablePropertiesTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), DE_FALSE, DE_FALSE),
1526                         ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_TRUE, DE_FALSE),
1527                         ExecutablePropertiesTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), DE_TRUE, DE_FALSE),
1528                         ExecutablePropertiesTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), DE_TRUE, DE_FALSE),
1529                         ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE, DE_TRUE),
1530                         ExecutablePropertiesTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), DE_FALSE, DE_TRUE),
1531                         ExecutablePropertiesTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), DE_FALSE, DE_TRUE),
1532                         ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_TRUE, DE_TRUE),
1533                         ExecutablePropertiesTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), DE_TRUE, DE_TRUE),
1534                         ExecutablePropertiesTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), DE_TRUE, DE_TRUE),
1535                 };
1536
1537                 for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
1538                         graphicsTests->addChild(newTestCase<GraphicsExecutablePropertiesTest>(testCtx, &testParams[i]));
1539
1540                 binaryInfoTests->addChild(graphicsTests.release());
1541         }
1542
1543         // Compute Pipeline Tests
1544         {
1545                 de::MovePtr<tcu::TestCaseGroup> computeTests (new tcu::TestCaseGroup(testCtx, "compute", "Test pipeline binary info with compute pipeline."));
1546
1547                 const VkShaderStageFlagBits testParamShaders0[] =
1548                 {
1549                         VK_SHADER_STAGE_COMPUTE_BIT,
1550                 };
1551                 const ExecutablePropertiesTestParam testParams[] =
1552                 {
1553                         ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE, DE_FALSE),
1554                         ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_TRUE, DE_FALSE),
1555                         ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE, DE_TRUE),
1556                         ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_TRUE, DE_TRUE),
1557                 };
1558
1559                 for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
1560                         computeTests->addChild(newTestCase<ComputeExecutablePropertiesTest>(testCtx, &testParams[i]));
1561
1562                 binaryInfoTests->addChild(computeTests.release());
1563         }
1564
1565         return binaryInfoTests.release();
1566 }
1567
1568 } // pipeline
1569
1570 } // vkt