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