diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2018-09-17 16:00:54 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2018-09-17 16:00:54 +0000 |
| commit | 9547c87d5cd9cbfcf6d82aa08ebe8792ef8d412d (patch) | |
| tree | 7873ad4e38be9345d29177f39b2f44cf21f5bda0 | |
| parent | Reworked dynamic memory allocation in D3D12 backend to not rely on ring buffe... (diff) | |
| download | DiligentCore-9547c87d5cd9cbfcf6d82aa08ebe8792ef8d412d.tar.gz DiligentCore-9547c87d5cd9cbfcf6d82aa08ebe8792ef8d412d.zip | |
Updated platform bit utilities
| -rw-r--r-- | Platforms/Android/include/AndroidPlatformMisc.h | 14 | ||||
| -rw-r--r-- | Platforms/Apple/include/ApplePlatformMisc.h | 14 | ||||
| -rw-r--r-- | Platforms/Basic/interface/BasicPlatformMisc.h | 28 | ||||
| -rw-r--r-- | Platforms/Linux/include/LinuxPlatformMisc.h | 55 | ||||
| -rw-r--r-- | Platforms/Win32/include/Win32Atomics.h | 15 | ||||
| -rw-r--r-- | Platforms/Win32/include/Win32PlatformMisc.h | 40 | ||||
| -rw-r--r-- | Platforms/interface/PlatformMisc.h | 8 |
7 files changed, 129 insertions, 45 deletions
diff --git a/Platforms/Android/include/AndroidPlatformMisc.h b/Platforms/Android/include/AndroidPlatformMisc.h index 1be455c8..4ccb0bb6 100644 --- a/Platforms/Android/include/AndroidPlatformMisc.h +++ b/Platforms/Android/include/AndroidPlatformMisc.h @@ -25,19 +25,9 @@ #include "../../Basic/interface/BasicPlatformMisc.h" #include "../../../Platforms/Basic/interface/DebugUtilities.h" +#include "../../Linux/include/LinuxPlatformMisc.h" -struct AndroidMisc : public BasicPlatformMisc +struct AndroidMisc : public LinuxMisc { - static Diligent::Uint32 GetMSB(Diligent::Uint32 Val) - { - if( Val == 0 )return 32; - // Returns the number of leading 0-bits in x, starting at the - // most significant bit position. If x is 0, the result is undefined. - auto LeadingZeros = __builtin_clz(Val); - auto MSB = 31 - LeadingZeros; - VERIFY_EXPR(MSB == BasicPlatformMisc::GetMSB(Val)); - - return MSB; - } }; diff --git a/Platforms/Apple/include/ApplePlatformMisc.h b/Platforms/Apple/include/ApplePlatformMisc.h index b1b22556..ca753feb 100644 --- a/Platforms/Apple/include/ApplePlatformMisc.h +++ b/Platforms/Apple/include/ApplePlatformMisc.h @@ -25,19 +25,9 @@ #include "../../Basic/interface/BasicPlatformMisc.h" #include "../../../Platforms/Basic/interface/DebugUtilities.h" +#include "../../Linux/include/LinuxPlatformMisc.h" -struct AppleMisc : public BasicPlatformMisc +struct AppleMisc : public LinuxMisc { - static Diligent::Uint32 GetMSB(Diligent::Uint32 Val) - { - if( Val == 0 )return 32; - // Returns the number of leading 0-bits in x, starting at the - // most significant bit position. If x is 0, the result is undefined. - auto LeadingZeros = __builtin_clz(Val); - auto MSB = 31 - LeadingZeros; - VERIFY_EXPR(MSB == BasicPlatformMisc::GetMSB(Val)); - - return MSB; - } }; diff --git a/Platforms/Basic/interface/BasicPlatformMisc.h b/Platforms/Basic/interface/BasicPlatformMisc.h index 023ec65d..c93497b3 100644 --- a/Platforms/Basic/interface/BasicPlatformMisc.h +++ b/Platforms/Basic/interface/BasicPlatformMisc.h @@ -27,25 +27,39 @@ struct BasicPlatformMisc { - static Diligent::Uint32 GetMSB(Diligent::Uint32 Val) + template<typename Type> + static Diligent::Uint32 GetMSB(Type Val) { - if( Val == 0 )return 32; + if( Val == 0 )return sizeof(Type)*8; - Diligent::Uint32 MSB = 31; - while( !(Val & (1u << MSB)) ) + Diligent::Uint32 MSB = sizeof(Type)*8-1; + while( !(Val & (Type{1} << MSB)) ) --MSB; return MSB; } - static Diligent::Uint32 GetLSB(Diligent::Uint32 Val) + template<typename Type> + static Diligent::Uint32 GetLSB(Type Val) { - if( Val == 0 )return 32; + if( Val == 0 )return sizeof(Type)*8; Diligent::Uint32 LSB = 0; - while( !(Val & (1u << LSB)) ) + while( !(Val & (Type{1} << LSB)) ) ++LSB; return LSB; } + + template<typename Type> + static Diligent::Uint32 CountOneBits(Type Val) + { + Diligent::Uint32 bits = 0; + while(Val != 0) + { + Val &= (Val-1); + ++bits; + } + return bits; + } }; diff --git a/Platforms/Linux/include/LinuxPlatformMisc.h b/Platforms/Linux/include/LinuxPlatformMisc.h index 40cbc849..6c7e5193 100644 --- a/Platforms/Linux/include/LinuxPlatformMisc.h +++ b/Platforms/Linux/include/LinuxPlatformMisc.h @@ -40,4 +40,59 @@ struct LinuxMisc : public BasicPlatformMisc return MSB; } + + static Diligent::Uint32 GetLSB(Diligent::Uint32 Val) + { + if( Val == 0 )return 32; + + // Returns the number of trailing 0-bits in x, starting at the + // least significant bit position. If x is 0, the result is undefined. + auto TrailingZeros = __builtin_ctz(Val); + auto LSB = TrailingZeros; + VERIFY_EXPR(LSB == BasicPlatformMisc::GetLSB(Val)); + + return LSB; + } + + static Diligent::Uint32 GetMSB(Diligent::Uint64 Val) + { + if( Val == 0 )return 64; + + // Returns the number of leading 0-bits in x, starting at the + // most significant bit position. If x is 0, the result is undefined. + auto LeadingZeros = __builtin_clzll(Val); + auto MSB = 63 - LeadingZeros; + VERIFY_EXPR(MSB == BasicPlatformMisc::GetMSB(Val)); + + return MSB; + } + + static Diligent::Uint32 GetLSB(Diligent::Uint64 Val) + { + if( Val == 0 )return 64; + + // Returns the number of trailing 0-bits in x, starting at the + // least significant bit position. If x is 0, the result is undefined. + auto TrailingZeros = __builtin_ctzll(Val); + auto LSB = TrailingZeros; + VERIFY_EXPR(LSB == BasicPlatformMisc::GetLSB(Val)); + + return LSB; + } + + static Diligent::Uint32 CountOneBits(Diligent::Uint32 Val) + { + // Returns the number of 1-bits in x. + auto bits = __builtin_popcount(Val); + VERIFY_EXPR(bits == BasicPlatformMisc::CountOneBits(Val)); + return bits; + } + + static Diligent::Uint32 CountOneBits(Diligent::Uint64 Val) + { + // Returns the number of 1-bits in x. + auto bits = __builtin_popcountll(Val); + VERIFY_EXPR(bits == BasicPlatformMisc::CountOneBits(Val)); + return bits; + } }; diff --git a/Platforms/Win32/include/Win32Atomics.h b/Platforms/Win32/include/Win32Atomics.h index 5ff75899..0af2f964 100644 --- a/Platforms/Win32/include/Win32Atomics.h +++ b/Platforms/Win32/include/Win32Atomics.h @@ -27,18 +27,17 @@ struct WindowsAtomics { // Use windows-specific atomics. Standard atomic eventually call // the same functions, but introduce significant overhead - - typedef long Long; - typedef volatile long AtomicLong; - typedef long long Int64; - typedef volatile long long AtomicInt64; + using Long = long; + using AtomicLong = volatile long; + using Int64 = long long; + using AtomicInt64 = volatile long long; // The function returns the resulting INCREMENTED value. - static Long AtomicIncrement(AtomicLong &Val); + static Long AtomicIncrement(AtomicLong &Val); static Int64 AtomicIncrement(AtomicInt64 &Val); // The function returns the resulting DECREMENTED value. - static Long AtomicDecrement(AtomicLong &Val); + static Long AtomicDecrement(AtomicLong &Val); static Int64 AtomicDecrement(AtomicInt64 &Val); // The function compares the Destination value with the Comparand value. If the Destination value is equal @@ -47,6 +46,6 @@ struct WindowsAtomics // The function returns the initial value of the Destination parameter static Long AtomicCompareExchange( AtomicLong &Destination, Long Exchange, Long Comparand); - static Long AtomicAdd( AtomicLong &Destination, Long Val); + static Long AtomicAdd( AtomicLong &Destination, Long Val); static Int64 AtomicAdd( AtomicInt64 &Destination, Int64 Val); }; diff --git a/Platforms/Win32/include/Win32PlatformMisc.h b/Platforms/Win32/include/Win32PlatformMisc.h index 8e354097..05b1bc52 100644 --- a/Platforms/Win32/include/Win32PlatformMisc.h +++ b/Platforms/Win32/include/Win32PlatformMisc.h @@ -30,7 +30,7 @@ struct WindowsMisc : public BasicPlatformMisc { - static Diligent::Uint32 GetMSB(Diligent::Uint32 Val) + inline static Diligent::Uint32 GetMSB(Diligent::Uint32 Val) { if( Val == 0 )return 32; @@ -41,7 +41,18 @@ struct WindowsMisc : public BasicPlatformMisc return MSB; } - static Diligent::Uint32 GetLSB(Diligent::Uint32 Val) + inline static Diligent::Uint32 GetMSB(Diligent::Uint64 Val) + { + if( Val == 0 )return 64; + + unsigned long MSB = 64; + _BitScanReverse64(&MSB, Val); + VERIFY_EXPR(MSB == BasicPlatformMisc::GetMSB(Val)); + + return MSB; + } + + inline static Diligent::Uint32 GetLSB(Diligent::Uint32 Val) { if( Val == 0 )return 32; @@ -51,4 +62,29 @@ struct WindowsMisc : public BasicPlatformMisc return LSB; } + + inline static Diligent::Uint32 GetLSB(Diligent::Uint64 Val) + { + if( Val == 0 )return 64; + + unsigned long LSB = 64; + _BitScanForward64(&LSB, Val); + VERIFY_EXPR(LSB == BasicPlatformMisc::GetLSB(Val)); + + return LSB; + } + + inline static Diligent::Uint32 CountOneBits(Diligent::Uint32 Val) + { + auto Bits = __popcnt(Val); + VERIFY_EXPR(Bits == BasicPlatformMisc::CountOneBits(Val)); + return Bits; + } + + inline static Diligent::Uint32 CountOneBits(Diligent::Uint64 Val) + { + auto Bits = __popcnt64(Val); + VERIFY_EXPR(Bits == BasicPlatformMisc::CountOneBits(Val)); + return static_cast<Diligent::Uint32>(Bits); + } }; diff --git a/Platforms/interface/PlatformMisc.h b/Platforms/interface/PlatformMisc.h index 76b0512c..4d64342a 100644 --- a/Platforms/interface/PlatformMisc.h +++ b/Platforms/interface/PlatformMisc.h @@ -27,19 +27,19 @@ #if PLATFORM_WIN32 || PLATFORM_UNIVERSAL_WINDOWS #include "../Win32/include/Win32PlatformMisc.h" - typedef WindowsMisc PlatformMisc; + using PlatformMisc = WindowsMisc; #elif PLATFORM_ANDROID #include "../Android/include/AndroidPlatformMisc.h" - typedef AndroidMisc PlatformMisc; + using PlatformMisc = AndroidMisc; #elif PLATFORM_LINUX #include "../Linux/include/LinuxPlatformMisc.h" - typedef LinuxMisc PlatformMisc; + using PlatformMisc = LinuxMisc; #elif PLATFORM_MACOS || PLATFORM_IOS #include "../Apple/include/ApplePlatformMisc.h" - typedef AppleMisc PlatformMisc; + using PlatformMisc = AppleMisc; #else |
