summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-09-17 16:00:54 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-09-17 16:00:54 +0000
commit9547c87d5cd9cbfcf6d82aa08ebe8792ef8d412d (patch)
tree7873ad4e38be9345d29177f39b2f44cf21f5bda0
parentReworked dynamic memory allocation in D3D12 backend to not rely on ring buffe... (diff)
downloadDiligentCore-9547c87d5cd9cbfcf6d82aa08ebe8792ef8d412d.tar.gz
DiligentCore-9547c87d5cd9cbfcf6d82aa08ebe8792ef8d412d.zip
Updated platform bit utilities
-rw-r--r--Platforms/Android/include/AndroidPlatformMisc.h14
-rw-r--r--Platforms/Apple/include/ApplePlatformMisc.h14
-rw-r--r--Platforms/Basic/interface/BasicPlatformMisc.h28
-rw-r--r--Platforms/Linux/include/LinuxPlatformMisc.h55
-rw-r--r--Platforms/Win32/include/Win32Atomics.h15
-rw-r--r--Platforms/Win32/include/Win32PlatformMisc.h40
-rw-r--r--Platforms/interface/PlatformMisc.h8
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