1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 ARM Ltd.
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 * \brief Pipeline Cache Tests
23 *//*--------------------------------------------------------------------*/
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"
37 #include "vkRefUtil.hpp"
38 #include "vkTypeUtil.hpp"
39 #include "vkCmdUtil.hpp"
40 #include "vkObjUtil.hpp"
41 #include "tcuImageCompare.hpp"
42 #include "deUniquePtr.hpp"
44 #include "tcuTestLog.hpp"
61 std::string getShaderFlagStr (const VkShaderStageFlags shader,
64 std::ostringstream desc;
65 if (shader & VK_SHADER_STAGE_COMPUTE_BIT)
67 desc << ((isDescription) ? "compute stage" : "compute_stage");
71 desc << ((isDescription) ? "vertex stage" : "vertex_stage");
72 if (shader & VK_SHADER_STAGE_GEOMETRY_BIT)
73 desc << ((isDescription) ? " geometry stage" : "_geometry_stage");
74 if (shader & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
75 desc << ((isDescription) ? " tessellation control stage" : "_tessellation_control_stage");
76 if (shader & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
77 desc << ((isDescription) ? " tessellation evaluation stage" : "_tessellation_evaluation_stage");
78 desc << ((isDescription) ? " fragment stage" : "_fragment_stage");
88 CacheTestParam (PipelineConstructionType pipelineConstructionType,
89 const VkShaderStageFlags shaders,
90 bool compileCacheMissShaders,
91 VkPipelineCacheCreateFlags pipelineCacheCreateFlags = 0u);
92 virtual ~CacheTestParam (void) = default;
93 virtual const std::string generateTestName (void) const;
94 virtual const std::string generateTestDescription (void) const;
95 PipelineConstructionType getPipelineConstructionType (void) const { return m_pipelineConstructionType; }
96 VkShaderStageFlags getShaderFlags (void) const { return m_shaders; }
97 VkPipelineCacheCreateFlags getPipelineCacheCreateFlags (void) const { return m_pipelineCacheCreateFlags; }
98 bool getCompileMissShaders (void) const { return m_compileCacheMissShaders; }
102 PipelineConstructionType m_pipelineConstructionType;
103 VkShaderStageFlags m_shaders;
104 VkPipelineCacheCreateFlags m_pipelineCacheCreateFlags;
105 bool m_compileCacheMissShaders;
108 CacheTestParam::CacheTestParam (PipelineConstructionType pipelineConstructionType, const VkShaderStageFlags shaders, bool compileCacheMissShaders, VkPipelineCacheCreateFlags pipelineCacheCreateFlags)
109 : m_pipelineConstructionType (pipelineConstructionType)
110 , m_shaders (shaders)
111 , m_pipelineCacheCreateFlags(pipelineCacheCreateFlags)
112 , m_compileCacheMissShaders (compileCacheMissShaders)
116 const std::string CacheTestParam::generateTestName (void) const
118 std::string name = getShaderFlagStr(m_shaders, false);
119 if (m_pipelineCacheCreateFlags == VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT) {
120 name += "_externally_synchronized";
125 const std::string CacheTestParam::generateTestDescription (void) const
127 std::string description = getShaderFlagStr(m_shaders, true);
128 if (m_pipelineCacheCreateFlags == VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT) {
129 description += "with externally synchronized bit";
134 template <class Test>
135 vkt::TestCase* newTestCase (tcu::TestContext& testContext,
136 const CacheTestParam* testParam)
138 return new Test(testContext,
139 testParam->generateTestName().c_str(),
140 testParam->generateTestDescription().c_str(),
144 Move<VkBuffer> createBufferAndBindMemory (Context& context, VkDeviceSize size, VkBufferUsageFlags usage, de::MovePtr<Allocation>* pAlloc)
146 const DeviceInterface& vk = context.getDeviceInterface();
147 const VkDevice vkDevice = context.getDevice();
148 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
150 const VkBufferCreateInfo vertexBufferParams =
152 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
153 DE_NULL, // const void* pNext;
154 0u, // VkBufferCreateFlags flags;
155 size, // VkDeviceSize size;
156 usage, // VkBufferUsageFlags usage;
157 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
158 1u, // deUint32 queueFamilyCount;
159 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
162 Move<VkBuffer> vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
164 *pAlloc = context.getDefaultAllocator().allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
165 VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, (*pAlloc)->getMemory(), (*pAlloc)->getOffset()));
170 Move<VkImage> createImage2DAndBindMemory (Context& context,
174 VkImageUsageFlags usage,
175 VkSampleCountFlagBits sampleCount,
176 de::details::MovePtr<Allocation>* pAlloc)
178 const DeviceInterface& vk = context.getDeviceInterface();
179 const VkDevice vkDevice = context.getDevice();
180 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
182 const VkImageCreateInfo colorImageParams =
184 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
185 DE_NULL, // const void* pNext;
186 0u, // VkImageCreateFlags flags;
187 VK_IMAGE_TYPE_2D, // VkImageType imageType;
188 format, // VkFormat format;
189 { width, height, 1u }, // VkExtent3D extent;
190 1u, // deUint32 mipLevels;
191 1u, // deUint32 arraySize;
192 sampleCount, // deUint32 samples;
193 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
194 usage, // VkImageUsageFlags usage;
195 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
196 1u, // deUint32 queueFamilyCount;
197 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
198 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
201 Move<VkImage> image = createImage(vk, vkDevice, &colorImageParams);
203 *pAlloc = context.getDefaultAllocator().allocate(getImageMemoryRequirements(vk, vkDevice, *image), MemoryRequirement::Any);
204 VK_CHECK(vk.bindImageMemory(vkDevice, *image, (*pAlloc)->getMemory(), (*pAlloc)->getOffset()));
210 class CacheTest : public vkt::TestCase
213 CacheTest (tcu::TestContext& testContext,
214 const std::string& name,
215 const std::string& description,
216 const CacheTestParam* param)
217 : vkt::TestCase (testContext, name, description)
220 virtual ~CacheTest (void) { }
222 const CacheTestParam m_param;
225 class CacheTestInstance : public vkt::TestInstance
230 PIPELINE_CACHE_NDX_NO_CACHE,
231 PIPELINE_CACHE_NDX_CACHED,
232 PIPELINE_CACHE_NDX_COUNT,
234 CacheTestInstance (Context& context,
235 const CacheTestParam* param);
236 virtual ~CacheTestInstance (void);
237 virtual tcu::TestStatus iterate (void);
239 virtual tcu::TestStatus verifyTestResult (void) = 0;
240 virtual void prepareCommandBuffer (void) = 0;
242 const CacheTestParam* m_param;
243 Move<VkCommandPool> m_cmdPool;
244 Move<VkCommandBuffer> m_cmdBuffer;
245 Move<VkPipelineCache> m_cache;
248 CacheTestInstance::CacheTestInstance (Context& context,
249 const CacheTestParam* param)
250 : TestInstance (context)
253 const DeviceInterface& vk = m_context.getDeviceInterface();
254 const VkDevice vkDevice = m_context.getDevice();
255 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
257 // Create command pool
258 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
260 // Create command buffer
261 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
263 // Create the Pipeline Cache
265 const VkPipelineCacheCreateInfo pipelineCacheCreateInfo =
267 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
268 DE_NULL, // const void* pNext;
269 m_param->getPipelineCacheCreateFlags(), // VkPipelineCacheCreateFlags flags;
270 0u, // deUintptr initialDataSize;
271 DE_NULL, // const void* pInitialData;
274 m_cache = createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo);
278 CacheTestInstance::~CacheTestInstance (void)
282 tcu::TestStatus CacheTestInstance::iterate (void)
284 const DeviceInterface& vk = m_context.getDeviceInterface();
285 const VkDevice vkDevice = m_context.getDevice();
286 const VkQueue queue = m_context.getUniversalQueue();
288 prepareCommandBuffer();
290 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
292 return verifyTestResult();
295 class GraphicsCacheTest : public CacheTest
298 GraphicsCacheTest (tcu::TestContext& testContext,
299 const std::string& name,
300 const std::string& description,
301 const CacheTestParam* param)
302 : CacheTest (testContext, name, description, param)
304 virtual ~GraphicsCacheTest (void) { }
305 virtual void initPrograms (SourceCollections& programCollection) const;
306 virtual void checkSupport (Context& context) const;
307 virtual TestInstance* createInstance (Context& context) const;
310 class GraphicsCacheTestInstance : public CacheTestInstance
313 GraphicsCacheTestInstance (Context& context,
314 const CacheTestParam* param);
315 virtual ~GraphicsCacheTestInstance (void);
318 void preparePipelineWrapper (GraphicsPipelineWrapper& gpw,
319 VkPipelineCache cache,
320 bool useMissShaders);
321 virtual void preparePipelines (void);
322 void prepareRenderPass (VkFramebuffer framebuffer, VkPipeline pipeline);
323 virtual void prepareCommandBuffer (void);
324 virtual tcu::TestStatus verifyTestResult (void);
327 const tcu::UVec2 m_renderSize;
328 const VkFormat m_colorFormat;
329 const VkFormat m_depthFormat;
330 Move<VkPipelineLayout> m_pipelineLayout;
332 Move<VkImage> m_depthImage;
333 de::MovePtr<Allocation> m_depthImageAlloc;
334 de::MovePtr<Allocation> m_colorImageAlloc[PIPELINE_CACHE_NDX_COUNT];
335 Move<VkImageView> m_depthAttachmentView;
336 VkImageMemoryBarrier m_imageLayoutBarriers[3];
338 Move<VkBuffer> m_vertexBuffer;
339 de::MovePtr<Allocation> m_vertexBufferMemory;
340 std::vector<Vertex4RGBA> m_vertices;
342 GraphicsPipelineWrapper m_pipeline[PIPELINE_CACHE_NDX_COUNT];
343 Move<VkRenderPass> m_renderPass;
345 Move<VkImage> m_colorImage[PIPELINE_CACHE_NDX_COUNT];
346 Move<VkImageView> m_colorAttachmentView[PIPELINE_CACHE_NDX_COUNT];
347 Move<VkFramebuffer> m_framebuffer[PIPELINE_CACHE_NDX_COUNT];
350 void GraphicsCacheTest::initPrograms (SourceCollections& programCollection) const
352 enum ShaderCacheOpType
354 SHADERS_CACHE_OP_HIT = 0,
355 SHADERS_CACHE_OP_MISS,
357 SHADERS_CACHE_OP_LAST
360 for (deUint32 shaderOpNdx = 0u; shaderOpNdx < SHADERS_CACHE_OP_LAST; shaderOpNdx++)
362 const ShaderCacheOpType shaderOp = (ShaderCacheOpType)shaderOpNdx;
364 if (shaderOp == SHADERS_CACHE_OP_MISS && !m_param.getCompileMissShaders())
367 const std::string missHitDiff = (shaderOp == SHADERS_CACHE_OP_HIT ? "" : " + 0.1");
368 const std::string missSuffix = (shaderOp == SHADERS_CACHE_OP_HIT ? "" : "_miss");
370 programCollection.glslSources.add("color_vert" + missSuffix) << glu::VertexSource(
372 "layout(location = 0) in vec4 position;\n"
373 "layout(location = 1) in vec4 color;\n"
374 "layout(location = 0) out highp vec4 vtxColor;\n"
377 " gl_Position = position;\n"
378 " vtxColor = color" + missHitDiff + ";\n"
381 programCollection.glslSources.add("color_frag" + missSuffix) << glu::FragmentSource(
383 "layout(location = 0) in highp vec4 vtxColor;\n"
384 "layout(location = 0) out highp vec4 fragColor;\n"
387 " fragColor = vtxColor" + missHitDiff + ";\n"
390 VkShaderStageFlags shaderFlag = m_param.getShaderFlags();
391 if (shaderFlag & VK_SHADER_STAGE_GEOMETRY_BIT)
393 programCollection.glslSources.add("unused_geo" + missSuffix) << glu::GeometrySource(
395 "layout(triangles) in;\n"
396 "layout(triangle_strip, max_vertices = 3) out;\n"
397 "layout(location = 0) in highp vec4 in_vtxColor[];\n"
398 "layout(location = 0) out highp vec4 vtxColor;\n"
399 "out gl_PerVertex { vec4 gl_Position; };\n"
400 "in gl_PerVertex { vec4 gl_Position; } gl_in[];\n"
403 " for(int ndx=0; ndx<3; ndx++)\n"
405 " gl_Position = gl_in[ndx].gl_Position;\n"
406 " vtxColor = in_vtxColor[ndx]" + missHitDiff + ";\n"
412 if (shaderFlag & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
414 programCollection.glslSources.add("basic_tcs" + missSuffix) << glu::TessellationControlSource(
416 "layout(vertices = 3) out;\n"
417 "layout(location = 0) in highp vec4 color[];\n"
418 "layout(location = 0) out highp vec4 vtxColor[];\n"
419 "out gl_PerVertex { vec4 gl_Position; } gl_out[3];\n"
420 "in gl_PerVertex { vec4 gl_Position; } gl_in[gl_MaxPatchVertices];\n"
423 " gl_TessLevelOuter[0] = 4.0;\n"
424 " gl_TessLevelOuter[1] = 4.0;\n"
425 " gl_TessLevelOuter[2] = 4.0;\n"
426 " gl_TessLevelInner[0] = 4.0;\n"
427 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
428 " vtxColor[gl_InvocationID] = color[gl_InvocationID]" + missHitDiff + ";\n"
431 if (shaderFlag & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
433 programCollection.glslSources.add("basic_tes" + missSuffix) << glu::TessellationEvaluationSource(
435 "layout(triangles, fractional_even_spacing, ccw) in;\n"
436 "layout(location = 0) in highp vec4 colors[];\n"
437 "layout(location = 0) out highp vec4 vtxColor;\n"
438 "out gl_PerVertex { vec4 gl_Position; };\n"
439 "in gl_PerVertex { vec4 gl_Position; } gl_in[gl_MaxPatchVertices];\n"
442 " float u = gl_TessCoord.x;\n"
443 " float v = gl_TessCoord.y;\n"
444 " float w = gl_TessCoord.z;\n"
445 " vec4 pos = vec4(0);\n"
446 " vec4 color = vec4(0)" + missHitDiff + ";\n"
447 " pos.xyz += u * gl_in[0].gl_Position.xyz;\n"
448 " color.xyz += u * colors[0].xyz;\n"
449 " pos.xyz += v * gl_in[1].gl_Position.xyz;\n"
450 " color.xyz += v * colors[1].xyz;\n"
451 " pos.xyz += w * gl_in[2].gl_Position.xyz;\n"
452 " color.xyz += w * colors[2].xyz;\n"
455 " gl_Position = pos;\n"
456 " vtxColor = color;\n"
462 void GraphicsCacheTest::checkSupport (Context& context) const
464 if (m_param.getShaderFlags() & VK_SHADER_STAGE_GEOMETRY_BIT)
465 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
466 if ((m_param.getShaderFlags() & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ||
467 (m_param.getShaderFlags() & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT))
468 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
470 checkPipelineLibraryRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_param.getPipelineConstructionType());
473 TestInstance* GraphicsCacheTest::createInstance (Context& context) const
475 return new GraphicsCacheTestInstance(context, &m_param);
478 GraphicsCacheTestInstance::GraphicsCacheTestInstance (Context& context,
479 const CacheTestParam* param)
480 : CacheTestInstance (context,param)
481 , m_renderSize (32u, 32u)
482 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
483 , m_depthFormat (VK_FORMAT_D16_UNORM)
486 { context.getDeviceInterface(), context.getDevice(), param->getPipelineConstructionType() },
487 { context.getDeviceInterface(), context.getDevice(), param->getPipelineConstructionType() },
490 const DeviceInterface& vk = m_context.getDeviceInterface();
491 const VkDevice vkDevice = m_context.getDevice();
493 // Create vertex buffer
495 m_vertexBuffer = createBufferAndBindMemory(m_context, 1024u, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, &m_vertexBufferMemory);
497 m_vertices = createOverlappingQuads();
498 // Load vertices into vertex buffer
499 deMemcpy(m_vertexBufferMemory->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
500 flushAlloc(vk, vkDevice, *m_vertexBufferMemory);
503 // Create render pass
504 m_renderPass = makeRenderPass(vk, vkDevice, m_colorFormat, m_depthFormat);
506 const VkComponentMapping ComponentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
507 // Create color image
509 m_colorImage[PIPELINE_CACHE_NDX_NO_CACHE] = createImage2DAndBindMemory(m_context,
513 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
514 VK_SAMPLE_COUNT_1_BIT,
515 &m_colorImageAlloc[PIPELINE_CACHE_NDX_NO_CACHE]);
516 m_colorImage[PIPELINE_CACHE_NDX_CACHED] = createImage2DAndBindMemory(m_context,
520 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
521 VK_SAMPLE_COUNT_1_BIT,
522 &m_colorImageAlloc[PIPELINE_CACHE_NDX_CACHED]);
525 // Create depth image
527 m_depthImage = createImage2DAndBindMemory(m_context,
531 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
532 VK_SAMPLE_COUNT_1_BIT,
536 // Set up image layout transition barriers
538 VkImageMemoryBarrier colorImageBarrier =
540 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
541 DE_NULL, // const void* pNext;
542 0u, // VkAccessFlags srcAccessMask;
543 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
544 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
545 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
546 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
547 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
548 *m_colorImage[PIPELINE_CACHE_NDX_NO_CACHE], // VkImage image;
549 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
552 m_imageLayoutBarriers[0] = colorImageBarrier;
554 colorImageBarrier.image = *m_colorImage[PIPELINE_CACHE_NDX_CACHED];
555 m_imageLayoutBarriers[1] = colorImageBarrier;
557 const VkImageMemoryBarrier depthImageBarrier =
559 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
560 DE_NULL, // const void* pNext;
561 0u, // VkAccessFlags srcAccessMask;
562 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
563 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
564 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
565 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
566 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
567 *m_depthImage, // VkImage image;
568 { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
571 m_imageLayoutBarriers[2] = depthImageBarrier;
573 // Create color attachment view
575 VkImageViewCreateInfo colorAttachmentViewParams =
577 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
578 DE_NULL, // const void* pNext;
579 0u, // VkImageViewCreateFlags flags;
580 *m_colorImage[PIPELINE_CACHE_NDX_NO_CACHE], // VkImage image;
581 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
582 m_colorFormat, // VkFormat format;
583 ComponentMappingRGBA, // VkComponentMapping components;
584 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
587 m_colorAttachmentView[PIPELINE_CACHE_NDX_NO_CACHE] = createImageView(vk, vkDevice, &colorAttachmentViewParams);
589 colorAttachmentViewParams.image = *m_colorImage[PIPELINE_CACHE_NDX_CACHED];
590 m_colorAttachmentView[PIPELINE_CACHE_NDX_CACHED] = createImageView(vk, vkDevice, &colorAttachmentViewParams);
593 // Create depth attachment view
595 const VkImageViewCreateInfo depthAttachmentViewParams =
597 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
598 DE_NULL, // const void* pNext;
599 0u, // VkImageViewCreateFlags flags;
600 *m_depthImage, // VkImage image;
601 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
602 m_depthFormat, // VkFormat format;
603 ComponentMappingRGBA, // VkComponentMapping components;
604 { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
607 m_depthAttachmentView = createImageView(vk, vkDevice, &depthAttachmentViewParams);
610 // Create framebuffer
612 VkImageView attachmentBindInfos[2] =
614 *m_colorAttachmentView[PIPELINE_CACHE_NDX_NO_CACHE],
615 *m_depthAttachmentView,
618 const VkFramebufferCreateInfo framebufferParams =
620 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
621 DE_NULL, // const void* pNext;
622 0u, // VkFramebufferCreateFlags flags;
623 *m_renderPass, // VkRenderPass renderPass;
624 2u, // deUint32 attachmentCount;
625 attachmentBindInfos, // const VkImageView* pAttachments;
626 (deUint32)m_renderSize.x(), // deUint32 width;
627 (deUint32)m_renderSize.y(), // deUint32 height;
628 1u, // deUint32 layers;
631 m_framebuffer[PIPELINE_CACHE_NDX_NO_CACHE] = createFramebuffer(vk, vkDevice, &framebufferParams);
633 attachmentBindInfos[0] = *m_colorAttachmentView[PIPELINE_CACHE_NDX_CACHED];
634 m_framebuffer[PIPELINE_CACHE_NDX_CACHED] = createFramebuffer(vk, vkDevice, &framebufferParams);
637 // Create pipeline layout
639 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
641 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
642 DE_NULL, // const void* pNext;
643 0u, // VkPipelineLayoutCreateFlags flags;
644 0u, // deUint32 setLayoutCount;
645 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
646 0u, // deUint32 pushConstantRangeCount;
647 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
650 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
654 GraphicsCacheTestInstance::~GraphicsCacheTestInstance (void)
658 void GraphicsCacheTestInstance::preparePipelineWrapper(GraphicsPipelineWrapper& gpw,
659 VkPipelineCache cache,
660 bool useMissShaders = false)
662 static const VkPipelineDepthStencilStateCreateInfo defaultDepthStencilState
664 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
665 DE_NULL, // const void* pNext;
666 0u, // VkPipelineDepthStencilStateCreateFlags flags;
667 VK_TRUE, // VkBool32 depthTestEnable;
668 VK_TRUE, // VkBool32 depthWriteEnable;
669 VK_COMPARE_OP_LESS_OR_EQUAL, // VkCompareOp depthCompareOp;
670 VK_FALSE, // VkBool32 depthBoundsTestEnable;
671 VK_FALSE, // VkBool32 stencilTestEnable;
672 { // VkStencilOpState front;
673 VK_STENCIL_OP_KEEP, // VkStencilOp failOp;
674 VK_STENCIL_OP_KEEP, // VkStencilOp passOp;
675 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp;
676 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
677 0u, // deUint32 compareMask;
678 0u, // deUint32 writeMask;
679 0u, // deUint32 reference;
681 { // VkStencilOpState back;
682 VK_STENCIL_OP_KEEP, // VkStencilOp failOp;
683 VK_STENCIL_OP_KEEP, // VkStencilOp passOp;
684 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp;
685 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
686 0u, // deUint32 compareMask;
687 0u, // deUint32 writeMask;
688 0u, // deUint32 reference;
690 0.0f, // float minDepthBounds;
691 1.0f, // float maxDepthBounds;
694 static const VkVertexInputBindingDescription defaultVertexInputBindingDescription
696 0u, // deUint32 binding;
697 sizeof(Vertex4RGBA), // deUint32 strideInBytes;
698 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
701 static const VkVertexInputAttributeDescription defaultVertexInputAttributeDescriptions[]
704 0u, // deUint32 location;
705 0u, // deUint32 binding;
706 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
707 0u // deUint32 offsetInBytes;
710 1u, // deUint32 location;
711 0u, // deUint32 binding;
712 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
713 DE_OFFSET_OF(Vertex4RGBA, color), // deUint32 offsetInBytes;
717 static const VkPipelineVertexInputStateCreateInfo defaultVertexInputStateParams
719 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
720 DE_NULL, // const void* pNext;
721 0u, // VkPipelineVertexInputStateCreateFlags flags;
722 1u, // deUint32 vertexBindingDescriptionCount;
723 &defaultVertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
724 2u, // deUint32 vertexAttributeDescriptionCount;
725 defaultVertexInputAttributeDescriptions, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
728 const DeviceInterface& vk = m_context.getDeviceInterface();
729 const VkDevice vkDevice = m_context.getDevice();
730 const std::string postfix = useMissShaders ? "_miss" : "";
732 auto createModule = [&vk, vkDevice, &postfix](Context& context, std::string shaderName)
734 return createShaderModule(vk, vkDevice, context.getBinaryCollection().get(shaderName + postfix), 0);
737 // Bind shader stages
738 Move<VkShaderModule> vertShaderModule = createModule(m_context, "color_vert");
739 Move<VkShaderModule> fragShaderModule = createModule(m_context, "color_frag");
740 Move<VkShaderModule> tescShaderModule;
741 Move<VkShaderModule> teseShaderModule;
742 Move<VkShaderModule> geomShaderModule;
744 if (m_param->getShaderFlags() & VK_SHADER_STAGE_GEOMETRY_BIT)
745 geomShaderModule = createModule(m_context, "unused_geo");
746 if (m_param->getShaderFlags() & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
747 tescShaderModule = createModule(m_context, "basic_tcs");
748 if (m_param->getShaderFlags() & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
749 teseShaderModule = createModule(m_context, "basic_tes");
751 const std::vector<VkViewport> viewport { makeViewport(m_renderSize) };
752 const std::vector<VkRect2D> scissor { makeRect2D(m_renderSize) };
754 gpw.setDefaultTopology((m_param->getShaderFlags() & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
755 ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
756 .setDefaultRasterizationState()
757 .setDefaultColorBlendState()
758 .setDefaultMultisampleState()
759 .setupVertexInputStete(&defaultVertexInputStateParams)
760 .setupPreRasterizationShaderState(viewport,
770 .setupFragmentShaderState(*m_pipelineLayout, *m_renderPass, 0u, *fragShaderModule, &defaultDepthStencilState)
771 .setupFragmentOutputState(*m_renderPass)
772 .setMonolithicPipelineLayout(*m_pipelineLayout)
773 .buildPipeline(cache);
776 void GraphicsCacheTestInstance::preparePipelines (void)
778 preparePipelineWrapper(m_pipeline[PIPELINE_CACHE_NDX_NO_CACHE], *m_cache);
779 preparePipelineWrapper(m_pipeline[PIPELINE_CACHE_NDX_CACHED], *m_cache);
782 void GraphicsCacheTestInstance::prepareRenderPass (VkFramebuffer framebuffer, VkPipeline pipeline)
784 const DeviceInterface& vk = m_context.getDeviceInterface();
786 const VkClearValue attachmentClearValues[2] =
788 defaultClearValue(m_colorFormat),
789 defaultClearValue(m_depthFormat),
792 beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), 2u, attachmentClearValues);
794 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
795 VkDeviceSize offsets = 0u;
796 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &offsets);
797 vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1u, 0u, 0u);
799 endRenderPass(vk, *m_cmdBuffer);
802 void GraphicsCacheTestInstance::prepareCommandBuffer (void)
804 const DeviceInterface& vk = m_context.getDeviceInterface();
808 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
810 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,
811 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(m_imageLayoutBarriers), m_imageLayoutBarriers);
813 prepareRenderPass(*m_framebuffer[PIPELINE_CACHE_NDX_NO_CACHE], m_pipeline[PIPELINE_CACHE_NDX_NO_CACHE].getPipeline());
815 // After the first render pass, the images are in correct layouts
817 prepareRenderPass(*m_framebuffer[PIPELINE_CACHE_NDX_CACHED], m_pipeline[PIPELINE_CACHE_NDX_CACHED].getPipeline());
819 endCommandBuffer(vk, *m_cmdBuffer);
822 tcu::TestStatus GraphicsCacheTestInstance::verifyTestResult (void)
824 const DeviceInterface& vk = m_context.getDeviceInterface();
825 const VkDevice vkDevice = m_context.getDevice();
826 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
828 const VkQueue queue = m_context.getUniversalQueue();
829 de::MovePtr<tcu::TextureLevel> resultNoCache = readColorAttachment(vk,
833 m_context.getDefaultAllocator(),
834 *m_colorImage[PIPELINE_CACHE_NDX_NO_CACHE],
837 de::MovePtr<tcu::TextureLevel> resultCache = readColorAttachment(vk,
841 m_context.getDefaultAllocator(),
842 *m_colorImage[PIPELINE_CACHE_NDX_CACHED],
846 bool compareOk = tcu::intThresholdCompare(m_context.getTestContext().getLog(),
849 resultNoCache->getAccess(),
850 resultCache->getAccess(),
851 tcu::UVec4(1, 1, 1, 1),
852 tcu::COMPARE_LOG_RESULT);
855 return tcu::TestStatus::pass("Render images w/o cached pipeline match.");
857 return tcu::TestStatus::fail("Render Images mismatch.");
860 class ComputeCacheTest : public CacheTest
863 ComputeCacheTest (tcu::TestContext& testContext,
864 const std::string& name,
865 const std::string& description,
866 const CacheTestParam* param)
867 : CacheTest (testContext, name, description, param)
869 virtual ~ComputeCacheTest (void) { }
870 virtual void initPrograms (SourceCollections& programCollection) const;
871 virtual TestInstance* createInstance (Context& context) const;
874 class ComputeCacheTestInstance : public CacheTestInstance
877 ComputeCacheTestInstance (Context& context,
878 const CacheTestParam* param);
879 virtual ~ComputeCacheTestInstance (void);
880 virtual void prepareCommandBuffer (void);
882 virtual tcu::TestStatus verifyTestResult (void);
883 void buildBuffers (void);
884 void buildDescriptorSets (deUint32 ndx);
885 void buildShader (void);
886 void buildPipeline (deUint32 ndx);
888 Move<VkBuffer> m_inputBuf;
889 de::MovePtr<Allocation> m_inputBufferAlloc;
890 Move<VkShaderModule> m_computeShaderModule;
892 Move<VkBuffer> m_outputBuf[PIPELINE_CACHE_NDX_COUNT];
893 de::MovePtr<Allocation> m_outputBufferAlloc[PIPELINE_CACHE_NDX_COUNT];
895 Move<VkDescriptorPool> m_descriptorPool[PIPELINE_CACHE_NDX_COUNT];
896 Move<VkDescriptorSetLayout> m_descriptorSetLayout[PIPELINE_CACHE_NDX_COUNT];
897 Move<VkDescriptorSet> m_descriptorSet[PIPELINE_CACHE_NDX_COUNT];
899 Move<VkPipelineLayout> m_pipelineLayout[PIPELINE_CACHE_NDX_COUNT];
900 Move<VkPipeline> m_pipeline[PIPELINE_CACHE_NDX_COUNT];
903 void ComputeCacheTest::initPrograms (SourceCollections& programCollection) const
905 programCollection.glslSources.add("basic_compute") << glu::ComputeSource(
907 "layout(local_size_x = 1) in;\n"
908 "layout(std430) buffer;\n"
909 "layout(binding = 0) readonly buffer Input0\n"
911 " vec4 elements[];\n"
913 "layout(binding = 1) writeonly buffer Output\n"
915 " vec4 elements[];\n"
919 " uint ident = gl_GlobalInvocationID.x;\n"
920 " output_data.elements[ident] = input_data0.elements[ident] * input_data0.elements[ident];\n"
924 TestInstance* ComputeCacheTest::createInstance (Context& context) const
926 return new ComputeCacheTestInstance(context, &m_param);
929 void ComputeCacheTestInstance::buildBuffers (void)
931 const DeviceInterface& vk = m_context.getDeviceInterface();
932 const VkDevice vkDevice = m_context.getDevice();
934 // Create buffer object, allocate storage, and generate input data
935 const VkDeviceSize size = sizeof(tcu::Vec4) * 128u;
936 m_inputBuf = createBufferAndBindMemory(m_context, size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, &m_inputBufferAlloc);
938 // Initialize input buffer
939 tcu::Vec4* pVec = reinterpret_cast<tcu::Vec4*>(m_inputBufferAlloc->getHostPtr());
940 for (deUint32 ndx = 0u; ndx < 128u; ndx++)
942 for (deUint32 component = 0u; component < 4u; component++)
943 pVec[ndx][component]= (float)(ndx * (component + 1u));
945 flushAlloc(vk, vkDevice, *m_inputBufferAlloc);
947 // Clear the output buffer
948 for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
950 m_outputBuf[ndx] = createBufferAndBindMemory(m_context, size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, &m_outputBufferAlloc[ndx]);
952 pVec = reinterpret_cast<tcu::Vec4*>(m_outputBufferAlloc[ndx]->getHostPtr());
954 for (deUint32 i = 0; i < (size / sizeof(tcu::Vec4)); i++)
955 pVec[i] = tcu::Vec4(0.0f);
957 flushAlloc(vk, vkDevice, *m_outputBufferAlloc[ndx]);
961 void ComputeCacheTestInstance::buildDescriptorSets (deUint32 ndx)
963 const DeviceInterface& vk = m_context.getDeviceInterface();
964 const VkDevice vkDevice = m_context.getDevice();
966 // Create descriptor set layout
967 DescriptorSetLayoutBuilder descLayoutBuilder;
969 for (deUint32 bindingNdx = 0u; bindingNdx < 2u; bindingNdx++)
970 descLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT);
972 m_descriptorSetLayout[ndx] = descLayoutBuilder.build(vk, vkDevice);
974 std::vector<VkDescriptorBufferInfo> descriptorInfos;
975 descriptorInfos.push_back(makeDescriptorBufferInfo(*m_inputBuf, 0u, sizeof(tcu::Vec4) * 128u));
976 descriptorInfos.push_back(makeDescriptorBufferInfo(*m_outputBuf[ndx], 0u, sizeof(tcu::Vec4) * 128u));
978 // Create descriptor pool
979 m_descriptorPool[ndx] = DescriptorPoolBuilder().addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2u).build(vk,
981 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
984 // Create descriptor set
985 const VkDescriptorSetAllocateInfo descriptorSetAllocInfo =
987 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType;
988 DE_NULL, // const void* pNext;
989 *m_descriptorPool[ndx], // VkDescriptorPool descriptorPool;
990 1u, // deUint32 setLayoutCount;
991 &m_descriptorSetLayout[ndx].get(), // const VkDescriptorSetLayout* pSetLayouts;
993 m_descriptorSet[ndx] = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocInfo);
995 DescriptorSetUpdateBuilder builder;
996 for (deUint32 descriptorNdx = 0u; descriptorNdx < 2u; descriptorNdx++)
998 builder.writeSingle(*m_descriptorSet[ndx],
999 DescriptorSetUpdateBuilder::Location::binding(descriptorNdx),
1000 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1001 &descriptorInfos[descriptorNdx]);
1003 builder.update(vk, vkDevice);
1006 void ComputeCacheTestInstance::buildShader (void)
1008 const DeviceInterface& vk = m_context.getDeviceInterface();
1009 const VkDevice vkDevice = m_context.getDevice();
1011 // Create compute shader
1012 VkShaderModuleCreateInfo shaderModuleCreateInfo =
1014 VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, // VkStructureType sType;
1015 DE_NULL, // const void* pNext;
1016 0u, // VkShaderModuleCreateFlags flags;
1017 m_context.getBinaryCollection().get("basic_compute").getSize(), // deUintptr codeSize;
1018 (deUint32*)m_context.getBinaryCollection().get("basic_compute").getBinary(), // const deUint32* pCode;
1020 m_computeShaderModule = createShaderModule(vk, vkDevice, &shaderModuleCreateInfo);
1023 void ComputeCacheTestInstance::buildPipeline (deUint32 ndx)
1025 const DeviceInterface& vk = m_context.getDeviceInterface();
1026 const VkDevice vkDevice = m_context.getDevice();
1028 // Create compute pipeline layout
1029 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
1031 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1032 DE_NULL, // const void* pNext;
1033 0u, // VkPipelineLayoutCreateFlags flags;
1034 1u, // deUint32 setLayoutCount;
1035 &m_descriptorSetLayout[ndx].get(), // const VkDescriptorSetLayout* pSetLayouts;
1036 0u, // deUint32 pushConstantRangeCount;
1037 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
1040 m_pipelineLayout[ndx] = createPipelineLayout(vk, vkDevice, &pipelineLayoutCreateInfo);
1042 const VkPipelineShaderStageCreateInfo stageCreateInfo =
1044 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1045 DE_NULL, // const void* pNext;
1046 0u, // VkPipelineShaderStageCreateFlags flags;
1047 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
1048 *m_computeShaderModule, // VkShaderModule module;
1049 "main", // const char* pName;
1050 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
1053 const VkComputePipelineCreateInfo pipelineCreateInfo =
1055 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
1056 DE_NULL, // const void* pNext;
1057 0u, // VkPipelineCreateFlags flags;
1058 stageCreateInfo, // VkPipelineShaderStageCreateInfo stage;
1059 *m_pipelineLayout[ndx], // VkPipelineLayout layout;
1060 (VkPipeline)0, // VkPipeline basePipelineHandle;
1061 0u, // deInt32 basePipelineIndex;
1064 m_pipeline[ndx] = createComputePipeline(vk, vkDevice, *m_cache, &pipelineCreateInfo);
1067 ComputeCacheTestInstance::ComputeCacheTestInstance (Context& context,
1068 const CacheTestParam* param)
1069 : CacheTestInstance (context, param)
1073 buildDescriptorSets(PIPELINE_CACHE_NDX_NO_CACHE);
1075 buildDescriptorSets(PIPELINE_CACHE_NDX_CACHED);
1079 buildPipeline(PIPELINE_CACHE_NDX_NO_CACHE);
1081 buildPipeline(PIPELINE_CACHE_NDX_CACHED);
1084 ComputeCacheTestInstance::~ComputeCacheTestInstance (void)
1088 void ComputeCacheTestInstance::prepareCommandBuffer (void)
1090 const DeviceInterface& vk = m_context.getDeviceInterface();
1092 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
1094 for (deUint32 ndx = 0; ndx < PIPELINE_CACHE_NDX_COUNT; ndx++)
1096 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipeline[ndx]);
1097 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout[ndx], 0u, 1u, &m_descriptorSet[ndx].get(), 0u, DE_NULL);
1098 vk.cmdDispatch(*m_cmdBuffer, 128u, 1u, 1u);
1101 endCommandBuffer(vk, *m_cmdBuffer);
1104 tcu::TestStatus ComputeCacheTestInstance::verifyTestResult (void)
1106 const DeviceInterface& vk = m_context.getDeviceInterface();
1107 const VkDevice vkDevice = m_context.getDevice();
1109 // Read the content of output buffers
1110 invalidateAlloc(vk, vkDevice, *m_outputBufferAlloc[PIPELINE_CACHE_NDX_NO_CACHE]);
1112 invalidateAlloc(vk, vkDevice, *m_outputBufferAlloc[PIPELINE_CACHE_NDX_CACHED]);
1113 // Compare the content
1114 deUint8* bufNoCache = reinterpret_cast<deUint8*>(m_outputBufferAlloc[PIPELINE_CACHE_NDX_NO_CACHE]->getHostPtr());
1115 deUint8* bufCached = reinterpret_cast<deUint8*>(m_outputBufferAlloc[PIPELINE_CACHE_NDX_CACHED]->getHostPtr());
1116 for (deUint32 ndx = 0u; ndx < sizeof(tcu::Vec4) * 128u; ndx++)
1118 if (bufNoCache[ndx] != bufCached[ndx])
1120 return tcu::TestStatus::fail("Output buffers w/o cached pipeline mismatch.");
1124 return tcu::TestStatus::pass("Output buffers w/o cached pipeline match.");
1127 class PipelineFromCacheTest : public GraphicsCacheTest
1130 PipelineFromCacheTest (tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param);
1131 virtual ~PipelineFromCacheTest (void) { }
1132 virtual TestInstance* createInstance (Context& context) const;
1135 PipelineFromCacheTest::PipelineFromCacheTest (tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param)
1136 : GraphicsCacheTest(testContext, name, description, param)
1140 class PipelineFromCacheTestInstance : public GraphicsCacheTestInstance
1143 PipelineFromCacheTestInstance (Context& context, const CacheTestParam* param);
1144 virtual ~PipelineFromCacheTestInstance (void);
1147 void preparePipelines(void);
1150 Move<VkPipelineCache> m_newCache;
1154 TestInstance* PipelineFromCacheTest::createInstance (Context& context) const
1156 return new PipelineFromCacheTestInstance(context, &m_param);
1159 PipelineFromCacheTestInstance::PipelineFromCacheTestInstance (Context& context, const CacheTestParam* param)
1160 : GraphicsCacheTestInstance (context, param)
1163 const DeviceInterface& vk = m_context.getDeviceInterface();
1164 const VkDevice vkDevice = m_context.getDevice();
1166 // Create more pipeline caches
1168 size_t dataSize = 0u;
1170 VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, DE_NULL));
1172 m_data = new deUint8[dataSize];
1174 VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, (void*)m_data));
1176 const VkPipelineCacheCreateInfo pipelineCacheCreateInfo =
1178 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
1179 DE_NULL, // const void* pNext;
1180 0u, // VkPipelineCacheCreateFlags flags;
1181 dataSize, // deUintptr initialDataSize;
1182 m_data, // const void* pInitialData;
1184 m_newCache = createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo);
1188 PipelineFromCacheTestInstance::~PipelineFromCacheTestInstance (void)
1193 void PipelineFromCacheTestInstance::preparePipelines (void)
1195 preparePipelineWrapper(m_pipeline[PIPELINE_CACHE_NDX_NO_CACHE], *m_cache);
1196 preparePipelineWrapper(m_pipeline[PIPELINE_CACHE_NDX_CACHED], *m_newCache);
1199 class PipelineFromIncompleteCacheTest : public GraphicsCacheTest
1202 PipelineFromIncompleteCacheTest (tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param);
1203 virtual ~PipelineFromIncompleteCacheTest (void) {}
1204 virtual TestInstance* createInstance (Context& context) const;
1207 PipelineFromIncompleteCacheTest::PipelineFromIncompleteCacheTest (tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param)
1208 : GraphicsCacheTest(testContext, name, description, param)
1212 class PipelineFromIncompleteCacheTestInstance : public GraphicsCacheTestInstance
1215 PipelineFromIncompleteCacheTestInstance(Context& context, const CacheTestParam* param);
1216 virtual ~PipelineFromIncompleteCacheTestInstance(void);
1218 void preparePipelines(void);
1220 Move<VkPipelineCache> m_newCache;
1224 TestInstance* PipelineFromIncompleteCacheTest::createInstance (Context& context) const
1226 return new PipelineFromIncompleteCacheTestInstance(context, &m_param);
1229 PipelineFromIncompleteCacheTestInstance::PipelineFromIncompleteCacheTestInstance (Context& context, const CacheTestParam* param)
1230 : GraphicsCacheTestInstance (context, param)
1233 const DeviceInterface& vk = m_context.getDeviceInterface();
1234 const VkDevice vkDevice = m_context.getDevice();
1236 // Create more pipeline caches
1238 size_t dataSize = 0u;
1239 VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, DE_NULL));
1242 TCU_THROW(NotSupportedError, "Empty pipeline cache - unable to test");
1246 m_data = new deUint8[dataSize];
1248 if (vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, (void*)m_data) != VK_INCOMPLETE)
1249 TCU_THROW(TestError, "GetPipelineCacheData should return VK_INCOMPLETE state!");
1251 const VkPipelineCacheCreateInfo pipelineCacheCreateInfo =
1253 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
1254 DE_NULL, // const void* pNext;
1255 0u, // VkPipelineCacheCreateFlags flags;
1256 dataSize, // deUintptr initialDataSize;
1257 m_data, // const void* pInitialData;
1259 m_newCache = createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo);
1263 PipelineFromIncompleteCacheTestInstance::~PipelineFromIncompleteCacheTestInstance (void)
1268 void PipelineFromIncompleteCacheTestInstance::preparePipelines (void)
1270 preparePipelineWrapper(m_pipeline[PIPELINE_CACHE_NDX_NO_CACHE], *m_cache);
1271 preparePipelineWrapper(m_pipeline[PIPELINE_CACHE_NDX_CACHED], *m_newCache);
1276 MERGE_CACHE_EMPTY = 0,
1277 MERGE_CACHE_FROM_DATA,
1280 MERGE_CACHE_MISS_AND_HIT,
1283 MERGE_CACHE_TYPE_LAST = MERGE_CACHE_MERGED
1286 std::string getMergeCacheTypeStr (MergeCacheType type)
1290 case MERGE_CACHE_EMPTY:
1292 case MERGE_CACHE_FROM_DATA:
1294 case MERGE_CACHE_HIT:
1296 case MERGE_CACHE_MISS_AND_HIT:
1298 case MERGE_CACHE_MISS:
1300 case MERGE_CACHE_MERGED:
1303 TCU_FAIL("unhandled merge cache type");
1306 std::string getMergeCacheTypesStr (const std::vector<MergeCacheType>& types)
1309 for (size_t idx = 0; idx < types.size(); ++idx)
1313 ret += getMergeCacheTypeStr(types[idx]);
1319 class MergeCacheTestParam
1322 MergeCacheType destCacheType;
1323 std::vector<MergeCacheType> srcCacheTypes;
1326 class MergeCacheTest : public GraphicsCacheTest
1329 MergeCacheTest (tcu::TestContext& testContext,
1330 const std::string& name,
1331 const std::string& description,
1332 const CacheTestParam* param,
1333 const MergeCacheTestParam* mergeCacheParam)
1334 : GraphicsCacheTest (testContext, name, description, param)
1335 , m_mergeCacheParam (*mergeCacheParam)
1337 virtual ~MergeCacheTest (void) { }
1338 virtual TestInstance* createInstance (Context& context) const;
1340 const MergeCacheTestParam m_mergeCacheParam;
1343 class MergeCacheTestInstance : public GraphicsCacheTestInstance
1346 MergeCacheTestInstance (Context& context,
1347 const CacheTestParam* param,
1348 const MergeCacheTestParam* mergeCacheParam);
1350 Move<VkPipelineCache> createPipelineCache (const DeviceInterface& vk, VkDevice device, MergeCacheType type);
1353 void preparePipelines (void);
1356 Move<VkPipelineCache> m_cacheMerged;
1359 TestInstance* MergeCacheTest::createInstance (Context& context) const
1361 return new MergeCacheTestInstance(context, &m_param, &m_mergeCacheParam);
1364 MergeCacheTestInstance::MergeCacheTestInstance (Context& context, const CacheTestParam* param, const MergeCacheTestParam* mergeCacheParam)
1365 : GraphicsCacheTestInstance (context, param)
1367 const DeviceInterface& vk = m_context.getDeviceInterface();
1368 const VkDevice vkDevice = m_context.getDevice();
1370 // Create a merge destination cache
1371 m_cacheMerged = createPipelineCache(vk, vkDevice, mergeCacheParam->destCacheType);
1373 // Create more pipeline caches
1374 std::vector<VkPipelineCache> sourceCaches (mergeCacheParam->srcCacheTypes.size());
1375 typedef de::SharedPtr<Move<VkPipelineCache> > PipelineCachePtr;
1376 std::vector<PipelineCachePtr> sourceCachePtrs (sourceCaches.size());
1378 for (size_t sourceIdx = 0; sourceIdx < mergeCacheParam->srcCacheTypes.size(); sourceIdx++)
1380 // vk::Move is not copyable, so create it on heap and wrap into de::SharedPtr
1381 PipelineCachePtr pipelineCachePtr (new Move<VkPipelineCache>());
1382 *pipelineCachePtr = createPipelineCache(vk, vkDevice, mergeCacheParam->srcCacheTypes[sourceIdx]);
1384 sourceCachePtrs[sourceIdx] = pipelineCachePtr;
1385 sourceCaches[sourceIdx] = **pipelineCachePtr;
1390 VK_CHECK(vk.mergePipelineCaches(vkDevice, *m_cacheMerged, static_cast<deUint32>(sourceCaches.size()), &sourceCaches[0]));
1393 Move<VkPipelineCache> MergeCacheTestInstance::createPipelineCache (const DeviceInterface& vk, VkDevice device, MergeCacheType type)
1395 VkPipelineCacheCreateInfo pipelineCacheCreateInfo =
1397 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
1398 DE_NULL, // const void* pNext;
1399 0u, // VkPipelineCacheCreateFlags flags;
1400 0u, // deUintptr initialDataSize;
1401 DE_NULL, // const void* pInitialData;
1404 GraphicsPipelineWrapper localPipeline (vk, device, m_param->getPipelineConstructionType());
1405 GraphicsPipelineWrapper localMissPipeline (vk, device, m_param->getPipelineConstructionType());
1409 case MERGE_CACHE_EMPTY:
1411 return vk::createPipelineCache(vk, device, &pipelineCacheCreateInfo);
1413 case MERGE_CACHE_FROM_DATA:
1415 // Create a cache with init data from m_cache
1416 size_t dataSize = 0u;
1417 VK_CHECK(vk.getPipelineCacheData(device, *m_cache, (deUintptr*)&dataSize, DE_NULL));
1419 std::vector<deUint8> data(dataSize);
1420 VK_CHECK(vk.getPipelineCacheData(device, *m_cache, (deUintptr*)&dataSize, &data[0]));
1422 pipelineCacheCreateInfo.initialDataSize = data.size();
1423 pipelineCacheCreateInfo.pInitialData = &data[0];
1424 return vk::createPipelineCache(vk, device, &pipelineCacheCreateInfo);
1426 case MERGE_CACHE_HIT:
1428 Move<VkPipelineCache> ret = createPipelineCache(vk, device, MERGE_CACHE_EMPTY);
1430 preparePipelineWrapper(localPipeline, *ret);
1434 case MERGE_CACHE_MISS:
1436 Move<VkPipelineCache> ret = createPipelineCache(vk, device, MERGE_CACHE_EMPTY);
1438 preparePipelineWrapper(localMissPipeline, *ret, true);
1442 case MERGE_CACHE_MISS_AND_HIT:
1444 Move<VkPipelineCache> ret = createPipelineCache(vk, device, MERGE_CACHE_EMPTY);
1446 preparePipelineWrapper(localPipeline, *ret);
1447 preparePipelineWrapper(localMissPipeline, *ret, true);
1451 case MERGE_CACHE_MERGED:
1453 Move<VkPipelineCache> cache1 = createPipelineCache(vk, device, MERGE_CACHE_FROM_DATA);
1454 Move<VkPipelineCache> cache2 = createPipelineCache(vk, device, MERGE_CACHE_HIT);
1455 Move<VkPipelineCache> cache3 = createPipelineCache(vk, device, MERGE_CACHE_MISS);
1457 const VkPipelineCache sourceCaches[] =
1464 Move<VkPipelineCache> ret = createPipelineCache(vk, device, MERGE_CACHE_EMPTY);
1467 VK_CHECK(vk.mergePipelineCaches(device, *ret, DE_LENGTH_OF_ARRAY(sourceCaches), sourceCaches));
1472 TCU_FAIL("unhandled merge cache type");
1475 void MergeCacheTestInstance::preparePipelines(void)
1477 preparePipelineWrapper(m_pipeline[PIPELINE_CACHE_NDX_NO_CACHE], *m_cache);
1479 // Create pipeline from merged cache
1480 preparePipelineWrapper(m_pipeline[PIPELINE_CACHE_NDX_CACHED], *m_cacheMerged);
1483 class CacheHeaderTest : public GraphicsCacheTest
1486 CacheHeaderTest (tcu::TestContext& testContext,
1487 const std::string& name,
1488 const std::string& description,
1489 const CacheTestParam* param)
1490 : GraphicsCacheTest(testContext, name, description, param)
1492 virtual ~CacheHeaderTest (void) { }
1493 virtual TestInstance* createInstance(Context& context) const;
1496 class CacheHeaderTestInstance : public GraphicsCacheTestInstance
1499 CacheHeaderTestInstance (Context& context, const CacheTestParam* param);
1500 virtual ~CacheHeaderTestInstance (void);
1506 deUint32 HeaderLength;
1507 deUint32 HeaderVersion;
1510 deUint8 PipelineCacheUUID[VK_UUID_SIZE];
1514 TestInstance* CacheHeaderTest::createInstance (Context& context) const
1516 return new CacheHeaderTestInstance(context, &m_param);
1519 CacheHeaderTestInstance::CacheHeaderTestInstance (Context& context, const CacheTestParam* param)
1520 : GraphicsCacheTestInstance (context, param)
1523 const DeviceInterface& vk = m_context.getDeviceInterface();
1524 const VkDevice vkDevice = m_context.getDevice();
1526 // Create more pipeline caches
1528 // Create a cache with init data from m_cache
1529 size_t dataSize = 0u;
1530 VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, DE_NULL));
1532 if (dataSize < sizeof(m_header))
1533 TCU_THROW(TestError, "Pipeline cache size is smaller than header size");
1535 m_data = new deUint8[dataSize];
1537 VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, (void*)m_data));
1539 deMemcpy(&m_header, m_data, sizeof(m_header));
1541 if (m_header.HeaderLength - VK_UUID_SIZE != 16)
1542 TCU_THROW(TestError, "Invalid header size!");
1544 if (m_header.HeaderVersion != 1)
1545 TCU_THROW(TestError, "Invalid header version!");
1547 if (m_header.VendorID != m_context.getDeviceProperties().vendorID)
1548 TCU_THROW(TestError, "Invalid header vendor ID!");
1550 if (m_header.DeviceID != m_context.getDeviceProperties().deviceID)
1551 TCU_THROW(TestError, "Invalid header device ID!");
1553 if (deMemCmp(&m_header.PipelineCacheUUID, &m_context.getDeviceProperties().pipelineCacheUUID, VK_UUID_SIZE) != 0)
1554 TCU_THROW(TestError, "Invalid header pipeline cache UUID!");
1558 CacheHeaderTestInstance::~CacheHeaderTestInstance (void)
1563 class InvalidSizeTest : public GraphicsCacheTest
1566 InvalidSizeTest (tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param);
1567 virtual ~InvalidSizeTest (void) {}
1568 virtual TestInstance* createInstance (Context& context) const;
1571 InvalidSizeTest::InvalidSizeTest (tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param)
1572 : GraphicsCacheTest(testContext, name, description, param)
1576 class InvalidSizeTestInstance : public GraphicsCacheTestInstance
1579 InvalidSizeTestInstance (Context& context, const CacheTestParam* param);
1580 virtual ~InvalidSizeTestInstance (void);
1583 deUint8* m_zeroBlock;
1586 TestInstance* InvalidSizeTest::createInstance (Context& context) const
1588 return new InvalidSizeTestInstance(context, &m_param);
1591 InvalidSizeTestInstance::InvalidSizeTestInstance (Context& context, const CacheTestParam* param)
1592 : GraphicsCacheTestInstance (context, param)
1594 , m_zeroBlock (DE_NULL)
1596 const DeviceInterface& vk = m_context.getDeviceInterface();
1597 const VkDevice vkDevice = m_context.getDevice();
1599 // Create more pipeline caches
1602 // Create a cache with init data from m_cache
1603 size_t dataSize = 0u;
1604 size_t savedDataSize = 0u;
1605 VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, DE_NULL));
1606 savedDataSize = dataSize;
1608 // If the value of dataSize is less than the maximum size that can be retrieved by the pipeline cache,
1609 // at most pDataSize bytes will be written to pData, and vkGetPipelineCacheData will return VK_INCOMPLETE.
1612 m_data = new deUint8[savedDataSize];
1613 deMemset(m_data, 0, savedDataSize);
1615 if (vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, (void*)m_data) != VK_INCOMPLETE)
1616 TCU_THROW(TestError, "GetPipelineCacheData should return VK_INCOMPLETE state!");
1621 // If the value of dataSize is less than what is necessary to store the header,
1622 // nothing will be written to pData and zero will be written to dataSize.
1623 dataSize = 16 + VK_UUID_SIZE - 1;
1625 m_data = new deUint8[savedDataSize];
1626 deMemset(m_data, 0, savedDataSize);
1628 if (vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, (void*)m_data) != VK_INCOMPLETE)
1629 TCU_THROW(TestError, "GetPipelineCacheData should return VK_INCOMPLETE state!");
1631 m_zeroBlock = new deUint8[savedDataSize];
1632 deMemset(m_zeroBlock, 0, savedDataSize);
1633 if (deMemCmp(m_data, m_zeroBlock, savedDataSize) != 0 || dataSize != 0)
1634 TCU_THROW(TestError, "Data needs to be empty and data size should be 0 when invalid size is passed to GetPipelineCacheData!");
1639 delete[] m_zeroBlock;
1644 InvalidSizeTestInstance::~InvalidSizeTestInstance (void)
1647 delete[] m_zeroBlock;
1650 class ZeroSizeTest : public GraphicsCacheTest
1653 ZeroSizeTest (tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param);
1654 virtual ~ZeroSizeTest (void) {}
1655 virtual TestInstance* createInstance (Context& context) const;
1658 ZeroSizeTest::ZeroSizeTest (tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param)
1659 : GraphicsCacheTest(testContext, name, description, param)
1663 class ZeroSizeTestInstance : public GraphicsCacheTestInstance
1666 ZeroSizeTestInstance (Context& context, const CacheTestParam* param);
1667 virtual ~ZeroSizeTestInstance (void);
1670 deUint8* m_zeroBlock;
1673 TestInstance* ZeroSizeTest::createInstance (Context& context) const
1675 return new ZeroSizeTestInstance(context, &m_param);
1678 ZeroSizeTestInstance::ZeroSizeTestInstance (Context& context, const CacheTestParam* param)
1679 : GraphicsCacheTestInstance (context, param)
1681 , m_zeroBlock (DE_NULL)
1683 const DeviceInterface& vk = m_context.getDeviceInterface();
1684 const VkDevice vkDevice = m_context.getDevice();
1686 // Create more pipeline caches
1689 // Create a cache with init data from m_cache
1690 size_t dataSize = 0u;
1692 VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, DE_NULL));
1694 m_data = new deUint8[dataSize];
1695 deMemset(m_data, 0, dataSize);
1698 VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, (void*)m_data));
1701 // Create a cache with initialDataSize = 0 & pInitialData != NULL
1702 const VkPipelineCacheCreateInfo pipelineCacheCreateInfo =
1704 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
1705 DE_NULL, // const void* pNext;
1706 0u, // VkPipelineCacheCreateFlags flags;
1707 0u, // deUintptr initialDataSize;
1708 m_data, // const void* pInitialData;
1711 const Unique<VkPipelineCache> pipelineCache (createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo));
1717 delete[] m_zeroBlock;
1722 ZeroSizeTestInstance::~ZeroSizeTestInstance (void)
1725 delete[] m_zeroBlock;
1728 class InvalidBlobTest : public GraphicsCacheTest
1731 InvalidBlobTest (tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param);
1732 virtual ~InvalidBlobTest (void) {}
1733 virtual TestInstance* createInstance (Context& context) const;
1736 InvalidBlobTest::InvalidBlobTest (tcu::TestContext& testContext, const std::string& name, const std::string& description, const CacheTestParam* param)
1737 : GraphicsCacheTest(testContext, name, description, param)
1741 class InvalidBlobTestInstance : public GraphicsCacheTestInstance
1744 InvalidBlobTestInstance (Context& context, const CacheTestParam* param);
1745 virtual ~InvalidBlobTestInstance (void);
1748 deUint8* m_zeroBlock;
1751 TestInstance* InvalidBlobTest::createInstance (Context& context) const
1753 return new InvalidBlobTestInstance(context, &m_param);
1756 InvalidBlobTestInstance::InvalidBlobTestInstance (Context& context, const CacheTestParam* param)
1757 : GraphicsCacheTestInstance (context, param)
1759 , m_zeroBlock (DE_NULL)
1761 const DeviceInterface& vk = m_context.getDeviceInterface();
1762 const VkDevice vkDevice = m_context.getDevice();
1764 // Create more pipeline caches
1767 // Create a cache with init data from m_cache
1768 size_t dataSize = 0u;
1770 VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, DE_NULL));
1772 m_data = new deUint8[dataSize];
1773 deMemset(m_data, 0, dataSize);
1776 VK_CHECK(vk.getPipelineCacheData(vkDevice, *m_cache, (deUintptr*)&dataSize, (void*)m_data));
1784 { 4u, "pipeline cache header version" },
1785 { 8u, "vendor ID" },
1786 { 12u, "device ID" },
1787 { 16u, "pipeline cache ID" }
1790 for (deUint32 i = 0u; i < DE_LENGTH_OF_ARRAY(headerLayout); i++)
1792 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Creating pipeline cache using previously retrieved data with invalid " << headerLayout[i].name << tcu::TestLog::EndMessage;
1794 m_data[headerLayout[i].offset] = (deUint8)(m_data[headerLayout[i].offset] + 13u); // Add arbitrary number to create an invalid value
1796 const VkPipelineCacheCreateInfo pipelineCacheCreateInfo =
1798 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
1799 DE_NULL, // const void* pNext;
1800 0u, // VkPipelineCacheCreateFlags flags;
1801 dataSize, // deUintptr initialDataSize;
1802 m_data, // const void* pInitialData;
1805 const Unique<VkPipelineCache> pipelineCache (createPipelineCache(vk, vkDevice, &pipelineCacheCreateInfo));
1807 m_data[headerLayout[i].offset] = (deUint8)(m_data[headerLayout[i].offset] - 13u); // Return to original value
1813 delete[] m_zeroBlock;
1818 InvalidBlobTestInstance::~InvalidBlobTestInstance (void)
1821 delete[] m_zeroBlock;
1825 tcu::TestCaseGroup* createCacheTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType)
1827 de::MovePtr<tcu::TestCaseGroup> cacheTests (new tcu::TestCaseGroup(testCtx, "cache", "pipeline cache tests"));
1829 const VkShaderStageFlags vertFragStages = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
1830 const VkShaderStageFlags vertGeomFragStages = vertFragStages | VK_SHADER_STAGE_GEOMETRY_BIT;
1831 const VkShaderStageFlags vertTesFragStages = vertFragStages | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
1833 // Graphics Pipeline Tests
1835 de::MovePtr<tcu::TestCaseGroup> graphicsTests (new tcu::TestCaseGroup(testCtx, "graphics_tests", "Test pipeline cache with graphics pipeline."));
1837 const CacheTestParam testParams[] =
1839 CacheTestParam(pipelineConstructionType, vertFragStages, false),
1840 CacheTestParam(pipelineConstructionType, vertGeomFragStages, false),
1841 CacheTestParam(pipelineConstructionType, vertTesFragStages, false),
1842 CacheTestParam(pipelineConstructionType, vertFragStages, false, VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT),
1843 CacheTestParam(pipelineConstructionType, vertGeomFragStages, false, VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT),
1844 CacheTestParam(pipelineConstructionType, vertTesFragStages, false, VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT),
1847 for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
1848 graphicsTests->addChild(newTestCase<GraphicsCacheTest>(testCtx, &testParams[i]));
1850 cacheTests->addChild(graphicsTests.release());
1853 // Graphics Pipeline Tests
1855 de::MovePtr<tcu::TestCaseGroup> graphicsTests(new tcu::TestCaseGroup(testCtx, "pipeline_from_get_data", "Test pipeline cache with graphics pipeline."));
1857 const CacheTestParam testParams[] =
1859 CacheTestParam(pipelineConstructionType, vertFragStages, false),
1860 CacheTestParam(pipelineConstructionType, vertGeomFragStages, false),
1861 CacheTestParam(pipelineConstructionType, vertTesFragStages, false),
1864 for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
1865 graphicsTests->addChild(newTestCase<PipelineFromCacheTest>(testCtx, &testParams[i]));
1867 cacheTests->addChild(graphicsTests.release());
1870 // Graphics Pipeline Tests
1872 de::MovePtr<tcu::TestCaseGroup> graphicsTests(new tcu::TestCaseGroup(testCtx, "pipeline_from_incomplete_get_data", "Test pipeline cache with graphics pipeline."));
1874 const CacheTestParam testParams[] =
1876 CacheTestParam(pipelineConstructionType, vertFragStages, false),
1877 CacheTestParam(pipelineConstructionType, vertGeomFragStages, false),
1878 CacheTestParam(pipelineConstructionType, vertTesFragStages, false),
1881 for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
1882 graphicsTests->addChild(newTestCase<PipelineFromIncompleteCacheTest>(testCtx, &testParams[i]));
1884 cacheTests->addChild(graphicsTests.release());
1887 // Compute Pipeline Tests - don't repeat those tests for graphics pipeline library
1888 if (pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1890 de::MovePtr<tcu::TestCaseGroup> computeTests (new tcu::TestCaseGroup(testCtx, "compute_tests", "Test pipeline cache with compute pipeline."));
1892 const CacheTestParam testParams[] =
1894 CacheTestParam(pipelineConstructionType, VK_SHADER_STAGE_COMPUTE_BIT, false),
1897 for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
1898 computeTests->addChild(newTestCase<ComputeCacheTest>(testCtx, &testParams[i]));
1900 cacheTests->addChild(computeTests.release());
1903 // Merge cache Tests
1905 de::MovePtr<tcu::TestCaseGroup> mergeTests (new tcu::TestCaseGroup(testCtx, "merge", "Cache merging tests"));
1907 const CacheTestParam testParams[] =
1909 CacheTestParam(pipelineConstructionType, vertFragStages, true),
1910 CacheTestParam(pipelineConstructionType, vertGeomFragStages, true),
1911 CacheTestParam(pipelineConstructionType, vertTesFragStages, true),
1914 for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(testParams); i++)
1917 de::MovePtr<tcu::TestCaseGroup> mergeStagesTests(new tcu::TestCaseGroup(testCtx, testParams[i].generateTestName().c_str(), testParams[i].generateTestDescription().c_str()));
1919 for (deUint32 destTypeIdx = 0u; destTypeIdx <= MERGE_CACHE_TYPE_LAST; destTypeIdx++)
1920 for (deUint32 srcType1Idx = 0u; srcType1Idx <= MERGE_CACHE_TYPE_LAST; srcType1Idx++)
1923 MergeCacheTestParam cacheTestParam;
1924 cacheTestParam.destCacheType = MergeCacheType(destTypeIdx);
1925 cacheTestParam.srcCacheTypes.push_back(MergeCacheType(srcType1Idx));
1927 // merge with one cache
1929 std::string testName = "src_" + getMergeCacheTypesStr(cacheTestParam.srcCacheTypes) + "_dst_" + getMergeCacheTypeStr(cacheTestParam.destCacheType);
1930 mergeStagesTests->addChild(new MergeCacheTest(testCtx,
1932 "Merge the caches test.",
1937 // merge with two caches
1938 for (deUint32 srcType2Idx = 0u; srcType2Idx <= MERGE_CACHE_TYPE_LAST; srcType2Idx++)
1940 MergeCacheTestParam cacheTestParamTwoCaches = cacheTestParam;
1942 cacheTestParamTwoCaches.srcCacheTypes.push_back(MergeCacheType(srcType2Idx));
1944 std::string testName = "src_" + getMergeCacheTypesStr(cacheTestParamTwoCaches.srcCacheTypes) + "_dst_" + getMergeCacheTypeStr(cacheTestParamTwoCaches.destCacheType);
1945 mergeStagesTests->addChild(new MergeCacheTest(testCtx,
1947 "Merge the caches test.",
1949 &cacheTestParamTwoCaches));
1952 mergeTests->addChild(mergeStagesTests.release());
1954 cacheTests->addChild(mergeTests.release());
1959 de::MovePtr<tcu::TestCaseGroup> miscTests(new tcu::TestCaseGroup(testCtx, "misc_tests", "Misc tests that can not be categorized to other group."));
1961 const CacheTestParam testParam(pipelineConstructionType, vertFragStages, false);
1963 miscTests->addChild(new CacheHeaderTest(testCtx,
1964 "cache_header_test",
1965 "Cache header test.",
1968 miscTests->addChild(new InvalidSizeTest(testCtx,
1969 "invalid_size_test",
1970 "Invalid size test.",
1973 miscTests->addChild(new ZeroSizeTest(testCtx,
1978 miscTests->addChild(new InvalidBlobTest(testCtx,
1979 "invalid_blob_test",
1980 "Invalid cache blob test.",
1983 cacheTests->addChild(miscTests.release());
1986 return cacheTests.release();