| 335 | } |
| 336 | |
| 337 | bool compare(Texture& lhs, Texture& rhs, float tolerance) { |
| 338 | const auto vkFormat = static_cast<VkFormat>(lhs.header.vkFormat); |
| 339 | const auto* bdfd = reinterpret_cast<const uint32_t*>(lhs.dfdData) + 1; |
| 340 | const auto componentCount = KHR_DFDSAMPLECOUNT(bdfd); |
| 341 | const auto texelBlockDimension0 = static_cast<uint8_t>(KHR_DFDVAL(bdfd, TEXELBLOCKDIMENSION0)); |
| 342 | const auto texelBlockDimension1 = static_cast<uint8_t>(KHR_DFDVAL(bdfd, TEXELBLOCKDIMENSION1)); |
| 343 | const auto texelBlockDimension2 = static_cast<uint8_t>(KHR_DFDVAL(bdfd, TEXELBLOCKDIMENSION2)); |
| 344 | const auto blockSizeX = texelBlockDimension0 + 1u; |
| 345 | const auto blockSizeY = texelBlockDimension1 + 1u; |
| 346 | const auto blockSizeZ = texelBlockDimension2 + 1u; |
| 347 | const bool isFormatSRGB = KHR_DFDVAL(bdfd, TRANSFER) == KHR_DF_TRANSFER_SRGB; |
| 348 | |
| 349 | const bool isSigned = (KHR_DFDSVAL(bdfd, 0, QUALIFIERS) & KHR_DF_SAMPLE_DATATYPE_SIGNED) != 0; |
| 350 | const bool isFloat = (KHR_DFDSVAL(bdfd, 0, QUALIFIERS) & KHR_DF_SAMPLE_DATATYPE_FLOAT) != 0; |
| 351 | const bool isNormalized = KHR_DFDSVAL(bdfd, 0, SAMPLEUPPER) == (isFloat ? bit_cast<uint32_t>(1.0f) : 1u); |
| 352 | const bool is32Bit = KHR_DFDSVAL(bdfd, 0, BITLENGTH) + 1 == 32; |
| 353 | const bool is8Bit = KHR_DFDSVAL(bdfd, 0, BITLENGTH) + 1 == 8; |
| 354 | const bool isFormatSFloat32 = isSigned && isFloat && is32Bit && vkFormat != VK_FORMAT_D32_SFLOAT_S8_UINT; |
| 355 | const bool isFormatUNORM8 = !isSigned && !isFloat && is8Bit && isNormalized; |
| 356 | |
| 357 | const auto mismatch = [&](auto&&... args) { |
| 358 | fmt::print("ktxdiff: "); |
| 359 | fmt::print(std::forward<decltype(args)>(args)...); |
| 360 | fmt::print(" between\n"); |
| 361 | fmt::print(" Expected: {} and\n", lhs.filepath); |
| 362 | fmt::print(" Received: {}\n", rhs.filepath); |
| 363 | return false; |
| 364 | }; |
| 365 | |
| 366 | if (lhs.transcoded) { |
| 367 | // For encoded images the compressed data sizes can differ. |
| 368 | // Skip the related checks for header.supercompressionGlobalData and levelIndex |
| 369 | if (std::memcmp(&lhs.header, &rhs.header, sizeof(lhs.header) - sizeof(ktxIndexEntry64)) != 0) |
| 370 | return mismatch("Mismatching header"); |
| 371 | } else { |
| 372 | if (std::memcmp(&lhs.header, &rhs.header, sizeof(lhs.header)) != 0) |
| 373 | return mismatch("Mismatching header"); |
| 374 | if (lhs.levelIndexSize != rhs.levelIndexSize) |
| 375 | return mismatch("Mismatching levelIndices"); |
| 376 | for (uint32_t i = 0; i < lhs.levelIndices.size(); ++i) |
| 377 | // Offsets and (compressed) sizes can differ, but uncompressedByteLength must match |
| 378 | if (lhs.levelIndices[i].uncompressedByteLength != rhs.levelIndices[i].uncompressedByteLength) |
| 379 | return mismatch("Mismatching levelIndices[{}].uncompressedByteLength", i); |
| 380 | } |
| 381 | if (lhs.dfdSize != rhs.dfdSize || std::memcmp(lhs.dfdData, rhs.dfdData, lhs.dfdSize) != 0) |
| 382 | return mismatch("Mismatching DFD"); |
| 383 | |
| 384 | if (lhs.kvdSize != rhs.kvdSize || std::memcmp(lhs.kvdData, rhs.kvdData, lhs.kvdSize) != 0) |
| 385 | return mismatch("Mismatching KVD"); |
| 386 | |
| 387 | if (!lhs.transcoded) |
| 388 | if (lhs.sgdSize != rhs.sgdSize || std::memcmp(lhs.sgdData, rhs.sgdData, lhs.sgdSize) != 0) |
| 389 | return mismatch("Mismatching SGD"); |
| 390 | |
| 391 | // If the tolerance is 1 or above accept every image data as matching |
| 392 | if (tolerance >= 1.0f) |
| 393 | return true; |
| 394 |
no test coverage detected