1/*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2016 The Khronos Group Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief Synchronization tests utilities 22 *//*--------------------------------------------------------------------*/ 23 24#include "vktSynchronizationUtil.hpp" 25#include "vkTypeUtil.hpp" 26#include "deStringUtil.hpp" 27 28namespace vkt 29{ 30namespace synchronization 31{ 32using namespace vk; 33 34VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize bufferSize, 35 const VkBufferUsageFlags usage) 36{ 37 const VkBufferCreateInfo bufferCreateInfo = 38 { 39 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 40 DE_NULL, // const void* pNext; 41 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags; 42 bufferSize, // VkDeviceSize size; 43 usage, // VkBufferUsageFlags usage; 44 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 45 0u, // deUint32 queueFamilyIndexCount; 46 DE_NULL, // const deUint32* pQueueFamilyIndices; 47 }; 48 return bufferCreateInfo; 49} 50 51VkMemoryBarrier makeMemoryBarrier (const VkAccessFlags srcAccessMask, 52 const VkAccessFlags dstAccessMask) 53{ 54 const VkMemoryBarrier barrier = 55 { 56 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // VkStructureType sType; 57 DE_NULL, // const void* pNext; 58 srcAccessMask, // VkAccessFlags srcAccessMask; 59 dstAccessMask, // VkAccessFlags dstAccessMask; 60 }; 61 return barrier; 62} 63 64VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags srcAccessMask, 65 const VkAccessFlags dstAccessMask, 66 const VkBuffer buffer, 67 const VkDeviceSize offset, 68 const VkDeviceSize bufferSizeBytes) 69{ 70 const VkBufferMemoryBarrier barrier = 71 { 72 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 73 DE_NULL, // const void* pNext; 74 srcAccessMask, // VkAccessFlags srcAccessMask; 75 dstAccessMask, // VkAccessFlags dstAccessMask; 76 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 77 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 78 buffer, // VkBuffer buffer; 79 offset, // VkDeviceSize offset; 80 bufferSizeBytes, // VkDeviceSize size; 81 }; 82 return barrier; 83} 84 85VkImageMemoryBarrier makeImageMemoryBarrier (const VkAccessFlags srcAccessMask, 86 const VkAccessFlags dstAccessMask, 87 const VkImageLayout oldLayout, 88 const VkImageLayout newLayout, 89 const VkImage image, 90 const VkImageSubresourceRange subresourceRange) 91{ 92 const VkImageMemoryBarrier barrier = 93 { 94 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 95 DE_NULL, // const void* pNext; 96 srcAccessMask, // VkAccessFlags outputMask; 97 dstAccessMask, // VkAccessFlags inputMask; 98 oldLayout, // VkImageLayout oldLayout; 99 newLayout, // VkImageLayout newLayout; 100 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 101 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 102 image, // VkImage image; 103 subresourceRange, // VkImageSubresourceRange subresourceRange; 104 }; 105 return barrier; 106} 107 108Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool) 109{ 110 const VkCommandBufferAllocateInfo info = 111 { 112 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 113 DE_NULL, // const void* pNext; 114 commandPool, // VkCommandPool commandPool; 115 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; 116 1u, // deUint32 commandBufferCount; 117 }; 118 return allocateCommandBuffer(vk, device, &info); 119} 120 121Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface& vk, 122 const VkDevice device, 123 const VkDescriptorPool descriptorPool, 124 const VkDescriptorSetLayout setLayout) 125{ 126 const VkDescriptorSetAllocateInfo info = 127 { 128 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType; 129 DE_NULL, // const void* pNext; 130 descriptorPool, // VkDescriptorPool descriptorPool; 131 1u, // deUint32 descriptorSetCount; 132 &setLayout, // const VkDescriptorSetLayout* pSetLayouts; 133 }; 134 return allocateDescriptorSet(vk, device, &info); 135} 136 137Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface& vk, 138 const VkDevice device, 139 const VkDescriptorSetLayout descriptorSetLayout) 140{ 141 const VkPipelineLayoutCreateInfo info = 142 { 143 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 144 DE_NULL, // const void* pNext; 145 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags; 146 1u, // deUint32 setLayoutCount; 147 &descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts; 148 0u, // deUint32 pushConstantRangeCount; 149 DE_NULL, // const VkPushConstantRange* pPushConstantRanges; 150 }; 151 return createPipelineLayout(vk, device, &info); 152} 153 154Move<VkPipelineLayout> makePipelineLayoutWithoutDescriptors (const DeviceInterface& vk, 155 const VkDevice device) 156{ 157 const VkPipelineLayoutCreateInfo info = 158 { 159 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 160 DE_NULL, // const void* pNext; 161 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags; 162 0u, // deUint32 setLayoutCount; 163 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts; 164 0u, // deUint32 pushConstantRangeCount; 165 DE_NULL, // const VkPushConstantRange* pPushConstantRanges; 166 }; 167 return createPipelineLayout(vk, device, &info); 168} 169 170Move<VkPipeline> makeComputePipeline (const DeviceInterface& vk, 171 const VkDevice device, 172 const VkPipelineLayout pipelineLayout, 173 const VkShaderModule shaderModule, 174 const VkSpecializationInfo* specInfo, 175 PipelineCacheData& pipelineCacheData) 176{ 177 const VkPipelineShaderStageCreateInfo shaderStageInfo = 178 { 179 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 180 DE_NULL, // const void* pNext; 181 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 182 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage; 183 shaderModule, // VkShaderModule module; 184 "main", // const char* pName; 185 specInfo, // const VkSpecializationInfo* pSpecializationInfo; 186 }; 187 const VkComputePipelineCreateInfo pipelineInfo = 188 { 189 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType; 190 DE_NULL, // const void* pNext; 191 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags; 192 shaderStageInfo, // VkPipelineShaderStageCreateInfo stage; 193 pipelineLayout, // VkPipelineLayout layout; 194 DE_NULL, // VkPipeline basePipelineHandle; 195 0, // deInt32 basePipelineIndex; 196 }; 197 198 { 199 const vk::Unique<vk::VkPipelineCache> pipelineCache (pipelineCacheData.createPipelineCache(vk, device)); 200 vk::Move<vk::VkPipeline> pipeline (createComputePipeline(vk, device, *pipelineCache, &pipelineInfo)); 201 202 // Refresh data from cache 203 pipelineCacheData.setFromPipelineCache(vk, device, *pipelineCache); 204 205 return pipeline; 206 } 207} 208 209VkImageCreateInfo makeImageCreateInfo (const VkImageType imageType, const VkExtent3D& extent, const VkFormat format, const VkImageUsageFlags usage) 210{ 211 const VkImageCreateInfo imageInfo = 212 { 213 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 214 DE_NULL, // const void* pNext; 215 (VkImageCreateFlags)0, // VkImageCreateFlags flags; 216 imageType, // VkImageType imageType; 217 format, // VkFormat format; 218 extent, // VkExtent3D extent; 219 1u, // uint32_t mipLevels; 220 1u, // uint32_t arrayLayers; 221 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 222 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 223 usage, // VkImageUsageFlags usage; 224 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 225 0u, // uint32_t queueFamilyIndexCount; 226 DE_NULL, // const uint32_t* pQueueFamilyIndices; 227 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 228 }; 229 return imageInfo; 230} 231 232Move<VkImageView> makeImageView (const DeviceInterface& vk, 233 const VkDevice device, 234 const VkImage image, 235 const VkImageViewType viewType, 236 const VkFormat format, 237 const VkImageSubresourceRange subresourceRange) 238{ 239 const VkImageViewCreateInfo imageViewParams = 240 { 241 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 242 DE_NULL, // const void* pNext; 243 (VkImageViewCreateFlags)0, // VkImageViewCreateFlags flags; 244 image, // VkImage image; 245 viewType, // VkImageViewType viewType; 246 format, // VkFormat format; 247 makeComponentMappingRGBA(), // VkComponentMapping components; 248 subresourceRange, // VkImageSubresourceRange subresourceRange; 249 }; 250 return createImageView(vk, device, &imageViewParams); 251} 252 253VkBufferImageCopy makeBufferImageCopy (const VkImageSubresourceLayers subresourceLayers, 254 const VkExtent3D extent) 255{ 256 const VkBufferImageCopy copyParams = 257 { 258 0ull, // VkDeviceSize bufferOffset; 259 0u, // deUint32 bufferRowLength; 260 0u, // deUint32 bufferImageHeight; 261 subresourceLayers, // VkImageSubresourceLayers imageSubresource; 262 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset; 263 extent, // VkExtent3D imageExtent; 264 }; 265 return copyParams; 266} 267 268void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer) 269{ 270 const VkCommandBufferBeginInfo info = 271 { 272 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 273 DE_NULL, // const void* pNext; 274 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; 275 DE_NULL, // const VkCommandBufferInheritanceInfo* pInheritanceInfo; 276 }; 277 VK_CHECK(vk.beginCommandBuffer(commandBuffer, &info)); 278} 279 280void endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer) 281{ 282 VK_CHECK(vk.endCommandBuffer(commandBuffer)); 283} 284 285void submitCommandsAndWait (const DeviceInterface& vk, 286 const VkDevice device, 287 const VkQueue queue, 288 const VkCommandBuffer commandBuffer) 289{ 290 const Unique<VkFence> fence(createFence(vk, device)); 291 292 const VkSubmitInfo submitInfo = 293 { 294 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 295 DE_NULL, // const void* pNext; 296 0u, // uint32_t waitSemaphoreCount; 297 DE_NULL, // const VkSemaphore* pWaitSemaphores; 298 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask; 299 1u, // uint32_t commandBufferCount; 300 &commandBuffer, // const VkCommandBuffer* pCommandBuffers; 301 0u, // uint32_t signalSemaphoreCount; 302 DE_NULL, // const VkSemaphore* pSignalSemaphores; 303 }; 304 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence)); 305 VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull)); 306} 307 308void beginRenderPass (const DeviceInterface& vk, 309 const VkCommandBuffer commandBuffer, 310 const VkRenderPass renderPass, 311 const VkFramebuffer framebuffer, 312 const VkRect2D& renderArea, 313 const tcu::Vec4& clearColor) 314{ 315 const VkClearValue clearValue = makeClearValueColor(clearColor); 316 317 const VkRenderPassBeginInfo renderPassBeginInfo = { 318 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 319 DE_NULL, // const void* pNext; 320 renderPass, // VkRenderPass renderPass; 321 framebuffer, // VkFramebuffer framebuffer; 322 renderArea, // VkRect2D renderArea; 323 1u, // uint32_t clearValueCount; 324 &clearValue, // const VkClearValue* pClearValues; 325 }; 326 327 vk.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 328} 329 330void beginRenderPassWithRasterizationDisabled (const DeviceInterface& vk, 331 const VkCommandBuffer commandBuffer, 332 const VkRenderPass renderPass, 333 const VkFramebuffer framebuffer) 334{ 335 const VkRect2D renderArea = {{ 0, 0 }, { 0, 0 }}; 336 337 const VkRenderPassBeginInfo renderPassBeginInfo = { 338 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 339 DE_NULL, // const void* pNext; 340 renderPass, // VkRenderPass renderPass; 341 framebuffer, // VkFramebuffer framebuffer; 342 renderArea, // VkRect2D renderArea; 343 0u, // uint32_t clearValueCount; 344 DE_NULL, // const VkClearValue* pClearValues; 345 }; 346 347 vk.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 348} 349 350void endRenderPass (const DeviceInterface& vk, 351 const VkCommandBuffer commandBuffer) 352{ 353 vk.cmdEndRenderPass(commandBuffer); 354} 355 356Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk, 357 const VkDevice device, 358 const VkFormat colorFormat) 359{ 360 const VkAttachmentDescription colorAttachmentDescription = 361 { 362 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; 363 colorFormat, // VkFormat format; 364 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 365 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 366 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 367 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 368 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 369 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 370 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; 371 }; 372 373 const VkAttachmentReference colorAttachmentReference = 374 { 375 0u, // deUint32 attachment; 376 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 377 }; 378 379 const VkAttachmentReference depthAttachmentReference = 380 { 381 VK_ATTACHMENT_UNUSED, // deUint32 attachment; 382 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout; 383 }; 384 385 const VkSubpassDescription subpassDescription = 386 { 387 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; 388 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 389 0u, // deUint32 inputAttachmentCount; 390 DE_NULL, // const VkAttachmentReference* pInputAttachments; 391 1u, // deUint32 colorAttachmentCount; 392 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments; 393 DE_NULL, // const VkAttachmentReference* pResolveAttachments; 394 &depthAttachmentReference, // const VkAttachmentReference* pDepthStencilAttachment; 395 0u, // deUint32 preserveAttachmentCount; 396 DE_NULL // const deUint32* pPreserveAttachments; 397 }; 398 399 const VkRenderPassCreateInfo renderPassInfo = 400 { 401 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 402 DE_NULL, // const void* pNext; 403 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags; 404 1u, // deUint32 attachmentCount; 405 &colorAttachmentDescription, // const VkAttachmentDescription* pAttachments; 406 1u, // deUint32 subpassCount; 407 &subpassDescription, // const VkSubpassDescription* pSubpasses; 408 0u, // deUint32 dependencyCount; 409 DE_NULL // const VkSubpassDependency* pDependencies; 410 }; 411 412 return createRenderPass(vk, device, &renderPassInfo); 413} 414 415Move<VkFramebuffer> makeFramebuffer (const DeviceInterface& vk, 416 const VkDevice device, 417 const VkRenderPass renderPass, 418 const VkImageView colorAttachment, 419 const deUint32 width, 420 const deUint32 height, 421 const deUint32 layers) 422{ 423 const VkFramebufferCreateInfo framebufferInfo = { 424 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 425 DE_NULL, // const void* pNext; 426 (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags; 427 renderPass, // VkRenderPass renderPass; 428 1u, // uint32_t attachmentCount; 429 &colorAttachment, // const VkImageView* pAttachments; 430 width, // uint32_t width; 431 height, // uint32_t height; 432 layers, // uint32_t layers; 433 }; 434 435 return createFramebuffer(vk, device, &framebufferInfo); 436} 437 438GraphicsPipelineBuilder& GraphicsPipelineBuilder::setShader (const DeviceInterface& vk, 439 const VkDevice device, 440 const VkShaderStageFlagBits stage, 441 const ProgramBinary& binary, 442 const VkSpecializationInfo* specInfo) 443{ 444 VkShaderModule module; 445 switch (stage) 446 { 447 case (VK_SHADER_STAGE_VERTEX_BIT): 448 DE_ASSERT(m_vertexShaderModule.get() == DE_NULL); 449 m_vertexShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0); 450 module = *m_vertexShaderModule; 451 break; 452 453 case (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT): 454 DE_ASSERT(m_tessControlShaderModule.get() == DE_NULL); 455 m_tessControlShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0); 456 module = *m_tessControlShaderModule; 457 break; 458 459 case (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT): 460 DE_ASSERT(m_tessEvaluationShaderModule.get() == DE_NULL); 461 m_tessEvaluationShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0); 462 module = *m_tessEvaluationShaderModule; 463 break; 464 465 case (VK_SHADER_STAGE_GEOMETRY_BIT): 466 DE_ASSERT(m_geometryShaderModule.get() == DE_NULL); 467 m_geometryShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0); 468 module = *m_geometryShaderModule; 469 break; 470 471 case (VK_SHADER_STAGE_FRAGMENT_BIT): 472 DE_ASSERT(m_fragmentShaderModule.get() == DE_NULL); 473 m_fragmentShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0); 474 module = *m_fragmentShaderModule; 475 break; 476 477 default: 478 DE_FATAL("Invalid shader stage"); 479 return *this; 480 } 481 482 const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo = 483 { 484 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 485 DE_NULL, // const void* pNext; 486 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 487 stage, // VkShaderStageFlagBits stage; 488 module, // VkShaderModule module; 489 "main", // const char* pName; 490 specInfo, // const VkSpecializationInfo* pSpecializationInfo; 491 }; 492 493 m_shaderStageFlags |= stage; 494 m_shaderStages.push_back(pipelineShaderStageInfo); 495 496 return *this; 497} 498 499GraphicsPipelineBuilder& GraphicsPipelineBuilder::setVertexInputSingleAttribute (const VkFormat vertexFormat, const deUint32 stride) 500{ 501 const VkVertexInputBindingDescription bindingDesc = 502 { 503 0u, // uint32_t binding; 504 stride, // uint32_t stride; 505 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate; 506 }; 507 const VkVertexInputAttributeDescription attributeDesc = 508 { 509 0u, // uint32_t location; 510 0u, // uint32_t binding; 511 vertexFormat, // VkFormat format; 512 0u, // uint32_t offset; 513 }; 514 515 m_vertexInputBindings.clear(); 516 m_vertexInputBindings.push_back(bindingDesc); 517 518 m_vertexInputAttributes.clear(); 519 m_vertexInputAttributes.push_back(attributeDesc); 520 521 return *this; 522} 523 524template<typename T> 525inline const T* dataPointer (const std::vector<T>& vec) 526{ 527 return (vec.size() != 0 ? &vec[0] : DE_NULL); 528} 529 530Move<VkPipeline> GraphicsPipelineBuilder::build (const DeviceInterface& vk, 531 const VkDevice device, 532 const VkPipelineLayout pipelineLayout, 533 const VkRenderPass renderPass, 534 PipelineCacheData& pipelineCacheData) 535{ 536 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo = 537 { 538 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 539 DE_NULL, // const void* pNext; 540 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags; 541 static_cast<deUint32>(m_vertexInputBindings.size()), // uint32_t vertexBindingDescriptionCount; 542 dataPointer(m_vertexInputBindings), // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 543 static_cast<deUint32>(m_vertexInputAttributes.size()), // uint32_t vertexAttributeDescriptionCount; 544 dataPointer(m_vertexInputAttributes), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 545 }; 546 547 const VkPrimitiveTopology topology = (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST 548 : m_primitiveTopology; 549 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo = 550 { 551 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 552 DE_NULL, // const void* pNext; 553 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags; 554 topology, // VkPrimitiveTopology topology; 555 VK_FALSE, // VkBool32 primitiveRestartEnable; 556 }; 557 558 const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo = 559 { 560 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType; 561 DE_NULL, // const void* pNext; 562 (VkPipelineTessellationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags; 563 m_patchControlPoints, // uint32_t patchControlPoints; 564 }; 565 566 const VkViewport viewport = makeViewport( 567 0.0f, 0.0f, 568 static_cast<float>(m_renderSize.x()), static_cast<float>(m_renderSize.y()), 569 0.0f, 1.0f); 570 571 const VkRect2D scissor = { 572 makeOffset2D(0, 0), 573 makeExtent2D(m_renderSize.x(), m_renderSize.y()), 574 }; 575 576 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo = 577 { 578 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 579 DE_NULL, // const void* pNext; 580 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags; 581 1u, // uint32_t viewportCount; 582 &viewport, // const VkViewport* pViewports; 583 1u, // uint32_t scissorCount; 584 &scissor, // const VkRect2D* pScissors; 585 }; 586 587 const bool isRasterizationDisabled = ((m_shaderStageFlags & VK_SHADER_STAGE_FRAGMENT_BIT) == 0); 588 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo = 589 { 590 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 591 DE_NULL, // const void* pNext; 592 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags; 593 VK_FALSE, // VkBool32 depthClampEnable; 594 isRasterizationDisabled, // VkBool32 rasterizerDiscardEnable; 595 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 596 m_cullModeFlags, // VkCullModeFlags cullMode; 597 m_frontFace, // VkFrontFace frontFace; 598 VK_FALSE, // VkBool32 depthBiasEnable; 599 0.0f, // float depthBiasConstantFactor; 600 0.0f, // float depthBiasClamp; 601 0.0f, // float depthBiasSlopeFactor; 602 1.0f, // float lineWidth; 603 }; 604 605 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo = 606 { 607 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 608 DE_NULL, // const void* pNext; 609 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags; 610 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples; 611 VK_FALSE, // VkBool32 sampleShadingEnable; 612 0.0f, // float minSampleShading; 613 DE_NULL, // const VkSampleMask* pSampleMask; 614 VK_FALSE, // VkBool32 alphaToCoverageEnable; 615 VK_FALSE // VkBool32 alphaToOneEnable; 616 }; 617 618 const VkStencilOpState stencilOpState = makeStencilOpState( 619 VK_STENCIL_OP_KEEP, // stencil fail 620 VK_STENCIL_OP_KEEP, // depth & stencil pass 621 VK_STENCIL_OP_KEEP, // depth only fail 622 VK_COMPARE_OP_NEVER, // compare op 623 0u, // compare mask 624 0u, // write mask 625 0u); // reference 626 627 const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo = 628 { 629 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; 630 DE_NULL, // const void* pNext; 631 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags; 632 VK_FALSE, // VkBool32 depthTestEnable; 633 VK_FALSE, // VkBool32 depthWriteEnable; 634 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp; 635 VK_FALSE, // VkBool32 depthBoundsTestEnable; 636 VK_FALSE, // VkBool32 stencilTestEnable; 637 stencilOpState, // VkStencilOpState front; 638 stencilOpState, // VkStencilOpState back; 639 0.0f, // float minDepthBounds; 640 1.0f, // float maxDepthBounds; 641 }; 642 643 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; 644 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState = 645 { 646 m_blendEnable, // VkBool32 blendEnable; 647 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor; 648 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstColorBlendFactor; 649 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 650 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcAlphaBlendFactor; 651 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor; 652 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 653 colorComponentsAll, // VkColorComponentFlags colorWriteMask; 654 }; 655 656 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo = 657 { 658 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 659 DE_NULL, // const void* pNext; 660 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags; 661 VK_FALSE, // VkBool32 logicOpEnable; 662 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 663 1u, // deUint32 attachmentCount; 664 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 665 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4]; 666 }; 667 668 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo = 669 { 670 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 671 DE_NULL, // const void* pNext; 672 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags; 673 static_cast<deUint32>(m_shaderStages.size()), // deUint32 stageCount; 674 &m_shaderStages[0], // const VkPipelineShaderStageCreateInfo* pStages; 675 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 676 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 677 (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? &pipelineTessellationStateInfo : DE_NULL), // const VkPipelineTessellationStateCreateInfo* pTessellationState; 678 (isRasterizationDisabled ? DE_NULL : &pipelineViewportStateInfo), // const VkPipelineViewportStateCreateInfo* pViewportState; 679 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState; 680 (isRasterizationDisabled ? DE_NULL : &pipelineMultisampleStateInfo), // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 681 (isRasterizationDisabled ? DE_NULL : &pipelineDepthStencilStateInfo), // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 682 (isRasterizationDisabled ? DE_NULL : &pipelineColorBlendStateInfo), // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 683 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 684 pipelineLayout, // VkPipelineLayout layout; 685 renderPass, // VkRenderPass renderPass; 686 0u, // deUint32 subpass; 687 DE_NULL, // VkPipeline basePipelineHandle; 688 0, // deInt32 basePipelineIndex; 689 }; 690 691 { 692 const vk::Unique<vk::VkPipelineCache> pipelineCache (pipelineCacheData.createPipelineCache(vk, device)); 693 vk::Move<vk::VkPipeline> pipeline (createGraphicsPipeline(vk, device, *pipelineCache, &graphicsPipelineInfo)); 694 695 // Refresh data from cache 696 pipelineCacheData.setFromPipelineCache(vk, device, *pipelineCache); 697 698 return pipeline; 699 } 700} 701 702void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags) 703{ 704 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice); 705 706 if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader) 707 throw tcu::NotSupportedError("Tessellation shader not supported"); 708 709 if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader) 710 throw tcu::NotSupportedError("Geometry shader not supported"); 711 712 if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64) 713 throw tcu::NotSupportedError("Double-precision floats not supported"); 714 715 if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics) 716 throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline"); 717 718 if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics) 719 throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader"); 720 721 if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize) 722 throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in"); 723 724 if (((flags & FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS) != 0) && !features.shaderStorageImageExtendedFormats) 725 throw tcu::NotSupportedError("Storage image extended formats not supported"); 726} 727 728std::string getResourceName (const ResourceDescription& resource) 729{ 730 std::ostringstream str; 731 732 if (resource.type == RESOURCE_TYPE_BUFFER) 733 str << "buffer_" << resource.size.x(); 734 else if (resource.type == RESOURCE_TYPE_IMAGE) 735 { 736 str << "image_" << resource.size.x() 737 << (resource.size.y() > 0 ? "x" + de::toString(resource.size.y()) : "") 738 << (resource.size.z() > 0 ? "x" + de::toString(resource.size.z()) : "") 739 << "_" << de::toLower(getFormatName(resource.imageFormat)).substr(10); 740 } 741 else if (isIndirectBuffer(resource.type)) 742 str << "indirect_buffer"; 743 else 744 DE_ASSERT(0); 745 746 return str.str(); 747} 748 749bool isIndirectBuffer (const ResourceType type) 750{ 751 switch (type) 752 { 753 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW: 754 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED: 755 case RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH: 756 return true; 757 758 default: 759 return false; 760 } 761} 762 763PipelineCacheData::PipelineCacheData (void) 764{ 765} 766 767PipelineCacheData::~PipelineCacheData (void) 768{ 769} 770 771vk::Move<VkPipelineCache> PipelineCacheData::createPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device) const 772{ 773 const de::ScopedLock dataLock (m_lock); 774 const struct vk::VkPipelineCacheCreateInfo params = 775 { 776 vk::VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, 777 DE_NULL, 778 (vk::VkPipelineCacheCreateFlags)0, 779 (deUintptr)m_data.size(), 780 (m_data.empty() ? DE_NULL : &m_data[0]) 781 }; 782 783 return vk::createPipelineCache(vk, device, ¶ms); 784} 785 786void PipelineCacheData::setFromPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkPipelineCache pipelineCache) 787{ 788 const de::ScopedLock dataLock (m_lock); 789 deUintptr dataSize = 0; 790 791 VK_CHECK(vk.getPipelineCacheData(device, pipelineCache, &dataSize, DE_NULL)); 792 793 m_data.resize(dataSize); 794 795 if (dataSize > 0) 796 VK_CHECK(vk.getPipelineCacheData(device, pipelineCache, &dataSize, &m_data[0])); 797} 798 799} // synchronization 800} // vkt 801