1 /*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2017 Google Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief YCbCr format copy tests 22 *//*--------------------------------------------------------------------*/ 23 24 #include "vktYCbCrCopyTests.hpp" 25 26 #include "vktTestCaseUtil.hpp" 27 #include "vktTestGroupUtil.hpp" 28 #include "vktYCbCrUtil.hpp" 29 30 #include "vkQueryUtil.hpp" 31 #include "vkRefUtil.hpp" 32 #include "vkTypeUtil.hpp" 33 34 #include "tcuSeedBuilder.hpp" 35 #include "tcuTestLog.hpp" 36 #include "tcuVector.hpp" 37 #include "tcuVectorUtil.hpp" 38 39 #include "deRandom.hpp" 40 #include "deSTLUtil.hpp" 41 #include "deStringUtil.hpp" 42 43 #include <string> 44 #include <utility> 45 #include <vector> 46 47 using tcu::UVec2; 48 using tcu::Vec4; 49 using tcu::TestLog; 50 51 using std::string; 52 using std::vector; 53 using std::pair; 54 55 namespace vkt 56 { 57 namespace ycbcr 58 { 59 namespace 60 { 61 typedef de::SharedPtr<vk::Allocation> AllocationSp; 62 63 struct ImageConfig 64 { 65 ImageConfig (vk::VkFormat format_, 66 vk::VkImageTiling tiling_, 67 bool disjoint_, 68 const UVec2& size_) 69 : format (format_) 70 , tiling (tiling_) 71 , disjoint (disjoint_) 72 , size (size_) 73 { 74 } 75 76 vk::VkFormat format; 77 vk::VkImageTiling tiling; 78 bool disjoint; 79 UVec2 size; 80 }; 81 82 struct TestConfig 83 { 84 TestConfig (const ImageConfig& src_, 85 const ImageConfig& dst_) 86 : src (src_) 87 , dst (dst_) 88 { 89 } 90 91 ImageConfig src; 92 ImageConfig dst; 93 }; 94 95 void checkSupport (Context& context, const TestConfig& config) 96 { 97 if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), string("VK_KHR_sampler_ycbcr_conversion"))) 98 TCU_THROW(NotSupportedError, "Extension VK_KHR_sampler_ycbcr_conversion not supported"); 99 100 try 101 { 102 const vk::VkFormatProperties properties (vk::getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), config.src.format)); 103 const vk::VkFormatFeatureFlags features (config.src.tiling == vk::VK_IMAGE_TILING_OPTIMAL 104 ? properties.optimalTilingFeatures 105 : properties.linearTilingFeatures); 106 107 if ((features & vk::VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0 108 && (features & vk::VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0) 109 { 110 TCU_THROW(NotSupportedError, "Source format doesn't support copies"); 111 } 112 113 if (config.src.disjoint && ((features & vk::VK_FORMAT_FEATURE_DISJOINT_BIT) == 0)) 114 TCU_THROW(NotSupportedError, "Format doesn'tsupport disjoint planes"); 115 } 116 catch (const vk::Error& err) 117 { 118 if (err.getError() == vk::VK_ERROR_FORMAT_NOT_SUPPORTED) 119 TCU_THROW(NotSupportedError, "Format not supported"); 120 121 throw; 122 } 123 124 try 125 { 126 const vk::VkFormatProperties properties (vk::getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), config.dst.format)); 127 const vk::VkFormatFeatureFlags features (config.dst.tiling == vk::VK_IMAGE_TILING_OPTIMAL 128 ? properties.optimalTilingFeatures 129 : properties.linearTilingFeatures); 130 131 if ((features & vk::VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0 132 && (features & vk::VK_FORMAT_FEATURE_TRANSFER_DST_BIT) == 0) 133 { 134 TCU_THROW(NotSupportedError, "Source format doesn't support copies"); 135 } 136 137 if (config.dst.disjoint && ((features & vk::VK_FORMAT_FEATURE_DISJOINT_BIT) == 0)) 138 TCU_THROW(NotSupportedError, "Format doesn't disjoint planes"); 139 } 140 catch (const vk::Error& err) 141 { 142 if (err.getError() == vk::VK_ERROR_FORMAT_NOT_SUPPORTED) 143 TCU_THROW(NotSupportedError, "Format not supported"); 144 145 throw; 146 } 147 } 148 149 vk::Move<vk::VkImage> createImage (const vk::DeviceInterface& vkd, 150 vk::VkDevice device, 151 vk::VkFormat format, 152 const UVec2& size, 153 bool disjoint, 154 vk::VkImageTiling tiling) 155 { 156 const vk::VkImageCreateInfo createInfo = 157 { 158 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, 159 DE_NULL, 160 disjoint ? (vk::VkImageCreateFlags)vk::VK_IMAGE_CREATE_DISJOINT_BIT : (vk::VkImageCreateFlags)0u, 161 162 vk::VK_IMAGE_TYPE_2D, 163 format, 164 vk::makeExtent3D(size.x(), size.y(), 1u), 165 1u, 166 1u, 167 vk::VK_SAMPLE_COUNT_1_BIT, 168 tiling, 169 vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT, 170 vk::VK_SHARING_MODE_EXCLUSIVE, 171 0u, 172 (const deUint32*)DE_NULL, 173 vk::VK_IMAGE_LAYOUT_UNDEFINED, 174 }; 175 176 return vk::createImage(vkd, device, &createInfo); 177 } 178 179 vk::VkFormat getPlaneCompatibleFormat (vk::VkFormat format, deUint32 planeNdx) 180 { 181 DE_ASSERT(planeNdx < 3); 182 183 switch (format) 184 { 185 case vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: 186 return vk::VK_FORMAT_R8_UNORM; 187 188 case vk::VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: 189 { 190 DE_ASSERT(planeNdx < 2); 191 192 if (planeNdx == 0) 193 return vk::VK_FORMAT_R8_UNORM; 194 else 195 return vk::VK_FORMAT_R8G8_UNORM; 196 } 197 198 case vk::VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM: 199 return vk::VK_FORMAT_R8_UNORM; 200 201 case vk::VK_FORMAT_G8_B8R8_2PLANE_422_UNORM: 202 { 203 DE_ASSERT(planeNdx < 2); 204 205 if (planeNdx == 0) 206 return vk::VK_FORMAT_R8_UNORM; 207 else 208 return vk::VK_FORMAT_R8G8_UNORM; 209 } 210 211 case vk::VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM: 212 return vk::VK_FORMAT_R8_UNORM; 213 214 case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16: 215 return vk::VK_FORMAT_R10X6_UNORM_PACK16; 216 217 case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16: 218 { 219 DE_ASSERT(planeNdx < 2); 220 221 if (planeNdx == 0) 222 return vk::VK_FORMAT_R10X6_UNORM_PACK16; 223 else 224 return vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16; 225 } 226 227 case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16: 228 return vk::VK_FORMAT_R10X6_UNORM_PACK16; 229 230 case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16: 231 { 232 DE_ASSERT(planeNdx < 2); 233 234 if (planeNdx == 0) 235 return vk::VK_FORMAT_R10X6_UNORM_PACK16; 236 else 237 return vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16; 238 } 239 240 case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16: 241 return vk::VK_FORMAT_R10X6_UNORM_PACK16; 242 243 case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16: 244 return vk::VK_FORMAT_R12X4_UNORM_PACK16; 245 246 case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16: 247 { 248 DE_ASSERT(planeNdx < 2); 249 250 if (planeNdx == 0) 251 return vk::VK_FORMAT_R12X4_UNORM_PACK16; 252 else 253 return vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16; 254 } 255 256 case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16: 257 return vk::VK_FORMAT_R12X4_UNORM_PACK16; 258 259 case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16: 260 { 261 DE_ASSERT(planeNdx < 2); 262 263 if (planeNdx == 0) 264 return vk::VK_FORMAT_R12X4_UNORM_PACK16; 265 else 266 return vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16; 267 } 268 269 case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16: 270 return vk::VK_FORMAT_R12X4_UNORM_PACK16; 271 272 case vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM: 273 return vk::VK_FORMAT_R16_UNORM; 274 275 case vk::VK_FORMAT_G16_B16R16_2PLANE_420_UNORM: 276 { 277 DE_ASSERT(planeNdx < 2); 278 279 if (planeNdx == 0) 280 return vk::VK_FORMAT_R16_UNORM; 281 else 282 return vk::VK_FORMAT_R16G16_UNORM; 283 } 284 285 case vk::VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM: 286 return vk::VK_FORMAT_R16_UNORM; 287 288 case vk::VK_FORMAT_G16_B16R16_2PLANE_422_UNORM: 289 { 290 DE_ASSERT(planeNdx < 2); 291 292 if (planeNdx == 0) 293 return vk::VK_FORMAT_R16_UNORM; 294 else 295 return vk::VK_FORMAT_R16G16_UNORM; 296 } 297 298 case vk::VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM: 299 return vk::VK_FORMAT_R16_UNORM; 300 301 default: 302 DE_ASSERT(planeNdx == 0); 303 return format; 304 } 305 } 306 307 bool isCompatible (vk::VkFormat srcFormat, 308 vk::VkFormat dstFormat) 309 { 310 if (srcFormat == dstFormat) 311 return true; 312 else 313 { 314 const vk::VkFormat class8Bit[] = 315 { 316 vk::VK_FORMAT_R4G4_UNORM_PACK8, 317 vk::VK_FORMAT_R8_UNORM, 318 vk::VK_FORMAT_R8_SNORM, 319 vk::VK_FORMAT_R8_USCALED, 320 vk::VK_FORMAT_R8_SSCALED, 321 vk::VK_FORMAT_R8_UINT, 322 vk::VK_FORMAT_R8_SINT, 323 vk::VK_FORMAT_R8_SRGB 324 }; 325 const vk::VkFormat class16Bit[] = 326 { 327 vk::VK_FORMAT_R4G4B4A4_UNORM_PACK16, 328 vk::VK_FORMAT_B4G4R4A4_UNORM_PACK16, 329 vk::VK_FORMAT_R5G6B5_UNORM_PACK16, 330 vk::VK_FORMAT_B5G6R5_UNORM_PACK16, 331 vk::VK_FORMAT_R5G5B5A1_UNORM_PACK16, 332 vk::VK_FORMAT_B5G5R5A1_UNORM_PACK16, 333 vk::VK_FORMAT_A1R5G5B5_UNORM_PACK16, 334 vk::VK_FORMAT_R8G8_UNORM, 335 vk::VK_FORMAT_R8G8_SNORM, 336 vk::VK_FORMAT_R8G8_USCALED, 337 vk::VK_FORMAT_R8G8_SSCALED, 338 vk::VK_FORMAT_R8G8_UINT, 339 vk::VK_FORMAT_R8G8_SINT, 340 vk::VK_FORMAT_R8G8_SRGB, 341 vk::VK_FORMAT_R16_UNORM, 342 vk::VK_FORMAT_R16_SNORM, 343 vk::VK_FORMAT_R16_USCALED, 344 vk::VK_FORMAT_R16_SSCALED, 345 vk::VK_FORMAT_R16_UINT, 346 vk::VK_FORMAT_R16_SINT, 347 vk::VK_FORMAT_R16_SFLOAT, 348 vk::VK_FORMAT_R10X6_UNORM_PACK16, 349 vk::VK_FORMAT_R12X4_UNORM_PACK16 350 }; 351 const vk::VkFormat class24Bit[] = 352 { 353 vk::VK_FORMAT_R8G8B8_UNORM, 354 vk::VK_FORMAT_R8G8B8_SNORM, 355 vk::VK_FORMAT_R8G8B8_USCALED, 356 vk::VK_FORMAT_R8G8B8_SSCALED, 357 vk::VK_FORMAT_R8G8B8_UINT, 358 vk::VK_FORMAT_R8G8B8_SINT, 359 vk::VK_FORMAT_R8G8B8_SRGB, 360 vk::VK_FORMAT_B8G8R8_UNORM, 361 vk::VK_FORMAT_B8G8R8_SNORM, 362 vk::VK_FORMAT_B8G8R8_USCALED, 363 vk::VK_FORMAT_B8G8R8_SSCALED, 364 vk::VK_FORMAT_B8G8R8_UINT, 365 vk::VK_FORMAT_B8G8R8_SINT, 366 vk::VK_FORMAT_B8G8R8_SRGB 367 }; 368 const vk::VkFormat class32Bit[] = 369 { 370 vk::VK_FORMAT_R8G8B8A8_UNORM, 371 vk::VK_FORMAT_R8G8B8A8_SNORM, 372 vk::VK_FORMAT_R8G8B8A8_USCALED, 373 vk::VK_FORMAT_R8G8B8A8_SSCALED, 374 vk::VK_FORMAT_R8G8B8A8_UINT, 375 vk::VK_FORMAT_R8G8B8A8_SINT, 376 vk::VK_FORMAT_R8G8B8A8_SRGB, 377 vk::VK_FORMAT_B8G8R8A8_UNORM, 378 vk::VK_FORMAT_B8G8R8A8_SNORM, 379 vk::VK_FORMAT_B8G8R8A8_USCALED, 380 vk::VK_FORMAT_B8G8R8A8_SSCALED, 381 vk::VK_FORMAT_B8G8R8A8_UINT, 382 vk::VK_FORMAT_B8G8R8A8_SINT, 383 vk::VK_FORMAT_B8G8R8A8_SRGB, 384 vk::VK_FORMAT_A8B8G8R8_UNORM_PACK32, 385 vk::VK_FORMAT_A8B8G8R8_SNORM_PACK32, 386 vk::VK_FORMAT_A8B8G8R8_USCALED_PACK32, 387 vk::VK_FORMAT_A8B8G8R8_SSCALED_PACK32, 388 vk::VK_FORMAT_A8B8G8R8_UINT_PACK32, 389 vk::VK_FORMAT_A8B8G8R8_SINT_PACK32, 390 vk::VK_FORMAT_A8B8G8R8_SRGB_PACK32, 391 vk::VK_FORMAT_A2R10G10B10_UNORM_PACK32, 392 vk::VK_FORMAT_A2R10G10B10_SNORM_PACK32, 393 vk::VK_FORMAT_A2R10G10B10_USCALED_PACK32, 394 vk::VK_FORMAT_A2R10G10B10_SSCALED_PACK32, 395 vk::VK_FORMAT_A2R10G10B10_UINT_PACK32, 396 vk::VK_FORMAT_A2R10G10B10_SINT_PACK32, 397 vk::VK_FORMAT_A2B10G10R10_UNORM_PACK32, 398 vk::VK_FORMAT_A2B10G10R10_SNORM_PACK32, 399 vk::VK_FORMAT_A2B10G10R10_USCALED_PACK32, 400 vk::VK_FORMAT_A2B10G10R10_SSCALED_PACK32, 401 vk::VK_FORMAT_A2B10G10R10_UINT_PACK32, 402 vk::VK_FORMAT_A2B10G10R10_SINT_PACK32, 403 vk::VK_FORMAT_R16G16_UNORM, 404 vk::VK_FORMAT_R16G16_SNORM, 405 vk::VK_FORMAT_R16G16_USCALED, 406 vk::VK_FORMAT_R16G16_SSCALED, 407 vk::VK_FORMAT_R16G16_UINT, 408 vk::VK_FORMAT_R16G16_SINT, 409 vk::VK_FORMAT_R16G16_SFLOAT, 410 vk::VK_FORMAT_R32_UINT, 411 vk::VK_FORMAT_R32_SINT, 412 vk::VK_FORMAT_R32_SFLOAT, 413 vk::VK_FORMAT_B10G11R11_UFLOAT_PACK32, 414 vk::VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, 415 vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16, 416 vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16 417 }; 418 const vk::VkFormat class48Bit[] = 419 { 420 vk::VK_FORMAT_R16G16B16_UNORM, 421 vk::VK_FORMAT_R16G16B16_SNORM, 422 vk::VK_FORMAT_R16G16B16_USCALED, 423 vk::VK_FORMAT_R16G16B16_SSCALED, 424 vk::VK_FORMAT_R16G16B16_UINT, 425 vk::VK_FORMAT_R16G16B16_SINT, 426 vk::VK_FORMAT_R16G16B16_SFLOAT 427 }; 428 const vk::VkFormat class64Bit[] = 429 { 430 vk::VK_FORMAT_R16G16B16A16_UNORM, 431 vk::VK_FORMAT_R16G16B16A16_SNORM, 432 vk::VK_FORMAT_R16G16B16A16_USCALED, 433 vk::VK_FORMAT_R16G16B16A16_SSCALED, 434 vk::VK_FORMAT_R16G16B16A16_UINT, 435 vk::VK_FORMAT_R16G16B16A16_SINT, 436 vk::VK_FORMAT_R16G16B16A16_SFLOAT, 437 vk::VK_FORMAT_R32G32_UINT, 438 vk::VK_FORMAT_R32G32_SINT, 439 vk::VK_FORMAT_R32G32_SFLOAT, 440 vk::VK_FORMAT_R64_UINT, 441 vk::VK_FORMAT_R64_SINT, 442 vk::VK_FORMAT_R64_SFLOAT 443 }; 444 const vk::VkFormat class96Bit[] = 445 { 446 vk::VK_FORMAT_R32G32B32_UINT, 447 vk::VK_FORMAT_R32G32B32_SINT, 448 vk::VK_FORMAT_R32G32B32_SFLOAT 449 }; 450 const vk::VkFormat class128Bit[] = 451 { 452 vk::VK_FORMAT_R32G32B32A32_UINT, 453 vk::VK_FORMAT_R32G32B32A32_SINT, 454 vk::VK_FORMAT_R32G32B32A32_SFLOAT, 455 vk::VK_FORMAT_R64G64_UINT, 456 vk::VK_FORMAT_R64G64_SINT, 457 vk::VK_FORMAT_R64G64_SFLOAT 458 }; 459 const vk::VkFormat class192Bit[] = 460 { 461 vk::VK_FORMAT_R64G64B64_UINT, 462 vk::VK_FORMAT_R64G64B64_SINT, 463 vk::VK_FORMAT_R64G64B64_SFLOAT 464 }; 465 const vk::VkFormat class256Bit[] = 466 { 467 vk::VK_FORMAT_R64G64B64A64_UINT, 468 vk::VK_FORMAT_R64G64B64A64_SINT, 469 vk::VK_FORMAT_R64G64B64A64_SFLOAT 470 }; 471 472 if (de::contains(DE_ARRAY_BEGIN(class8Bit), DE_ARRAY_END(class8Bit), srcFormat) 473 && de::contains(DE_ARRAY_BEGIN(class8Bit), DE_ARRAY_END(class8Bit), dstFormat)) 474 return true; 475 476 if (de::contains(DE_ARRAY_BEGIN(class16Bit), DE_ARRAY_END(class16Bit), srcFormat) 477 && de::contains(DE_ARRAY_BEGIN(class16Bit), DE_ARRAY_END(class16Bit), dstFormat)) 478 return true; 479 480 if (de::contains(DE_ARRAY_BEGIN(class24Bit), DE_ARRAY_END(class24Bit), srcFormat) 481 && de::contains(DE_ARRAY_BEGIN(class24Bit), DE_ARRAY_END(class24Bit), dstFormat)) 482 return true; 483 484 if (de::contains(DE_ARRAY_BEGIN(class32Bit), DE_ARRAY_END(class32Bit), srcFormat) 485 && de::contains(DE_ARRAY_BEGIN(class32Bit), DE_ARRAY_END(class32Bit), dstFormat)) 486 return true; 487 488 if (de::contains(DE_ARRAY_BEGIN(class48Bit), DE_ARRAY_END(class48Bit), srcFormat) 489 && de::contains(DE_ARRAY_BEGIN(class48Bit), DE_ARRAY_END(class48Bit), dstFormat)) 490 return true; 491 492 if (de::contains(DE_ARRAY_BEGIN(class64Bit), DE_ARRAY_END(class64Bit), srcFormat) 493 && de::contains(DE_ARRAY_BEGIN(class64Bit), DE_ARRAY_END(class64Bit), dstFormat)) 494 return true; 495 496 if (de::contains(DE_ARRAY_BEGIN(class96Bit), DE_ARRAY_END(class96Bit), srcFormat) 497 && de::contains(DE_ARRAY_BEGIN(class96Bit), DE_ARRAY_END(class96Bit), dstFormat)) 498 return true; 499 500 if (de::contains(DE_ARRAY_BEGIN(class128Bit), DE_ARRAY_END(class128Bit), srcFormat) 501 && de::contains(DE_ARRAY_BEGIN(class128Bit), DE_ARRAY_END(class128Bit), dstFormat)) 502 return true; 503 504 if (de::contains(DE_ARRAY_BEGIN(class192Bit), DE_ARRAY_END(class192Bit), srcFormat) 505 && de::contains(DE_ARRAY_BEGIN(class192Bit), DE_ARRAY_END(class192Bit), dstFormat)) 506 return true; 507 508 if (de::contains(DE_ARRAY_BEGIN(class256Bit), DE_ARRAY_END(class256Bit), srcFormat) 509 && de::contains(DE_ARRAY_BEGIN(class256Bit), DE_ARRAY_END(class256Bit), dstFormat)) 510 return true; 511 512 return false; 513 } 514 } 515 516 UVec2 getBlockSize (vk::VkFormat format) 517 { 518 switch (format) 519 { 520 case vk::VK_FORMAT_G8B8G8R8_422_UNORM: 521 case vk::VK_FORMAT_B8G8R8G8_422_UNORM: 522 case vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16: 523 case vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16: 524 case vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16: 525 case vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16: 526 case vk::VK_FORMAT_G16B16G16R16_422_UNORM: 527 case vk::VK_FORMAT_B16G16R16G16_422_UNORM: 528 return UVec2(2, 1); 529 530 default: 531 return UVec2(1u, 1u); 532 } 533 } 534 535 deUint32 getBlockByteSize (vk::VkFormat format) 536 { 537 switch (format) 538 { 539 case vk::VK_FORMAT_B8G8R8G8_422_UNORM: 540 case vk::VK_FORMAT_G8B8G8R8_422_UNORM: 541 return 4u; 542 543 case vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16: 544 case vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16: 545 case vk::VK_FORMAT_B16G16R16G16_422_UNORM: 546 case vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16: 547 case vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16: 548 case vk::VK_FORMAT_G16B16G16R16_422_UNORM: 549 case vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16: 550 case vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16: 551 case vk::VK_FORMAT_R16G16B16A16_UNORM: 552 return 4u * 2u; 553 554 case vk::VK_FORMAT_R10X6_UNORM_PACK16: 555 case vk::VK_FORMAT_R12X4_UNORM_PACK16: 556 return 2u; 557 558 case vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16: 559 case vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16: 560 return 2u * 2u; 561 562 case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16: 563 case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16: 564 return 3u * 2u; 565 566 case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16: 567 case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16: 568 case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16: 569 case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16: 570 case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16: 571 case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16: 572 case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16: 573 case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16: 574 case vk::VK_FORMAT_G16_B16R16_2PLANE_420_UNORM: 575 case vk::VK_FORMAT_G16_B16R16_2PLANE_422_UNORM: 576 case vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM: 577 case vk::VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM: 578 case vk::VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM: 579 case vk::VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: 580 case vk::VK_FORMAT_G8_B8R8_2PLANE_422_UNORM: 581 case vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: 582 case vk::VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM: 583 case vk::VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM: 584 DE_FATAL("Plane formats not supported"); 585 return ~0u; 586 587 default: 588 return (deUint32)vk::mapVkFormat(format).getPixelSize(); 589 } 590 } 591 592 UVec2 getPlaneSize (const vk::PlanarFormatDescription& info, 593 deUint32 planeNdx, 594 const UVec2& size) 595 { 596 if (info.numPlanes > 1) 597 return UVec2(size.x() / info.planes[planeNdx].widthDivisor, size.y() / info.planes[planeNdx].heightDivisor); 598 else 599 return size; 600 } 601 602 UVec2 randomUVec2 (de::Random& rng, 603 const UVec2& min, 604 const UVec2& max) 605 { 606 UVec2 result; 607 608 result[0] = min[0] + (rng.getUint32() % (1 + max[0] - min[0])); 609 result[1] = min[1] + (rng.getUint32() % (1 + max[1] - min[1])); 610 611 return result; 612 } 613 614 void genCopies (de::Random& rng, 615 size_t copyCount, 616 vk::VkFormat srcFormat, 617 const UVec2& srcSize, 618 vk::VkFormat dstFormat, 619 const UVec2& dstSize, 620 vector<vk::VkImageCopy>* copies) 621 { 622 vector<pair<deUint32, deUint32> > pairs; 623 const vk::PlanarFormatDescription srcPlaneInfo (vk::getPlanarFormatDescription(srcFormat)); 624 const vk::PlanarFormatDescription dstPlaneInfo (vk::getPlanarFormatDescription(dstFormat)); 625 626 for (deUint32 srcPlaneNdx = 0; srcPlaneNdx < srcPlaneInfo.numPlanes; srcPlaneNdx++) 627 { 628 for (deUint32 dstPlaneNdx = 0; dstPlaneNdx < dstPlaneInfo.numPlanes; dstPlaneNdx++) 629 { 630 const vk::VkFormat srcPlaneFormat (getPlaneCompatibleFormat(srcFormat, srcPlaneNdx)); 631 const vk::VkFormat dstPlaneFormat (getPlaneCompatibleFormat(dstFormat, dstPlaneNdx)); 632 633 if (isCompatible(srcPlaneFormat, dstPlaneFormat)) 634 pairs.push_back(std::make_pair(srcPlaneNdx, dstPlaneNdx)); 635 } 636 } 637 638 DE_ASSERT(!pairs.empty()); 639 640 copies->reserve(copyCount); 641 642 for (size_t copyNdx = 0; copyNdx < copyCount; copyNdx++) 643 { 644 const pair<deUint32, deUint32> planes (rng.choose<pair<deUint32, deUint32> >(pairs.begin(), pairs.end())); 645 646 const deUint32 srcPlaneNdx (planes.first); 647 const vk::VkFormat srcPlaneFormat (getPlaneCompatibleFormat(srcFormat, srcPlaneNdx)); 648 const UVec2 srcBlockSize (getBlockSize(srcPlaneFormat)); 649 const UVec2 srcPlaneSize (getPlaneSize(srcPlaneInfo, srcPlaneNdx, srcSize)); 650 const UVec2 srcPlaneBlockSize (srcPlaneSize / srcBlockSize); 651 652 const deUint32 dstPlaneNdx (planes.second); 653 const vk::VkFormat dstPlaneFormat (getPlaneCompatibleFormat(dstFormat, dstPlaneNdx)); 654 const UVec2 dstBlockSize (getBlockSize(dstPlaneFormat)); 655 const UVec2 dstPlaneSize (getPlaneSize(dstPlaneInfo, dstPlaneNdx, dstSize)); 656 const UVec2 dstPlaneBlockSize (dstPlaneSize / dstBlockSize); 657 658 const UVec2 copyBlockSize (randomUVec2(rng, UVec2(1u, 1u), tcu::min(srcPlaneBlockSize, dstPlaneBlockSize))); 659 const UVec2 srcOffset (srcBlockSize * randomUVec2(rng, UVec2(0u, 0u), srcPlaneBlockSize - copyBlockSize)); 660 const UVec2 dstOffset (dstBlockSize * randomUVec2(rng, UVec2(0u, 0u), dstPlaneBlockSize - copyBlockSize)); 661 const UVec2 copySize (copyBlockSize * srcBlockSize); 662 const vk::VkImageCopy copy = 663 { 664 // src 665 { 666 static_cast<vk::VkImageAspectFlags>(srcPlaneInfo.numPlanes > 1 ? vk::getPlaneAspect(srcPlaneNdx) : vk::VK_IMAGE_ASPECT_COLOR_BIT), 667 0u, 668 0u, 669 1u 670 }, 671 { 672 (deInt32)srcOffset.x(), 673 (deInt32)srcOffset.y(), 674 0, 675 }, 676 // dst 677 { 678 static_cast<vk::VkImageAspectFlags>(dstPlaneInfo.numPlanes > 1 ? vk::getPlaneAspect(dstPlaneNdx) : vk::VK_IMAGE_ASPECT_COLOR_BIT), 679 0u, 680 0u, 681 1u 682 }, 683 { 684 (deInt32)dstOffset.x(), 685 (deInt32)dstOffset.y(), 686 0, 687 }, 688 // size 689 { 690 copySize.x(), 691 copySize.y(), 692 1u 693 } 694 }; 695 696 copies->push_back(copy); 697 } 698 } 699 700 tcu::SeedBuilder& operator<< (tcu::SeedBuilder& builder, const ImageConfig& config) 701 { 702 703 builder << (deUint32)config.format << (deUint32)config.tiling << config.disjoint << config.size[0] << config.size[1]; 704 return builder; 705 } 706 707 deUint32 buildSeed (const TestConfig& config) 708 { 709 tcu::SeedBuilder builder; 710 711 builder << 6792903u << config.src << config.dst; 712 713 return builder.get(); 714 } 715 716 void logImageInfo (TestLog& log, 717 const ImageConfig& config) 718 { 719 log << TestLog::Message << "Format: " << config.format << TestLog::EndMessage; 720 log << TestLog::Message << "Tiling: " << config.tiling << TestLog::EndMessage; 721 log << TestLog::Message << "Size: " << config.size << TestLog::EndMessage; 722 log << TestLog::Message << "Disjoint: " << (config.disjoint ? "true" : "false") << TestLog::EndMessage; 723 } 724 void logTestCaseInfo (TestLog& log, 725 const TestConfig& config, 726 const vector<vk::VkImageCopy>& copies) 727 { 728 { 729 const tcu::ScopedLogSection section (log, "SourceImage", "SourceImage"); 730 logImageInfo(log, config.src); 731 } 732 733 { 734 const tcu::ScopedLogSection section (log, "DestinationImage", "DestinationImage"); 735 logImageInfo(log, config.dst); 736 } 737 { 738 const tcu::ScopedLogSection section (log, "Copies", "Copies"); 739 740 for (size_t copyNdx = 0; copyNdx < copies.size(); copyNdx++) 741 log << TestLog::Message << copies[copyNdx] << TestLog::EndMessage; 742 } 743 } 744 745 tcu::TestStatus imageCopyTest (Context& context, const TestConfig config) 746 { 747 checkSupport(context, config); 748 749 { 750 const size_t copyCount = 10; 751 TestLog& log (context.getTestContext().getLog()); 752 753 MultiPlaneImageData srcData (config.src.format, config.src.size); 754 MultiPlaneImageData dstData (config.dst.format, config.dst.size); 755 MultiPlaneImageData result (config.dst.format, config.dst.size); 756 vector<vk::VkImageCopy> copies; 757 758 de::Random rng (buildSeed(config)); 759 760 genCopies(rng, copyCount, config.src.format, config.src.size, config.dst.format, config.dst.size, &copies); 761 762 logTestCaseInfo(log, config, copies); 763 764 fillRandom(&rng, &srcData); 765 fillRandom(&rng, &dstData); 766 767 { 768 const vk::DeviceInterface& vkd (context.getDeviceInterface()); 769 const vk::VkDevice device (context.getDevice()); 770 771 const vk::Unique<vk::VkImage> srcImage (createImage(vkd, device, config.src.format, config.src.size, config.src.disjoint, config.src.tiling)); 772 const vk::MemoryRequirement srcMemoryRequirement (config.src.tiling == vk::VK_IMAGE_TILING_OPTIMAL 773 ? vk::MemoryRequirement::Any 774 : vk::MemoryRequirement::HostVisible); 775 const vk::VkImageCreateFlags srcCreateFlags (config.src.disjoint ? vk::VK_IMAGE_CREATE_DISJOINT_BIT : (vk::VkImageCreateFlagBits)0u); 776 const vector<AllocationSp> srcImageMemory (allocateAndBindImageMemory(vkd, device, context.getDefaultAllocator(), *srcImage, config.src.format, srcCreateFlags, srcMemoryRequirement)); 777 778 const vk::Unique<vk::VkImage> dstImage (createImage(vkd, device, config.dst.format, config.dst.size, config.dst.disjoint, config.dst.tiling)); 779 const vk::MemoryRequirement dstMemoryRequirement (config.dst.tiling == vk::VK_IMAGE_TILING_OPTIMAL 780 ? vk::MemoryRequirement::Any 781 : vk::MemoryRequirement::HostVisible); 782 const vk::VkImageCreateFlags dstCreateFlags (config.dst.disjoint ? vk::VK_IMAGE_CREATE_DISJOINT_BIT : (vk::VkImageCreateFlagBits)0u); 783 const vector<AllocationSp> dstImageMemory (allocateAndBindImageMemory(vkd, device, context.getDefaultAllocator(), *dstImage, config.dst.format, dstCreateFlags, dstMemoryRequirement)); 784 785 if (config.src.tiling == vk::VK_IMAGE_TILING_OPTIMAL) 786 uploadImage(vkd, device, context.getUniversalQueueFamilyIndex(), context.getDefaultAllocator(), *srcImage, srcData, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); 787 else 788 fillImageMemory(vkd, device, context.getUniversalQueueFamilyIndex(), *srcImage, srcImageMemory, srcData, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); 789 790 if (config.dst.tiling == vk::VK_IMAGE_TILING_OPTIMAL) 791 uploadImage(vkd, device, context.getUniversalQueueFamilyIndex(), context.getDefaultAllocator(), *dstImage, dstData, vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); 792 else 793 fillImageMemory(vkd, device, context.getUniversalQueueFamilyIndex(), *dstImage, dstImageMemory, dstData, vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); 794 795 { 796 const deUint32 queueFamilyNdx (context.getUniversalQueueFamilyIndex()); 797 const vk::VkQueue queue (context.getUniversalQueue()); 798 const vk::Unique<vk::VkCommandPool> cmdPool (createCommandPool(vkd, device, (vk::VkCommandPoolCreateFlags)0, queueFamilyNdx)); 799 const vk::Unique<vk::VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vkd, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY)); 800 { 801 const vk::VkCommandBufferBeginInfo beginInfo = 802 { 803 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 804 DE_NULL, 805 (vk::VkCommandBufferUsageFlags)vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, 806 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL 807 }; 808 809 VK_CHECK(vkd.beginCommandBuffer(*cmdBuffer, &beginInfo)); 810 } 811 812 for (size_t i = 0; i < copies.size(); i++) 813 { 814 vkd.cmdCopyImage(*cmdBuffer, *srcImage, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *dstImage, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copies[i]); 815 816 const vk::VkImageMemoryBarrier preCopyBarrier = 817 { 818 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 819 DE_NULL, 820 vk::VK_ACCESS_TRANSFER_WRITE_BIT, 821 vk::VK_ACCESS_TRANSFER_WRITE_BIT, 822 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 823 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 824 VK_QUEUE_FAMILY_IGNORED, 825 VK_QUEUE_FAMILY_IGNORED, 826 *dstImage, 827 { vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } 828 }; 829 830 vkd.cmdPipelineBarrier(*cmdBuffer, 831 (vk::VkPipelineStageFlags)vk::VK_PIPELINE_STAGE_TRANSFER_BIT, 832 (vk::VkPipelineStageFlags)vk::VK_PIPELINE_STAGE_TRANSFER_BIT, 833 (vk::VkDependencyFlags)0u, 834 0u, 835 (const vk::VkMemoryBarrier*)DE_NULL, 836 0u, 837 (const vk::VkBufferMemoryBarrier*)DE_NULL, 838 1u, 839 &preCopyBarrier); 840 } 841 842 VK_CHECK(vkd.endCommandBuffer(*cmdBuffer)); 843 844 { 845 const vk::Unique<vk::VkFence> fence (createFence(vkd, device)); 846 const vk::VkSubmitInfo submitInfo = 847 { 848 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO, 849 DE_NULL, 850 0u, 851 (const vk::VkSemaphore*)DE_NULL, 852 (const vk::VkPipelineStageFlags*)DE_NULL, 853 1u, 854 &*cmdBuffer, 855 0u, 856 (const vk::VkSemaphore*)DE_NULL, 857 }; 858 859 VK_CHECK(vkd.queueSubmit(queue, 1u, &submitInfo, *fence)); 860 VK_CHECK(vkd.waitForFences(device, 1u, &*fence, VK_TRUE, ~0ull)); 861 } 862 } 863 864 if (config.dst.tiling == vk::VK_IMAGE_TILING_OPTIMAL) 865 downloadImage(vkd, device, context.getUniversalQueueFamilyIndex(), context.getDefaultAllocator(), *dstImage, &result, vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); 866 else 867 readImageMemory(vkd, device, context.getUniversalQueueFamilyIndex(), *dstImage, dstImageMemory, &result, vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); 868 } 869 870 { 871 MultiPlaneImageData reference (dstData); 872 const size_t maxErrorCount = 30; 873 size_t errorCount = 0; 874 875 for (size_t copyNdx = 0; copyNdx < copies.size(); copyNdx++) 876 { 877 const vk::VkImageCopy& copy (copies[copyNdx]); 878 879 const deUint32 srcPlaneNdx (copy.srcSubresource.aspectMask != vk::VK_IMAGE_ASPECT_COLOR_BIT 880 ? vk::getAspectPlaneNdx((vk::VkImageAspectFlagBits)copy.srcSubresource.aspectMask) 881 : 0u); 882 const UVec2 srcPlaneSize (getPlaneSize(srcData.getDescription(), srcPlaneNdx, config.src.size)); 883 884 const vk::VkFormat srcPlaneFormat (getPlaneCompatibleFormat(config.src.format, srcPlaneNdx)); 885 const UVec2 srcBlockSize (getBlockSize(srcPlaneFormat)); 886 887 const deUint32 blockSizeBytes (getBlockByteSize(srcPlaneFormat)); 888 889 const UVec2 srcPlaneBlockSize (srcPlaneSize / srcBlockSize); 890 const UVec2 srcBlockOffset (copy.srcOffset.x / srcBlockSize.x(), copy.srcOffset.y / srcBlockSize.y()); 891 const UVec2 srcBlockPitch (blockSizeBytes, blockSizeBytes * srcPlaneBlockSize.x()); 892 893 const deUint32 dstPlaneNdx (copy.dstSubresource.aspectMask != vk::VK_IMAGE_ASPECT_COLOR_BIT 894 ? vk::getAspectPlaneNdx((vk::VkImageAspectFlagBits)copy.dstSubresource.aspectMask) 895 : 0u); 896 const UVec2 dstPlaneSize (getPlaneSize(dstData.getDescription(), dstPlaneNdx, config.dst.size)); 897 898 const vk::VkFormat dstPlaneFormat (getPlaneCompatibleFormat(config.dst.format, dstPlaneNdx)); 899 const UVec2 dstBlockSize (getBlockSize(dstPlaneFormat)); 900 901 const UVec2 dstPlaneBlockSize (dstPlaneSize / dstBlockSize); 902 const UVec2 dstBlockOffset (copy.dstOffset.x / dstBlockSize.x(), copy.dstOffset.y / dstBlockSize.y()); 903 const UVec2 dstBlockPitch (blockSizeBytes, blockSizeBytes * dstPlaneBlockSize.x()); 904 905 const UVec2 blockSize (copy.extent.width / srcBlockSize.x(), copy.extent.height / srcBlockSize.y()); 906 907 DE_ASSERT(blockSizeBytes == getBlockByteSize(dstPlaneFormat)); 908 909 for (deUint32 y = 0; y < blockSize.y(); y++) 910 { 911 const deUint32 size = blockSize.x() * blockSizeBytes; 912 const deUint32 srcPos = tcu::dot(srcBlockPitch, UVec2(srcBlockOffset.x(), srcBlockOffset.y() + y)); 913 const deUint32 dstPos = tcu::dot(dstBlockPitch, UVec2(dstBlockOffset.x(), dstBlockOffset.y() + y)); 914 915 deMemcpy(((deUint8*)reference.getPlanePtr(dstPlaneNdx)) + dstPos, 916 ((const deUint8*)srcData.getPlanePtr(srcPlaneNdx)) + srcPos, size); 917 } 918 } 919 920 for (deUint32 planeNdx = 0; planeNdx < result.getDescription().numPlanes; ++planeNdx) 921 { 922 for (size_t byteNdx = 0; byteNdx < result.getPlaneSize(planeNdx); byteNdx++) 923 { 924 const deUint8 res = ((const deUint8*)result.getPlanePtr(planeNdx))[byteNdx]; 925 const deUint8 ref = ((const deUint8*)reference.getPlanePtr(planeNdx))[byteNdx]; 926 927 if (res != ref) 928 { 929 log << TestLog::Message << "Plane: " << planeNdx << ", Offset: " << byteNdx << ", Expected: " << (deUint32)ref << ", Got: " << (deUint32)res << TestLog::EndMessage; 930 errorCount++; 931 932 if (errorCount > maxErrorCount) 933 break; 934 } 935 } 936 937 if (errorCount > maxErrorCount) 938 break; 939 } 940 941 if (errorCount > 0) 942 return tcu::TestStatus::fail("Failed, found " + (errorCount > maxErrorCount ? de::toString(maxErrorCount) + "+" : de::toString(errorCount)) + " incorrect bytes"); 943 else 944 return tcu::TestStatus::pass("Pass"); 945 } 946 } 947 } 948 949 bool isCopyCompatible (vk::VkFormat srcFormat, vk::VkFormat dstFormat) 950 { 951 if (isYCbCrFormat(srcFormat) && isYCbCrFormat(dstFormat)) 952 { 953 const vk::PlanarFormatDescription srcPlaneInfo (vk::getPlanarFormatDescription(srcFormat)); 954 const vk::PlanarFormatDescription dstPlaneInfo (vk::getPlanarFormatDescription(dstFormat)); 955 956 for (deUint32 srcPlaneNdx = 0; srcPlaneNdx < srcPlaneInfo.numPlanes; srcPlaneNdx++) 957 { 958 for (deUint32 dstPlaneNdx = 0; dstPlaneNdx < dstPlaneInfo.numPlanes; dstPlaneNdx++) 959 { 960 const vk::VkFormat srcPlaneFormat (getPlaneCompatibleFormat(srcFormat, srcPlaneNdx)); 961 const vk::VkFormat dstPlaneFormat (getPlaneCompatibleFormat(dstFormat, dstPlaneNdx)); 962 963 if (isCompatible(srcPlaneFormat, dstPlaneFormat)) 964 return true; 965 } 966 } 967 } 968 else if (isYCbCrFormat(srcFormat)) 969 { 970 const vk::PlanarFormatDescription srcPlaneInfo (vk::getPlanarFormatDescription(srcFormat)); 971 972 for (deUint32 srcPlaneNdx = 0; srcPlaneNdx < srcPlaneInfo.numPlanes; srcPlaneNdx++) 973 { 974 const vk::VkFormat srcPlaneFormat (getPlaneCompatibleFormat(srcFormat, srcPlaneNdx)); 975 976 if (isCompatible(srcPlaneFormat, dstFormat)) 977 return true; 978 } 979 } 980 else if (isYCbCrFormat(dstFormat)) 981 { 982 const vk::PlanarFormatDescription dstPlaneInfo (vk::getPlanarFormatDescription(dstFormat)); 983 984 for (deUint32 dstPlaneNdx = 0; dstPlaneNdx < dstPlaneInfo.numPlanes; dstPlaneNdx++) 985 { 986 const vk::VkFormat dstPlaneFormat (getPlaneCompatibleFormat(dstFormat, dstPlaneNdx)); 987 988 if (isCompatible(dstPlaneFormat, srcFormat)) 989 return true; 990 } 991 } 992 else 993 return isCompatible(srcFormat, dstFormat); 994 995 return false; 996 } 997 998 void initTests (tcu::TestCaseGroup* testGroup) 999 { 1000 const vk::VkFormat ycbcrFormats[] = 1001 { 1002 vk::VK_FORMAT_R4G4_UNORM_PACK8, 1003 vk::VK_FORMAT_R4G4B4A4_UNORM_PACK16, 1004 vk::VK_FORMAT_B4G4R4A4_UNORM_PACK16, 1005 vk::VK_FORMAT_R5G6B5_UNORM_PACK16, 1006 vk::VK_FORMAT_B5G6R5_UNORM_PACK16, 1007 vk::VK_FORMAT_R5G5B5A1_UNORM_PACK16, 1008 vk::VK_FORMAT_B5G5R5A1_UNORM_PACK16, 1009 vk::VK_FORMAT_A1R5G5B5_UNORM_PACK16, 1010 vk::VK_FORMAT_R8_UNORM, 1011 vk::VK_FORMAT_R8G8_UNORM, 1012 vk::VK_FORMAT_R8G8B8_UNORM, 1013 vk::VK_FORMAT_B8G8R8_UNORM, 1014 vk::VK_FORMAT_R8G8B8A8_UNORM, 1015 vk::VK_FORMAT_B8G8R8A8_UNORM, 1016 vk::VK_FORMAT_A8B8G8R8_UNORM_PACK32, 1017 vk::VK_FORMAT_A2R10G10B10_UNORM_PACK32, 1018 vk::VK_FORMAT_R16_UNORM, 1019 vk::VK_FORMAT_R16G16_UNORM, 1020 vk::VK_FORMAT_R16G16B16_UNORM, 1021 vk::VK_FORMAT_R16G16B16A16_UNORM, 1022 vk::VK_FORMAT_B10G11R11_UFLOAT_PACK32, 1023 vk::VK_FORMAT_G8B8G8R8_422_UNORM, 1024 vk::VK_FORMAT_B8G8R8G8_422_UNORM, 1025 vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, 1026 vk::VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, 1027 vk::VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM, 1028 vk::VK_FORMAT_G8_B8R8_2PLANE_422_UNORM, 1029 vk::VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM, 1030 vk::VK_FORMAT_R10X6_UNORM_PACK16, 1031 vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16, 1032 vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16, 1033 vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16, 1034 vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16, 1035 vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16, 1036 vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16, 1037 vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16, 1038 vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16, 1039 vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16, 1040 vk::VK_FORMAT_R12X4_UNORM_PACK16, 1041 vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16, 1042 vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16, 1043 vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16, 1044 vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16, 1045 vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16, 1046 vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16, 1047 vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16, 1048 vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16, 1049 vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16, 1050 vk::VK_FORMAT_G16B16G16R16_422_UNORM, 1051 vk::VK_FORMAT_B16G16R16G16_422_UNORM, 1052 vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM, 1053 vk::VK_FORMAT_G16_B16R16_2PLANE_420_UNORM, 1054 vk::VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM, 1055 vk::VK_FORMAT_G16_B16R16_2PLANE_422_UNORM, 1056 vk::VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM 1057 }; 1058 const struct 1059 { 1060 const char* name; 1061 vk::VkImageTiling value; 1062 } imageTilings[] = 1063 { 1064 { "linear", vk::VK_IMAGE_TILING_LINEAR }, 1065 { "optimal", vk::VK_IMAGE_TILING_OPTIMAL } 1066 }; 1067 tcu::TestContext& testCtx = testGroup->getTestContext(); 1068 1069 for (size_t srcFormatNdx = 0; srcFormatNdx < DE_LENGTH_OF_ARRAY(ycbcrFormats); srcFormatNdx++) 1070 { 1071 const vk::VkFormat srcFormat (ycbcrFormats[srcFormatNdx]); 1072 const UVec2 srcSize (isYCbCrFormat(srcFormat) ? UVec2(24u, 16u) : UVec2(23u, 17u)); 1073 const string srcFormatName (de::toLower(std::string(getFormatName(srcFormat)).substr(10))); 1074 de::MovePtr<tcu::TestCaseGroup> srcFormatGroup (new tcu::TestCaseGroup(testCtx, srcFormatName.c_str(), ("Tests for copies using format " + srcFormatName).c_str())); 1075 1076 for (size_t dstFormatNdx = 0; dstFormatNdx < DE_LENGTH_OF_ARRAY(ycbcrFormats); dstFormatNdx++) 1077 { 1078 const vk::VkFormat dstFormat (ycbcrFormats[dstFormatNdx]); 1079 const UVec2 dstSize (isYCbCrFormat(dstFormat) ? UVec2(24u, 16u) : UVec2(23u, 17u)); 1080 const string dstFormatName (de::toLower(std::string(getFormatName(dstFormat)).substr(10))); 1081 1082 if ((!vk::isYCbCrFormat(srcFormat) && !vk::isYCbCrFormat(dstFormat)) 1083 || !isCopyCompatible(srcFormat, dstFormat)) 1084 continue; 1085 1086 de::MovePtr<tcu::TestCaseGroup> dstFormatGroup (new tcu::TestCaseGroup(testCtx, dstFormatName.c_str(), ("Tests for copies using format " + dstFormatName).c_str())); 1087 1088 for (size_t srcTilingNdx = 0; srcTilingNdx < DE_LENGTH_OF_ARRAY(imageTilings); srcTilingNdx++) 1089 { 1090 const vk::VkImageTiling srcTiling = imageTilings[srcTilingNdx].value; 1091 const char* const srcTilingName = imageTilings[srcTilingNdx].name; 1092 1093 for (size_t dstTilingNdx = 0; dstTilingNdx < DE_LENGTH_OF_ARRAY(imageTilings); dstTilingNdx++) 1094 { 1095 const vk::VkImageTiling dstTiling = imageTilings[dstTilingNdx].value; 1096 const char* const dstTilingName = imageTilings[dstTilingNdx].name; 1097 1098 for (size_t srcDisjointNdx = 0; srcDisjointNdx < 2; srcDisjointNdx++) 1099 for (size_t dstDisjointNdx = 0; dstDisjointNdx < 2; dstDisjointNdx++) 1100 { 1101 const bool srcDisjoint = srcDisjointNdx == 1; 1102 const bool dstDisjoint = dstDisjointNdx == 1; 1103 const TestConfig config (ImageConfig(srcFormat, srcTiling, srcDisjoint, srcSize), ImageConfig(dstFormat, dstTiling, dstDisjoint, dstSize)); 1104 1105 addFunctionCase(dstFormatGroup.get(), string(srcTilingName) + (srcDisjoint ? "_disjoint_" : "_") + string(dstTilingName) + (dstDisjoint ? "_disjoint" : ""), "", imageCopyTest, config); 1106 } 1107 } 1108 } 1109 1110 srcFormatGroup->addChild(dstFormatGroup.release()); 1111 } 1112 1113 testGroup->addChild(srcFormatGroup.release()); 1114 } 1115 } 1116 1117 } // anonymous 1118 1119 tcu::TestCaseGroup* createCopyTests (tcu::TestContext& testCtx) 1120 { 1121 return createTestGroup(testCtx, "copy", "YCbCr Format Copy Tests", initTests); 1122 } 1123 1124 } // ycbcr 1125 } // vkt 1126