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 vktSparseResourcesTestsUtil.cpp 21 * \brief Sparse Resources Tests Utility Classes 22 *//*--------------------------------------------------------------------*/ 23 24 #include "vktSparseResourcesTestsUtil.hpp" 25 #include "vkQueryUtil.hpp" 26 #include "vkTypeUtil.hpp" 27 #include "tcuTextureUtil.hpp" 28 29 #include <deMath.h> 30 31 using namespace vk; 32 33 namespace vkt 34 { 35 namespace sparse 36 { 37 38 tcu::UVec3 getShaderGridSize (const ImageType imageType, const tcu::UVec3& imageSize, const deUint32 mipLevel) 39 { 40 const deUint32 mipLevelX = std::max(imageSize.x() >> mipLevel, 1u); 41 const deUint32 mipLevelY = std::max(imageSize.y() >> mipLevel, 1u); 42 const deUint32 mipLevelZ = std::max(imageSize.z() >> mipLevel, 1u); 43 44 switch (imageType) 45 { 46 case IMAGE_TYPE_1D: 47 return tcu::UVec3(mipLevelX, 1u, 1u); 48 49 case IMAGE_TYPE_BUFFER: 50 return tcu::UVec3(imageSize.x(), 1u, 1u); 51 52 case IMAGE_TYPE_1D_ARRAY: 53 return tcu::UVec3(mipLevelX, imageSize.z(), 1u); 54 55 case IMAGE_TYPE_2D: 56 return tcu::UVec3(mipLevelX, mipLevelY, 1u); 57 58 case IMAGE_TYPE_2D_ARRAY: 59 return tcu::UVec3(mipLevelX, mipLevelY, imageSize.z()); 60 61 case IMAGE_TYPE_3D: 62 return tcu::UVec3(mipLevelX, mipLevelY, mipLevelZ); 63 64 case IMAGE_TYPE_CUBE: 65 return tcu::UVec3(mipLevelX, mipLevelY, 6u); 66 67 case IMAGE_TYPE_CUBE_ARRAY: 68 return tcu::UVec3(mipLevelX, mipLevelY, 6u * imageSize.z()); 69 70 default: 71 DE_FATAL("Unknown image type"); 72 return tcu::UVec3(1u, 1u, 1u); 73 } 74 } 75 76 tcu::UVec3 getLayerSize (const ImageType imageType, const tcu::UVec3& imageSize) 77 { 78 switch (imageType) 79 { 80 case IMAGE_TYPE_1D: 81 case IMAGE_TYPE_1D_ARRAY: 82 case IMAGE_TYPE_BUFFER: 83 return tcu::UVec3(imageSize.x(), 1u, 1u); 84 85 case IMAGE_TYPE_2D: 86 case IMAGE_TYPE_2D_ARRAY: 87 case IMAGE_TYPE_CUBE: 88 case IMAGE_TYPE_CUBE_ARRAY: 89 return tcu::UVec3(imageSize.x(), imageSize.y(), 1u); 90 91 case IMAGE_TYPE_3D: 92 return tcu::UVec3(imageSize.x(), imageSize.y(), imageSize.z()); 93 94 default: 95 DE_FATAL("Unknown image type"); 96 return tcu::UVec3(1u, 1u, 1u); 97 } 98 } 99 100 deUint32 getNumLayers (const ImageType imageType, const tcu::UVec3& imageSize) 101 { 102 switch (imageType) 103 { 104 case IMAGE_TYPE_1D: 105 case IMAGE_TYPE_2D: 106 case IMAGE_TYPE_3D: 107 case IMAGE_TYPE_BUFFER: 108 return 1u; 109 110 case IMAGE_TYPE_1D_ARRAY: 111 case IMAGE_TYPE_2D_ARRAY: 112 return imageSize.z(); 113 114 case IMAGE_TYPE_CUBE: 115 return 6u; 116 117 case IMAGE_TYPE_CUBE_ARRAY: 118 return imageSize.z() * 6u; 119 120 default: 121 DE_FATAL("Unknown image type"); 122 return 0u; 123 } 124 } 125 126 deUint32 getNumPixels (const ImageType imageType, const tcu::UVec3& imageSize) 127 { 128 const tcu::UVec3 gridSize = getShaderGridSize(imageType, imageSize); 129 130 return gridSize.x() * gridSize.y() * gridSize.z(); 131 } 132 133 deUint32 getDimensions (const ImageType imageType) 134 { 135 switch (imageType) 136 { 137 case IMAGE_TYPE_1D: 138 case IMAGE_TYPE_BUFFER: 139 return 1u; 140 141 case IMAGE_TYPE_1D_ARRAY: 142 case IMAGE_TYPE_2D: 143 return 2u; 144 145 case IMAGE_TYPE_2D_ARRAY: 146 case IMAGE_TYPE_CUBE: 147 case IMAGE_TYPE_CUBE_ARRAY: 148 case IMAGE_TYPE_3D: 149 return 3u; 150 151 default: 152 DE_FATAL("Unknown image type"); 153 return 0u; 154 } 155 } 156 157 deUint32 getLayerDimensions (const ImageType imageType) 158 { 159 switch (imageType) 160 { 161 case IMAGE_TYPE_1D: 162 case IMAGE_TYPE_BUFFER: 163 case IMAGE_TYPE_1D_ARRAY: 164 return 1u; 165 166 case IMAGE_TYPE_2D: 167 case IMAGE_TYPE_2D_ARRAY: 168 case IMAGE_TYPE_CUBE: 169 case IMAGE_TYPE_CUBE_ARRAY: 170 return 2u; 171 172 case IMAGE_TYPE_3D: 173 return 3u; 174 175 default: 176 DE_FATAL("Unknown image type"); 177 return 0u; 178 } 179 } 180 181 bool isImageSizeSupported (const InstanceInterface& instance, const VkPhysicalDevice physicalDevice, const ImageType imageType, const tcu::UVec3& imageSize) 182 { 183 const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice); 184 185 switch (imageType) 186 { 187 case IMAGE_TYPE_1D: 188 return imageSize.x() <= deviceProperties.limits.maxImageDimension1D; 189 case IMAGE_TYPE_1D_ARRAY: 190 return imageSize.x() <= deviceProperties.limits.maxImageDimension1D && 191 imageSize.z() <= deviceProperties.limits.maxImageArrayLayers; 192 case IMAGE_TYPE_2D: 193 return imageSize.x() <= deviceProperties.limits.maxImageDimension2D && 194 imageSize.y() <= deviceProperties.limits.maxImageDimension2D; 195 case IMAGE_TYPE_2D_ARRAY: 196 return imageSize.x() <= deviceProperties.limits.maxImageDimension2D && 197 imageSize.y() <= deviceProperties.limits.maxImageDimension2D && 198 imageSize.z() <= deviceProperties.limits.maxImageArrayLayers; 199 case IMAGE_TYPE_CUBE: 200 return imageSize.x() <= deviceProperties.limits.maxImageDimensionCube && 201 imageSize.y() <= deviceProperties.limits.maxImageDimensionCube; 202 case IMAGE_TYPE_CUBE_ARRAY: 203 return imageSize.x() <= deviceProperties.limits.maxImageDimensionCube && 204 imageSize.y() <= deviceProperties.limits.maxImageDimensionCube && 205 imageSize.z() <= deviceProperties.limits.maxImageArrayLayers; 206 case IMAGE_TYPE_3D: 207 return imageSize.x() <= deviceProperties.limits.maxImageDimension3D && 208 imageSize.y() <= deviceProperties.limits.maxImageDimension3D && 209 imageSize.z() <= deviceProperties.limits.maxImageDimension3D; 210 case IMAGE_TYPE_BUFFER: 211 return true; 212 default: 213 DE_FATAL("Unknown image type"); 214 return false; 215 } 216 } 217 218 VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize bufferSize, 219 const VkBufferUsageFlags usage) 220 { 221 const VkBufferCreateInfo bufferCreateInfo = 222 { 223 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 224 DE_NULL, // const void* pNext; 225 0u, // VkBufferCreateFlags flags; 226 bufferSize, // VkDeviceSize size; 227 usage, // VkBufferUsageFlags usage; 228 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 229 0u, // deUint32 queueFamilyIndexCount; 230 DE_NULL, // const deUint32* pQueueFamilyIndices; 231 }; 232 return bufferCreateInfo; 233 } 234 235 VkBufferImageCopy makeBufferImageCopy (const VkExtent3D extent, 236 const deUint32 layerCount, 237 const deUint32 mipmapLevel, 238 const VkDeviceSize bufferOffset) 239 { 240 const VkBufferImageCopy copyParams = 241 { 242 bufferOffset, // VkDeviceSize bufferOffset; 243 0u, // deUint32 bufferRowLength; 244 0u, // deUint32 bufferImageHeight; 245 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, mipmapLevel, 0u, layerCount), // VkImageSubresourceLayers imageSubresource; 246 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset; 247 extent, // VkExtent3D imageExtent; 248 }; 249 return copyParams; 250 } 251 252 Move<VkCommandPool> makeCommandPool (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex) 253 { 254 const VkCommandPoolCreateInfo commandPoolParams = 255 { 256 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 257 DE_NULL, // const void* pNext; 258 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags; 259 queueFamilyIndex, // deUint32 queueFamilyIndex; 260 }; 261 return createCommandPool(vk, device, &commandPoolParams); 262 } 263 264 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool) 265 { 266 const VkCommandBufferAllocateInfo bufferAllocateParams = 267 { 268 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 269 DE_NULL, // const void* pNext; 270 commandPool, // VkCommandPool commandPool; 271 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; 272 1u, // deUint32 bufferCount; 273 }; 274 return allocateCommandBuffer(vk, device, &bufferAllocateParams); 275 } 276 277 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface& vk, 278 const VkDevice device, 279 const VkDescriptorSetLayout descriptorSetLayout) 280 { 281 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 282 { 283 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 284 DE_NULL, // const void* pNext; 285 0u, // VkPipelineLayoutCreateFlags flags; 286 (descriptorSetLayout != DE_NULL ? 1u : 0u), // deUint32 setLayoutCount; 287 (descriptorSetLayout != DE_NULL ? &descriptorSetLayout : DE_NULL), // const VkDescriptorSetLayout* pSetLayouts; 288 0u, // deUint32 pushConstantRangeCount; 289 DE_NULL, // const VkPushConstantRange* pPushConstantRanges; 290 }; 291 return createPipelineLayout(vk, device, &pipelineLayoutParams); 292 } 293 294 Move<VkPipeline> makeComputePipeline (const DeviceInterface& vk, 295 const VkDevice device, 296 const VkPipelineLayout pipelineLayout, 297 const VkShaderModule shaderModule, 298 const VkSpecializationInfo* specializationInfo) 299 { 300 const VkPipelineShaderStageCreateInfo pipelineShaderStageParams = 301 { 302 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 303 DE_NULL, // const void* pNext; 304 0u, // VkPipelineShaderStageCreateFlags flags; 305 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage; 306 shaderModule, // VkShaderModule module; 307 "main", // const char* pName; 308 specializationInfo, // const VkSpecializationInfo* pSpecializationInfo; 309 }; 310 const VkComputePipelineCreateInfo pipelineCreateInfo = 311 { 312 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType; 313 DE_NULL, // const void* pNext; 314 0u, // VkPipelineCreateFlags flags; 315 pipelineShaderStageParams, // VkPipelineShaderStageCreateInfo stage; 316 pipelineLayout, // VkPipelineLayout layout; 317 DE_NULL, // VkPipeline basePipelineHandle; 318 0, // deInt32 basePipelineIndex; 319 }; 320 return createComputePipeline(vk, device, DE_NULL , &pipelineCreateInfo); 321 } 322 323 Move<VkBufferView> makeBufferView (const DeviceInterface& vk, 324 const VkDevice vkDevice, 325 const VkBuffer buffer, 326 const VkFormat format, 327 const VkDeviceSize offset, 328 const VkDeviceSize size) 329 { 330 const VkBufferViewCreateInfo bufferViewParams = 331 { 332 VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, // VkStructureType sType; 333 DE_NULL, // const void* pNext; 334 0u, // VkBufferViewCreateFlags flags; 335 buffer, // VkBuffer buffer; 336 format, // VkFormat format; 337 offset, // VkDeviceSize offset; 338 size, // VkDeviceSize range; 339 }; 340 return createBufferView(vk, vkDevice, &bufferViewParams); 341 } 342 343 Move<VkImageView> makeImageView (const DeviceInterface& vk, 344 const VkDevice vkDevice, 345 const VkImage image, 346 const VkImageViewType imageViewType, 347 const VkFormat format, 348 const VkImageSubresourceRange subresourceRange) 349 { 350 const VkImageViewCreateInfo imageViewParams = 351 { 352 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 353 DE_NULL, // const void* pNext; 354 0u, // VkImageViewCreateFlags flags; 355 image, // VkImage image; 356 imageViewType, // VkImageViewType viewType; 357 format, // VkFormat format; 358 makeComponentMappingRGBA(), // VkComponentMapping components; 359 subresourceRange, // VkImageSubresourceRange subresourceRange; 360 }; 361 return createImageView(vk, vkDevice, &imageViewParams); 362 } 363 364 Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface& vk, 365 const VkDevice device, 366 const VkDescriptorPool descriptorPool, 367 const VkDescriptorSetLayout setLayout) 368 { 369 const VkDescriptorSetAllocateInfo allocateParams = 370 { 371 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType; 372 DE_NULL, // const void* pNext; 373 descriptorPool, // VkDescriptorPool descriptorPool; 374 1u, // deUint32 setLayoutCount; 375 &setLayout, // const VkDescriptorSetLayout* pSetLayouts; 376 }; 377 return allocateDescriptorSet(vk, device, &allocateParams); 378 } 379 380 Move<VkSemaphore> makeSemaphore (const DeviceInterface& vk, const VkDevice device) 381 { 382 const VkSemaphoreCreateInfo semaphoreCreateInfo = 383 { 384 VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, 385 DE_NULL, 386 0u 387 }; 388 389 return createSemaphore(vk, device, &semaphoreCreateInfo); 390 } 391 392 Move<VkFence> makeFence (const DeviceInterface& vk, const VkDevice device, const VkFenceCreateFlags flags) 393 { 394 const VkFenceCreateInfo fenceCreateInfo = 395 { 396 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; 397 DE_NULL, // const void* pNext; 398 flags, // VkFenceCreateFlags flags; 399 }; 400 return createFence(vk, device, &fenceCreateInfo); 401 } 402 403 Move<VkFramebuffer> makeFramebuffer (const DeviceInterface& vk, 404 const VkDevice device, 405 const VkRenderPass renderPass, 406 const deUint32 attachmentCount, 407 const VkImageView* pAttachments, 408 const deUint32 width, 409 const deUint32 height, 410 const deUint32 layers) 411 { 412 const VkFramebufferCreateInfo framebufferInfo = 413 { 414 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 415 DE_NULL, // const void* pNext; 416 (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags; 417 renderPass, // VkRenderPass renderPass; 418 attachmentCount, // uint32_t attachmentCount; 419 pAttachments, // const VkImageView* pAttachments; 420 width, // uint32_t width; 421 height, // uint32_t height; 422 layers, // uint32_t layers; 423 }; 424 425 return createFramebuffer(vk, device, &framebufferInfo); 426 } 427 428 VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags srcAccessMask, 429 const VkAccessFlags dstAccessMask, 430 const VkBuffer buffer, 431 const VkDeviceSize offset, 432 const VkDeviceSize bufferSizeBytes) 433 { 434 const VkBufferMemoryBarrier barrier = 435 { 436 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 437 DE_NULL, // const void* pNext; 438 srcAccessMask, // VkAccessFlags srcAccessMask; 439 dstAccessMask, // VkAccessFlags dstAccessMask; 440 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 441 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 442 buffer, // VkBuffer buffer; 443 offset, // VkDeviceSize offset; 444 bufferSizeBytes, // VkDeviceSize size; 445 }; 446 return barrier; 447 } 448 449 VkImageMemoryBarrier makeImageMemoryBarrier (const VkAccessFlags srcAccessMask, 450 const VkAccessFlags dstAccessMask, 451 const VkImageLayout oldLayout, 452 const VkImageLayout newLayout, 453 const VkImage image, 454 const VkImageSubresourceRange subresourceRange) 455 { 456 const VkImageMemoryBarrier barrier = 457 { 458 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 459 DE_NULL, // const void* pNext; 460 srcAccessMask, // VkAccessFlags outputMask; 461 dstAccessMask, // VkAccessFlags inputMask; 462 oldLayout, // VkImageLayout oldLayout; 463 newLayout, // VkImageLayout newLayout; 464 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 465 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 466 image, // VkImage image; 467 subresourceRange, // VkImageSubresourceRange subresourceRange; 468 }; 469 return barrier; 470 } 471 472 VkImageMemoryBarrier makeImageMemoryBarrier (const VkAccessFlags srcAccessMask, 473 const VkAccessFlags dstAccessMask, 474 const VkImageLayout oldLayout, 475 const VkImageLayout newLayout, 476 const deUint32 srcQueueFamilyIndex, 477 const deUint32 destQueueFamilyIndex, 478 const VkImage image, 479 const VkImageSubresourceRange subresourceRange) 480 { 481 const VkImageMemoryBarrier barrier = 482 { 483 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 484 DE_NULL, // const void* pNext; 485 srcAccessMask, // VkAccessFlags outputMask; 486 dstAccessMask, // VkAccessFlags inputMask; 487 oldLayout, // VkImageLayout oldLayout; 488 newLayout, // VkImageLayout newLayout; 489 srcQueueFamilyIndex, // deUint32 srcQueueFamilyIndex; 490 destQueueFamilyIndex, // deUint32 destQueueFamilyIndex; 491 image, // VkImage image; 492 subresourceRange, // VkImageSubresourceRange subresourceRange; 493 }; 494 return barrier; 495 } 496 497 VkMemoryBarrier makeMemoryBarrier (const VkAccessFlags srcAccessMask, 498 const VkAccessFlags dstAccessMask) 499 { 500 const VkMemoryBarrier barrier = 501 { 502 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // VkStructureType sType; 503 DE_NULL, // const void* pNext; 504 srcAccessMask, // VkAccessFlags outputMask; 505 dstAccessMask, // VkAccessFlags inputMask; 506 }; 507 return barrier; 508 } 509 510 de::MovePtr<Allocation> bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement) 511 { 512 de::MovePtr<Allocation> alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement); 513 VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset())); 514 return alloc; 515 } 516 517 de::MovePtr<Allocation> bindBuffer (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkBuffer buffer, const MemoryRequirement requirement) 518 { 519 de::MovePtr<Allocation> alloc(allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), requirement)); 520 VK_CHECK(vk.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset())); 521 return alloc; 522 } 523 524 void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer) 525 { 526 const VkCommandBufferBeginInfo commandBufBeginParams = 527 { 528 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 529 DE_NULL, // const void* pNext; 530 0u, // VkCommandBufferUsageFlags flags; 531 (const VkCommandBufferInheritanceInfo*)DE_NULL, 532 }; 533 VK_CHECK(vk.beginCommandBuffer(commandBuffer, &commandBufBeginParams)); 534 } 535 536 void endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer) 537 { 538 VK_CHECK(vk.endCommandBuffer(commandBuffer)); 539 } 540 541 void submitCommands (const DeviceInterface& vk, 542 const VkQueue queue, 543 const VkCommandBuffer commandBuffer, 544 const deUint32 waitSemaphoreCount, 545 const VkSemaphore* pWaitSemaphores, 546 const VkPipelineStageFlags* pWaitDstStageMask, 547 const deUint32 signalSemaphoreCount, 548 const VkSemaphore* pSignalSemaphores) 549 { 550 const VkSubmitInfo submitInfo = 551 { 552 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 553 DE_NULL, // const void* pNext; 554 waitSemaphoreCount, // deUint32 waitSemaphoreCount; 555 pWaitSemaphores, // const VkSemaphore* pWaitSemaphores; 556 pWaitDstStageMask, // const VkPipelineStageFlags* pWaitDstStageMask; 557 1u, // deUint32 commandBufferCount; 558 &commandBuffer, // const VkCommandBuffer* pCommandBuffers; 559 signalSemaphoreCount, // deUint32 signalSemaphoreCount; 560 pSignalSemaphores, // const VkSemaphore* pSignalSemaphores; 561 }; 562 563 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, DE_NULL)); 564 } 565 566 void submitCommandsAndWait (const DeviceInterface& vk, 567 const VkDevice device, 568 const VkQueue queue, 569 const VkCommandBuffer commandBuffer, 570 const deUint32 waitSemaphoreCount, 571 const VkSemaphore* pWaitSemaphores, 572 const VkPipelineStageFlags* pWaitDstStageMask, 573 const deUint32 signalSemaphoreCount, 574 const VkSemaphore* pSignalSemaphores) 575 { 576 const VkFenceCreateInfo fenceParams = 577 { 578 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; 579 DE_NULL, // const void* pNext; 580 0u, // VkFenceCreateFlags flags; 581 }; 582 const Unique<VkFence> fence(createFence(vk, device, &fenceParams)); 583 584 const VkSubmitInfo submitInfo = 585 { 586 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 587 DE_NULL, // const void* pNext; 588 waitSemaphoreCount, // deUint32 waitSemaphoreCount; 589 pWaitSemaphores, // const VkSemaphore* pWaitSemaphores; 590 pWaitDstStageMask, // const VkPipelineStageFlags* pWaitDstStageMask; 591 1u, // deUint32 commandBufferCount; 592 &commandBuffer, // const VkCommandBuffer* pCommandBuffers; 593 signalSemaphoreCount, // deUint32 signalSemaphoreCount; 594 pSignalSemaphores, // const VkSemaphore* pSignalSemaphores; 595 }; 596 597 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence)); 598 VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull)); 599 } 600 601 VkImageType mapImageType (const ImageType imageType) 602 { 603 switch (imageType) 604 { 605 case IMAGE_TYPE_1D: 606 case IMAGE_TYPE_1D_ARRAY: 607 case IMAGE_TYPE_BUFFER: 608 return VK_IMAGE_TYPE_1D; 609 610 case IMAGE_TYPE_2D: 611 case IMAGE_TYPE_2D_ARRAY: 612 case IMAGE_TYPE_CUBE: 613 case IMAGE_TYPE_CUBE_ARRAY: 614 return VK_IMAGE_TYPE_2D; 615 616 case IMAGE_TYPE_3D: 617 return VK_IMAGE_TYPE_3D; 618 619 default: 620 DE_ASSERT(false); 621 return VK_IMAGE_TYPE_LAST; 622 } 623 } 624 625 VkImageViewType mapImageViewType (const ImageType imageType) 626 { 627 switch (imageType) 628 { 629 case IMAGE_TYPE_1D: return VK_IMAGE_VIEW_TYPE_1D; 630 case IMAGE_TYPE_1D_ARRAY: return VK_IMAGE_VIEW_TYPE_1D_ARRAY; 631 case IMAGE_TYPE_2D: return VK_IMAGE_VIEW_TYPE_2D; 632 case IMAGE_TYPE_2D_ARRAY: return VK_IMAGE_VIEW_TYPE_2D_ARRAY; 633 case IMAGE_TYPE_3D: return VK_IMAGE_VIEW_TYPE_3D; 634 case IMAGE_TYPE_CUBE: return VK_IMAGE_VIEW_TYPE_CUBE; 635 case IMAGE_TYPE_CUBE_ARRAY: return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; 636 637 default: 638 DE_ASSERT(false); 639 return VK_IMAGE_VIEW_TYPE_LAST; 640 } 641 } 642 643 std::string getImageTypeName (const ImageType imageType) 644 { 645 switch (imageType) 646 { 647 case IMAGE_TYPE_1D: return "1d"; 648 case IMAGE_TYPE_1D_ARRAY: return "1d_array"; 649 case IMAGE_TYPE_2D: return "2d"; 650 case IMAGE_TYPE_2D_ARRAY: return "2d_array"; 651 case IMAGE_TYPE_3D: return "3d"; 652 case IMAGE_TYPE_CUBE: return "cube"; 653 case IMAGE_TYPE_CUBE_ARRAY: return "cube_array"; 654 case IMAGE_TYPE_BUFFER: return "buffer"; 655 656 default: 657 DE_ASSERT(false); 658 return ""; 659 } 660 } 661 662 std::string getShaderImageType (const tcu::TextureFormat& format, const ImageType imageType) 663 { 664 std::string formatPart = tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ? "u" : 665 tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? "i" : ""; 666 667 std::string imageTypePart; 668 switch (imageType) 669 { 670 case IMAGE_TYPE_1D: imageTypePart = "1D"; break; 671 case IMAGE_TYPE_1D_ARRAY: imageTypePart = "1DArray"; break; 672 case IMAGE_TYPE_2D: imageTypePart = "2D"; break; 673 case IMAGE_TYPE_2D_ARRAY: imageTypePart = "2DArray"; break; 674 case IMAGE_TYPE_3D: imageTypePart = "3D"; break; 675 case IMAGE_TYPE_CUBE: imageTypePart = "Cube"; break; 676 case IMAGE_TYPE_CUBE_ARRAY: imageTypePart = "CubeArray"; break; 677 case IMAGE_TYPE_BUFFER: imageTypePart = "Buffer"; break; 678 679 default: 680 DE_ASSERT(false); 681 } 682 683 return formatPart + "image" + imageTypePart; 684 } 685 686 687 std::string getShaderImageDataType(const tcu::TextureFormat& format) 688 { 689 switch (tcu::getTextureChannelClass(format.type)) 690 { 691 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 692 return "uvec4"; 693 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 694 return "ivec4"; 695 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 696 return "vec4"; 697 default: 698 DE_ASSERT(false); 699 return ""; 700 } 701 } 702 703 704 std::string getShaderImageFormatQualifier (const tcu::TextureFormat& format) 705 { 706 const char* orderPart; 707 const char* typePart; 708 709 switch (format.order) 710 { 711 case tcu::TextureFormat::R: orderPart = "r"; break; 712 case tcu::TextureFormat::RG: orderPart = "rg"; break; 713 case tcu::TextureFormat::RGB: orderPart = "rgb"; break; 714 case tcu::TextureFormat::RGBA: orderPart = "rgba"; break; 715 716 default: 717 DE_ASSERT(false); 718 orderPart = DE_NULL; 719 } 720 721 switch (format.type) 722 { 723 case tcu::TextureFormat::FLOAT: typePart = "32f"; break; 724 case tcu::TextureFormat::HALF_FLOAT: typePart = "16f"; break; 725 726 case tcu::TextureFormat::UNSIGNED_INT32: typePart = "32ui"; break; 727 case tcu::TextureFormat::UNSIGNED_INT16: typePart = "16ui"; break; 728 case tcu::TextureFormat::UNSIGNED_INT8: typePart = "8ui"; break; 729 730 case tcu::TextureFormat::SIGNED_INT32: typePart = "32i"; break; 731 case tcu::TextureFormat::SIGNED_INT16: typePart = "16i"; break; 732 case tcu::TextureFormat::SIGNED_INT8: typePart = "8i"; break; 733 734 case tcu::TextureFormat::UNORM_INT16: typePart = "16"; break; 735 case tcu::TextureFormat::UNORM_INT8: typePart = "8"; break; 736 737 case tcu::TextureFormat::SNORM_INT16: typePart = "16_snorm"; break; 738 case tcu::TextureFormat::SNORM_INT8: typePart = "8_snorm"; break; 739 740 default: 741 DE_ASSERT(false); 742 typePart = DE_NULL; 743 } 744 745 return std::string() + orderPart + typePart; 746 } 747 748 std::string getShaderImageCoordinates (const ImageType imageType, 749 const std::string& x, 750 const std::string& xy, 751 const std::string& xyz) 752 { 753 switch (imageType) 754 { 755 case IMAGE_TYPE_1D: 756 case IMAGE_TYPE_BUFFER: 757 return x; 758 759 case IMAGE_TYPE_1D_ARRAY: 760 case IMAGE_TYPE_2D: 761 return xy; 762 763 case IMAGE_TYPE_2D_ARRAY: 764 case IMAGE_TYPE_3D: 765 case IMAGE_TYPE_CUBE: 766 case IMAGE_TYPE_CUBE_ARRAY: 767 return xyz; 768 769 default: 770 DE_ASSERT(0); 771 return ""; 772 } 773 } 774 775 VkExtent3D mipLevelExtents (const VkExtent3D& baseExtents, const deUint32 mipLevel) 776 { 777 VkExtent3D result; 778 779 result.width = std::max(baseExtents.width >> mipLevel, 1u); 780 result.height = std::max(baseExtents.height >> mipLevel, 1u); 781 result.depth = std::max(baseExtents.depth >> mipLevel, 1u); 782 783 return result; 784 } 785 786 deUint32 getImageMaxMipLevels (const VkImageFormatProperties& imageFormatProperties, const VkExtent3D& extent) 787 { 788 const deUint32 widestEdge = std::max(std::max(extent.width, extent.height), extent.depth); 789 790 return std::min(static_cast<deUint32>(deFloatLog2(static_cast<float>(widestEdge))) + 1u, imageFormatProperties.maxMipLevels); 791 } 792 793 deUint32 getImageMipLevelSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel, const deUint32 mipmapMemoryAlignment) 794 { 795 const VkExtent3D extents = mipLevelExtents(baseExtents, mipmapLevel); 796 797 return deAlign32(extents.width * extents.height * extents.depth * layersCount * tcu::getPixelSize(format), mipmapMemoryAlignment); 798 } 799 800 deUint32 getImageSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevelsCount, const deUint32 mipmapMemoryAlignment) 801 { 802 deUint32 imageSizeInBytes = 0; 803 for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel) 804 imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, format, mipmapLevel, mipmapMemoryAlignment); 805 806 return imageSizeInBytes; 807 } 808 809 VkSparseImageMemoryBind makeSparseImageMemoryBind (const DeviceInterface& vk, 810 const VkDevice device, 811 const VkDeviceSize allocationSize, 812 const deUint32 memoryType, 813 const VkImageSubresource& subresource, 814 const VkOffset3D& offset, 815 const VkExtent3D& extent) 816 { 817 const VkMemoryAllocateInfo allocInfo = 818 { 819 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType; 820 DE_NULL, // const void* pNext; 821 allocationSize, // VkDeviceSize allocationSize; 822 memoryType, // deUint32 memoryTypeIndex; 823 }; 824 825 VkDeviceMemory deviceMemory = 0; 826 VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory)); 827 828 VkSparseImageMemoryBind imageMemoryBind; 829 830 imageMemoryBind.subresource = subresource; 831 imageMemoryBind.memory = deviceMemory; 832 imageMemoryBind.memoryOffset = 0u; 833 imageMemoryBind.flags = 0u; 834 imageMemoryBind.offset = offset; 835 imageMemoryBind.extent = extent; 836 837 return imageMemoryBind; 838 } 839 840 VkSparseMemoryBind makeSparseMemoryBind (const DeviceInterface& vk, 841 const VkDevice device, 842 const VkDeviceSize allocationSize, 843 const deUint32 memoryType, 844 const VkDeviceSize resourceOffset) 845 { 846 const VkMemoryAllocateInfo allocInfo = 847 { 848 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType; 849 DE_NULL, // const void* pNext; 850 allocationSize, // VkDeviceSize allocationSize; 851 memoryType, // deUint32 memoryTypeIndex; 852 }; 853 854 VkDeviceMemory deviceMemory = 0; 855 VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory)); 856 857 VkSparseMemoryBind memoryBind; 858 859 memoryBind.resourceOffset = resourceOffset; 860 memoryBind.size = allocationSize; 861 memoryBind.memory = deviceMemory; 862 memoryBind.memoryOffset = 0u; 863 memoryBind.flags = 0u; 864 865 return memoryBind; 866 } 867 868 void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags) 869 { 870 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice); 871 872 if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader) 873 throw tcu::NotSupportedError("Tessellation shader not supported"); 874 875 if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader) 876 throw tcu::NotSupportedError("Geometry shader not supported"); 877 878 if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64) 879 throw tcu::NotSupportedError("Double-precision floats not supported"); 880 881 if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics) 882 throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline"); 883 884 if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics) 885 throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader"); 886 887 if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize) 888 throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in"); 889 } 890 891 deUint32 findMatchingMemoryType (const InstanceInterface& instance, 892 const VkPhysicalDevice physicalDevice, 893 const VkMemoryRequirements& objectMemoryRequirements, 894 const MemoryRequirement& memoryRequirement) 895 { 896 const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice); 897 898 for (deUint32 memoryTypeNdx = 0; memoryTypeNdx < deviceMemoryProperties.memoryTypeCount; ++memoryTypeNdx) 899 { 900 if ((objectMemoryRequirements.memoryTypeBits & (1u << memoryTypeNdx)) != 0 && 901 memoryRequirement.matchesHeap(deviceMemoryProperties.memoryTypes[memoryTypeNdx].propertyFlags)) 902 { 903 return memoryTypeNdx; 904 } 905 } 906 907 return NO_MATCH_FOUND; 908 } 909 910 bool checkSparseSupportForImageType (const InstanceInterface& instance, 911 const VkPhysicalDevice physicalDevice, 912 const ImageType imageType) 913 { 914 const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(instance, physicalDevice); 915 916 if (!deviceFeatures.sparseBinding) 917 return false; 918 919 switch (mapImageType(imageType)) 920 { 921 case VK_IMAGE_TYPE_2D: 922 return deviceFeatures.sparseResidencyImage2D == VK_TRUE; 923 case VK_IMAGE_TYPE_3D: 924 return deviceFeatures.sparseResidencyImage3D == VK_TRUE; 925 default: 926 DE_ASSERT(0); 927 return false; 928 }; 929 } 930 931 bool checkSparseSupportForImageFormat (const InstanceInterface& instance, 932 const VkPhysicalDevice physicalDevice, 933 const VkImageCreateInfo& imageInfo) 934 { 935 const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec = getPhysicalDeviceSparseImageFormatProperties( 936 instance, physicalDevice, imageInfo.format, imageInfo.imageType, imageInfo.samples, imageInfo.usage, imageInfo.tiling); 937 938 return sparseImageFormatPropVec.size() > 0u; 939 } 940 941 bool checkImageFormatFeatureSupport (const InstanceInterface& instance, 942 const VkPhysicalDevice physicalDevice, 943 const VkFormat format, 944 const VkFormatFeatureFlags featureFlags) 945 { 946 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(instance, physicalDevice, format); 947 948 return (formatProperties.optimalTilingFeatures & featureFlags) == featureFlags; 949 } 950 951 deUint32 getSparseAspectRequirementsIndex (const std::vector<VkSparseImageMemoryRequirements>& requirements, 952 const VkImageAspectFlags aspectFlags) 953 { 954 for (deUint32 memoryReqNdx = 0; memoryReqNdx < requirements.size(); ++memoryReqNdx) 955 { 956 if (requirements[memoryReqNdx].formatProperties.aspectMask & aspectFlags) 957 return memoryReqNdx; 958 } 959 960 return NO_MATCH_FOUND; 961 } 962 963 } // sparse 964 } // vkt 965