Fix tests in dEQP-EGL.functional.robustness* am: fd0b6eda1c am: d3ac80fae5 am: 54c4090dfe
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / pipeline / vktPipelineCacheTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 ARM Ltd.
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 "vktPipelineCacheTests.hpp"
26 #include "vktPipelineClearUtil.hpp"
27 #include "vktPipelineImageUtil.hpp"
28 #include "vktPipelineVertexUtil.hpp"
29 #include "vktTestCase.hpp"
30 #include "vktTestCaseUtil.hpp"
31 #include "vkImageUtil.hpp"
32 #include "vkMemUtil.hpp"
33 #include "vkPrograms.hpp"
34 #include "vkBuilderUtil.hpp"
35 #include "vkQueryUtil.hpp"
36 #include "vkRef.hpp"
37 #include "vkRefUtil.hpp"
38 #include "tcuImageCompare.hpp"
39 #include "deUniquePtr.hpp"
40 #include "deMemory.h"
41 #include "vkTypeUtil.hpp"
42
43 #include <sstream>
44 #include <vector>
45
46 namespace vkt
47 {
48 namespace pipeline
49 {
50
51 using namespace vk;
52
53 namespace
54 {
55 enum
56 {
57         VK_MAX_SHADER_STAGES = 6,
58 };
59
60 // helper functions
61
62 std::string getShaderFlagStr (const VkShaderStageFlagBits shader,
63                                                           bool                        isDescription)
64 {
65         std::ostringstream desc;
66         switch(shader)
67         {
68                 case VK_SHADER_STAGE_VERTEX_BIT:
69                 {
70                         desc << ((isDescription) ? "vertex stage" : "vertex_stage");
71                         break;
72                 }
73                 case VK_SHADER_STAGE_FRAGMENT_BIT:
74                 {
75                         desc << ((isDescription) ? "fragment stage" : "fragment_stage");
76                         break;
77                 }
78                 case VK_SHADER_STAGE_GEOMETRY_BIT:
79                 {
80                         desc << ((isDescription) ? "geometry stage" : "geometry_stage");
81                         break;
82                 }
83                 case VK_SHADER_STAGE_COMPUTE_BIT:
84                 {
85                         desc << ((isDescription) ? "compute stage" : "compute_stage");
86                         break;
87                 }
88                 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
89                 {
90                         desc << ((isDescription) ? "tessellation control stage" : "tessellation_control_stage");
91                         break;
92                 }
93                 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
94                 {
95                         desc << ((isDescription) ? "tessellation evaluation stage" : "tessellation_evaluation_stage");
96                         break;
97                 }
98           default:
99                 desc << "unknown shader stage!";
100                 DE_FATAL("Unknown shader Stage!");
101                 break;
102         };
103
104         return desc.str();
105 }
106
107 // helper classes
108 class CacheTestParam
109 {
110 public:
111                                                                 CacheTestParam          (const VkShaderStageFlagBits* shaders,
112                                                                                                                  deUint32                     count);
113         virtual                                         ~CacheTestParam         (void);
114         virtual const std::string   generateTestName        (void)          const;
115         virtual const std::string   generateTestDescription (void)          const;
116         VkShaderStageFlagBits       getShaderFlag           (deUint32 ndx)  const   { return m_shaders[ndx]; }
117         deUint32                    getShaderCount          (void)          const   { return (deUint32)m_shaderCount; }
118 protected:
119         VkShaderStageFlagBits       m_shaders[VK_MAX_SHADER_STAGES];
120         size_t                      m_shaderCount;
121 };
122
123 CacheTestParam::CacheTestParam (const VkShaderStageFlagBits* shaders, deUint32 count)
124 {
125         DE_ASSERT(count <= VK_MAX_SHADER_STAGES);
126         for (deUint32 ndx = 0; ndx < count; ndx++)
127                 m_shaders[ndx] = shaders[ndx];
128         m_shaderCount = count;
129 }
130
131 CacheTestParam::~CacheTestParam (void)
132 {
133 }
134
135 const std::string CacheTestParam::generateTestName (void) const
136 {
137         std::string result(getShaderFlagStr(m_shaders[0], false));
138
139         for(deUint32 ndx = 1; ndx < m_shaderCount; ndx++)
140                 result += '_' + getShaderFlagStr(m_shaders[ndx], false) ;
141
142         return result;
143 }
144
145 const std::string CacheTestParam::generateTestDescription (void) const
146 {
147         std::string result("Create pipeline cache with " + getShaderFlagStr(m_shaders[0], true));
148
149         for(deUint32 ndx = 1; ndx < m_shaderCount; ndx++)
150                 result += ' ' + getShaderFlagStr(m_shaders[ndx], true);
151
152         return result;
153 }
154
155 class SimpleGraphicsPipelineBuilder
156 {
157 public:
158                                                         SimpleGraphicsPipelineBuilder   (Context&                               context);
159                                                         ~SimpleGraphicsPipelineBuilder  (void) { }
160         void                                    bindShaderStage                                 (VkShaderStageFlagBits  stage,
161                                                                                                                          const char*                    sourceName,
162                                                                                                                          const char*                    entryName);
163         void                                    enableTessellationStage                 (deUint32                               patchControlPoints);
164         Move<VkPipeline>                buildPipeline                                   (tcu::UVec2                             renderSize,
165                                                                                                                          VkRenderPass                   renderPass,
166                                                                                                                          VkPipelineCache                cache,
167                                                                                                                          VkPipelineLayout               pipelineLayout);
168 protected:
169         Context&                            m_context;
170
171         Move<VkShaderModule>                m_shaderModules[VK_MAX_SHADER_STAGES];
172         deUint32                            m_shaderStageCount;
173         VkPipelineShaderStageCreateInfo     m_shaderStageInfo[VK_MAX_SHADER_STAGES];
174
175         deUint32                            m_patchControlPoints;
176 };
177
178 SimpleGraphicsPipelineBuilder::SimpleGraphicsPipelineBuilder (Context& context)
179         : m_context(context)
180 {
181         m_patchControlPoints = 0;
182         m_shaderStageCount   = 0;
183 }
184
185 void SimpleGraphicsPipelineBuilder::bindShaderStage (VkShaderStageFlagBits stage,
186                                                                                                          const char*           sourceName,
187                                                                                                          const char*           entryName)
188 {
189         const DeviceInterface&  vk        = m_context.getDeviceInterface();
190         const VkDevice          vkDevice  = m_context.getDevice();
191
192         // Create shader module
193         deUint32*               code     = (deUint32*)m_context.getBinaryCollection().get(sourceName).getBinary();
194         deUint32                codeSize  = (deUint32)m_context.getBinaryCollection().get(sourceName).getSize();
195
196         const VkShaderModuleCreateInfo moduleCreateInfo =
197         {
198                 VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,                // VkStructureType             sType;
199                 DE_NULL,                                                    // const void*                 pNext;
200                 0u,                                                         // VkShaderModuleCreateFlags   flags;
201                 codeSize,                                                   // deUintptr                   codeSize;
202                 code,                                                       // const deUint32*             pCode;
203         };
204
205         m_shaderModules[m_shaderStageCount] = createShaderModule(vk, vkDevice, &moduleCreateInfo);
206
207         // Prepare shader stage info
208         m_shaderStageInfo[m_shaderStageCount].sType               = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
209         m_shaderStageInfo[m_shaderStageCount].pNext               = DE_NULL;
210         m_shaderStageInfo[m_shaderStageCount].flags               = 0u;
211         m_shaderStageInfo[m_shaderStageCount].stage               = stage;
212         m_shaderStageInfo[m_shaderStageCount].module              = *m_shaderModules[m_shaderStageCount];
213         m_shaderStageInfo[m_shaderStageCount].pName               = entryName;
214         m_shaderStageInfo[m_shaderStageCount].pSpecializationInfo = DE_NULL;
215
216         m_shaderStageCount++;
217 }
218
219 Move<VkPipeline> SimpleGraphicsPipelineBuilder::buildPipeline (tcu::UVec2 renderSize, VkRenderPass renderPass, VkPipelineCache cache, VkPipelineLayout pipelineLayout)
220 {
221         const DeviceInterface&      vk                  = m_context.getDeviceInterface();
222         const VkDevice              vkDevice            = m_context.getDevice();
223
224         // Create pipeline
225         const VkVertexInputBindingDescription vertexInputBindingDescription =
226         {
227                 0u,                                 // deUint32                 binding;
228                 sizeof(Vertex4RGBA),                // deUint32                 strideInBytes;
229                 VK_VERTEX_INPUT_RATE_VERTEX,        // VkVertexInputRate        inputRate;
230         };
231
232         const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
233         {
234                 {
235                         0u,                                 // deUint32 location;
236                         0u,                                 // deUint32 binding;
237                         VK_FORMAT_R32G32B32A32_SFLOAT,      // VkFormat format;
238                         0u                                  // deUint32 offsetInBytes;
239                 },
240                 {
241                         1u,                                 // deUint32 location;
242                         0u,                                 // deUint32 binding;
243                         VK_FORMAT_R32G32B32A32_SFLOAT,      // VkFormat format;
244                         DE_OFFSET_OF(Vertex4RGBA, color),   // deUint32 offsetInBytes;
245                 }
246         };
247
248         const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
249         {
250                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,      // VkStructureType                          sType;
251                 DE_NULL,                                                        // const void*                              pNext;
252                 0u,                                                             // VkPipelineVertexInputStateCreateFlags    flags;
253                 1u,                                                             // deUint32                                 vertexBindingDescriptionCount;
254                 &vertexInputBindingDescription,                                 // const VkVertexInputBindingDescription*   pVertexBindingDescriptions;
255                 2u,                                                             // deUint32                                 vertexAttributeDescriptionCount;
256                 vertexInputAttributeDescriptions,                               // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
257         };
258
259         const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
260         {
261                 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                          sType;
262                 DE_NULL,                                                        // const void*                              pNext;
263                 0u,                                                             // VkPipelineInputAssemblyStateCreateFlags  flags;
264                 (m_patchControlPoints == 0 ? VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
265                                                                    : VK_PRIMITIVE_TOPOLOGY_PATCH_LIST), // VkPrimitiveTopology                      topology;
266                 VK_FALSE,                                                       // VkBool32                                 primitiveRestartEnable;
267         };
268
269         const VkViewport viewport =
270         {
271                 0.0f,                       // float    originX;
272                 0.0f,                       // float    originY;
273                 (float)renderSize.x(),      // float    width;
274                 (float)renderSize.y(),      // float    height;
275                 0.0f,                       // float    minDepth;
276                 1.0f                        // float    maxDepth;
277         };
278         const VkRect2D scissor =
279         {
280                 { 0, 0 },                                                       // VkOffset2D  offset;
281                 { renderSize.x(), renderSize.y() }                              // VkExtent2D  extent;
282         };
283         const VkPipelineViewportStateCreateInfo viewportStateParams =
284         {
285                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,          // VkStructureType                      sType;
286                 DE_NULL,                                                        // const void*                          pNext;
287                 0u,                                                             // VkPipelineViewportStateCreateFlags   flags;
288                 1u,                                                             // deUint32                             viewportCount;
289                 &viewport,                                                      // const VkViewport*                    pViewports;
290                 1u,                                                             // deUint32                             scissorCount;
291                 &scissor                                                        // const VkRect2D*                      pScissors;
292         };
293
294         const VkPipelineRasterizationStateCreateInfo rasterStateParams =
295         {
296                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,     // VkStructureType                          sType;
297                 DE_NULL,                                                        // const void*                              pNext;
298                 0u,                                                             // VkPipelineRasterizationStateCreateFlags  flags;
299                 VK_FALSE,                                                       // VkBool32                                 depthClampEnable;
300                 VK_FALSE,                                                       // VkBool32                                 rasterizerDiscardEnable;
301                 VK_POLYGON_MODE_FILL,                                           // VkPolygonMode                            polygonMode;
302                 VK_CULL_MODE_NONE,                                              // VkCullModeFlags                          cullMode;
303                 VK_FRONT_FACE_COUNTER_CLOCKWISE,                                // VkFrontFace                              frontFace;
304                 VK_FALSE,                                                       // VkBool32                                 depthBiasEnable;
305                 0.0f,                                                           // float                                    depthBiasConstantFactor;
306                 0.0f,                                                           // float                                    depthBiasClamp;
307                 0.0f,                                                           // float                                    depthBiasSlopeFactor;
308                 1.0f,                                                           // float                                    lineWidth;
309         };
310
311         const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
312         {
313                 VK_FALSE,                                                                   // VkBool32                 blendEnable;
314                 VK_BLEND_FACTOR_ONE,                                                        // VkBlendFactor            srcColorBlendFactor;
315                 VK_BLEND_FACTOR_ZERO,                                                       // VkBlendFactor            dstColorBlendFactor;
316                 VK_BLEND_OP_ADD,                                                            // VkBlendOp                colorBlendOp;
317                 VK_BLEND_FACTOR_ONE,                                                        // VkBlendFactor            srcAlphaBlendFactor;
318                 VK_BLEND_FACTOR_ZERO,                                                       // VkBlendFactor            dstAlphaBlendFactor;
319                 VK_BLEND_OP_ADD,                                                            // VkBlendOp                alphaBlendOp;
320                 VK_COLOR_COMPONENT_R_BIT |
321                 VK_COLOR_COMPONENT_G_BIT |
322                 VK_COLOR_COMPONENT_B_BIT |
323                 VK_COLOR_COMPONENT_A_BIT                                                    // VkColorComponentFlags    colorWriteMask;
324         };
325
326         const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
327         {
328                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,   // VkStructureType                              sType;
329                 DE_NULL,                                                    // const void*                                  pNext;
330                 0u,                                                         // VkPipelineColorBlendStateCreateFlags         flags;
331                 VK_FALSE,                                                   // VkBool32                                     logicOpEnable;
332                 VK_LOGIC_OP_COPY,                                           // VkLogicOp                                    logicOp;
333                 1u,                                                         // deUint32                                     attachmentCount;
334                 &colorBlendAttachmentState,                                 // const VkPipelineColorBlendAttachmentState*   pAttachments;
335                 { 0.0f, 0.0f, 0.0f, 0.0f },                                 // float                                        blendConst[4];
336         };
337
338         const VkPipelineMultisampleStateCreateInfo  multisampleStateParams  =
339         {
340                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,   // VkStructureType                          sType;
341                 DE_NULL,                                                    // const void*                              pNext;
342                 0u,                                                         // VkPipelineMultisampleStateCreateFlags    flags;
343                 VK_SAMPLE_COUNT_1_BIT,                                      // VkSampleCountFlagBits                    rasterizationSamples;
344                 VK_FALSE,                                                   // VkBool32                                 sampleShadingEnable;
345                 0.0f,                                                       // float                                    minSampleShading;
346                 DE_NULL,                                                    // const VkSampleMask*                      pSampleMask;
347                 VK_FALSE,                                                   // VkBool32                                 alphaToCoverageEnable;
348                 VK_FALSE,                                                   // VkBool32                                 alphaToOneEnable;
349         };
350
351         VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
352         {
353                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType                          sType;
354                 DE_NULL,                                                    // const void*                              pNext;
355                 0u,                                                         // VkPipelineDepthStencilStateCreateFlags   flags;
356                 VK_TRUE,                                                    // VkBool32                                 depthTestEnable;
357                 VK_TRUE,                                                    // VkBool32                                 depthWriteEnable;
358                 VK_COMPARE_OP_LESS_OR_EQUAL,                                // VkCompareOp                              depthCompareOp;
359                 VK_FALSE,                                                   // VkBool32                                 depthBoundsTestEnable;
360                 VK_FALSE,                                                   // VkBool32                                 stencilTestEnable;
361                 // VkStencilOpState front;
362                 {
363                         VK_STENCIL_OP_KEEP,     // VkStencilOp  failOp;
364                         VK_STENCIL_OP_KEEP,     // VkStencilOp  passOp;
365                         VK_STENCIL_OP_KEEP,     // VkStencilOp  depthFailOp;
366                         VK_COMPARE_OP_NEVER,    // VkCompareOp  compareOp;
367                         0u,                     // deUint32     compareMask;
368                         0u,                     // deUint32     writeMask;
369                         0u,                     // deUint32     reference;
370                 },
371                 // VkStencilOpState back;
372                 {
373                         VK_STENCIL_OP_KEEP,     // VkStencilOp  failOp;
374                         VK_STENCIL_OP_KEEP,     // VkStencilOp  passOp;
375                         VK_STENCIL_OP_KEEP,     // VkStencilOp  depthFailOp;
376                         VK_COMPARE_OP_NEVER,    // VkCompareOp  compareOp;
377                         0u,                     // deUint32     compareMask;
378                         0u,                     // deUint32     writeMask;
379                         0u,                     // deUint32     reference;
380                 },
381                 0.0f,                                                      // float                                    minDepthBounds;
382                 1.0f,                                                      // float                                    maxDepthBounds;
383         };
384
385         const VkPipelineTessellationStateCreateInfo tessStateCreateInfo =
386         {
387                 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,  // VkStructureType                          sType;
388                 DE_NULL,                                                    // const void*                              pNext;
389                 0u,                                                         // VkPipelineTesselationStateCreateFlags    flags;
390                 m_patchControlPoints,                                       // deUint32                                 patchControlPoints;
391         };
392         const VkPipelineTessellationStateCreateInfo* pTessCreateInfo = (m_patchControlPoints > 0)
393                                                                                                                                   ? &tessStateCreateInfo
394                                                                                                                                   : DE_NULL;
395
396         const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
397         {
398                 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,    // VkStructureType                                  sType;
399                 DE_NULL,                                            // const void*                                      pNext;
400                 0u,                                                 // VkPipelineCreateFlags                            flags;
401                 m_shaderStageCount,                                 // deUint32                                         stageCount;
402                 m_shaderStageInfo,                                  // const VkPipelineShaderStageCreateInfo*           pStages;
403                 &vertexInputStateParams,                            // const VkPipelineVertexInputStateCreateInfo*      pVertexInputState;
404                 &inputAssemblyStateParams,                          // const VkPipelineInputAssemblyStateCreateInfo*    pInputAssemblyState;
405                 pTessCreateInfo,                                    // const VkPipelineTessellationStateCreateInfo*     pTessellationState;
406                 &viewportStateParams,                               // const VkPipelineViewportStateCreateInfo*         pViewportState;
407                 &rasterStateParams,                                 // const VkPipelineRasterizationStateCreateInfo*    pRasterState;
408                 &multisampleStateParams,                            // const VkPipelineMultisampleStateCreateInfo*      pMultisampleState;
409                 &depthStencilStateParams,                           // const VkPipelineDepthStencilStateCreateInfo*     pDepthStencilState;
410                 &colorBlendStateParams,                             // const VkPipelineColorBlendStateCreateInfo*       pColorBlendState;
411                 (const VkPipelineDynamicStateCreateInfo*)DE_NULL,   // const VkPipelineDynamicStateCreateInfo*          pDynamicState;
412                 pipelineLayout,                                     // VkPipelineLayout                                 layout;
413                 renderPass,                                         // VkRenderPass                                     renderPass;
414                 0u,                                                 // deUint32                                         subpass;
415                 0u,                                                 // VkPipeline                                       basePipelineHandle;
416                 0,                                                  // deInt32                                          basePipelineIndex;
417         };
418
419         return createGraphicsPipeline(vk, vkDevice, cache, &graphicsPipelineParams);
420 }
421
422 void SimpleGraphicsPipelineBuilder::enableTessellationStage (deUint32 patchControlPoints)
423 {
424         m_patchControlPoints = patchControlPoints;
425 }
426
427 template <class Test>
428 vkt::TestCase* newTestCase (tcu::TestContext&     testContext,
429                                                         const CacheTestParam* testParam)
430 {
431         return new Test(testContext,
432                                         testParam->generateTestName().c_str(),
433                                         testParam->generateTestDescription().c_str(),
434                                         testParam);
435 }
436
437 Move<VkBuffer> createBufferAndBindMemory (Context& context, VkDeviceSize size, VkBufferUsageFlags usage, de::MovePtr<Allocation>* pAlloc)
438 {
439         const DeviceInterface&  vk               = context.getDeviceInterface();
440         const VkDevice          vkDevice         = context.getDevice();
441         const deUint32          queueFamilyIndex = context.getUniversalQueueFamilyIndex();
442
443         const VkBufferCreateInfo vertexBufferParams =
444         {
445                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,       // VkStructureType      sType;
446                 DE_NULL,                                    // const void*          pNext;
447                 0u,                                         // VkBufferCreateFlags  flags;
448                 size,                                       // VkDeviceSize         size;
449                 usage,                                      // VkBufferUsageFlags   usage;
450                 VK_SHARING_MODE_EXCLUSIVE,                  // VkSharingMode        sharingMode;
451                 1u,                                         // deUint32             queueFamilyCount;
452                 &queueFamilyIndex                           // const deUint32*      pQueueFamilyIndices;
453         };
454
455         Move<VkBuffer> vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
456
457         *pAlloc = context.getDefaultAllocator().allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
458         VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, (*pAlloc)->getMemory(), (*pAlloc)->getOffset()));
459
460         return vertexBuffer;
461 }
462
463 Move<VkImage> createImage2DAndBindMemory (Context&                          context,
464                                                                                   VkFormat                          format,
465                                                                                   deUint32                          width,
466                                                                                   deUint32                          height,
467                                                                                   VkImageUsageFlags                 usage,
468                                                                                   VkSampleCountFlagBits             sampleCount,
469                                                                                   de::details::MovePtr<Allocation>* pAlloc)
470 {
471         const DeviceInterface&  vk               = context.getDeviceInterface();
472         const VkDevice          vkDevice         = context.getDevice();
473         const deUint32          queueFamilyIndex = context.getUniversalQueueFamilyIndex();
474
475         const VkImageCreateInfo colorImageParams =
476         {
477                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                        // VkStructureType      sType;
478                 DE_NULL,                                                                    // const void*          pNext;
479                 0u,                                                                         // VkImageCreateFlags   flags;
480                 VK_IMAGE_TYPE_2D,                                                           // VkImageType          imageType;
481                 format,                                                                     // VkFormat             format;
482                 { width, height, 1u },                                                      // VkExtent3D           extent;
483                 1u,                                                                         // deUint32             mipLevels;
484                 1u,                                                                         // deUint32             arraySize;
485                 sampleCount,                                                                // deUint32             samples;
486                 VK_IMAGE_TILING_OPTIMAL,                                                    // VkImageTiling        tiling;
487                 usage,                                                                      // VkImageUsageFlags    usage;
488                 VK_SHARING_MODE_EXCLUSIVE,                                                  // VkSharingMode        sharingMode;
489                 1u,                                                                         // deUint32             queueFamilyCount;
490                 &queueFamilyIndex,                                                          // const deUint32*      pQueueFamilyIndices;
491                 VK_IMAGE_LAYOUT_UNDEFINED,                                                  // VkImageLayout        initialLayout;
492         };
493
494         Move<VkImage> image = createImage(vk, vkDevice, &colorImageParams);
495
496         *pAlloc = context.getDefaultAllocator().allocate(getImageMemoryRequirements(vk, vkDevice, *image), MemoryRequirement::Any);
497         VK_CHECK(vk.bindImageMemory(vkDevice, *image, (*pAlloc)->getMemory(), (*pAlloc)->getOffset()));
498
499         return image;
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         enum
522         {
523                 PIPELINE_CACHE_NDX_NO_CACHE,
524                 PIPELINE_CACHE_NDX_CACHED,
525                 PIPELINE_CACHE_NDX_COUNT,
526         };
527                                                         CacheTestInstance           (Context&                 context,
528                                                                                                                  const CacheTestParam*    param);
529         virtual                 ~CacheTestInstance          (void);
530         virtual tcu::TestStatus iterate                     (void);
531 protected:
532         virtual tcu::TestStatus verifyTestResult            (void) = 0;
533         virtual void            prepareCommandBuffer        (void) = 0;
534 protected:
535         const CacheTestParam*   m_param;
536
537         Move<VkCommandPool>     m_cmdPool;
538         Move<VkCommandBuffer>   m_cmdBuffer;
539         Move<VkFence>           m_fence;
540         Move<VkPipelineCache>   m_cache;
541 };
542
543 CacheTestInstance::CacheTestInstance (Context&                 context,
544                                                                           const CacheTestParam*    param)
545         : TestInstance       (context)
546         , m_param            (param)
547 {
548         const DeviceInterface&  vk               = m_context.getDeviceInterface();
549         const VkDevice          vkDevice         = m_context.getDevice();
550         const deUint32          queueFamilyIndex = context.getUniversalQueueFamilyIndex();
551
552         // Create command pool
553         m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
554
555         // Create command buffer
556         m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
557
558         // Create fence
559         m_fence = createFence(vk, vkDevice);
560
561         // Create the Pipeline Cache
562         {
563                 const VkPipelineCacheCreateInfo pipelineCacheCreateInfo =
564                 {
565                         VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,           // VkStructureType             sType;
566                         DE_NULL,                                                // const void*                 pNext;
567                         0u,                                                     // VkPipelineCacheCreateFlags  flags;
568                         0u,                                                     // deUintptr                   initialDataSize;
569                         DE_NULL,                                                // const void*                 pInitialData;
570                 };
571
572                 m_cache = createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo);
573         }
574 }
575
576 CacheTestInstance::~CacheTestInstance (void)
577 {
578 }
579
580 tcu::TestStatus CacheTestInstance::iterate (void)
581 {
582         const DeviceInterface&  vk       = m_context.getDeviceInterface();
583         const VkDevice          vkDevice = m_context.getDevice();
584         const VkQueue           queue    = m_context.getUniversalQueue();
585
586         prepareCommandBuffer();
587
588         VK_CHECK(vk.resetFences(vkDevice, 1u, &m_fence.get()));
589
590         const VkSubmitInfo          submitInfo =
591         {
592                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                      // VkStructureType             sType;
593                 DE_NULL,                                            // const void*                 pNext;
594                 0u,                                                 // deUint32                    waitSemaphoreCount;
595                 DE_NULL,                                            // const VkSemaphore*          pWaitSemaphores;
596                 (const VkPipelineStageFlags*)DE_NULL,               // const VkPipelineStageFlags* pWaitDstStageMask;
597                 1u,                                                 // deUint32                    commandBufferCount;
598                 &m_cmdBuffer.get(),                                 // const VkCommandBuffer*      pCommandBuffers;
599                 0u,                                                 // deUint32                    signalSemaphoreCount;
600                 DE_NULL,                                            // const VkSemaphore*          pSignalSemaphores;
601         };
602         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *m_fence));
603
604         VK_CHECK(vk.waitForFences(vkDevice, 1u, &m_fence.get(), true, ~(0ull) /* infinity*/));
605
606         return verifyTestResult();
607 }
608
609 class GraphicsCacheTest : public CacheTest
610 {
611 public:
612                                                         GraphicsCacheTest   (tcu::TestContext&      testContext,
613                                                                                                  const std::string&     name,
614                                                                                                  const std::string&     description,
615                                                                                                  const CacheTestParam*  param)
616                                                                 : CacheTest (testContext, name, description, param)
617                                                                 { }
618         virtual                 ~GraphicsCacheTest  (void) { }
619         virtual void            initPrograms        (SourceCollections&      programCollection) const;
620         virtual TestInstance*   createInstance      (Context&                context) const;
621 };
622
623 class GraphicsCacheTestInstance : public CacheTestInstance
624 {
625 public:
626                                                         GraphicsCacheTestInstance   (Context&              context,
627                                                                                                                  const CacheTestParam*  param);
628         virtual                 ~GraphicsCacheTestInstance  (void);
629 protected:
630                         void            prepareRenderPass           (VkFramebuffer framebuffer, VkPipeline pipeline);
631         virtual void            prepareCommandBuffer        (void);
632         virtual tcu::TestStatus verifyTestResult            (void);
633
634 protected:
635         const tcu::UVec2                    m_renderSize;
636         const VkFormat                      m_colorFormat;
637         const VkFormat                      m_depthFormat;
638         Move<VkPipelineLayout>              m_pipelineLayout;
639
640         Move<VkImage>                       m_depthImage;
641         de::MovePtr<Allocation>             m_depthImageAlloc;
642         de::MovePtr<Allocation>             m_colorImageAlloc[PIPELINE_CACHE_NDX_COUNT];
643         Move<VkImageView>                   m_depthAttachmentView;
644         VkImageMemoryBarrier                            m_imageLayoutBarriers[3];
645
646         Move<VkBuffer>                      m_vertexBuffer;
647         de::MovePtr<Allocation>                         m_vertexBufferMemory;
648         std::vector<Vertex4RGBA>            m_vertices;
649
650         SimpleGraphicsPipelineBuilder       m_pipelineBuilder;
651         Move<VkRenderPass>                  m_renderPass;
652
653         Move<VkImage>                       m_colorImage[PIPELINE_CACHE_NDX_COUNT];
654         Move<VkImageView>                   m_colorAttachmentView[PIPELINE_CACHE_NDX_COUNT];
655         Move<VkFramebuffer>                 m_framebuffer[PIPELINE_CACHE_NDX_COUNT];
656         Move<VkPipeline>                    m_pipeline[PIPELINE_CACHE_NDX_COUNT];
657 };
658
659 void GraphicsCacheTest::initPrograms (SourceCollections& programCollection) const
660 {
661         for (deUint32 shaderNdx = 0; shaderNdx < m_param.getShaderCount(); shaderNdx++)
662         {
663                 switch(m_param.getShaderFlag(shaderNdx))
664                 {
665                         case VK_SHADER_STAGE_VERTEX_BIT:
666                                 programCollection.glslSources.add("color_vert") << glu::VertexSource(
667                                         "#version 310 es\n"
668                                         "layout(location = 0) in vec4 position;\n"
669                                         "layout(location = 1) in vec4 color;\n"
670                                         "layout(location = 0) out highp vec4 vtxColor;\n"
671                                         "void main (void)\n"
672                                         "{\n"
673                                         "  gl_Position = position;\n"
674                                         "  vtxColor = color;\n"
675                                         "}\n");
676                                 break;
677
678                         case VK_SHADER_STAGE_FRAGMENT_BIT:
679                                 programCollection.glslSources.add("color_frag") << glu::FragmentSource(
680                                         "#version 310 es\n"
681                                         "layout(location = 0) in highp vec4 vtxColor;\n"
682                                         "layout(location = 0) out highp vec4 fragColor;\n"
683                                         "void main (void)\n"
684                                         "{\n"
685                                         "  fragColor = vtxColor;\n"
686                                         "}\n");
687                                 break;
688
689                         case VK_SHADER_STAGE_GEOMETRY_BIT:
690                                 programCollection.glslSources.add("dummy_geo") << glu::GeometrySource(
691                                         "#version 450 \n"
692                                         "layout(triangles) in;\n"
693                                         "layout(triangle_strip, max_vertices = 3) out;\n"
694                                         "layout(location = 0) in highp vec4 in_vtxColor[];\n"
695                                         "layout(location = 0) out highp vec4 vtxColor;\n"
696                                         "out gl_PerVertex { vec4 gl_Position; };\n"
697                                         "in gl_PerVertex { vec4 gl_Position; } gl_in[];\n"
698                                         "void main (void)\n"
699                                         "{\n"
700                                         "  for(int ndx=0; ndx<3; ndx++)\n"
701                                         "  {\n"
702                                         "    gl_Position = gl_in[ndx].gl_Position;\n"
703                                         "    vtxColor    = in_vtxColor[ndx];\n"
704                                         "    EmitVertex();\n"
705                                         "  }\n"
706                                         "  EndPrimitive();\n"
707                                         "}\n");
708                                 break;
709
710                         case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
711                                 programCollection.glslSources.add("basic_tcs") << glu::TessellationControlSource(
712                                         "#version 450 \n"
713                                         "layout(vertices = 3) out;\n"
714                                         "layout(location = 0) in highp vec4 color[];\n"
715                                         "layout(location = 0) out highp vec4 vtxColor[];\n"
716                                         "out gl_PerVertex { vec4 gl_Position; } gl_out[3];\n"
717                                         "in gl_PerVertex { vec4 gl_Position; } gl_in[gl_MaxPatchVertices];\n"
718                                         "void main()\n"
719                                         "{\n"
720                                         "  gl_TessLevelOuter[0] = 4.0;\n"
721                                         "  gl_TessLevelOuter[1] = 4.0;\n"
722                                         "  gl_TessLevelOuter[2] = 4.0;\n"
723                                         "  gl_TessLevelInner[0] = 4.0;\n"
724                                         "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
725                                         "  vtxColor[gl_InvocationID] = color[gl_InvocationID];\n"
726                                         "}\n");
727                                 break;
728
729                         case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
730                                 programCollection.glslSources.add("basic_tes") << glu::TessellationEvaluationSource(
731                                         "#version 450 \n"
732                                         "layout(triangles, fractional_even_spacing, ccw) in;\n"
733                                         "layout(location = 0) in highp vec4 colors[];\n"
734                                         "layout(location = 0) out highp vec4 vtxColor;\n"
735                                         "out gl_PerVertex { vec4 gl_Position; };\n"
736                                         "in gl_PerVertex { vec4 gl_Position; } gl_in[gl_MaxPatchVertices];\n"
737                                         "void main() \n"
738                                         "{\n"
739                                         "  float u = gl_TessCoord.x;\n"
740                                         "  float v = gl_TessCoord.y;\n"
741                                         "  float w = gl_TessCoord.z;\n"
742                                         "  vec4 pos = vec4(0);\n"
743                                         "  vec4 color = vec4(0);\n"
744                                         "  pos.xyz += u * gl_in[0].gl_Position.xyz;\n"
745                                         "  color.xyz += u * colors[0].xyz;\n"
746                                         "  pos.xyz += v * gl_in[1].gl_Position.xyz;\n"
747                                         "  color.xyz += v * colors[1].xyz;\n"
748                                         "  pos.xyz += w * gl_in[2].gl_Position.xyz;\n"
749                                         "  color.xyz += w * colors[2].xyz;\n"
750                                         "  pos.w = 1.0;\n"
751                                         "  color.w = 1.0;\n"
752                                         "  gl_Position = pos;\n"
753                                         "  vtxColor = color;\n"
754                                         "}\n");
755                                 break;
756
757                         default:
758                                 DE_FATAL("Unknown Shader Stage!");
759                                 break;
760                 };
761         }
762 }
763
764 TestInstance* GraphicsCacheTest::createInstance (Context& context) const
765 {
766         return new GraphicsCacheTestInstance(context, &m_param);
767 }
768
769 GraphicsCacheTestInstance::GraphicsCacheTestInstance (Context&              context,
770                                                                                                           const CacheTestParam* param)
771         : CacheTestInstance (context,param)
772         , m_renderSize      (32u, 32u)
773         , m_colorFormat     (VK_FORMAT_R8G8B8A8_UNORM)
774         , m_depthFormat     (VK_FORMAT_D16_UNORM)
775         , m_pipelineBuilder (context)
776 {
777         const DeviceInterface&  vk               = m_context.getDeviceInterface();
778         const VkDevice          vkDevice         = m_context.getDevice();
779
780         // Create vertex buffer
781         {
782                 m_vertexBuffer = createBufferAndBindMemory(m_context, 1024u, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, &m_vertexBufferMemory);
783
784                 m_vertices          = createOverlappingQuads();
785                 // Load vertices into vertex buffer
786                 deMemcpy(m_vertexBufferMemory->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
787                 flushMappedMemoryRange(vk, vkDevice, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset(), 1024u);
788         }
789
790         // Create render pass
791         {
792                 const VkAttachmentDescription colorAttachmentDescription =
793                 {
794                         0u,                                                 // VkAttachmentDescriptionFlags    flags;
795                         m_colorFormat,                                      // VkFormat                        format;
796                         VK_SAMPLE_COUNT_1_BIT,                              // VkSampleCountFlagBits           samples;
797                         VK_ATTACHMENT_LOAD_OP_CLEAR,                        // VkAttachmentLoadOp              loadOp;
798                         VK_ATTACHMENT_STORE_OP_STORE,                       // VkAttachmentStoreOp             storeOp;
799                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                    // VkAttachmentLoadOp              stencilLoadOp;
800                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                   // VkAttachmentStoreOp             stencilStoreOp;
801                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,           // VkImageLayout                   initialLayout;
802                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,           // VkImageLayout                   finalLayout;
803                 };
804
805                 const VkAttachmentDescription depthAttachmentDescription =
806                 {
807                         0u,                                                 // VkAttachmentDescriptionFlags flags;
808                         m_depthFormat,                                      // VkFormat                     format;
809                         VK_SAMPLE_COUNT_1_BIT,                              // VkSampleCountFlagBits        samples;
810                         VK_ATTACHMENT_LOAD_OP_CLEAR,                        // VkAttachmentLoadOp           loadOp;
811                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                   // VkAttachmentStoreOp          storeOp;
812                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                    // VkAttachmentLoadOp           stencilLoadOp;
813                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                   // VkAttachmentStoreOp          stencilStoreOp;
814                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,   // VkImageLayout                initialLayout;
815                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,   // VkImageLayout                finalLayout;
816                 };
817
818                 const VkAttachmentDescription attachments[2] =
819                 {
820                         colorAttachmentDescription,
821                         depthAttachmentDescription
822                 };
823
824                 const VkAttachmentReference colorAttachmentReference =
825                 {
826                         0u,                                                 // deUint32         attachment;
827                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL            // VkImageLayout    layout;
828                 };
829
830                 const VkAttachmentReference depthAttachmentReference =
831                 {
832                         1u,                                                 // deUint32         attachment;
833                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL    // VkImageLayout    layout;
834                 };
835
836                 const VkSubpassDescription subpassDescription =
837                 {
838                         0u,                                                 // VkSubpassDescriptionFlags        flags;
839                         VK_PIPELINE_BIND_POINT_GRAPHICS,                    // VkPipelineBindPoint              pipelineBindPoint;
840                         0u,                                                 // deUint32                         inputAttachmentCount;
841                         DE_NULL,                                            // const VkAttachmentReference*     pInputAttachments;
842                         1u,                                                 // deUint32                         colorAttachmentCount;
843                         &colorAttachmentReference,                          // const VkAttachmentReference*     pColorAttachments;
844                         DE_NULL,                                            // const VkAttachmentReference*     pResolveAttachments;
845                         &depthAttachmentReference,                          // const VkAttachmentReference*     pDepthStencilAttachment;
846                         0u,                                                 // deUint32                         preserveAttachmentCount;
847                         DE_NULL                                             // const VkAttachmentReference*     pPreserveAttachments;
848                 };
849
850                 const VkRenderPassCreateInfo renderPassParams =
851                 {
852                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,          // VkStructureType                  sType;
853                         DE_NULL,                                            // const void*                      pNext;
854                         0u,                                                 // VkRenderPassCreateFlags          flags;
855                         2u,                                                 // deUint32                         attachmentCount;
856                         attachments,                                        // const VkAttachmentDescription*   pAttachments;
857                         1u,                                                 // deUint32                         subpassCount;
858                         &subpassDescription,                                // const VkSubpassDescription*      pSubpasses;
859                         0u,                                                 // deUint32                         dependencyCount;
860                         DE_NULL                                             // const VkSubpassDependency*       pDependencies;
861                 };
862
863                 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
864         }
865
866         const VkComponentMapping    ComponentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
867         // Create color image
868         {
869                 m_colorImage[PIPELINE_CACHE_NDX_NO_CACHE] = createImage2DAndBindMemory(m_context,
870                                                                                                                                                            m_colorFormat,
871                                                                                                                                                            m_renderSize.x(),
872                                                                                                                                                            m_renderSize.y(),
873                                                                                                                                                            VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
874                                                                                                                                                            VK_SAMPLE_COUNT_1_BIT,
875                                                                                                                                                            &m_colorImageAlloc[PIPELINE_CACHE_NDX_NO_CACHE]);
876                 m_colorImage[PIPELINE_CACHE_NDX_CACHED]   = createImage2DAndBindMemory(m_context,
877                                                                                                                                                            m_colorFormat,
878                                                                                                                                                            m_renderSize.x(),
879                                                                                                                                                            m_renderSize.y(),
880                                                                                                                                                            VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
881                                                                                                                                                            VK_SAMPLE_COUNT_1_BIT,
882                                                                                                                                                            &m_colorImageAlloc[PIPELINE_CACHE_NDX_CACHED]);
883         }
884
885         // Create depth image
886         {
887                 m_depthImage = createImage2DAndBindMemory(m_context,
888                                                                                                   m_depthFormat,
889                                                                                                   m_renderSize.x(),
890                                                                                                   m_renderSize.y(),
891                                                                                                   VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
892                                                                                                   VK_SAMPLE_COUNT_1_BIT,
893                                                                                                   &m_depthImageAlloc);
894         }
895
896         // Set up image layout transition barriers
897         {
898                 VkImageMemoryBarrier colorImageBarrier =
899                 {
900                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                         // VkStructureType                      sType;
901                         DE_NULL,                                                                                        // const void*                          pNext;
902                         0u,                                                                                                     // VkAccessFlags                        srcAccessMask;
903                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
904                         VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                        oldLayout;
905                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                        newLayout;
906                         VK_QUEUE_FAMILY_IGNORED,                                                        // deUint32                                     srcQueueFamilyIndex;
907                         VK_QUEUE_FAMILY_IGNORED,                                                        // deUint32                                     dstQueueFamilyIndex;
908                         *m_colorImage[PIPELINE_CACHE_NDX_NO_CACHE],                     // VkImage                                      image;
909                         { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },          // VkImageSubresourceRange      subresourceRange;
910                 };
911
912                 m_imageLayoutBarriers[0] = colorImageBarrier;
913
914                 colorImageBarrier.image = *m_colorImage[PIPELINE_CACHE_NDX_CACHED];
915                 m_imageLayoutBarriers[1] = colorImageBarrier;
916
917                 const VkImageMemoryBarrier depthImageBarrier =
918                 {
919                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                         // VkStructureType                      sType;
920                         DE_NULL,                                                                                        // const void*                          pNext;
921                         0u,                                                                                                     // VkAccessFlags                        srcAccessMask;
922                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        dstAccessMask;
923                         VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                        oldLayout;
924                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,       // VkImageLayout                        newLayout;
925                         VK_QUEUE_FAMILY_IGNORED,                                                        // deUint32                                     srcQueueFamilyIndex;
926                         VK_QUEUE_FAMILY_IGNORED,                                                        // deUint32                                     dstQueueFamilyIndex;
927                         *m_depthImage,                                                                          // VkImage                                      image;
928                         { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u },          // VkImageSubresourceRange      subresourceRange;
929                 };
930
931                 m_imageLayoutBarriers[2] = depthImageBarrier;
932         }
933         // Create color attachment view
934         {
935                 VkImageViewCreateInfo colorAttachmentViewParams =
936                 {
937                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType          sType;
938                         DE_NULL,                                        // const void*              pNext;
939                         0u,                                             // VkImageViewCreateFlags   flags;
940                         *m_colorImage[PIPELINE_CACHE_NDX_NO_CACHE],     // VkImage                  image;
941                         VK_IMAGE_VIEW_TYPE_2D,                          // VkImageViewType          viewType;
942                         m_colorFormat,                                  // VkFormat                 format;
943                         ComponentMappingRGBA,                           // VkComponentMapping       components;
944                         { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },  // VkImageSubresourceRange  subresourceRange;
945                 };
946
947                 m_colorAttachmentView[PIPELINE_CACHE_NDX_NO_CACHE] = createImageView(vk, vkDevice, &colorAttachmentViewParams);
948
949                 colorAttachmentViewParams.image = *m_colorImage[PIPELINE_CACHE_NDX_CACHED];
950                 m_colorAttachmentView[PIPELINE_CACHE_NDX_CACHED] = createImageView(vk, vkDevice, &colorAttachmentViewParams);
951         }
952
953         // Create depth attachment view
954         {
955                 const VkImageViewCreateInfo depthAttachmentViewParams =
956                 {
957                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType          sType;
958                         DE_NULL,                                        // const void*              pNext;
959                         0u,                                             // VkImageViewCreateFlags   flags;
960                         *m_depthImage,                                  // VkImage                  image;
961                         VK_IMAGE_VIEW_TYPE_2D,                          // VkImageViewType          viewType;
962                         m_depthFormat,                                  // VkFormat                 format;
963                         ComponentMappingRGBA,                           // VkComponentMapping       components;
964                         { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u },  // VkImageSubresourceRange  subresourceRange;
965                 };
966
967                 m_depthAttachmentView = createImageView(vk, vkDevice, &depthAttachmentViewParams);
968         }
969
970         // Create framebuffer
971         {
972                 VkImageView attachmentBindInfos[2] =
973                 {
974                         *m_colorAttachmentView[PIPELINE_CACHE_NDX_NO_CACHE],
975                         *m_depthAttachmentView,
976                 };
977
978                 const VkFramebufferCreateInfo framebufferParams =
979                 {
980                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,          // VkStructureType              sType;
981                         DE_NULL,                                            // const void*                  pNext;
982                         0u,                                                 // VkFramebufferCreateFlags     flags;
983                         *m_renderPass,                                      // VkRenderPass                 renderPass;
984                         2u,                                                 // deUint32                     attachmentCount;
985                         attachmentBindInfos,                                // const VkImageView*           pAttachments;
986                         (deUint32)m_renderSize.x(),                         // deUint32                     width;
987                         (deUint32)m_renderSize.y(),                         // deUint32                     height;
988                         1u,                                                 // deUint32                     layers;
989                 };
990
991                 m_framebuffer[PIPELINE_CACHE_NDX_NO_CACHE] = createFramebuffer(vk, vkDevice, &framebufferParams);
992
993                 attachmentBindInfos[0] = *m_colorAttachmentView[PIPELINE_CACHE_NDX_CACHED];
994                 m_framebuffer[PIPELINE_CACHE_NDX_CACHED] = createFramebuffer(vk, vkDevice, &framebufferParams);
995         }
996
997         // Bind shader stages
998         VkPhysicalDeviceFeatures  features = m_context.getDeviceFeatures();
999         for (deUint32 shaderNdx = 0; shaderNdx < m_param->getShaderCount(); shaderNdx++)
1000         {
1001                 switch(m_param->getShaderFlag(shaderNdx))
1002                 {
1003                         case VK_SHADER_STAGE_VERTEX_BIT:
1004                                 m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_VERTEX_BIT, "color_vert", "main");
1005                                 break;
1006                         case VK_SHADER_STAGE_FRAGMENT_BIT:
1007                                 m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_FRAGMENT_BIT, "color_frag", "main");
1008                                 break;
1009                         case VK_SHADER_STAGE_GEOMETRY_BIT:
1010                                 if (features.geometryShader == VK_FALSE)
1011                                 {
1012                                         TCU_THROW(NotSupportedError, "Geometry Shader Not Supported");
1013                                 }
1014                                 else
1015                                 {
1016                                         m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_GEOMETRY_BIT, "dummy_geo", "main");
1017                                 }
1018                                 break;
1019                         case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
1020                                 if (features.tessellationShader == VK_FALSE)
1021                                 {
1022                                         TCU_THROW(NotSupportedError, "Tessellation Not Supported");
1023                                 }
1024                                 else
1025                                 {
1026                                         m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "basic_tcs", "main");
1027                                         m_pipelineBuilder.enableTessellationStage(3);
1028                                 }
1029                                 break;
1030                         case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
1031                                 if (features.tessellationShader == VK_FALSE)
1032                                 {
1033                                         TCU_THROW(NotSupportedError, "Tessellation Not Supported");
1034                                 }
1035                                 else
1036                                 {
1037                                         m_pipelineBuilder.bindShaderStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "basic_tes", "main");
1038                                         m_pipelineBuilder.enableTessellationStage(3);
1039                                 }
1040                                 break;
1041                         default:
1042                                 DE_FATAL("Unknown Shader Stage!");
1043                                 break;
1044                 };
1045         }
1046
1047         // Create pipeline layout
1048         {
1049                 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1050                 {
1051                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                                      sType;
1052                         DE_NULL,                                                                                        // const void*                                          pNext;
1053                         0u,                                                                                                     // VkPipelineLayoutCreateFlags          flags;
1054                         0u,                                                                                                     // deUint32                                                     setLayoutCount;
1055                         DE_NULL,                                                                                        // const VkDescriptorSetLayout*         pSetLayouts;
1056                         0u,                                                                                                     // deUint32                                                     pushConstantRangeCount;
1057                         DE_NULL                                                                                         // const VkPushConstantRange*           pPushConstantRanges;
1058                 };
1059
1060                 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1061         }
1062
1063         m_pipeline[PIPELINE_CACHE_NDX_NO_CACHE] = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass, *m_cache, *m_pipelineLayout);
1064         m_pipeline[PIPELINE_CACHE_NDX_CACHED]   = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass, *m_cache, *m_pipelineLayout);
1065 }
1066
1067 GraphicsCacheTestInstance::~GraphicsCacheTestInstance (void)
1068 {
1069 }
1070
1071 void GraphicsCacheTestInstance::prepareRenderPass (VkFramebuffer framebuffer, VkPipeline pipeline)
1072 {
1073         const DeviceInterface&  vk               = m_context.getDeviceInterface();
1074
1075         const VkClearValue attachmentClearValues[2] =
1076         {
1077                 defaultClearValue(m_colorFormat),
1078                 defaultClearValue(m_depthFormat),
1079         };
1080
1081         const VkRenderPassBeginInfo renderPassBeginInfo =
1082         {
1083                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,               // VkStructureType      sType;
1084                 DE_NULL,                                                // const void*          pNext;
1085                 *m_renderPass,                                          // VkRenderPass         renderPass;
1086                 framebuffer,                                            // VkFramebuffer        framebuffer;
1087                 { { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } },   // VkRect2D             renderArea;
1088                 2u,                                                     // deUint32             clearValueCount;
1089                 attachmentClearValues                                   // const VkClearValue*  pClearValues;
1090         };
1091
1092         vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
1093
1094         vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
1095         VkDeviceSize offsets = 0u;
1096         vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &offsets);
1097         vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1u, 0u, 0u);
1098
1099         vk.cmdEndRenderPass(*m_cmdBuffer);
1100 }
1101
1102 void GraphicsCacheTestInstance::prepareCommandBuffer (void)
1103 {
1104         const DeviceInterface&  vk               = m_context.getDeviceInterface();
1105
1106         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1107         {
1108                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                  sType;
1109                 DE_NULL,                                        // const void*                      pNext;
1110                 0u,                                             // VkCommandBufferUsageFlags        flags;
1111                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1112         };
1113
1114         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1115
1116         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0,
1117                 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(m_imageLayoutBarriers), m_imageLayoutBarriers);
1118
1119         prepareRenderPass(*m_framebuffer[PIPELINE_CACHE_NDX_NO_CACHE], *m_pipeline[PIPELINE_CACHE_NDX_NO_CACHE]);
1120
1121         // After the first render pass, the images are in correct layouts
1122
1123         prepareRenderPass(*m_framebuffer[PIPELINE_CACHE_NDX_CACHED], *m_pipeline[PIPELINE_CACHE_NDX_CACHED]);
1124
1125         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1126 }
1127
1128 tcu::TestStatus GraphicsCacheTestInstance::verifyTestResult (void)
1129 {
1130         const DeviceInterface&  vk               = m_context.getDeviceInterface();
1131         const VkDevice          vkDevice         = m_context.getDevice();
1132         const deUint32          queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1133
1134         const VkQueue                   queue               = m_context.getUniversalQueue();
1135         de::MovePtr<tcu::TextureLevel>  resultNoCache       = readColorAttachment(vk,
1136                                                                                                                                                           vkDevice,
1137                                                                                                                                                           queue,
1138                                                                                                                                                           queueFamilyIndex,
1139                                                                                                                                                           m_context.getDefaultAllocator(),
1140                                                                                                                                                           *m_colorImage[PIPELINE_CACHE_NDX_NO_CACHE],
1141                                                                                                                                                           m_colorFormat,
1142                                                                                                                                                           m_renderSize);
1143         de::MovePtr<tcu::TextureLevel>  resultCache         = readColorAttachment(vk,
1144                                                                                                                                                           vkDevice,
1145                                                                                                                                                           queue,
1146                                                                                                                                                           queueFamilyIndex,
1147                                                                                                                                                           m_context.getDefaultAllocator(),
1148                                                                                                                                                           *m_colorImage[PIPELINE_CACHE_NDX_CACHED],
1149                                                                                                                                                           m_colorFormat,
1150                                                                                                                                                           m_renderSize);
1151
1152         bool compareOk = tcu::intThresholdCompare(m_context.getTestContext().getLog(),
1153                                                                                           "IntImageCompare",
1154                                                                                           "Image comparison",
1155                                                                                           resultNoCache->getAccess(),
1156                                                                                           resultCache->getAccess(),
1157                                                                                           tcu::UVec4(1, 1, 1, 1),
1158                                                                                           tcu::COMPARE_LOG_RESULT);
1159
1160         if (compareOk)
1161                 return tcu::TestStatus::pass("Render images w/o cached pipeline match.");
1162         else
1163                 return tcu::TestStatus::fail("Render Images mismatch.");
1164 }
1165
1166 class ComputeCacheTest : public CacheTest
1167 {
1168 public:
1169                                                         ComputeCacheTest    (tcu::TestContext&      testContext,
1170                                                                                                  const std::string&     name,
1171                                                                                                  const std::string&     description,
1172                                                                                                  const CacheTestParam*  param)
1173                                                                 : CacheTest (testContext, name, description, param)
1174                                                                 { }
1175         virtual                 ~ComputeCacheTest   (void) { }
1176         virtual void            initPrograms        (SourceCollections&      programCollection) const;
1177         virtual TestInstance*   createInstance      (Context&                context) const;
1178 };
1179
1180 class ComputeCacheTestInstance : public CacheTestInstance
1181 {
1182 public:
1183                                                         ComputeCacheTestInstance    (Context&               context,
1184                                                                                                                  const CacheTestParam*  param);
1185         virtual                 ~ComputeCacheTestInstance   (void);
1186         virtual void            prepareCommandBuffer        (void);
1187 protected:
1188         virtual tcu::TestStatus verifyTestResult            (void);
1189                         void            buildBuffers                (void);
1190                         void            buildDescriptorSets         (deUint32 ndx);
1191                         void            buildShader                 (void);
1192                         void            buildPipeline               (deUint32 ndx);
1193 protected:
1194         Move<VkBuffer>              m_inputBuf;
1195         de::MovePtr<Allocation>     m_inputBufferAlloc;
1196         Move<VkShaderModule>        m_computeShaderModule;
1197
1198         Move<VkBuffer>              m_outputBuf[PIPELINE_CACHE_NDX_COUNT];
1199         de::MovePtr<Allocation>     m_outputBufferAlloc[PIPELINE_CACHE_NDX_COUNT];
1200
1201         Move<VkDescriptorPool>      m_descriptorPool[PIPELINE_CACHE_NDX_COUNT];
1202         Move<VkDescriptorSetLayout> m_descriptorSetLayout[PIPELINE_CACHE_NDX_COUNT];
1203         Move<VkDescriptorSet>       m_descriptorSet[PIPELINE_CACHE_NDX_COUNT];
1204
1205         Move<VkPipelineLayout>      m_pipelineLayout[PIPELINE_CACHE_NDX_COUNT];
1206         Move<VkPipeline>            m_pipeline[PIPELINE_CACHE_NDX_COUNT];
1207 };
1208
1209 void ComputeCacheTest::initPrograms (SourceCollections& programCollection) const
1210 {
1211         programCollection.glslSources.add("basic_compute") << glu::ComputeSource(
1212                 "#version 310 es\n"
1213                 "layout(local_size_x = 1) in;\n"
1214                 "layout(std430) buffer;\n"
1215                 "layout(binding = 0) readonly buffer Input0\n"
1216                 "{\n"
1217                 "  vec4 elements[];\n"
1218                 "} input_data0;\n"
1219                 "layout(binding = 1) writeonly buffer Output\n"
1220                 "{\n"
1221                 "  vec4 elements[];\n"
1222                 "} output_data;\n"
1223                 "void main()\n"
1224                 "{\n"
1225                 "  uint ident = gl_GlobalInvocationID.x;\n"
1226                 "  output_data.elements[ident] = input_data0.elements[ident] * input_data0.elements[ident];\n"
1227                 "}");
1228 }
1229
1230 TestInstance* ComputeCacheTest::createInstance (Context& context) const
1231 {
1232         return new ComputeCacheTestInstance(context, &m_param);
1233 }
1234
1235 void ComputeCacheTestInstance::buildBuffers (void)
1236 {
1237         const DeviceInterface&  vk               = m_context.getDeviceInterface();
1238         const VkDevice          vkDevice         = m_context.getDevice();
1239
1240         // Create buffer object, allocate storage, and generate input data
1241         const VkDeviceSize          size                = sizeof(tcu::Vec4) * 128u;
1242         m_inputBuf = createBufferAndBindMemory(m_context, size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, &m_inputBufferAlloc);
1243
1244         // Initialize input buffer
1245         tcu::Vec4* pVec = reinterpret_cast<tcu::Vec4*>(m_inputBufferAlloc->getHostPtr());
1246         for (deUint32 ndx = 0u; ndx < 128u; ndx++)
1247         {
1248                 for (deUint32 component = 0u; component < 4u; component++)
1249                         pVec[ndx][component]= (float)(ndx * (component + 1u));
1250         }
1251         flushMappedMemoryRange(vk, vkDevice, m_inputBufferAlloc->getMemory(), m_inputBufferAlloc->getOffset(), size);
1252
1253         // Clear the output buffer
1254         for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
1255         {
1256                 m_outputBuf[ndx] = createBufferAndBindMemory(m_context, size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, &m_outputBufferAlloc[ndx]);
1257
1258                 pVec = reinterpret_cast<tcu::Vec4*>(m_outputBufferAlloc[ndx]->getHostPtr());
1259                 memset(pVec, 0u, size);
1260                 flushMappedMemoryRange(vk, vkDevice, m_outputBufferAlloc[ndx]->getMemory(), m_outputBufferAlloc[ndx]->getOffset(), size);
1261         }
1262 }
1263
1264 void ComputeCacheTestInstance::buildDescriptorSets (deUint32 ndx)
1265 {
1266         const DeviceInterface&  vk               = m_context.getDeviceInterface();
1267         const VkDevice          vkDevice         = m_context.getDevice();
1268
1269         // Create descriptor set layout
1270         DescriptorSetLayoutBuilder descLayoutBuilder;
1271
1272         for (deUint32 bindingNdx = 0u; bindingNdx < 2u; bindingNdx++)
1273                 descLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
1274
1275         m_descriptorSetLayout[ndx] = descLayoutBuilder.build(vk, vkDevice);
1276
1277         std::vector<VkDescriptorBufferInfo>        descriptorInfos;
1278         descriptorInfos.push_back(makeDescriptorBufferInfo(*m_inputBuf, 0u, sizeof(tcu::Vec4) * 128u));
1279         descriptorInfos.push_back(makeDescriptorBufferInfo(*m_outputBuf[ndx], 0u, sizeof(tcu::Vec4) * 128u));
1280
1281         // Create descriptor pool
1282         m_descriptorPool[ndx] = DescriptorPoolBuilder().addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2u).build(vk,
1283                                                                                                                                                                                                                  vkDevice,
1284                                                                                                                                                                                                                  VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
1285                                                                                                                                                                                                                  1u);
1286
1287         // Create descriptor set
1288         const VkDescriptorSetAllocateInfo descriptorSetAllocInfo =
1289         {
1290                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,     // VkStructureType                 sType;
1291                 DE_NULL,                                            // const void*                     pNext;
1292                 *m_descriptorPool[ndx],                             // VkDescriptorPool                descriptorPool;
1293                 1u,                                                 // deUint32                        setLayoutCount;
1294                 &m_descriptorSetLayout[ndx].get(),                  // const VkDescriptorSetLayout*    pSetLayouts;
1295         };
1296         m_descriptorSet[ndx] = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocInfo);
1297
1298         DescriptorSetUpdateBuilder  builder;
1299         for (deUint32 descriptorNdx = 0u; descriptorNdx < 2u; descriptorNdx++)
1300         {
1301                 builder.writeSingle(*m_descriptorSet[ndx],
1302                                                         DescriptorSetUpdateBuilder::Location::binding(descriptorNdx),
1303                                                         VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1304                                                         &descriptorInfos[descriptorNdx]);
1305         }
1306         builder.update(vk, vkDevice);
1307 }
1308
1309 void ComputeCacheTestInstance::buildShader (void)
1310 {
1311         const DeviceInterface&  vk               = m_context.getDeviceInterface();
1312         const VkDevice          vkDevice         = m_context.getDevice();
1313
1314         // Create compute shader
1315         VkShaderModuleCreateInfo shaderModuleCreateInfo =
1316         {
1317                 VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,                                    // VkStructureType             sType;
1318                 DE_NULL,                                                                        // const void*                 pNext;
1319                 0u,                                                                             // VkShaderModuleCreateFlags   flags;
1320                 m_context.getBinaryCollection().get("basic_compute").getSize(),                 // deUintptr                   codeSize;
1321                 (deUint32*)m_context.getBinaryCollection().get("basic_compute").getBinary(),    // const deUint32*             pCode;
1322         };
1323         m_computeShaderModule = createShaderModule(vk, vkDevice, &shaderModuleCreateInfo);
1324 }
1325
1326 void ComputeCacheTestInstance::buildPipeline (deUint32 ndx)
1327 {
1328         const DeviceInterface&  vk               = m_context.getDeviceInterface();
1329         const VkDevice          vkDevice         = m_context.getDevice();
1330
1331         // Create compute pipeline layout
1332         const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
1333         {
1334                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,  // VkStructureType                 sType;
1335                 DE_NULL,                                        // const void*                     pNext;
1336                 0u,                                             // VkPipelineLayoutCreateFlags     flags;
1337                 1u,                                             // deUint32                        setLayoutCount;
1338                 &m_descriptorSetLayout[ndx].get(),              // const VkDescriptorSetLayout*    pSetLayouts;
1339                 0u,                                             // deUint32                        pushConstantRangeCount;
1340                 DE_NULL,                                        // const VkPushConstantRange*      pPushConstantRanges;
1341         };
1342
1343         m_pipelineLayout[ndx] = createPipelineLayout(vk, vkDevice, &pipelineLayoutCreateInfo);
1344
1345         const VkPipelineShaderStageCreateInfo stageCreateInfo =
1346         {
1347                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType                     sType;
1348                 DE_NULL,                                             // const void*                         pNext;
1349                 0u,                                                  // VkPipelineShaderStageCreateFlags    flags;
1350                 VK_SHADER_STAGE_COMPUTE_BIT,                         // VkShaderStageFlagBits               stage;
1351                 *m_computeShaderModule,                              // VkShaderModule                      module;
1352                 "main",                                              // const char*                         pName;
1353                 DE_NULL,                                             // const VkSpecializationInfo*         pSpecializationInfo;
1354         };
1355
1356         const VkComputePipelineCreateInfo pipelineCreateInfo =
1357         {
1358                 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,      // VkStructureType                 sType;
1359                 DE_NULL,                                             // const void*                     pNext;
1360                 0u,                                                  // VkPipelineCreateFlags           flags;
1361                 stageCreateInfo,                                     // VkPipelineShaderStageCreateInfo stage;
1362                 *m_pipelineLayout[ndx],                              // VkPipelineLayout                layout;
1363                 (VkPipeline)0,                                       // VkPipeline                      basePipelineHandle;
1364                 0u,                                                  // deInt32                         basePipelineIndex;
1365         };
1366
1367         m_pipeline[ndx] = createComputePipeline(vk, vkDevice, *m_cache, &pipelineCreateInfo);
1368 }
1369
1370 ComputeCacheTestInstance::ComputeCacheTestInstance (Context&              context,
1371                                                                                                         const CacheTestParam*  param)
1372         : CacheTestInstance (context, param)
1373 {
1374         buildBuffers();
1375
1376         buildDescriptorSets(PIPELINE_CACHE_NDX_NO_CACHE);
1377
1378         buildDescriptorSets(PIPELINE_CACHE_NDX_CACHED);
1379
1380         buildShader();
1381
1382         buildPipeline(PIPELINE_CACHE_NDX_NO_CACHE);
1383
1384         buildPipeline(PIPELINE_CACHE_NDX_CACHED);
1385 }
1386
1387 ComputeCacheTestInstance::~ComputeCacheTestInstance (void)
1388 {
1389 }
1390
1391 void ComputeCacheTestInstance::prepareCommandBuffer (void)
1392 {
1393         const DeviceInterface&  vk               = m_context.getDeviceInterface();
1394
1395         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1396         {
1397                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                  sType;
1398                 DE_NULL,                                        // const void*                      pNext;
1399                 0u,                                             // VkCommandBufferUsageFlags        flags;
1400                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1401         };
1402
1403         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1404
1405         for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
1406         {
1407                 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipeline[ndx]);
1408                 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout[ndx], 0u, 1u, &m_descriptorSet[ndx].get(), 0u, DE_NULL);
1409                 vk.cmdDispatch(*m_cmdBuffer, 128u, 1u, 1u);
1410         }
1411
1412         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1413 }
1414
1415 tcu::TestStatus ComputeCacheTestInstance::verifyTestResult (void)
1416 {
1417         const DeviceInterface&  vk               = m_context.getDeviceInterface();
1418         const VkDevice          vkDevice         = m_context.getDevice();
1419
1420         // Read the content of output buffers
1421         invalidateMappedMemoryRange(vk,
1422                                                                 vkDevice,
1423                                                                 m_outputBufferAlloc[PIPELINE_CACHE_NDX_NO_CACHE]->getMemory(),
1424                                                                 m_outputBufferAlloc[PIPELINE_CACHE_NDX_NO_CACHE]->getOffset(),
1425                                                                 sizeof(tcu::Vec4) * 128u);
1426
1427         invalidateMappedMemoryRange(vk,
1428                                                                 vkDevice,
1429                                                                 m_outputBufferAlloc[PIPELINE_CACHE_NDX_CACHED]->getMemory(),
1430                                                                 m_outputBufferAlloc[PIPELINE_CACHE_NDX_CACHED]->getOffset(),
1431                                                                 sizeof(tcu::Vec4) * 128u);
1432         // Compare the content
1433         deUint8* bufNoCache = reinterpret_cast<deUint8*>(m_outputBufferAlloc[PIPELINE_CACHE_NDX_NO_CACHE]->getHostPtr());
1434         deUint8* bufCached  = reinterpret_cast<deUint8*>(m_outputBufferAlloc[PIPELINE_CACHE_NDX_CACHED]->getHostPtr());
1435         for (deUint32 ndx = 0u; ndx < sizeof(tcu::Vec4) * 128u; ndx++)
1436         {
1437                 if (bufNoCache[ndx] != bufCached[ndx])
1438                 {
1439                         return tcu::TestStatus::fail("Output buffers w/o cached pipeline mismatch.");
1440                 }
1441         }
1442
1443         return tcu::TestStatus::pass("Output buffers w/o cached pipeline match.");
1444 }
1445
1446 class PipelineFromCacheTest : public GraphicsCacheTest
1447 {
1448 public:
1449                                                         PipelineFromCacheTest           (tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param);
1450         virtual                 ~PipelineFromCacheTest          (void) {                }
1451         virtual TestInstance*   createInstance                          (Context& context) const;
1452 };
1453
1454 PipelineFromCacheTest::PipelineFromCacheTest (tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param)
1455         : GraphicsCacheTest(testContext, name, description, param)
1456 {
1457 }
1458
1459 class PipelineFromCacheTestInstance : public GraphicsCacheTestInstance
1460 {
1461 public:
1462                                                         PipelineFromCacheTestInstance   (Context& context, const CacheTestParam* param);
1463         virtual                 ~PipelineFromCacheTestInstance  (void);
1464 protected:
1465         Move<VkPipelineCache>   m_newCache;
1466         deUint8*                m_data;
1467 };
1468
1469 TestInstance* PipelineFromCacheTest::createInstance (Context& context) const
1470 {
1471         return new PipelineFromCacheTestInstance(context, &m_param);
1472 }
1473
1474 PipelineFromCacheTestInstance::PipelineFromCacheTestInstance (Context& context, const CacheTestParam* param)
1475         : GraphicsCacheTestInstance     (context, param)
1476         , m_data                                        (DE_NULL)
1477 {
1478         const DeviceInterface&  vk = m_context.getDeviceInterface();
1479         const VkDevice          vkDevice = m_context.getDevice();
1480
1481         // Create more pipeline caches
1482         {
1483                 size_t  dataSize        = 0u;
1484
1485                 VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, DE_NULL));
1486
1487                 m_data                          = new deUint8[dataSize];
1488                 DE_ASSERT(m_data);
1489                 VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, (void*)m_data));
1490
1491                 const VkPipelineCacheCreateInfo pipelineCacheCreateInfo =
1492                 {
1493                         VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,           // VkStructureType             sType;
1494                         DE_NULL,                                                // const void*                 pNext;
1495                         0u,                                                     // VkPipelineCacheCreateFlags  flags;
1496                         dataSize,                                               // deUintptr                   initialDataSize;
1497                         m_data,                                                 // const void*                 pInitialData;
1498                 };
1499                 m_newCache = createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo);
1500         }
1501         m_pipeline[PIPELINE_CACHE_NDX_CACHED] = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass, *m_newCache, *m_pipelineLayout);
1502 }
1503
1504 PipelineFromCacheTestInstance::~PipelineFromCacheTestInstance (void)
1505 {
1506         delete[] m_data;
1507 }
1508
1509 class PipelineFromIncompleteCacheTest : public GraphicsCacheTest
1510 {
1511 public:
1512                                                         PipelineFromIncompleteCacheTest         (tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param);
1513         virtual                 ~PipelineFromIncompleteCacheTest        (void)                  {}
1514         virtual TestInstance*   createInstance                                          (Context& context) const;
1515 };
1516
1517 PipelineFromIncompleteCacheTest::PipelineFromIncompleteCacheTest (tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param)
1518         : GraphicsCacheTest(testContext, name, description, param)
1519 {
1520 }
1521
1522 class PipelineFromIncompleteCacheTestInstance : public GraphicsCacheTestInstance
1523 {
1524 public:
1525                                                         PipelineFromIncompleteCacheTestInstance(Context& context, const CacheTestParam* param);
1526         virtual                 ~PipelineFromIncompleteCacheTestInstance(void);
1527 protected:
1528 protected:
1529         Move<VkPipelineCache>   m_newCache;
1530         deUint8*                m_data;
1531 };
1532
1533 TestInstance* PipelineFromIncompleteCacheTest::createInstance (Context& context) const
1534 {
1535         return new PipelineFromIncompleteCacheTestInstance(context, &m_param);
1536 }
1537
1538 PipelineFromIncompleteCacheTestInstance::PipelineFromIncompleteCacheTestInstance (Context& context, const CacheTestParam* param)
1539         : GraphicsCacheTestInstance     (context, param)
1540         , m_data                                        (DE_NULL)
1541 {
1542         const DeviceInterface&  vk                      = m_context.getDeviceInterface();
1543         const VkDevice          vkDevice        = m_context.getDevice();
1544
1545         // Create more pipeline caches
1546         {
1547                 size_t  dataSize = 0u;
1548                 VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, DE_NULL));
1549
1550                 if (dataSize == 0)
1551                         TCU_THROW(NotSupportedError, "Empty pipeline cache - unable to test");
1552
1553                 dataSize--;
1554
1555                 m_data = new deUint8[dataSize];
1556                 DE_ASSERT(m_data);
1557                 if (vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, (void*)m_data) != VK_INCOMPLETE)
1558                         TCU_THROW(TestError, "GetPipelineCacheData should return VK_INCOMPLETE state!");
1559
1560                 const VkPipelineCacheCreateInfo pipelineCacheCreateInfo =
1561                 {
1562                         VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,           // VkStructureType             sType;
1563                         DE_NULL,                                                // const void*                 pNext;
1564                         0u,                                                     // VkPipelineCacheCreateFlags  flags;
1565                         dataSize,                                               // deUintptr                   initialDataSize;
1566                         m_data,                                                 // const void*                 pInitialData;
1567                 };
1568                 m_newCache = createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo);
1569         }
1570         m_pipeline[PIPELINE_CACHE_NDX_CACHED] = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass, *m_newCache, *m_pipelineLayout);
1571 }
1572
1573 PipelineFromIncompleteCacheTestInstance::~PipelineFromIncompleteCacheTestInstance (void)
1574 {
1575         delete[] m_data;
1576 }
1577
1578 class MergeCacheTest : public GraphicsCacheTest
1579 {
1580 public:
1581                                                         MergeCacheTest      (tcu::TestContext&      testContext,
1582                                                                                                  const std::string&     name,
1583                                                                                                  const std::string&     description,
1584                                                                                                  const CacheTestParam*  param)
1585                                                                 : GraphicsCacheTest (testContext, name, description, param)
1586                                                                 { }
1587         virtual                 ~MergeCacheTest     (void) { }
1588         virtual TestInstance*   createInstance      (Context&               context) const;
1589 };
1590
1591 class MergeCacheTestInstance : public GraphicsCacheTestInstance
1592 {
1593 public:
1594                                                         MergeCacheTestInstance  (Context&              context,
1595                                                                                                          const CacheTestParam*  param);
1596         virtual                 ~MergeCacheTestInstance (void);
1597 protected:
1598         Move<VkPipelineCache>   m_cacheGetData;
1599         Move<VkPipelineCache>   m_cacheEmpty;
1600         Move<VkPipelineCache>   m_cacheMerged;
1601         deUint8*                m_data;
1602 };
1603
1604 TestInstance* MergeCacheTest::createInstance (Context& context) const
1605 {
1606         return new MergeCacheTestInstance(context, &m_param);
1607 }
1608
1609 MergeCacheTestInstance::MergeCacheTestInstance (Context& context, const CacheTestParam* param)
1610         : GraphicsCacheTestInstance (context, param)
1611         , m_data                    (DE_NULL)
1612 {
1613         const DeviceInterface&  vk               = m_context.getDeviceInterface();
1614         const VkDevice          vkDevice         = m_context.getDevice();
1615
1616         // Create more pipeline caches
1617         {
1618                 // Create a empty cache as one of source cache
1619                 VkPipelineCacheCreateInfo pipelineCacheCreateInfo =
1620                 {
1621                         VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,           // VkStructureType             sType;
1622                         DE_NULL,                                                // const void*                 pNext;
1623                         0u,                                                     // VkPipelineCacheCreateFlags  flags;
1624                         0u,                                                     // deUintptr                   initialDataSize;
1625                         DE_NULL,                                                // const void*                 pInitialData;
1626                 };
1627                 m_cacheEmpty = createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo);
1628
1629                 // Create a empty cache for merge destination cache
1630                 m_cacheMerged = createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo);
1631
1632                 // Create a cache with init data from m_cache
1633                 size_t  dataSize = 0u;
1634                 VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, DE_NULL));
1635
1636                 m_data = new deUint8[dataSize];
1637                 DE_ASSERT(m_data);
1638                 VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, (void*)m_data));
1639
1640                 pipelineCacheCreateInfo.initialDataSize = dataSize;
1641                 pipelineCacheCreateInfo.pInitialData = m_data;
1642                 m_cacheGetData = createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo);
1643         }
1644
1645         // Merge the caches
1646         const VkPipelineCache sourceCaches[] =
1647         {
1648                 *m_cacheEmpty,
1649                 *m_cacheGetData,
1650         };
1651         VK_CHECK(vk.mergePipelineCaches(vkDevice, *m_cacheMerged, 2u, sourceCaches));
1652
1653         // Create pipeline from merged cache
1654         m_pipeline[PIPELINE_CACHE_NDX_CACHED] = m_pipelineBuilder.buildPipeline(m_renderSize, *m_renderPass, *m_cacheMerged, *m_pipelineLayout);
1655 }
1656
1657 MergeCacheTestInstance::~MergeCacheTestInstance (void)
1658 {
1659         delete[] m_data;
1660 }
1661
1662 class CacheHeaderTest : public GraphicsCacheTest
1663 {
1664 public:
1665         CacheHeaderTest(tcu::TestContext&      testContext,
1666                 const std::string&     name,
1667                 const std::string&     description,
1668                 const CacheTestParam*  param)
1669                 : GraphicsCacheTest(testContext, name, description, param)
1670         { }
1671         virtual                 ~CacheHeaderTest(void) { }
1672         virtual TestInstance*   createInstance(Context&               context) const;
1673 };
1674
1675 class CacheHeaderTestInstance : public GraphicsCacheTestInstance
1676 {
1677 public:
1678                                                         CacheHeaderTestInstance  (Context& context, const CacheTestParam*  param);
1679         virtual                 ~CacheHeaderTestInstance (void);
1680 protected:
1681         deUint8*                m_data;
1682
1683         struct CacheHeader
1684         {
1685                 deUint32 HeaderLength;
1686                 deUint32 HeaderVersion;
1687                 deUint32 VendorID;
1688                 deUint32 DeviceID;
1689                 deUint8 PipelineCacheUUID[VK_UUID_SIZE];
1690         } m_header;
1691 };
1692
1693 TestInstance* CacheHeaderTest::createInstance (Context& context) const
1694 {
1695         return new CacheHeaderTestInstance(context, &m_param);
1696 }
1697
1698 CacheHeaderTestInstance::CacheHeaderTestInstance (Context& context, const CacheTestParam* param)
1699         : GraphicsCacheTestInstance (context, param)
1700         , m_data                    (DE_NULL)
1701 {
1702         const DeviceInterface&  vk               = m_context.getDeviceInterface();
1703         const VkDevice          vkDevice         = m_context.getDevice();
1704
1705         // Create more pipeline caches
1706         {
1707                 // Create a cache with init data from m_cache
1708                 size_t  dataSize = 0u;
1709                 VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, DE_NULL));
1710
1711                 if (dataSize < sizeof(m_header))
1712                         TCU_THROW(TestError, "Pipeline cache size is smaller than header size");
1713
1714                 m_data = new deUint8[dataSize];
1715                 DE_ASSERT(m_data);
1716                 VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, (void*)m_data));
1717
1718                 deMemcpy(&m_header, m_data, sizeof(m_header));
1719
1720                 if (m_header.HeaderLength - VK_UUID_SIZE != 16)
1721                         TCU_THROW(TestError, "Invalid header size!");
1722
1723                 if (m_header.HeaderVersion != 1)
1724                         TCU_THROW(TestError, "Invalid header version!");
1725
1726                 if (m_header.VendorID != m_context.getDeviceProperties().vendorID)
1727                         TCU_THROW(TestError, "Invalid header vendor ID!");
1728
1729                 if (m_header.DeviceID != m_context.getDeviceProperties().deviceID)
1730                         TCU_THROW(TestError, "Invalid header device ID!");
1731
1732                 if (deMemCmp(&m_header.PipelineCacheUUID, &m_context.getDeviceProperties().pipelineCacheUUID, VK_UUID_SIZE) != 0)
1733                         TCU_THROW(TestError, "Invalid header pipeline cache UUID!");
1734         }
1735 }
1736
1737 CacheHeaderTestInstance::~CacheHeaderTestInstance (void)
1738 {
1739         delete[] m_data;
1740 }
1741
1742 class InvalidSizeTest : public GraphicsCacheTest
1743 {
1744 public:
1745                                                         InvalidSizeTest         (tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param);
1746         virtual                 ~InvalidSizeTest        (void)   {}
1747         virtual TestInstance*   createInstance          (Context& context) const;
1748 };
1749
1750 InvalidSizeTest::InvalidSizeTest (tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param)
1751         : GraphicsCacheTest(testContext, name, description, param)
1752 {
1753 }
1754
1755 class InvalidSizeTestInstance : public GraphicsCacheTestInstance
1756 {
1757 public:
1758                                                         InvalidSizeTestInstance         (Context& context, const CacheTestParam*  param);
1759         virtual                 ~InvalidSizeTestInstance        (void);
1760 protected:
1761         deUint8*                m_data;
1762         deUint8*                m_zeroBlock;
1763 };
1764
1765 TestInstance* InvalidSizeTest::createInstance (Context& context) const
1766 {
1767         return new InvalidSizeTestInstance(context, &m_param);
1768 }
1769
1770 InvalidSizeTestInstance::InvalidSizeTestInstance (Context& context, const CacheTestParam* param)
1771         : GraphicsCacheTestInstance     (context, param)
1772         , m_data                                        (DE_NULL)
1773         , m_zeroBlock                           (DE_NULL)
1774 {
1775         const DeviceInterface&  vk                      = m_context.getDeviceInterface();
1776         const VkDevice          vkDevice        = m_context.getDevice();
1777
1778         // Create more pipeline caches
1779         try
1780         {
1781                 // Create a cache with init data from m_cache
1782                 size_t dataSize                 = 0u;
1783                 size_t savedDataSize    = 0u;
1784                 VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, DE_NULL));
1785                 savedDataSize = dataSize;
1786
1787                 // If the value of dataSize is less than the maximum size that can be retrieved by the pipeline cache,
1788                 // at most pDataSize bytes will be written to pData, and vkGetPipelineCacheData will return VK_INCOMPLETE.
1789                 dataSize--;
1790
1791                 m_data = new deUint8[savedDataSize];
1792                 deMemset(m_data, 0, savedDataSize);
1793                 DE_ASSERT(m_data);
1794                 if (vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, (void*)m_data) != VK_INCOMPLETE)
1795                         TCU_THROW(TestError, "GetPipelineCacheData should return VK_INCOMPLETE state!");
1796
1797                 delete[] m_data;
1798                 m_data = DE_NULL;
1799
1800                 // If the value of dataSize is less than what is necessary to store the header,
1801                 // nothing will be written to pData and zero will be written to dataSize.
1802                 dataSize = 16 + VK_UUID_SIZE - 1;
1803
1804                 m_data = new deUint8[savedDataSize];
1805                 deMemset(m_data, 0, savedDataSize);
1806                 DE_ASSERT(m_data);
1807                 if (vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, (void*)m_data) != VK_INCOMPLETE)
1808                         TCU_THROW(TestError, "GetPipelineCacheData should return VK_INCOMPLETE state!");
1809
1810                 m_zeroBlock = new deUint8[savedDataSize];
1811                 deMemset(m_zeroBlock, 0, savedDataSize);
1812                 if (deMemCmp(m_data, m_zeroBlock, savedDataSize) != 0 || dataSize != 0)
1813                         TCU_THROW(TestError, "Data needs to be empty and data size should be 0 when invalid size is passed to GetPipelineCacheData!");
1814         }
1815         catch (...)
1816         {
1817                 delete[] m_data;
1818                 delete[] m_zeroBlock;
1819                 throw;
1820         }
1821 }
1822
1823 InvalidSizeTestInstance::~InvalidSizeTestInstance (void)
1824 {
1825         delete[] m_data;
1826         delete[] m_zeroBlock;
1827 }
1828
1829 } // anonymous
1830
1831 tcu::TestCaseGroup* createCacheTests (tcu::TestContext& testCtx)
1832 {
1833
1834         de::MovePtr<tcu::TestCaseGroup> cacheTests (new tcu::TestCaseGroup(testCtx, "cache", "pipeline cache tests"));
1835
1836         // Graphics Pipeline Tests
1837         {
1838                 de::MovePtr<tcu::TestCaseGroup> graphicsTests (new tcu::TestCaseGroup(testCtx, "graphics_tests", "Test pipeline cache with graphics pipeline."));
1839
1840                 const VkShaderStageFlagBits testParamShaders0[] =
1841                 {
1842                         VK_SHADER_STAGE_VERTEX_BIT,
1843                         VK_SHADER_STAGE_FRAGMENT_BIT,
1844                 };
1845                 const VkShaderStageFlagBits testParamShaders1[] =
1846                 {
1847                         VK_SHADER_STAGE_VERTEX_BIT,
1848                         VK_SHADER_STAGE_GEOMETRY_BIT,
1849                         VK_SHADER_STAGE_FRAGMENT_BIT,
1850                 };
1851                 const VkShaderStageFlagBits testParamShaders2[] =
1852                 {
1853                         VK_SHADER_STAGE_VERTEX_BIT,
1854                         VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
1855                         VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
1856                         VK_SHADER_STAGE_FRAGMENT_BIT,
1857                 };
1858                 const CacheTestParam testParams[] =
1859                 {
1860                         CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0)),
1861                         CacheTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1)),
1862                         CacheTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2)),
1863                 };
1864
1865                 for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
1866                         graphicsTests->addChild(newTestCase<GraphicsCacheTest>(testCtx, &testParams[i]));
1867
1868                 cacheTests->addChild(graphicsTests.release());
1869         }
1870
1871         // Graphics Pipeline Tests
1872         {
1873                 de::MovePtr<tcu::TestCaseGroup> graphicsTests(new tcu::TestCaseGroup(testCtx, "pipeline_from_get_data", "Test pipeline cache with graphics pipeline."));
1874
1875                 const VkShaderStageFlagBits testParamShaders0[] =
1876                 {
1877                         VK_SHADER_STAGE_VERTEX_BIT,
1878                         VK_SHADER_STAGE_FRAGMENT_BIT,
1879                 };
1880                 const VkShaderStageFlagBits testParamShaders1[] =
1881                 {
1882                         VK_SHADER_STAGE_VERTEX_BIT,
1883                         VK_SHADER_STAGE_GEOMETRY_BIT,
1884                         VK_SHADER_STAGE_FRAGMENT_BIT,
1885                 };
1886                 const VkShaderStageFlagBits testParamShaders2[] =
1887                 {
1888                         VK_SHADER_STAGE_VERTEX_BIT,
1889                         VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
1890                         VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
1891                         VK_SHADER_STAGE_FRAGMENT_BIT,
1892                 };
1893                 const CacheTestParam testParams[] =
1894                 {
1895                         CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0)),
1896                         CacheTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1)),
1897                         CacheTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2)),
1898                 };
1899
1900                 for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
1901                         graphicsTests->addChild(newTestCase<PipelineFromCacheTest>(testCtx, &testParams[i]));
1902
1903                 cacheTests->addChild(graphicsTests.release());
1904         }
1905
1906         // Graphics Pipeline Tests
1907         {
1908                 de::MovePtr<tcu::TestCaseGroup> graphicsTests(new tcu::TestCaseGroup(testCtx, "pipeline_from_incomplete_get_data", "Test pipeline cache with graphics pipeline."));
1909
1910                 const VkShaderStageFlagBits testParamShaders0[] =
1911                 {
1912                         VK_SHADER_STAGE_VERTEX_BIT,
1913                         VK_SHADER_STAGE_FRAGMENT_BIT,
1914                 };
1915                 const VkShaderStageFlagBits testParamShaders1[] =
1916                 {
1917                         VK_SHADER_STAGE_VERTEX_BIT,
1918                         VK_SHADER_STAGE_GEOMETRY_BIT,
1919                         VK_SHADER_STAGE_FRAGMENT_BIT,
1920                 };
1921                 const VkShaderStageFlagBits testParamShaders2[] =
1922                 {
1923                         VK_SHADER_STAGE_VERTEX_BIT,
1924                         VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
1925                         VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
1926                         VK_SHADER_STAGE_FRAGMENT_BIT,
1927                 };
1928                 const CacheTestParam testParams[] =
1929                 {
1930                         CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0)),
1931                         CacheTestParam(testParamShaders1, DE_LENGTH_OF_ARRAY(testParamShaders1)),
1932                         CacheTestParam(testParamShaders2, DE_LENGTH_OF_ARRAY(testParamShaders2)),
1933                 };
1934
1935                 for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
1936                         graphicsTests->addChild(newTestCase<PipelineFromIncompleteCacheTest>(testCtx, &testParams[i]));
1937
1938                 cacheTests->addChild(graphicsTests.release());
1939         }
1940
1941         // Compute Pipeline Tests
1942         {
1943                 de::MovePtr<tcu::TestCaseGroup> computeTests (new tcu::TestCaseGroup(testCtx, "compute_tests", "Test pipeline cache with compute pipeline."));
1944
1945                 const VkShaderStageFlagBits testParamShaders0[] =
1946                 {
1947                         VK_SHADER_STAGE_COMPUTE_BIT,
1948                 };
1949                 const CacheTestParam testParams[] =
1950                 {
1951                         CacheTestParam(testParamShaders0, DE_LENGTH_OF_ARRAY(testParamShaders0)),
1952                 };
1953
1954                 for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
1955                         computeTests->addChild(newTestCase<ComputeCacheTest>(testCtx, &testParams[i]));
1956
1957                 cacheTests->addChild(computeTests.release());
1958         }
1959
1960         // Misc Tests
1961         {
1962                 de::MovePtr<tcu::TestCaseGroup> miscTests (new tcu::TestCaseGroup(testCtx, "misc_tests", "Misc tests that can not be categorized to other group."));
1963
1964                 const VkShaderStageFlagBits testParamShaders[] =
1965                 {
1966                         VK_SHADER_STAGE_VERTEX_BIT,
1967                         VK_SHADER_STAGE_FRAGMENT_BIT,
1968                 };
1969
1970                 const CacheTestParam testParam(testParamShaders, DE_LENGTH_OF_ARRAY(testParamShaders));
1971                 miscTests->addChild(new MergeCacheTest(testCtx,
1972                                                                                            "merge_cache_test",
1973                                                                                            "Merge the caches test.",
1974                                                                                            &testParam));
1975
1976                 miscTests->addChild(new CacheHeaderTest(testCtx,
1977                                                                                            "cache_header_test",
1978                                                                                            "Cache header test.",
1979                                                                                            &testParam));
1980
1981                 miscTests->addChild(new InvalidSizeTest(testCtx,
1982                                                                                                 "invalid_size_test",
1983                                                                                                 "Invalid size test.",
1984                                                                                                 &testParam));
1985
1986                 cacheTests->addChild(miscTests.release());
1987         }
1988
1989         return cacheTests.release();
1990 }
1991
1992 } // pipeline
1993
1994 } // vkt