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 bool compileCacheMissShaders);
117 virtual ~CacheTestParam (void);
118 virtual const std::string generateTestName (void) const;
119 virtual const std::string generateTestDescription (void) const;
getShaderFlag(deUint32 ndx) const120 VkShaderStageFlagBits getShaderFlag (deUint32 ndx) const { return m_shaders[ndx]; }
getShaderCount(void) const121 deUint32 getShaderCount (void) const { return (deUint32)m_shaderCount; }
getCompileMissShaders(void) const122 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
CacheTestParam(const VkShaderStageFlagBits * shaders,deUint32 count,bool compileCacheMissShaders)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
~CacheTestParam(void)140 CacheTestParam::~CacheTestParam (void)
141 {
142 }
143
generateTestName(void) const144 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
generateTestDescription(void) const154 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);
~SimpleGraphicsPipelineBuilder(void)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
SimpleGraphicsPipelineBuilder(Context & context)185 SimpleGraphicsPipelineBuilder::SimpleGraphicsPipelineBuilder (Context& context)
186 : m_context(context)
187 {
188 m_patchControlPoints = 0;
189 m_shaderStageCount = 0;
190 }
191
bindShaderStage(VkShaderStageFlagBits stage,const char * sourceName,const char * entryName)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
buildPipeline(tcu::UVec2 renderSize,VkRenderPass renderPass,VkPipelineCache cache,VkPipelineLayout pipelineLayout)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
enableTessellationStage(deUint32 patchControlPoints)418 void SimpleGraphicsPipelineBuilder::enableTessellationStage (deUint32 patchControlPoints)
419 {
420 m_patchControlPoints = patchControlPoints;
421 }
422
423 template <class Test>
newTestCase(tcu::TestContext & testContext,const CacheTestParam * testParam)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
createBufferAndBindMemory(Context & context,VkDeviceSize size,VkBufferUsageFlags usage,de::MovePtr<Allocation> * pAlloc)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
createImage2DAndBindMemory(Context & context,VkFormat format,deUint32 width,deUint32 height,VkImageUsageFlags usage,VkSampleCountFlagBits sampleCount,de::details::MovePtr<Allocation> * pAlloc)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:
CacheTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const CacheTestParam * param)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 { }
~CacheTest(void)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
CacheTestInstance(Context & context,const CacheTestParam * param)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
~CacheTestInstance(void)567 CacheTestInstance::~CacheTestInstance (void)
568 {
569 }
570
iterate(void)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:
GraphicsCacheTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const CacheTestParam * param)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 { }
~GraphicsCacheTest(void)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
initPrograms(SourceCollections & programCollection) const636 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("dummy_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
checkSupport(Context & context) const760 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
createInstance(Context & context) const779 TestInstance* GraphicsCacheTest::createInstance (Context& context) const
780 {
781 return new GraphicsCacheTestInstance(context, &m_param);
782 }
783
GraphicsCacheTestInstance(Context & context,const CacheTestParam * param)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, "dummy_geo", "main");
961 if (m_param->getCompileMissShaders())
962 {
963 m_missPipelineBuilder.bindShaderStage(VK_SHADER_STAGE_GEOMETRY_BIT, "dummy_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
~GraphicsCacheTestInstance(void)1010 GraphicsCacheTestInstance::~GraphicsCacheTestInstance (void)
1011 {
1012 }
1013
prepareRenderPass(VkFramebuffer framebuffer,VkPipeline pipeline)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
prepareCommandBuffer(void)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
verifyTestResult(void)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:
ComputeCacheTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const CacheTestParam * param)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 { }
~ComputeCacheTest(void)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
initPrograms(SourceCollections & programCollection) const1133 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
createInstance(Context & context) const1154 TestInstance* ComputeCacheTest::createInstance (Context& context) const
1155 {
1156 return new ComputeCacheTestInstance(context, &m_param);
1157 }
1158
buildBuffers(void)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
buildDescriptorSets(deUint32 ndx)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
buildShader(void)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
buildPipeline(deUint32 ndx)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
ComputeCacheTestInstance(Context & context,const CacheTestParam * param)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
~ComputeCacheTestInstance(void)1314 ComputeCacheTestInstance::~ComputeCacheTestInstance (void)
1315 {
1316 }
1317
prepareCommandBuffer(void)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
verifyTestResult(void)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);
~PipelineFromCacheTest(void)1361 virtual ~PipelineFromCacheTest (void) { }
1362 virtual TestInstance* createInstance (Context& context) const;
1363 };
1364
PipelineFromCacheTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const CacheTestParam * param)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
createInstance(Context & context) const1380 TestInstance* PipelineFromCacheTest::createInstance (Context& context) const
1381 {
1382 return new PipelineFromCacheTestInstance(context, &m_param);
1383 }
1384
PipelineFromCacheTestInstance(Context & context,const CacheTestParam * param)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
~PipelineFromCacheTestInstance(void)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);
~PipelineFromIncompleteCacheTest(void)1424 virtual ~PipelineFromIncompleteCacheTest (void) {}
1425 virtual TestInstance* createInstance (Context& context) const;
1426 };
1427
PipelineFromIncompleteCacheTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const CacheTestParam * param)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
createInstance(Context & context) const1444 TestInstance* PipelineFromIncompleteCacheTest::createInstance (Context& context) const
1445 {
1446 return new PipelineFromIncompleteCacheTestInstance(context, &m_param);
1447 }
1448
PipelineFromIncompleteCacheTestInstance(Context & context,const CacheTestParam * param)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
~PipelineFromIncompleteCacheTestInstance(void)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
getMergeCacheTypeStr(MergeCacheType type)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
getMergeCacheTypesStr(const std::vector<MergeCacheType> & types)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:
MergeCacheTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const CacheTestParam * param,const MergeCacheTestParam * mergeCacheParam)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 { }
~MergeCacheTest(void)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
createInstance(Context & context) const1571 TestInstance* MergeCacheTest::createInstance (Context& context) const
1572 {
1573 return new MergeCacheTestInstance(context, &m_param, &m_mergeCacheParam);
1574 }
1575
MergeCacheTestInstance(Context & context,const CacheTestParam * param,const MergeCacheTestParam * mergeCacheParam)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
createPipelineCache(const DeviceInterface & vk,VkDevice device,MergeCacheType type)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:
CacheHeaderTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const CacheTestParam * param)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 { }
~CacheHeaderTest(void)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
createInstance(Context & context) const1718 TestInstance* CacheHeaderTest::createInstance (Context& context) const
1719 {
1720 return new CacheHeaderTestInstance(context, &m_param);
1721 }
1722
CacheHeaderTestInstance(Context & context,const CacheTestParam * param)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
~CacheHeaderTestInstance(void)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);
~InvalidSizeTest(void)1771 virtual ~InvalidSizeTest (void) {}
1772 virtual TestInstance* createInstance (Context& context) const;
1773 };
1774
InvalidSizeTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const CacheTestParam * param)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
createInstance(Context & context) const1790 TestInstance* InvalidSizeTest::createInstance (Context& context) const
1791 {
1792 return new InvalidSizeTestInstance(context, &m_param);
1793 }
1794
InvalidSizeTestInstance(Context & context,const CacheTestParam * param)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
~InvalidSizeTestInstance(void)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);
~ZeroSizeTest(void)1858 virtual ~ZeroSizeTest (void) {}
1859 virtual TestInstance* createInstance (Context& context) const;
1860 };
1861
ZeroSizeTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const CacheTestParam * param)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
createInstance(Context & context) const1877 TestInstance* ZeroSizeTest::createInstance (Context& context) const
1878 {
1879 return new ZeroSizeTestInstance(context, &m_param);
1880 }
1881
ZeroSizeTestInstance(Context & context,const CacheTestParam * param)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
~ZeroSizeTestInstance(void)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);
~InvalidBlobTest(void)1936 virtual ~InvalidBlobTest (void) {}
1937 virtual TestInstance* createInstance (Context& context) const;
1938 };
1939
InvalidBlobTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const CacheTestParam * param)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
createInstance(Context & context) const1955 TestInstance* InvalidBlobTest::createInstance (Context& context) const
1956 {
1957 return new InvalidBlobTestInstance(context, &m_param);
1958 }
1959
InvalidBlobTestInstance(Context & context,const CacheTestParam * param)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
~InvalidBlobTestInstance(void)2022 InvalidBlobTestInstance::~InvalidBlobTestInstance (void)
2023 {
2024 delete[] m_data;
2025 delete[] m_zeroBlock;
2026 }
2027 } // anonymous
2028
createCacheTests(tcu::TestContext & testCtx)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
2272