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