Commit 6de51858 by Jamie Madill Committed by Commit Bot

Optimize angle::BitSetIterator.

Adds a new custom bitset template to handle packing as many bits as possible into a single variable. Intelligently select the right class depending on platform features and bit sizes. For now, always use a packed 64-bit set on 64-bit, instead of using a 32-bit set for smaller bitsets. BUG=angleproject:1814 Change-Id: I3ffef815c15515555833f6fc9302d8a4eee5423b Reviewed-on: https://chromium-review.googlesource.com/471827Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent a0e0aebb
......@@ -59,6 +59,13 @@ config("internal_config") {
"GL_GLEXT_PROTOTYPES",
"EGL_EGLEXT_PROTOTYPES",
]
if (target_cpu == "x86") {
defines += [ "ANGLE_X86_CPU" ]
}
if (target_cpu == "x64") {
defines += [ "ANGLE_X64_CPU" ]
}
}
config("extra_warnings") {
......
......@@ -281,6 +281,7 @@
'TargetMachine': '1', # x86
},
},
'defines': [ 'ANGLE_X86_CPU' ],
}, # x86_Base
'x64_Base':
......@@ -298,6 +299,7 @@
'TargetMachine': '17', # x86 - 64
},
},
'defines': [ 'ANGLE_X64_CPU' ],
}, # x64_Base
# Concrete configurations
......
......@@ -18,25 +18,25 @@ namespace
class BitSetIteratorTest : public testing::Test
{
protected:
std::bitset<40> mStateBits;
BitSet<40> mStateBits;
};
// Simple iterator test.
TEST_F(BitSetIteratorTest, Iterator)
{
std::set<unsigned long> originalValues;
std::set<size_t> originalValues;
originalValues.insert(2);
originalValues.insert(6);
originalValues.insert(8);
originalValues.insert(35);
for (unsigned long value : originalValues)
for (size_t value : originalValues)
{
mStateBits.set(value);
}
std::set<unsigned long> readValues;
for (unsigned long bit : IterateBitSet(mStateBits))
std::set<size_t> readValues;
for (size_t bit : mStateBits)
{
EXPECT_EQ(1u, originalValues.count(bit));
EXPECT_EQ(0u, readValues.count(bit));
......@@ -52,7 +52,7 @@ TEST_F(BitSetIteratorTest, EmptySet)
// We don't use the FAIL gtest macro here since it returns immediately,
// causing an unreachable code warning in MSVS
bool sawBit = false;
for (unsigned long bit : IterateBitSet(mStateBits))
for (size_t bit : mStateBits)
{
sawBit = true;
UNUSED_VARIABLE(bit);
......@@ -63,7 +63,7 @@ TEST_F(BitSetIteratorTest, EmptySet)
// Test iterating a result of combining two bitsets.
TEST_F(BitSetIteratorTest, NonLValueBitset)
{
std::bitset<40> otherBits;
BitSet<40> otherBits;
mStateBits.set(1);
mStateBits.set(2);
......@@ -75,9 +75,10 @@ TEST_F(BitSetIteratorTest, NonLValueBitset)
otherBits.set(3);
otherBits.set(5);
std::set<unsigned long> seenBits;
std::set<size_t> seenBits;
for (unsigned long bit : IterateBitSet(mStateBits & otherBits))
angle::BitSet<40> maskedBits = (mStateBits & otherBits);
for (size_t bit : maskedBits)
{
EXPECT_EQ(0u, seenBits.count(bit));
seenBits.insert(bit);
......
......@@ -805,34 +805,73 @@ inline uint32_t BitfieldReverse(uint32_t value)
}
// Count the 1 bits.
inline int BitCount(unsigned int bits)
#if defined(ANGLE_PLATFORM_WINDOWS)
inline int BitCount(uint32_t bits)
{
#if defined(_MSC_VER)
return static_cast<int>(__popcnt(bits));
#elif defined(__GNUC__)
}
#if defined(ANGLE_X64_CPU)
inline int BitCount(uint64_t bits)
{
return static_cast<int>(__popcnt64(bits));
}
#endif // defined(ANGLE_X64_CPU)
#endif // defined(ANGLE_PLATFORM_WINDOWS)
#if defined(ANGLE_PLATFORM_POSIX)
inline int BitCount(uint32_t bits)
{
return __builtin_popcount(bits);
#else
#error Please implement bit count for your platform!
#endif
}
#if defined(ANGLE_X64_CPU)
inline int BitCount(uint64_t bits)
{
return __builtin_popcountll(bits);
}
#endif // defined(ANGLE_X64_CPU)
#endif // defined(ANGLE_PLATFORM_POSIX)
#if defined(ANGLE_PLATFORM_WINDOWS)
// Return the index of the least significant bit set. Indexing is such that bit 0 is the least
// significant bit.
inline unsigned long ScanForward(unsigned long bits)
// significant bit. Implemented for different bit widths on different platforms.
inline unsigned long ScanForward(uint32_t bits)
{
ASSERT(bits != 0u);
#if defined(ANGLE_PLATFORM_WINDOWS)
unsigned long firstBitIndex = 0ul;
unsigned char ret = _BitScanForward(&firstBitIndex, bits);
ASSERT(ret != 0u);
return firstBitIndex;
#elif defined(ANGLE_PLATFORM_POSIX)
return static_cast<unsigned long>(__builtin_ctzl(bits));
#else
#error Please implement bit-scan-forward for your platform!
#endif
}
#if defined(ANGLE_X64_CPU)
inline unsigned long ScanForward(uint64_t bits)
{
ASSERT(bits != 0u);
unsigned long firstBitIndex = 0ul;
unsigned char ret = _BitScanForward64(&firstBitIndex, bits);
ASSERT(ret != 0u);
return firstBitIndex;
}
#endif // defined(ANGLE_X64_CPU)
#endif // defined(ANGLE_PLATFORM_WINDOWS)
#if defined(ANGLE_PLATFORM_POSIX)
inline unsigned long ScanForward(uint32_t bits)
{
ASSERT(bits != 0u);
return static_cast<unsigned long>(__builtin_ctz(bits));
}
#if defined(ANGLE_X64_CPU)
inline unsigned long ScanForward(uint64_t bits)
{
ASSERT(bits != 0u);
return static_cast<unsigned long>(__builtin_ctzll(bits));
}
#endif // defined(ANGLE_X64_CPU)
#endif // defined(ANGLE_PLATFORM_POSIX)
// Return the index of the most significant bit set. Indexing is such that bit 0 is the least
// significant bit.
inline unsigned long ScanReverse(unsigned long bits)
......@@ -851,8 +890,10 @@ inline unsigned long ScanReverse(unsigned long bits)
}
// Returns -1 on 0, otherwise the index of the least significant 1 bit as in GLSL.
inline int FindLSB(uint32_t bits)
template <typename T>
int FindLSB(T bits)
{
static_assert(std::is_integral<T>::value, "must be integral type.");
if (bits == 0u)
{
return -1;
......@@ -864,8 +905,10 @@ inline int FindLSB(uint32_t bits)
}
// Returns -1 on 0, otherwise the index of the most significant 1 bit as in GLSL.
inline int FindMSB(uint32_t bits)
template <typename T>
int FindMSB(T bits)
{
static_assert(std::is_integral<T>::value, "must be integral type.");
if (bits == 0u)
{
return -1;
......
......@@ -274,14 +274,26 @@ TEST(MathUtilTest, BitCount)
EXPECT_EQ(0, gl::BitCount(0u));
EXPECT_EQ(32, gl::BitCount(0xFFFFFFFFu));
EXPECT_EQ(10, gl::BitCount(0x17103121u));
#if defined(ANGLE_X64_CPU)
EXPECT_EQ(0, gl::BitCount(0ull));
EXPECT_EQ(32, gl::BitCount(0xFFFFFFFFull));
EXPECT_EQ(10, gl::BitCount(0x17103121ull));
#endif // defined(ANGLE_X64_CPU)
}
// Test ScanForward, which scans for the least significant 1 bit from a non-zero integer.
TEST(MathUtilTest, ScanForward)
{
EXPECT_EQ(0ul, gl::ScanForward(1ul));
EXPECT_EQ(16ul, gl::ScanForward(0x80010000ul));
EXPECT_EQ(31ul, gl::ScanForward(0x80000000ul));
EXPECT_EQ(0ul, gl::ScanForward(1u));
EXPECT_EQ(16ul, gl::ScanForward(0x80010000u));
EXPECT_EQ(31ul, gl::ScanForward(0x80000000u));
#if defined(ANGLE_X64_CPU)
EXPECT_EQ(0ul, gl::ScanForward(1ull));
EXPECT_EQ(16ul, gl::ScanForward(0x80010000ull));
EXPECT_EQ(31ul, gl::ScanForward(0x80000000ull));
#endif // defined(ANGLE_X64_CPU)
}
// Test ScanReverse, which scans for the most significant 1 bit from a non-zero integer.
......
......@@ -1263,7 +1263,7 @@ bool Framebuffer::formsRenderingFeedbackLoopWith(const State &state) const
}
// The bitset will skip inactive draw buffers.
for (GLuint drawIndex : angle::IterateBitSet(mState.mEnabledDrawBuffers))
for (size_t drawIndex : mState.mEnabledDrawBuffers)
{
const FramebufferAttachment *attachment = getDrawBuffer(drawIndex);
if (attachment && attachment->type() == GL_TEXTURE)
......
......@@ -100,7 +100,7 @@ class FramebufferState final : angle::NonCopyable
std::vector<GLenum> mDrawBufferStates;
GLenum mReadBufferState;
std::bitset<IMPLEMENTATION_MAX_DRAW_BUFFERS> mEnabledDrawBuffers;
angle::BitSet<IMPLEMENTATION_MAX_DRAW_BUFFERS> mEnabledDrawBuffers;
GLint mDefaultWidth;
GLint mDefaultHeight;
......@@ -259,7 +259,7 @@ class Framebuffer final : public LabeledObject, public OnAttachmentDirtyReceiver
DIRTY_BIT_MAX = DIRTY_BIT_UNKNOWN
};
typedef std::bitset<DIRTY_BIT_MAX> DirtyBits;
typedef angle::BitSet<DIRTY_BIT_MAX> DirtyBits;
bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
void syncState(const Context *context);
......
......@@ -260,7 +260,7 @@ class ProgramState final : angle::NonCopyable
UniformBlockBindingMask mActiveUniformBlockBindings;
std::vector<sh::Attribute> mAttributes;
std::bitset<MAX_VERTEX_ATTRIBS> mActiveAttribLocationsMask;
angle::BitSet<MAX_VERTEX_ATTRIBS> mActiveAttribLocationsMask;
// Uniforms are sorted in order:
// 1. Non-sampler uniforms
......
......@@ -1370,9 +1370,9 @@ void State::setVertexAttribDivisor(GLuint index, GLuint divisor)
mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
}
const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(size_t attribNum) const
{
ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
ASSERT(attribNum < mVertexAttribCurrentValues.size());
return mVertexAttribCurrentValues[attribNum];
}
......@@ -2114,7 +2114,7 @@ void State::syncDirtyObjects(const Context *context)
void State::syncDirtyObjects(const Context *context, const DirtyObjects &bitset)
{
for (auto dirtyObject : angle::IterateBitSet(bitset))
for (auto dirtyObject : bitset)
{
switch (dirtyObject)
{
......
......@@ -13,6 +13,7 @@
#include <memory>
#include "common/angleutils.h"
#include "common/bitset_utils.h"
#include "common/Color.h"
#include "libANGLE/Debug.h"
#include "libANGLE/Program.h"
......@@ -266,7 +267,7 @@ class State : angle::NonCopyable
void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
bool normalized, bool pureInteger, GLsizei stride, const void *pointer);
void setVertexAttribDivisor(GLuint index, GLuint divisor);
const VertexAttribCurrentValueData &getVertexAttribCurrentValue(unsigned int attribNum) const;
const VertexAttribCurrentValueData &getVertexAttribCurrentValue(size_t attribNum) const;
const void *getVertexAttribPointer(unsigned int attribNum) const;
void bindVertexBuffer(GLuint bindingIndex,
Buffer *boundBuffer,
......@@ -425,13 +426,13 @@ class State : angle::NonCopyable
DIRTY_OBJECT_MAX = DIRTY_OBJECT_UNKNOWN,
};
typedef std::bitset<DIRTY_BIT_MAX> DirtyBits;
typedef angle::BitSet<DIRTY_BIT_MAX> DirtyBits;
const DirtyBits &getDirtyBits() const { return mDirtyBits; }
void clearDirtyBits() { mDirtyBits.reset(); }
void clearDirtyBits(const DirtyBits &bitset) { mDirtyBits &= ~bitset; }
void setAllDirtyBits() { mDirtyBits.set(); }
typedef std::bitset<DIRTY_OBJECT_MAX> DirtyObjects;
typedef angle::BitSet<DIRTY_OBJECT_MAX> DirtyObjects;
void clearDirtyObjects() { mDirtyObjects.reset(); }
void setAllDirtyObjects() { mDirtyObjects.set(); }
void syncDirtyObjects(const Context *context);
......
......@@ -395,7 +395,7 @@ class Texture final : public egl::ImageSibling,
DIRTY_BIT_COUNT,
};
using DirtyBits = std::bitset<DIRTY_BIT_COUNT>;
using DirtyBits = angle::BitSet<DIRTY_BIT_COUNT>;
void syncImplState();
bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
......
......@@ -93,7 +93,7 @@ const VertexBinding &VertexArray::getVertexBinding(size_t bindingIndex) const
return mState.mVertexBindings[bindingIndex];
}
size_t VertexArray::GetAttribIndex(unsigned long dirtyBit)
size_t VertexArray::GetAttribIndex(size_t dirtyBit)
{
static_assert(gl::MAX_VERTEX_ATTRIBS == gl::MAX_VERTEX_ATTRIB_BINDINGS,
"The stride of vertex attributes should equal to that of vertex bindings.");
......
......@@ -168,9 +168,9 @@ class VertexArray final : public LabeledObject
DIRTY_BIT_MAX = DIRTY_BIT_UNKNOWN,
};
typedef std::bitset<DIRTY_BIT_MAX> DirtyBits;
typedef angle::BitSet<DIRTY_BIT_MAX> DirtyBits;
static size_t GetAttribIndex(unsigned long dirtyBit);
static size_t GetAttribIndex(size_t dirtyBit);
void syncImplState(const Context *context);
bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
......
......@@ -26,7 +26,7 @@ TEST(VertexArrayTest, VerifyGetAttribIndex)
dirtyBits.set(bits[i]);
}
for (unsigned long dirtyBit : angle::IterateBitSet(dirtyBits))
for (size_t dirtyBit : dirtyBits)
{
size_t index = VertexArray::GetAttribIndex(dirtyBit);
if (dirtyBit < VertexArray::DIRTY_BIT_ATTRIB_MAX_ENABLED)
......
......@@ -9,6 +9,7 @@
#ifndef LIBANGLE_ANGLETYPES_H_
#define LIBANGLE_ANGLETYPES_H_
#include "common/bitset_utils.h"
#include "libANGLE/Constants.h"
#include "libANGLE/RefCountObject.h"
......@@ -253,10 +254,10 @@ struct PixelPackState : PixelStoreStateBase
};
// Used in Program and VertexArray.
typedef std::bitset<MAX_VERTEX_ATTRIBS> AttributesMask;
using AttributesMask = angle::BitSet<MAX_VERTEX_ATTRIBS>;
// Use in Program
typedef std::bitset<IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS> UniformBlockBindingMask;
using UniformBlockBindingMask = angle::BitSet<IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS>;
// A map of GL objects indexed by object ID. The specific map implementation may change.
// Client code should treat it as a std::map.
......
......@@ -306,7 +306,7 @@ void FramebufferD3D::syncState(ContextImpl *contextImpl,
invalidateColorAttachmentCache = true;
}
for (auto dirtyBit : angle::IterateBitSet(dirtyBits))
for (auto dirtyBit : dirtyBits)
{
if ((dirtyBit >= gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 &&
dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX) ||
......
......@@ -2359,7 +2359,7 @@ void ProgramD3D::updateCachedInputLayout(const gl::State &state)
mCachedInputLayout.clear();
const auto &vertexAttributes = state.getVertexArray()->getVertexAttributes();
for (unsigned int locationIndex : IterateBitSet(mState.getActiveAttribLocationsMask()))
for (size_t locationIndex : mState.getActiveAttribLocationsMask())
{
int d3dSemantic = mAttribLocationToD3DSemantic[locationIndex];
......
......@@ -241,8 +241,7 @@ gl::Error VertexDataManager::prepareVertexData(const gl::State &state,
translatedAttribs->resize(attribIndex + 1);
TranslatedAttribute *translated = &(*translatedAttribs)[attribIndex];
auto currentValueData =
state.getVertexAttribCurrentValue(static_cast<unsigned int>(attribIndex));
auto currentValueData = state.getVertexAttribCurrentValue(attribIndex);
// Record the attribute now
translated->active = true;
......@@ -401,14 +400,14 @@ gl::Error VertexDataManager::storeDynamicAttribs(
StreamingBufferUnmapper localUnmapper(mStreamingBuffer);
// Reserve the required space for the dynamic buffers.
for (auto attribIndex : IterateBitSet(dynamicAttribsMask))
for (auto attribIndex : dynamicAttribsMask)
{
const auto &dynamicAttrib = (*translatedAttribs)[attribIndex];
ANGLE_TRY(reserveSpaceForAttrib(dynamicAttrib, count, instances));
}
// Store dynamic attributes
for (auto attribIndex : IterateBitSet(dynamicAttribsMask))
for (auto attribIndex : dynamicAttribsMask)
{
auto *dynamicAttrib = &(*translatedAttribs)[attribIndex];
ANGLE_TRY(storeDynamicAttrib(dynamicAttrib, start, count, instances));
......@@ -422,7 +421,7 @@ void VertexDataManager::PromoteDynamicAttribs(
const gl::AttributesMask &dynamicAttribsMask,
GLsizei count)
{
for (auto attribIndex : IterateBitSet(dynamicAttribsMask))
for (auto attribIndex : dynamicAttribsMask)
{
const auto &dynamicAttrib = translatedAttribs[attribIndex];
const auto &binding = *dynamicAttrib.binding;
......
......@@ -384,7 +384,7 @@ void Framebuffer11::syncState(ContextImpl *contextImpl, const gl::Framebuffer::D
const auto &mergedDirtyBits = dirtyBits | mInternalDirtyBits;
mInternalDirtyBits.reset();
for (auto dirtyBit : IterateBitSet(mergedDirtyBits))
for (auto dirtyBit : mergedDirtyBits)
{
switch (dirtyBit)
{
......
......@@ -47,7 +47,7 @@ gl::InputLayout GetInputLayout(const std::vector<const TranslatedAttribute *> &t
return inputLayout;
}
GLenum GetGLSLAttributeType(const std::vector<sh::Attribute> &shaderAttributes, int index)
GLenum GetGLSLAttributeType(const std::vector<sh::Attribute> &shaderAttributes, size_t index)
{
// Count matrices differently
for (const sh::Attribute &attrib : shaderAttributes)
......@@ -59,8 +59,9 @@ GLenum GetGLSLAttributeType(const std::vector<sh::Attribute> &shaderAttributes,
GLenum transposedType = gl::TransposeMatrixType(attrib.type);
int rows = gl::VariableRowCount(transposedType);
int intIndex = static_cast<int>(index);
if (index >= attrib.location && index < attrib.location + rows)
if (intIndex >= attrib.location && intIndex < attrib.location + rows)
{
return transposedType;
}
......@@ -105,7 +106,7 @@ void SortAttributesByLayout(const gl::Program *program,
const auto &locationToSemantic =
GetImplAs<ProgramD3D>(program)->getAttribLocationToD3DSemantics();
for (auto locationIndex : angle::IterateBitSet(program->getActiveAttribLocationsMask()))
for (auto locationIndex : program->getActiveAttribLocationsMask())
{
int d3dSemantic = locationToSemantic[locationIndex];
if (sortedAttributesOut->size() <= static_cast<size_t>(d3dSemantic))
......@@ -485,7 +486,7 @@ gl::Error InputLayoutCache::updateInputLayout(const gl::State &state,
const auto &bindings = state.getVertexArray()->getVertexBindings();
const auto &locationToSemantic = programD3D->getAttribLocationToD3DSemantics();
for (unsigned long attribIndex : angle::IterateBitSet(program->getActiveAttribLocationsMask()))
for (size_t attribIndex : program->getActiveAttribLocationsMask())
{
// Record the type of the associated vertex shader vector in our key
// This will prevent mismatched vertex shaders from using the same input layout
......@@ -495,7 +496,8 @@ gl::Error InputLayoutCache::updateInputLayout(const gl::State &state,
const auto &binding = bindings[attrib.bindingIndex];
int d3dSemantic = locationToSemantic[attribIndex];
const auto &currentValue = state.getVertexAttribCurrentValue(attribIndex);
const auto &currentValue =
state.getVertexAttribCurrentValue(static_cast<unsigned int>(attribIndex));
gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib, currentValue.Type);
layout.addAttributeData(glslElementType, d3dSemantic, vertexFormatType, binding.divisor);
......
......@@ -253,7 +253,7 @@ void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBit
return;
}
for (auto dirtyBit : angle::IterateBitSet(dirtyBits))
for (auto dirtyBit : dirtyBits)
{
switch (dirtyBit)
{
......@@ -1103,15 +1103,14 @@ gl::Error StateManager11::updateCurrentValueAttribs(const gl::State &state,
const auto &dirtyActiveAttribs = (activeAttribsMask & mDirtyCurrentValueAttribs);
const auto &vertexAttributes = state.getVertexArray()->getVertexAttributes();
for (auto attribIndex : angle::IterateBitSet(dirtyActiveAttribs))
for (auto attribIndex : dirtyActiveAttribs)
{
if (vertexAttributes[attribIndex].enabled)
continue;
mDirtyCurrentValueAttribs.reset(attribIndex);
const auto &currentValue =
state.getVertexAttribCurrentValue(static_cast<unsigned int>(attribIndex));
const auto &currentValue = state.getVertexAttribCurrentValue(attribIndex);
auto currentValueAttrib = &mCurrentValueAttribs[attribIndex];
currentValueAttrib->currentValueType = currentValue.Type;
currentValueAttrib->attribute = &vertexAttributes[attribIndex];
......
......@@ -42,7 +42,7 @@ VertexArray11::~VertexArray11()
void VertexArray11::syncState(ContextImpl *contextImpl, const gl::VertexArray::DirtyBits &dirtyBits)
{
for (auto dirtyBit : angle::IterateBitSet(dirtyBits))
for (auto dirtyBit : dirtyBits)
{
if (dirtyBit == gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER)
continue;
......@@ -62,9 +62,9 @@ void VertexArray11::flushAttribUpdates(const gl::State &state)
if (mAttribsToUpdate.any())
{
// Skip attrib locations the program doesn't use.
const auto &activeToUpdate = (mAttribsToUpdate & activeLocations);
gl::AttributesMask activeToUpdate = mAttribsToUpdate & activeLocations;
for (auto toUpdateIndex : angle::IterateBitSet(activeToUpdate))
for (auto toUpdateIndex : activeToUpdate)
{
mAttribsToUpdate.reset(toUpdateIndex);
updateVertexAttribStorage(toUpdateIndex);
......@@ -155,15 +155,14 @@ gl::Error VertexArray11::updateDirtyAndDynamicAttribs(VertexDataManager *vertexD
if (mAttribsToTranslate.any())
{
// Skip attrib locations the program doesn't use, saving for the next frame.
const auto &dirtyActiveAttribs = (mAttribsToTranslate & activeLocations);
gl::AttributesMask dirtyActiveAttribs = (mAttribsToTranslate & activeLocations);
for (auto dirtyAttribIndex : angle::IterateBitSet(dirtyActiveAttribs))
for (auto dirtyAttribIndex : dirtyActiveAttribs)
{
mAttribsToTranslate.reset(dirtyAttribIndex);
auto *translatedAttrib = &mTranslatedAttribs[dirtyAttribIndex];
const auto &currentValue =
state.getVertexAttribCurrentValue(static_cast<unsigned int>(dirtyAttribIndex));
const auto &currentValue = state.getVertexAttribCurrentValue(dirtyAttribIndex);
// Record basic attrib info
translatedAttrib->attribute = &attribs[dirtyAttribIndex];
......@@ -195,11 +194,10 @@ gl::Error VertexArray11::updateDirtyAndDynamicAttribs(VertexDataManager *vertexD
{
auto activeDynamicAttribs = (mDynamicAttribsMask & activeLocations);
for (auto dynamicAttribIndex : angle::IterateBitSet(activeDynamicAttribs))
for (auto dynamicAttribIndex : activeDynamicAttribs)
{
auto *dynamicAttrib = &mTranslatedAttribs[dynamicAttribIndex];
const auto &currentValue =
state.getVertexAttribCurrentValue(static_cast<unsigned int>(dynamicAttribIndex));
const auto &currentValue = state.getVertexAttribCurrentValue(dynamicAttribIndex);
// Record basic attrib info
dynamicAttrib->attribute = &attribs[dynamicAttribIndex];
......
......@@ -120,7 +120,7 @@ void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits
return;
}
for (auto dirtyBit : angle::IterateBitSet(dirtyBits))
for (auto dirtyBit : dirtyBits)
{
switch (dirtyBit)
{
......@@ -396,7 +396,7 @@ gl::Error StateManager9::setBlendDepthRasterStates(const gl::State &glState,
mCurFrontFaceCCW = frontFaceCCW;
}
for (auto dirtyBit : angle::IterateBitSet(mDirtyBits))
for (auto dirtyBit : mDirtyBits)
{
switch (dirtyBit)
{
......
......@@ -155,7 +155,7 @@ class StateManager9 final : angle::NonCopyable
DIRTY_BIT_MAX
};
typedef std::bitset<DIRTY_BIT_MAX> DirtyBits;
using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
bool mUsingZeroColorMaskWorkaround;
......
......@@ -417,7 +417,7 @@ void FramebufferGL::syncState(ContextImpl *contextImpl, const Framebuffer::Dirty
mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
for (auto dirtyBit : angle::IterateBitSet(dirtyBits))
for (auto dirtyBit : dirtyBits)
{
switch (dirtyBit)
{
......
......@@ -75,9 +75,10 @@ LinkResult ProgramGL::load(const ContextImpl *contextImpl,
const WorkaroundsGL &workaroundsGL = GetAs<ContextGL>(contextImpl)->getWorkaroundsGL();
if (workaroundsGL.reapplyUBOBindingsAfterLoadingBinaryProgram)
{
for (GLuint bindingIndex : angle::IterateBitSet(mState.getActiveUniformBlockBindingsMask()))
for (size_t bindingIndex : mState.getActiveUniformBlockBindingsMask())
{
setUniformBlockBinding(bindingIndex, mState.getUniformBlockBinding(bindingIndex));
GLuint uintIndex = static_cast<GLuint>(bindingIndex);
setUniformBlockBinding(uintIndex, mState.getUniformBlockBinding(uintIndex));
}
}
......
......@@ -1394,7 +1394,7 @@ void StateManagerGL::syncState(const gl::ContextState &data,
mLocalDirtyBits.set(gl::State::DIRTY_BIT_FRAMEBUFFER_SRGB);
}
const auto &glAndLocalDirtyBits = (glDirtyBits | mLocalDirtyBits);
const gl::State::DirtyBits &glAndLocalDirtyBits = (glDirtyBits | mLocalDirtyBits);
if (!glAndLocalDirtyBits.any())
{
......@@ -1402,7 +1402,7 @@ void StateManagerGL::syncState(const gl::ContextState &data,
}
// TODO(jmadill): Investigate only syncing vertex state for active attributes
for (auto dirtyBit : angle::IterateBitSet(glAndLocalDirtyBits))
for (auto dirtyBit : glAndLocalDirtyBits)
{
switch (dirtyBit)
{
......@@ -1648,8 +1648,8 @@ void StateManagerGL::syncState(const gl::ContextState &data,
dirtyBit < gl::State::DIRTY_BIT_CURRENT_VALUE_MAX);
size_t attribIndex =
static_cast<size_t>(dirtyBit) - gl::State::DIRTY_BIT_CURRENT_VALUE_0;
setAttributeCurrentData(attribIndex, state.getVertexAttribCurrentValue(
static_cast<unsigned int>(attribIndex)));
setAttributeCurrentData(attribIndex,
state.getVertexAttribCurrentValue(attribIndex));
break;
}
}
......
......@@ -942,7 +942,7 @@ void TextureGL::syncState(const gl::Texture::DirtyBits &dirtyBits)
mLocalDirtyBits |= GetLevelWorkaroundDirtyBits();
}
for (auto dirtyBit : angle::IterateBitSet(dirtyBits | mLocalDirtyBits))
for (auto dirtyBit : (dirtyBits | mLocalDirtyBits))
{
switch (dirtyBit)
{
......
......@@ -257,7 +257,10 @@ void VertexArrayGL::computeStreamingAttributeSizes(const gl::AttributesMask &act
const auto &attribs = mData.getVertexAttributes();
const auto &bindings = mData.getVertexBindings();
for (auto idx : angle::IterateBitSet(mAttributesNeedStreaming & activeAttributesMask))
gl::AttributesMask attribsToStream = (mAttributesNeedStreaming & activeAttributesMask);
for (auto idx : attribsToStream)
{
const auto &attrib = attribs[idx];
const auto &binding = bindings[attrib.bindingIndex];
......@@ -320,7 +323,10 @@ gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &activeAttrib
const auto &attribs = mData.getVertexAttributes();
const auto &bindings = mData.getVertexBindings();
for (auto idx : angle::IterateBitSet(mAttributesNeedStreaming & activeAttributesMask))
gl::AttributesMask attribsToStream = (mAttributesNeedStreaming & activeAttributesMask);
for (auto idx : attribsToStream)
{
const auto &attrib = attribs[idx];
const auto &binding = bindings[attrib.bindingIndex];
......@@ -526,7 +532,7 @@ void VertexArrayGL::updateAttribDivisor(size_t attribIndex)
void VertexArrayGL::syncState(ContextImpl *contextImpl, const VertexArray::DirtyBits &dirtyBits)
{
for (unsigned long dirtyBit : angle::IterateBitSet(dirtyBits))
for (size_t dirtyBit : dirtyBits)
{
if (dirtyBit == VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER)
{
......
......@@ -99,7 +99,7 @@ gl::Error ContextVk::initPipeline()
std::vector<VkVertexInputBindingDescription> vertexBindings;
std::vector<VkVertexInputAttributeDescription> vertexAttribs;
for (auto attribIndex : angle::IterateBitSet(programGL->getActiveAttribLocationsMask()))
for (auto attribIndex : programGL->getActiveAttribLocationsMask())
{
const auto &attrib = attribs[attribIndex];
const auto &binding = bindings[attrib.bindingIndex];
......@@ -293,7 +293,7 @@ gl::Error ContextVk::drawArrays(GLenum mode, GLint first, GLsizei count)
std::vector<VkBuffer> vertexHandles;
std::vector<VkDeviceSize> vertexOffsets;
for (auto attribIndex : angle::IterateBitSet(programGL->getActiveAttribLocationsMask()))
for (auto attribIndex : programGL->getActiveAttribLocationsMask())
{
const auto &attrib = attribs[attribIndex];
const auto &binding = bindings[attrib.bindingIndex];
......
......@@ -19,6 +19,7 @@
'<(angle_path)/src/tests/perf_tests/ANGLEPerfTest.h',
'<(angle_path)/src/tests/perf_tests/BlitFramebufferPerf.cpp',
'<(angle_path)/src/tests/perf_tests/BindingPerf.cpp',
'<(angle_path)/src/tests/perf_tests/BitSetIteratorPerf.cpp',
'<(angle_path)/src/tests/perf_tests/BufferSubData.cpp',
'<(angle_path)/src/tests/perf_tests/DrawCallPerf.cpp',
'<(angle_path)/src/tests/perf_tests/DrawCallPerfParams.cpp',
......
//
// Copyright 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// IndexDataManagerPerfTest:
// Performance test for index buffer management.
//
#include "ANGLEPerfTest.h"
#include <gmock/gmock.h>
#include "angle_unittests_utils.h"
#include "common/bitset_utils.h"
using namespace testing;
namespace
{
template <typename T>
class BitSetIteratorPerfTest : public ANGLEPerfTest
{
public:
BitSetIteratorPerfTest();
void step() override;
T mBits;
};
template <typename T>
BitSetIteratorPerfTest<T>::BitSetIteratorPerfTest() : ANGLEPerfTest("BitSetIteratorPerf", "_run")
{
}
template <typename T>
void BitSetIteratorPerfTest<T>::step()
{
mBits.flip();
for (size_t bit : mBits)
{
UNUSED_VARIABLE(bit);
}
mBits.reset();
}
// These type names unfortunately don't get printed correctly in Gtest.
#if defined(ANGLE_X64_CPU)
using TestTypes = Types<angle::IterableBitSet<32>, angle::BitSet32<32>, angle::BitSet64<32>>;
#else
using TestTypes = Types<angle::IterableBitSet<32>, angle::BitSet32<32>>;
#endif // defined(ANGLE_X64_CPU)
TYPED_TEST_CASE(BitSetIteratorPerfTest, TestTypes);
TYPED_TEST(BitSetIteratorPerfTest, Run)
{
this->run();
}
} // anonymous namespace
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