Commit 971ba359 by Shahbaz Youssefi Committed by Angle LUCI CQ

Add angle::BitMask for creating bit masks

angle::BitMask(n) implements the common pattern of angle::Bit(n)-1. Bug: angleproject:6048 Change-Id: Icd56ef1504804add59d0804a7249b3035c96f9c2 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2984099 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 27e9883b
......@@ -21,6 +21,7 @@
namespace angle
{
// Given x, create 1 << x.
template <typename BitsT, typename ParamT>
constexpr static BitsT Bit(ParamT x)
{
......@@ -30,6 +31,17 @@ constexpr static BitsT Bit(ParamT x)
return (static_cast<BitsT>(1) << static_cast<size_t>(x));
}
// Given x, create (1 << x) - 1, i.e. a mask with x bits set.
template <typename BitsT, typename ParamT>
constexpr static BitsT BitMask(ParamT x)
{
if (static_cast<size_t>(x) == 0)
{
return 0;
}
return ((Bit<BitsT>(static_cast<ParamT>(static_cast<size_t>(x) - 1)) - 1) << 1) | 1;
}
template <size_t N, typename BitsT, typename ParamT = std::size_t>
class BitSetT final
{
......@@ -151,10 +163,7 @@ class BitSetT final
constexpr ParamT last() const;
// Produces a mask of ones up to the "x"th bit.
constexpr static BitsT Mask(std::size_t x)
{
return ((Bit<BitsT>(static_cast<ParamT>(x - 1)) - 1) << 1) + 1;
}
constexpr static BitsT Mask(std::size_t x) { return BitMask<BitsT>(static_cast<ParamT>(x)); }
private:
BitsT mBits;
......
......@@ -575,4 +575,27 @@ TYPED_TEST(BitSetArrayTest, BasicTest)
EXPECT_TRUE(testBitSet.test(bit));
}
}
// Unit test for angle::Bit
TEST(Bit, Test)
{
EXPECT_EQ(Bit<uint32_t>(0), 1u);
EXPECT_EQ(Bit<uint32_t>(1), 2u);
EXPECT_EQ(Bit<uint32_t>(2), 4u);
EXPECT_EQ(Bit<uint32_t>(3), 8u);
EXPECT_EQ(Bit<uint32_t>(31), 0x8000'0000u);
EXPECT_EQ(Bit<uint64_t>(63), static_cast<uint64_t>(0x8000'0000'0000'0000llu));
}
// Unit test for angle::BitMask
TEST(BitMask, Test)
{
EXPECT_EQ(BitMask<uint32_t>(1), 1u);
EXPECT_EQ(BitMask<uint32_t>(2), 3u);
EXPECT_EQ(BitMask<uint32_t>(3), 7u);
EXPECT_EQ(BitMask<uint32_t>(31), 0x7FFF'FFFFu);
EXPECT_EQ(BitMask<uint32_t>(32), 0xFFFF'FFFFu);
EXPECT_EQ(BitMask<uint64_t>(63), static_cast<uint64_t>(0x7FFF'FFFF'FFFF'FFFFllu));
EXPECT_EQ(BitMask<uint64_t>(64), static_cast<uint64_t>(0xFFFF'FFFF'FFFF'FFFFllu));
}
} // anonymous namespace
......@@ -2393,7 +2393,7 @@ void TextureVk::prepareForGenerateMipmap(ContextVk *contextVk)
// different.
static_assert(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS < 32,
"levels mask assumes 32-bits is enough");
gl::TexLevelMask::value_type levelsMask = angle::Bit<uint32_t>(maxLevel + 1 - baseLevel) - 1;
gl::TexLevelMask::value_type levelsMask = angle::BitMask<uint32_t>(maxLevel + 1 - baseLevel);
gl::LevelIndex imageAllocatedLevel = mImage->getFirstAllocatedLevel();
if (imageAllocatedLevel > baseLevel)
......
......@@ -1823,7 +1823,7 @@ angle::Result UtilsVk::convertVertexBuffer(ContextVk *contextVk,
// See GLES3.0 section 2.9.1 Transferring Array Elements
const uint32_t srcValueBits = shaderParams.isSrcHDR ? 2 : shaderParams.Bs * 8;
const uint32_t srcValueMask =
srcValueBits == 32 ? 0xFFFFFFFFu : angle::Bit<uint32_t>(srcValueBits) - 1;
srcValueBits == 32 ? 0xFFFFFFFFu : angle::BitMask<uint32_t>(srcValueBits);
switch (flags)
{
case ConvertVertex_comp::kSintToSint:
......
......@@ -1203,7 +1203,7 @@ angle::Result InitializeRenderPassFromDesc(ContextVk *contextVk,
}
SubpassVector<uint32_t> viewMasks(subpassDesc.size(),
angle::Bit<uint32_t>(desc.viewCount()) - 1);
angle::BitMask<uint32_t>(desc.viewCount()));
VkRenderPassMultiviewCreateInfo multiviewInfo = {};
multiviewInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO;
multiviewInfo.subpassCount = createInfo.subpassCount;
......
......@@ -603,7 +603,7 @@ uint8_t GetContentDefinedLayerRangeBits(uint32_t layerStart,
uint32_t maxLayerCount)
{
uint8_t layerRangeBits = layerCount >= maxLayerCount ? static_cast<uint8_t>(~0u)
: angle::Bit<uint8_t>(layerCount) - 1;
: angle::BitMask<uint8_t>(layerCount);
layerRangeBits <<= layerStart;
return layerRangeBits;
......@@ -6005,7 +6005,7 @@ void ImageHelper::stageSelfAsSubresourceUpdates(ContextVk *contextVk,
{
// Nothing to do if every level must be skipped
if ((~skipLevelsMask & gl::TexLevelMask(angle::Bit<uint32_t>(levelCount) - 1)).none())
if ((~skipLevelsMask & gl::TexLevelMask(angle::BitMask<uint32_t>(levelCount))).none())
{
return;
}
......@@ -6260,7 +6260,7 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk,
}
else
{
const uint64_t subresourceHashRange = angle::Bit<uint64_t>(updateLayerCount) - 1;
const uint64_t subresourceHashRange = angle::BitMask<uint64_t>(updateLayerCount);
const uint32_t subresourceHashOffset =
updateBaseLayer % kMaxParallelSubresourceUpload;
const uint64_t subresourceHash =
......@@ -6497,7 +6497,7 @@ void ImageHelper::removeSupersededUpdates(ContextVk *contextVk, gl::TexLevelMask
ASSERT(updateLayerCount <= 64);
uint64_t updateLayersMask = updateLayerCount >= 64
? ~static_cast<uint64_t>(0)
: angle::Bit<uint64_t>(updateLayerCount) - 1;
: angle::BitMask<uint64_t>(updateLayerCount);
updateLayersMask <<= updateBaseLayer;
const bool isColorOrDepthSuperseded =
......
......@@ -789,7 +789,7 @@ void ClearValuesArray::storeNoDepthStencil(uint32_t index, const VkClearValue &c
gl::DrawBufferMask ClearValuesArray::getColorMask() const
{
constexpr uint32_t kColorBuffersMask =
angle::Bit<uint32_t>(gl::IMPLEMENTATION_MAX_DRAW_BUFFERS) - 1;
angle::BitMask<uint32_t>(gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
return gl::DrawBufferMask(mEnabled.bits() & kColorBuffersMask);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment