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