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