3e58d292383d1350f40af8bd53165e92bec76918
[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         Move<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 Move<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
519         return createGraphicsPipeline(vk, vkDevice, cache, &graphicsPipelineParams, DE_NULL);
520 }
521
522 void SimpleGraphicsPipelineBuilder::enableTessellationStage (deUint32 patchControlPoints)
523 {
524         m_patchControlPoints = patchControlPoints;
525 }
526
527 template <class Test>
528 vkt::TestCase* newTestCase (tcu::TestContext&           testContext,
529                                                         const ExecutablePropertiesTestParam*    testParam)
530 {
531         return new Test(testContext,
532                                         testParam->generateTestName().c_str(),
533                                         testParam->generateTestDescription().c_str(),
534                                         testParam);
535 }
536
537 // Test Classes
538 class ExecutablePropertiesTest : public vkt::TestCase
539 {
540 public:
541                                                         ExecutablePropertiesTest(tcu::TestContext&              testContext,
542                                                                                    const std::string&           name,
543                                                                                    const std::string&           description,
544                                                                                    const ExecutablePropertiesTestParam* param)
545                                                                 : vkt::TestCase (testContext, name, description)
546                                                                 , m_param (*param)
547                                                                 { }
548         virtual                                 ~ExecutablePropertiesTest (void) { }
549 protected:
550         const ExecutablePropertiesTestParam     m_param;
551 };
552
553 class ExecutablePropertiesTestInstance : public vkt::TestInstance
554 {
555 public:
556                                                         ExecutablePropertiesTestInstance                        (Context&                               context,
557                                                                                                                          const ExecutablePropertiesTestParam*   param);
558         virtual                                 ~ExecutablePropertiesTestInstance                       (void);
559         virtual tcu::TestStatus iterate                                                 (void);
560 protected:
561         virtual tcu::TestStatus verifyStatistics                                (deUint32 binaryNdx);
562         virtual tcu::TestStatus verifyInternalRepresentations   (deUint32 binaryNdx);
563         virtual tcu::TestStatus verifyTestResult                                (void);
564 protected:
565         const ExecutablePropertiesTestParam*    m_param;
566
567         Move<VkPipelineCache>   m_cache;
568         deBool                                  m_extensions;
569
570         Move<VkPipeline>                m_pipeline[PIPELINE_CACHE_NDX_COUNT];
571 };
572
573 ExecutablePropertiesTestInstance::ExecutablePropertiesTestInstance (Context&                                    context,
574                                                                                                 const ExecutablePropertiesTestParam*    param)
575         : TestInstance          (context)
576         , m_param                       (param)
577         , m_extensions          (m_context.requireDeviceFunctionality("VK_KHR_pipeline_executable_properties"))
578 {
579         const DeviceInterface&  vk                              = m_context.getDeviceInterface();
580         const VkDevice                  vkDevice                = m_context.getDevice();
581
582         const VkPipelineCacheCreateInfo pipelineCacheCreateInfo =
583         {
584                 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,                   // VkStructureType                              sType;
585                 DE_NULL,                                                                                                // const void*                                  pNext;
586                 0u,                                                                                                             // VkPipelineCacheCreateFlags   flags;
587                 0u,                                                                                                             // deUintptr                                    initialDataSize;
588                 DE_NULL,                                                                                                // const void*                                  pInitialData;
589         };
590
591         m_cache = createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo);
592 }
593
594 ExecutablePropertiesTestInstance::~ExecutablePropertiesTestInstance (void)
595 {
596 }
597
598 tcu::TestStatus ExecutablePropertiesTestInstance::iterate (void)
599 {
600         return verifyTestResult();
601 }
602
603 bool
604 checkString(const char *string, size_t size)
605 {
606         size_t i = 0;
607         for (; i < size; i++)
608         {
609                 if (string[i] == 0)
610                 {
611                         break;
612                 }
613         }
614
615         // The string needs to be non-empty and null terminated
616         if (i == 0 || i >= size)
617         {
618                 return false;
619         }
620
621         return true;
622 }
623
624 tcu::TestStatus ExecutablePropertiesTestInstance::verifyStatistics (deUint32 executableNdx)
625 {
626         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
627         const VkDevice                          vkDevice        = m_context.getDevice();
628         tcu::TestLog                            &log            = m_context.getTestContext().getLog();
629
630         std::vector<VkPipelineExecutableStatisticKHR> statistics[PIPELINE_CACHE_NDX_COUNT];
631
632         for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
633         {
634                 const VkPipelineExecutableInfoKHR pipelineExecutableInfo =
635                 {
636                         VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR, // VkStructureType                                      sType;
637                         DE_NULL,                                                                                // const void*                                          pNext;
638                         *m_pipeline[ndx],                                                               // VkPipeline                                           pipeline;
639                         executableNdx,                                                                  // uint32_t                                                     executableIndex;
640                 };
641
642                 deUint32 statisticCount = 0;
643                 VK_CHECK(vk.getPipelineExecutableStatisticsKHR(vkDevice, &pipelineExecutableInfo, &statisticCount, DE_NULL));
644
645                 if (statisticCount == 0)
646                 {
647                         continue;
648                 }
649
650                 statistics[ndx].resize(statisticCount);
651                 for (deUint32 statNdx = 0; statNdx < statisticCount; statNdx++)
652                 {
653                         deMemset(&statistics[ndx][statNdx], 0, sizeof(statistics[ndx][statNdx]));
654                         statistics[ndx][statNdx].sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR;
655                         statistics[ndx][statNdx].pNext = DE_NULL;
656                 }
657                 VK_CHECK(vk.getPipelineExecutableStatisticsKHR(vkDevice, &pipelineExecutableInfo, &statisticCount, &statistics[ndx][0]));
658
659                 for (deUint32 statNdx = 0; statNdx < statisticCount; statNdx++)
660                 {
661                         if (!checkString(statistics[ndx][statNdx].name, DE_LENGTH_OF_ARRAY(statistics[ndx][statNdx].name)))
662                         {
663                                 return tcu::TestStatus::fail("Invalid statistic name string");
664                         }
665
666                         for (deUint32 otherNdx = 0; otherNdx < statNdx; otherNdx++)
667                         {
668                                 if (deMemCmp(statistics[ndx][statNdx].name, statistics[ndx][otherNdx].name,
669                                                          DE_LENGTH_OF_ARRAY(statistics[ndx][statNdx].name)) == 0)
670                                 {
671                                         return tcu::TestStatus::fail("Statistic name string not unique within the executable");
672                                 }
673                         }
674
675                         if (!checkString(statistics[ndx][statNdx].description, DE_LENGTH_OF_ARRAY(statistics[ndx][statNdx].description)))
676                         {
677                                 return tcu::TestStatus::fail("Invalid statistic description string");
678                         }
679
680                         if (statistics[ndx][statNdx].format == VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR)
681                         {
682                                 if (statistics[ndx][statNdx].value.b32 != VK_TRUE && statistics[ndx][statNdx].value.b32 != VK_FALSE)
683                                 {
684                                         return tcu::TestStatus::fail("Boolean statistic is neither VK_TRUE nor VK_FALSE");
685                                 }
686                         }
687                 }
688         }
689
690         if (statistics[0].size() != statistics[1].size())
691         {
692                 return tcu::TestStatus::fail("Identical pipelines have different numbers of statistics");
693         }
694
695         if (statistics[0].size() == 0)
696         {
697                 return tcu::TestStatus::pass("No statistics reported");
698         }
699
700         // Both compiles had better have specified the same infos
701         for (deUint32 statNdx0 = 0; statNdx0 < statistics[0].size(); statNdx0++)
702         {
703                 deUint32 statNdx1 = 0;
704                 for (; statNdx1 < statistics[1].size(); statNdx1++)
705                 {
706                         if (deMemCmp(statistics[0][statNdx0].name, statistics[1][statNdx1].name,
707                                                  DE_LENGTH_OF_ARRAY(statistics[0][statNdx0].name)) == 0)
708                         {
709                                 break;
710                         }
711                 }
712                 if (statNdx1 >= statistics[1].size())
713                 {
714                         return tcu::TestStatus::fail("Identical pipelines have different statistics");
715                 }
716
717                 if (deMemCmp(statistics[0][statNdx0].description, statistics[1][statNdx1].description,
718                                          DE_LENGTH_OF_ARRAY(statistics[0][statNdx0].description)) != 0)
719                 {
720                         return tcu::TestStatus::fail("Invalid binary description string");
721                 }
722
723                 if (statistics[0][statNdx0].format != statistics[1][statNdx1].format)
724                 {
725                         return tcu::TestStatus::fail("Identical pipelines have statistics with different formats");
726                 }
727
728                 switch (statistics[0][statNdx0].format)
729                 {
730                         case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR:
731                         {
732                                 bool match = statistics[0][statNdx0].value.b32 == statistics[1][statNdx1].value.b32;
733                                 log << tcu::TestLog::Message
734                                         << statistics[0][statNdx0].name << ": "
735                                         << (statistics[0][statNdx0].value.b32 ? "VK_TRUE" : "VK_FALSE")
736                                         << (match ? "" : " (non-deterministic)")
737                                         << " (" << statistics[0][statNdx0].description << ")"
738                                         << tcu::TestLog::EndMessage;
739                                 break;
740                         }
741                         case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_INT64_KHR:
742                         {
743                                 bool match = statistics[0][statNdx0].value.i64 == statistics[1][statNdx1].value.i64;
744                                 log << tcu::TestLog::Message
745                                         << statistics[0][statNdx0].name << ": "
746                                         << statistics[0][statNdx0].value.i64
747                                         << (match ? "" : " (non-deterministic)")
748                                         << " (" << statistics[0][statNdx0].description << ")"
749                                         << tcu::TestLog::EndMessage;
750                                 break;
751                         }
752                         case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR:
753                         {
754                                 bool match = statistics[0][statNdx0].value.u64 == statistics[1][statNdx1].value.u64;
755                                 log << tcu::TestLog::Message
756                                         << statistics[0][statNdx0].name << ": "
757                                         << statistics[0][statNdx0].value.u64
758                                         << (match ? "" : " (non-deterministic)")
759                                         << " (" << statistics[0][statNdx0].description << ")"
760                                         << tcu::TestLog::EndMessage;
761                                 break;
762                         }
763                         case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_FLOAT64_KHR:
764                         {
765                                 bool match = statistics[0][statNdx0].value.f64 == statistics[1][statNdx1].value.f64;
766                                 log << tcu::TestLog::Message
767                                         << statistics[0][statNdx0].name << ": "
768                                         << statistics[0][statNdx0].value.f64
769                                         << (match ? "" : " (non-deterministic)")
770                                         << " (" << statistics[0][statNdx0].description << ")"
771                                         << tcu::TestLog::EndMessage;
772                                 break;
773                         }
774                         default:
775                                 return tcu::TestStatus::fail("Invalid statistic format");
776                 }
777         }
778
779         return tcu::TestStatus::pass("Pass");
780 }
781
782 tcu::TestStatus ExecutablePropertiesTestInstance::verifyInternalRepresentations (deUint32 executableNdx)
783 {
784         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
785         const VkDevice                          vkDevice        = m_context.getDevice();
786         tcu::TestLog                            &log            = m_context.getTestContext().getLog();
787
788         // We only care about internal representations on the second pipeline.
789         // We still compile twice to ensure that we still get the right thing
790         // even if the pipeline is hot in the cache.
791         const VkPipelineExecutableInfoKHR pipelineExecutableInfo =
792         {
793                 VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR, // VkStructureType                                      sType;
794                 DE_NULL,                                                                                // const void*                                          pNext;
795                 *m_pipeline[1],                                                                 // VkPipeline                                           pipeline;
796                 executableNdx,                                                                  // uint32_t                                                     executableIndex;
797         };
798
799         std::vector<VkPipelineExecutableInternalRepresentationKHR> irs;
800         std::vector<std::vector<deUint8>> irDatas;
801
802         deUint32 irCount = 0;
803         VK_CHECK(vk.getPipelineExecutableInternalRepresentationsKHR(vkDevice, &pipelineExecutableInfo, &irCount, DE_NULL));
804
805         if (irCount == 0)
806         {
807                 return tcu::TestStatus::pass("No internal representations reported");
808         }
809
810         irs.resize(irCount);
811         irDatas.resize(irCount);
812         for (deUint32 irNdx = 0; irNdx < irCount; irNdx++)
813         {
814                 deMemset(&irs[irNdx], 0, sizeof(irs[irNdx]));
815                 irs[irNdx].sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR;
816                 irs[irNdx].pNext = DE_NULL;
817         }
818         VK_CHECK(vk.getPipelineExecutableInternalRepresentationsKHR(vkDevice, &pipelineExecutableInfo, &irCount, &irs[0]));
819
820         for (deUint32 irNdx = 0; irNdx < irCount; irNdx++)
821         {
822                 if (!checkString(irs[irNdx].name, DE_LENGTH_OF_ARRAY(irs[irNdx].name)))
823                 {
824                         return tcu::TestStatus::fail("Invalid internal representation name string");
825                 }
826
827                 for (deUint32 otherNdx = 0; otherNdx < irNdx; otherNdx++)
828                 {
829                         if (deMemCmp(irs[irNdx].name, irs[otherNdx].name,
830                                                  DE_LENGTH_OF_ARRAY(irs[irNdx].name)) == 0)
831                         {
832                                 return tcu::TestStatus::fail("Internal representation name string not unique within the executable");
833                         }
834                 }
835
836                 if (!checkString(irs[irNdx].description, DE_LENGTH_OF_ARRAY(irs[irNdx].description)))
837                 {
838                         return tcu::TestStatus::fail("Invalid binary description string");
839                 }
840
841                 if (irs[irNdx].dataSize == 0)
842                 {
843                         return tcu::TestStatus::fail("Internal representation has no data");
844                 }
845
846                 irDatas[irNdx].resize(irs[irNdx].dataSize);
847                 irs[irNdx].pData = &irDatas[irNdx][0];
848                 if (irs[irNdx].isText)
849                 {
850                         // For binary data the size is important.  We check that the
851                         // implementation fills the whole buffer by filling it with
852                         // garbage first and then looking for that same garbage later.
853                         for (size_t i = 0; i < irs[irNdx].dataSize; i++)
854                         {
855                                 irDatas[irNdx][i] = (deUint8)(37 * (17 + i));
856                         }
857                 }
858         }
859
860         VK_CHECK(vk.getPipelineExecutableInternalRepresentationsKHR(vkDevice, &pipelineExecutableInfo, &irCount, &irs[0]));
861
862         for (deUint32 irNdx = 0; irNdx < irCount; irNdx++)
863         {
864                 if (irs[irNdx].isText)
865                 {
866                         if (!checkString((char *)irs[irNdx].pData, irs[irNdx].dataSize))
867                         {
868                                 return tcu::TestStatus::fail("Textual internal representation isn't a valid string");
869                         }
870                         log << tcu::TestLog::Section(irs[irNdx].name, irs[irNdx].description)
871                                 << tcu::LogKernelSource((char *)irs[irNdx].pData)
872                                 << tcu::TestLog::EndSection;
873                 }
874                 else
875                 {
876                         size_t maxMatchingChunkSize = 0;
877                         size_t matchingChunkSize = 0;
878                         for (size_t i = 0; i < irs[irNdx].dataSize; i++)
879                         {
880                                 if (irDatas[irNdx][i] == (deUint8)(37 * (17 + i)))
881                                 {
882                                         matchingChunkSize++;
883                                         if (matchingChunkSize > maxMatchingChunkSize)
884                                         {
885                                                 maxMatchingChunkSize = matchingChunkSize;
886                                         }
887                                 }
888                                 else
889                                 {
890                                         matchingChunkSize = 0;
891                                 }
892                         }
893
894                         // 64 bytes of our random data still being in the buffer probably
895                         // isn't a coincidence
896                         if (matchingChunkSize == irs[irNdx].dataSize || matchingChunkSize >= 64)
897                         {
898                                 return tcu::TestStatus::fail("Implementation didn't fill the whole internal representation data buffer");
899                         }
900
901                         log << tcu::TestLog::Section(irs[irNdx].name, irs[irNdx].description)
902                                 << tcu::TestLog::Message << "Received " << irs[irNdx].dataSize << "B of binary data" << tcu::TestLog::EndMessage
903                                 << tcu::TestLog::EndSection;
904                 }
905         }
906
907         return tcu::TestStatus::pass("Pass");
908 }
909
910 tcu::TestStatus ExecutablePropertiesTestInstance::verifyTestResult (void)
911 {
912         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
913         const VkDevice                          vkDevice        = m_context.getDevice();
914         tcu::TestLog                            &log            = m_context.getTestContext().getLog();
915
916         std::vector<VkPipelineExecutablePropertiesKHR> props[PIPELINE_CACHE_NDX_COUNT];
917
918         for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
919         {
920                 const VkPipelineInfoKHR pipelineInfo =
921                 {
922                         VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR,    // VkStructureType                                      sType;
923                         DE_NULL,                                                                // const void*                                          pNext;
924                         *m_pipeline[ndx],                                               // VkPipeline                                           pipeline;
925
926                 };
927                 deUint32 executableCount = 0;
928                 VK_CHECK(vk.getPipelineExecutablePropertiesKHR(vkDevice, &pipelineInfo, &executableCount, DE_NULL));
929
930                 if (executableCount == 0)
931                 {
932                         continue;
933                 }
934
935                 props[ndx].resize(executableCount);
936                 for (deUint32 execNdx = 0; execNdx < executableCount; execNdx++)
937                 {
938                         deMemset(&props[ndx][execNdx], 0, sizeof(props[ndx][execNdx]));
939                         props[ndx][execNdx].sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_PROPERTIES_KHR;
940                         props[ndx][execNdx].pNext = DE_NULL;
941                 }
942                 VK_CHECK(vk.getPipelineExecutablePropertiesKHR(vkDevice, &pipelineInfo, &executableCount, &props[ndx][0]));
943
944                 for (deUint32 execNdx = 0; execNdx < executableCount; execNdx++)
945                 {
946                         if (!checkString(props[ndx][execNdx].name, DE_LENGTH_OF_ARRAY(props[ndx][execNdx].name)))
947                         {
948                                 return tcu::TestStatus::fail("Invalid binary name string");
949                         }
950
951                         for (deUint32 otherNdx = 0; otherNdx < execNdx; otherNdx++)
952                         {
953                                 if (deMemCmp(props[ndx][execNdx].name, props[ndx][otherNdx].name,
954                                                          DE_LENGTH_OF_ARRAY(props[ndx][execNdx].name)) == 0)
955                                 {
956                                         return tcu::TestStatus::fail("Binary name string not unique within the pipeline");
957                                 }
958                         }
959
960                         if (!checkString(props[ndx][execNdx].description, DE_LENGTH_OF_ARRAY(props[ndx][execNdx].description)))
961                         {
962                                 return tcu::TestStatus::fail("Invalid binary description string");
963                         }
964
965                         // Check that the binary only contains stages actually used to
966                         // compile the pipeline
967                         VkShaderStageFlags stages = props[ndx][execNdx].stages;
968                         for (deUint32 stageNdx = 0; stageNdx < m_param->getShaderCount(); stageNdx++)
969                         {
970                                 stages &= ~m_param->getShaderFlag(stageNdx);
971                         }
972                         if (stages != 0)
973                         {
974                                 return tcu::TestStatus::fail("Binary uses unprovided stage");
975                         }
976                 }
977         }
978
979         if (props[0].size() != props[1].size())
980         {
981                 return tcu::TestStatus::fail("Identical pipelines have different numbers of props");
982         }
983
984         if (props[0].size() == 0)
985         {
986                 return tcu::TestStatus::pass("No executables reported");
987         }
988
989         // Both compiles had better have specified the same infos
990         for (deUint32 execNdx0 = 0; execNdx0 < props[0].size(); execNdx0++)
991         {
992                 deUint32 execNdx1 = 0;
993                 for (; execNdx1 < props[1].size(); execNdx1++)
994                 {
995                         if (deMemCmp(props[0][execNdx0].name, props[1][execNdx1].name,
996                                                  DE_LENGTH_OF_ARRAY(props[0][execNdx0].name)) == 0)
997                         {
998                                 break;
999                         }
1000                 }
1001                 if (execNdx1 >= props[1].size())
1002                 {
1003                         return tcu::TestStatus::fail("Identical pipelines have different sets of executables");
1004                 }
1005
1006                 if (deMemCmp(props[0][execNdx0].description, props[1][execNdx1].description,
1007                                          DE_LENGTH_OF_ARRAY(props[0][execNdx0].description)) != 0)
1008                 {
1009                         return tcu::TestStatus::fail("Same binary has different descriptions");
1010                 }
1011
1012                 if (props[0][execNdx0].stages != props[1][execNdx1].stages)
1013                 {
1014                         return tcu::TestStatus::fail("Same binary has different stages");
1015                 }
1016
1017                 if (props[0][execNdx0].subgroupSize != props[1][execNdx1].subgroupSize)
1018                 {
1019                         return tcu::TestStatus::fail("Same binary has different subgroup sizes");
1020                 }
1021         }
1022
1023         log << tcu::TestLog::Section("Binaries", "Binaries reported for this pipeline");
1024         log << tcu::TestLog::Message << "Pipeline reported " << props[0].size() << " props" << tcu::TestLog::EndMessage;
1025
1026         tcu::TestStatus status = tcu::TestStatus::pass("Pass");
1027         for (deUint32 execNdx = 0; execNdx < props[0].size(); execNdx++)
1028         {
1029                 log << tcu::TestLog::Section(props[0][execNdx].name, props[0][execNdx].description);
1030                 log << tcu::TestLog::Message << "Name: " << props[0][execNdx].name << tcu::TestLog::EndMessage;
1031                 log << tcu::TestLog::Message << "Description: " << props[0][execNdx].description << tcu::TestLog::EndMessage;
1032                 log << tcu::TestLog::Message << "Stages: " << getShaderFlagsStr(props[0][execNdx].stages) << tcu::TestLog::EndMessage;
1033                 log << tcu::TestLog::Message << "Subgroup Size: " << props[0][execNdx].subgroupSize << tcu::TestLog::EndMessage;
1034
1035                 if (m_param->getTestStatistics())
1036                 {
1037                         status = verifyStatistics(execNdx);
1038                         if (status.getCode() != QP_TEST_RESULT_PASS)
1039                         {
1040                                 log << tcu::TestLog::EndSection;
1041                                 break;
1042                         }
1043                 }
1044
1045                 if (m_param->getTestInternalRepresentations())
1046                 {
1047                         status = verifyInternalRepresentations(execNdx);
1048                         if (status.getCode() != QP_TEST_RESULT_PASS)
1049                         {
1050                                 log << tcu::TestLog::EndSection;
1051                                 break;
1052                         }
1053                 }
1054
1055                 log << tcu::TestLog::EndSection;
1056         }
1057
1058         log << tcu::TestLog::EndSection;
1059
1060         return status;
1061 }
1062
1063 class GraphicsExecutablePropertiesTest : public ExecutablePropertiesTest
1064 {
1065 public:
1066                                                         GraphicsExecutablePropertiesTest        (tcu::TestContext&              testContext,
1067                                                                                                          const std::string&     name,
1068                                                                                                          const std::string&     description,
1069                                                                                                          const ExecutablePropertiesTestParam*   param)
1070                                                                 : ExecutablePropertiesTest (testContext, name, description, param)
1071                                                                 { }
1072         virtual                                 ~GraphicsExecutablePropertiesTest       (void) { }
1073         virtual void                    initPrograms            (SourceCollections&     programCollection) const;
1074         virtual TestInstance*   createInstance          (Context&                               context) const;
1075 };
1076
1077 class GraphicsExecutablePropertiesTestInstance : public ExecutablePropertiesTestInstance
1078 {
1079 public:
1080                                                         GraphicsExecutablePropertiesTestInstance        (Context&                               context,
1081                                                                                                                          const ExecutablePropertiesTestParam*   param);
1082         virtual                                 ~GraphicsExecutablePropertiesTestInstance       (void);
1083 protected:
1084         const tcu::UVec2                                        m_renderSize;
1085         const VkFormat                                          m_colorFormat;
1086         const VkFormat                                          m_depthFormat;
1087         Move<VkPipelineLayout>                          m_pipelineLayout;
1088
1089         SimpleGraphicsPipelineBuilder           m_pipelineBuilder;
1090         SimpleGraphicsPipelineBuilder           m_missPipelineBuilder;
1091         Move<VkRenderPass>                                      m_renderPass;
1092 };
1093
1094 void GraphicsExecutablePropertiesTest::initPrograms (SourceCollections& programCollection) const
1095 {
1096         for (deUint32 shaderNdx = 0; shaderNdx < m_param.getShaderCount(); shaderNdx++)
1097         {
1098                 switch(m_param.getShaderFlag(shaderNdx))
1099                 {
1100                 case VK_SHADER_STAGE_VERTEX_BIT:
1101                         programCollection.glslSources.add("color_vert") << glu::VertexSource(
1102                                                 "#version 310 es\n"
1103                                                 "layout(location = 0) in vec4 position;\n"
1104                                                 "layout(location = 1) in vec4 color;\n"
1105                                                 "layout(location = 0) out highp vec4 vtxColor;\n"
1106                                                 "void main (void)\n"
1107                                                 "{\n"
1108                                                 "  gl_Position = position;\n"
1109                                                 "  vtxColor = color;\n"
1110                                                 "}\n");
1111                                         break;
1112                 case VK_SHADER_STAGE_FRAGMENT_BIT:
1113                         programCollection.glslSources.add("color_frag") << glu::FragmentSource(
1114                                                 "#version 310 es\n"
1115                                                 "layout(location = 0) in highp vec4 vtxColor;\n"
1116                                                 "layout(location = 0) out highp vec4 fragColor;\n"
1117                                                 "void main (void)\n"
1118                                                 "{\n"
1119                                                 "  fragColor = vtxColor;\n"
1120                                                 "}\n");
1121                         break;
1122
1123                 case VK_SHADER_STAGE_GEOMETRY_BIT:
1124                         programCollection.glslSources.add("dummy_geo") << glu::GeometrySource(
1125                                                 "#version 450 \n"
1126                                                 "layout(triangles) in;\n"
1127                                                 "layout(triangle_strip, max_vertices = 3) out;\n"
1128                                                 "layout(location = 0) in highp vec4 in_vtxColor[];\n"
1129                                                 "layout(location = 0) out highp vec4 vtxColor;\n"
1130                                                 "out gl_PerVertex { vec4 gl_Position; float gl_PointSize; };\n"
1131                                                 "in gl_PerVertex { vec4 gl_Position; float gl_PointSize; } gl_in[];\n"
1132                                                 "void main (void)\n"
1133                                                 "{\n"
1134                                                 "  for(int ndx=0; ndx<3; ndx++)\n"
1135                                                 "  {\n"
1136                                                 "    gl_Position = gl_in[ndx].gl_Position;\n"
1137                                                 "    gl_PointSize = gl_in[ndx].gl_PointSize;\n"
1138                                                 "    vtxColor    = in_vtxColor[ndx];\n"
1139                                                 "    EmitVertex();\n"
1140                                                 "  }\n"
1141                                                 "  EndPrimitive();\n"
1142                                                 "}\n");
1143                         break;
1144
1145                 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
1146                         programCollection.glslSources.add("basic_tcs") << glu::TessellationControlSource(
1147                                                 "#version 450 \n"
1148                                                 "layout(vertices = 3) out;\n"
1149                                                 "layout(location = 0) in highp vec4 color[];\n"
1150                                                 "layout(location = 0) out highp vec4 vtxColor[];\n"
1151                                                 "out gl_PerVertex { vec4 gl_Position; float gl_PointSize; } gl_out[3];\n"
1152                                                 "in gl_PerVertex { vec4 gl_Position; float gl_PointSize; } gl_in[gl_MaxPatchVertices];\n"
1153                                                 "void main()\n"
1154                                                 "{\n"
1155                                                 "  gl_TessLevelOuter[0] = 4.0;\n"
1156                                                 "  gl_TessLevelOuter[1] = 4.0;\n"
1157                                                 "  gl_TessLevelOuter[2] = 4.0;\n"
1158                                                 "  gl_TessLevelInner[0] = 4.0;\n"
1159                                                 "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1160                                                 "  gl_out[gl_InvocationID].gl_PointSize = gl_in[gl_InvocationID].gl_PointSize;\n"
1161                                                 "  vtxColor[gl_InvocationID] = color[gl_InvocationID];\n"
1162                                                 "}\n");
1163                                         break;
1164
1165                                 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
1166                                         programCollection.glslSources.add("basic_tes") << glu::TessellationEvaluationSource(
1167                                                 "#version 450 \n"
1168                                                 "layout(triangles, fractional_even_spacing, ccw) in;\n"
1169                                                 "layout(location = 0) in highp vec4 colors[];\n"
1170                                                 "layout(location = 0) out highp vec4 vtxColor;\n"
1171                                                 "out gl_PerVertex { vec4 gl_Position; float gl_PointSize; };\n"
1172                                                 "in gl_PerVertex { vec4 gl_Position; float gl_PointSize; } gl_in[gl_MaxPatchVertices];\n"
1173                                                 "void main() \n"
1174                                                 "{\n"
1175                                                 "  float u = gl_TessCoord.x;\n"
1176                                                 "  float v = gl_TessCoord.y;\n"
1177                                                 "  float w = gl_TessCoord.z;\n"
1178                                                 "  vec4 pos = vec4(0);\n"
1179                                                 "  vec4 color = vec4(0);\n"
1180                                                 "  pos.xyz += u * gl_in[0].gl_Position.xyz;\n"
1181                                                 "  color.xyz += u * colors[0].xyz;\n"
1182                                                 "  pos.xyz += v * gl_in[1].gl_Position.xyz;\n"
1183                                                 "  color.xyz += v * colors[1].xyz;\n"
1184                                                 "  pos.xyz += w * gl_in[2].gl_Position.xyz;\n"
1185                                                 "  color.xyz += w * colors[2].xyz;\n"
1186                                                 "  pos.w = 1.0;\n"
1187                                                 "  color.w = 1.0;\n"
1188                                                 "  gl_Position = pos;\n"
1189                                                 "  gl_PointSize = gl_in[0].gl_PointSize;"
1190                                                 "  vtxColor = color;\n"
1191                                                 "}\n");
1192                                         break;
1193
1194                                 default:
1195                                         DE_FATAL("Unknown Shader Stage!");
1196                                         break;
1197                 };
1198         }
1199 }
1200
1201 TestInstance* GraphicsExecutablePropertiesTest::createInstance (Context& context) const
1202 {
1203         return new GraphicsExecutablePropertiesTestInstance(context, &m_param);
1204 }
1205
1206 GraphicsExecutablePropertiesTestInstance::GraphicsExecutablePropertiesTestInstance (Context&                                    context,
1207                                                                                                                                 const ExecutablePropertiesTestParam*    param)
1208         : ExecutablePropertiesTestInstance              (context, param)
1209         , m_renderSize                  (32u, 32u)
1210         , m_colorFormat                 (VK_FORMAT_R8G8B8A8_UNORM)
1211         , m_depthFormat                 (VK_FORMAT_D16_UNORM)
1212         , m_pipelineBuilder             (context)
1213         , m_missPipelineBuilder (context)
1214 {
1215         const DeviceInterface&  vk                              = m_context.getDeviceInterface();
1216         const VkDevice                  vkDevice                = m_context.getDevice();
1217
1218         // Create pipeline layout
1219         {
1220                 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1221                 {
1222                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                                      sType;
1223                         DE_NULL,                                                                                        // const void*                                          pNext;
1224                         0u,                                                                                                     // VkPipelineLayoutCreateFlags          flags;
1225                         0u,                                                                                                     // deUint32                                                     setLayoutCount;
1226                         DE_NULL,                                                                                        // const VkDescriptorSetLayout*         pSetLayouts;
1227                         0u,                                                                                                     // deUint32                                                     pushConstantRangeCount;
1228                         DE_NULL                                                                                         // const VkPushConstantRange*           pPushConstantRanges;
1229                 };
1230
1231                 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1232         }
1233
1234         // Create render pass
1235         m_renderPass = makeRenderPass(vk, vkDevice, m_colorFormat, m_depthFormat);
1236
1237         // Bind shader stages
1238
1239         VkPhysicalDeviceFeatures        features = m_context.getDeviceFeatures();
1240         for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
1241         {
1242                 for (deUint32 shaderNdx = 0; shaderNdx < m_param->getShaderCount(); shaderNdx++)
1243                 {
1244                         switch(m_param->getShaderFlag(shaderNdx))
1245                         {
1246                         case VK_SHADER_STAGE_VERTEX_BIT:
1247                                 m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_VERTEX_BIT, "color_vert", "main");
1248                                 break;
1249                         case VK_SHADER_STAGE_FRAGMENT_BIT:
1250                                 m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_FRAGMENT_BIT, "color_frag", "main");
1251                                 break;
1252                         case VK_SHADER_STAGE_GEOMETRY_BIT:
1253                                 if (features.geometryShader == VK_FALSE)
1254                                 {
1255                                         TCU_THROW(NotSupportedError, "Geometry Shader Not Supported");
1256                                 }
1257                                 else
1258                                 {
1259                                         m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_GEOMETRY_BIT, "dummy_geo", "main");
1260                                 }
1261                                 break;
1262                         case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
1263                                 if (features.tessellationShader == VK_FALSE)
1264                                 {
1265                                         TCU_THROW(NotSupportedError, "Tessellation Not Supported");
1266                                 }
1267                                 else
1268                                 {
1269                                         m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "basic_tcs", "main");
1270                                         m_pipelineBuilder.enableTessellationStage(3);
1271                                 }
1272                                 break;
1273                         case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
1274                                 if (features.tessellationShader == VK_FALSE)
1275                                 {
1276                                         TCU_THROW(NotSupportedError, "Tessellation Not Supported");
1277                                 }
1278                                 else
1279                                 {
1280                                         m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "basic_tes", "main");
1281                                         m_pipelineBuilder.enableTessellationStage(3);
1282                                 }
1283                                 break;
1284                         default:
1285                                 DE_FATAL("Unknown Shader Stage!");
1286                                 break;
1287                         };
1288
1289                 }
1290
1291                 VkPipelineCreateFlags flags = 0;
1292                 if (param->getTestStatistics())
1293                 {
1294                         flags |= VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR;
1295                 }
1296
1297                 // Only check gather internal representations on the second
1298                 // pipeline.  This way, it's more obvious if they failed to capture
1299                 // due to the pipeline being cached.
1300                 if (ndx == PIPELINE_CACHE_NDX_CACHED && param->getTestInternalRepresentations())
1301                 {
1302                         flags |= VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR;
1303                 }
1304
1305                 m_pipeline[ndx] = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass, *m_cache, *m_pipelineLayout, flags);
1306                 m_pipelineBuilder.resetBuilder();
1307         }
1308 }
1309
1310 GraphicsExecutablePropertiesTestInstance::~GraphicsExecutablePropertiesTestInstance (void)
1311 {
1312 }
1313
1314 class ComputeExecutablePropertiesTest : public ExecutablePropertiesTest
1315 {
1316 public:
1317                                                         ComputeExecutablePropertiesTest (tcu::TestContext&              testContext,
1318                                                                                                          const std::string&             name,
1319                                                                                                          const std::string&             description,
1320                                                                                                          const ExecutablePropertiesTestParam*   param)
1321                                                                 : ExecutablePropertiesTest      (testContext, name, description, param)
1322                                                                 { }
1323         virtual                                 ~ComputeExecutablePropertiesTest        (void) { }
1324         virtual void                    initPrograms                    (SourceCollections&     programCollection) const;
1325         virtual TestInstance*   createInstance                  (Context&                               context) const;
1326 };
1327
1328 class ComputeExecutablePropertiesTestInstance : public ExecutablePropertiesTestInstance
1329 {
1330 public:
1331                                                         ComputeExecutablePropertiesTestInstance (Context&                               context,
1332                                                                                                                          const ExecutablePropertiesTestParam*   param);
1333         virtual                                 ~ComputeExecutablePropertiesTestInstance        (void);
1334 protected:
1335         void                                    buildDescriptorSets                             (deUint32 ndx);
1336         void                                    buildShader                                             (deUint32 ndx);
1337         void                                    buildPipeline                                   (deUint32 ndx);
1338 protected:
1339         Move<VkBuffer>                                  m_inputBuf;
1340         de::MovePtr<Allocation>                 m_inputBufferAlloc;
1341         Move<VkShaderModule>                    m_computeShaderModule[PIPELINE_CACHE_NDX_COUNT];
1342
1343         Move<VkBuffer>                                  m_outputBuf[PIPELINE_CACHE_NDX_COUNT];
1344         de::MovePtr<Allocation>                 m_outputBufferAlloc[PIPELINE_CACHE_NDX_COUNT];
1345
1346         Move<VkDescriptorPool>                  m_descriptorPool[PIPELINE_CACHE_NDX_COUNT];
1347         Move<VkDescriptorSetLayout>             m_descriptorSetLayout[PIPELINE_CACHE_NDX_COUNT];
1348         Move<VkDescriptorSet>                   m_descriptorSet[PIPELINE_CACHE_NDX_COUNT];
1349
1350         Move<VkPipelineLayout>                  m_pipelineLayout[PIPELINE_CACHE_NDX_COUNT];
1351 };
1352
1353 void ComputeExecutablePropertiesTest::initPrograms (SourceCollections& programCollection) const
1354 {
1355         programCollection.glslSources.add("basic_compute") << glu::ComputeSource(
1356                 "#version 310 es\n"
1357                 "layout(local_size_x = 1) in;\n"
1358                 "layout(std430) buffer;\n"
1359                 "layout(binding = 0) readonly buffer Input0\n"
1360                 "{\n"
1361                 "  vec4 elements[];\n"
1362                 "} input_data0;\n"
1363                 "layout(binding = 1) writeonly buffer Output\n"
1364                 "{\n"
1365                 "  vec4 elements[];\n"
1366                 "} output_data;\n"
1367                 "void main()\n"
1368                 "{\n"
1369                 "  uint ident = gl_GlobalInvocationID.x;\n"
1370                 "  output_data.elements[ident] = input_data0.elements[ident] * input_data0.elements[ident];\n"
1371                 "}");
1372 }
1373
1374 TestInstance* ComputeExecutablePropertiesTest::createInstance (Context& context) const
1375 {
1376         return new ComputeExecutablePropertiesTestInstance(context, &m_param);
1377 }
1378
1379 void ComputeExecutablePropertiesTestInstance::buildDescriptorSets (deUint32 ndx)
1380 {
1381         const DeviceInterface&  vk                              = m_context.getDeviceInterface();
1382         const VkDevice                  vkDevice                = m_context.getDevice();
1383
1384         // Create descriptor set layout
1385         DescriptorSetLayoutBuilder descLayoutBuilder;
1386         for (deUint32 bindingNdx = 0u; bindingNdx < 2u; bindingNdx++)
1387                 descLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
1388         m_descriptorSetLayout[ndx] = descLayoutBuilder.build(vk, vkDevice);
1389 }
1390
1391 void ComputeExecutablePropertiesTestInstance::buildShader (deUint32 ndx)
1392 {
1393         const DeviceInterface&  vk                              = m_context.getDeviceInterface();
1394         const VkDevice                  vkDevice                = m_context.getDevice();
1395
1396         // Create compute shader
1397         VkShaderModuleCreateInfo shaderModuleCreateInfo =
1398         {
1399                 VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,                                                                    // VkStructureType                              sType;
1400                 DE_NULL,                                                                                                                                                // const void*                                  pNext;
1401                 0u,                                                                                                                                                             // VkShaderModuleCreateFlags    flags;
1402                 m_context.getBinaryCollection().get("basic_compute").getSize(),                                 // deUintptr                                    codeSize;
1403                 (deUint32*)m_context.getBinaryCollection().get("basic_compute").getBinary(),    // const deUint32*                              pCode;
1404         };
1405         m_computeShaderModule[ndx] = createShaderModule(vk, vkDevice, &shaderModuleCreateInfo);
1406 }
1407
1408 void ComputeExecutablePropertiesTestInstance::buildPipeline (deUint32 ndx)
1409 {
1410         const DeviceInterface&  vk                               = m_context.getDeviceInterface();
1411         const VkDevice                  vkDevice                 = m_context.getDevice();
1412
1413         // Create compute pipeline layout
1414         const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
1415         {
1416                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,                                  // VkStructureType                                      sType;
1417                 DE_NULL,                                                                                                                // const void*                                          pNext;
1418                 0u,                                                                                                                             // VkPipelineLayoutCreateFlags          flags;
1419                 1u,                                                                                                                             // deUint32                                                     setLayoutCount;
1420                 &m_descriptorSetLayout[ndx].get(),                                                              // const VkDescriptorSetLayout*         pSetLayouts;
1421                 0u,                                                                                                                             // deUint32                                                     pushConstantRangeCount;
1422                 DE_NULL,                                                                                                                // const VkPushConstantRange*           pPushConstantRanges;
1423         };
1424
1425         m_pipelineLayout[ndx] = createPipelineLayout(vk, vkDevice, &pipelineLayoutCreateInfo);
1426
1427         const VkPipelineShaderStageCreateInfo stageCreateInfo =
1428         {
1429                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,                    // VkStructureType                                      sType;
1430                 DE_NULL,                                                                                                                // const void*                                          pNext;
1431                 0u,                                                                                                                             // VkPipelineShaderStageCreateFlags     flags;
1432                 VK_SHADER_STAGE_COMPUTE_BIT,                                                                    // VkShaderStageFlagBits                        stage;
1433                 *m_computeShaderModule[ndx],                                                                    // VkShaderModule                                       module;
1434                 "main",                                                                                                                 // const char*                                          pName;
1435                 DE_NULL,                                                                                                                // const VkSpecializationInfo*          pSpecializationInfo;
1436         };
1437
1438         VkPipelineCreateFlags flags = 0;
1439         if (m_param->getTestStatistics())
1440         {
1441                 flags |= VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR;
1442         }
1443
1444         // Only check gather internal representations on the second
1445         // pipeline.  This way, it's more obvious if they failed to capture
1446         // due to the pipeline being cached.
1447         if (ndx == PIPELINE_CACHE_NDX_CACHED && m_param->getTestInternalRepresentations())
1448         {
1449                 flags |= VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR;
1450         }
1451
1452         const VkComputePipelineCreateInfo pipelineCreateInfo =
1453         {
1454                 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,                         // VkStructureType                                      sType;
1455                 DE_NULL,                                                                                                        // const void*                                          pNext;
1456                 flags,                                                                                                          // VkPipelineCreateFlags                        flags;
1457                 stageCreateInfo,                                                                                        // VkPipelineShaderStageCreateInfo      stage;
1458                 *m_pipelineLayout[ndx],                                                                         // VkPipelineLayout                                     layout;
1459                 (VkPipeline)0,                                                                                          // VkPipeline                                           basePipelineHandle;
1460                 0u,                                                                                                                     // deInt32                                                      basePipelineIndex;
1461         };
1462
1463         m_pipeline[ndx] = createComputePipeline(vk, vkDevice, *m_cache, &pipelineCreateInfo, DE_NULL);
1464 }
1465
1466 ComputeExecutablePropertiesTestInstance::ComputeExecutablePropertiesTestInstance (Context&                              context,
1467                                                                                                         const ExecutablePropertiesTestParam*    param)
1468         : ExecutablePropertiesTestInstance (context, param)
1469 {
1470         for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
1471         {
1472                 buildDescriptorSets(ndx);
1473                 buildShader(ndx);
1474                 buildPipeline(ndx);
1475         }
1476 }
1477
1478 ComputeExecutablePropertiesTestInstance::~ComputeExecutablePropertiesTestInstance (void)
1479 {
1480 }
1481
1482 } // anonymous
1483
1484 tcu::TestCaseGroup* createExecutablePropertiesTests (tcu::TestContext& testCtx)
1485 {
1486
1487         de::MovePtr<tcu::TestCaseGroup> binaryInfoTests (new tcu::TestCaseGroup(testCtx, "executable_properties", "pipeline binary statistics tests"));
1488
1489         // Graphics Pipeline Tests
1490         {
1491                 de::MovePtr<tcu::TestCaseGroup> graphicsTests (new tcu::TestCaseGroup(testCtx, "graphics", "Test pipeline binary info with graphics pipeline."));
1492
1493                 const VkShaderStageFlagBits testParamShaders0[] =
1494                 {
1495                         VK_SHADER_STAGE_VERTEX_BIT,
1496                         VK_SHADER_STAGE_FRAGMENT_BIT,
1497                 };
1498                 const VkShaderStageFlagBits testParamShaders1[] =
1499                 {
1500                         VK_SHADER_STAGE_VERTEX_BIT,
1501                         VK_SHADER_STAGE_GEOMETRY_BIT,
1502                         VK_SHADER_STAGE_FRAGMENT_BIT,
1503                 };
1504                 const VkShaderStageFlagBits testParamShaders2[] =
1505                 {
1506                         VK_SHADER_STAGE_VERTEX_BIT,
1507                         VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
1508                         VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
1509                         VK_SHADER_STAGE_FRAGMENT_BIT,
1510                 };
1511                 const ExecutablePropertiesTestParam testParams[] =
1512                 {
1513                         ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE, DE_FALSE),
1514                         ExecutablePropertiesTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), DE_FALSE, DE_FALSE),
1515                         ExecutablePropertiesTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), DE_FALSE, DE_FALSE),
1516                         ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_TRUE, DE_FALSE),
1517                         ExecutablePropertiesTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), DE_TRUE, DE_FALSE),
1518                         ExecutablePropertiesTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), DE_TRUE, DE_FALSE),
1519                         ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE, DE_TRUE),
1520                         ExecutablePropertiesTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), DE_FALSE, DE_TRUE),
1521                         ExecutablePropertiesTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), DE_FALSE, DE_TRUE),
1522                         ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_TRUE, DE_TRUE),
1523                         ExecutablePropertiesTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), DE_TRUE, DE_TRUE),
1524                         ExecutablePropertiesTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), DE_TRUE, DE_TRUE),
1525                 };
1526
1527                 for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
1528                         graphicsTests->addChild(newTestCase<GraphicsExecutablePropertiesTest>(testCtx, &testParams[i]));
1529
1530                 binaryInfoTests->addChild(graphicsTests.release());
1531         }
1532
1533         // Compute Pipeline Tests
1534         {
1535                 de::MovePtr<tcu::TestCaseGroup> computeTests (new tcu::TestCaseGroup(testCtx, "compute", "Test pipeline binary info with compute pipeline."));
1536
1537                 const VkShaderStageFlagBits testParamShaders0[] =
1538                 {
1539                         VK_SHADER_STAGE_COMPUTE_BIT,
1540                 };
1541                 const ExecutablePropertiesTestParam testParams[] =
1542                 {
1543                         ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE, DE_FALSE),
1544                         ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_TRUE, DE_FALSE),
1545                         ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE, DE_TRUE),
1546                         ExecutablePropertiesTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_TRUE, DE_TRUE),
1547                 };
1548
1549                 for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
1550                         computeTests->addChild(newTestCase<ComputeExecutablePropertiesTest>(testCtx, &testParams[i]));
1551
1552                 binaryInfoTests->addChild(computeTests.release());
1553         }
1554
1555         return binaryInfoTests.release();
1556 }
1557
1558 } // pipeline
1559
1560 } // vkt