diff --git a/renderdoc/os/os_specific.cpp b/renderdoc/os/os_specific.cpp index d7a85bceb..3000f9c7a 100644 --- a/renderdoc/os/os_specific.cpp +++ b/renderdoc/os/os_specific.cpp @@ -301,6 +301,150 @@ TEST_CASE("Test Process functions", "[osspecific]") // timestamp as of the creation of this test CHECK(Timing::GetUnixTimestamp() > 1504519614); }; + + SECTION("Bit counting") + { + SECTION("32-bits") + { + uint32_t val = 0; + + { + INFO("val is " << val); + CHECK(Bits::CountLeadingZeroes(val) == 32); + } + + val = 1; + + { + INFO("val is " << val); + CHECK(Bits::CountLeadingZeroes(val) == 31); + } + + val <<= 1; + + { + INFO("val is " << val); + CHECK(Bits::CountLeadingZeroes(val) == 30); + } + + val <<= 4; + + { + INFO("val is " << val); + CHECK(Bits::CountLeadingZeroes(val) == 26); + } + + val++; + + { + INFO("val is " << val); + CHECK(Bits::CountLeadingZeroes(val) == 26); + } + + val += 5; + + { + INFO("val is " << val); + CHECK(Bits::CountLeadingZeroes(val) == 26); + } + + val += 1000; + + { + INFO("val is " << val); + CHECK(Bits::CountLeadingZeroes(val) == 21); + } + + val *= 3; + + { + INFO("val is " << val); + CHECK(Bits::CountLeadingZeroes(val) == 20); + } + + val *= 200000; + + { + INFO("val is " << val); + CHECK(Bits::CountLeadingZeroes(val) == 2); + } + }; + +#if ENABLED(RDOC_X64) + SECTION("64-bits") + { + uint64_t val = 0; + + { + INFO("val is " << val); + CHECK(Bits::CountLeadingZeroes(val) == 64); + } + + val = 1; + + { + INFO("val is " << val); + CHECK(Bits::CountLeadingZeroes(val) == 63); + } + + val <<= 1; + + { + INFO("val is " << val); + CHECK(Bits::CountLeadingZeroes(val) == 62); + } + + val <<= 4; + + { + INFO("val is " << val); + CHECK(Bits::CountLeadingZeroes(val) == 58); + } + + val++; + + { + INFO("val is " << val); + CHECK(Bits::CountLeadingZeroes(val) == 58); + } + + val += 5; + + { + INFO("val is " << val); + CHECK(Bits::CountLeadingZeroes(val) == 58); + } + + val += 1000; + + { + INFO("val is " << val); + CHECK(Bits::CountLeadingZeroes(val) == 53); + } + + val *= 3; + + { + INFO("val is " << val); + CHECK(Bits::CountLeadingZeroes(val) == 52); + } + + val *= 200000; + + { + INFO("val is " << val); + CHECK(Bits::CountLeadingZeroes(val) == 34); + } + + val *= 1000000; + + { + INFO("val is " << val); + CHECK(Bits::CountLeadingZeroes(val) == 14); + } + }; +#endif + }; }; #endif // ENABLED(ENABLE_UNIT_TESTS) \ No newline at end of file diff --git a/renderdoc/os/posix/posix_specific.h b/renderdoc/os/posix/posix_specific.h index 594b39dd5..c68e5267f 100644 --- a/renderdoc/os/posix/posix_specific.h +++ b/renderdoc/os/posix/posix_specific.h @@ -64,13 +64,13 @@ namespace Bits { inline uint32_t CountLeadingZeroes(uint32_t value) { - return __builtin_clz(value); + return value == 0 ? 32 : __builtin_clz(value); } #if ENABLED(RDOC_X64) inline uint64_t CountLeadingZeroes(uint64_t value) { - return __builtin_clzl(value); + return value == 0 ? 64 : __builtin_clzl(value); } #endif };