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