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