diff --git a/Source/Core/Common/BitSet.h b/Source/Core/Common/BitSet.h index ab446a986b..ad7df6afcd 100644 --- a/Source/Core/Common/BitSet.h +++ b/Source/Core/Common/BitSet.h @@ -2,89 +2,15 @@ #pragma once +#include #include #include #include + #include "Common/CommonTypes.h" -#ifdef _WIN32 - -#include - namespace Common { -template -constexpr int CountSetBits(T v) -{ - // from https://graphics.stanford.edu/~seander/bithacks.html - // GCC has this built in, but MSVC's intrinsic will only emit the actual - // POPCNT instruction, which we're not depending on - v = v - ((v >> 1) & (T) ~(T)0 / 3); - v = (v & (T) ~(T)0 / 15 * 3) + ((v >> 2) & (T) ~(T)0 / 15 * 3); - v = (v + (v >> 4)) & (T) ~(T)0 / 255 * 15; - return (T)(v * ((T) ~(T)0 / 255)) >> (sizeof(T) - 1) * 8; -} -inline int LeastSignificantSetBit(u8 val) -{ - unsigned long index; - _BitScanForward(&index, val); - return (int)index; -} -inline int LeastSignificantSetBit(u16 val) -{ - unsigned long index; - _BitScanForward(&index, val); - return (int)index; -} -inline int LeastSignificantSetBit(u32 val) -{ - unsigned long index; - _BitScanForward(&index, val); - return (int)index; -} -inline int LeastSignificantSetBit(u64 val) -{ - unsigned long index; - _BitScanForward64(&index, val); - return (int)index; -} -#else -namespace Common -{ -constexpr int CountSetBits(u8 val) -{ - return __builtin_popcount(val); -} -constexpr int CountSetBits(u16 val) -{ - return __builtin_popcount(val); -} -constexpr int CountSetBits(u32 val) -{ - return __builtin_popcount(val); -} -constexpr int CountSetBits(u64 val) -{ - return __builtin_popcountll(val); -} -inline int LeastSignificantSetBit(u8 val) -{ - return __builtin_ctz(val); -} -inline int LeastSignificantSetBit(u16 val) -{ - return __builtin_ctz(val); -} -inline int LeastSignificantSetBit(u32 val) -{ - return __builtin_ctz(val); -} -inline int LeastSignificantSetBit(u64 val) -{ - return __builtin_ctzll(val); -} -#endif - // Similar to std::bitset, this is a class which encapsulates a bitset, i.e. // using the set bits of an integer to represent a set of integers. Like that // class, it acts like an array of bools: @@ -146,7 +72,7 @@ public: } else { - int bit = LeastSignificantSetBit(m_val); + int bit = std::countr_zero(m_val); m_val &= ~(1 << bit); m_bit = bit; } @@ -203,7 +129,7 @@ public: // Dolphin's official builds do not currently assume POPCNT support on x86, // so slower explicit bit twiddling is generated. Still should generally // be faster than a loop. - constexpr unsigned int Count() const { return CountSetBits(m_val); } + constexpr unsigned int Count() const { return std::popcount(m_val); } constexpr Iterator begin() const { return ++Iterator(m_val, 0); } constexpr Iterator end() const { return Iterator(m_val, -1); } IntTy m_val; diff --git a/Source/Core/VideoBackends/D3D/D3DState.cpp b/Source/Core/VideoBackends/D3D/D3DState.cpp index 5712f6fd3c..66ccec2416 100644 --- a/Source/Core/VideoBackends/D3D/D3DState.cpp +++ b/Source/Core/VideoBackends/D3D/D3DState.cpp @@ -5,9 +5,9 @@ #include #include +#include #include "Common/Assert.h" -#include "Common/BitSet.h" #include "Common/CommonTypes.h" #include "Common/Logging/Log.h" #include "Common/MsgHandler.h" @@ -163,8 +163,8 @@ void StateManager::Apply() void StateManager::ApplyTextures() { - const int textureMaskShift = Common::LeastSignificantSetBit((u32)DirtyFlag_Texture0); - const int samplerMaskShift = Common::LeastSignificantSetBit((u32)DirtyFlag_Sampler0); + const int textureMaskShift = std::countr_zero((u32)DirtyFlag_Texture0); + const int samplerMaskShift = std::countr_zero((u32)DirtyFlag_Sampler0); u32 dirtyTextures = (m_dirtyFlags & @@ -178,7 +178,7 @@ void StateManager::ApplyTextures() samplerMaskShift; while (dirtyTextures) { - const int index = Common::LeastSignificantSetBit(dirtyTextures); + const int index = std::countr_zero(dirtyTextures); if (m_current.textures[index] != m_pending.textures[index]) { D3D::context->PSSetShaderResources(index, 1, &m_pending.textures[index]); @@ -190,7 +190,7 @@ void StateManager::ApplyTextures() while (dirtySamplers) { - const int index = Common::LeastSignificantSetBit(dirtySamplers); + const int index = std::countr_zero(dirtySamplers); if (m_current.samplers[index] != m_pending.samplers[index]) { D3D::context->PSSetSamplers(index, 1, &m_pending.samplers[index]); @@ -221,7 +221,7 @@ void StateManager::SetTextureByMask(u32 textureSlotMask, ID3D11ShaderResourceVie { while (textureSlotMask) { - const int index = Common::LeastSignificantSetBit(textureSlotMask); + const int index = std::countr_zero(textureSlotMask); SetTexture(index, srv); textureSlotMask &= ~(1 << index); } diff --git a/Source/Core/VideoCommon/VertexLoaderBase.cpp b/Source/Core/VideoCommon/VertexLoaderBase.cpp index 0ed8fc6439..dae75ddd6a 100644 --- a/Source/Core/VideoCommon/VertexLoaderBase.cpp +++ b/Source/Core/VideoCommon/VertexLoaderBase.cpp @@ -4,6 +4,7 @@ #include "VideoCommon/VertexLoaderBase.h" #include +#include #include #include #include @@ -12,7 +13,6 @@ #include #include "Common/Assert.h" -#include "Common/BitSet.h" #include "Common/CommonTypes.h" #include "Common/Logging/Log.h" #include "Common/MsgHandler.h" @@ -99,7 +99,7 @@ u32 VertexLoaderBase::GetVertexSize(const TVtxDesc& vtx_desc, const VAT& vtx_att u32 size = 0; // Each enabled TexMatIdx adds one byte, as does PosMatIdx - size += Common::CountSetBits(vtx_desc.low.Hex & 0x1FF); + size += std::popcount(vtx_desc.low.Hex & 0x1FF); const u32 pos_size = VertexLoader_Position::GetSize(vtx_desc.low.Position, vtx_attr.g0.PosFormat, vtx_attr.g0.PosElements);