Avoid undefined shift in threshold calculation
srcBitDepth and dstBitDepth may be >= 32, so shifting "1" by them is
undefined behavior.
Affects:
dEQP-VK.api.copy_and_blit.core.blit_image.all_formats.*linear
Components: Vulkan
VK-GL-CTS issue: 4517
Bug: 128950
Change-Id: I6908ef5e7326ba11a13e93549f083cd99c3467ef
Reviewed-on: https://fuchsia-review.googlesource.com/c/third_party/vulkan-cts/+/870423
Reviewed-by: Craig Stout <cstout@google.com>
diff --git a/external/vulkancts/modules/vulkan/api/vktApiCopiesAndBlittingTests.cpp b/external/vulkancts/modules/vulkan/api/vktApiCopiesAndBlittingTests.cpp
index 50b8f34..fb793a6 100644
--- a/external/vulkancts/modules/vulkan/api/vktApiCopiesAndBlittingTests.cpp
+++ b/external/vulkancts/modules/vulkan/api/vktApiCopiesAndBlittingTests.cpp
@@ -58,6 +58,7 @@
#include <array>
#include <algorithm>
#include <iterator>
+#include <limits>
#include <sstream>
namespace vkt
@@ -3615,7 +3616,13 @@
const tcu::IVec4 dstBitDepth = tcu::getTextureFormatBitDepth(dstFormat);
const tcu::IVec4 srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
for (deUint32 i = 0; i < 4; ++i)
- threshold[i] = 1 + de::max( ( ( 1 << dstBitDepth[i] ) - 1 ) / de::clamp((1 << srcBitDepth[i]) - 1, 1, 256), 1);
+ {
+ DE_ASSERT(dstBitDepth[i] < std::numeric_limits<unsigned long>::digits);
+ DE_ASSERT(srcBitDepth[i] < std::numeric_limits<unsigned long>::digits);
+ deUint64 threshold64 = 1 + de::max( ( ( 1ul << dstBitDepth[i] ) - 1 ) / de::clamp((1ul << srcBitDepth[i]) - 1, 1ul, 256ul), 1ul);
+ DE_ASSERT(threshold64 <= std::numeric_limits<uint32_t>::max());
+ threshold[i] = static_cast<deUint32>(threshold64);
+ }
isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
log << tcu::TestLog::EndSection;
@@ -5070,7 +5077,13 @@
const tcu::IVec4 dstBitDepth = tcu::getTextureFormatBitDepth(dstFormat);
const tcu::IVec4 srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
for (deUint32 i = 0; i < 4; ++i)
- threshold[i] = 1 + de::max(((1 << dstBitDepth[i]) - 1) / de::clamp((1 << srcBitDepth[i]) - 1, 1, 256), 1);
+ {
+ DE_ASSERT(dstBitDepth[i] < std::numeric_limits<unsigned long>::digits);
+ DE_ASSERT(srcBitDepth[i] < std::numeric_limits<unsigned long>::digits);
+ deUint64 threshold64 = 1 + de::max( ( ( 1ul << dstBitDepth[i] ) - 1 ) / de::clamp((1ul << srcBitDepth[i]) - 1, 1ul, 256ul), 1ul);
+ DE_ASSERT(threshold64 <= std::numeric_limits<uint32_t>::max());
+ threshold[i] = static_cast<deUint32>(threshold64);
+ }
singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
log << tcu::TestLog::EndSection;