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