849f80e3f3378c7f8935bd7e376dd05a22ebb847
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / pipeline / vktPipelineCreationFeedbackTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2019 The Khronos Group Inc.
6  * Copyright (c) 2019 Valve 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 Pipeline Cache Tests
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktPipelineCreationFeedbackTests.hpp"
26 #include "vktPipelineVertexUtil.hpp"
27 #include "vktTestCase.hpp"
28 #include "vktTestCaseUtil.hpp"
29 #include "vkMemUtil.hpp"
30 #include "vkBuilderUtil.hpp"
31 #include "vkRefUtil.hpp"
32 #include "vkTypeUtil.hpp"
33 #include "vkObjUtil.hpp"
34 #include "tcuTestLog.hpp"
35
36 #include <sstream>
37 #include <vector>
38
39 namespace vkt
40 {
41 namespace pipeline
42 {
43
44 using namespace vk;
45
46 namespace
47 {
48 enum
49 {
50         VK_MAX_SHADER_STAGES = 6,
51 };
52
53 enum
54 {
55         PIPELINE_CACHE_NDX_NO_CACHE = 0,
56         PIPELINE_CACHE_NDX_DERIVATIVE = 1,
57         PIPELINE_CACHE_NDX_CACHED = 2,
58         PIPELINE_CACHE_NDX_COUNT,
59 };
60
61 // helper functions
62
63 std::string getShaderFlagStr (const VkShaderStageFlagBits       shader,
64                                                           bool                                                  isDescription)
65 {
66         std::ostringstream desc;
67         switch(shader)
68         {
69                 case VK_SHADER_STAGE_VERTEX_BIT:
70                 {
71                         desc << ((isDescription) ? "vertex stage" : "vertex_stage");
72                         break;
73                 }
74                 case VK_SHADER_STAGE_FRAGMENT_BIT:
75                 {
76                         desc << ((isDescription) ? "fragment stage" : "fragment_stage");
77                         break;
78                 }
79                 case VK_SHADER_STAGE_GEOMETRY_BIT:
80                 {
81                         desc << ((isDescription) ? "geometry stage" : "geometry_stage");
82                         break;
83                 }
84                 case VK_SHADER_STAGE_COMPUTE_BIT:
85                 {
86                         desc << ((isDescription) ? "compute stage" : "compute_stage");
87                         break;
88                 }
89                 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
90                 {
91                         desc << ((isDescription) ? "tessellation control stage" : "tessellation_control_stage");
92                         break;
93                 }
94                 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
95                 {
96                         desc << ((isDescription) ? "tessellation evaluation stage" : "tessellation_evaluation_stage");
97                         break;
98                 }
99           default:
100                 desc << "unknown shader stage!";
101                 DE_FATAL("Unknown shader Stage!");
102                 break;
103         };
104
105         return desc.str();
106 }
107
108 std::string getCaseStr (const deUint32 ndx)
109 {
110         std::ostringstream desc;
111         switch(ndx)
112         {
113                 case PIPELINE_CACHE_NDX_NO_CACHE:
114                 {
115                         desc << "No cached pipeline";
116                         break;
117                 }
118                 case PIPELINE_CACHE_NDX_CACHED:
119                 {
120                         desc << "Cached pipeline";
121                         break;
122                 }
123                 case PIPELINE_CACHE_NDX_DERIVATIVE:
124                 {
125                         desc << "Pipeline derivative";
126                         break;
127                 }
128           default:
129                 desc << "Unknown case";
130                 DE_FATAL("Unknown case!");
131                 break;
132         };
133
134         return desc.str();
135 }
136
137 // helper classes
138 class CacheTestParam
139 {
140 public:
141                                                                 CacheTestParam                          (const VkShaderStageFlagBits*   shaders,
142                                                                                                                          deUint32                                               count,
143                                                                                                                          deBool                                                 noCache,
144                                                                                                                          deBool                                                 delayedDestroy);
145         virtual                                 ~CacheTestParam                                 (void);
146         virtual const std::string       generateTestName                        (void)                  const;
147         virtual const std::string       generateTestDescription         (void)                  const;
148         VkShaderStageFlagBits           getShaderFlag                           (deUint32 ndx)  const   { return m_shaders[ndx]; }
149         deUint32                                        getShaderCount                          (void)                  const   { return (deUint32)m_shaderCount; }
150         deBool                                          isCacheDisabled                         (void)                  const   { return m_noCache; }
151         deBool                                          isDelayedDestroy                        (void)                  const   { return m_delayedDestroy; }
152
153 protected:
154         VkShaderStageFlagBits           m_shaders[VK_MAX_SHADER_STAGES];
155         size_t                                          m_shaderCount;
156         bool                                            m_noCache;
157         bool                                            m_delayedDestroy;
158 };
159
160 CacheTestParam::CacheTestParam (const VkShaderStageFlagBits* shaders, deUint32 count, deBool noCache, deBool delayedDestroy)
161 {
162         DE_ASSERT(count <= VK_MAX_SHADER_STAGES);
163         for (deUint32 ndx = 0; ndx < count; ndx++)
164                 m_shaders[ndx] = shaders[ndx];
165         m_shaderCount           = count;
166         m_noCache                       = noCache;
167         m_delayedDestroy        = delayedDestroy;
168 }
169
170 CacheTestParam::~CacheTestParam (void)
171 {
172 }
173
174 const std::string CacheTestParam::generateTestName (void) const
175 {
176         std::string result(getShaderFlagStr(m_shaders[0], false));
177         std::string cacheString [] = { "", "_no_cache" };
178         std::string delayedDestroyString [] = { "", "_delayed_destroy" };
179
180         for(deUint32 ndx = 1; ndx < m_shaderCount; ndx++)
181                 result += '_' + getShaderFlagStr(m_shaders[ndx], false) + cacheString[m_noCache ? 1 : 0] + delayedDestroyString[m_delayedDestroy ? 1 : 0];
182
183         if (m_shaderCount == 1)
184                 result += cacheString[m_noCache ? 1 : 0] + delayedDestroyString[m_delayedDestroy ? 1 : 0];
185
186         return result;
187 }
188
189 const std::string CacheTestParam::generateTestDescription (void) const
190 {
191         std::string result("Get pipeline creation feedback with " + getShaderFlagStr(m_shaders[0], true));
192         if (m_noCache)
193                 result += " with no cache";
194         if (m_delayedDestroy)
195                 result += " with delayed destroy";
196
197         for(deUint32 ndx = 1; ndx < m_shaderCount; ndx++)
198                 result += ' ' + getShaderFlagStr(m_shaders[ndx], true);
199
200         return result;
201 }
202
203 class SimpleGraphicsPipelineBuilder
204 {
205 public:
206                                                         SimpleGraphicsPipelineBuilder   (Context&                                               context);
207                                                         ~SimpleGraphicsPipelineBuilder  (void) { }
208         void                                    bindShaderStage                                 (VkShaderStageFlagBits                  stage,
209                                                                                                                          const char*                                    sourceName,
210                                                                                                                          const char*                                    entryName);
211         void                                    enableTessellationStage                 (deUint32                                               patchControlPoints);
212         VkPipeline                              buildPipeline                                   (tcu::UVec2                                             renderSize,
213                                                                                                                          VkRenderPass                                   renderPass,
214                                                                                                                          VkPipelineCache                                cache,
215                                                                                                                          VkPipelineLayout                               pipelineLayout,
216                                                                                                                          VkPipelineCreationFeedbackEXT  *pipelineCreationFeedback,
217                                                                                                                          VkPipelineCreationFeedbackEXT  *pipelineStageCreationFeedbacks,
218                                                                                                                          VkPipeline                                             basePipelineHandle);
219         void                                    resetBuilder                                    (void);
220
221 protected:
222         Context&                                                        m_context;
223
224         Move<VkShaderModule>                            m_shaderModules[VK_MAX_SHADER_STAGES];
225         deUint32                                                        m_shaderStageCount;
226         VkPipelineShaderStageCreateInfo m_shaderStageInfo[VK_MAX_SHADER_STAGES];
227
228         deUint32                                                        m_patchControlPoints;
229 };
230
231 SimpleGraphicsPipelineBuilder::SimpleGraphicsPipelineBuilder (Context& context)
232         : m_context(context)
233 {
234         m_patchControlPoints = 0;
235         m_shaderStageCount   = 0;
236 }
237
238 void SimpleGraphicsPipelineBuilder::resetBuilder (void)
239 {
240         m_shaderStageCount = 0;
241 }
242
243 void SimpleGraphicsPipelineBuilder::bindShaderStage (VkShaderStageFlagBits      stage,
244                                                                                                          const char*                    sourceName,
245                                                                                                          const char*                    entryName)
246 {
247         const DeviceInterface&  vk                      = m_context.getDeviceInterface();
248         const VkDevice                  vkDevice        = m_context.getDevice();
249
250         // Create shader module
251         deUint32*                               code            = (deUint32*)m_context.getBinaryCollection().get(sourceName).getBinary();
252         deUint32                                codeSize        = (deUint32)m_context.getBinaryCollection().get(sourceName).getSize();
253
254         const VkShaderModuleCreateInfo moduleCreateInfo =
255         {
256                 VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,                            // VkStructureType                              sType;
257                 DE_NULL,                                                                                                        // const void*                                  pNext;
258                 0u,                                                                                                                     // VkShaderModuleCreateFlags    flags;
259                 codeSize,                                                                                                       // deUintptr                                    codeSize;
260                 code,                                                                                                           // const deUint32*                              pCode;
261         };
262
263         m_shaderModules[m_shaderStageCount] = createShaderModule(vk, vkDevice, &moduleCreateInfo);
264
265         // Prepare shader stage info
266         m_shaderStageInfo[m_shaderStageCount].sType                             = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
267         m_shaderStageInfo[m_shaderStageCount].pNext                             = DE_NULL;
268         m_shaderStageInfo[m_shaderStageCount].flags                             = 0u;
269         m_shaderStageInfo[m_shaderStageCount].stage                             = stage;
270         m_shaderStageInfo[m_shaderStageCount].module                            = *m_shaderModules[m_shaderStageCount];
271         m_shaderStageInfo[m_shaderStageCount].pName                             = entryName;
272         m_shaderStageInfo[m_shaderStageCount].pSpecializationInfo       = DE_NULL;
273
274         m_shaderStageCount++;
275 }
276
277 VkPipeline SimpleGraphicsPipelineBuilder::buildPipeline (tcu::UVec2 renderSize, VkRenderPass renderPass, VkPipelineCache cache,
278                                                                                                                  VkPipelineLayout pipelineLayout, VkPipelineCreationFeedbackEXT *pipelineCreationFeedback,
279                                                                                                                  VkPipelineCreationFeedbackEXT *pipelineStageCreationFeedbacks, VkPipeline basePipelineHandle)
280 {
281         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
282         const VkDevice                          vkDevice                        = m_context.getDevice();
283
284         // Create pipeline
285         const VkVertexInputBindingDescription vertexInputBindingDescription =
286         {
287                 0u,                                                                     // deUint32                             binding;
288                 sizeof(Vertex4RGBA),                            // deUint32                             strideInBytes;
289                 VK_VERTEX_INPUT_RATE_VERTEX,            // VkVertexInputRate    inputRate;
290         };
291
292         const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
293         {
294                 {
295                         0u,                                                                     // deUint32 location;
296                         0u,                                                                     // deUint32 binding;
297                         VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat format;
298                         0u                                                                      // deUint32 offsetInBytes;
299                 },
300                 {
301                         1u,                                                                     // deUint32 location;
302                         0u,                                                                     // deUint32 binding;
303                         VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat format;
304                         DE_OFFSET_OF(Vertex4RGBA, color),       // deUint32 offsetInBytes;
305                 }
306         };
307
308         const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
309         {
310                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                                                      sType;
311                 DE_NULL,                                                                                                                // const void*                                                          pNext;
312                 0u,                                                                                                                             // VkPipelineVertexInputStateCreateFlags        flags;
313                 1u,                                                                                                                             // deUint32                                                                     vertexBindingDescriptionCount;
314                 &vertexInputBindingDescription,                                                                 // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
315                 2u,                                                                                                                             // deUint32                                                                     vertexAttributeDescriptionCount;
316                 vertexInputAttributeDescriptions,                                                               // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
317         };
318
319         const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
320         {
321                 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                                      sType;
322                 DE_NULL,                                                                                                                // const void*                                                          pNext;
323                 0u,                                                                                                                             // VkPipelineInputAssemblyStateCreateFlags      flags;
324                 (m_patchControlPoints == 0 ? VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
325                                                                    : VK_PRIMITIVE_TOPOLOGY_PATCH_LIST), // VkPrimitiveTopology                                          topology;
326                 VK_FALSE,                                                                                                               // VkBool32                                                                     primitiveRestartEnable;
327         };
328
329         const VkViewport        viewport        = makeViewport(renderSize);
330         const VkRect2D          scissor = makeRect2D(renderSize);
331
332         const VkPipelineViewportStateCreateInfo viewportStateParams =
333         {
334                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,                  // VkStructureType                                              sType;
335                 DE_NULL,                                                                                                                // const void*                                                  pNext;
336                 0u,                                                                                                                             // VkPipelineViewportStateCreateFlags   flags;
337                 1u,                                                                                                                             // deUint32                                                             viewportCount;
338                 &viewport,                                                                                                              // const VkViewport*                                    pViewports;
339                 1u,                                                                                                                             // deUint32                                                             scissorCount;
340                 &scissor                                                                                                                // const VkRect2D*                                              pScissors;
341         };
342
343         const VkPipelineRasterizationStateCreateInfo rasterStateParams =
344         {
345                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
346                 DE_NULL,                                                                                                                // const void*                                                          pNext;
347                 0u,                                                                                                                             // VkPipelineRasterizationStateCreateFlags      flags;
348                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthClampEnable;
349                 VK_FALSE,                                                                                                               // VkBool32                                                                     rasterizerDiscardEnable;
350                 VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
351                 VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                      cullMode;
352                 VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
353                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
354                 0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
355                 0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
356                 0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
357                 1.0f,                                                                                                                   // float                                                                        lineWidth;
358         };
359
360         const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
361         {
362                 VK_FALSE,                                                                                                               // VkBool32             blendEnable;
363                 VK_BLEND_FACTOR_ONE,                                                                                    // VkBlendFactor        srcColorBlendFactor;
364                 VK_BLEND_FACTOR_ZERO,                                                                                   // VkBlendFactor        dstColorBlendFactor;
365                 VK_BLEND_OP_ADD,                                                                                                // VkBlendOp            colorBlendOp;
366                 VK_BLEND_FACTOR_ONE,                                                                                    // VkBlendFactor        srcAlphaBlendFactor;
367                 VK_BLEND_FACTOR_ZERO,                                                                                   // VkBlendFactor        dstAlphaBlendFactor;
368                 VK_BLEND_OP_ADD,                                                                                                // VkBlendOp            alphaBlendOp;
369                 VK_COLOR_COMPONENT_R_BIT |
370                 VK_COLOR_COMPONENT_G_BIT |
371                 VK_COLOR_COMPONENT_B_BIT |
372                 VK_COLOR_COMPONENT_A_BIT                                                                                // VkColorComponentFlags    colorWriteMask;
373         };
374
375         const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
376         {
377                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
378                 DE_NULL,                                                                                                        // const void*                                                                  pNext;
379                 0u,                                                                                                                     // VkPipelineColorBlendStateCreateFlags                 flags;
380                 VK_FALSE,                                                                                                       // VkBool32                                                                             logicOpEnable;
381                 VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
382                 1u,                                                                                                                     // deUint32                                                                             attachmentCount;
383                 &colorBlendAttachmentState,                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
384                 { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConst[4];
385         };
386
387         const VkPipelineMultisampleStateCreateInfo  multisampleStateParams      =
388         {
389                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
390                 DE_NULL,                                                                                                        // const void*                                                          pNext;
391                 0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
392                 VK_SAMPLE_COUNT_1_BIT,                                                                          // VkSampleCountFlagBits                                        rasterizationSamples;
393                 VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable;
394                 0.0f,                                                                                                           // float                                                                        minSampleShading;
395                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
396                 VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
397                 VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToOneEnable;
398         };
399
400         VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
401         {
402                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType                                                  sType;
403                 DE_NULL,                                                                                                        // const void*                                                          pNext;
404                 0u,                                                                                                                     // VkPipelineDepthStencilStateCreateFlags       flags;
405                 VK_TRUE,                                                                                                        // VkBool32                                                                     depthTestEnable;
406                 VK_TRUE,                                                                                                        // VkBool32                                                                     depthWriteEnable;
407                 VK_COMPARE_OP_LESS_OR_EQUAL,                                                            // VkCompareOp                                                          depthCompareOp;
408                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthBoundsTestEnable;
409                 VK_FALSE,                                                                                                       // VkBool32                                                                     stencilTestEnable;
410                 // VkStencilOpState front;
411                 {
412                         VK_STENCIL_OP_KEEP,             // VkStencilOp  failOp;
413                         VK_STENCIL_OP_KEEP,             // VkStencilOp  passOp;
414                         VK_STENCIL_OP_KEEP,             // VkStencilOp  depthFailOp;
415                         VK_COMPARE_OP_NEVER,    // VkCompareOp  compareOp;
416                         0u,                                             // deUint32             compareMask;
417                         0u,                                             // deUint32             writeMask;
418                         0u,                                             // deUint32             reference;
419                 },
420                 // VkStencilOpState back;
421                 {
422                         VK_STENCIL_OP_KEEP,             // VkStencilOp  failOp;
423                         VK_STENCIL_OP_KEEP,             // VkStencilOp  passOp;
424                         VK_STENCIL_OP_KEEP,             // VkStencilOp  depthFailOp;
425                         VK_COMPARE_OP_NEVER,    // VkCompareOp  compareOp;
426                         0u,                                             // deUint32             compareMask;
427                         0u,                                             // deUint32             writeMask;
428                         0u,                                             // deUint32             reference;
429                 },
430                 0.0f,                                                                                                           // float                                                                        minDepthBounds;
431                 1.0f,                                                                                                           // float                                                                        maxDepthBounds;
432         };
433
434         const VkPipelineTessellationStateCreateInfo tessStateCreateInfo =
435         {
436                 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,      // VkStructureType                                                      sType;
437                 DE_NULL,                                                                                                        // const void*                                                          pNext;
438                 0u,                                                                                                                     // VkPipelineTesselationStateCreateFlags        flags;
439                 m_patchControlPoints,                                                                           // deUint32                                                                     patchControlPoints;
440         };
441         const VkPipelineTessellationStateCreateInfo* pTessCreateInfo = (m_patchControlPoints > 0)
442                                                                                                                                   ? &tessStateCreateInfo
443                                                                                                                                   : DE_NULL;
444
445         const VkPipelineCreationFeedbackCreateInfoEXT pipelineCreationFeedbackCreateInfo =
446         {
447                 VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT,   // VkStructureType                                              sType;
448                 DE_NULL,                                                                                                                // const void*                                                  pNext;
449                 pipelineCreationFeedback,                                                                               // VkPipelineCreationFeedbackEXT*               pPipelineCreationFeedback;
450                 m_shaderStageCount,                                                                                             // deUint32                                                             pipelineStageCreationFeedbackCount;
451                 pipelineStageCreationFeedbacks                                                                  // VkPipelineCreationFeedbackEXT*               pPipelineStageCreationFeedbacks;
452         };
453
454         deUint32 flagsCreateInfo = VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT;
455         if (basePipelineHandle != DE_NULL)
456         {
457                 flagsCreateInfo = VK_PIPELINE_CREATE_DERIVATIVE_BIT;
458         }
459
460         const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
461         {
462                 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
463                 &pipelineCreationFeedbackCreateInfo,                            // const void*                                                                          pNext;
464                 flagsCreateInfo,                                                                        // VkPipelineCreateFlags                                                        flags;
465                 m_shaderStageCount,                                                                     // deUint32                                                                                     stageCount;
466                 m_shaderStageInfo,                                                                      // const VkPipelineShaderStageCreateInfo*                       pStages;
467                 &vertexInputStateParams,                                                        // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
468                 &inputAssemblyStateParams,                                                      // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
469                 pTessCreateInfo,                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
470                 &viewportStateParams,                                                           // const VkPipelineViewportStateCreateInfo*                     pViewportState;
471                 &rasterStateParams,                                                                     // const VkPipelineRasterizationStateCreateInfo*        pRasterState;
472                 &multisampleStateParams,                                                        // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
473                 &depthStencilStateParams,                                                       // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
474                 &colorBlendStateParams,                                                         // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
475                 (const VkPipelineDynamicStateCreateInfo*)DE_NULL,       // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
476                 pipelineLayout,                                                                         // VkPipelineLayout                                                                     layout;
477                 renderPass,                                                                                     // VkRenderPass                                                                         renderPass;
478                 0u,                                                                                                     // deUint32                                                                                     subpass;
479                 basePipelineHandle,                                                                     // VkPipeline                                                                           basePipelineHandle;
480                 basePipelineHandle != DE_NULL ? -1 : 0,                         // deInt32                                                                                      basePipelineIndex;
481         };
482         VkPipeline pipeline;
483         vk.createGraphicsPipelines(vkDevice, cache, 1u, &graphicsPipelineParams, DE_NULL, &pipeline);
484         return pipeline;
485 }
486
487 void SimpleGraphicsPipelineBuilder::enableTessellationStage (deUint32 patchControlPoints)
488 {
489         m_patchControlPoints = patchControlPoints;
490 }
491
492 template <class Test>
493 vkt::TestCase* newTestCase (tcu::TestContext&           testContext,
494                                                         const CacheTestParam*   testParam)
495 {
496         return new Test(testContext,
497                                         testParam->generateTestName().c_str(),
498                                         testParam->generateTestDescription().c_str(),
499                                         testParam);
500 }
501
502 // Test Classes
503 class CacheTest : public vkt::TestCase
504 {
505 public:
506                                                         CacheTest(tcu::TestContext&             testContext,
507                                                                           const std::string&            name,
508                                                                           const std::string&            description,
509                                                                           const CacheTestParam* param)
510                                                                 : vkt::TestCase (testContext, name, description)
511                                                                 , m_param (*param)
512                                                                 { }
513         virtual                         ~CacheTest (void) { }
514 protected:
515         const CacheTestParam    m_param;
516 };
517
518 class CacheTestInstance : public vkt::TestInstance
519 {
520 public:
521                                                         CacheTestInstance                       (Context&                               context,
522                                                                                                                  const CacheTestParam*  param);
523         virtual                                 ~CacheTestInstance                      (void);
524         virtual tcu::TestStatus iterate                                         (void);
525 protected:
526         virtual tcu::TestStatus verifyTestResult                        (void) = 0;
527 protected:
528         const CacheTestParam*   m_param;
529
530         Move<VkPipelineCache>   m_cache;
531         deBool                                  m_extensions;
532 };
533
534 CacheTestInstance::CacheTestInstance (Context&                                  context,
535                                                                           const CacheTestParam* param)
536         : TestInstance          (context)
537         , m_param                       (param)
538         , m_extensions          (m_context.requireDeviceFunctionality("VK_EXT_pipeline_creation_feedback"))
539 {
540         const DeviceInterface&  vk                              = m_context.getDeviceInterface();
541         const VkDevice                  vkDevice                = m_context.getDevice();
542
543         if (m_param->isCacheDisabled() == DE_FALSE)
544         {
545                 const VkPipelineCacheCreateInfo pipelineCacheCreateInfo =
546                 {
547                         VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,                   // VkStructureType                              sType;
548                         DE_NULL,                                                                                                // const void*                                  pNext;
549                         0u,                                                                                                             // VkPipelineCacheCreateFlags   flags;
550                         0u,                                                                                                             // deUintptr                                    initialDataSize;
551                         DE_NULL,                                                                                                // const void*                                  pInitialData;
552                 };
553
554                 m_cache = createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo);
555         }
556 }
557
558 CacheTestInstance::~CacheTestInstance (void)
559 {
560 }
561
562 tcu::TestStatus CacheTestInstance::iterate (void)
563 {
564         return verifyTestResult();
565 }
566
567 class GraphicsCacheTest : public CacheTest
568 {
569 public:
570                                                         GraphicsCacheTest       (tcu::TestContext&              testContext,
571                                                                                                  const std::string&             name,
572                                                                                                  const std::string&             description,
573                                                                                                  const CacheTestParam*  param)
574                                                                 : CacheTest (testContext, name, description, param)
575                                                                 { }
576         virtual                                 ~GraphicsCacheTest      (void) { }
577         virtual void                    initPrograms            (SourceCollections&     programCollection) const;
578         virtual void                    checkSupport            (Context&                       context) const;
579         virtual TestInstance*   createInstance          (Context&                       context) const;
580 };
581
582 class GraphicsCacheTestInstance : public CacheTestInstance
583 {
584 public:
585                                                         GraphicsCacheTestInstance       (Context&                               context,
586                                                                                                                  const CacheTestParam*  param);
587         virtual                                 ~GraphicsCacheTestInstance      (void);
588 protected:
589         virtual tcu::TestStatus verifyTestResult                        (void);
590
591 protected:
592         const tcu::UVec2                                        m_renderSize;
593         const VkFormat                                          m_colorFormat;
594         const VkFormat                                          m_depthFormat;
595         Move<VkPipelineLayout>                          m_pipelineLayout;
596
597         SimpleGraphicsPipelineBuilder           m_pipelineBuilder;
598         SimpleGraphicsPipelineBuilder           m_missPipelineBuilder;
599         Move<VkRenderPass>                                      m_renderPass;
600
601         VkPipeline                                                      m_pipeline[PIPELINE_CACHE_NDX_COUNT];
602         VkPipelineCreationFeedbackEXT           m_pipelineCreationFeedback[PIPELINE_CACHE_NDX_COUNT];
603         VkPipelineCreationFeedbackEXT           m_pipelineStageCreationFeedbacks[PIPELINE_CACHE_NDX_COUNT * VK_MAX_SHADER_STAGES];
604 };
605
606 void GraphicsCacheTest::initPrograms (SourceCollections& programCollection) const
607 {
608         for (deUint32 shaderNdx = 0; shaderNdx < m_param.getShaderCount(); shaderNdx++)
609         {
610                 switch(m_param.getShaderFlag(shaderNdx))
611                 {
612                 case VK_SHADER_STAGE_VERTEX_BIT:
613                         programCollection.glslSources.add("color_vert_1") << glu::VertexSource(
614                                                 "#version 310 es\n"
615                                                 "layout(location = 0) in vec4 position;\n"
616                                                 "layout(location = 1) in vec4 color;\n"
617                                                 "layout(location = 0) out highp vec4 vtxColor;\n"
618                                                 "void main (void)\n"
619                                                 "{\n"
620                                                 "  gl_Position = position;\n"
621                                                 "  vtxColor = color;\n"
622                                                 "}\n");
623                         programCollection.glslSources.add("color_vert_2") << glu::VertexSource(
624                                                 "#version 310 es\n"
625                                                 "layout(location = 0) in vec4 position;\n"
626                                                 "layout(location = 1) in vec4 color;\n"
627                                                 "layout(location = 0) out highp vec4 vtxColor;\n"
628                                                 "void main (void)\n"
629                                                 "{\n"
630                                                 "  gl_Position = position;\n"
631                                                 "  gl_PointSize = 1.0f;\n"
632                                                 "  vtxColor = color + vec4(0.1, 0.2, 0.3, 0.0);\n"
633                                                 "}\n");
634                                         break;
635                 case VK_SHADER_STAGE_FRAGMENT_BIT:
636                         programCollection.glslSources.add("color_frag") << glu::FragmentSource(
637                                                 "#version 310 es\n"
638                                                 "layout(location = 0) in highp vec4 vtxColor;\n"
639                                                 "layout(location = 0) out highp vec4 fragColor;\n"
640                                                 "void main (void)\n"
641                                                 "{\n"
642                                                 "  fragColor = vtxColor;\n"
643                                                 "}\n");
644                         break;
645
646                 case VK_SHADER_STAGE_GEOMETRY_BIT:
647                         programCollection.glslSources.add("unused_geo") << glu::GeometrySource(
648                                                 "#version 450 \n"
649                                                 "layout(triangles) in;\n"
650                                                 "layout(triangle_strip, max_vertices = 3) out;\n"
651                                                 "layout(location = 0) in highp vec4 in_vtxColor[];\n"
652                                                 "layout(location = 0) out highp vec4 vtxColor;\n"
653                                                 "out gl_PerVertex { vec4 gl_Position; float gl_PointSize; };\n"
654                                                 "in gl_PerVertex { vec4 gl_Position; float gl_PointSize; } gl_in[];\n"
655                                                 "void main (void)\n"
656                                                 "{\n"
657                                                 "  for(int ndx=0; ndx<3; ndx++)\n"
658                                                 "  {\n"
659                                                 "    gl_Position = gl_in[ndx].gl_Position;\n"
660                                                 "    gl_PointSize = gl_in[ndx].gl_PointSize;\n"
661                                                 "    vtxColor    = in_vtxColor[ndx];\n"
662                                                 "    EmitVertex();\n"
663                                                 "  }\n"
664                                                 "  EndPrimitive();\n"
665                                                 "}\n");
666                         break;
667
668                 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
669                         programCollection.glslSources.add("basic_tcs") << glu::TessellationControlSource(
670                                                 "#version 450 \n"
671                                                 "layout(vertices = 3) out;\n"
672                                                 "layout(location = 0) in highp vec4 color[];\n"
673                                                 "layout(location = 0) out highp vec4 vtxColor[];\n"
674                                                 "out gl_PerVertex { vec4 gl_Position; float gl_PointSize; } gl_out[3];\n"
675                                                 "in gl_PerVertex { vec4 gl_Position; float gl_PointSize; } gl_in[gl_MaxPatchVertices];\n"
676                                                 "void main()\n"
677                                                 "{\n"
678                                                 "  gl_TessLevelOuter[0] = 4.0;\n"
679                                                 "  gl_TessLevelOuter[1] = 4.0;\n"
680                                                 "  gl_TessLevelOuter[2] = 4.0;\n"
681                                                 "  gl_TessLevelInner[0] = 4.0;\n"
682                                                 "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
683                                                 "  gl_out[gl_InvocationID].gl_PointSize = gl_in[gl_InvocationID].gl_PointSize;\n"
684                                                 "  vtxColor[gl_InvocationID] = color[gl_InvocationID];\n"
685                                                 "}\n");
686                                         break;
687
688                                 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
689                                         programCollection.glslSources.add("basic_tes") << glu::TessellationEvaluationSource(
690                                                 "#version 450 \n"
691                                                 "layout(triangles, fractional_even_spacing, ccw) in;\n"
692                                                 "layout(location = 0) in highp vec4 colors[];\n"
693                                                 "layout(location = 0) out highp vec4 vtxColor;\n"
694                                                 "out gl_PerVertex { vec4 gl_Position; float gl_PointSize; };\n"
695                                                 "in gl_PerVertex { vec4 gl_Position; float gl_PointSize; } gl_in[gl_MaxPatchVertices];\n"
696                                                 "void main() \n"
697                                                 "{\n"
698                                                 "  float u = gl_TessCoord.x;\n"
699                                                 "  float v = gl_TessCoord.y;\n"
700                                                 "  float w = gl_TessCoord.z;\n"
701                                                 "  vec4 pos = vec4(0);\n"
702                                                 "  vec4 color = vec4(0);\n"
703                                                 "  pos.xyz += u * gl_in[0].gl_Position.xyz;\n"
704                                                 "  color.xyz += u * colors[0].xyz;\n"
705                                                 "  pos.xyz += v * gl_in[1].gl_Position.xyz;\n"
706                                                 "  color.xyz += v * colors[1].xyz;\n"
707                                                 "  pos.xyz += w * gl_in[2].gl_Position.xyz;\n"
708                                                 "  color.xyz += w * colors[2].xyz;\n"
709                                                 "  pos.w = 1.0;\n"
710                                                 "  color.w = 1.0;\n"
711                                                 "  gl_Position = pos;\n"
712                                                 "  gl_PointSize = gl_in[0].gl_PointSize;"
713                                                 "  vtxColor = color;\n"
714                                                 "}\n");
715                                         break;
716
717                                 default:
718                                         DE_FATAL("Unknown Shader Stage!");
719                                         break;
720                 };
721         }
722 }
723
724 void GraphicsCacheTest::checkSupport (Context& context) const
725 {
726         for (deUint32 shaderNdx = 0; shaderNdx < m_param.getShaderCount(); shaderNdx++)
727         {
728                 switch(m_param.getShaderFlag(shaderNdx))
729                 {
730                 case VK_SHADER_STAGE_GEOMETRY_BIT:
731                         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
732                         break;
733                 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
734                 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
735                         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
736                         break;
737                 default:
738                         break;
739                 };
740         }
741 }
742
743 TestInstance* GraphicsCacheTest::createInstance (Context& context) const
744 {
745         return new GraphicsCacheTestInstance(context, &m_param);
746 }
747
748 GraphicsCacheTestInstance::GraphicsCacheTestInstance (Context&                          context,
749                                                                                                           const CacheTestParam* param)
750         : CacheTestInstance             (context, param)
751         , m_renderSize                  (32u, 32u)
752         , m_colorFormat                 (VK_FORMAT_R8G8B8A8_UNORM)
753         , m_depthFormat                 (VK_FORMAT_D16_UNORM)
754         , m_pipelineBuilder             (context)
755         , m_missPipelineBuilder (context)
756 {
757         const DeviceInterface&  vk                              = m_context.getDeviceInterface();
758         const VkDevice                  vkDevice                = m_context.getDevice();
759
760         // Create pipeline layout
761         {
762                 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
763                 {
764                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                                      sType;
765                         DE_NULL,                                                                                        // const void*                                          pNext;
766                         0u,                                                                                                     // VkPipelineLayoutCreateFlags          flags;
767                         0u,                                                                                                     // deUint32                                                     setLayoutCount;
768                         DE_NULL,                                                                                        // const VkDescriptorSetLayout*         pSetLayouts;
769                         0u,                                                                                                     // deUint32                                                     pushConstantRangeCount;
770                         DE_NULL                                                                                         // const VkPushConstantRange*           pPushConstantRanges;
771                 };
772
773                 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
774         }
775
776         // Create render pass
777         m_renderPass = makeRenderPass(vk, vkDevice, m_colorFormat, m_depthFormat);
778
779         // Bind shader stages
780         for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
781         {
782                 for (deUint32 shaderNdx = 0; shaderNdx < m_param->getShaderCount(); shaderNdx++)
783                 {
784                         switch(m_param->getShaderFlag(shaderNdx))
785                         {
786                         case VK_SHADER_STAGE_VERTEX_BIT:
787                                 {
788                                         std::string     shader_name("color_vert_");
789                                         shader_name += (ndx == PIPELINE_CACHE_NDX_DERIVATIVE) ? "2" : "1";
790                                         m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_VERTEX_BIT, shader_name.c_str(), "main");
791                                 }
792                                 break;
793                         case VK_SHADER_STAGE_FRAGMENT_BIT:
794                                 m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_FRAGMENT_BIT, "color_frag", "main");
795                                 break;
796                         case VK_SHADER_STAGE_GEOMETRY_BIT:
797                                 m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_GEOMETRY_BIT, "unused_geo", "main");
798                                 break;
799                         case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
800                                 m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "basic_tcs", "main");
801                                 m_pipelineBuilder.enableTessellationStage(3);
802                                 break;
803                         case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
804                                 m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "basic_tes", "main");
805                                 m_pipelineBuilder.enableTessellationStage(3);
806                                 break;
807                         default:
808                                 DE_FATAL("Unknown Shader Stage!");
809                                 break;
810                         };
811                 }
812                 if (ndx == PIPELINE_CACHE_NDX_CACHED && !param->isDelayedDestroy())
813                 {
814                         // Destroy the NO_CACHE pipeline to check that the cached one really hits cache,
815                         // except for the case where we're testing cache hit of a pipeline still active.
816                         vk.destroyPipeline(vkDevice, m_pipeline[PIPELINE_CACHE_NDX_NO_CACHE], DE_NULL);
817                 }
818
819                 m_pipeline[ndx] = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass, *m_cache, *m_pipelineLayout,
820                                                                                                                   &m_pipelineCreationFeedback[ndx],
821                                                                                                                   &m_pipelineStageCreationFeedbacks[VK_MAX_SHADER_STAGES * ndx],
822                                                                                                                   ndx == PIPELINE_CACHE_NDX_DERIVATIVE ? m_pipeline[PIPELINE_CACHE_NDX_NO_CACHE] : DE_NULL);
823                 m_pipelineBuilder.resetBuilder();
824
825                 if (ndx != PIPELINE_CACHE_NDX_NO_CACHE)
826                 {
827                         // Destroy the pipeline as soon as it is created, except the NO_CACHE because
828                         // it is needed as a base pipeline for the derivative case.
829                         vk.destroyPipeline(vkDevice, m_pipeline[ndx], DE_NULL);
830
831                         if (ndx == PIPELINE_CACHE_NDX_CACHED && param->isDelayedDestroy())
832                         {
833                                 // Destroy the pipeline we didn't destroy earlier for the isDelayedDestroy case.
834                                 vk.destroyPipeline(vkDevice, m_pipeline[PIPELINE_CACHE_NDX_NO_CACHE], DE_NULL);
835                         }
836         }
837         }
838 }
839
840 GraphicsCacheTestInstance::~GraphicsCacheTestInstance (void)
841 {
842 }
843
844 tcu::TestStatus GraphicsCacheTestInstance::verifyTestResult (void)
845 {
846         tcu::TestLog &log                       = m_context.getTestContext().getLog();
847         bool durationZeroWarning        = DE_FALSE;
848         bool cachedPipelineWarning      = DE_FALSE;
849
850         for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
851         {
852                 std::ostringstream      message;
853                 message << getCaseStr(ndx);
854
855                 // No need to check per stage status as it is compute pipeline (only one stage) and Vulkan spec mentions that:
856                 // "One common scenario for an implementation to skip per-stage feedback is when
857                 // VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT is set in pPipelineCreationFeedback."
858                 //
859                 // Check first that the no cached pipeline was missed in the pipeline cache
860                 if (!(m_pipelineCreationFeedback[ndx].flags & VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT))
861                 {
862                         message << ": invalid data";
863                         return tcu::TestStatus::fail(message.str());
864                 }
865
866                 if (m_param->isCacheDisabled() && m_pipelineCreationFeedback[ndx].flags & VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT)
867                 {
868                         message << ": feedback indicates pipeline hit cache when it shouldn't";
869                         return tcu::TestStatus::fail(message.str());
870                 }
871
872                 if (ndx == PIPELINE_CACHE_NDX_NO_CACHE && m_pipelineCreationFeedback[ndx].flags & VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT)
873                 {
874                         message << ": hit the cache when it shouldn't";
875                         return tcu::TestStatus::fail(message.str());
876                 }
877
878                 if (ndx != PIPELINE_CACHE_NDX_DERIVATIVE && m_pipelineCreationFeedback[ndx].flags & VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT_EXT)
879                 {
880                         message << ": feedback indicates base pipeline acceleration when it shouldn't";
881                         return tcu::TestStatus::fail(message.str());
882                 }
883
884                 if (ndx == PIPELINE_CACHE_NDX_CACHED && !m_param->isCacheDisabled() && (m_pipelineCreationFeedback[ndx].flags & VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT) == 0)
885                 {
886                         message << "\nWarning: Cached pipeline case did not hit the cache";
887                         cachedPipelineWarning = DE_TRUE;
888                 }
889
890                 if (m_pipelineCreationFeedback[ndx].duration == 0)
891                 {
892                         message << "\nWarning: Pipeline creation feedback reports duration spent creating a pipeline was zero nanoseconds\n";
893                         durationZeroWarning = DE_TRUE;
894                 }
895
896                 message << "\n";
897                 message << "\t\t Hit cache ? \t\t\t"                            << (m_pipelineCreationFeedback[ndx].flags & VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT ? "yes" : "no")        << "\n";
898                 message << "\t\t Base Pipeline Acceleration ? \t"       << (m_pipelineCreationFeedback[ndx].flags & VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT_EXT ?   "yes" : "no")          << "\n";
899                 message << "\t\t Duration (ns): \t\t"                           << m_pipelineCreationFeedback[ndx].duration                                                                                                                                                                                     << "\n";
900
901                 for(deUint32 shader = 0; shader < m_param->getShaderCount(); shader++)
902                 {
903                         const deUint32 index = VK_MAX_SHADER_STAGES * ndx + shader;
904                         message << "\t" << getShaderFlagStr(m_param->getShaderFlag(shader), true) << "\n";
905
906                         if (!(m_pipelineStageCreationFeedbacks[index].flags & VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT))
907                         {
908                                 if (m_pipelineStageCreationFeedbacks[index].flags)
909                                 {
910                                         std::ostringstream                      errorMsg;
911                                         errorMsg << getCaseStr(ndx) << ": Creation feedback is not valid for " + getShaderFlagStr(m_param->getShaderFlag(shader), true) + " but there are other flags written";
912                                         return tcu::TestStatus::fail(errorMsg.str());
913                                 }
914                                 message << "\t\t Pipeline Creation Feedback data is not valid\n";
915                                 continue;
916                         }
917                         if (m_param->isCacheDisabled() && m_pipelineStageCreationFeedbacks[index].flags & VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT)
918                         {
919                                 std::ostringstream                      errorMsg;
920                                 errorMsg << getCaseStr(ndx) << ": feedback indicates pipeline " + getShaderFlagStr(m_param->getShaderFlag(shader), true) + " stage hit cache when it shouldn't";
921                                 return tcu::TestStatus::fail(errorMsg.str());
922                         }
923
924                         if (ndx == PIPELINE_CACHE_NDX_CACHED && !m_param->isCacheDisabled() && (m_pipelineStageCreationFeedbacks[index].flags & VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT) == 0)
925                         {
926                                 message << "Warning: pipeline stage did not hit the cache\n";
927                                 cachedPipelineWarning = DE_TRUE;
928                         }
929                         if (cachedPipelineWarning && m_pipelineStageCreationFeedbacks[index].flags & VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT)
930                         {
931                                 // We only set the warning when the pipeline nor the pipeline stages hit the cache. If any of them did, them disable the warning.
932                                 cachedPipelineWarning = DE_FALSE;
933                         }
934
935                         message << "\t\t Hit cache ? \t\t\t"                            << (m_pipelineStageCreationFeedbacks[index].flags & VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT ? "yes" : "no")        << "\n";
936                         message << "\t\t Base Pipeline Acceleration ? \t"       << (m_pipelineStageCreationFeedbacks[index].flags & VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT_EXT ?   "yes" : "no")          << "\n";
937                         message << "\t\t Duration (ns): \t\t"                           << m_pipelineStageCreationFeedbacks[index].duration                                                                                                                                                                                     << "\n";
938                 }
939
940                 log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
941         }
942
943         if (cachedPipelineWarning)
944         {
945                 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Cached pipeline or stage did not hit the cache");
946         }
947         if (durationZeroWarning)
948         {
949                 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Pipeline creation feedback reports duration spent creating a pipeline was zero nanoseconds");
950         }
951         return tcu::TestStatus::pass("Pass");
952 }
953
954 class ComputeCacheTest : public CacheTest
955 {
956 public:
957                                                         ComputeCacheTest                (tcu::TestContext&              testContext,
958                                                                                                          const std::string&             name,
959                                                                                                          const std::string&             description,
960                                                                                                          const CacheTestParam*  param)
961                                                                 : CacheTest             (testContext, name, description, param)
962                                                                 { }
963         virtual                                 ~ComputeCacheTest       (void) { }
964         virtual void                    initPrograms                    (SourceCollections&     programCollection) const;
965         virtual TestInstance*   createInstance                  (Context&                               context) const;
966 };
967
968 class ComputeCacheTestInstance : public CacheTestInstance
969 {
970 public:
971                                                         ComputeCacheTestInstance                (Context&                               context,
972                                                                                                                          const CacheTestParam*  param);
973         virtual                                 ~ComputeCacheTestInstance       (void);
974 protected:
975         virtual tcu::TestStatus verifyTestResult                                (void);
976                         void                    buildDescriptorSets                             (deUint32 ndx);
977                         void                    buildShader                                             (deUint32 ndx);
978                         void                    buildPipeline                                   (const CacheTestParam*  param, deUint32 ndx);
979 protected:
980         Move<VkBuffer>                                  m_inputBuf;
981         de::MovePtr<Allocation>         m_inputBufferAlloc;
982         Move<VkShaderModule>                    m_computeShaderModule[PIPELINE_CACHE_NDX_COUNT];
983
984         Move<VkBuffer>                                  m_outputBuf[PIPELINE_CACHE_NDX_COUNT];
985         de::MovePtr<Allocation>         m_outputBufferAlloc[PIPELINE_CACHE_NDX_COUNT];
986
987         Move<VkDescriptorPool>                  m_descriptorPool[PIPELINE_CACHE_NDX_COUNT];
988         Move<VkDescriptorSetLayout>     m_descriptorSetLayout[PIPELINE_CACHE_NDX_COUNT];
989         Move<VkDescriptorSet>                   m_descriptorSet[PIPELINE_CACHE_NDX_COUNT];
990
991         Move<VkPipelineLayout>                  m_pipelineLayout[PIPELINE_CACHE_NDX_COUNT];
992         VkPipeline                                              m_pipeline[PIPELINE_CACHE_NDX_COUNT];
993         VkPipelineCreationFeedbackEXT   m_pipelineCreationFeedback[PIPELINE_CACHE_NDX_COUNT];
994         VkPipelineCreationFeedbackEXT   m_pipelineStageCreationFeedback[PIPELINE_CACHE_NDX_COUNT];
995 };
996
997 void ComputeCacheTest::initPrograms (SourceCollections& programCollection) const
998 {
999         programCollection.glslSources.add("basic_compute_1") << glu::ComputeSource(
1000                 "#version 310 es\n"
1001                 "layout(local_size_x = 1) in;\n"
1002                 "layout(std430) buffer;\n"
1003                 "layout(binding = 0) readonly buffer Input0\n"
1004                 "{\n"
1005                 "  vec4 elements[];\n"
1006                 "} input_data0;\n"
1007                 "layout(binding = 1) writeonly buffer Output\n"
1008                 "{\n"
1009                 "  vec4 elements[];\n"
1010                 "} output_data;\n"
1011                 "void main()\n"
1012                 "{\n"
1013                 "  uint ident = gl_GlobalInvocationID.x;\n"
1014                 "  output_data.elements[ident] = input_data0.elements[ident] * input_data0.elements[ident];\n"
1015                 "}");
1016         programCollection.glslSources.add("basic_compute_2") << glu::ComputeSource(
1017                 "#version 310 es\n"
1018                 "layout(local_size_x = 1) in;\n"
1019                 "layout(std430) buffer;\n"
1020                 "layout(binding = 0) readonly buffer Input0\n"
1021                 "{\n"
1022                 "  vec4 elements[];\n"
1023                 "} input_data0;\n"
1024                 "layout(binding = 1) writeonly buffer Output\n"
1025                 "{\n"
1026                 "  vec4 elements[];\n"
1027                 "} output_data;\n"
1028                 "void main()\n"
1029                 "{\n"
1030                 "  uint ident = gl_GlobalInvocationID.x;\n"
1031                 "  output_data.elements[ident] = input_data0.elements[ident];\n"
1032                 "}");
1033 }
1034
1035 TestInstance* ComputeCacheTest::createInstance (Context& context) const
1036 {
1037         return new ComputeCacheTestInstance(context, &m_param);
1038 }
1039
1040 void ComputeCacheTestInstance::buildDescriptorSets (deUint32 ndx)
1041 {
1042         const DeviceInterface&  vk                              = m_context.getDeviceInterface();
1043         const VkDevice                  vkDevice                = m_context.getDevice();
1044
1045         // Create descriptor set layout
1046         DescriptorSetLayoutBuilder descLayoutBuilder;
1047         for (deUint32 bindingNdx = 0u; bindingNdx < 2u; bindingNdx++)
1048                 descLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
1049         m_descriptorSetLayout[ndx] = descLayoutBuilder.build(vk, vkDevice);
1050 }
1051
1052 void ComputeCacheTestInstance::buildShader (deUint32 ndx)
1053 {
1054         const DeviceInterface&  vk                              = m_context.getDeviceInterface();
1055         const VkDevice                  vkDevice                = m_context.getDevice();
1056
1057         std::string shader_name("basic_compute_");
1058
1059         shader_name += (ndx == PIPELINE_CACHE_NDX_DERIVATIVE) ? "2" : "1";
1060
1061         // Create compute shader
1062         VkShaderModuleCreateInfo shaderModuleCreateInfo =
1063         {
1064                 VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,                                                            // VkStructureType                              sType;
1065                 DE_NULL,                                                                                                                                        // const void*                                  pNext;
1066                 0u,                                                                                                                                             // VkShaderModuleCreateFlags    flags;
1067                 m_context.getBinaryCollection().get(shader_name).getSize(),                             // deUintptr                                    codeSize;
1068                 (deUint32*)m_context.getBinaryCollection().get(shader_name).getBinary(),        // const deUint32*                              pCode;
1069         };
1070         m_computeShaderModule[ndx] = createShaderModule(vk, vkDevice, &shaderModuleCreateInfo);
1071 }
1072
1073 void ComputeCacheTestInstance::buildPipeline (const CacheTestParam*     param, deUint32 ndx)
1074 {
1075         const DeviceInterface&  vk                               = m_context.getDeviceInterface();
1076         const VkDevice                  vkDevice                 = m_context.getDevice();
1077
1078         deMemset(&m_pipelineCreationFeedback[ndx], 0, sizeof(VkPipelineCreationFeedbackEXT));
1079         deMemset(&m_pipelineStageCreationFeedback[ndx], 0, sizeof(VkPipelineCreationFeedbackEXT));
1080
1081         const VkPipelineCreationFeedbackCreateInfoEXT pipelineCreationFeedbackCreateInfo =
1082         {
1083                 VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT,   // VkStructureType                                      sType;
1084                 DE_NULL,                                                                                                                // const void *                                         pNext;
1085                 &m_pipelineCreationFeedback[ndx],                                                               // VkPipelineCreationFeedbackEXT*       pPipelineCreationFeedback;
1086                 1u,                                                                                                                     // deUint32                                             pipelineStageCreationFeedbackCount;
1087                 &m_pipelineStageCreationFeedback[ndx]                                                   // VkPipelineCreationFeedbackEXT*       pPipelineStageCreationFeedbacks;
1088         };
1089
1090         // Create compute pipeline layout
1091         const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
1092         {
1093                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,                                  // VkStructureType                                      sType;
1094                 DE_NULL,                                                                                                                // const void*                                          pNext;
1095                 0u,                                                                                                                     // VkPipelineLayoutCreateFlags          flags;
1096                 1u,                                                                                                                     // deUint32                                             setLayoutCount;
1097                 &m_descriptorSetLayout[ndx].get(),                                                              // const VkDescriptorSetLayout* pSetLayouts;
1098                 0u,                                                                                                                     // deUint32                                             pushConstantRangeCount;
1099                 DE_NULL,                                                                                                                // const VkPushConstantRange*           pPushConstantRanges;
1100         };
1101
1102         m_pipelineLayout[ndx] = createPipelineLayout(vk, vkDevice, &pipelineLayoutCreateInfo);
1103
1104         const VkPipelineShaderStageCreateInfo stageCreateInfo =
1105         {
1106                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,                    // VkStructureType                                      sType;
1107                 DE_NULL,                                                                                                                // const void*                                          pNext;
1108                 0u,                                                                                                                     // VkPipelineShaderStageCreateFlags     flags;
1109                 VK_SHADER_STAGE_COMPUTE_BIT,                                                                    // VkShaderStageFlagBits                                stage;
1110                 *m_computeShaderModule[ndx],                                                                    // VkShaderModule                                               module;
1111                 "main",                                                                                                         // const char*                                          pName;
1112                 DE_NULL,                                                                                                                // const VkSpecializationInfo*          pSpecializationInfo;
1113         };
1114
1115         VkComputePipelineCreateInfo pipelineCreateInfo =
1116         {
1117                 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,                         // VkStructureType                                      sType;
1118                 &pipelineCreationFeedbackCreateInfo,                                                    // const void*                                          pNext;
1119                 0u,                                                                                                                     // VkPipelineCreateFlags                        flags;
1120                 stageCreateInfo,                                                                                                // VkPipelineShaderStageCreateInfo      stage;
1121                 *m_pipelineLayout[ndx],                                                                         // VkPipelineLayout                             layout;
1122                 (VkPipeline)0,                                                                                                  // VkPipeline                                           basePipelineHandle;
1123                 0u,                                                                                                                     // deInt32                                                      basePipelineIndex;
1124         };
1125
1126         if (ndx != PIPELINE_CACHE_NDX_DERIVATIVE)
1127         {
1128                 pipelineCreateInfo.flags = VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT;
1129         }
1130
1131         if (ndx == PIPELINE_CACHE_NDX_DERIVATIVE)
1132         {
1133                 pipelineCreateInfo.flags = VK_PIPELINE_CREATE_DERIVATIVE_BIT;
1134                 pipelineCreateInfo.basePipelineHandle = m_pipeline[PIPELINE_CACHE_NDX_NO_CACHE];
1135                 pipelineCreateInfo.basePipelineIndex = -1;
1136         }
1137
1138         if (ndx == PIPELINE_CACHE_NDX_CACHED && !param->isDelayedDestroy())
1139         {
1140                 // Destroy the NO_CACHE pipeline to check that the cached one really hits cache,
1141                 // except for the case where we're testing cache hit of a pipeline still active.
1142                 vk.destroyPipeline(vkDevice, m_pipeline[PIPELINE_CACHE_NDX_NO_CACHE], DE_NULL);
1143         }
1144
1145         vk.createComputePipelines(vkDevice, *m_cache, 1u, &pipelineCreateInfo, DE_NULL, &m_pipeline[ndx]);
1146
1147         if (ndx != PIPELINE_CACHE_NDX_NO_CACHE)
1148         {
1149                 // Destroy the pipeline as soon as it is created, except the NO_CACHE because
1150                 // it is needed as a base pipeline for the derivative case.
1151                 vk.destroyPipeline(vkDevice, m_pipeline[ndx], DE_NULL);
1152
1153                 if (ndx == PIPELINE_CACHE_NDX_CACHED && param->isDelayedDestroy())
1154                 {
1155                         // Destroy the pipeline we didn't destroy earlier for the isDelayedDestroy case.
1156                         vk.destroyPipeline(vkDevice, m_pipeline[PIPELINE_CACHE_NDX_NO_CACHE], DE_NULL);
1157                 }
1158         }
1159 }
1160
1161 ComputeCacheTestInstance::ComputeCacheTestInstance (Context&                            context,
1162                                                                                                         const CacheTestParam*   param)
1163         : CacheTestInstance (context, param)
1164 {
1165         for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
1166         {
1167                 buildDescriptorSets(ndx);
1168                 buildShader(ndx);
1169                 buildPipeline(param, ndx);
1170         }
1171 }
1172
1173 ComputeCacheTestInstance::~ComputeCacheTestInstance (void)
1174 {
1175 }
1176
1177 tcu::TestStatus ComputeCacheTestInstance::verifyTestResult (void)
1178 {
1179         tcu::TestLog &log                               = m_context.getTestContext().getLog();
1180         deBool durationZeroWarning              = DE_FALSE;
1181         deBool cachedPipelineWarning    = DE_FALSE;
1182
1183         for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
1184         {
1185                 std::ostringstream message;
1186                 message << getCaseStr(ndx);
1187
1188                 // No need to check per stage status as it is compute pipeline (only one stage) and Vulkan spec mentions that:
1189                 // "One common scenario for an implementation to skip per-stage feedback is when
1190                 // VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT is set in pPipelineCreationFeedback."
1191                 //
1192                 // Check first that the no cached pipeline was missed in the pipeline cache
1193                 if (!(m_pipelineCreationFeedback[ndx].flags & VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT))
1194                 {
1195                         message << ": invalid data";
1196                         return tcu::TestStatus::fail(message.str());
1197                 }
1198
1199                 if (m_param->isCacheDisabled() && m_pipelineCreationFeedback[ndx].flags & VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT)
1200                 {
1201                         message << ": feedback indicates pipeline hit cache when it shouldn't";
1202                         return tcu::TestStatus::fail(message.str());
1203                 }
1204
1205                 if (ndx == PIPELINE_CACHE_NDX_NO_CACHE && m_pipelineCreationFeedback[ndx].flags & VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT)
1206                 {
1207                         message << ": hit the cache when it shouldn't";
1208                         return tcu::TestStatus::fail(message.str());
1209                 }
1210
1211                 if (!(ndx == PIPELINE_CACHE_NDX_DERIVATIVE && !m_param->isCacheDisabled()) && m_pipelineCreationFeedback[ndx].flags & VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT_EXT)
1212                 {
1213                         message << ": feedback indicates base pipeline acceleration when it shouldn't";
1214                         return tcu::TestStatus::fail(message.str());
1215                 }
1216
1217                 if (ndx == PIPELINE_CACHE_NDX_CACHED && !m_param->isCacheDisabled() && (m_pipelineCreationFeedback[ndx].flags & VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT) == 0)
1218                 {
1219                         message << "\nWarning: Cached pipeline case did not hit the cache";
1220                         cachedPipelineWarning = DE_TRUE;
1221                 }
1222
1223                 if (m_pipelineCreationFeedback[ndx].duration == 0)
1224                 {
1225                         message << "\nWarning: Pipeline creation feedback reports duration spent creating a pipeline was zero nanoseconds\n";
1226                         durationZeroWarning = DE_TRUE;
1227                 }
1228
1229                 message << "\n";
1230
1231                 message << "\t\t Hit cache ? \t\t\t"                            << (m_pipelineCreationFeedback[ndx].flags & VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT ? "yes" : "no")        << "\n";
1232                 message << "\t\t Base Pipeline Acceleration ? \t"       << (m_pipelineCreationFeedback[ndx].flags & VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT_EXT ? "yes" : "no")            << "\n";
1233                 message << "\t\t Duration (ns): \t\t"                           << m_pipelineCreationFeedback[ndx].duration                                                                                                                                                                             << "\n";
1234
1235                 message << "\t Compute Stage\n";
1236
1237                 // According to the spec:
1238                 //
1239                 // "An implementation should write pipeline creation feedback to pPipelineCreationFeedback and
1240                 //      may write pipeline stage creation feedback to pPipelineStageCreationFeedbacks."
1241                 if (!(m_pipelineStageCreationFeedback[ndx].flags & VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT))
1242                 {
1243                         // According to the spec:
1244                         // "If the VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT is not set in flags, an implementation
1245                         //      must not set any other bits in flags, and all other VkPipelineCreationFeedbackEXT data members are undefined."
1246                         if (m_pipelineStageCreationFeedback[ndx].flags)
1247                         {
1248                                 std::ostringstream                      errorMsg;
1249                                 errorMsg << getCaseStr(ndx) << ": Creation feedback is not valid for compute stage but there are other flags written";
1250                                 return tcu::TestStatus::fail(errorMsg.str());
1251                         }
1252                         message << "\t\t Pipeline Creation Feedback data is not valid\n";
1253                 }
1254                 else
1255                 {
1256                         if (m_param->isCacheDisabled() && m_pipelineStageCreationFeedback[ndx].flags & VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT)
1257                         {
1258                                 std::ostringstream                      errorMsg;
1259                                 errorMsg << getCaseStr(ndx) << ": feedback indicates pipeline compute stage hit cache when it shouldn't";
1260                                 return tcu::TestStatus::fail(errorMsg.str());
1261                         }
1262
1263                         if (ndx == PIPELINE_CACHE_NDX_CACHED && !m_param->isCacheDisabled() && (m_pipelineStageCreationFeedback[ndx].flags & VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT) == 0)
1264                         {
1265                                 message << "Warning: pipeline stage did not hit the cache\n";
1266                                 cachedPipelineWarning = DE_TRUE;
1267                         }
1268                         if (cachedPipelineWarning && m_pipelineStageCreationFeedback[ndx].flags & VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT)
1269                         {
1270                                 // We only set the warning when the pipeline nor the pipeline stages hit the cache. If any of them did, them disable the warning.
1271                                 cachedPipelineWarning = DE_FALSE;
1272                         }
1273
1274                         message << "\t\t Hit cache ? \t\t\t"                            << (m_pipelineStageCreationFeedback[ndx].flags & VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT ? "yes" : "no")   << "\n";
1275                         message << "\t\t Base Pipeline Acceleration ? \t"       << (m_pipelineStageCreationFeedback[ndx].flags & VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT_EXT ? "yes" : "no")               << "\n";
1276                         message << "\t\t Duration (ns): \t\t"                           << m_pipelineStageCreationFeedback[ndx].duration                                                                                                                                                                                << "\n";
1277                 }
1278
1279                 log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
1280         }
1281
1282         if (cachedPipelineWarning)
1283         {
1284                 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Cached pipeline or stage did not hit the cache");
1285         }
1286         if (durationZeroWarning)
1287         {
1288                 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Pipeline creation feedback reports duration spent creating a pipeline was zero nanoseconds");
1289         }
1290         return tcu::TestStatus::pass("Pass");
1291 }
1292 } // anonymous
1293
1294 tcu::TestCaseGroup* createCreationFeedbackTests (tcu::TestContext& testCtx)
1295 {
1296         de::MovePtr<tcu::TestCaseGroup> cacheTests (new tcu::TestCaseGroup(testCtx, "creation_feedback", "pipeline creation feedback tests"));
1297
1298         // Graphics Pipeline Tests
1299         {
1300                 de::MovePtr<tcu::TestCaseGroup> graphicsTests (new tcu::TestCaseGroup(testCtx, "graphics_tests", "Test pipeline creation feedback with graphics pipeline."));
1301
1302                 const VkShaderStageFlagBits testParamShaders0[] =
1303                 {
1304                         VK_SHADER_STAGE_VERTEX_BIT,
1305                         VK_SHADER_STAGE_FRAGMENT_BIT,
1306                 };
1307                 const VkShaderStageFlagBits testParamShaders1[] =
1308                 {
1309                         VK_SHADER_STAGE_VERTEX_BIT,
1310                         VK_SHADER_STAGE_GEOMETRY_BIT,
1311                         VK_SHADER_STAGE_FRAGMENT_BIT,
1312                 };
1313                 const VkShaderStageFlagBits testParamShaders2[] =
1314                 {
1315                         VK_SHADER_STAGE_VERTEX_BIT,
1316                         VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
1317                         VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
1318                         VK_SHADER_STAGE_FRAGMENT_BIT,
1319                 };
1320                 const CacheTestParam testParams[] =
1321                 {
1322                         CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE, DE_FALSE),
1323                         CacheTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), DE_FALSE, DE_FALSE),
1324                         CacheTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), DE_FALSE, DE_FALSE),
1325                         CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_TRUE, DE_FALSE),
1326                         CacheTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), DE_TRUE, DE_FALSE),
1327                         CacheTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), DE_TRUE, DE_FALSE),
1328                         CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE, DE_TRUE),
1329                         CacheTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1), DE_FALSE, DE_TRUE),
1330                         CacheTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2), DE_FALSE, DE_TRUE),
1331                 };
1332
1333                 for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
1334                         graphicsTests->addChild(newTestCase<GraphicsCacheTest>(testCtx, &testParams[i]));
1335
1336                 cacheTests->addChild(graphicsTests.release());
1337         }
1338
1339         // Compute Pipeline Tests
1340         {
1341                 de::MovePtr<tcu::TestCaseGroup> computeTests (new tcu::TestCaseGroup(testCtx, "compute_tests", "Test pipeline creation feedback with compute pipeline."));
1342
1343                 const VkShaderStageFlagBits testParamShaders0[] =
1344                 {
1345                         VK_SHADER_STAGE_COMPUTE_BIT,
1346                 };
1347                 const CacheTestParam testParams[] =
1348                 {
1349                         CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE, DE_FALSE),
1350                         CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_TRUE, DE_FALSE),
1351                         CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0), DE_FALSE, DE_TRUE),
1352                 };
1353
1354                 for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
1355                         computeTests->addChild(newTestCase<ComputeCacheTest>(testCtx, &testParams[i]));
1356
1357                 cacheTests->addChild(computeTests.release());
1358         }
1359
1360         return cacheTests.release();
1361 }
1362
1363 } // pipeline
1364
1365 } // vkt