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