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#include "deStringUtil.hpp" 30 31#include <deMath.h> 32 33using namespace vk; 34 35namespace vkt 36{ 37namespace sparse 38{ 39 40bool formatIsR64 (const VkFormat& format) 41{ 42 switch (format) 43 { 44 case VK_FORMAT_R64_SINT: 45 case VK_FORMAT_R64_UINT: 46 return true; 47 default: 48 return false; 49 } 50} 51 52std::vector<TestFormat> getTestFormats (const ImageType& imageType) 53{ 54 std::vector<TestFormat> results = 55 { 56 { VK_FORMAT_R64_SINT }, { VK_FORMAT_R32_SINT }, { VK_FORMAT_R16_SINT }, { VK_FORMAT_R8_SINT }, 57 { VK_FORMAT_R64_UINT }, { VK_FORMAT_R32_UINT }, { VK_FORMAT_R16_UINT }, { VK_FORMAT_R8_UINT }, 58 59 { VK_FORMAT_R16_UNORM }, { VK_FORMAT_R8_UNORM }, 60 { VK_FORMAT_R16_SNORM }, { VK_FORMAT_R8_SNORM }, 61 { VK_FORMAT_R32G32_SINT }, { VK_FORMAT_R16G16_SINT }, { VK_FORMAT_R8G8_SINT }, 62 { VK_FORMAT_R32G32_UINT }, { VK_FORMAT_R16G16_UINT }, { VK_FORMAT_R8G8_UINT }, 63 { VK_FORMAT_R16G16_UNORM }, { VK_FORMAT_R8G8_UNORM }, 64 { VK_FORMAT_R16G16_SNORM }, { VK_FORMAT_R8G8_SNORM }, 65 { VK_FORMAT_R32G32B32A32_SINT }, { VK_FORMAT_R16G16B16A16_SINT }, { VK_FORMAT_R8G8B8A8_SINT }, 66 { VK_FORMAT_R32G32B32A32_UINT }, { VK_FORMAT_R16G16B16A16_UINT }, { VK_FORMAT_R8G8B8A8_UINT }, 67 { VK_FORMAT_R16G16B16A16_UNORM }, { VK_FORMAT_R8G8B8A8_UNORM }, 68 { VK_FORMAT_R16G16B16A16_SNORM }, { VK_FORMAT_R8G8B8A8_SNORM } 69 }; 70 71 if (imageType == IMAGE_TYPE_2D || imageType == IMAGE_TYPE_2D_ARRAY) 72 { 73 std::vector<TestFormat> ycbcrFormats = 74 { 75 { VK_FORMAT_G8B8G8R8_422_UNORM }, 76 { VK_FORMAT_B8G8R8G8_422_UNORM }, 77 { VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM }, 78 { VK_FORMAT_G8_B8R8_2PLANE_420_UNORM }, 79 { VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM }, 80 { VK_FORMAT_G8_B8R8_2PLANE_422_UNORM }, 81 { VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM }, 82 { VK_FORMAT_R10X6_UNORM_PACK16 }, 83 { VK_FORMAT_R10X6G10X6_UNORM_2PACK16 }, 84 { VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 }, 85 { VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16 }, 86 { VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16 }, 87 { VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16 }, 88 { VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 }, 89 { VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16 }, 90 { VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16 }, 91 { VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16 }, 92 { VK_FORMAT_R12X4_UNORM_PACK16 }, 93 { VK_FORMAT_R12X4G12X4_UNORM_2PACK16 }, 94 { VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 }, 95 { VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16 }, 96 { VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16 }, 97 { VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16 }, 98 { VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16 }, 99 { VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16 }, 100 { VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16 }, 101 { VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16 }, 102 { VK_FORMAT_G16B16G16R16_422_UNORM }, 103 { VK_FORMAT_B16G16R16G16_422_UNORM }, 104 { VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM }, 105 { VK_FORMAT_G16_B16R16_2PLANE_420_UNORM }, 106 { VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM }, 107 { VK_FORMAT_G16_B16R16_2PLANE_422_UNORM }, 108 { VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM }, 109 { VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT }, 110 { VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT }, 111 { VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT }, 112 { VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT }, 113 }; 114 std::copy(begin(ycbcrFormats), end(ycbcrFormats), std::back_inserter(results)); 115 } 116 117 return results; 118} 119 120tcu::UVec3 getShaderGridSize (const ImageType imageType, const tcu::UVec3& imageSize, const deUint32 mipLevel) 121{ 122 const deUint32 mipLevelX = std::max(imageSize.x() >> mipLevel, 1u); 123 const deUint32 mipLevelY = std::max(imageSize.y() >> mipLevel, 1u); 124 const deUint32 mipLevelZ = std::max(imageSize.z() >> mipLevel, 1u); 125 126 switch (imageType) 127 { 128 case IMAGE_TYPE_1D: 129 return tcu::UVec3(mipLevelX, 1u, 1u); 130 131 case IMAGE_TYPE_BUFFER: 132 return tcu::UVec3(imageSize.x(), 1u, 1u); 133 134 case IMAGE_TYPE_1D_ARRAY: 135 return tcu::UVec3(mipLevelX, imageSize.z(), 1u); 136 137 case IMAGE_TYPE_2D: 138 return tcu::UVec3(mipLevelX, mipLevelY, 1u); 139 140 case IMAGE_TYPE_2D_ARRAY: 141 return tcu::UVec3(mipLevelX, mipLevelY, imageSize.z()); 142 143 case IMAGE_TYPE_3D: 144 return tcu::UVec3(mipLevelX, mipLevelY, mipLevelZ); 145 146 case IMAGE_TYPE_CUBE: 147 return tcu::UVec3(mipLevelX, mipLevelY, 6u); 148 149 case IMAGE_TYPE_CUBE_ARRAY: 150 return tcu::UVec3(mipLevelX, mipLevelY, 6u * imageSize.z()); 151 152 default: 153 DE_FATAL("Unknown image type"); 154 return tcu::UVec3(1u, 1u, 1u); 155 } 156} 157 158tcu::UVec3 getLayerSize (const ImageType imageType, const tcu::UVec3& imageSize) 159{ 160 switch (imageType) 161 { 162 case IMAGE_TYPE_1D: 163 case IMAGE_TYPE_1D_ARRAY: 164 case IMAGE_TYPE_BUFFER: 165 return tcu::UVec3(imageSize.x(), 1u, 1u); 166 167 case IMAGE_TYPE_2D: 168 case IMAGE_TYPE_2D_ARRAY: 169 case IMAGE_TYPE_CUBE: 170 case IMAGE_TYPE_CUBE_ARRAY: 171 return tcu::UVec3(imageSize.x(), imageSize.y(), 1u); 172 173 case IMAGE_TYPE_3D: 174 return tcu::UVec3(imageSize.x(), imageSize.y(), imageSize.z()); 175 176 default: 177 DE_FATAL("Unknown image type"); 178 return tcu::UVec3(1u, 1u, 1u); 179 } 180} 181 182deUint32 getNumLayers (const ImageType imageType, const tcu::UVec3& imageSize) 183{ 184 switch (imageType) 185 { 186 case IMAGE_TYPE_1D: 187 case IMAGE_TYPE_2D: 188 case IMAGE_TYPE_3D: 189 case IMAGE_TYPE_BUFFER: 190 return 1u; 191 192 case IMAGE_TYPE_1D_ARRAY: 193 case IMAGE_TYPE_2D_ARRAY: 194 return imageSize.z(); 195 196 case IMAGE_TYPE_CUBE: 197 return 6u; 198 199 case IMAGE_TYPE_CUBE_ARRAY: 200 return imageSize.z() * 6u; 201 202 default: 203 DE_FATAL("Unknown image type"); 204 return 0u; 205 } 206} 207 208deUint32 getNumPixels (const ImageType imageType, const tcu::UVec3& imageSize) 209{ 210 const tcu::UVec3 gridSize = getShaderGridSize(imageType, imageSize); 211 212 return gridSize.x() * gridSize.y() * gridSize.z(); 213} 214 215deUint32 getDimensions (const ImageType imageType) 216{ 217 switch (imageType) 218 { 219 case IMAGE_TYPE_1D: 220 case IMAGE_TYPE_BUFFER: 221 return 1u; 222 223 case IMAGE_TYPE_1D_ARRAY: 224 case IMAGE_TYPE_2D: 225 return 2u; 226 227 case IMAGE_TYPE_2D_ARRAY: 228 case IMAGE_TYPE_CUBE: 229 case IMAGE_TYPE_CUBE_ARRAY: 230 case IMAGE_TYPE_3D: 231 return 3u; 232 233 default: 234 DE_FATAL("Unknown image type"); 235 return 0u; 236 } 237} 238 239deUint32 getLayerDimensions (const ImageType imageType) 240{ 241 switch (imageType) 242 { 243 case IMAGE_TYPE_1D: 244 case IMAGE_TYPE_BUFFER: 245 case IMAGE_TYPE_1D_ARRAY: 246 return 1u; 247 248 case IMAGE_TYPE_2D: 249 case IMAGE_TYPE_2D_ARRAY: 250 case IMAGE_TYPE_CUBE: 251 case IMAGE_TYPE_CUBE_ARRAY: 252 return 2u; 253 254 case IMAGE_TYPE_3D: 255 return 3u; 256 257 default: 258 DE_FATAL("Unknown image type"); 259 return 0u; 260 } 261} 262 263bool isImageSizeSupported (const InstanceInterface& instance, const VkPhysicalDevice physicalDevice, const ImageType imageType, const tcu::UVec3& imageSize) 264{ 265 const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice); 266 267 switch (imageType) 268 { 269 case IMAGE_TYPE_1D: 270 return imageSize.x() <= deviceProperties.limits.maxImageDimension1D; 271 case IMAGE_TYPE_1D_ARRAY: 272 return imageSize.x() <= deviceProperties.limits.maxImageDimension1D && 273 imageSize.z() <= deviceProperties.limits.maxImageArrayLayers; 274 case IMAGE_TYPE_2D: 275 return imageSize.x() <= deviceProperties.limits.maxImageDimension2D && 276 imageSize.y() <= deviceProperties.limits.maxImageDimension2D; 277 case IMAGE_TYPE_2D_ARRAY: 278 return imageSize.x() <= deviceProperties.limits.maxImageDimension2D && 279 imageSize.y() <= deviceProperties.limits.maxImageDimension2D && 280 imageSize.z() <= deviceProperties.limits.maxImageArrayLayers; 281 case IMAGE_TYPE_CUBE: 282 return imageSize.x() <= deviceProperties.limits.maxImageDimensionCube && 283 imageSize.y() <= deviceProperties.limits.maxImageDimensionCube; 284 case IMAGE_TYPE_CUBE_ARRAY: 285 return imageSize.x() <= deviceProperties.limits.maxImageDimensionCube && 286 imageSize.y() <= deviceProperties.limits.maxImageDimensionCube && 287 imageSize.z() <= deviceProperties.limits.maxImageArrayLayers; 288 case IMAGE_TYPE_3D: 289 return imageSize.x() <= deviceProperties.limits.maxImageDimension3D && 290 imageSize.y() <= deviceProperties.limits.maxImageDimension3D && 291 imageSize.z() <= deviceProperties.limits.maxImageDimension3D; 292 case IMAGE_TYPE_BUFFER: 293 return true; 294 default: 295 DE_FATAL("Unknown image type"); 296 return false; 297 } 298} 299 300VkBufferImageCopy makeBufferImageCopy (const VkExtent3D extent, 301 const deUint32 layerCount, 302 const deUint32 mipmapLevel, 303 const VkDeviceSize bufferOffset) 304{ 305 const VkBufferImageCopy copyParams = 306 { 307 bufferOffset, // VkDeviceSize bufferOffset; 308 0u, // deUint32 bufferRowLength; 309 0u, // deUint32 bufferImageHeight; 310 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, mipmapLevel, 0u, layerCount), // VkImageSubresourceLayers imageSubresource; 311 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset; 312 extent, // VkExtent3D imageExtent; 313 }; 314 return copyParams; 315} 316 317void submitCommands (const DeviceInterface& vk, 318 const VkQueue queue, 319 const VkCommandBuffer commandBuffer, 320 const deUint32 waitSemaphoreCount, 321 const VkSemaphore* pWaitSemaphores, 322 const VkPipelineStageFlags* pWaitDstStageMask, 323 const deUint32 signalSemaphoreCount, 324 const VkSemaphore* pSignalSemaphores) 325{ 326 const VkSubmitInfo submitInfo = 327 { 328 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 329 DE_NULL, // const void* pNext; 330 waitSemaphoreCount, // deUint32 waitSemaphoreCount; 331 pWaitSemaphores, // const VkSemaphore* pWaitSemaphores; 332 pWaitDstStageMask, // const VkPipelineStageFlags* pWaitDstStageMask; 333 1u, // deUint32 commandBufferCount; 334 &commandBuffer, // const VkCommandBuffer* pCommandBuffers; 335 signalSemaphoreCount, // deUint32 signalSemaphoreCount; 336 pSignalSemaphores, // const VkSemaphore* pSignalSemaphores; 337 }; 338 339 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, DE_NULL)); 340} 341 342void submitCommandsAndWait (const DeviceInterface& vk, 343 const VkDevice device, 344 const VkQueue queue, 345 const VkCommandBuffer commandBuffer, 346 const deUint32 waitSemaphoreCount, 347 const VkSemaphore* pWaitSemaphores, 348 const VkPipelineStageFlags* pWaitDstStageMask, 349 const deUint32 signalSemaphoreCount, 350 const VkSemaphore* pSignalSemaphores, 351 const bool useDeviceGroups, 352 const deUint32 physicalDeviceID) 353{ 354 const VkFenceCreateInfo fenceParams = 355 { 356 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; 357 DE_NULL, // const void* pNext; 358 0u, // VkFenceCreateFlags flags; 359 }; 360 const Unique<VkFence> fence(createFence (vk, device, &fenceParams)); 361 362 const deUint32 deviceMask = 1 << physicalDeviceID; 363 std::vector<deUint32> deviceIndices (waitSemaphoreCount, physicalDeviceID); 364 VkDeviceGroupSubmitInfo deviceGroupSubmitInfo = 365 { 366 VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO, //VkStructureType sType 367 DE_NULL, // const void* pNext 368 waitSemaphoreCount, // uint32_t waitSemaphoreCount 369 deviceIndices.size() ? &deviceIndices[0] : DE_NULL, // const uint32_t* pWaitSemaphoreDeviceIndices 370 1u, // uint32_t commandBufferCount 371 &deviceMask, // const uint32_t* pCommandBufferDeviceMasks 372 0u, // uint32_t signalSemaphoreCount 373 DE_NULL, // const uint32_t* pSignalSemaphoreDeviceIndices 374 }; 375 const VkSubmitInfo submitInfo = 376 { 377 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 378 useDeviceGroups ? &deviceGroupSubmitInfo : DE_NULL, // const void* pNext; 379 waitSemaphoreCount, // deUint32 waitSemaphoreCount; 380 pWaitSemaphores, // const VkSemaphore* pWaitSemaphores; 381 pWaitDstStageMask, // const VkPipelineStageFlags* pWaitDstStageMask; 382 1u, // deUint32 commandBufferCount; 383 &commandBuffer, // const VkCommandBuffer* pCommandBuffers; 384 signalSemaphoreCount, // deUint32 signalSemaphoreCount; 385 pSignalSemaphores, // const VkSemaphore* pSignalSemaphores; 386 }; 387 388 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence)); 389 VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull)); 390} 391 392VkImageType mapImageType (const ImageType imageType) 393{ 394 switch (imageType) 395 { 396 case IMAGE_TYPE_1D: 397 case IMAGE_TYPE_1D_ARRAY: 398 case IMAGE_TYPE_BUFFER: 399 return VK_IMAGE_TYPE_1D; 400 401 case IMAGE_TYPE_2D: 402 case IMAGE_TYPE_2D_ARRAY: 403 case IMAGE_TYPE_CUBE: 404 case IMAGE_TYPE_CUBE_ARRAY: 405 return VK_IMAGE_TYPE_2D; 406 407 case IMAGE_TYPE_3D: 408 return VK_IMAGE_TYPE_3D; 409 410 default: 411 DE_FATAL("Unexpected image type"); 412 return VK_IMAGE_TYPE_LAST; 413 } 414} 415 416VkImageViewType mapImageViewType (const ImageType imageType) 417{ 418 switch (imageType) 419 { 420 case IMAGE_TYPE_1D: return VK_IMAGE_VIEW_TYPE_1D; 421 case IMAGE_TYPE_1D_ARRAY: return VK_IMAGE_VIEW_TYPE_1D_ARRAY; 422 case IMAGE_TYPE_2D: return VK_IMAGE_VIEW_TYPE_2D; 423 case IMAGE_TYPE_2D_ARRAY: return VK_IMAGE_VIEW_TYPE_2D_ARRAY; 424 case IMAGE_TYPE_3D: return VK_IMAGE_VIEW_TYPE_3D; 425 case IMAGE_TYPE_CUBE: return VK_IMAGE_VIEW_TYPE_CUBE; 426 case IMAGE_TYPE_CUBE_ARRAY: return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; 427 428 default: 429 DE_FATAL("Unexpected image type"); 430 return VK_IMAGE_VIEW_TYPE_LAST; 431 } 432} 433 434std::string getImageTypeName (const ImageType imageType) 435{ 436 switch (imageType) 437 { 438 case IMAGE_TYPE_1D: return "1d"; 439 case IMAGE_TYPE_1D_ARRAY: return "1d_array"; 440 case IMAGE_TYPE_2D: return "2d"; 441 case IMAGE_TYPE_2D_ARRAY: return "2d_array"; 442 case IMAGE_TYPE_3D: return "3d"; 443 case IMAGE_TYPE_CUBE: return "cube"; 444 case IMAGE_TYPE_CUBE_ARRAY: return "cube_array"; 445 case IMAGE_TYPE_BUFFER: return "buffer"; 446 447 default: 448 DE_FATAL("Unexpected image type"); 449 return ""; 450 } 451} 452 453std::string getShaderImageType (const tcu::TextureFormat& format, const ImageType imageType) 454{ 455 std::string formatPart = tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ? "u" : 456 tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? "i" : ""; 457 458 std::string imageTypePart; 459 switch (imageType) 460 { 461 case IMAGE_TYPE_1D: imageTypePart = "1D"; break; 462 case IMAGE_TYPE_1D_ARRAY: imageTypePart = "1DArray"; break; 463 case IMAGE_TYPE_2D: imageTypePart = "2D"; break; 464 case IMAGE_TYPE_2D_ARRAY: imageTypePart = "2DArray"; break; 465 case IMAGE_TYPE_3D: imageTypePart = "3D"; break; 466 case IMAGE_TYPE_CUBE: imageTypePart = "Cube"; break; 467 case IMAGE_TYPE_CUBE_ARRAY: imageTypePart = "CubeArray"; break; 468 case IMAGE_TYPE_BUFFER: imageTypePart = "Buffer"; break; 469 470 default: 471 DE_FATAL("Unexpected image type"); 472 } 473 474 return formatPart + "image" + imageTypePart; 475} 476 477std::string getShaderImageType (const vk::PlanarFormatDescription& description, const ImageType imageType) 478{ 479 std::string formatPart; 480 std::string imageTypePart; 481 482 // all PlanarFormatDescription types have at least one channel ( 0 ) and all channel types are the same : 483 switch (description.channels[0].type) 484 { 485 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 486 formatPart = "i"; 487 break; 488 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 489 formatPart = "u"; 490 break; 491 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 492 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 493 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 494 break; 495 496 default: 497 DE_FATAL("Unexpected channel type"); 498 } 499 500 if (formatIsR64(description.planes[0].planeCompatibleFormat)) 501 formatPart += "64"; 502 503 switch (imageType) 504 { 505 case IMAGE_TYPE_1D: imageTypePart = "1D"; break; 506 case IMAGE_TYPE_1D_ARRAY: imageTypePart = "1DArray"; break; 507 case IMAGE_TYPE_2D: imageTypePart = "2D"; break; 508 case IMAGE_TYPE_2D_ARRAY: imageTypePart = "2DArray"; break; 509 case IMAGE_TYPE_3D: imageTypePart = "3D"; break; 510 case IMAGE_TYPE_CUBE: imageTypePart = "Cube"; break; 511 case IMAGE_TYPE_CUBE_ARRAY: imageTypePart = "CubeArray"; break; 512 case IMAGE_TYPE_BUFFER: imageTypePart = "Buffer"; break; 513 514 default: 515 DE_FATAL("Unexpected image type"); 516 } 517 518 return formatPart + "image" + imageTypePart; 519} 520 521std::string getShaderImageDataType(const tcu::TextureFormat& format) 522{ 523 switch (tcu::getTextureChannelClass(format.type)) 524 { 525 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 526 return "uvec4"; 527 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 528 return "ivec4"; 529 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 530 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 531 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 532 return "vec4"; 533 default: 534 DE_FATAL("Unexpected channel type"); 535 return ""; 536 } 537} 538 539std::string getShaderImageDataType (const vk::PlanarFormatDescription& description) 540{ 541 switch (description.channels[0].type) 542 { 543 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 544 return (formatIsR64(description.planes[0].planeCompatibleFormat) ? "u64vec4" : "uvec4"); 545 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 546 return (formatIsR64(description.planes[0].planeCompatibleFormat) ? "i64vec4" : "ivec4"); 547 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 548 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 549 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 550 return "vec4"; 551 default: 552 DE_FATAL("Unexpected channel type"); 553 return ""; 554 } 555} 556 557std::string getShaderImageFormatQualifier (const tcu::TextureFormat& format) 558{ 559 const char* orderPart; 560 const char* typePart; 561 562 switch (format.order) 563 { 564 case tcu::TextureFormat::R: orderPart = "r"; break; 565 case tcu::TextureFormat::RG: orderPart = "rg"; break; 566 case tcu::TextureFormat::RGB: orderPart = "rgb"; break; 567 case tcu::TextureFormat::RGBA: orderPart = "rgba"; break; 568 569 default: 570 DE_FATAL("Unexpected channel order"); 571 orderPart = DE_NULL; 572 } 573 574 switch (format.type) 575 { 576 case tcu::TextureFormat::FLOAT: typePart = "32f"; break; 577 case tcu::TextureFormat::HALF_FLOAT: typePart = "16f"; break; 578 579 case tcu::TextureFormat::UNSIGNED_INT32: typePart = "32ui"; break; 580 case tcu::TextureFormat::UNSIGNED_INT16: typePart = "16ui"; break; 581 case tcu::TextureFormat::UNSIGNED_INT8: typePart = "8ui"; break; 582 583 case tcu::TextureFormat::SIGNED_INT32: typePart = "32i"; break; 584 case tcu::TextureFormat::SIGNED_INT16: typePart = "16i"; break; 585 case tcu::TextureFormat::SIGNED_INT8: typePart = "8i"; break; 586 587 case tcu::TextureFormat::UNORM_INT16: typePart = "16"; break; 588 case tcu::TextureFormat::UNORM_INT8: typePart = "8"; break; 589 590 case tcu::TextureFormat::SNORM_INT16: typePart = "16_snorm"; break; 591 case tcu::TextureFormat::SNORM_INT8: typePart = "8_snorm"; break; 592 593 default: 594 DE_FATAL("Unexpected channel type"); 595 typePart = DE_NULL; 596 } 597 598 return std::string() + orderPart + typePart; 599} 600 601std::string getShaderImageFormatQualifier (VkFormat format) 602{ 603 switch (format) 604 { 605 case VK_FORMAT_R8_SINT: return "r8i"; 606 case VK_FORMAT_R16_SINT: return "r16i"; 607 case VK_FORMAT_R32_SINT: return "r32i"; 608 case VK_FORMAT_R64_SINT: return "r64i"; 609 case VK_FORMAT_R8_UINT: return "r8ui"; 610 case VK_FORMAT_R16_UINT: return "r16ui"; 611 case VK_FORMAT_R32_UINT: return "r32ui"; 612 case VK_FORMAT_R64_UINT: return "r64ui"; 613 case VK_FORMAT_R8_SNORM: return "r8_snorm"; 614 case VK_FORMAT_R16_SNORM: return "r16_snorm"; 615 case VK_FORMAT_R8_UNORM: return "r8"; 616 case VK_FORMAT_R16_UNORM: return "r16"; 617 618 case VK_FORMAT_R8G8_SINT: return "rg8i"; 619 case VK_FORMAT_R16G16_SINT: return "rg16i"; 620 case VK_FORMAT_R32G32_SINT: return "rg32i"; 621 case VK_FORMAT_R8G8_UINT: return "rg8ui"; 622 case VK_FORMAT_R16G16_UINT: return "rg16ui"; 623 case VK_FORMAT_R32G32_UINT: return "rg32ui"; 624 case VK_FORMAT_R8G8_SNORM: return "rg8_snorm"; 625 case VK_FORMAT_R16G16_SNORM: return "rg16_snorm"; 626 case VK_FORMAT_R8G8_UNORM: return "rg8"; 627 case VK_FORMAT_R16G16_UNORM: return "rg16"; 628 629 case VK_FORMAT_R8G8B8A8_SINT: return "rgba8i"; 630 case VK_FORMAT_R16G16B16A16_SINT: return "rgba16i"; 631 case VK_FORMAT_R32G32B32A32_SINT: return "rgba32i"; 632 case VK_FORMAT_R8G8B8A8_UINT: return "rgba8ui"; 633 case VK_FORMAT_R16G16B16A16_UINT: return "rgba16ui"; 634 case VK_FORMAT_R32G32B32A32_UINT: return "rgba32ui"; 635 case VK_FORMAT_R8G8B8A8_SNORM: return "rgba8_snorm"; 636 case VK_FORMAT_R16G16B16A16_SNORM: return "rgba16_snorm"; 637 case VK_FORMAT_R8G8B8A8_UNORM: return "rgba8"; 638 case VK_FORMAT_R16G16B16A16_UNORM: return "rgba16"; 639 640 case VK_FORMAT_G8B8G8R8_422_UNORM: return "rgba8"; 641 case VK_FORMAT_B8G8R8G8_422_UNORM: return "rgba8"; 642 case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: return "rgba8"; 643 case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: return "rgba8"; 644 case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM: return "rgba8"; 645 case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM: return "rgba8"; 646 case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM: return "rgba8"; 647 case VK_FORMAT_R10X6_UNORM_PACK16: return "r16"; 648 case VK_FORMAT_R10X6G10X6_UNORM_2PACK16: return "rg16"; 649 case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16: return "rgba16"; 650 case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16: return "rgba16"; 651 case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16: return "rgba16"; 652 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16: return "rgba16"; 653 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16: return "rgba16"; 654 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16: return "rgba16"; 655 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16: return "rgba16"; 656 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16: return "rgba16"; 657 case VK_FORMAT_R12X4_UNORM_PACK16: return "r16"; 658 case VK_FORMAT_R12X4G12X4_UNORM_2PACK16: return "rg16"; 659 case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16: return "rgba16"; 660 case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16: return "rgba16"; 661 case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16: return "rgba16"; 662 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16: return "rgba16"; 663 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16: return "rgba16"; 664 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16: return "rgba16"; 665 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16: return "rgba16"; 666 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16: return "rgba16"; 667 case VK_FORMAT_G16B16G16R16_422_UNORM: return "rgba16"; 668 case VK_FORMAT_B16G16R16G16_422_UNORM: return "rgba16"; 669 case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM: return "rgba16"; 670 case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM: return "rgba16"; 671 case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM: return "rgba16"; 672 case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM: return "rgba16"; 673 case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM: return "rgba16"; 674 case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT: return "rgba8"; 675 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT:return "rgba16"; 676 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT:return "rgba16"; 677 case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT: return "rgba16"; 678 679 default: 680 DE_FATAL("Unexpected texture format"); 681 return "error"; 682 } 683} 684 685std::string getImageFormatID (VkFormat format) 686{ 687 switch (format) 688 { 689 case VK_FORMAT_R8_SINT: return "r8i"; 690 case VK_FORMAT_R16_SINT: return "r16i"; 691 case VK_FORMAT_R32_SINT: return "r32i"; 692 case VK_FORMAT_R64_SINT: return "r64i"; 693 case VK_FORMAT_R8_UINT: return "r8ui"; 694 case VK_FORMAT_R16_UINT: return "r16ui"; 695 case VK_FORMAT_R32_UINT: return "r32ui"; 696 case VK_FORMAT_R64_UINT: return "r64ui"; 697 case VK_FORMAT_R8_SNORM: return "r8_snorm"; 698 case VK_FORMAT_R16_SNORM: return "r16_snorm"; 699 case VK_FORMAT_R8_UNORM: return "r8"; 700 case VK_FORMAT_R16_UNORM: return "r16"; 701 702 case VK_FORMAT_R8G8_SINT: return "rg8i"; 703 case VK_FORMAT_R16G16_SINT: return "rg16i"; 704 case VK_FORMAT_R32G32_SINT: return "rg32i"; 705 case VK_FORMAT_R8G8_UINT: return "rg8ui"; 706 case VK_FORMAT_R16G16_UINT: return "rg16ui"; 707 case VK_FORMAT_R32G32_UINT: return "rg32ui"; 708 case VK_FORMAT_R8G8_SNORM: return "rg8_snorm"; 709 case VK_FORMAT_R16G16_SNORM: return "rg16_snorm"; 710 case VK_FORMAT_R8G8_UNORM: return "rg8"; 711 case VK_FORMAT_R16G16_UNORM: return "rg16"; 712 713 case VK_FORMAT_R8G8B8A8_SINT: return "rgba8i"; 714 case VK_FORMAT_R16G16B16A16_SINT: return "rgba16i"; 715 case VK_FORMAT_R32G32B32A32_SINT: return "rgba32i"; 716 case VK_FORMAT_R8G8B8A8_UINT: return "rgba8ui"; 717 case VK_FORMAT_R16G16B16A16_UINT: return "rgba16ui"; 718 case VK_FORMAT_R32G32B32A32_UINT: return "rgba32ui"; 719 case VK_FORMAT_R8G8B8A8_SNORM: return "rgba8_snorm"; 720 case VK_FORMAT_R16G16B16A16_SNORM: return "rgba16_snorm"; 721 case VK_FORMAT_R8G8B8A8_UNORM: return "rgba8"; 722 case VK_FORMAT_R16G16B16A16_UNORM: return "rgba16"; 723 724 case VK_FORMAT_G8B8G8R8_422_UNORM: 725 case VK_FORMAT_B8G8R8G8_422_UNORM: 726 case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: 727 case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: 728 case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM: 729 case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM: 730 case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM: 731 case VK_FORMAT_R10X6_UNORM_PACK16: 732 case VK_FORMAT_R10X6G10X6_UNORM_2PACK16: 733 case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16: 734 case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16: 735 case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16: 736 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16: 737 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16: 738 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16: 739 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16: 740 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16: 741 case VK_FORMAT_R12X4_UNORM_PACK16: 742 case VK_FORMAT_R12X4G12X4_UNORM_2PACK16: 743 case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16: 744 case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16: 745 case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16: 746 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16: 747 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16: 748 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16: 749 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16: 750 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16: 751 case VK_FORMAT_G16B16G16R16_422_UNORM: 752 case VK_FORMAT_B16G16R16G16_422_UNORM: 753 case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM: 754 case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM: 755 case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM: 756 case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM: 757 case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM: 758 case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT: 759 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT: 760 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT: 761 case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT: 762#ifndef CTS_USES_VULKANSC 763 case VK_FORMAT_A8_UNORM_KHR: 764#endif // CTS_USES_VULKANSC 765 return de::toLower(std::string(getFormatName(format)).substr(10)); 766 767 default: 768 DE_FATAL("Unexpected texture format"); 769 return "error"; 770 } 771} 772 773std::string getShaderImageCoordinates (const ImageType imageType, 774 const std::string& x, 775 const std::string& xy, 776 const std::string& xyz) 777{ 778 switch (imageType) 779 { 780 case IMAGE_TYPE_1D: 781 case IMAGE_TYPE_BUFFER: 782 return x; 783 784 case IMAGE_TYPE_1D_ARRAY: 785 case IMAGE_TYPE_2D: 786 return xy; 787 788 case IMAGE_TYPE_2D_ARRAY: 789 case IMAGE_TYPE_3D: 790 case IMAGE_TYPE_CUBE: 791 case IMAGE_TYPE_CUBE_ARRAY: 792 return xyz; 793 794 default: 795 DE_FATAL("Unexpected image type"); 796 return ""; 797 } 798} 799 800deUint32 getImageMipLevelSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel, const deUint32 mipmapMemoryAlignment) 801{ 802 const VkExtent3D extents = mipLevelExtents(baseExtents, mipmapLevel); 803 804 return deAlign32(extents.width * extents.height * extents.depth * layersCount * tcu::getPixelSize(format), mipmapMemoryAlignment); 805} 806 807deUint32 getImageSizeInBytes(const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevelsCount, const deUint32 mipmapMemoryAlignment) 808{ 809 deUint32 imageSizeInBytes = 0; 810 for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel) 811 imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, format, mipmapLevel, mipmapMemoryAlignment); 812 813 return imageSizeInBytes; 814} 815 816deUint32 getImageMipLevelSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const vk::PlanarFormatDescription& formatDescription, const deUint32 planeNdx, const deUint32 mipmapLevel, const deUint32 mipmapMemoryAlignment) 817{ 818 return layersCount * getPlaneSizeInBytes(formatDescription, baseExtents, planeNdx, mipmapLevel, mipmapMemoryAlignment); 819} 820 821deUint32 getImageSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const vk::PlanarFormatDescription& formatDescription, const deUint32 planeNdx, const deUint32 mipmapLevelsCount, const deUint32 mipmapMemoryAlignment) 822{ 823 deUint32 imageSizeInBytes = 0; 824 825 for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel) 826 imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, formatDescription, planeNdx, mipmapLevel, mipmapMemoryAlignment); 827 828 return imageSizeInBytes; 829} 830 831VkSparseImageMemoryBind makeSparseImageMemoryBind (const DeviceInterface& vk, 832 const VkDevice device, 833 const VkDeviceSize allocationSize, 834 const deUint32 memoryType, 835 const VkImageSubresource& subresource, 836 const VkOffset3D& offset, 837 const VkExtent3D& extent) 838{ 839 const VkMemoryAllocateInfo allocInfo = 840 { 841 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType; 842 DE_NULL, // const void* pNext; 843 allocationSize, // VkDeviceSize allocationSize; 844 memoryType, // deUint32 memoryTypeIndex; 845 }; 846 847 VkDeviceMemory deviceMemory = 0; 848 VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory)); 849 850 VkSparseImageMemoryBind imageMemoryBind; 851 852 imageMemoryBind.subresource = subresource; 853 imageMemoryBind.memory = deviceMemory; 854 imageMemoryBind.memoryOffset = 0u; 855 imageMemoryBind.flags = 0u; 856 imageMemoryBind.offset = offset; 857 imageMemoryBind.extent = extent; 858 859 return imageMemoryBind; 860} 861 862VkSparseMemoryBind makeSparseMemoryBind (const DeviceInterface& vk, 863 const VkDevice device, 864 const VkDeviceSize allocationSize, 865 const deUint32 memoryType, 866 const VkDeviceSize resourceOffset, 867 const VkSparseMemoryBindFlags flags) 868{ 869 const VkMemoryAllocateInfo allocInfo = 870 { 871 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType; 872 DE_NULL, // const void* pNext; 873 allocationSize, // VkDeviceSize allocationSize; 874 memoryType, // deUint32 memoryTypeIndex; 875 }; 876 877 VkDeviceMemory deviceMemory = 0; 878 VK_CHECK(vk.allocateMemory(device, &allocInfo, DE_NULL, &deviceMemory)); 879 880 VkSparseMemoryBind memoryBind; 881 882 memoryBind.resourceOffset = resourceOffset; 883 memoryBind.size = allocationSize; 884 memoryBind.memory = deviceMemory; 885 memoryBind.memoryOffset = 0u; 886 memoryBind.flags = flags; 887 888 return memoryBind; 889} 890 891void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags) 892{ 893 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice); 894 895 if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader) 896 throw tcu::NotSupportedError("Tessellation shader not supported"); 897 898 if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader) 899 throw tcu::NotSupportedError("Geometry shader not supported"); 900 901 if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64) 902 throw tcu::NotSupportedError("Double-precision floats not supported"); 903 904 if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics) 905 throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline"); 906 907 if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics) 908 throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader"); 909 910 if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize) 911 throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in"); 912} 913 914deUint32 findMatchingMemoryType (const InstanceInterface& instance, 915 const VkPhysicalDevice physicalDevice, 916 const VkMemoryRequirements& objectMemoryRequirements, 917 const MemoryRequirement& memoryRequirement) 918{ 919 const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice); 920 921 for (deUint32 memoryTypeNdx = 0; memoryTypeNdx < deviceMemoryProperties.memoryTypeCount; ++memoryTypeNdx) 922 { 923 if ((objectMemoryRequirements.memoryTypeBits & (1u << memoryTypeNdx)) != 0 && 924 memoryRequirement.matchesHeap(deviceMemoryProperties.memoryTypes[memoryTypeNdx].propertyFlags)) 925 { 926 return memoryTypeNdx; 927 } 928 } 929 930 return NO_MATCH_FOUND; 931} 932 933deUint32 getHeapIndexForMemoryType (const InstanceInterface& instance, 934 const VkPhysicalDevice physicalDevice, 935 const deUint32 memoryType) 936{ 937 const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice); 938 DE_ASSERT(memoryType < deviceMemoryProperties.memoryTypeCount); 939 return deviceMemoryProperties.memoryTypes[memoryType].heapIndex; 940} 941 942bool checkSparseSupportForImageType (const InstanceInterface& instance, 943 const VkPhysicalDevice physicalDevice, 944 const ImageType imageType) 945{ 946 const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(instance, physicalDevice); 947 948 if (!deviceFeatures.sparseBinding) 949 return false; 950 951 switch (mapImageType(imageType)) 952 { 953 case VK_IMAGE_TYPE_2D: 954 return deviceFeatures.sparseResidencyImage2D == VK_TRUE; 955 case VK_IMAGE_TYPE_3D: 956 return deviceFeatures.sparseResidencyImage3D == VK_TRUE; 957 default: 958 DE_FATAL("Unexpected image type"); 959 return false; 960 } 961} 962 963bool checkSparseSupportForImageFormat (const InstanceInterface& instance, 964 const VkPhysicalDevice physicalDevice, 965 const VkImageCreateInfo& imageInfo) 966{ 967 const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec = getPhysicalDeviceSparseImageFormatProperties( 968 instance, physicalDevice, imageInfo.format, imageInfo.imageType, imageInfo.samples, imageInfo.usage, imageInfo.tiling); 969 970 return sparseImageFormatPropVec.size() > 0u; 971} 972 973bool checkImageFormatFeatureSupport (const InstanceInterface& instance, 974 const VkPhysicalDevice physicalDevice, 975 const VkFormat format, 976 const VkFormatFeatureFlags featureFlags) 977{ 978 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(instance, physicalDevice, format); 979 980 return (formatProperties.optimalTilingFeatures & featureFlags) == featureFlags; 981} 982 983deUint32 getSparseAspectRequirementsIndex (const std::vector<VkSparseImageMemoryRequirements>& requirements, 984 const VkImageAspectFlags aspectFlags) 985{ 986 for (deUint32 memoryReqNdx = 0; memoryReqNdx < requirements.size(); ++memoryReqNdx) 987 { 988 if (requirements[memoryReqNdx].formatProperties.aspectMask & aspectFlags) 989 return memoryReqNdx; 990 } 991 992 return NO_MATCH_FOUND; 993} 994 995vk::VkFormat getPlaneCompatibleFormatForWriting(const vk::PlanarFormatDescription& formatInfo, deUint32 planeNdx) 996{ 997 DE_ASSERT(planeNdx < formatInfo.numPlanes); 998 vk::VkFormat result = formatInfo.planes[planeNdx].planeCompatibleFormat; 999 1000 // redirect result for some of the YCbCr image formats 1001 static const std::pair<vk::VkFormat, vk::VkFormat> ycbcrFormats[] = 1002 { 1003 { VK_FORMAT_G8B8G8R8_422_UNORM, VK_FORMAT_R8G8B8A8_UNORM }, 1004 { VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16, VK_FORMAT_R16G16B16A16_UNORM }, 1005 { VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16, VK_FORMAT_R16G16B16A16_UNORM }, 1006 { VK_FORMAT_G16B16G16R16_422_UNORM, VK_FORMAT_R16G16B16A16_UNORM }, 1007 { VK_FORMAT_B8G8R8G8_422_UNORM, VK_FORMAT_R8G8B8A8_UNORM }, 1008 { VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16, VK_FORMAT_R16G16B16A16_UNORM }, 1009 { VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16, VK_FORMAT_R16G16B16A16_UNORM }, 1010 { VK_FORMAT_B16G16R16G16_422_UNORM, VK_FORMAT_R16G16B16A16_UNORM } 1011 }; 1012 auto it = std::find_if(std::begin(ycbcrFormats), std::end(ycbcrFormats), [result](const std::pair<vk::VkFormat, vk::VkFormat>& p) { return p.first == result; }); 1013 if (it != std::end(ycbcrFormats)) 1014 result = it->second; 1015 return result; 1016} 1017 1018bool areLsb6BitsDontCare(vk::VkFormat format) 1019{ 1020 if ((format == vk::VK_FORMAT_R10X6_UNORM_PACK16) || 1021 (format == vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16) || 1022 (format == vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16) || 1023 (format == vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16) || 1024 (format == vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16) || 1025 (format == vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16) || 1026 (format == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16) || 1027 (format == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16) || 1028 (format == vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16) || 1029 (format == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16)) 1030 { 1031 return true; 1032 } 1033 1034 return false; 1035} 1036 1037bool areLsb4BitsDontCare(vk::VkFormat format) 1038{ 1039 if ((format == vk::VK_FORMAT_R12X4_UNORM_PACK16) || 1040 (format == vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16) || 1041 (format == vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16) || 1042 (format == vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16) || 1043 (format == vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16) || 1044 (format == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16) || 1045 (format == vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16) || 1046 (format == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16) || 1047 (format == vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16) || 1048 (format == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16)) 1049 { 1050 return true; 1051 } 1052 1053 return false; 1054} 1055 1056} // sparse 1057} // vkt 1058