Merge pull request #11351 from JosJuice/bitset-cpp20
Common: Use C++20 <bit> header in BitSet.h
This commit is contained in:
commit
43366d2384
|
@ -2,89 +2,15 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <bit>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
#include <intrin.h>
|
|
||||||
|
|
||||||
namespace Common
|
namespace Common
|
||||||
{
|
{
|
||||||
template <typename T>
|
|
||||||
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.
|
// 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
|
// using the set bits of an integer to represent a set of integers. Like that
|
||||||
// class, it acts like an array of bools:
|
// class, it acts like an array of bools:
|
||||||
|
@ -146,7 +72,7 @@ public:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int bit = LeastSignificantSetBit(m_val);
|
int bit = std::countr_zero(m_val);
|
||||||
m_val &= ~(1 << bit);
|
m_val &= ~(1 << bit);
|
||||||
m_bit = bit;
|
m_bit = bit;
|
||||||
}
|
}
|
||||||
|
@ -203,7 +129,7 @@ public:
|
||||||
// Dolphin's official builds do not currently assume POPCNT support on x86,
|
// Dolphin's official builds do not currently assume POPCNT support on x86,
|
||||||
// so slower explicit bit twiddling is generated. Still should generally
|
// so slower explicit bit twiddling is generated. Still should generally
|
||||||
// be faster than a loop.
|
// 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 begin() const { return ++Iterator(m_val, 0); }
|
||||||
constexpr Iterator end() const { return Iterator(m_val, -1); }
|
constexpr Iterator end() const { return Iterator(m_val, -1); }
|
||||||
IntTy m_val;
|
IntTy m_val;
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <bit>
|
||||||
|
|
||||||
#include "Common/Assert.h"
|
#include "Common/Assert.h"
|
||||||
#include "Common/BitSet.h"
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
#include "Common/MsgHandler.h"
|
#include "Common/MsgHandler.h"
|
||||||
|
@ -163,8 +163,8 @@ void StateManager::Apply()
|
||||||
|
|
||||||
void StateManager::ApplyTextures()
|
void StateManager::ApplyTextures()
|
||||||
{
|
{
|
||||||
const int textureMaskShift = Common::LeastSignificantSetBit((u32)DirtyFlag_Texture0);
|
const int textureMaskShift = std::countr_zero((u32)DirtyFlag_Texture0);
|
||||||
const int samplerMaskShift = Common::LeastSignificantSetBit((u32)DirtyFlag_Sampler0);
|
const int samplerMaskShift = std::countr_zero((u32)DirtyFlag_Sampler0);
|
||||||
|
|
||||||
u32 dirtyTextures =
|
u32 dirtyTextures =
|
||||||
(m_dirtyFlags &
|
(m_dirtyFlags &
|
||||||
|
@ -178,7 +178,7 @@ void StateManager::ApplyTextures()
|
||||||
samplerMaskShift;
|
samplerMaskShift;
|
||||||
while (dirtyTextures)
|
while (dirtyTextures)
|
||||||
{
|
{
|
||||||
const int index = Common::LeastSignificantSetBit(dirtyTextures);
|
const int index = std::countr_zero(dirtyTextures);
|
||||||
if (m_current.textures[index] != m_pending.textures[index])
|
if (m_current.textures[index] != m_pending.textures[index])
|
||||||
{
|
{
|
||||||
D3D::context->PSSetShaderResources(index, 1, &m_pending.textures[index]);
|
D3D::context->PSSetShaderResources(index, 1, &m_pending.textures[index]);
|
||||||
|
@ -190,7 +190,7 @@ void StateManager::ApplyTextures()
|
||||||
|
|
||||||
while (dirtySamplers)
|
while (dirtySamplers)
|
||||||
{
|
{
|
||||||
const int index = Common::LeastSignificantSetBit(dirtySamplers);
|
const int index = std::countr_zero(dirtySamplers);
|
||||||
if (m_current.samplers[index] != m_pending.samplers[index])
|
if (m_current.samplers[index] != m_pending.samplers[index])
|
||||||
{
|
{
|
||||||
D3D::context->PSSetSamplers(index, 1, &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)
|
while (textureSlotMask)
|
||||||
{
|
{
|
||||||
const int index = Common::LeastSignificantSetBit(textureSlotMask);
|
const int index = std::countr_zero(textureSlotMask);
|
||||||
SetTexture(index, srv);
|
SetTexture(index, srv);
|
||||||
textureSlotMask &= ~(1 << index);
|
textureSlotMask &= ~(1 << index);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "VideoCommon/VertexLoaderBase.h"
|
#include "VideoCommon/VertexLoaderBase.h"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <bit>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -12,7 +13,6 @@
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
|
||||||
#include "Common/Assert.h"
|
#include "Common/Assert.h"
|
||||||
#include "Common/BitSet.h"
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
#include "Common/MsgHandler.h"
|
#include "Common/MsgHandler.h"
|
||||||
|
@ -99,7 +99,7 @@ u32 VertexLoaderBase::GetVertexSize(const TVtxDesc& vtx_desc, const VAT& vtx_att
|
||||||
u32 size = 0;
|
u32 size = 0;
|
||||||
|
|
||||||
// Each enabled TexMatIdx adds one byte, as does PosMatIdx
|
// 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,
|
const u32 pos_size = VertexLoader_Position::GetSize(vtx_desc.low.Position, vtx_attr.g0.PosFormat,
|
||||||
vtx_attr.g0.PosElements);
|
vtx_attr.g0.PosElements);
|
||||||
|
|
Loading…
Reference in New Issue