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