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 31using namespace vk; 32 33namespace vkt 34{ 35namespace sparse 36{ 37 38tcu::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 76tcu::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 100deUint32 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 126deUint32 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 133deUint32 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 157deUint32 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 181bool 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 218VkBufferCreateInfo 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 235VkBufferImageCopy 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 252Move<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 264Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface& vk, 265 const VkDevice device, 266 const VkDescriptorSetLayout descriptorSetLayout) 267{ 268 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 269 { 270 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 271 DE_NULL, // const void* pNext; 272 0u, // VkPipelineLayoutCreateFlags flags; 273 (descriptorSetLayout != DE_NULL ? 1u : 0u), // deUint32 setLayoutCount; 274 (descriptorSetLayout != DE_NULL ? &descriptorSetLayout : DE_NULL), // const VkDescriptorSetLayout* pSetLayouts; 275 0u, // deUint32 pushConstantRangeCount; 276 DE_NULL, // const VkPushConstantRange* pPushConstantRanges; 277 }; 278 return createPipelineLayout(vk, device, &pipelineLayoutParams); 279} 280 281Move<VkPipeline> makeComputePipeline (const DeviceInterface& vk, 282 const VkDevice device, 283 const VkPipelineLayout pipelineLayout, 284 const VkShaderModule shaderModule, 285 const VkSpecializationInfo* specializationInfo) 286{ 287 const VkPipelineShaderStageCreateInfo pipelineShaderStageParams = 288 { 289 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 290 DE_NULL, // const void* pNext; 291 0u, // VkPipelineShaderStageCreateFlags flags; 292 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage; 293 shaderModule, // VkShaderModule module; 294 "main", // const char* pName; 295 specializationInfo, // const VkSpecializationInfo* pSpecializationInfo; 296 }; 297 const VkComputePipelineCreateInfo pipelineCreateInfo = 298 { 299 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType; 300 DE_NULL, // const void* pNext; 301 0u, // VkPipelineCreateFlags flags; 302 pipelineShaderStageParams, // VkPipelineShaderStageCreateInfo stage; 303 pipelineLayout, // VkPipelineLayout layout; 304 DE_NULL, // VkPipeline basePipelineHandle; 305 0, // deInt32 basePipelineIndex; 306 }; 307 return createComputePipeline(vk, device, DE_NULL , &pipelineCreateInfo); 308} 309 310Move<VkBufferView> makeBufferView (const DeviceInterface& vk, 311 const VkDevice vkDevice, 312 const VkBuffer buffer, 313 const VkFormat format, 314 const VkDeviceSize offset, 315 const VkDeviceSize size) 316{ 317 const VkBufferViewCreateInfo bufferViewParams = 318 { 319 VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, // VkStructureType sType; 320 DE_NULL, // const void* pNext; 321 0u, // VkBufferViewCreateFlags flags; 322 buffer, // VkBuffer buffer; 323 format, // VkFormat format; 324 offset, // VkDeviceSize offset; 325 size, // VkDeviceSize range; 326 }; 327 return createBufferView(vk, vkDevice, &bufferViewParams); 328} 329 330Move<VkImageView> makeImageView (const DeviceInterface& vk, 331 const VkDevice vkDevice, 332 const VkImage image, 333 const VkImageViewType imageViewType, 334 const VkFormat format, 335 const VkImageSubresourceRange subresourceRange) 336{ 337 const VkImageViewCreateInfo imageViewParams = 338 { 339 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 340 DE_NULL, // const void* pNext; 341 0u, // VkImageViewCreateFlags flags; 342 image, // VkImage image; 343 imageViewType, // VkImageViewType viewType; 344 format, // VkFormat format; 345 makeComponentMappingRGBA(), // VkComponentMapping components; 346 subresourceRange, // VkImageSubresourceRange subresourceRange; 347 }; 348 return createImageView(vk, vkDevice, &imageViewParams); 349} 350 351Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface& vk, 352 const VkDevice device, 353 const VkDescriptorPool descriptorPool, 354 const VkDescriptorSetLayout setLayout) 355{ 356 const VkDescriptorSetAllocateInfo allocateParams = 357 { 358 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType; 359 DE_NULL, // const void* pNext; 360 descriptorPool, // VkDescriptorPool descriptorPool; 361 1u, // deUint32 setLayoutCount; 362 &setLayout, // const VkDescriptorSetLayout* pSetLayouts; 363 }; 364 return allocateDescriptorSet(vk, device, &allocateParams); 365} 366 367Move<VkFramebuffer> makeFramebuffer (const DeviceInterface& vk, 368 const VkDevice device, 369 const VkRenderPass renderPass, 370 const deUint32 attachmentCount, 371 const VkImageView* pAttachments, 372 const deUint32 width, 373 const deUint32 height, 374 const deUint32 layers) 375{ 376 const VkFramebufferCreateInfo framebufferInfo = 377 { 378 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 379 DE_NULL, // const void* pNext; 380 (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags; 381 renderPass, // VkRenderPass renderPass; 382 attachmentCount, // uint32_t attachmentCount; 383 pAttachments, // const VkImageView* pAttachments; 384 width, // uint32_t width; 385 height, // uint32_t height; 386 layers, // uint32_t layers; 387 }; 388 389 return createFramebuffer(vk, device, &framebufferInfo); 390} 391 392VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags srcAccessMask, 393 const VkAccessFlags dstAccessMask, 394 const VkBuffer buffer, 395 const VkDeviceSize offset, 396 const VkDeviceSize bufferSizeBytes) 397{ 398 const VkBufferMemoryBarrier barrier = 399 { 400 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 401 DE_NULL, // const void* pNext; 402 srcAccessMask, // VkAccessFlags srcAccessMask; 403 dstAccessMask, // VkAccessFlags dstAccessMask; 404 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 405 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 406 buffer, // VkBuffer buffer; 407 offset, // VkDeviceSize offset; 408 bufferSizeBytes, // VkDeviceSize size; 409 }; 410 return barrier; 411} 412 413VkImageMemoryBarrier makeImageMemoryBarrier (const VkAccessFlags srcAccessMask, 414 const VkAccessFlags dstAccessMask, 415 const VkImageLayout oldLayout, 416 const VkImageLayout newLayout, 417 const VkImage image, 418 const VkImageSubresourceRange subresourceRange) 419{ 420 const VkImageMemoryBarrier barrier = 421 { 422 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 423 DE_NULL, // const void* pNext; 424 srcAccessMask, // VkAccessFlags outputMask; 425 dstAccessMask, // VkAccessFlags inputMask; 426 oldLayout, // VkImageLayout oldLayout; 427 newLayout, // VkImageLayout newLayout; 428 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 429 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 430 image, // VkImage image; 431 subresourceRange, // VkImageSubresourceRange subresourceRange; 432 }; 433 return barrier; 434} 435 436VkImageMemoryBarrier makeImageMemoryBarrier (const VkAccessFlags srcAccessMask, 437 const VkAccessFlags dstAccessMask, 438 const VkImageLayout oldLayout, 439 const VkImageLayout newLayout, 440 const deUint32 srcQueueFamilyIndex, 441 const deUint32 destQueueFamilyIndex, 442 const VkImage image, 443 const VkImageSubresourceRange subresourceRange) 444{ 445 const VkImageMemoryBarrier barrier = 446 { 447 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 448 DE_NULL, // const void* pNext; 449 srcAccessMask, // VkAccessFlags outputMask; 450 dstAccessMask, // VkAccessFlags inputMask; 451 oldLayout, // VkImageLayout oldLayout; 452 newLayout, // VkImageLayout newLayout; 453 srcQueueFamilyIndex, // deUint32 srcQueueFamilyIndex; 454 destQueueFamilyIndex, // deUint32 destQueueFamilyIndex; 455 image, // VkImage image; 456 subresourceRange, // VkImageSubresourceRange subresourceRange; 457 }; 458 return barrier; 459} 460 461VkMemoryBarrier makeMemoryBarrier (const VkAccessFlags srcAccessMask, 462 const VkAccessFlags dstAccessMask) 463{ 464 const VkMemoryBarrier barrier = 465 { 466 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // VkStructureType sType; 467 DE_NULL, // const void* pNext; 468 srcAccessMask, // VkAccessFlags outputMask; 469 dstAccessMask, // VkAccessFlags inputMask; 470 }; 471 return barrier; 472} 473 474de::MovePtr<Allocation> bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement) 475{ 476 de::MovePtr<Allocation> alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement); 477 VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset())); 478 return alloc; 479} 480 481de::MovePtr<Allocation> bindBuffer (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkBuffer buffer, const MemoryRequirement requirement) 482{ 483 de::MovePtr<Allocation> alloc(allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), requirement)); 484 VK_CHECK(vk.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset())); 485 return alloc; 486} 487 488void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer) 489{ 490 const VkCommandBufferBeginInfo commandBufBeginParams = 491 { 492 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 493 DE_NULL, // const void* pNext; 494 0u, // VkCommandBufferUsageFlags flags; 495 (const VkCommandBufferInheritanceInfo*)DE_NULL, 496 }; 497 VK_CHECK(vk.beginCommandBuffer(commandBuffer, &commandBufBeginParams)); 498} 499 500void endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer) 501{ 502 VK_CHECK(vk.endCommandBuffer(commandBuffer)); 503} 504 505void submitCommands (const DeviceInterface& vk, 506 const VkQueue queue, 507 const VkCommandBuffer commandBuffer, 508 const deUint32 waitSemaphoreCount, 509 const VkSemaphore* pWaitSemaphores, 510 const VkPipelineStageFlags* pWaitDstStageMask, 511 const deUint32 signalSemaphoreCount, 512 const VkSemaphore* pSignalSemaphores) 513{ 514 const VkSubmitInfo submitInfo = 515 { 516 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 517 DE_NULL, // const void* pNext; 518 waitSemaphoreCount, // deUint32 waitSemaphoreCount; 519 pWaitSemaphores, // const VkSemaphore* pWaitSemaphores; 520 pWaitDstStageMask, // const VkPipelineStageFlags* pWaitDstStageMask; 521 1u, // deUint32 commandBufferCount; 522 &commandBuffer, // const VkCommandBuffer* pCommandBuffers; 523 signalSemaphoreCount, // deUint32 signalSemaphoreCount; 524 pSignalSemaphores, // const VkSemaphore* pSignalSemaphores; 525 }; 526 527 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, DE_NULL)); 528} 529 530void submitCommandsAndWait (const DeviceInterface& vk, 531 const VkDevice device, 532 const VkQueue queue, 533 const VkCommandBuffer commandBuffer, 534 const deUint32 waitSemaphoreCount, 535 const VkSemaphore* pWaitSemaphores, 536 const VkPipelineStageFlags* pWaitDstStageMask, 537 const deUint32 signalSemaphoreCount, 538 const VkSemaphore* pSignalSemaphores) 539{ 540 const VkFenceCreateInfo fenceParams = 541 { 542 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; 543 DE_NULL, // const void* pNext; 544 0u, // VkFenceCreateFlags flags; 545 }; 546 const Unique<VkFence> fence(createFence(vk, device, &fenceParams)); 547 548 const VkSubmitInfo submitInfo = 549 { 550 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 551 DE_NULL, // const void* pNext; 552 waitSemaphoreCount, // deUint32 waitSemaphoreCount; 553 pWaitSemaphores, // const VkSemaphore* pWaitSemaphores; 554 pWaitDstStageMask, // const VkPipelineStageFlags* pWaitDstStageMask; 555 1u, // deUint32 commandBufferCount; 556 &commandBuffer, // const VkCommandBuffer* pCommandBuffers; 557 signalSemaphoreCount, // deUint32 signalSemaphoreCount; 558 pSignalSemaphores, // const VkSemaphore* pSignalSemaphores; 559 }; 560 561 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence)); 562 VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull)); 563} 564 565VkImageType mapImageType (const ImageType imageType) 566{ 567 switch (imageType) 568 { 569 case IMAGE_TYPE_1D: 570 case IMAGE_TYPE_1D_ARRAY: 571 case IMAGE_TYPE_BUFFER: 572 return VK_IMAGE_TYPE_1D; 573 574 case IMAGE_TYPE_2D: 575 case IMAGE_TYPE_2D_ARRAY: 576 case IMAGE_TYPE_CUBE: 577 case IMAGE_TYPE_CUBE_ARRAY: 578 return VK_IMAGE_TYPE_2D; 579 580 case IMAGE_TYPE_3D: 581 return VK_IMAGE_TYPE_3D; 582 583 default: 584 DE_ASSERT(false); 585 return VK_IMAGE_TYPE_LAST; 586 } 587} 588 589VkImageViewType mapImageViewType (const ImageType imageType) 590{ 591 switch (imageType) 592 { 593 case IMAGE_TYPE_1D: return VK_IMAGE_VIEW_TYPE_1D; 594 case IMAGE_TYPE_1D_ARRAY: return VK_IMAGE_VIEW_TYPE_1D_ARRAY; 595 case IMAGE_TYPE_2D: return VK_IMAGE_VIEW_TYPE_2D; 596 case IMAGE_TYPE_2D_ARRAY: return VK_IMAGE_VIEW_TYPE_2D_ARRAY; 597 case IMAGE_TYPE_3D: return VK_IMAGE_VIEW_TYPE_3D; 598 case IMAGE_TYPE_CUBE: return VK_IMAGE_VIEW_TYPE_CUBE; 599 case IMAGE_TYPE_CUBE_ARRAY: return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; 600 601 default: 602 DE_ASSERT(false); 603 return VK_IMAGE_VIEW_TYPE_LAST; 604 } 605} 606 607std::string getImageTypeName (const ImageType imageType) 608{ 609 switch (imageType) 610 { 611 case IMAGE_TYPE_1D: return "1d"; 612 case IMAGE_TYPE_1D_ARRAY: return "1d_array"; 613 case IMAGE_TYPE_2D: return "2d"; 614 case IMAGE_TYPE_2D_ARRAY: return "2d_array"; 615 case IMAGE_TYPE_3D: return "3d"; 616 case IMAGE_TYPE_CUBE: return "cube"; 617 case IMAGE_TYPE_CUBE_ARRAY: return "cube_array"; 618 case IMAGE_TYPE_BUFFER: return "buffer"; 619 620 default: 621 DE_ASSERT(false); 622 return ""; 623 } 624} 625 626std::string getShaderImageType (const tcu::TextureFormat& format, const ImageType imageType) 627{ 628 std::string formatPart = tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ? "u" : 629 tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? "i" : ""; 630 631 std::string imageTypePart; 632 switch (imageType) 633 { 634 case IMAGE_TYPE_1D: imageTypePart = "1D"; break; 635 case IMAGE_TYPE_1D_ARRAY: imageTypePart = "1DArray"; break; 636 case IMAGE_TYPE_2D: imageTypePart = "2D"; break; 637 case IMAGE_TYPE_2D_ARRAY: imageTypePart = "2DArray"; break; 638 case IMAGE_TYPE_3D: imageTypePart = "3D"; break; 639 case IMAGE_TYPE_CUBE: imageTypePart = "Cube"; break; 640 case IMAGE_TYPE_CUBE_ARRAY: imageTypePart = "CubeArray"; break; 641 case IMAGE_TYPE_BUFFER: imageTypePart = "Buffer"; break; 642 643 default: 644 DE_ASSERT(false); 645 } 646 647 return formatPart + "image" + imageTypePart; 648} 649 650 651std::string getShaderImageDataType(const tcu::TextureFormat& format) 652{ 653 switch (tcu::getTextureChannelClass(format.type)) 654 { 655 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 656 return "uvec4"; 657 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 658 return "ivec4"; 659 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 660 return "vec4"; 661 default: 662 DE_ASSERT(false); 663 return ""; 664 } 665} 666 667 668std::string getShaderImageFormatQualifier (const tcu::TextureFormat& format) 669{ 670 const char* orderPart; 671 const char* typePart; 672 673 switch (format.order) 674 { 675 case tcu::TextureFormat::R: orderPart = "r"; break; 676 case tcu::TextureFormat::RG: orderPart = "rg"; break; 677 case tcu::TextureFormat::RGB: orderPart = "rgb"; break; 678 case tcu::TextureFormat::RGBA: orderPart = "rgba"; break; 679 680 default: 681 DE_ASSERT(false); 682 orderPart = DE_NULL; 683 } 684 685 switch (format.type) 686 { 687 case tcu::TextureFormat::FLOAT: typePart = "32f"; break; 688 case tcu::TextureFormat::HALF_FLOAT: typePart = "16f"; break; 689 690 case tcu::TextureFormat::UNSIGNED_INT32: typePart = "32ui"; break; 691 case tcu::TextureFormat::UNSIGNED_INT16: typePart = "16ui"; break; 692 case tcu::TextureFormat::UNSIGNED_INT8: typePart = "8ui"; break; 693 694 case tcu::TextureFormat::SIGNED_INT32: typePart = "32i"; break; 695 case tcu::TextureFormat::SIGNED_INT16: typePart = "16i"; break; 696 case tcu::TextureFormat::SIGNED_INT8: typePart = "8i"; break; 697 698 case tcu::TextureFormat::UNORM_INT16: typePart = "16"; break; 699 case tcu::TextureFormat::UNORM_INT8: typePart = "8"; break; 700 701 case tcu::TextureFormat::SNORM_INT16: typePart = "16_snorm"; break; 702 case tcu::TextureFormat::SNORM_INT8: typePart = "8_snorm"; break; 703 704 default: 705 DE_ASSERT(false); 706 typePart = DE_NULL; 707 } 708 709 return std::string() + orderPart + typePart; 710} 711 712std::string getShaderImageCoordinates (const ImageType imageType, 713 const std::string& x, 714 const std::string& xy, 715 const std::string& xyz) 716{ 717 switch (imageType) 718 { 719 case IMAGE_TYPE_1D: 720 case IMAGE_TYPE_BUFFER: 721 return x; 722 723 case IMAGE_TYPE_1D_ARRAY: 724 case IMAGE_TYPE_2D: 725 return xy; 726 727 case IMAGE_TYPE_2D_ARRAY: 728 case IMAGE_TYPE_3D: 729 case IMAGE_TYPE_CUBE: 730 case IMAGE_TYPE_CUBE_ARRAY: 731 return xyz; 732 733 default: 734 DE_ASSERT(0); 735 return ""; 736 } 737} 738 739VkExtent3D mipLevelExtents (const VkExtent3D& baseExtents, const deUint32 mipLevel) 740{ 741 VkExtent3D result; 742 743 result.width = std::max(baseExtents.width >> mipLevel, 1u); 744 result.height = std::max(baseExtents.height >> mipLevel, 1u); 745 result.depth = std::max(baseExtents.depth >> mipLevel, 1u); 746 747 return result; 748} 749 750deUint32 getImageMaxMipLevels (const VkImageFormatProperties& imageFormatProperties, const VkExtent3D& extent) 751{ 752 const deUint32 widestEdge = std::max(std::max(extent.width, extent.height), extent.depth); 753 754 return std::min(static_cast<deUint32>(deFloatLog2(static_cast<float>(widestEdge))) + 1u, imageFormatProperties.maxMipLevels); 755} 756 757deUint32 getImageMipLevelSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel, const deUint32 mipmapMemoryAlignment) 758{ 759 const VkExtent3D extents = mipLevelExtents(baseExtents, mipmapLevel); 760 761 return deAlign32(extents.width * extents.height * extents.depth * layersCount * tcu::getPixelSize(format), mipmapMemoryAlignment); 762} 763 764deUint32 getImageSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevelsCount, const deUint32 mipmapMemoryAlignment) 765{ 766 deUint32 imageSizeInBytes = 0; 767 for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel) 768 imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, format, mipmapLevel, mipmapMemoryAlignment); 769 770 return imageSizeInBytes; 771} 772 773VkSparseImageMemoryBind makeSparseImageMemoryBind (const DeviceInterface& vk, 774 const VkDevice device, 775 const VkDeviceSize allocationSize, 776 const deUint32 memoryType, 777 const VkImageSubresource& subresource, 778 const VkOffset3D& offset, 779 const VkExtent3D& extent) 780{ 781 const VkMemoryAllocateInfo allocInfo = 782 { 783 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType; 784 DE_NULL, // const void* pNext; 785 allocationSize, // VkDeviceSize allocationSize; 786 memoryType, // deUint32 memoryTypeIndex; 787 }; 788 789 VkDeviceMemory deviceMemory = 0; 790 VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory)); 791 792 VkSparseImageMemoryBind imageMemoryBind; 793 794 imageMemoryBind.subresource = subresource; 795 imageMemoryBind.memory = deviceMemory; 796 imageMemoryBind.memoryOffset = 0u; 797 imageMemoryBind.flags = 0u; 798 imageMemoryBind.offset = offset; 799 imageMemoryBind.extent = extent; 800 801 return imageMemoryBind; 802} 803 804VkSparseMemoryBind makeSparseMemoryBind (const DeviceInterface& vk, 805 const VkDevice device, 806 const VkDeviceSize allocationSize, 807 const deUint32 memoryType, 808 const VkDeviceSize resourceOffset, 809 const VkSparseMemoryBindFlags flags) 810{ 811 const VkMemoryAllocateInfo allocInfo = 812 { 813 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType; 814 DE_NULL, // const void* pNext; 815 allocationSize, // VkDeviceSize allocationSize; 816 memoryType, // deUint32 memoryTypeIndex; 817 }; 818 819 VkDeviceMemory deviceMemory = 0; 820 VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory)); 821 822 VkSparseMemoryBind memoryBind; 823 824 memoryBind.resourceOffset = resourceOffset; 825 memoryBind.size = allocationSize; 826 memoryBind.memory = deviceMemory; 827 memoryBind.memoryOffset = 0u; 828 memoryBind.flags = flags; 829 830 return memoryBind; 831} 832 833void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags) 834{ 835 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice); 836 837 if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader) 838 throw tcu::NotSupportedError("Tessellation shader not supported"); 839 840 if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader) 841 throw tcu::NotSupportedError("Geometry shader not supported"); 842 843 if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64) 844 throw tcu::NotSupportedError("Double-precision floats not supported"); 845 846 if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics) 847 throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline"); 848 849 if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics) 850 throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader"); 851 852 if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize) 853 throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in"); 854} 855 856deUint32 findMatchingMemoryType (const InstanceInterface& instance, 857 const VkPhysicalDevice physicalDevice, 858 const VkMemoryRequirements& objectMemoryRequirements, 859 const MemoryRequirement& memoryRequirement) 860{ 861 const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice); 862 863 for (deUint32 memoryTypeNdx = 0; memoryTypeNdx < deviceMemoryProperties.memoryTypeCount; ++memoryTypeNdx) 864 { 865 if ((objectMemoryRequirements.memoryTypeBits & (1u << memoryTypeNdx)) != 0 && 866 memoryRequirement.matchesHeap(deviceMemoryProperties.memoryTypes[memoryTypeNdx].propertyFlags)) 867 { 868 return memoryTypeNdx; 869 } 870 } 871 872 return NO_MATCH_FOUND; 873} 874 875bool checkSparseSupportForImageType (const InstanceInterface& instance, 876 const VkPhysicalDevice physicalDevice, 877 const ImageType imageType) 878{ 879 const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(instance, physicalDevice); 880 881 if (!deviceFeatures.sparseBinding) 882 return false; 883 884 switch (mapImageType(imageType)) 885 { 886 case VK_IMAGE_TYPE_2D: 887 return deviceFeatures.sparseResidencyImage2D == VK_TRUE; 888 case VK_IMAGE_TYPE_3D: 889 return deviceFeatures.sparseResidencyImage3D == VK_TRUE; 890 default: 891 DE_ASSERT(0); 892 return false; 893 }; 894} 895 896bool checkSparseSupportForImageFormat (const InstanceInterface& instance, 897 const VkPhysicalDevice physicalDevice, 898 const VkImageCreateInfo& imageInfo) 899{ 900 const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec = getPhysicalDeviceSparseImageFormatProperties( 901 instance, physicalDevice, imageInfo.format, imageInfo.imageType, imageInfo.samples, imageInfo.usage, imageInfo.tiling); 902 903 return sparseImageFormatPropVec.size() > 0u; 904} 905 906bool checkImageFormatFeatureSupport (const InstanceInterface& instance, 907 const VkPhysicalDevice physicalDevice, 908 const VkFormat format, 909 const VkFormatFeatureFlags featureFlags) 910{ 911 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(instance, physicalDevice, format); 912 913 return (formatProperties.optimalTilingFeatures & featureFlags) == featureFlags; 914} 915 916deUint32 getSparseAspectRequirementsIndex (const std::vector<VkSparseImageMemoryRequirements>& requirements, 917 const VkImageAspectFlags aspectFlags) 918{ 919 for (deUint32 memoryReqNdx = 0; memoryReqNdx < requirements.size(); ++memoryReqNdx) 920 { 921 if (requirements[memoryReqNdx].formatProperties.aspectMask & aspectFlags) 922 return memoryReqNdx; 923 } 924 925 return NO_MATCH_FOUND; 926} 927 928} // sparse 929} // vkt 930