1/*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2021 The Khronos Group Inc. 6 * Copyright (c) 2023 LunarG, Inc. 7 * Copyright (c) 2023 Nintendo 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 *//*! 22 * \file 23 * \brief Tests Verifying Graphics Pipeline Libraries 24 *//*--------------------------------------------------------------------*/ 25 26#include "vktPipelineLibraryTests.hpp" 27 28#include "vkDefs.hpp" 29#include "vkCmdUtil.hpp" 30#include "vkObjUtil.hpp" 31#include "vkTypeUtil.hpp" 32#include "vkQueryUtil.hpp" 33#include "vkImageUtil.hpp" 34#include "vkBarrierUtil.hpp" 35#include "vkBufferWithMemory.hpp" 36#include "vkImageWithMemory.hpp" 37#include "vkBuilderUtil.hpp" 38#include "vkRayTracingUtil.hpp" 39#include "vktTestCase.hpp" 40#include "vktTestGroupUtil.hpp" 41#include "tcuCommandLine.hpp" 42#include "tcuImageCompare.hpp" 43#include "tcuTestLog.hpp" 44#include "tcuRGBA.hpp" 45 46#include "../draw/vktDrawCreateInfoUtil.hpp" 47#include "deMath.h" 48#include "deRandom.hpp" 49#include "deClock.h" 50 51#include <vector> 52#include <chrono> 53#include <set> 54#include <limits> 55 56namespace vkt 57{ 58namespace pipeline 59{ 60namespace 61{ 62using namespace vk; 63using namespace vkt; 64using namespace tcu; 65 66 67static const deUint32 RENDER_SIZE_WIDTH = 16u; 68static const deUint32 RENDER_SIZE_HEIGHT = 16u; 69static const VkColorComponentFlags COLOR_COMPONENTS_NO_RED = VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; 70static const VkGraphicsPipelineLibraryFlagBitsEXT GRAPHICS_PIPELINE_LIBRARY_FLAGS[] = 71{ 72 VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT, 73 VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT, 74 VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT, 75 VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT, 76}; 77static const VkGraphicsPipelineLibraryFlagsEXT ALL_GRAPHICS_PIPELINE_LIBRARY_FLAGS = static_cast<VkGraphicsPipelineLibraryFlagsEXT>(VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT) 78 | static_cast<VkGraphicsPipelineLibraryFlagsEXT>(VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT) 79 | static_cast<VkGraphicsPipelineLibraryFlagsEXT>(VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT) 80 | static_cast<VkGraphicsPipelineLibraryFlagsEXT>(VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT); 81 82struct PipelineTreeNode 83{ 84 deInt32 parentIndex; 85 deUint32 shaderCount; 86}; 87 88typedef std::vector<PipelineTreeNode> PipelineTreeConfiguration; 89 90struct TestParams 91{ 92 PipelineTreeConfiguration pipelineTreeConfiguration; 93 bool optimize; 94 bool delayedShaderCreate; 95 bool useMaintenance5; 96}; 97 98struct RuntimePipelineTreeNode 99{ 100 deInt32 parentIndex; 101 VkGraphicsPipelineLibraryFlagsEXT graphicsPipelineLibraryFlags; 102 VkGraphicsPipelineLibraryFlagsEXT subtreeGraphicsPipelineLibraryFlags; 103 Move<VkPipeline> pipeline; 104 std::vector<VkPipeline> pipelineLibraries; 105 // We need to track the linked libraries too, included in VkPipelineLibraryCreateInfoKHR->pLibraries 106 std::vector<VkGraphicsPipelineLibraryFlagsEXT> linkedLibraryFlags; 107}; 108 109typedef std::vector<RuntimePipelineTreeNode> RuntimePipelineTreeConfiguration; 110 111inline UVec4 ivec2uvec (const IVec4& ivec) 112{ 113 return UVec4 114 { 115 static_cast<deUint32>(ivec[0]), 116 static_cast<deUint32>(ivec[1]), 117 static_cast<deUint32>(ivec[2]), 118 static_cast<deUint32>(ivec[3]), 119 }; 120} 121 122inline std::string getTestName (const PipelineTreeConfiguration& pipelineTreeConfiguration) 123{ 124 std::string result; 125 int level = pipelineTreeConfiguration[0].parentIndex; 126 127 for (const auto& node: pipelineTreeConfiguration) 128 { 129 if (level != node.parentIndex) 130 { 131 DE_ASSERT(level < node.parentIndex); 132 133 result += '_'; 134 135 level = node.parentIndex; 136 } 137 138 result += de::toString(node.shaderCount); 139 } 140 141 return result; 142} 143 144inline VkPipelineCreateFlags calcPipelineCreateFlags (bool optimize, bool buildLibrary) 145{ 146 VkPipelineCreateFlags result = 0; 147 148 if (buildLibrary) 149 result |= static_cast<VkPipelineCreateFlags>(VK_PIPELINE_CREATE_LIBRARY_BIT_KHR); 150 151 if (optimize) 152 { 153 if (buildLibrary) 154 result |= static_cast<VkPipelineCreateFlags>(VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT); 155 else 156 result |= static_cast<VkPipelineCreateFlags>(VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT); 157 } 158 159 return result; 160} 161 162inline VkRenderPass getRenderPass (VkGraphicsPipelineLibraryFlagsEXT subset, VkRenderPass renderPass) 163{ 164 static const VkGraphicsPipelineLibraryFlagsEXT subsetRequiresRenderPass = static_cast<VkGraphicsPipelineLibraryFlagsEXT>(VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT) 165 | static_cast<VkGraphicsPipelineLibraryFlagsEXT>(VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT) 166 | static_cast<VkGraphicsPipelineLibraryFlagsEXT>(VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT); 167 if ((subsetRequiresRenderPass & subset) != 0) 168 return renderPass; 169 170 return DE_NULL; 171} 172 173inline VkGraphicsPipelineLibraryCreateInfoEXT makeGraphicsPipelineLibraryCreateInfo (const VkGraphicsPipelineLibraryFlagsEXT flags) 174{ 175 const VkGraphicsPipelineLibraryCreateInfoEXT graphicsPipelineLibraryCreateInfo = 176 { 177 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT, // VkStructureType sType; 178 DE_NULL, // void* pNext; 179 flags, // VkGraphicsPipelineLibraryFlagsEXT flags; 180 }; 181 182 return graphicsPipelineLibraryCreateInfo; 183} 184 185inline VkPipelineLibraryCreateInfoKHR makePipelineLibraryCreateInfo (const std::vector<VkPipeline>& pipelineLibraries) 186{ 187 const deUint32 libraryCount = static_cast<deUint32>(pipelineLibraries.size()); 188 const VkPipeline* libraries = de::dataOrNull(pipelineLibraries); 189 const VkPipelineLibraryCreateInfoKHR pipelineLibraryCreateInfo = 190 { 191 VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR, // VkStructureType sType; 192 DE_NULL, // const void* pNext; 193 libraryCount, // deUint32 libraryCount; 194 libraries, // const VkPipeline* pLibraries; 195 }; 196 197 return pipelineLibraryCreateInfo; 198} 199 200inline std::string getGraphicsPipelineLibraryFlagsString (const VkGraphicsPipelineLibraryFlagsEXT flags) 201{ 202 std::string result; 203 204 if ((flags & VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT) != 0) result += "VERTEX_INPUT_INTERFACE "; 205 if ((flags & VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT) != 0) result += "PRE_RASTERIZATION_SHADERS "; 206 if ((flags & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT) != 0) result += "FRAGMENT_SHADER "; 207 if ((flags & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT) != 0) result += "FRAGMENT_OUTPUT_INTERFACE "; 208 209 if (!result.empty()) 210 result.resize(result.size() - 1); 211 212 return result; 213}; 214 215VkImageCreateInfo makeColorImageCreateInfo (const VkFormat format, const deUint32 width, const deUint32 height) 216{ 217 const VkImageUsageFlags usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 218 const VkImageCreateInfo imageInfo = 219 { 220 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 221 DE_NULL, // const void* pNext; 222 (VkImageCreateFlags)0, // VkImageCreateFlags flags; 223 VK_IMAGE_TYPE_2D, // VkImageType imageType; 224 format, // VkFormat format; 225 makeExtent3D(width, height, 1), // VkExtent3D extent; 226 1u, // deUint32 mipLevels; 227 1u, // deUint32 arrayLayers; 228 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 229 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 230 usage, // VkImageUsageFlags usage; 231 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 232 0u, // deUint32 queueFamilyIndexCount; 233 DE_NULL, // const deUint32* pQueueFamilyIndices; 234 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 235 }; 236 237 return imageInfo; 238} 239 240VkImageViewCreateInfo makeImageViewCreateInfo (VkImage image, VkFormat format, VkImageAspectFlags aspectMask) 241{ 242 const VkComponentMapping components = 243 { 244 VK_COMPONENT_SWIZZLE_R, 245 VK_COMPONENT_SWIZZLE_G, 246 VK_COMPONENT_SWIZZLE_B, 247 VK_COMPONENT_SWIZZLE_A, 248 }; 249 const VkImageSubresourceRange subresourceRange = 250 { 251 aspectMask, // VkImageAspectFlags aspectMask; 252 0, // deUint32 baseMipLevel; 253 1, // deUint32 levelCount; 254 0, // deUint32 baseArrayLayer; 255 1, // deUint32 layerCount; 256 }; 257 const VkImageViewCreateInfo result = 258 { 259 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 260 DE_NULL, // const void* pNext; 261 0u, // VkImageViewCreateFlags flags; 262 image, // VkImage image; 263 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 264 format, // VkFormat format; 265 components, // VkComponentMapping components; 266 subresourceRange, // VkImageSubresourceRange subresourceRange; 267 }; 268 269 return result; 270} 271 272VkImageCreateInfo makeDepthImageCreateInfo (const VkFormat format, const deUint32 width, const deUint32 height) 273{ 274 const VkImageUsageFlags usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 275 const VkImageCreateInfo imageInfo = 276 { 277 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 278 DE_NULL, // const void* pNext; 279 (VkImageCreateFlags)0, // VkImageCreateFlags flags; 280 VK_IMAGE_TYPE_2D, // VkImageType imageType; 281 format, // VkFormat format; 282 makeExtent3D(width, height, 1), // VkExtent3D extent; 283 1u, // deUint32 mipLevels; 284 1u, // deUint32 arrayLayers; 285 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 286 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 287 usage, // VkImageUsageFlags usage; 288 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 289 0u, // deUint32 queueFamilyIndexCount; 290 DE_NULL, // const deUint32* pQueueFamilyIndices; 291 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 292 }; 293 294 return imageInfo; 295} 296 297const VkFramebufferCreateInfo makeFramebufferCreateInfo (const VkRenderPass renderPass, 298 const deUint32 attachmentCount, 299 const VkImageView* attachments, 300 const deUint32 width, 301 const deUint32 height) 302{ 303 const VkFramebufferCreateInfo result = 304 { 305 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 306 DE_NULL, // const void* pNext; 307 0, // VkFramebufferCreateFlags flags; 308 renderPass, // VkRenderPass renderPass; 309 attachmentCount, // deUint32 attachmentCount; 310 attachments, // const VkImageView* pAttachments; 311 width, // deUint32 width; 312 height, // deUint32 height; 313 1, // deUint32 layers; 314 }; 315 316 return result; 317} 318 319const VkPipelineMultisampleStateCreateInfo makePipelineMultisampleStateCreateInfo (void) 320{ 321 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateCreateInfo = 322 { 323 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 324 DE_NULL, // const void* pNext; 325 0u, // VkPipelineMultisampleStateCreateFlags flags; 326 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples; 327 DE_FALSE, // VkBool32 sampleShadingEnable; 328 0.0f, // float minSampleShading; 329 DE_NULL, // const VkSampleMask* pSampleMask; 330 DE_FALSE, // VkBool32 alphaToCoverageEnable; 331 DE_FALSE, // VkBool32 alphaToOneEnable; 332 }; 333 334 return pipelineMultisampleStateCreateInfo; 335} 336 337class GraphicsPipelineCreateInfo : public ::vkt::Draw::PipelineCreateInfo 338{ 339public: 340 GraphicsPipelineCreateInfo (vk::VkPipelineLayout _layout, 341 vk::VkRenderPass _renderPass, 342 int _subpass, 343 vk::VkPipelineCreateFlags _flags) 344 : ::vkt::Draw::PipelineCreateInfo (_layout, _renderPass, _subpass, _flags) 345 , m_vertexInputBindingDescription () 346 , m_vertexInputAttributeDescription () 347 , m_shaderModuleCreateInfoCount (0) 348 , m_shaderModuleCreateInfo { initVulkanStructure(), initVulkanStructure() } 349 , m_pipelineShaderStageCreateInfo () 350 , m_vertModule () 351 , m_fragModule () 352 { 353 } 354 355 VkVertexInputBindingDescription m_vertexInputBindingDescription; 356 VkVertexInputAttributeDescription m_vertexInputAttributeDescription; 357 deUint32 m_shaderModuleCreateInfoCount; 358 VkShaderModuleCreateInfo m_shaderModuleCreateInfo[2]; 359 std::vector<VkPipelineShaderStageCreateInfo> m_pipelineShaderStageCreateInfo; 360 Move<VkShaderModule> m_vertModule; 361 Move<VkShaderModule> m_fragModule; 362}; 363 364void updateVertexInputInterface (Context& context, 365 GraphicsPipelineCreateInfo& graphicsPipelineCreateInfo, 366 VkPrimitiveTopology topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 367 deUint32 vertexDescriptionCount = 1u) 368{ 369 DE_UNREF(context); 370 371 graphicsPipelineCreateInfo.m_vertexInputBindingDescription = 372 { 373 0u, // deUint32 binding; 374 sizeof(tcu::Vec4), // deUint32 strideInBytes; 375 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate; 376 }; 377 graphicsPipelineCreateInfo.m_vertexInputAttributeDescription = 378 { 379 0u, // deUint32 location; 380 0u, // deUint32 binding; 381 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 382 0u // deUint32 offsetInBytes; 383 }; 384 385 const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo 386 { 387 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 388 DE_NULL, // const void* pNext; 389 0u, // VkPipelineVertexInputStateCreateFlags flags; 390 vertexDescriptionCount, // deUint32 vertexBindingDescriptionCount; 391 &graphicsPipelineCreateInfo.m_vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 392 vertexDescriptionCount, // deUint32 vertexAttributeDescriptionCount; 393 &graphicsPipelineCreateInfo.m_vertexInputAttributeDescription, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 394 }; 395 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo 396 { 397 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 398 DE_NULL, // const void* pNext; 399 0u, // VkPipelineInputAssemblyStateCreateFlags flags; 400 topology, // VkPrimitiveTopology topology; 401 VK_FALSE, // VkBool32 primitiveRestartEnable; 402 }; 403 404 graphicsPipelineCreateInfo.addState(vertexInputStateCreateInfo); 405 graphicsPipelineCreateInfo.addState(inputAssemblyStateCreateInfo); 406} 407 408void updatePreRasterization (Context& context, 409 GraphicsPipelineCreateInfo& graphicsPipelineCreateInfo, 410 bool delayedShaderCreate, 411 VkPolygonMode polygonMode = VK_POLYGON_MODE_FILL, 412 const VkSpecializationInfo* specializationInfo = DE_NULL) 413{ 414 const ProgramBinary& shaderBinary = context.getBinaryCollection().get("vert"); 415 VkShaderModuleCreateInfo& shaderModuleCreateInfo = graphicsPipelineCreateInfo.m_shaderModuleCreateInfo[graphicsPipelineCreateInfo.m_shaderModuleCreateInfoCount]; 416 417 DE_ASSERT(graphicsPipelineCreateInfo.m_shaderModuleCreateInfoCount < DE_LENGTH_OF_ARRAY(graphicsPipelineCreateInfo.m_shaderModuleCreateInfo)); 418 419 shaderModuleCreateInfo = 420 { 421 VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, // VkStructureType sType; 422 DE_NULL, // const void* pNext; 423 0u, // VkShaderModuleCreateFlags flags; 424 (deUintptr)shaderBinary.getSize(), // deUintptr codeSize; 425 (deUint32*)shaderBinary.getBinary(), // const deUint32* pCode; 426 }; 427 428 if (!delayedShaderCreate) 429 { 430 const DeviceInterface& vk = context.getDeviceInterface(); 431 const VkDevice device = context.getDevice(); 432 433 graphicsPipelineCreateInfo.m_vertModule = createShaderModule(vk, device, &shaderModuleCreateInfo); 434 } 435 436 const void* pNext = delayedShaderCreate 437 ? &shaderModuleCreateInfo 438 : DE_NULL; 439 const VkShaderModule shaderModule = delayedShaderCreate 440 ? DE_NULL 441 : *graphicsPipelineCreateInfo.m_vertModule; 442 const VkPipelineShaderStageCreateInfo pipelineShaderStageCreateInfo = 443 { 444 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 445 pNext, // const void* pNext; 446 0u, // VkPipelineShaderStageCreateFlags flags; 447 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage; 448 shaderModule, // VkShaderModule module; 449 "main", // const char* pName; 450 specializationInfo // const VkSpecializationInfo* pSpecializationInfo; 451 }; 452 453 shaderBinary.setUsed(); 454 455 // Within the VkPipelineLayout, all bindings that affect the specified shader stages 456 const VkViewport viewport = makeViewport(RENDER_SIZE_WIDTH, RENDER_SIZE_HEIGHT); 457 const VkRect2D scissor = makeRect2D(3 * RENDER_SIZE_WIDTH / 4, RENDER_SIZE_HEIGHT); 458 const VkPipelineViewportStateCreateInfo pipelineViewportStateCreateInfo = 459 { 460 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 461 DE_NULL, // const void* pNext; 462 0u, // VkPipelineViewportStateCreateFlags flags; 463 1u, // deUint32 viewportCount; 464 &viewport, // const VkViewport* pViewports; 465 1u, // deUint32 scissorCount; 466 &scissor // const VkRect2D* pScissors; 467 }; 468 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateCreateInfo = 469 { 470 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 471 DE_NULL, // const void* pNext; 472 0u, // VkPipelineRasterizationStateCreateFlags flags; 473 VK_FALSE, // VkBool32 depthClampEnable; 474 VK_FALSE, // VkBool32 rasterizerDiscardEnable; 475 polygonMode, // VkPolygonMode polygonMode; 476 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; 477 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 478 VK_FALSE, // VkBool32 depthBiasEnable; 479 0.0f, // float depthBiasConstantFactor; 480 0.0f, // float depthBiasClamp; 481 0.0f, // float depthBiasSlopeFactor; 482 1.0f, // float lineWidth; 483 }; 484 485 graphicsPipelineCreateInfo.m_shaderModuleCreateInfoCount++; 486 487 graphicsPipelineCreateInfo.addShader(pipelineShaderStageCreateInfo); 488 graphicsPipelineCreateInfo.addState(pipelineViewportStateCreateInfo); 489 graphicsPipelineCreateInfo.addState(pipelineRasterizationStateCreateInfo); 490} 491 492void updatePostRasterization (Context& context, 493 GraphicsPipelineCreateInfo& graphicsPipelineCreateInfo, 494 bool delayedShaderCreate, 495 bool enableDepth = true, 496 const VkSpecializationInfo* specializationInfo = DE_NULL) 497{ 498 const ProgramBinary& shaderBinary = context.getBinaryCollection().get("frag"); 499 VkShaderModuleCreateInfo& shaderModuleCreateInfo = graphicsPipelineCreateInfo.m_shaderModuleCreateInfo[graphicsPipelineCreateInfo.m_shaderModuleCreateInfoCount]; 500 501 DE_ASSERT(graphicsPipelineCreateInfo.m_shaderModuleCreateInfoCount < DE_LENGTH_OF_ARRAY(graphicsPipelineCreateInfo.m_shaderModuleCreateInfo)); 502 503 shaderModuleCreateInfo = 504 { 505 VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, // VkStructureType sType; 506 DE_NULL, // const void* pNext; 507 0u, // VkShaderModuleCreateFlags flags; 508 (deUintptr)shaderBinary.getSize(), // deUintptr codeSize; 509 (deUint32*)shaderBinary.getBinary(), // const deUint32* pCode; 510 }; 511 512 if (!delayedShaderCreate) 513 { 514 const DeviceInterface& vk = context.getDeviceInterface(); 515 const VkDevice device = context.getDevice(); 516 517 graphicsPipelineCreateInfo.m_fragModule = createShaderModule(vk, device, &shaderModuleCreateInfo); 518 } 519 520 const void* pNext = delayedShaderCreate 521 ? &shaderModuleCreateInfo 522 : DE_NULL; 523 const VkShaderModule shaderModule = delayedShaderCreate 524 ? DE_NULL 525 : *graphicsPipelineCreateInfo.m_fragModule; 526 const VkPipelineShaderStageCreateInfo pipelineShaderStageCreateInfo = 527 { 528 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 529 pNext, // const void* pNext; 530 0u, // VkPipelineShaderStageCreateFlags flags; 531 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage; 532 shaderModule, // VkShaderModule module; 533 "main", // const char* pName; 534 specializationInfo // const VkSpecializationInfo* pSpecializationInfo; 535 }; 536 537 shaderBinary.setUsed(); 538 539 // Within the VkPipelineLayout, all bindings that affect the fragment shader stage 540 541 const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateCreateInfo = 542 { 543 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; 544 DE_NULL, // const void* pNext; 545 0u, // VkPipelineDepthStencilStateCreateFlags flags; 546 enableDepth, // VkBool32 depthTestEnable; 547 enableDepth, // VkBool32 depthWriteEnable; 548 VK_COMPARE_OP_LESS_OR_EQUAL, // VkCompareOp depthCompareOp; 549 VK_FALSE, // VkBool32 depthBoundsTestEnable; 550 VK_FALSE, // VkBool32 stencilTestEnable; 551 { // VkStencilOpState front; 552 VK_STENCIL_OP_KEEP, // VkStencilOp failOp; 553 VK_STENCIL_OP_KEEP, // VkStencilOp passOp; 554 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp; 555 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp; 556 0u, // deUint32 compareMask; 557 0u, // deUint32 writeMask; 558 0u, // deUint32 reference; 559 }, 560 { // VkStencilOpState back; 561 VK_STENCIL_OP_KEEP, // VkStencilOp failOp; 562 VK_STENCIL_OP_KEEP, // VkStencilOp passOp; 563 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp; 564 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp; 565 0u, // deUint32 compareMask; 566 0u, // deUint32 writeMask; 567 0u, // deUint32 reference; 568 }, 569 0.0f, // float minDepthBounds; 570 1.0f, // float maxDepthBounds; 571 }; 572 573 graphicsPipelineCreateInfo.m_shaderModuleCreateInfoCount++; 574 graphicsPipelineCreateInfo.addShader(pipelineShaderStageCreateInfo); 575 576 DE_ASSERT(graphicsPipelineCreateInfo.pDepthStencilState == DE_NULL); 577 graphicsPipelineCreateInfo.addState(pipelineDepthStencilStateCreateInfo); 578 579 if (graphicsPipelineCreateInfo.pMultisampleState == DE_NULL) 580 { 581 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateCreateInfo = makePipelineMultisampleStateCreateInfo(); 582 583 graphicsPipelineCreateInfo.addState(pipelineMultisampleStateCreateInfo); 584 } 585} 586 587void updateFragmentOutputInterface (Context& context, 588 GraphicsPipelineCreateInfo& graphicsPipelineCreateInfo, 589 VkColorComponentFlags colorWriteMask = COLOR_COMPONENTS_NO_RED) 590{ 591 DE_UNREF(context); 592 593 // Number of blend attachments must equal the number of color attachments during any subpass. 594 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState = 595 { 596 VK_FALSE, // VkBool32 blendEnable; 597 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor; 598 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor; 599 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 600 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor; 601 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor; 602 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 603 colorWriteMask, // VkColorComponentFlags colorWriteMask; 604 }; 605 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateCreateInfo = 606 { 607 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 608 DE_NULL, // const void* pNext; 609 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags; 610 VK_FALSE, // VkBool32 logicOpEnable; 611 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 612 1u, // deUint32 attachmentCount; 613 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 614 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4]; 615 }; 616 617 graphicsPipelineCreateInfo.addState(pipelineColorBlendStateCreateInfo); 618 619 if (graphicsPipelineCreateInfo.pMultisampleState == DE_NULL) 620 { 621 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateCreateInfo = makePipelineMultisampleStateCreateInfo(); 622 623 graphicsPipelineCreateInfo.addState(pipelineMultisampleStateCreateInfo); 624 } 625} 626 627/* 628 To test that each of graphics pipeline libraries have influence on final pipeline 629 the functions have following features: 630 631 updateVertexInputInterface 632 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST 633 VK_VERTEX_INPUT_RATE_VERTEX 634 Z is read from uniform and written in shader 635 636 updatePreRasterization 637 VkRect2D scissor = makeRect2D(3 * RENDER_SIZE_WIDTH / 4, RENDER_SIZE_HEIGHT); 638 639 updatePostRasterization 640 Fragment shader top and bottom colors read from uniform buffer 641 642 updateFragmentOutputInterface 643 Cut off red component 644*/ 645 646class PipelineLibraryTestInstance : public TestInstance 647{ 648public: 649 PipelineLibraryTestInstance (Context& context, 650 const TestParams& data); 651 ~PipelineLibraryTestInstance (void); 652 tcu::TestStatus iterate (void); 653 654protected: 655 de::MovePtr<BufferWithMemory> makeVertexBuffer (void); 656 de::MovePtr<BufferWithMemory> makeZCoordBuffer (void); 657 de::MovePtr<BufferWithMemory> makePaletteBuffer (void); 658 Move<VkDescriptorPool> createDescriptorPool (void); 659 Move<VkDescriptorSetLayout> createDescriptorSetLayout (const VkBuffer vertShaderBuffer, 660 const VkBuffer fragShaderBuffer); 661 Move<VkDescriptorSet> createDescriptorSet (const VkDescriptorPool pool, 662 const VkDescriptorSetLayout layout, 663 const VkBuffer vertShaderBuffer, 664 const VkBuffer fragShaderBuffer); 665 bool verifyColorImage (const tcu::ConstPixelBufferAccess& pba); 666 bool verifyDepthImage (const tcu::ConstPixelBufferAccess& pba); 667 bool runTest (RuntimePipelineTreeConfiguration& runtimePipelineTreeConfiguration, 668 const bool optimize, 669 const bool delayedShaderCreate); 670private: 671 TestParams m_data; 672 std::vector<tcu::Vec4> m_vertexData; 673 std::vector<tcu::Vec4> m_paletteData; 674 std::vector<tcu::Vec4> m_zCoordData; 675}; 676 677PipelineLibraryTestInstance::PipelineLibraryTestInstance (Context& context, const TestParams& data) 678 : vkt::TestInstance (context) 679 , m_data (data) 680 , m_vertexData () 681 , m_paletteData () 682{ 683 m_vertexData = 684 { 685 { -1.0f, -1.0f, 0.0f, 1.0f }, 686 { +1.0f, -1.0f, 0.5f, 1.0f }, 687 { -1.0f, +1.0f, 0.5f, 1.0f }, 688 { -1.0f, +1.0f, 0.5f, 1.0f }, 689 { +1.0f, -1.0f, 0.5f, 1.0f }, 690 { +1.0f, +1.0f, 1.0f, 1.0f }, 691 }; 692 m_paletteData = 693 { 694 { 0.25f, 1.0f, 0.0f, 1.0f }, 695 { 0.75f, 0.0f, 1.0f, 1.0f }, 696 }; 697 m_zCoordData = 698 { 699 { 0.25f, 0.75f, 0.0f, 1.0f }, 700 }; 701} 702 703PipelineLibraryTestInstance::~PipelineLibraryTestInstance (void) 704{ 705} 706 707de::MovePtr<BufferWithMemory> PipelineLibraryTestInstance::makeVertexBuffer (void) 708{ 709 const DeviceInterface& vk = m_context.getDeviceInterface(); 710 const VkDevice device = m_context.getDevice(); 711 Allocator& allocator = m_context.getDefaultAllocator(); 712 const size_t bufferDataSize = de::dataSize(m_vertexData); 713 const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); 714 de::MovePtr<BufferWithMemory> buffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible)); 715 716 deMemcpy(buffer->getAllocation().getHostPtr(), m_vertexData.data(), bufferDataSize); 717 flushAlloc(vk, device, buffer->getAllocation()); 718 719 return buffer; 720} 721 722de::MovePtr<BufferWithMemory> PipelineLibraryTestInstance::makeZCoordBuffer (void) 723{ 724 const DeviceInterface& vk = m_context.getDeviceInterface(); 725 const VkDevice device = m_context.getDevice(); 726 Allocator& allocator = m_context.getDefaultAllocator(); 727 const size_t bufferDataSize = de::dataSize(m_zCoordData); 728 const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); 729 de::MovePtr<BufferWithMemory> buffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible)); 730 731 deMemcpy(buffer->getAllocation().getHostPtr(), m_zCoordData.data(), bufferDataSize); 732 flushAlloc(vk, device, buffer->getAllocation()); 733 734 return buffer; 735} 736 737de::MovePtr<BufferWithMemory> PipelineLibraryTestInstance::makePaletteBuffer (void) 738{ 739 const DeviceInterface& vk = m_context.getDeviceInterface(); 740 const VkDevice device = m_context.getDevice(); 741 Allocator& allocator = m_context.getDefaultAllocator(); 742 const size_t bufferDataSize = de::dataSize(m_paletteData); 743 const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); 744 de::MovePtr<BufferWithMemory> buffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible)); 745 746 deMemcpy(buffer->getAllocation().getHostPtr(), m_paletteData.data(), bufferDataSize); 747 flushAlloc(vk, device, buffer->getAllocation()); 748 749 return buffer; 750} 751 752Move<VkDescriptorPool> PipelineLibraryTestInstance::createDescriptorPool (void) 753{ 754 const DeviceInterface& vk = m_context.getDeviceInterface(); 755 const VkDevice device = m_context.getDevice(); 756 757 return DescriptorPoolBuilder() 758 .addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 4) 759 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 3); 760} 761 762Move<VkDescriptorSetLayout> PipelineLibraryTestInstance::createDescriptorSetLayout (const VkBuffer vertShaderBuffer, 763 const VkBuffer fragShaderBuffer) 764{ 765 const DeviceInterface& vk = m_context.getDeviceInterface(); 766 const VkDevice device = m_context.getDevice(); 767 DescriptorSetLayoutBuilder builder; 768 769 if (vertShaderBuffer != DE_NULL) 770 builder.addIndexedBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1u, VK_SHADER_STAGE_VERTEX_BIT, 0u, DE_NULL); 771 772 if (fragShaderBuffer != DE_NULL) 773 builder.addIndexedBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1u, VK_SHADER_STAGE_FRAGMENT_BIT, 1u, DE_NULL); 774 775 return builder.build(vk, device); 776} 777 778Move<VkDescriptorSet> PipelineLibraryTestInstance::createDescriptorSet (const VkDescriptorPool pool, 779 const VkDescriptorSetLayout layout, 780 const VkBuffer vertShaderBuffer, 781 const VkBuffer fragShaderBuffer) 782{ 783 const DeviceInterface& vk = m_context.getDeviceInterface(); 784 const VkDevice device = m_context.getDevice(); 785 const VkDescriptorSetAllocateInfo allocInfo = 786 { 787 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType; 788 DE_NULL, // const void* pNext; 789 pool, // VkDescriptorPool descriptorPool; 790 1u, // deUint32 descriptorSetCount; 791 &layout // const VkDescriptorSetLayout* pSetLayouts; 792 }; 793 Move<VkDescriptorSet> descriptorSet = allocateDescriptorSet(vk, device, &allocInfo); 794 DescriptorSetUpdateBuilder builder; 795 796 if (vertShaderBuffer != DE_NULL) 797 { 798 const VkDeviceSize vertShaderBufferSize = de::dataSize(m_zCoordData); 799 const VkDescriptorBufferInfo vertShaderBufferInfo = makeDescriptorBufferInfo(vertShaderBuffer, 0u, vertShaderBufferSize); 800 801 builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &vertShaderBufferInfo); 802 } 803 804 if (fragShaderBuffer != DE_NULL) 805 { 806 const VkDeviceSize fragShaderBufferSize = de::dataSize(m_paletteData); 807 const VkDescriptorBufferInfo fragShaderBufferInfo = makeDescriptorBufferInfo(fragShaderBuffer, 0u, fragShaderBufferSize); 808 809 builder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &fragShaderBufferInfo); 810 } 811 812 builder.update(vk, device); 813 814 return descriptorSet; 815} 816 817VkFormat getSupportedDepthFormat(const InstanceInterface &vk, const VkPhysicalDevice physicalDevice) 818{ 819 VkFormatProperties properties; 820 821 const VkFormat DepthFormats[] = 822 { 823 VK_FORMAT_D32_SFLOAT, 824 VK_FORMAT_X8_D24_UNORM_PACK32, 825 VK_FORMAT_D24_UNORM_S8_UINT, 826 VK_FORMAT_D32_SFLOAT_S8_UINT 827 }; 828 829 for (const auto format: DepthFormats) 830 { 831 vk.getPhysicalDeviceFormatProperties(physicalDevice, format, &properties); 832 833 if (properties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) 834 return format; 835 } 836 837 TCU_THROW(NotSupportedError, "Depth format is not supported"); 838} 839 840bool PipelineLibraryTestInstance::runTest (RuntimePipelineTreeConfiguration& runtimePipelineTreeConfiguration, 841 const bool optimize, 842 const bool delayedShaderCreate) 843{ 844 const DeviceInterface& vk = m_context.getDeviceInterface(); 845 const VkDevice device = m_context.getDevice(); 846 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 847 Allocator& allocator = m_context.getDefaultAllocator(); 848 tcu::TestLog& log = m_context.getTestContext().getLog(); 849 const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM; 850 const VkFormat depthFormat = getSupportedDepthFormat(m_context.getInstanceInterface(), m_context.getPhysicalDevice()); 851 const VkGraphicsPipelineLibraryFlagsEXT vertPipelineFlags = static_cast<VkGraphicsPipelineLibraryFlagsEXT>(VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT); 852 const VkGraphicsPipelineLibraryFlagsEXT fragPipelineFlags = static_cast<VkGraphicsPipelineLibraryFlagsEXT>(VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT); 853 const VkGraphicsPipelineLibraryFlagsEXT samePipelineFlags = vertPipelineFlags | fragPipelineFlags; 854 const deInt32 nodeNdxLast = static_cast<deInt32>(runtimePipelineTreeConfiguration.size()) - 1; 855 const Move<VkRenderPass> renderPass = makeRenderPass(vk, device, colorFormat, depthFormat); 856 const de::MovePtr<BufferWithMemory> zCoordBuffer = makeZCoordBuffer(); 857 const de::MovePtr<BufferWithMemory> paletteBuffer = makePaletteBuffer(); 858 const Move<VkDescriptorPool> descriptorPool = createDescriptorPool(); 859 860 const Move<VkDescriptorSetLayout> descriptorSetLayoutVert = createDescriptorSetLayout(**zCoordBuffer, DE_NULL); 861 const Move<VkDescriptorSetLayout> descriptorSetLayoutFrag = createDescriptorSetLayout(DE_NULL, **paletteBuffer); 862 const Move<VkDescriptorSetLayout> descriptorSetLayoutBoth = createDescriptorSetLayout(**zCoordBuffer, **paletteBuffer); 863 const Move<VkDescriptorSet> descriptorSetVert = createDescriptorSet(*descriptorPool, *descriptorSetLayoutVert, **zCoordBuffer, DE_NULL); 864 const Move<VkDescriptorSet> descriptorSetFrag = createDescriptorSet(*descriptorPool, *descriptorSetLayoutFrag, DE_NULL , **paletteBuffer); 865 866 VkDescriptorSet vecDescriptorSetBoth[2] = { *descriptorSetVert, *descriptorSetFrag }; 867 868 VkDescriptorSetLayout vecLayoutVert[2] = { *descriptorSetLayoutVert, DE_NULL }; 869 VkDescriptorSetLayout vecLayoutFrag[2] = { DE_NULL, *descriptorSetLayoutFrag }; 870 VkDescriptorSetLayout vecLayoutBoth[2] = { *descriptorSetLayoutVert, *descriptorSetLayoutFrag }; 871 872 VkPipelineLayoutCreateFlags pipelineLayoutCreateFlag = 0u; 873 if (!m_data.useMaintenance5 && (m_data.delayedShaderCreate || (m_data.pipelineTreeConfiguration.size() > 1))) 874 pipelineLayoutCreateFlag = VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT; 875 876 const Move<VkCommandPool> cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex); 877 const Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 878 const Move<VkPipelineLayout> pipelineLayoutSame = makePipelineLayout(vk, device, 2, vecLayoutBoth, pipelineLayoutCreateFlag); 879 Move<VkPipelineLayout> pipelineLayoutVert; 880 Move<VkPipelineLayout> pipelineLayoutFrag; 881 Move<VkPipeline> rootPipeline; 882 883 // Go through tree nodes and create library for each up to root 884 for (deInt32 nodeNdx = nodeNdxLast; nodeNdx >= 0 ; --nodeNdx) // We expect only backward node reference, thus build pipielines from end is safe 885 { 886 RuntimePipelineTreeNode& node = runtimePipelineTreeConfiguration[nodeNdx]; 887 const bool buildLibrary = (nodeNdx != 0); 888 const VkPipelineCreateFlags pipelineCreateFlags = calcPipelineCreateFlags(optimize, buildLibrary); 889 const VkGraphicsPipelineLibraryFlagsEXT subtreeGraphicsPipelineLibraryFlags = node.subtreeGraphicsPipelineLibraryFlags | node.graphicsPipelineLibraryFlags; 890 const bool samePipelineLayout = samePipelineFlags == (samePipelineFlags & subtreeGraphicsPipelineLibraryFlags); 891 const bool vertPipelineLayout = vertPipelineFlags == (vertPipelineFlags & subtreeGraphicsPipelineLibraryFlags); 892 const bool fragPipelineLayout = fragPipelineFlags == (fragPipelineFlags & subtreeGraphicsPipelineLibraryFlags); 893 894 if (samePipelineLayout) 895 ; // pipelineLayoutSame is always built before. 896 else if (vertPipelineLayout) 897 { 898 if (!pipelineLayoutVert) 899 pipelineLayoutVert = makePipelineLayout(vk, device, 2, vecLayoutVert, pipelineLayoutCreateFlag); 900 } 901 else if (fragPipelineLayout) 902 { 903 if (!pipelineLayoutFrag) 904 pipelineLayoutFrag = makePipelineLayout(vk, device, 2, vecLayoutFrag, pipelineLayoutCreateFlag); 905 } 906 907 const VkPipelineLayout pipelineLayout = samePipelineLayout ? *pipelineLayoutSame 908 : vertPipelineLayout ? *pipelineLayoutVert 909 : fragPipelineLayout ? *pipelineLayoutFrag 910 : DE_NULL; 911 const VkRenderPass renderPassHandle = getRenderPass(node.graphicsPipelineLibraryFlags, *renderPass); 912 VkGraphicsPipelineLibraryCreateInfoEXT graphicsPipelineLibraryCreateInfo = makeGraphicsPipelineLibraryCreateInfo(node.graphicsPipelineLibraryFlags); 913 VkPipelineLibraryCreateInfoKHR linkingInfo = makePipelineLibraryCreateInfo(node.pipelineLibraries); 914 GraphicsPipelineCreateInfo graphicsPipelineCreateInfo (pipelineLayout, renderPassHandle, 0, pipelineCreateFlags); 915 916 for (const auto subsetFlag: GRAPHICS_PIPELINE_LIBRARY_FLAGS) 917 { 918 if ((node.graphicsPipelineLibraryFlags & subsetFlag) != 0) 919 { 920 switch (subsetFlag) 921 { 922 case VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT: updateVertexInputInterface(m_context, graphicsPipelineCreateInfo); break; 923 case VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT: updatePreRasterization(m_context, graphicsPipelineCreateInfo, delayedShaderCreate); break; 924 case VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT: updatePostRasterization(m_context, graphicsPipelineCreateInfo, delayedShaderCreate);break; 925 case VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT: updateFragmentOutputInterface(m_context, graphicsPipelineCreateInfo); break; 926 default: TCU_THROW(InternalError, "Unknown pipeline subset"); 927 } 928 } 929 } 930 931 VkGraphicsPipelineLibraryFlagsEXT linkedLibrariesFlags = 0; 932 933 for (auto flag : node.linkedLibraryFlags) 934 linkedLibrariesFlags |= flag; 935 936 // When pLibraries have any pipeline library with fragment shader state and current pipeline we try to create doesn't, 937 // we need to set a MS info. 938 if ((linkedLibrariesFlags & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT) && 939 !(node.graphicsPipelineLibraryFlags & VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT) && 940 (graphicsPipelineCreateInfo.pMultisampleState == DE_NULL)) 941 { 942 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateCreateInfo = makePipelineMultisampleStateCreateInfo(); 943 944 graphicsPipelineCreateInfo.addState(pipelineMultisampleStateCreateInfo); 945 } 946 947 948 if (!m_data.useMaintenance5 && linkedLibrariesFlags != ALL_GRAPHICS_PIPELINE_LIBRARY_FLAGS && graphicsPipelineLibraryCreateInfo.flags != 0) 949 appendStructurePtrToVulkanChain(&graphicsPipelineCreateInfo.pNext, &graphicsPipelineLibraryCreateInfo); 950 951 if (linkingInfo.libraryCount != 0) 952 { 953 appendStructurePtrToVulkanChain(&graphicsPipelineCreateInfo.pNext, &linkingInfo); 954 graphicsPipelineCreateInfo.layout = *pipelineLayoutSame; 955 } 956 957 linkedLibrariesFlags |= node.graphicsPipelineLibraryFlags; 958 959 // if current pipeline that we try to create and pLibraries have all states of pipelines, we are not allowed to create a pipeline library. 960 if (linkedLibrariesFlags == ALL_GRAPHICS_PIPELINE_LIBRARY_FLAGS) 961 { 962 DE_ASSERT(!buildLibrary); 963 graphicsPipelineCreateInfo.flags &= ~VK_PIPELINE_CREATE_LIBRARY_BIT_KHR; 964 } 965 966 node.pipeline = createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineCreateInfo); 967 968 if (buildLibrary) 969 { 970 DE_ASSERT(de::inBounds(node.parentIndex, 0, static_cast<deInt32>(runtimePipelineTreeConfiguration.size()))); 971 972 runtimePipelineTreeConfiguration[node.parentIndex].pipelineLibraries.push_back(*node.pipeline); 973 runtimePipelineTreeConfiguration[node.parentIndex].linkedLibraryFlags.push_back(linkedLibrariesFlags); 974 } 975 else 976 { 977 DE_ASSERT(node.parentIndex == -1); 978 979 rootPipeline = node.pipeline; 980 } 981 } 982 983 // Queue commands and read results. 984 { 985 const tcu::UVec2 renderSize = { RENDER_SIZE_WIDTH, RENDER_SIZE_HEIGHT }; 986 const VkRect2D renderArea = makeRect2D(renderSize.x(), renderSize.y()); 987 const de::MovePtr<BufferWithMemory> vertexBuffer = makeVertexBuffer(); 988 const deUint32 vertexCount = static_cast<deUint32>(m_vertexData.size()); 989 const VkDeviceSize vertexBufferOffset = 0; 990 const Vec4 colorClearColor (0.0f, 0.0f, 0.0f, 1.0f); 991 const VkImageCreateInfo colorImageCreateInfo = makeColorImageCreateInfo(colorFormat, renderSize.x(), renderSize.y()); 992 const ImageWithMemory colorImage (vk, device, allocator, colorImageCreateInfo, MemoryRequirement::Any); 993 const VkImageViewCreateInfo colorImageViewCreateInfo = makeImageViewCreateInfo(*colorImage, colorFormat, static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT)); 994 const Move<VkImageView> colorImageView = createImageView(vk, device, &colorImageViewCreateInfo); 995 const VkImageCreateInfo depthImageCreateInfo = makeDepthImageCreateInfo(depthFormat, renderSize.x(), renderSize.y()); 996 const ImageWithMemory depthImage (vk, device, allocator, depthImageCreateInfo, MemoryRequirement::Any); 997 const VkImageViewCreateInfo depthImageViewCreateInfo = makeImageViewCreateInfo(*depthImage, depthFormat, static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_DEPTH_BIT)); 998 const Move<VkImageView> depthImageView = createImageView(vk, device, &depthImageViewCreateInfo); 999 const float depthClearDepth = 1.0f; 1000 const deUint32 depthClearStencil = 0u; 1001 const VkDeviceSize colorBufferDataSize = static_cast<VkDeviceSize>(renderSize.x() * renderSize.y() * tcu::getPixelSize(mapVkFormat(colorFormat))); 1002 const VkBufferCreateInfo colorBufferCreateInfo = makeBufferCreateInfo(colorBufferDataSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT); 1003 const BufferWithMemory colorBuffer (vk, device, allocator, colorBufferCreateInfo, MemoryRequirement::HostVisible); 1004 const VkDeviceSize depthBufferDataSize = static_cast<VkDeviceSize>(renderSize.x() * renderSize.y() * tcu::getPixelSize(mapVkFormat(depthFormat))); 1005 const VkBufferCreateInfo depthBufferCreateInfo = makeBufferCreateInfo(depthBufferDataSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT); 1006 const BufferWithMemory depthBuffer (vk, device, allocator, depthBufferCreateInfo, MemoryRequirement::HostVisible); 1007 const VkImageView attachments[] = { *colorImageView, *depthImageView }; 1008 const VkFramebufferCreateInfo framebufferCreateInfo = makeFramebufferCreateInfo(*renderPass, DE_LENGTH_OF_ARRAY(attachments), attachments, renderSize.x(), renderSize.y()); 1009 const Move<VkFramebuffer> framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo); 1010 1011 vk::beginCommandBuffer(vk, *cmdBuffer, 0u); 1012 { 1013 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderArea, colorClearColor, depthClearDepth, depthClearStencil); 1014 { 1015 vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer->get(), &vertexBufferOffset); 1016 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *rootPipeline); 1017 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayoutSame, 0u, 2u, vecDescriptorSetBoth, 0u, DE_NULL); 1018 vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u); 1019 } 1020 endRenderPass(vk, *cmdBuffer); 1021 1022 const tcu::IVec2 size = { (deInt32)renderSize.x(), (deInt32)renderSize.y() }; 1023 copyImageToBuffer(vk, *cmdBuffer, *colorImage, *colorBuffer, size); 1024 copyImageToBuffer(vk, *cmdBuffer, *depthImage, *depthBuffer, size, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1u, VK_IMAGE_ASPECT_DEPTH_BIT, VK_IMAGE_ASPECT_DEPTH_BIT); 1025 } 1026 vk::endCommandBuffer(vk, *cmdBuffer); 1027 vk::submitCommandsAndWait(vk, device, m_context.getUniversalQueue(), cmdBuffer.get()); 1028 1029 vk::invalidateAlloc(vk, device, colorBuffer.getAllocation()); 1030 vk::invalidateAlloc(vk, device, depthBuffer.getAllocation()); 1031 1032 const tcu::ConstPixelBufferAccess colorPixelAccess(mapVkFormat(colorFormat), renderSize.x(), renderSize.y(), 1, colorBuffer.getAllocation().getHostPtr()); 1033 const tcu::ConstPixelBufferAccess depthPixelAccess(mapVkFormat(depthFormat), renderSize.x(), renderSize.y(), 1, depthBuffer.getAllocation().getHostPtr()); 1034 1035 if (!verifyColorImage(colorPixelAccess)) 1036 { 1037 log << tcu::TestLog::Image("color", "Rendered image", colorPixelAccess); 1038 1039 return false; 1040 } 1041 1042 if (!verifyDepthImage(depthPixelAccess)) 1043 { 1044 log << tcu::TestLog::Image("depth", "Rendered image", depthPixelAccess); 1045 1046 return false; 1047 } 1048 } 1049 1050 return true; 1051} 1052 1053bool PipelineLibraryTestInstance::verifyColorImage (const ConstPixelBufferAccess& pba) 1054{ 1055 tcu::TestLog& log = m_context.getTestContext().getLog(); 1056 TextureLevel referenceImage (pba.getFormat(), pba.getWidth(), pba.getHeight()); 1057 PixelBufferAccess reference (referenceImage); 1058 const int horzEdge = 3 * reference.getWidth() / 4; 1059 const int vertEdge = reference.getHeight() / 2; 1060 const UVec4 green = ivec2uvec(RGBA::green().toIVec()); 1061 const UVec4 blue = ivec2uvec(RGBA::blue().toIVec()); 1062 const UVec4 black = ivec2uvec(RGBA::black().toIVec()); 1063 1064 for (int y = 0; y < reference.getHeight(); ++y) 1065 { 1066 for (int x = 0; x < reference.getWidth(); ++x) 1067 { 1068 if (x < horzEdge) 1069 { 1070 if (y < vertEdge) 1071 reference.setPixel(green, x, y); 1072 else 1073 reference.setPixel(blue, x, y); 1074 } 1075 else 1076 reference.setPixel(black, x, y); 1077 } 1078 } 1079 1080 return intThresholdCompare(log, "colorImage", "colorImage", reference, pba, UVec4(), COMPARE_LOG_RESULT); 1081} 1082 1083bool PipelineLibraryTestInstance::verifyDepthImage (const ConstPixelBufferAccess& pba) 1084{ 1085 tcu::TestLog& log = m_context.getTestContext().getLog(); 1086 const VkFormat compareFormat = VK_FORMAT_R8_UNORM; 1087 TextureLevel referenceImage (mapVkFormat(compareFormat), pba.getWidth(), pba.getHeight()); 1088 PixelBufferAccess reference (referenceImage); 1089 TextureLevel resultImage (mapVkFormat(compareFormat), pba.getWidth(), pba.getHeight()); 1090 PixelBufferAccess result (resultImage); 1091 const int horzEdge = 3 * reference.getWidth() / 4; 1092 const int diagonalEdge = (reference.getWidth() + reference.getHeight()) / 2 - 1; 1093 const UVec4 red100 = ivec2uvec(RGBA::red().toIVec()); 1094 const UVec4 red025 = UVec4(red100[0] / 4, red100[1] / 4, red100[2] / 4, red100[3]); 1095 const UVec4 red075 = UVec4(3 * red100[0] / 4, 3 * red100[1] / 4, 3 * red100[2] / 4, red100[3]); 1096 1097 for (int y = 0; y < result.getHeight(); ++y) 1098 for (int x = 0; x < result.getWidth(); ++x) 1099 { 1100 const UVec4 pix(static_cast<deUint32>(static_cast<float>(red100[0]) * pba.getPixDepth(x, y)), 0, 0, 0); 1101 1102 result.setPixel(pix, x, y); 1103 } 1104 1105 for (int y = 0; y < reference.getHeight(); ++y) 1106 { 1107 for (int x = 0; x < reference.getWidth(); ++x) 1108 { 1109 if (x < horzEdge) 1110 { 1111 if (x + y < diagonalEdge) 1112 reference.setPixel(red025, x, y); 1113 else 1114 reference.setPixel(red075, x, y); 1115 } 1116 else 1117 reference.setPixel(red100, x, y); 1118 } 1119 } 1120 1121 return intThresholdCompare(log, "depthImage", "depthImage", reference, result, UVec4(), COMPARE_LOG_RESULT); 1122} 1123 1124tcu::TestStatus PipelineLibraryTestInstance::iterate (void) 1125{ 1126 VkGraphicsPipelineLibraryFlagBitsEXT graphicsPipelineLibraryFlags[] = 1127 { 1128 VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT, 1129 VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT, 1130 VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT, 1131 VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT, 1132 }; 1133 const auto graphicsPipelineLibraryFlagsBegin = graphicsPipelineLibraryFlags; 1134 const auto graphicsPipelineLibraryFlagsEnd = graphicsPipelineLibraryFlags + DE_LENGTH_OF_ARRAY(graphicsPipelineLibraryFlags); 1135 deUint32 permutationId = 0; 1136 std::set<deUint32> was; 1137 bool result = true; 1138 1139 do 1140 { 1141 RuntimePipelineTreeConfiguration runtimePipelineTreeConfiguration (m_data.pipelineTreeConfiguration.size()); 1142 size_t subsetNdxStart = 0; 1143 deUint32 uniqueTreeSubsetCode = 0; 1144 1145 for (size_t nodeNdx = 0; nodeNdx < runtimePipelineTreeConfiguration.size(); ++nodeNdx) 1146 { 1147 const deUint32 shaderCount = m_data.pipelineTreeConfiguration[nodeNdx].shaderCount; 1148 RuntimePipelineTreeNode& node = runtimePipelineTreeConfiguration[nodeNdx]; 1149 1150 node.parentIndex = m_data.pipelineTreeConfiguration[nodeNdx].parentIndex; 1151 node.graphicsPipelineLibraryFlags = 0u; 1152 1153 for (size_t subsetNdx = 0; subsetNdx < shaderCount; ++subsetNdx) 1154 node.graphicsPipelineLibraryFlags |= static_cast<VkGraphicsPipelineLibraryFlagsEXT>(graphicsPipelineLibraryFlags[subsetNdxStart + subsetNdx]); 1155 1156 if (node.parentIndex > 0) 1157 runtimePipelineTreeConfiguration[node.parentIndex].subtreeGraphicsPipelineLibraryFlags |= node.graphicsPipelineLibraryFlags; 1158 1159 // Each shader subset should be tested in each node of tree 1160 subsetNdxStart += shaderCount; 1161 1162 uniqueTreeSubsetCode = (uniqueTreeSubsetCode << 4) | node.graphicsPipelineLibraryFlags; 1163 } 1164 1165 // Check whether this configuration has been tried 1166 if (was.find(uniqueTreeSubsetCode) == was.end()) 1167 was.insert(uniqueTreeSubsetCode); 1168 else 1169 continue; 1170 1171 result = result && runTest(runtimePipelineTreeConfiguration, m_data.optimize, m_data.delayedShaderCreate); 1172 1173 if (!result) 1174 { 1175 tcu::TestLog& log = m_context.getTestContext().getLog(); 1176 std::ostringstream ess; 1177 1178 for (size_t nodeNdx = 0; nodeNdx < runtimePipelineTreeConfiguration.size(); ++nodeNdx) 1179 { 1180 const RuntimePipelineTreeNode& node = runtimePipelineTreeConfiguration[nodeNdx]; 1181 1182 ess << node.parentIndex << " {"; 1183 1184 for (size_t subsetNdx = 0; subsetNdx < DE_LENGTH_OF_ARRAY(graphicsPipelineLibraryFlags); ++subsetNdx) 1185 { 1186 if ((node.graphicsPipelineLibraryFlags & graphicsPipelineLibraryFlags[subsetNdx]) == 0) 1187 continue; 1188 1189 ess << getGraphicsPipelineLibraryFlagsString(graphicsPipelineLibraryFlags[subsetNdx]) << " "; 1190 } 1191 1192 ess << "}" << std::endl; 1193 } 1194 1195 log << tcu::TestLog::Message << ess.str() << tcu::TestLog::EndMessage; 1196 1197 return tcu::TestStatus::fail("At permutation " + de::toString(permutationId)); 1198 } 1199 1200 ++permutationId; 1201 } while (std::next_permutation(graphicsPipelineLibraryFlagsBegin, graphicsPipelineLibraryFlagsEnd)); 1202 1203 return tcu::TestStatus::pass("OK"); 1204} 1205 1206 1207class PipelineLibraryTestCase : public TestCase 1208{ 1209 public: 1210 PipelineLibraryTestCase (tcu::TestContext& context, const char* name, const TestParams data); 1211 ~PipelineLibraryTestCase (void); 1212 1213 virtual void checkSupport (Context& context) const; 1214 virtual void initPrograms (SourceCollections& programCollection) const; 1215 virtual TestInstance* createInstance (Context& context) const; 1216private: 1217 TestParams m_data; 1218}; 1219 1220PipelineLibraryTestCase::PipelineLibraryTestCase (tcu::TestContext& context, const char* name, const TestParams data) 1221 : vkt::TestCase (context, name) 1222 , m_data (data) 1223{ 1224} 1225 1226PipelineLibraryTestCase::~PipelineLibraryTestCase (void) 1227{ 1228} 1229 1230void PipelineLibraryTestCase::checkSupport (Context& context) const 1231{ 1232 if (m_data.useMaintenance5) 1233 { 1234 context.requireDeviceFunctionality("VK_KHR_maintenance5"); 1235 return; 1236 } 1237 1238 context.requireDeviceFunctionality("VK_KHR_pipeline_library"); 1239 1240 if (m_data.delayedShaderCreate || (m_data.pipelineTreeConfiguration.size() > 1)) 1241 { 1242 context.requireDeviceFunctionality("VK_EXT_graphics_pipeline_library"); 1243 1244 const VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT& graphicsPipelineLibraryFeaturesEXT = context.getGraphicsPipelineLibraryFeaturesEXT(); 1245 1246 if (!graphicsPipelineLibraryFeaturesEXT.graphicsPipelineLibrary) 1247 TCU_THROW(NotSupportedError, "graphicsPipelineLibraryFeaturesEXT.graphicsPipelineLibrary required"); 1248 } 1249} 1250 1251void PipelineLibraryTestCase::initPrograms (SourceCollections& programCollection) const 1252{ 1253 std::string vert = 1254 "#version 450\n" 1255 "layout(location = 0) in vec4 in_position;\n" 1256 "layout(set = 0, binding = 0) uniform buf\n" 1257 "{\n" 1258 " vec4 z_coord;\n" 1259 "};\n" 1260 "\n" 1261 "out gl_PerVertex\n" 1262 "{\n" 1263 " vec4 gl_Position;\n" 1264 "};\n" 1265 "\n" 1266 "void main()\n" 1267 "{\n" 1268 " const float z = gl_VertexIndex < 3 ? z_coord.x : z_coord.y;\n" 1269 " gl_Position = vec4(in_position.x, in_position.y, z, 1.0f);\n" 1270 "}\n"; 1271 1272 programCollection.glslSources.add("vert") << glu::VertexSource(vert); 1273 1274 std::string frag = 1275 "#version 450\n" 1276 "layout(location = 0) out highp vec4 o_color;\n" 1277 "layout(set = 1, binding = 1) uniform buf\n" 1278 "{\n" 1279 " vec4 colorTop;\n" 1280 " vec4 colorBot;\n" 1281 "};\n" 1282 "\n" 1283 "void main()\n" 1284 "{\n" 1285 " const int middle = " + de::toString(RENDER_SIZE_HEIGHT / 2) + ";\n" 1286 " o_color = int(gl_FragCoord.y - 0.5f) < middle ? colorTop : colorBot;\n" 1287 "}\n"; 1288 1289 programCollection.glslSources.add("frag") << glu::FragmentSource(frag); 1290} 1291 1292TestInstance* PipelineLibraryTestCase::createInstance (Context& context) const 1293{ 1294 return new PipelineLibraryTestInstance(context, m_data); 1295} 1296 1297enum class MiscTestMode 1298{ 1299 INDEPENDENT_PIPELINE_LAYOUT_SETS_FAST_LINKED = 0, 1300 INDEPENDENT_PIPELINE_LAYOUT_SETS_WITH_LINK_TIME_OPTIMIZATION_UNION_HANDLE, 1301 BIND_NULL_DESCRIPTOR_SET, 1302 BIND_NULL_DESCRIPTOR_SET_IN_MONOLITHIC_PIPELINE, 1303 COMPARE_LINK_TIMES, 1304 SHADER_MODULE_CREATE_INFO_COMP, 1305 SHADER_MODULE_CREATE_INFO_RT, 1306 SHADER_MODULE_CREATE_INFO_RT_LIB, 1307 NULL_RENDERING_CREATE_INFO, 1308}; 1309 1310struct MiscTestParams 1311{ 1312 MiscTestMode mode; 1313 1314 // attributes used in BIND_NULL_DESCRIPTOR_SET mode 1315 deUint32 layoutsCount; 1316 deUint32 layoutsBits; 1317}; 1318 1319class PipelineLibraryMiscTestInstance : public TestInstance 1320{ 1321public: 1322 PipelineLibraryMiscTestInstance (Context& context, 1323 const MiscTestParams& params); 1324 ~PipelineLibraryMiscTestInstance (void) = default; 1325 tcu::TestStatus iterate (void); 1326 1327protected: 1328 1329 tcu::TestStatus runNullDescriptorSet (void); 1330 tcu::TestStatus runNullDescriptorSetInMonolithicPipeline(void); 1331 tcu::TestStatus runIndependentPipelineLayoutSets (bool useLinkTimeOptimization = false); 1332 tcu::TestStatus runCompareLinkTimes (void); 1333 1334 struct VerificationData 1335 { 1336 const tcu::IVec2 point; 1337 const tcu::IVec4 color; 1338 }; 1339 tcu::TestStatus verifyResult (const std::vector<VerificationData>& verificationData, 1340 const tcu::ConstPixelBufferAccess& colorPixelAccess) const; 1341 1342private: 1343 MiscTestParams m_testParams; 1344 const VkFormat m_colorFormat; 1345 const Vec4 m_colorClearColor; 1346 const VkRect2D m_renderArea; 1347 1348 de::MovePtr<ImageWithMemory> m_colorImage; 1349 Move<VkImageView> m_colorImageView; 1350 1351 Move<VkRenderPass> m_renderPass; 1352 Move<VkFramebuffer> m_framebuffer; 1353 1354 Move<VkCommandPool> m_cmdPool; 1355 Move<VkCommandBuffer> m_cmdBuffer; 1356}; 1357 1358PipelineLibraryMiscTestInstance::PipelineLibraryMiscTestInstance(Context& context, const MiscTestParams& params) 1359 : vkt::TestInstance (context) 1360 , m_testParams (params) 1361 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 1362 , m_colorClearColor (0.0f, 0.0f, 0.0f, 1.0f) 1363 , m_renderArea (makeRect2D(RENDER_SIZE_WIDTH, RENDER_SIZE_HEIGHT)) 1364{ 1365} 1366 1367tcu::TestStatus PipelineLibraryMiscTestInstance::iterate (void) 1368{ 1369 const DeviceInterface& vk = m_context.getDeviceInterface(); 1370 const VkDevice device = m_context.getDevice(); 1371 Allocator& allocator = m_context.getDefaultAllocator(); 1372 1373 // create image and image view that will hold rendered frame 1374 const VkImageCreateInfo colorImageCreateInfo = makeColorImageCreateInfo(m_colorFormat, m_renderArea.extent.width, m_renderArea.extent.height); 1375 m_colorImage = de::MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, allocator, colorImageCreateInfo, MemoryRequirement::Any)); 1376 const VkImageViewCreateInfo colorImageViewCreateInfo = makeImageViewCreateInfo(**m_colorImage, m_colorFormat, static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT)); 1377 const Move<VkImageView> colorImageView = createImageView(vk, device, &colorImageViewCreateInfo); 1378 1379 // create renderpass and framebuffer 1380 m_renderPass = makeRenderPass(vk, device, m_colorFormat); 1381 const VkFramebufferCreateInfo framebufferCreateInfo = makeFramebufferCreateInfo(*m_renderPass, 1u, &*colorImageView, m_renderArea.extent.width, m_renderArea.extent.height); 1382 m_framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo); 1383 1384 // create command pool and command buffer 1385 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 1386 m_cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex); 1387 m_cmdBuffer = allocateCommandBuffer(vk, device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 1388 1389 // run selected test 1390 if (m_testParams.mode == MiscTestMode::BIND_NULL_DESCRIPTOR_SET) 1391 return runNullDescriptorSet(); 1392 else if (m_testParams.mode == MiscTestMode::BIND_NULL_DESCRIPTOR_SET_IN_MONOLITHIC_PIPELINE) 1393 return runNullDescriptorSetInMonolithicPipeline(); 1394 else if (m_testParams.mode == MiscTestMode::INDEPENDENT_PIPELINE_LAYOUT_SETS_FAST_LINKED) 1395 return runIndependentPipelineLayoutSets(); 1396 else if (m_testParams.mode == MiscTestMode::INDEPENDENT_PIPELINE_LAYOUT_SETS_WITH_LINK_TIME_OPTIMIZATION_UNION_HANDLE) 1397 return runIndependentPipelineLayoutSets(true); 1398 else if (m_testParams.mode == MiscTestMode::COMPARE_LINK_TIMES) 1399 return runCompareLinkTimes(); 1400 1401 DE_ASSERT(DE_FALSE); 1402 return tcu::TestStatus::fail("Fail"); 1403} 1404 1405tcu::TestStatus PipelineLibraryMiscTestInstance::runNullDescriptorSet(void) 1406{ 1407 const DeviceInterface& vk = m_context.getDeviceInterface(); 1408 const VkDevice device = m_context.getDevice(); 1409 Allocator& allocator = m_context.getDefaultAllocator(); 1410 1411 const VkDeviceSize colorBufferDataSize = static_cast<VkDeviceSize>(m_renderArea.extent.width * m_renderArea.extent.height * tcu::getPixelSize(mapVkFormat(m_colorFormat))); 1412 const VkBufferCreateInfo colorBufferCreateInfo = makeBufferCreateInfo(colorBufferDataSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT); 1413 const BufferWithMemory colorBuffer (vk, device, allocator, colorBufferCreateInfo, MemoryRequirement::HostVisible); 1414 1415 VkDeviceSize uniformBufferDataSize = sizeof(tcu::Vec4); 1416 const VkBufferCreateInfo uniformBufferCreateInfo = makeBufferCreateInfo(uniformBufferDataSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); 1417 de::MovePtr<BufferWithMemory> uniformBuffer[2]; 1418 1419 // setup data in uniform buffers that will give us expected result for validation 1420 const tcu::Vec4 uniformBuffData[] 1421 { 1422 { -1.00f, 1.00f, 2.0f, -2.00f }, 1423 { 0.00f, 0.20f, 0.6f, 0.75f }, 1424 }; 1425 1426 for (deUint32 i = 0; i < 2; ++i) 1427 { 1428 uniformBuffer[i] = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, uniformBufferCreateInfo, MemoryRequirement::HostVisible)); 1429 deMemcpy(uniformBuffer[i]->getAllocation().getHostPtr(), uniformBuffData[i].getPtr(), (size_t)uniformBufferDataSize); 1430 flushAlloc(vk, device, uniformBuffer[i]->getAllocation()); 1431 } 1432 1433 const deUint32 maxBitsCount = 8 * sizeof(m_testParams.layoutsBits); 1434 VkDescriptorSetLayout vertDescriptorSetLayouts[maxBitsCount]; 1435 VkDescriptorSetLayout fragDescriptorSetLayouts[maxBitsCount]; 1436 VkDescriptorSetLayout allDescriptorSetLayouts[maxBitsCount]; 1437 1438 // set all layouts to NULL 1439 deMemset(&vertDescriptorSetLayouts, DE_NULL, maxBitsCount * sizeof(VkDescriptorSetLayout)); 1440 deMemset(&fragDescriptorSetLayouts, DE_NULL, maxBitsCount * sizeof(VkDescriptorSetLayout)); 1441 1442 // create used descriptor set layouts 1443 Move<VkDescriptorSetLayout> usedDescriptorSetLayouts[] 1444 { 1445 DescriptorSetLayoutBuilder() 1446 .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT) 1447 .build(vk, device), 1448 DescriptorSetLayoutBuilder() 1449 .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT) 1450 .build(vk, device) 1451 }; 1452 1453 // create descriptor set layouts that are not used by shaders in test - finalPipelineLayout, 1454 // needs to always be the complete pipeline layout with no holes; we can put NULLs in 1455 // DescriptorSetLayouts used by partial pipelines (vertDescriptorSetLayouts and fragDescriptorSetLayouts) 1456 Move<VkDescriptorSetLayout> unusedDescriptorSetLayouts[maxBitsCount]; 1457 for (deUint32 i = 0u; i < m_testParams.layoutsCount; ++i) 1458 { 1459 unusedDescriptorSetLayouts[i] = DescriptorSetLayoutBuilder().build(vk, device); 1460 1461 // by default allDescriptorSetLayouts is filled with unused layouts but later 1462 // if test requires this proper indexes are replaced with used layouts 1463 allDescriptorSetLayouts[i] = *unusedDescriptorSetLayouts[i]; 1464 } 1465 1466 VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = initVulkanStructure(); 1467 pipelineLayoutCreateInfo.flags = VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT; 1468 1469 // find set bits 1470 std::vector<deUint32> bitsThatAreSet; 1471 for (deUint32 i = 0u; i < m_testParams.layoutsCount; ++i) 1472 { 1473 if (m_testParams.layoutsBits & (1 << (maxBitsCount - 1 - i))) 1474 bitsThatAreSet.push_back(i); 1475 } 1476 1477 deUint32 usedDescriptorSets = static_cast<deUint32>(bitsThatAreSet.size()); 1478 DE_ASSERT(usedDescriptorSets && (usedDescriptorSets < 3u)); 1479 1480 deUint32 vertSetIndex = bitsThatAreSet[0]; 1481 deUint32 fragSetIndex = 0u; 1482 vertDescriptorSetLayouts[vertSetIndex] = *usedDescriptorSetLayouts[0]; 1483 allDescriptorSetLayouts[vertSetIndex] = *usedDescriptorSetLayouts[0]; 1484 pipelineLayoutCreateInfo.setLayoutCount = vertSetIndex + 1u; 1485 pipelineLayoutCreateInfo.pSetLayouts = vertDescriptorSetLayouts; 1486 1487 Move<VkPipelineLayout> vertPipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo); 1488 Move<VkPipelineLayout> fragPipelineLayout; 1489 1490 if (usedDescriptorSets == 2u) 1491 { 1492 fragSetIndex = bitsThatAreSet[1]; 1493 fragDescriptorSetLayouts[fragSetIndex] = *usedDescriptorSetLayouts[1]; 1494 allDescriptorSetLayouts[fragSetIndex] = *usedDescriptorSetLayouts[1]; 1495 pipelineLayoutCreateInfo.setLayoutCount = fragSetIndex + 1u; 1496 pipelineLayoutCreateInfo.pSetLayouts = fragDescriptorSetLayouts; 1497 1498 fragPipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo); 1499 } 1500 else 1501 { 1502 pipelineLayoutCreateInfo.setLayoutCount = 0u; 1503 pipelineLayoutCreateInfo.pSetLayouts = DE_NULL; 1504 fragPipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo); 1505 } 1506 1507 // create descriptor pool 1508 Move<VkDescriptorPool> descriptorPool = DescriptorPoolBuilder() 1509 .addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, usedDescriptorSets) 1510 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, usedDescriptorSets); 1511 1512 const VkDescriptorBufferInfo vertShaderBufferInfo = makeDescriptorBufferInfo(**uniformBuffer[0], 0u, uniformBufferDataSize); 1513 Move<VkDescriptorSet> vertDescriptorSet = makeDescriptorSet(vk, device, *descriptorPool, *usedDescriptorSetLayouts[0]); 1514 Move<VkDescriptorSet> fragDescriptorSet; 1515 1516 if (usedDescriptorSets == 1u) 1517 { 1518 // update single descriptors with actual buffer 1519 DescriptorSetUpdateBuilder() 1520 .writeSingle(*vertDescriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &vertShaderBufferInfo) 1521 .update(vk, device); 1522 } 1523 else 1524 { 1525 const VkDescriptorBufferInfo fragShaderBufferInfo = makeDescriptorBufferInfo(**uniformBuffer[1], 0u, uniformBufferDataSize); 1526 fragDescriptorSet = makeDescriptorSet(vk, device, *descriptorPool, *usedDescriptorSetLayouts[1]); 1527 1528 // update both descriptors with actual buffers 1529 DescriptorSetUpdateBuilder() 1530 .writeSingle(*vertDescriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &vertShaderBufferInfo) 1531 .writeSingle(*fragDescriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &fragShaderBufferInfo) 1532 .update(vk, device); 1533 } 1534 1535 pipelineLayoutCreateInfo.setLayoutCount = m_testParams.layoutsCount; 1536 pipelineLayoutCreateInfo.pSetLayouts = allDescriptorSetLayouts; 1537 Move<VkPipelineLayout> finalPipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo); 1538 1539 const deUint32 commonPipelinePartFlags = deUint32(VK_PIPELINE_CREATE_LIBRARY_BIT_KHR); 1540 GraphicsPipelineCreateInfo partialPipelineCreateInfo[] 1541 { 1542 { *vertPipelineLayout, *m_renderPass, 0, commonPipelinePartFlags }, 1543 { *fragPipelineLayout, *m_renderPass, 0, commonPipelinePartFlags }, 1544 }; 1545 1546 // fill proper portion of pipeline state 1547 updateVertexInputInterface(m_context, partialPipelineCreateInfo[0], VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 0u); 1548 updatePreRasterization(m_context, partialPipelineCreateInfo[0], false); 1549 updatePostRasterization(m_context, partialPipelineCreateInfo[1], false); 1550 updateFragmentOutputInterface(m_context, partialPipelineCreateInfo[1]); 1551 1552 Move<VkPipeline> vertPipelinePart; 1553 Move<VkPipeline> fragPipelinePart; 1554 1555 // extend pNext chain and create partial pipelines 1556 { 1557 VkGraphicsPipelineLibraryCreateInfoEXT libraryCreateInfo = makeGraphicsPipelineLibraryCreateInfo(VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT | VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT); 1558 appendStructurePtrToVulkanChain(&partialPipelineCreateInfo[0].pNext, &libraryCreateInfo); 1559 vertPipelinePart = createGraphicsPipeline(vk, device, DE_NULL, &partialPipelineCreateInfo[0]); 1560 1561 libraryCreateInfo.flags = VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT | VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT, 1562 appendStructurePtrToVulkanChain(&partialPipelineCreateInfo[1].pNext, &libraryCreateInfo); 1563 fragPipelinePart = createGraphicsPipeline(vk, device, DE_NULL, &partialPipelineCreateInfo[1]); 1564 } 1565 1566 // create final pipeline out of two parts 1567 std::vector<VkPipeline> rawParts = { *vertPipelinePart, *fragPipelinePart }; 1568 VkPipelineLibraryCreateInfoKHR linkingInfo = makePipelineLibraryCreateInfo(rawParts); 1569 VkGraphicsPipelineCreateInfo finalPipelineInfo = initVulkanStructure(); 1570 1571 finalPipelineInfo.layout = *finalPipelineLayout; 1572 appendStructurePtrToVulkanChain(&finalPipelineInfo.pNext, &linkingInfo); 1573 Move<VkPipeline> pipeline = createGraphicsPipeline(vk, device, DE_NULL, &finalPipelineInfo); 1574 1575 vk::beginCommandBuffer(vk, *m_cmdBuffer, 0u); 1576 { 1577 // change color image layout 1578 const VkImageMemoryBarrier initialImageBarrier = makeImageMemoryBarrier( 1579 0, // VkAccessFlags srcAccessMask; 1580 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 1581 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 1582 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 1583 **m_colorImage, // VkImage image; 1584 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; 1585 ); 1586 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0, DE_NULL, 0, DE_NULL, 1, &initialImageBarrier); 1587 1588 // wait for uniform buffers 1589 std::vector<VkBufferMemoryBarrier> initialBufferBarriers(2u, makeBufferMemoryBarrier( 1590 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags2KHR srcAccessMask 1591 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags2KHR dstAccessMask 1592 uniformBuffer[0]->get(), // VkBuffer buffer 1593 0u, // VkDeviceSize offset 1594 uniformBufferDataSize // VkDeviceSize size 1595 )); 1596 initialBufferBarriers[1].buffer = uniformBuffer[1]->get(); 1597 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, DE_NULL, 2, initialBufferBarriers.data(), 0, DE_NULL); 1598 1599 beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, m_renderArea, m_colorClearColor); 1600 1601 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); 1602 1603 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *finalPipelineLayout, vertSetIndex, 1u, &*vertDescriptorSet, 0u, DE_NULL); 1604 if (usedDescriptorSets == 2u) 1605 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *finalPipelineLayout, fragSetIndex, 1u, &*fragDescriptorSet, 0u, DE_NULL); 1606 1607 vk.cmdDraw(*m_cmdBuffer, 4, 1u, 0u, 0u); 1608 1609 endRenderPass(vk, *m_cmdBuffer); 1610 1611 const tcu::IVec2 size { (deInt32)m_renderArea.extent.width, (deInt32)m_renderArea.extent.height }; 1612 copyImageToBuffer(vk, *m_cmdBuffer, **m_colorImage, *colorBuffer, size); 1613 } 1614 vk::endCommandBuffer(vk, *m_cmdBuffer); 1615 vk::submitCommandsAndWait(vk, device, m_context.getUniversalQueue(), *m_cmdBuffer); 1616 1617 vk::invalidateAlloc(vk, device, colorBuffer.getAllocation()); 1618 const tcu::ConstPixelBufferAccess colorPixelAccess(mapVkFormat(m_colorFormat), m_renderArea.extent.width, m_renderArea.extent.height, 1, colorBuffer.getAllocation().getHostPtr()); 1619 1620 // verify result 1621 deInt32 width = (deInt32)m_renderArea.extent.width; 1622 deInt32 height = (deInt32)m_renderArea.extent.height; 1623 const std::vector<VerificationData> verificationData 1624 { 1625 { { 1, 1 }, { 0, 51, 153, 191 } }, // note COLOR_COMPONENTS_NO_RED is used 1626 { { width / 2, height / 2 }, { 0, 51, 153, 191 } }, 1627 { { width - 2, height - 2 }, { 0, 0, 0, 255 } } // clear color 1628 }; 1629 return verifyResult(verificationData, colorPixelAccess); 1630} 1631 1632tcu::TestStatus PipelineLibraryMiscTestInstance::runNullDescriptorSetInMonolithicPipeline() 1633{ 1634 // VK_NULL_HANDLE can be used for descriptor set layouts when creating a pipeline layout whether independent sets are used or not, 1635 // as long as graphics pipeline libraries are enabled; VK_NULL_HANDLE is also alowed for a descriptor set under the same conditions 1636 // when using vkCmdBindDescriptorSets 1637 1638 const DeviceInterface& vk = m_context.getDeviceInterface(); 1639 const VkDevice device = m_context.getDevice(); 1640 Allocator& allocator = m_context.getDefaultAllocator(); 1641 1642 const VkDeviceSize colorBufferDataSize = static_cast<VkDeviceSize>(m_renderArea.extent.width * m_renderArea.extent.height * tcu::getPixelSize(mapVkFormat(m_colorFormat))); 1643 const VkBufferCreateInfo colorBufferCreateInfo = makeBufferCreateInfo(colorBufferDataSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT); 1644 const BufferWithMemory colorBuffer(vk, device, allocator, colorBufferCreateInfo, MemoryRequirement::HostVisible); 1645 1646 const tcu::Vec4 uniformBuffData { 0.0f, 0.20f, 0.6f, 0.75f }; 1647 VkDeviceSize uniformBufferDataSize = sizeof(tcu::Vec4); 1648 const VkBufferCreateInfo uniformBufferCreateInfo = makeBufferCreateInfo(uniformBufferDataSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); 1649 1650 de::MovePtr<BufferWithMemory> uniformBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, uniformBufferCreateInfo, MemoryRequirement::HostVisible)); 1651 deMemcpy(uniformBuffer->getAllocation().getHostPtr(), uniformBuffData.getPtr(), (size_t)uniformBufferDataSize); 1652 flushAlloc(vk, device, uniformBuffer->getAllocation()); 1653 1654 // create descriptor set layouts - first unused, second used 1655 Move<VkDescriptorSetLayout> descriptorSetLayout 1656 { 1657 DescriptorSetLayoutBuilder() 1658 .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT) 1659 .build(vk, device) 1660 }; 1661 1662 Move<VkDescriptorPool> allDescriptorPool = DescriptorPoolBuilder() 1663 .addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1) 1664 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1); 1665 1666 // create descriptor set 1667 Move<VkDescriptorSet> descriptorSet = makeDescriptorSet(vk, device, *allDescriptorPool, *descriptorSetLayout); 1668 1669 // update descriptor with actual buffer 1670 const VkDescriptorBufferInfo shaderBufferInfo = makeDescriptorBufferInfo(**uniformBuffer, 0u, uniformBufferDataSize); 1671 DescriptorSetUpdateBuilder() 1672 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &shaderBufferInfo) 1673 .update(vk, device); 1674 1675 // create a pipeline layout with its first descriptor set layout as VK_NULL_HANDLE 1676 // and a second with a valid descriptor set layout containing a buffer 1677 VkDescriptorSet rawDescriptorSets[] = { DE_NULL, *descriptorSet }; 1678 VkDescriptorSetLayout rawDescriptorSetLayouts[] = { DE_NULL, *descriptorSetLayout }; 1679 1680 VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = initVulkanStructure(); 1681 pipelineLayoutCreateInfo.setLayoutCount = 2u; 1682 pipelineLayoutCreateInfo.pSetLayouts = rawDescriptorSetLayouts; 1683 Move<VkPipelineLayout> pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo); 1684 1685 // create monolithic graphics pipeline 1686 GraphicsPipelineCreateInfo pipelineCreateInfo(*pipelineLayout, *m_renderPass, 0, 0u); 1687 updateVertexInputInterface(m_context, pipelineCreateInfo, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 0u); 1688 updatePreRasterization(m_context, pipelineCreateInfo, false); 1689 updatePostRasterization(m_context, pipelineCreateInfo, false); 1690 updateFragmentOutputInterface(m_context, pipelineCreateInfo); 1691 Move<VkPipeline> pipeline = createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo); 1692 1693 vk::beginCommandBuffer(vk, *m_cmdBuffer, 0u); 1694 { 1695 // change color image layout 1696 const VkImageMemoryBarrier initialImageBarrier = makeImageMemoryBarrier( 1697 0, // VkAccessFlags srcAccessMask; 1698 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 1699 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 1700 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 1701 **m_colorImage, // VkImage image; 1702 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; 1703 ); 1704 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0, DE_NULL, 0, DE_NULL, 1, &initialImageBarrier); 1705 1706 // wait for uniform buffer 1707 const VkBufferMemoryBarrier initialBufferBarrier = makeBufferMemoryBarrier( 1708 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags2KHR srcAccessMask 1709 VK_ACCESS_UNIFORM_READ_BIT, // VkAccessFlags2KHR dstAccessMask 1710 uniformBuffer->get(), // VkBuffer buffer 1711 0u, // VkDeviceSize offset 1712 uniformBufferDataSize // VkDeviceSize size 1713 ); 1714 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, (VkDependencyFlags)0, 0, DE_NULL, 1, &initialBufferBarrier, 0, DE_NULL); 1715 1716 beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, m_renderArea, m_colorClearColor); 1717 1718 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); 1719 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 2u, rawDescriptorSets, 0u, DE_NULL); 1720 vk.cmdDraw(*m_cmdBuffer, 4, 1u, 0u, 0u); 1721 1722 endRenderPass(vk, *m_cmdBuffer); 1723 1724 const tcu::IVec2 size{ (deInt32)m_renderArea.extent.width, (deInt32)m_renderArea.extent.height }; 1725 copyImageToBuffer(vk, *m_cmdBuffer, **m_colorImage, *colorBuffer, size); 1726 } 1727 vk::endCommandBuffer(vk, *m_cmdBuffer); 1728 vk::submitCommandsAndWait(vk, device, m_context.getUniversalQueue(), *m_cmdBuffer); 1729 1730 vk::invalidateAlloc(vk, device, colorBuffer.getAllocation()); 1731 const tcu::ConstPixelBufferAccess colorPixelAccess(mapVkFormat(m_colorFormat), m_renderArea.extent.width, m_renderArea.extent.height, 1, colorBuffer.getAllocation().getHostPtr()); 1732 1733 // verify result 1734 deInt32 width = (deInt32)m_renderArea.extent.width; 1735 deInt32 height = (deInt32)m_renderArea.extent.height; 1736 tcu::IVec4 outColor 1737 { 1738 0, // r is 0 because COLOR_COMPONENTS_NO_RED is used 1739 static_cast<int>(uniformBuffData[1] * 255), 1740 static_cast<int>(uniformBuffData[2] * 255), 1741 static_cast<int>(uniformBuffData[3] * 255) 1742 }; 1743 const std::vector<VerificationData> verificationData 1744 { 1745 { { 1, 1 }, outColor }, 1746 { { width / 2, height / 2 }, outColor }, 1747 { { width - 2, height - 2 }, { 0, 0, 0, 255 } } // clear color 1748 }; 1749 1750 return verifyResult(verificationData, colorPixelAccess); 1751} 1752 1753tcu::TestStatus PipelineLibraryMiscTestInstance::runIndependentPipelineLayoutSets (bool useLinkTimeOptimization) 1754{ 1755 const DeviceInterface& vk = m_context.getDeviceInterface(); 1756 const VkDevice device = m_context.getDevice(); 1757 Allocator& allocator = m_context.getDefaultAllocator(); 1758 1759 const VkDeviceSize colorBufferDataSize = static_cast<VkDeviceSize>(m_renderArea.extent.width * m_renderArea.extent.height * tcu::getPixelSize(mapVkFormat(m_colorFormat))); 1760 const VkBufferCreateInfo colorBufferCreateInfo = makeBufferCreateInfo(colorBufferDataSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT); 1761 const BufferWithMemory colorBuffer (vk, device, allocator, colorBufferCreateInfo, MemoryRequirement::HostVisible); 1762 1763 VkDeviceSize uniformBufferDataSize = sizeof(tcu::Vec4); 1764 const VkBufferCreateInfo uniformBufferCreateInfo = makeBufferCreateInfo(uniformBufferDataSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT); 1765 1766 de::MovePtr<BufferWithMemory> uniformBuffer[3]; 1767 1768 // setup data in uniform buffers that will give us expected result for validation 1769 const tcu::Vec4 uniformBuffData[3] 1770 { 1771 { 4.00f, 3.00f, -1.0f, 4.00f }, 1772 { 0.10f, 0.25f, -0.5f, 0.05f }, 1773 { -5.00f, -2.00f, 3.0f, -6.00f }, 1774 }; 1775 1776 for (deUint32 i = 0; i < 3; ++i) 1777 { 1778 uniformBuffer[i] = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, uniformBufferCreateInfo, MemoryRequirement::HostVisible)); 1779 deMemcpy(uniformBuffer[i]->getAllocation().getHostPtr(), uniformBuffData[i].getPtr(), (size_t)uniformBufferDataSize); 1780 flushAlloc(vk, device, uniformBuffer[i]->getAllocation()); 1781 } 1782 1783 // create three descriptor set layouts 1784 Move<VkDescriptorSetLayout> descriptorSetLayouts[3]; 1785 descriptorSetLayouts[0] = DescriptorSetLayoutBuilder() 1786 .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT) 1787 .build(vk, device); 1788 descriptorSetLayouts[1] = DescriptorSetLayoutBuilder() 1789 .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT) 1790 .build(vk, device); 1791 descriptorSetLayouts[2] = DescriptorSetLayoutBuilder() 1792 .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT) 1793 .build(vk, device); 1794 1795 // for the link time opt (and when null handle is used) use total pipeline layout recreated without the INDEPENDENT SETS bit 1796 deUint32 allLayoutsFlag = deUint32(VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT); 1797 if (useLinkTimeOptimization) 1798 allLayoutsFlag = 0u; 1799 1800 // Pre-rasterization stage library has sets 0, 1, 2 1801 // * set 0 has descriptors 1802 // * set 1 has no descriptors 1803 // * set 2 has descriptors 1804 // Fragment stage library has sets 0, 1 1805 // * set 0 has descriptors 1806 // * set 1 has descriptors 1807 VkDescriptorSetLayout vertDescriptorSetLayouts[] = { *descriptorSetLayouts[0], DE_NULL, *descriptorSetLayouts[2] }; 1808 VkDescriptorSetLayout fragDescriptorSetLayouts[] = { *descriptorSetLayouts[0], *descriptorSetLayouts[1] }; 1809 VkDescriptorSetLayout allDescriptorSetLayouts[] = { *descriptorSetLayouts[0], *descriptorSetLayouts[1], *descriptorSetLayouts[2] }; 1810 1811 VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = initVulkanStructure(); 1812 pipelineLayoutCreateInfo.flags = allLayoutsFlag; 1813 pipelineLayoutCreateInfo.setLayoutCount = 3u; 1814 pipelineLayoutCreateInfo.pSetLayouts = allDescriptorSetLayouts; 1815 Move<VkPipelineLayout> allLayouts = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo); 1816 pipelineLayoutCreateInfo.flags = deUint32(VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT); 1817 pipelineLayoutCreateInfo.pSetLayouts = vertDescriptorSetLayouts; 1818 Move<VkPipelineLayout> vertLayouts = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo); 1819 pipelineLayoutCreateInfo.setLayoutCount = 2u; 1820 pipelineLayoutCreateInfo.pSetLayouts = fragDescriptorSetLayouts; 1821 Move<VkPipelineLayout> fragLayouts = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo); 1822 1823 Move<VkDescriptorPool> allDescriptorPool = DescriptorPoolBuilder() 1824 .addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 3) 1825 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 3); 1826 1827 // create three descriptor sets 1828 Move<VkDescriptorSet> descriptorSetA = makeDescriptorSet(vk, device, *allDescriptorPool, *descriptorSetLayouts[0]); 1829 Move<VkDescriptorSet> descriptorSetB = makeDescriptorSet(vk, device, *allDescriptorPool, *descriptorSetLayouts[1]); 1830 Move<VkDescriptorSet> descriptorSetC = makeDescriptorSet(vk, device, *allDescriptorPool, *descriptorSetLayouts[2]); 1831 VkDescriptorSet allDescriptorSets[] = { *descriptorSetA , *descriptorSetB , *descriptorSetC }; 1832 1833 // update descriptors with actual buffers 1834 const VkDescriptorBufferInfo shaderBufferAInfo = makeDescriptorBufferInfo(**uniformBuffer[0], 0u, uniformBufferDataSize); 1835 const VkDescriptorBufferInfo shaderBufferBInfo = makeDescriptorBufferInfo(**uniformBuffer[1], 0u, uniformBufferDataSize); 1836 const VkDescriptorBufferInfo shaderBufferCInfo = makeDescriptorBufferInfo(**uniformBuffer[2], 0u, uniformBufferDataSize); 1837 DescriptorSetUpdateBuilder() 1838 .writeSingle(*descriptorSetA, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &shaderBufferAInfo) 1839 .writeSingle(*descriptorSetB, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &shaderBufferBInfo) 1840 .writeSingle(*descriptorSetC, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &shaderBufferCInfo) 1841 .update(vk, device); 1842 1843 deUint32 commonPipelinePartFlags = deUint32(VK_PIPELINE_CREATE_LIBRARY_BIT_KHR); 1844 deUint32 finalPipelineFlag = 0u; 1845 if (useLinkTimeOptimization) 1846 { 1847 commonPipelinePartFlags |= deUint32(VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT); 1848 finalPipelineFlag = deUint32(VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT); 1849 } 1850 1851 GraphicsPipelineCreateInfo partialPipelineCreateInfo[] 1852 { 1853 { DE_NULL, *m_renderPass, 0, commonPipelinePartFlags }, 1854 { *vertLayouts, *m_renderPass, 0, commonPipelinePartFlags }, 1855 { *fragLayouts, *m_renderPass, 0, commonPipelinePartFlags }, 1856 { DE_NULL, *m_renderPass, 0, commonPipelinePartFlags } 1857 }; 1858 1859 // fill proper portion of pipeline state 1860 updateVertexInputInterface (m_context, partialPipelineCreateInfo[0], VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 0u); 1861 updatePreRasterization (m_context, partialPipelineCreateInfo[1], false); 1862 updatePostRasterization (m_context, partialPipelineCreateInfo[2], false); 1863 updateFragmentOutputInterface (m_context, partialPipelineCreateInfo[3]); 1864 1865 // extend pNext chain and create all partial pipelines 1866 std::vector<VkPipeline> rawParts(4u, DE_NULL); 1867 std::vector<Move<VkPipeline> > pipelineParts; 1868 pipelineParts.reserve(4u); 1869 VkGraphicsPipelineLibraryCreateInfoEXT libraryCreateInfo = makeGraphicsPipelineLibraryCreateInfo(VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT); 1870 for (deUint32 i = 0 ; i < 4u ; ++i) 1871 { 1872 libraryCreateInfo.flags = GRAPHICS_PIPELINE_LIBRARY_FLAGS[i]; 1873 appendStructurePtrToVulkanChain(&partialPipelineCreateInfo[i].pNext, &libraryCreateInfo); 1874 pipelineParts.emplace_back(createGraphicsPipeline(vk, device, DE_NULL, &partialPipelineCreateInfo[i])); 1875 rawParts[i] = *pipelineParts[i]; 1876 } 1877 1878 // create final pipeline out of four parts 1879 VkPipelineLibraryCreateInfoKHR linkingInfo = makePipelineLibraryCreateInfo(rawParts); 1880 VkGraphicsPipelineCreateInfo finalPipelineInfo = initVulkanStructure(); 1881 1882 finalPipelineInfo.flags = finalPipelineFlag; 1883 finalPipelineInfo.layout = *allLayouts; 1884 1885 appendStructurePtrToVulkanChain(&finalPipelineInfo.pNext, &linkingInfo); 1886 Move<VkPipeline> pipeline = createGraphicsPipeline(vk, device, DE_NULL, &finalPipelineInfo); 1887 1888 vk::beginCommandBuffer(vk, *m_cmdBuffer, 0u); 1889 { 1890 // change color image layout 1891 const VkImageMemoryBarrier initialImageBarrier = makeImageMemoryBarrier( 1892 0, // VkAccessFlags srcAccessMask; 1893 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 1894 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 1895 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 1896 **m_colorImage, // VkImage image; 1897 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; 1898 ); 1899 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0, DE_NULL, 0, DE_NULL, 1, &initialImageBarrier); 1900 1901 // wait for uniform buffers 1902 std::vector<VkBufferMemoryBarrier> initialBufferBarriers(3u, makeBufferMemoryBarrier( 1903 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags2KHR srcAccessMask 1904 VK_ACCESS_UNIFORM_READ_BIT, // VkAccessFlags2KHR dstAccessMask 1905 uniformBuffer[0]->get(), // VkBuffer buffer 1906 0u, // VkDeviceSize offset 1907 uniformBufferDataSize // VkDeviceSize size 1908 )); 1909 initialBufferBarriers[1].buffer = uniformBuffer[1]->get(); 1910 initialBufferBarriers[2].buffer = uniformBuffer[2]->get(); 1911 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, (VkDependencyFlags)0, 0, DE_NULL, 3, initialBufferBarriers.data(), 0, DE_NULL); 1912 1913 beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, m_renderArea, m_colorClearColor); 1914 1915 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); 1916 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *allLayouts, 0u, 3u, allDescriptorSets, 0u, DE_NULL); 1917 vk.cmdDraw(*m_cmdBuffer, 4, 1u, 0u, 0u); 1918 1919 endRenderPass(vk, *m_cmdBuffer); 1920 1921 const tcu::IVec2 size{ (deInt32)m_renderArea.extent.width, (deInt32)m_renderArea.extent.height }; 1922 copyImageToBuffer(vk, *m_cmdBuffer, **m_colorImage, *colorBuffer, size); 1923 } 1924 vk::endCommandBuffer(vk, *m_cmdBuffer); 1925 vk::submitCommandsAndWait(vk, device, m_context.getUniversalQueue(), *m_cmdBuffer); 1926 1927 vk::invalidateAlloc(vk, device, colorBuffer.getAllocation()); 1928 const tcu::ConstPixelBufferAccess colorPixelAccess(mapVkFormat(m_colorFormat), m_renderArea.extent.width, m_renderArea.extent.height, 1, colorBuffer.getAllocation().getHostPtr()); 1929 1930 // verify result 1931 deInt32 width = (deInt32)m_renderArea.extent.width; 1932 deInt32 height = (deInt32)m_renderArea.extent.height; 1933 const std::vector<VerificationData> verificationData 1934 { 1935 { { 1, 1 }, { 0, 191, 127, 51 } }, // note COLOR_COMPONENTS_NO_RED is used 1936 { { width / 2, height / 2 }, { 0, 191, 127, 51 } }, 1937 { { width - 2, height - 2 }, { 0, 0, 0, 255 } } // clear color 1938 }; 1939 return verifyResult(verificationData, colorPixelAccess); 1940} 1941 1942tcu::TestStatus PipelineLibraryMiscTestInstance::runCompareLinkTimes (void) 1943{ 1944 const deUint32 uniqueLibrariesCount = 2u; 1945 const deUint32 pipelinesCount = 4u * uniqueLibrariesCount; 1946 1947 const DeviceInterface& vk = m_context.getDeviceInterface(); 1948 const VkDevice device = m_context.getDevice(); 1949 tcu::TestLog& log = m_context.getTestContext().getLog(); 1950 bool allChecksPassed = true; 1951 VkPipelineLayoutCreateInfo pipelineLayoutParams = initVulkanStructure(); 1952 Move<VkPipelineLayout> layout = createPipelineLayout(vk, device, &pipelineLayoutParams); 1953 1954 GraphicsPipelineCreateInfo partialPipelineCreateInfo[] 1955 { 1956 { *layout, *m_renderPass, 0, VK_PIPELINE_CREATE_LIBRARY_BIT_KHR }, 1957 { *layout, *m_renderPass, 0, VK_PIPELINE_CREATE_LIBRARY_BIT_KHR }, 1958 { *layout, *m_renderPass, 0, VK_PIPELINE_CREATE_LIBRARY_BIT_KHR }, 1959 { *layout, *m_renderPass, 0, VK_PIPELINE_CREATE_LIBRARY_BIT_KHR }, 1960 { *layout, *m_renderPass, 0, VK_PIPELINE_CREATE_LIBRARY_BIT_KHR }, 1961 { *layout, *m_renderPass, 0, VK_PIPELINE_CREATE_LIBRARY_BIT_KHR }, 1962 { *layout, *m_renderPass, 0, VK_PIPELINE_CREATE_LIBRARY_BIT_KHR }, 1963 { *layout, *m_renderPass, 0, VK_PIPELINE_CREATE_LIBRARY_BIT_KHR }, 1964 }; 1965 1966 de::Random rnd(static_cast<deUint32>(deGetMicroseconds())); 1967 1968 const uint32_t vertexRandSpecConsts[] = { rnd.getUint32() * 2, rnd.getUint32() * 2 }; 1969 const uint32_t fragmentRandSpecConsts[] = { rnd.getUint32() * 2, rnd.getUint32() * 2 }; 1970 1971 const VkSpecializationMapEntry entry = 1972 { 1973 0, // uint32_t constantID; 1974 0, // uint32_t offset; 1975 sizeof(int32_t) // size_t size; 1976 }; 1977 1978 const VkSpecializationInfo vertexSpecializationInfos[] = 1979 { 1980 { 1981 1u, // uint32_t mapEntryCount; 1982 &entry, // const VkSpecializationMapEntry* pMapEntries; 1983 sizeof(int32_t), // size_t dataSize; 1984 &vertexRandSpecConsts[0] // const void* pData; 1985 }, 1986 { 1987 1u, // uint32_t mapEntryCount; 1988 &entry, // const VkSpecializationMapEntry* pMapEntries; 1989 sizeof(int32_t), // size_t dataSize; 1990 &vertexRandSpecConsts[1] // const void* pData; 1991 } 1992 }; 1993 1994 const VkSpecializationInfo fragmentSpecializationInfos[] = 1995 { 1996 { 1997 1u, // uint32_t mapEntryCount; 1998 &entry, // const VkSpecializationMapEntry* pMapEntries; 1999 sizeof(int32_t), // size_t dataSize; 2000 &fragmentRandSpecConsts[0] // const void* pData; 2001 }, 2002 { 2003 1u, // uint32_t mapEntryCount; 2004 &entry, // const VkSpecializationMapEntry* pMapEntries; 2005 sizeof(int32_t), // size_t dataSize; 2006 &fragmentRandSpecConsts[1] // const void* pData; 2007 } 2008 }; 2009 2010 // fill proper portion of pipeline state - this cant be easily done in a scalable loop 2011 updateVertexInputInterface (m_context, partialPipelineCreateInfo[0], VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP); 2012 updateVertexInputInterface (m_context, partialPipelineCreateInfo[1], VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST); 2013 updatePreRasterization (m_context, partialPipelineCreateInfo[2], false, VK_POLYGON_MODE_FILL, &vertexSpecializationInfos[0]); 2014 updatePreRasterization (m_context, partialPipelineCreateInfo[3], false, VK_POLYGON_MODE_LINE, &vertexSpecializationInfos[1]); 2015 updatePostRasterization (m_context, partialPipelineCreateInfo[4], false, true, &fragmentSpecializationInfos[0]); 2016 updatePostRasterization (m_context, partialPipelineCreateInfo[5], false, false, &fragmentSpecializationInfos[1]); 2017 updateFragmentOutputInterface (m_context, partialPipelineCreateInfo[6], 0xf); 2018 updateFragmentOutputInterface (m_context, partialPipelineCreateInfo[7]); 2019 2020 // construct all pipeline parts and mesure time it took 2021 struct PipelinePartData 2022 { 2023 Move<VkPipeline> pipelineHandle; 2024 std::chrono::duration<deInt64, std::nano> creationDuration; 2025 }; 2026 std::vector<PipelinePartData> pipelinePartData(pipelinesCount); 2027 VkGraphicsPipelineLibraryCreateInfoEXT libraryCreateInfo = makeGraphicsPipelineLibraryCreateInfo(VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT); 2028 for (deUint32 i = 0; i < pipelinesCount; ++i) 2029 { 2030 appendStructurePtrToVulkanChain(&partialPipelineCreateInfo[i].pNext, &libraryCreateInfo); 2031 libraryCreateInfo.flags = GRAPHICS_PIPELINE_LIBRARY_FLAGS[i / 2]; 2032 2033 auto& partData = pipelinePartData[i]; 2034 auto timeStart = std::chrono::high_resolution_clock::now(); 2035 partData.pipelineHandle = createGraphicsPipeline(vk, device, DE_NULL, partialPipelineCreateInfo + i); 2036 partData.creationDuration = std::chrono::high_resolution_clock::now() - timeStart; 2037 } 2038 2039 // iterate over all combinations of parts 2040 for (deUint32 i = 0u ; i < (deUint32)dePow(4, uniqueLibrariesCount) ; ++i) 2041 { 2042 // select new unique combination of parts 2043 deUint32 vertexInputIndex = (i ) % 2; 2044 deUint32 preRasterizationIndex = (i / 2) % 2; 2045 deUint32 fragmentStateIndex = (i / 4) % 2; 2046 deUint32 fragmentOutputIndex = (i / 8) % 2; 2047 2048 const auto& vertexInputData = pipelinePartData[ vertexInputIndex]; 2049 const auto& preRasterizationData = pipelinePartData[ uniqueLibrariesCount + preRasterizationIndex]; 2050 const auto& fragmentStateData = pipelinePartData[2 * uniqueLibrariesCount + fragmentStateIndex]; 2051 const auto& fragmentOutputData = pipelinePartData[3 * uniqueLibrariesCount + fragmentOutputIndex]; 2052 2053 std::vector<VkPipeline> pipelinesToLink 2054 { 2055 *vertexInputData.pipelineHandle, 2056 *preRasterizationData.pipelineHandle, 2057 *fragmentStateData.pipelineHandle, 2058 *fragmentOutputData.pipelineHandle, 2059 }; 2060 2061 VkPipelineLibraryCreateInfoKHR linkingInfo = makePipelineLibraryCreateInfo(pipelinesToLink); 2062 VkGraphicsPipelineCreateInfo finalPipelineInfo = initVulkanStructure(); 2063 finalPipelineInfo.layout = *layout; 2064 2065 appendStructurePtrToVulkanChain(&finalPipelineInfo.pNext, &linkingInfo); 2066 2067 // link pipeline without the optimised bit, and record the time taken to link it 2068 auto timeStart = std::chrono::high_resolution_clock::now(); 2069 Move<VkPipeline> pipeline = createGraphicsPipeline(vk, device, DE_NULL, &finalPipelineInfo); 2070 const auto linkingTime = std::chrono::high_resolution_clock::now() - timeStart; 2071 const auto creationTime = preRasterizationData.creationDuration + fragmentStateData.creationDuration; 2072 2073 if (linkingTime > (10 * creationTime)) 2074 { 2075 allChecksPassed = false; 2076 log << tcu::TestLog::Message 2077 << "Liking time (" << linkingTime.count() << ") of combination " << i 2078 << " is more then ten times greater than creation of both pre-rasterization and fragment states (" << creationTime.count() << ")" 2079 << tcu::TestLog::EndMessage; 2080 } 2081 } 2082 2083 if (allChecksPassed) 2084 return tcu::TestStatus::pass("Pass"); 2085 2086 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Liking of one or more combinations took to long"); 2087} 2088 2089tcu::TestStatus PipelineLibraryMiscTestInstance::verifyResult(const std::vector<VerificationData>& verificationData, const tcu::ConstPixelBufferAccess& colorPixelAccess) const 2090{ 2091 const deInt32 epsilon = 1; 2092 for (const auto& v : verificationData) 2093 { 2094 const IVec4 pixel = colorPixelAccess.getPixelInt(v.point.x(), v.point.y()); 2095 const IVec4 diff = pixel - v.color; 2096 for (deUint32 compNdx = 0; compNdx < 4u; ++compNdx) 2097 { 2098 if (de::abs(diff[compNdx]) > epsilon) 2099 { 2100 const Vec4 pixelBias(0.0f); 2101 const Vec4 pixelScale(1.0f); 2102 2103 m_context.getTestContext().getLog() 2104 << TestLog::Image("Result", "Result", colorPixelAccess, pixelScale, pixelBias) 2105 << tcu::TestLog::Message 2106 << "For texel " << v.point << " expected color " 2107 << v.color << " got: " << pixel 2108 << tcu::TestLog::EndMessage; 2109 2110 return tcu::TestStatus::fail("Fail"); 2111 } 2112 } 2113 } 2114 2115 return tcu::TestStatus::pass("Pass"); 2116} 2117 2118class PipelineLibraryShaderModuleInfoInstance : public TestInstance 2119{ 2120public: 2121 PipelineLibraryShaderModuleInfoInstance (Context& context) 2122 : TestInstance (context) 2123 , m_vkd (m_context.getDeviceInterface()) 2124 , m_device (m_context.getDevice()) 2125 , m_alloc (m_context.getDefaultAllocator()) 2126 , m_queueIndex (m_context.getUniversalQueueFamilyIndex()) 2127 , m_queue (m_context.getUniversalQueue()) 2128 , m_outVector (kOutputBufferElements, std::numeric_limits<uint32_t>::max()) 2129 , m_cmdBuffer (DE_NULL) 2130 {} 2131 virtual ~PipelineLibraryShaderModuleInfoInstance (void) {} 2132 2133 static constexpr size_t kOutputBufferElements = 64u; 2134 2135protected: 2136 void prepareOutputBuffer (VkShaderStageFlags stages); 2137 void allocateCmdBuffers (void); 2138 void addModule (const std::string& moduleName, VkShaderStageFlagBits stage); 2139 void recordShaderToHostBarrier (VkPipelineStageFlagBits pipelineStage) const; 2140 void verifyOutputBuffer (void); 2141 2142 using BufferWithMemoryPtr = de::MovePtr<BufferWithMemory>; 2143 2144 // From the context. 2145 const DeviceInterface& m_vkd; 2146 const VkDevice m_device; 2147 Allocator& m_alloc; 2148 const uint32_t m_queueIndex; 2149 const VkQueue m_queue; 2150 2151 Move<VkDescriptorSetLayout> m_setLayout; 2152 Move<VkDescriptorPool> m_descriptorPool; 2153 Move<VkDescriptorSet> m_descriptorSet; 2154 std::vector<uint32_t> m_outVector; 2155 BufferWithMemoryPtr m_outputBuffer; 2156 2157 Move<VkCommandPool> m_cmdPool; 2158 Move<VkCommandBuffer> m_cmdBufferPtr; 2159 VkCommandBuffer m_cmdBuffer; 2160 2161 std::vector<VkPipelineShaderStageCreateInfo> m_pipelineStageInfos; 2162 std::vector<VkShaderModuleCreateInfo> m_shaderModuleInfos; 2163}; 2164 2165void PipelineLibraryShaderModuleInfoInstance::prepareOutputBuffer (VkShaderStageFlags stages) 2166{ 2167 const auto descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; 2168 const auto poolFlags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; 2169 2170 // Create set layout. 2171 DescriptorSetLayoutBuilder layoutBuilder; 2172 layoutBuilder.addSingleBinding(descriptorType, stages); 2173 m_setLayout = layoutBuilder.build(m_vkd, m_device); 2174 2175 // Create pool and set. 2176 DescriptorPoolBuilder poolBuilder; 2177 poolBuilder.addType(descriptorType); 2178 m_descriptorPool = poolBuilder.build(m_vkd, m_device, poolFlags, 1u); 2179 m_descriptorSet = makeDescriptorSet(m_vkd, m_device, m_descriptorPool.get(), m_setLayout.get()); 2180 2181 // Create buffer. 2182 const auto outputBufferSize = static_cast<VkDeviceSize>(de::dataSize(m_outVector)); 2183 const auto outputBufferCreateInfo = makeBufferCreateInfo(outputBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); 2184 m_outputBuffer = BufferWithMemoryPtr(new BufferWithMemory(m_vkd, m_device, m_alloc, outputBufferCreateInfo, MemoryRequirement::HostVisible)); 2185 2186 // Update set. 2187 const auto outputBufferDescInfo = makeDescriptorBufferInfo(m_outputBuffer->get(), 0ull, outputBufferSize); 2188 DescriptorSetUpdateBuilder updateBuilder; 2189 updateBuilder.writeSingle(m_descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &outputBufferDescInfo); 2190 updateBuilder.update(m_vkd, m_device); 2191} 2192 2193void PipelineLibraryShaderModuleInfoInstance::addModule (const std::string& moduleName, VkShaderStageFlagBits stage) 2194{ 2195 const auto& binary = m_context.getBinaryCollection().get(moduleName); 2196 2197 const VkShaderModuleCreateInfo modInfo = 2198 { 2199 VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, // VkStructureType sType; 2200 nullptr, // const void* pNext; 2201 0u, // VkShaderModuleCreateFlags flags; 2202 binary.getSize(), // size_t codeSize; 2203 reinterpret_cast<const uint32_t*>(binary.getBinary()), // const uint32_t* pCode; 2204 }; 2205 m_shaderModuleInfos.push_back(modInfo); 2206 2207 // Note: the pNext pointer will be updated below. 2208 const VkPipelineShaderStageCreateInfo stageInfo = 2209 { 2210 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 2211 nullptr, // const void* pNext; 2212 0u, // VkPipelineShaderStageCreateFlags flags; 2213 stage, // VkShaderStageFlagBits stage; 2214 DE_NULL, // VkShaderModule module; 2215 "main", // const char* pName; 2216 nullptr, // const VkSpecializationInfo* pSpecializationInfo; 2217 }; 2218 m_pipelineStageInfos.push_back(stageInfo); 2219 2220 DE_ASSERT(m_shaderModuleInfos.size() == m_pipelineStageInfos.size()); 2221 2222 // Update pNext pointers after possible reallocation. 2223 for (size_t i = 0u; i < m_shaderModuleInfos.size(); ++i) 2224 m_pipelineStageInfos[i].pNext = &(m_shaderModuleInfos[i]); 2225} 2226 2227void PipelineLibraryShaderModuleInfoInstance::recordShaderToHostBarrier (VkPipelineStageFlagBits pipelineStage) const 2228{ 2229 const auto postWriteBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT); 2230 cmdPipelineMemoryBarrier(m_vkd, m_cmdBuffer, pipelineStage, VK_PIPELINE_STAGE_HOST_BIT, &postWriteBarrier); 2231} 2232 2233void PipelineLibraryShaderModuleInfoInstance::verifyOutputBuffer (void) 2234{ 2235 auto& allocation = m_outputBuffer->getAllocation(); 2236 2237 invalidateAlloc(m_vkd, m_device, allocation); 2238 deMemcpy(m_outVector.data(), allocation.getHostPtr(), de::dataSize(m_outVector)); 2239 2240 for (uint32_t i = 0; i < static_cast<uint32_t>(m_outVector.size()); ++i) 2241 { 2242 if (m_outVector[i] != i) 2243 { 2244 std::ostringstream msg; 2245 msg << "Unexpected value found at position " << i << ": " << m_outVector[i]; 2246 TCU_FAIL(msg.str()); 2247 } 2248 } 2249} 2250 2251void PipelineLibraryShaderModuleInfoInstance::allocateCmdBuffers (void) 2252{ 2253 m_cmdPool = makeCommandPool(m_vkd, m_device, m_queueIndex); 2254 m_cmdBufferPtr = allocateCommandBuffer(m_vkd, m_device, m_cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY); 2255 m_cmdBuffer = m_cmdBufferPtr.get(); 2256} 2257 2258class PipelineLibraryShaderModuleInfoCompInstance : public PipelineLibraryShaderModuleInfoInstance 2259{ 2260public: 2261 PipelineLibraryShaderModuleInfoCompInstance (Context& context) 2262 : PipelineLibraryShaderModuleInfoInstance(context) 2263 {} 2264 virtual ~PipelineLibraryShaderModuleInfoCompInstance (void) {} 2265 2266 tcu::TestStatus iterate (void) override; 2267}; 2268 2269tcu::TestStatus PipelineLibraryShaderModuleInfoCompInstance::iterate (void) 2270{ 2271 const auto stage = VK_SHADER_STAGE_COMPUTE_BIT; 2272 const auto bindPoint = VK_PIPELINE_BIND_POINT_COMPUTE; 2273 2274 prepareOutputBuffer(stage); 2275 addModule("comp", stage); 2276 allocateCmdBuffers(); 2277 2278 const auto pipelineLayout = makePipelineLayout(m_vkd, m_device, m_setLayout.get()); 2279 2280 const VkComputePipelineCreateInfo pipelineCreateInfo = 2281 { 2282 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType; 2283 nullptr, // const void* pNext; 2284 0u, // VkPipelineCreateFlags flags; 2285 m_pipelineStageInfos.at(0u), // VkPipelineShaderStageCreateInfo stage; 2286 pipelineLayout.get(), // VkPipelineLayout layout; 2287 DE_NULL, // VkPipeline basePipelineHandle; 2288 0, // int32_t basePipelineIndex; 2289 }; 2290 2291 const auto pipeline = createComputePipeline(m_vkd, m_device, DE_NULL, &pipelineCreateInfo); 2292 2293 beginCommandBuffer(m_vkd, m_cmdBuffer); 2294 m_vkd.cmdBindDescriptorSets(m_cmdBuffer, bindPoint, pipelineLayout.get(), 0u, 1u, &m_descriptorSet.get(), 0u, nullptr); 2295 m_vkd.cmdBindPipeline(m_cmdBuffer, bindPoint, pipeline.get()); 2296 m_vkd.cmdDispatch(m_cmdBuffer, 1u, 1u, 1u); 2297 recordShaderToHostBarrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT); 2298 endCommandBuffer(m_vkd, m_cmdBuffer); 2299 submitCommandsAndWait(m_vkd, m_device, m_queue, m_cmdBuffer); 2300 verifyOutputBuffer(); 2301 2302 return tcu::TestStatus::pass("Pass"); 2303} 2304 2305class PipelineLibraryShaderModuleInfoRTInstance : public PipelineLibraryShaderModuleInfoInstance 2306{ 2307public: 2308 PipelineLibraryShaderModuleInfoRTInstance (Context& context, bool withLibrary) 2309 : PipelineLibraryShaderModuleInfoInstance (context) 2310 , m_withLibrary (withLibrary) 2311 {} 2312 virtual ~PipelineLibraryShaderModuleInfoRTInstance (void) {} 2313 2314 tcu::TestStatus iterate (void) override; 2315 2316protected: 2317 bool m_withLibrary; 2318}; 2319 2320tcu::TestStatus PipelineLibraryShaderModuleInfoRTInstance::iterate (void) 2321{ 2322 const auto stage = VK_SHADER_STAGE_RAYGEN_BIT_KHR; 2323 const auto bindPoint = VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR; 2324 2325 prepareOutputBuffer(stage); 2326 addModule("rgen", stage); 2327 allocateCmdBuffers(); 2328 2329 const auto pipelineLayout = makePipelineLayout(m_vkd, m_device, m_setLayout.get()); 2330 2331 const VkRayTracingShaderGroupCreateInfoKHR shaderGroupInfo = 2332 { 2333 VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR, // VkStructureType sType; 2334 nullptr, // const void* pNext; 2335 VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR, // VkRayTracingShaderGroupTypeKHR type; 2336 0u, // uint32_t generalShader; 2337 VK_SHADER_UNUSED_KHR, // uint32_t closestHitShader; 2338 VK_SHADER_UNUSED_KHR, // uint32_t anyHitShader; 2339 VK_SHADER_UNUSED_KHR, // uint32_t intersectionShader; 2340 nullptr, // const void* pShaderGroupCaptureReplayHandle; 2341 }; 2342 2343 const VkPipelineCreateFlags createFlags = (m_withLibrary ? static_cast<VkPipelineCreateFlags>(VK_PIPELINE_CREATE_LIBRARY_BIT_KHR) : 0u); 2344 const VkRayTracingPipelineInterfaceCreateInfoKHR libIfaceInfo = initVulkanStructure(); 2345 const VkRayTracingPipelineInterfaceCreateInfoKHR* pLibraryIface = (m_withLibrary ? &libIfaceInfo : nullptr); 2346 2347 const VkRayTracingPipelineCreateInfoKHR pipelineCreateInfo = 2348 { 2349 VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR, // VkStructureType sType; 2350 nullptr, // const void* pNext; 2351 createFlags, // VkPipelineCreateFlags flags; 2352 de::sizeU32(m_pipelineStageInfos), // uint32_t stageCount; 2353 de::dataOrNull(m_pipelineStageInfos), // const VkPipelineShaderStageCreateInfo* pStages; 2354 1u, // uint32_t groupCount; 2355 &shaderGroupInfo, // const VkRayTracingShaderGroupCreateInfoKHR* pGroups; 2356 1u, // uint32_t maxPipelineRayRecursionDepth; 2357 nullptr, // const VkPipelineLibraryCreateInfoKHR* pLibraryInfo; 2358 pLibraryIface, // const VkRayTracingPipelineInterfaceCreateInfoKHR* pLibraryInterface; 2359 nullptr, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 2360 pipelineLayout.get(), // VkPipelineLayout layout; 2361 DE_NULL, // VkPipeline basePipelineHandle; 2362 0, // int32_t basePipelineIndex; 2363 }; 2364 2365 Move<VkPipeline> pipelineLib; 2366 Move<VkPipeline> pipeline; 2367 2368 if (m_withLibrary) 2369 { 2370 pipelineLib = createRayTracingPipelineKHR(m_vkd, m_device, DE_NULL, DE_NULL, &pipelineCreateInfo); 2371 2372 const VkPipelineLibraryCreateInfoKHR libraryInfo = 2373 { 2374 VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR, // VkStructureType sType; 2375 nullptr, // const void* pNext; 2376 1u, // uint32_t libraryCount; 2377 &pipelineLib.get(), // const VkPipeline* pLibraries; 2378 }; 2379 2380 const VkRayTracingPipelineCreateInfoKHR nonLibCreateInfo = 2381 { 2382 VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR, // VkStructureType sType; 2383 nullptr, // const void* pNext; 2384 0u, // VkPipelineCreateFlags flags; 2385 0u, // uint32_t stageCount; 2386 nullptr, // const VkPipelineShaderStageCreateInfo* pStages; 2387 0u, // uint32_t groupCount; 2388 nullptr, // const VkRayTracingShaderGroupCreateInfoKHR* pGroups; 2389 1u, // uint32_t maxPipelineRayRecursionDepth; 2390 &libraryInfo, // const VkPipelineLibraryCreateInfoKHR* pLibraryInfo; 2391 pLibraryIface, // const VkRayTracingPipelineInterfaceCreateInfoKHR* pLibraryInterface; 2392 nullptr, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 2393 pipelineLayout.get(), // VkPipelineLayout layout; 2394 DE_NULL, // VkPipeline basePipelineHandle; 2395 0, // int32_t basePipelineIndex; 2396 }; 2397 pipeline = createRayTracingPipelineKHR(m_vkd, m_device, DE_NULL, DE_NULL, &nonLibCreateInfo); 2398 } 2399 else 2400 { 2401 pipeline = createRayTracingPipelineKHR(m_vkd, m_device, DE_NULL, DE_NULL, &pipelineCreateInfo); 2402 } 2403 2404 // Make shader binding table. 2405 const auto rtProperties = makeRayTracingProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()); 2406 const auto rtHandleSize = rtProperties->getShaderGroupHandleSize(); 2407 const auto sbtSize = static_cast<VkDeviceSize>(rtHandleSize); 2408 const auto sbtMemReqs = (MemoryRequirement::HostVisible | MemoryRequirement::DeviceAddress); 2409 const auto sbtCreateInfo = makeBufferCreateInfo(sbtSize, VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); 2410 BufferWithMemoryPtr sbt = BufferWithMemoryPtr(new BufferWithMemory(m_vkd, m_device, m_alloc, sbtCreateInfo, sbtMemReqs)); 2411 auto& sbtAlloc = sbt->getAllocation(); 2412 void* sbtData = sbtAlloc.getHostPtr(); 2413 2414 // Copy ray gen shader group handle to the start of the buffer. 2415 VK_CHECK(m_vkd.getRayTracingShaderGroupHandlesKHR(m_device, pipeline.get(), 0u, 1u, static_cast<size_t>(sbtSize), sbtData)); 2416 flushAlloc(m_vkd, m_device, sbtAlloc); 2417 2418 // Strided device address regions. 2419 VkStridedDeviceAddressRegionKHR rgenSBTRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(m_vkd, m_device, sbt->get(), 0), rtHandleSize, rtHandleSize); 2420 VkStridedDeviceAddressRegionKHR missSBTRegion = makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0); 2421 VkStridedDeviceAddressRegionKHR hitsSBTRegion = makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0); 2422 VkStridedDeviceAddressRegionKHR callSBTRegion = makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0); 2423 2424 beginCommandBuffer(m_vkd, m_cmdBuffer); 2425 m_vkd.cmdBindDescriptorSets(m_cmdBuffer, bindPoint, pipelineLayout.get(), 0u, 1u, &m_descriptorSet.get(), 0u, nullptr); 2426 m_vkd.cmdBindPipeline(m_cmdBuffer, bindPoint, pipeline.get()); 2427 m_vkd.cmdTraceRaysKHR(m_cmdBuffer, &rgenSBTRegion, &missSBTRegion, &hitsSBTRegion, &callSBTRegion, kOutputBufferElements, 1u, 1u); 2428 recordShaderToHostBarrier(VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR); 2429 endCommandBuffer(m_vkd, m_cmdBuffer); 2430 submitCommandsAndWait(m_vkd, m_device, m_queue, m_cmdBuffer); 2431 verifyOutputBuffer(); 2432 2433 return tcu::TestStatus::pass("Pass"); 2434} 2435 2436class NullRenderingCreateInfoInstance : public vkt::TestInstance 2437{ 2438public: 2439 NullRenderingCreateInfoInstance (Context& context) 2440 : vkt::TestInstance(context) 2441 {} 2442 virtual ~NullRenderingCreateInfoInstance (void) {} 2443 2444 tcu::TestStatus iterate (void) override; 2445}; 2446 2447tcu::TestStatus NullRenderingCreateInfoInstance::iterate (void) 2448{ 2449 const auto ctx = m_context.getContextCommonData(); 2450 const tcu::IVec3 colorExtent (1, 1, 1); 2451 const auto imageExtent = makeExtent3D(colorExtent); 2452 const auto colorFormat = VK_FORMAT_R8G8B8A8_UNORM; 2453 const auto tcuFormat = mapVkFormat(colorFormat); 2454 const auto colorUsage = (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT); 2455 const auto colorSRR = makeDefaultImageSubresourceRange(); 2456 const auto colorSRL = makeDefaultImageSubresourceLayers(); 2457 2458 // Color buffer and view. 2459 ImageWithBuffer colorBuffer (ctx.vkd, ctx.device, ctx.allocator, imageExtent, colorFormat, colorUsage, VK_IMAGE_TYPE_2D); 2460 const auto colorView = makeImageView(ctx.vkd, ctx.device, colorBuffer.getImage(), VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSRR); 2461 2462 // Verification buffer. 2463 const auto verificationBufferSize = static_cast<VkDeviceSize>(colorExtent.x() * colorExtent.y() * colorExtent.z() * tcu::getPixelSize(tcuFormat)); 2464 const auto verificationBufferInfo = makeBufferCreateInfo(verificationBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT); 2465 BufferWithMemory verificationBuffer (ctx.vkd, ctx.device, ctx.allocator, verificationBufferInfo, MemoryRequirement::HostVisible); 2466 auto& verificationBufferAlloc = verificationBuffer.getAllocation(); 2467 void* verificationBufferPtr = verificationBufferAlloc.getHostPtr(); 2468 2469 const auto pipelineLayout = makePipelineLayout(ctx.vkd, ctx.device); 2470 2471 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo = initVulkanStructure(); 2472 VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateInfo = initVulkanStructure(); 2473 inputAssemblyStateInfo.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; 2474 2475 const std::vector<VkViewport> viewports (1u, makeViewport(imageExtent)); 2476 const std::vector<VkRect2D> scissors (1u, makeRect2D(imageExtent)); 2477 2478 const auto& binaries = m_context.getBinaryCollection(); 2479 const auto vertModule = createShaderModule(ctx.vkd, ctx.device, binaries.get("vert")); 2480 const auto fragModule = createShaderModule(ctx.vkd, ctx.device, binaries.get("frag")); 2481 2482 // We will use a null-filled pipeline rendering info structure for all substates except the fragment output state. 2483 VkPipelineRenderingCreateInfo nullRenderingInfo = initVulkanStructure(); 2484 nullRenderingInfo.colorAttachmentCount = std::numeric_limits<uint32_t>::max(); 2485 2486 VkPipelineRenderingCreateInfo finalRenderingInfo = initVulkanStructure(); 2487 finalRenderingInfo.colorAttachmentCount = 1u; 2488 finalRenderingInfo.pColorAttachmentFormats = &colorFormat; 2489 2490 const VkPipelineViewportStateCreateInfo viewportStateInfo = 2491 { 2492 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 2493 nullptr, // const void* pNext; 2494 0u, // VkPipelineViewportStateCreateFlags flags; 2495 de::sizeU32(viewports), // uint32_t viewportCount; 2496 de::dataOrNull(viewports), // const VkViewport* pViewports; 2497 de::sizeU32(scissors), // uint32_t scissorCount; 2498 de::dataOrNull(scissors), // const VkRect2D* pScissors; 2499 }; 2500 2501 const VkPipelineRasterizationStateCreateInfo rasterizationStateInfo = 2502 { 2503 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 2504 nullptr, // const void* pNext; 2505 0u, // VkPipelineRasterizationStateCreateFlags flags; 2506 VK_FALSE, // VkBool32 depthClampEnable; 2507 VK_FALSE, // VkBool32 rasterizerDiscardEnable; 2508 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 2509 VK_CULL_MODE_BACK_BIT, // VkCullModeFlags cullMode; 2510 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 2511 VK_FALSE, // VkBool32 depthBiasEnable; 2512 0.0f, // float depthBiasConstantFactor; 2513 0.0f, // float depthBiasClamp; 2514 0.0f, // float depthBiasSlopeFactor; 2515 1.0f, // float lineWidth; 2516 }; 2517 2518 const VkPipelineMultisampleStateCreateInfo multisampleStateInfo = 2519 { 2520 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 2521 nullptr, // const void* pNext; 2522 0u, // VkPipelineMultisampleStateCreateFlags flags; 2523 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples; 2524 VK_FALSE, // VkBool32 sampleShadingEnable; 2525 1.0f, // float minSampleShading; 2526 nullptr, // const VkSampleMask* pSampleMask; 2527 VK_FALSE, // VkBool32 alphaToCoverageEnable; 2528 VK_FALSE, // VkBool32 alphaToOneEnable; 2529 }; 2530 2531 const VkPipelineDepthStencilStateCreateInfo depthStencilStateInfo = initVulkanStructure(); 2532 2533 const VkColorComponentFlags colorComponentFlags = (VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT); 2534 2535 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = 2536 { 2537 VK_FALSE, // VkBool32 blendEnable; 2538 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcColorBlendFactor; 2539 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor; 2540 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 2541 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcAlphaBlendFactor; 2542 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor; 2543 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 2544 colorComponentFlags, // VkColorComponentFlags colorWriteMask; 2545 }; 2546 2547 const VkPipelineColorBlendStateCreateInfo colorBlendStateInfo = 2548 { 2549 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 2550 nullptr, // const void* pNext; 2551 0u, // VkPipelineColorBlendStateCreateFlags flags; 2552 VK_FALSE, // VkBool32 logicOpEnable; 2553 VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp; 2554 1u, // uint32_t attachmentCount; 2555 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 2556 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4]; 2557 }; 2558 2559 // Build the different pipeline pieces. 2560 Move<VkPipeline> vertexInputLib; 2561 Move<VkPipeline> preRasterShaderLib; 2562 Move<VkPipeline> fragShaderLib; 2563 Move<VkPipeline> fragOutputLib; 2564 2565 const VkPipelineCreateFlags libCreationFlags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR; 2566 const VkPipelineCreateFlags linkFlags = 0u; 2567 2568 // Vertex input state library. 2569 { 2570 VkGraphicsPipelineLibraryCreateInfoEXT vertexInputLibInfo = initVulkanStructure(); 2571 vertexInputLibInfo.flags |= VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT; 2572 2573 VkGraphicsPipelineCreateInfo vertexInputPipelineInfo = initVulkanStructure(&vertexInputLibInfo); 2574 vertexInputPipelineInfo.flags = libCreationFlags; 2575 vertexInputPipelineInfo.pVertexInputState = &vertexInputStateInfo; 2576 vertexInputPipelineInfo.pInputAssemblyState = &inputAssemblyStateInfo; 2577 2578 vertexInputLib = createGraphicsPipeline(ctx.vkd, ctx.device, VK_NULL_HANDLE, &vertexInputPipelineInfo); 2579 } 2580 2581 // Pre-rasterization shader state library. 2582 { 2583 VkGraphicsPipelineLibraryCreateInfoEXT preRasterShaderLibInfo = initVulkanStructure(&nullRenderingInfo); // What we're testing. 2584 preRasterShaderLibInfo.flags |= VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT; 2585 2586 VkGraphicsPipelineCreateInfo preRasterShaderPipelineInfo = initVulkanStructure(&preRasterShaderLibInfo); 2587 preRasterShaderPipelineInfo.flags = libCreationFlags; 2588 preRasterShaderPipelineInfo.layout = pipelineLayout.get(); 2589 preRasterShaderPipelineInfo.pViewportState = &viewportStateInfo; 2590 preRasterShaderPipelineInfo.pRasterizationState = &rasterizationStateInfo; 2591 2592 const auto vertShaderInfo = makePipelineShaderStageCreateInfo(VK_SHADER_STAGE_VERTEX_BIT, vertModule.get()); 2593 preRasterShaderPipelineInfo.stageCount = 1u; 2594 preRasterShaderPipelineInfo.pStages = &vertShaderInfo; 2595 2596 preRasterShaderLib = createGraphicsPipeline(ctx.vkd, ctx.device, DE_NULL, &preRasterShaderPipelineInfo); 2597 } 2598 2599 // Fragment shader stage library. 2600 { 2601 VkGraphicsPipelineLibraryCreateInfoEXT fragShaderLibInfo = initVulkanStructure(&nullRenderingInfo); // What we're testing. 2602 fragShaderLibInfo.flags |= VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT; 2603 2604 VkGraphicsPipelineCreateInfo fragShaderPipelineInfo = initVulkanStructure(&fragShaderLibInfo); 2605 fragShaderPipelineInfo.flags = libCreationFlags; 2606 fragShaderPipelineInfo.layout = pipelineLayout.get(); 2607 fragShaderPipelineInfo.pMultisampleState = &multisampleStateInfo; 2608 fragShaderPipelineInfo.pDepthStencilState = &depthStencilStateInfo; 2609 2610 const auto fragShaderInfo = makePipelineShaderStageCreateInfo(VK_SHADER_STAGE_FRAGMENT_BIT, fragModule.get()); 2611 fragShaderPipelineInfo.stageCount = 1u; 2612 fragShaderPipelineInfo.pStages = &fragShaderInfo; 2613 2614 fragShaderLib = createGraphicsPipeline(ctx.vkd, ctx.device, DE_NULL, &fragShaderPipelineInfo); 2615 } 2616 2617 // Fragment output library. 2618 { 2619 VkGraphicsPipelineLibraryCreateInfoEXT fragOutputLibInfo = initVulkanStructure(&finalRenderingInfo); // Good info only in the fragment output substate. 2620 fragOutputLibInfo.flags |= VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT; 2621 2622 VkGraphicsPipelineCreateInfo fragOutputPipelineInfo = initVulkanStructure(&fragOutputLibInfo); 2623 fragOutputPipelineInfo.flags = libCreationFlags; 2624 fragOutputPipelineInfo.pColorBlendState = &colorBlendStateInfo; 2625 fragOutputPipelineInfo.pMultisampleState = &multisampleStateInfo; 2626 2627 fragOutputLib = createGraphicsPipeline(ctx.vkd, ctx.device, DE_NULL, &fragOutputPipelineInfo); 2628 } 2629 2630 // Linked pipeline. 2631 const std::vector<VkPipeline> libraryHandles 2632 { 2633 vertexInputLib.get(), 2634 preRasterShaderLib.get(), 2635 fragShaderLib.get(), 2636 fragOutputLib.get(), 2637 }; 2638 2639 VkPipelineLibraryCreateInfoKHR linkedPipelineLibraryInfo = initVulkanStructure(); 2640 linkedPipelineLibraryInfo.libraryCount = de::sizeU32(libraryHandles); 2641 linkedPipelineLibraryInfo.pLibraries = de::dataOrNull(libraryHandles); 2642 2643 VkGraphicsPipelineCreateInfo linkedPipelineInfo = initVulkanStructure(&linkedPipelineLibraryInfo); 2644 linkedPipelineInfo.flags = linkFlags; 2645 linkedPipelineInfo.layout = pipelineLayout.get(); 2646 2647 const auto pipeline = createGraphicsPipeline(ctx.vkd, ctx.device, DE_NULL, &linkedPipelineInfo); 2648 2649 CommandPoolWithBuffer cmd (ctx.vkd, ctx.device, ctx.qfIndex); 2650 const auto cmdBuffer = cmd.cmdBuffer.get(); 2651 2652 const auto clearValue = makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f); 2653 2654 beginCommandBuffer(ctx.vkd, cmdBuffer); 2655 2656 const auto preRenderBarrier = makeImageMemoryBarrier(0u, (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT), 2657 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 2658 colorBuffer.getImage(), colorSRR); 2659 cmdPipelineImageMemoryBarrier(ctx.vkd, cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, &preRenderBarrier); 2660 2661 beginRendering(ctx.vkd, cmdBuffer, colorView.get(), scissors.at(0u), clearValue, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); 2662 ctx.vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.get()); 2663 ctx.vkd.cmdDraw(cmdBuffer, 3u, 1u, 0u, 0u); 2664 endRendering(ctx.vkd, cmdBuffer); 2665 2666 const auto color2Transfer = makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, 2667 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 2668 colorBuffer.getImage(), colorSRR); 2669 cmdPipelineImageMemoryBarrier(ctx.vkd, cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &color2Transfer); 2670 const auto copyRegion = makeBufferImageCopy(imageExtent, colorSRL); 2671 ctx.vkd.cmdCopyImageToBuffer(cmdBuffer, colorBuffer.getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, verificationBuffer.get(), 1u, ©Region); 2672 2673 const auto transfer2Host = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT); 2674 cmdPipelineMemoryBarrier(ctx.vkd, cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &transfer2Host); 2675 2676 endCommandBuffer(ctx.vkd, cmdBuffer); 2677 2678 submitCommandsAndWait(ctx.vkd, ctx.device, ctx.queue, cmdBuffer); 2679 invalidateAlloc(ctx.vkd, ctx.device, verificationBufferAlloc); 2680 2681 auto& testLog = m_context.getTestContext().getLog(); 2682 const tcu::Vec4 expectedColor (0.0f, 0.0f, 1.0f, 1.0f); // Must match frag shader. 2683 const tcu::Vec4 threshold (0.0f, 0.0f, 0.0f, 0.0f); 2684 tcu::ConstPixelBufferAccess resultAccess (tcuFormat, colorExtent, verificationBufferPtr); 2685 2686 if (!tcu::floatThresholdCompare(testLog, "Result", "", expectedColor, resultAccess, threshold, tcu::COMPARE_LOG_ON_ERROR)) 2687 return tcu::TestStatus::fail("Unexpected color buffer contents -- check log for details"); 2688 2689 return tcu::TestStatus::pass("Pass"); 2690} 2691 2692class PipelineLibraryMiscTestCase : public TestCase 2693{ 2694public: 2695 PipelineLibraryMiscTestCase (tcu::TestContext& context, const char* name, const MiscTestParams data); 2696 ~PipelineLibraryMiscTestCase (void) = default; 2697 2698 void checkSupport (Context& context) const; 2699 void initPrograms (SourceCollections& programCollection) const; 2700 TestInstance* createInstance (Context& context) const; 2701 2702private: 2703 MiscTestParams m_testParams; 2704}; 2705 2706PipelineLibraryMiscTestCase::PipelineLibraryMiscTestCase(tcu::TestContext& context, const char* name, const MiscTestParams params) 2707 : TestCase (context, name) 2708 , m_testParams (params) 2709{ 2710} 2711 2712void PipelineLibraryMiscTestCase::checkSupport(Context& context) const 2713{ 2714 context.requireDeviceFunctionality("VK_EXT_graphics_pipeline_library"); 2715 2716 if ((m_testParams.mode == MiscTestMode::INDEPENDENT_PIPELINE_LAYOUT_SETS_FAST_LINKED) && 2717 !context.getGraphicsPipelineLibraryPropertiesEXT().graphicsPipelineLibraryFastLinking) 2718 TCU_THROW(NotSupportedError, "graphicsPipelineLibraryFastLinking is not supported"); 2719 2720 if (m_testParams.mode == MiscTestMode::SHADER_MODULE_CREATE_INFO_RT || m_testParams.mode == MiscTestMode::SHADER_MODULE_CREATE_INFO_RT_LIB) 2721 context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline"); 2722 2723 if (m_testParams.mode == MiscTestMode::SHADER_MODULE_CREATE_INFO_RT_LIB) 2724 context.requireDeviceFunctionality("VK_KHR_pipeline_library"); 2725 2726 if (m_testParams.mode == MiscTestMode::NULL_RENDERING_CREATE_INFO) 2727 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering"); 2728} 2729 2730void PipelineLibraryMiscTestCase::initPrograms(SourceCollections& programCollection) const 2731{ 2732 if ((m_testParams.mode == MiscTestMode::BIND_NULL_DESCRIPTOR_SET) || 2733 (m_testParams.mode == MiscTestMode::BIND_NULL_DESCRIPTOR_SET_IN_MONOLITHIC_PIPELINE)) 2734 { 2735 std::string vertDefinition = ""; 2736 std::string fragDefinition = ""; 2737 std::string vertValue = " vec4 v = vec4(-1.0, 1.0, 2.0, -2.0);\n"; 2738 std::string fragValue = " vec4 v = vec4(0.0, 0.2, 0.6, 0.75);\n"; 2739 2740 // define lambda that creates proper uniform buffer definition 2741 auto constructBufferDefinition = [](deUint32 setIndex) 2742 { 2743 return std::string("layout(set = ") + std::to_string(setIndex) + ", binding = 0) uniform buf\n" 2744 "{\n" 2745 " vec4 v;\n" 2746 "};\n\n"; 2747 }; 2748 2749 if (m_testParams.mode == MiscTestMode::BIND_NULL_DESCRIPTOR_SET_IN_MONOLITHIC_PIPELINE) 2750 { 2751 // descriptor set 0 will be DE_NULL, descriptor set 1 will be valid buffer with color 2752 fragDefinition = constructBufferDefinition(1); 2753 fragValue = ""; 2754 } 2755 else if (m_testParams.layoutsBits > 0u) 2756 { 2757 std::vector<deUint32> bitsThatAreSet; 2758 const deUint32 maxBitsCount = 8 * sizeof(m_testParams.layoutsBits); 2759 2760 // find set bits 2761 for (deUint32 i = 0u; i < m_testParams.layoutsCount; ++i) 2762 { 2763 if (m_testParams.layoutsBits & (1 << (maxBitsCount - 1 - i))) 2764 bitsThatAreSet.push_back(i); 2765 } 2766 2767 // there should be 1 or 2 bits set 2768 DE_ASSERT((bitsThatAreSet.size() > 0) && (bitsThatAreSet.size() < 3)); 2769 2770 vertDefinition = constructBufferDefinition(bitsThatAreSet[0]); 2771 vertValue = ""; 2772 2773 if (bitsThatAreSet.size() == 2u) 2774 { 2775 fragDefinition = constructBufferDefinition(bitsThatAreSet[1]); 2776 fragValue = ""; 2777 } 2778 } 2779 2780 programCollection.glslSources.add("vert") << glu::VertexSource( 2781 std::string("#version 450\n" 2782 "precision mediump int;\nprecision highp float;\n") + 2783 vertDefinition + 2784 "out gl_PerVertex\n" 2785 "{\n" 2786 " vec4 gl_Position;\n" 2787 "};\n\n" 2788 "void main()\n" 2789 "{\n" + 2790 vertValue + 2791 " const float x = (v.x+v.z*((gl_VertexIndex & 2)>>1));\n" 2792 " const float y = (v.y+v.w* (gl_VertexIndex % 2));\n" 2793 2794 // note: there won't be full screen quad because of used scissors 2795 " gl_Position = vec4(x, y, 0.0, 1.0);\n" 2796 "}\n"); 2797 2798 programCollection.glslSources.add("frag") << glu::FragmentSource( 2799 std::string("#version 450\n" 2800 "precision mediump int; precision highp float;" 2801 "layout(location = 0) out highp vec4 o_color;\n") + 2802 fragDefinition + 2803 "void main()\n" 2804 "{\n" + 2805 fragValue + 2806 " o_color = v;\n" 2807 "}\n"); 2808 } 2809 else if ((m_testParams.mode == MiscTestMode::INDEPENDENT_PIPELINE_LAYOUT_SETS_FAST_LINKED) || 2810 (m_testParams.mode == MiscTestMode::INDEPENDENT_PIPELINE_LAYOUT_SETS_WITH_LINK_TIME_OPTIMIZATION_UNION_HANDLE)) 2811 { 2812 programCollection.glslSources.add("vert") << glu::VertexSource( 2813 "#version 450\n" 2814 "precision mediump int; precision highp float;\n" 2815 "layout(set = 0, binding = 0) uniform bufA\n" 2816 "{\n" 2817 " vec4 valueA;\n" 2818 "};\n" 2819 "layout(set = 2, binding = 0) uniform bufC\n" 2820 "{\n" 2821 " vec4 valueC;\n" 2822 "};\n" 2823 "out gl_PerVertex\n" 2824 "{\n" 2825 " vec4 gl_Position;\n" 2826 "};\n\n" 2827 "void main()\n" 2828 "{\n" 2829 // note: values in buffers were set to get vec4(-1, 1, 2, -2) 2830 " const vec4 v = valueA + valueC;\n" 2831 " const float x = (v.x+v.z*((gl_VertexIndex & 2)>>1));\n" 2832 " const float y = (v.y+v.w* (gl_VertexIndex % 2));\n" 2833 2834 // note: there won't be full screen quad because of used scissors 2835 " gl_Position = vec4(x, y, 0.0, 1.0);\n" 2836 "}\n"); 2837 2838 programCollection.glslSources.add("frag") << glu::FragmentSource( 2839 "#version 450\n" 2840 "precision mediump int; precision highp float;" 2841 "layout(location = 0) out highp vec4 o_color;\n" 2842 "layout(set = 0, binding = 0) uniform bufA\n" 2843 "{\n" 2844 " vec4 valueA;\n" 2845 "};\n" 2846 "layout(set = 1, binding = 0) uniform bufB\n" 2847 "{\n" 2848 " vec4 valueB;\n" 2849 "};\n" 2850 "void main()\n" 2851 "{\n" 2852 // note: values in buffers were set to get vec4(0.0, 0.75, 0.5, 0.2) 2853 " o_color = valueA * valueB;\n" 2854 "}\n"); 2855 } 2856 else if (m_testParams.mode == MiscTestMode::COMPARE_LINK_TIMES) 2857 { 2858 programCollection.glslSources.add("vert") << glu::VertexSource( 2859 "#version 450\n" 2860 "precision mediump int; precision highp float;" 2861 "layout(location = 0) in vec4 in_position;\n" 2862 "out gl_PerVertex\n" 2863 "{\n" 2864 " vec4 gl_Position;\n" 2865 "};\n" 2866 "layout(constant_id = 0) const int random = 0;\n\n" 2867 "void main()\n" 2868 "{\n" 2869 " gl_Position = vec4(float(1 - 2 * int(gl_VertexIndex != 1)),\n" 2870 " float(1 - 2 * int(gl_VertexIndex > 0)), 0.0, 1.0) + float(random & 1);\n" 2871 "}\n"); 2872 2873 programCollection.glslSources.add("frag") << glu::FragmentSource( 2874 "#version 450\n" 2875 "precision mediump int; precision highp float;" 2876 "layout(location = 0) out highp vec4 o_color;\n" 2877 "layout(constant_id = 0) const int random = 0;\n\n" 2878 "void main()\n" 2879 "{\n" 2880 " o_color = vec4(0.0, 1.0, 0.5, 1.0) + float(random & 1);\n" 2881 "}\n"); 2882 } 2883 else if (m_testParams.mode == MiscTestMode::SHADER_MODULE_CREATE_INFO_COMP) 2884 { 2885 std::ostringstream comp; 2886 comp 2887 << "#version 450\n" 2888 << "layout (set=0, binding=0, std430) buffer BufferBlock {\n" 2889 << " uint values[" << PipelineLibraryShaderModuleInfoInstance::kOutputBufferElements << "];\n" 2890 << "} outBuffer;\n" 2891 << "layout (local_size_x=" << PipelineLibraryShaderModuleInfoInstance::kOutputBufferElements << ", local_size_y=1, local_size_z=1) in;\n" 2892 << "void main (void)\n" 2893 << "{\n" 2894 << " outBuffer.values[gl_LocalInvocationIndex] = gl_LocalInvocationIndex;\n" 2895 << "}\n" 2896 ; 2897 programCollection.glslSources.add("comp") << glu::ComputeSource(comp.str()); 2898 } 2899 else if (m_testParams.mode == MiscTestMode::SHADER_MODULE_CREATE_INFO_RT || m_testParams.mode == MiscTestMode::SHADER_MODULE_CREATE_INFO_RT_LIB) 2900 { 2901 const vk::ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true); 2902 std::ostringstream rgen; 2903 rgen 2904 << "#version 460 core\n" 2905 << "#extension GL_EXT_ray_tracing : require\n" 2906 << "layout (set=0, binding=0, std430) buffer BufferBlock {\n" 2907 << " uint values[" << PipelineLibraryShaderModuleInfoInstance::kOutputBufferElements << "];\n" 2908 << "} outBuffer;\n" 2909 << "void main (void)\n" 2910 << "{\n" 2911 << " outBuffer.values[gl_LaunchIDEXT.x] = gl_LaunchIDEXT.x;\n" 2912 << "}\n" 2913 ; 2914 programCollection.glslSources.add("rgen") << glu::RaygenSource(rgen.str()) << buildOptions; 2915 } 2916 else if (m_testParams.mode == MiscTestMode::NULL_RENDERING_CREATE_INFO) 2917 { 2918 std::ostringstream vert; 2919 vert 2920 << "#version 460\n" 2921 << "vec2 positions[3] = vec2[](\n" 2922 << " vec2(-1.0, -1.0),\n" 2923 << " vec2(-1.0, 3.0),\n" 2924 << " vec2( 3.0, -1.0)\n" 2925 << ");\n" 2926 << "void main() {\n" 2927 << " gl_Position = vec4(positions[gl_VertexIndex % 3], 0.0, 1.0);\n" 2928 << "}\n" 2929 ; 2930 programCollection.glslSources.add("vert") << glu::VertexSource(vert.str()); 2931 2932 std::ostringstream frag; 2933 frag 2934 << "#version 460\n" 2935 << "layout (location=0) out vec4 color;\n" 2936 << "void main () {\n" 2937 << " color = vec4(0.0, 0.0, 1.0, 1.0);\n" 2938 << "}\n" 2939 ; 2940 programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str()); 2941 } 2942 else 2943 { 2944 DE_ASSERT(false); 2945 } 2946} 2947 2948TestInstance* PipelineLibraryMiscTestCase::createInstance(Context& context) const 2949{ 2950 if (m_testParams.mode == MiscTestMode::SHADER_MODULE_CREATE_INFO_COMP) 2951 return new PipelineLibraryShaderModuleInfoCompInstance(context); 2952 2953 if (m_testParams.mode == MiscTestMode::SHADER_MODULE_CREATE_INFO_RT) 2954 return new PipelineLibraryShaderModuleInfoRTInstance(context, false/*withLibrary*/); 2955 2956 if (m_testParams.mode == MiscTestMode::SHADER_MODULE_CREATE_INFO_RT_LIB) 2957 return new PipelineLibraryShaderModuleInfoRTInstance(context, true/*withLibrary*/); 2958 2959 if (m_testParams.mode == MiscTestMode::NULL_RENDERING_CREATE_INFO) 2960 return new NullRenderingCreateInfoInstance(context); 2961 2962 return new PipelineLibraryMiscTestInstance(context, m_testParams); 2963} 2964 2965void addPipelineLibraryConfigurationsTests (tcu::TestCaseGroup* group, bool optimize) 2966{ 2967 const int R = -1; 2968 const PipelineTreeConfiguration pipelineTreeConfiguration[] = 2969 { 2970 { { 2971 { R, 4 }, /* 4 */ 2972 } }, 2973 2974 { { 2975 { R, 0 }, /* 0 */ 2976 /* / / \ \ */ 2977 { 0, 1 }, { 0, 1 }, { 0, 1 }, { 0, 1 } /* 1 1 1 1 */ 2978 } }, 2979 2980 { { 2981 { R, 0 }, /* 0 */ 2982 /* / / \ */ 2983 { 0, 1 }, { 0, 1 }, { 0, 2 } /* 1 1 2 */ 2984 } }, 2985 2986 { { 2987 { R, 0 }, /* 0 */ 2988 /* / / \ */ 2989 { 0, 1 }, { 0, 2 }, { 0, 1 } /* 1 2 1 */ 2990 } }, 2991 2992 { { 2993 { R, 0 }, /* 0 */ 2994 /* / \ */ 2995 { 0, 2 }, { 0, 2 }, /* 2 2 */ 2996 } }, 2997 2998 { { 2999 { R, 1 }, /* 1 */ 3000 /* / \ */ 3001 { 0, 2 }, { 0, 1 }, /* 2 1 */ 3002 } }, 3003 3004 { { 3005 { R, 2 }, /* 2 */ 3006 /* / \ */ 3007 { 0, 1 }, { 0, 1 }, /* 1 1 */ 3008 } }, 3009 3010 { { 3011 { R, 3 }, /* 3 */ 3012 /* / */ 3013 { 0, 1 }, /* 1 */ 3014 } }, 3015 3016 { { 3017 { R, 1 }, /* 1 */ 3018 /* / */ 3019 { 0, 3 }, /* 3 */ 3020 } }, 3021 3022 { { 3023 { R, 0 }, /* 0 */ 3024 /* / \ */ 3025 { 0, 0 }, { 0, 0 }, /* 0 0 */ 3026 /* / \ / \ */ 3027 { 1, 1 }, { 1, 1 }, { 2, 1 }, { 2, 1 }, /* 1 1 1 1 */ 3028 } }, 3029 3030 { { 3031 { R, 0 }, /* 0 */ 3032 /* / \ */ 3033 { 0, 0 }, { 0, 1 }, /* 0 1 */ 3034 /* / \ \ */ 3035 { 1, 1 }, { 1, 1 }, { 2, 1 }, /* 1 1 1 */ 3036 } }, 3037 3038 { { 3039 { R, 1 }, /* 1 */ 3040 /* / \ */ 3041 { 0, 0 }, { 0, 1 }, /* 0 1 */ 3042 /* / \ */ 3043 { 1, 1 }, { 1, 1 }, /* 1 1 */ 3044 } }, 3045 3046 { { 3047 { R, 1 }, /* 1 */ 3048 /* / */ 3049 { 0, 1 }, /* 1 */ 3050 /* / \ */ 3051 { 1, 1 }, { 1, 1 }, /* 1 1 */ 3052 } }, 3053 3054 { { 3055 { R, 1 }, /* 1 */ 3056 /* / */ 3057 { 0, 1 }, /* 1 */ 3058 /* / */ 3059 { 1, 1 }, /* 1 */ 3060 /* / */ 3061 { 2, 1 }, /* 1 */ 3062 } }, 3063 }; 3064 3065 for (size_t libConfigNdx = 0; libConfigNdx < DE_LENGTH_OF_ARRAY(pipelineTreeConfiguration); ++libConfigNdx) 3066 { 3067 const bool delayedShaderCreate = (libConfigNdx != 0); 3068 const TestParams testParams = 3069 { 3070 pipelineTreeConfiguration[libConfigNdx], // PipelineTreeConfiguration pipelineTreeConfiguration; 3071 optimize, // bool optimize; 3072 delayedShaderCreate, // bool delayedShaderCreate; 3073 false // bool useMaintenance5; 3074 }; 3075 const std::string testName = getTestName(pipelineTreeConfiguration[libConfigNdx]); 3076 3077 if (optimize && testParams.pipelineTreeConfiguration.size() == 1) 3078 continue; 3079 3080 group->addChild(new PipelineLibraryTestCase(group->getTestContext(), testName.c_str(), testParams)); 3081 } 3082 3083 // repeat first case (one that creates montolithic pipeline) to test VK_KHR_maintenance5; 3084 // VkShaderModule deprecation (tested with delayedShaderCreate) was added to VK_KHR_maintenance5 3085 if (optimize == false) 3086 { 3087 const TestParams testParams 3088 { 3089 pipelineTreeConfiguration[0], // PipelineTreeConfiguration pipelineTreeConfiguration; 3090 false, // bool optimize; 3091 true, // bool delayedShaderCreate; 3092 true // bool useMaintenance5; 3093 }; 3094 3095 group->addChild(new PipelineLibraryTestCase(group->getTestContext(), "maintenance5", testParams)); 3096 } 3097} 3098 3099} // anonymous 3100 3101tcu::TestCaseGroup* createPipelineLibraryTests (tcu::TestContext& testCtx) 3102{ 3103 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "graphics_library")); 3104 3105 // Tests graphics pipeline libraries linkage without optimization 3106 addTestGroup(group.get(), "fast", addPipelineLibraryConfigurationsTests, false); 3107 // Tests graphics pipeline libraries linkage with optimization 3108 addTestGroup(group.get(), "optimize", addPipelineLibraryConfigurationsTests, true); 3109 3110 de::MovePtr<tcu::TestCaseGroup> miscTests(new tcu::TestCaseGroup(testCtx, "misc")); 3111 3112 de::MovePtr<tcu::TestCaseGroup> independentLayoutSetsTests(new tcu::TestCaseGroup(testCtx, "independent_pipeline_layout_sets")); 3113 independentLayoutSetsTests->addChild(new PipelineLibraryMiscTestCase(testCtx, "fast_linked", { MiscTestMode::INDEPENDENT_PIPELINE_LAYOUT_SETS_FAST_LINKED, 0u, 0u })); 3114 independentLayoutSetsTests->addChild(new PipelineLibraryMiscTestCase(testCtx, "link_opt_union_handle", { MiscTestMode::INDEPENDENT_PIPELINE_LAYOUT_SETS_WITH_LINK_TIME_OPTIMIZATION_UNION_HANDLE, 0u, 0u })); 3115 miscTests->addChild(independentLayoutSetsTests.release()); 3116 3117 de::MovePtr<tcu::TestCaseGroup> bindNullDescriptorCombinationsTests(new tcu::TestCaseGroup(testCtx, "bind_null_descriptor_set")); 3118 const std::vector<const char*> bindNullDescriptorCombinations 3119 { 3120 // note: there will be as many descriptor sets layouts in pipeline layout as there are chcaracters in the case name; 3121 // '0' represents unused descriptor set layout, '1' represents used one; 3122 // location of first '1' represents index of layout used in vertex shader; 3123 // if present second '1' represents index of layout used in fragment shader 3124 "1", 3125 "11", 3126 "01", 3127 "10", 3128 "101", 3129 "1010", 3130 "1001" // descriptor sets layouts for first pipeline part will be (&layoutA, NULL, NULL, NULL), 3131 // for second pipeline part (NULL, NULL, NULL, &layoutB) 3132 }; 3133 for (const char* name : bindNullDescriptorCombinations) 3134 { 3135 deUint32 layoutsCount = static_cast<deUint32>(strlen(name)); 3136 deUint32 layoutsBits = 0u; 3137 3138 // construct deUint32 with bits sets based on case name 3139 for (deUint32 i = 0; i < layoutsCount; ++i) 3140 layoutsBits |= (name[i] == '1') * (1 << (8 * sizeof(layoutsBits) - i - 1)); 3141 3142 bindNullDescriptorCombinationsTests->addChild(new PipelineLibraryMiscTestCase(testCtx, name, { MiscTestMode::BIND_NULL_DESCRIPTOR_SET, layoutsCount, layoutsBits })); 3143 } 3144 miscTests->addChild(bindNullDescriptorCombinationsTests.release()); 3145 3146 { 3147 de::MovePtr<tcu::TestCaseGroup> otherTests(new tcu::TestCaseGroup(testCtx, "other")); 3148 otherTests->addChild(new PipelineLibraryMiscTestCase(testCtx, "compare_link_times", { MiscTestMode::COMPARE_LINK_TIMES, 0u, 0u })); 3149 otherTests->addChild(new PipelineLibraryMiscTestCase(testCtx, "null_descriptor_set_in_monolithic_pipeline", { MiscTestMode::BIND_NULL_DESCRIPTOR_SET_IN_MONOLITHIC_PIPELINE, 0u, 0u })); 3150 otherTests->addChild(new PipelineLibraryMiscTestCase(testCtx, "null_rendering_create_info", { MiscTestMode::NULL_RENDERING_CREATE_INFO, 0u, 0u })); 3151 miscTests->addChild(otherTests.release()); 3152 } 3153 3154 { 3155 de::MovePtr<tcu::TestCaseGroup> nonGraphicsTests(new tcu::TestCaseGroup(testCtx, "non_graphics")); 3156 nonGraphicsTests->addChild(new PipelineLibraryMiscTestCase(testCtx, "shader_module_info_comp", { MiscTestMode::SHADER_MODULE_CREATE_INFO_COMP, 0u, 0u })); 3157 nonGraphicsTests->addChild(new PipelineLibraryMiscTestCase(testCtx, "shader_module_info_rt", { MiscTestMode::SHADER_MODULE_CREATE_INFO_RT, 0u, 0u })); 3158 nonGraphicsTests->addChild(new PipelineLibraryMiscTestCase(testCtx, "shader_module_info_rt_lib", { MiscTestMode::SHADER_MODULE_CREATE_INFO_RT_LIB, 0u, 0u })); 3159 miscTests->addChild(nonGraphicsTests.release()); 3160 } 3161 3162 group->addChild(miscTests.release()); 3163 3164 return group.release(); 3165} 3166 3167} // pipeline 3168 3169} // vkt 3170