Optimize more front-end VertexArray binding.
Improves perf slightly (1-2%) in the Vulkan VBO state change test.
Bug: angleproject:3014
Change-Id: Ia8082b5b3f5e847a6b2775e896893fa8d38c1afd
Reviewed-on: https://chromium-review.googlesource.com/c/1393904
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index 545a0ac..a4ae976 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -4787,7 +4787,7 @@
const void *ptr)
{
mState.setVertexAttribPointer(this, index, mState.getTargetBuffer(BufferBinding::Array), size,
- type, ConvertToBool(normalized), false, stride, ptr);
+ type, ConvertToBool(normalized), stride, ptr);
mStateCache.onVertexArrayStateChange(this);
}
@@ -4834,8 +4834,8 @@
GLsizei stride,
const void *pointer)
{
- mState.setVertexAttribPointer(this, index, mState.getTargetBuffer(BufferBinding::Array), size,
- type, false, true, stride, pointer);
+ mState.setVertexAttribIPointer(this, index, mState.getTargetBuffer(BufferBinding::Array), size,
+ type, stride, pointer);
mStateCache.onVertexArrayStateChange(this);
}
diff --git a/src/libANGLE/Framebuffer.cpp b/src/libANGLE/Framebuffer.cpp
index bcc7d76..c4e83d1 100644
--- a/src/libANGLE/Framebuffer.cpp
+++ b/src/libANGLE/Framebuffer.cpp
@@ -673,7 +673,7 @@
FramebufferAttachment::kDefaultMultiviewLayout,
FramebufferAttachment::kDefaultViewportOffsets);
}
- mState.mDrawBufferTypeMask.setIndex(getDrawbufferWriteType(0), 0);
+ SetComponentTypeMask(getDrawbufferWriteType(0), 0, &mState.mDrawBufferTypeMask);
}
Framebuffer::Framebuffer(rx::GLImplFactory *factory)
@@ -684,7 +684,7 @@
mDirtyStencilAttachmentBinding(this, DIRTY_BIT_STENCIL_ATTACHMENT)
{
mDirtyColorAttachmentBindings.emplace_back(this, DIRTY_BIT_COLOR_ATTACHMENT_0);
- mState.mDrawBufferTypeMask.setIndex(getDrawbufferWriteType(0), 0);
+ SetComponentTypeMask(getDrawbufferWriteType(0), 0, &mState.mDrawBufferTypeMask);
}
Framebuffer::~Framebuffer()
@@ -871,7 +871,7 @@
for (size_t index = 0; index < count; ++index)
{
- mState.mDrawBufferTypeMask.setIndex(getDrawbufferWriteType(index), index);
+ SetComponentTypeMask(getDrawbufferWriteType(index), index, &mState.mDrawBufferTypeMask);
if (drawStates[index] != GL_NONE && mState.mColorAttachments[index].isAttached())
{
@@ -885,23 +885,24 @@
return mState.getDrawBuffer(drawBuffer);
}
-GLenum Framebuffer::getDrawbufferWriteType(size_t drawBuffer) const
+ComponentType Framebuffer::getDrawbufferWriteType(size_t drawBuffer) const
{
const FramebufferAttachment *attachment = mState.getDrawBuffer(drawBuffer);
if (attachment == nullptr)
{
- return GL_NONE;
+ return ComponentType::NoType;
}
GLenum componentType = attachment->getFormat().info->componentType;
switch (componentType)
{
case GL_INT:
+ return ComponentType::Int;
case GL_UNSIGNED_INT:
- return componentType;
+ return ComponentType::UnsignedInt;
default:
- return GL_FLOAT;
+ return ComponentType::Float;
}
}
@@ -1761,7 +1762,8 @@
// formsRenderingFeedbackLoopWith
bool enabled = (type != GL_NONE && getDrawBufferState(colorIndex) != GL_NONE);
mState.mEnabledDrawBuffers.set(colorIndex, enabled);
- mState.mDrawBufferTypeMask.setIndex(getDrawbufferWriteType(colorIndex), colorIndex);
+ SetComponentTypeMask(getDrawbufferWriteType(colorIndex), colorIndex,
+ &mState.mDrawBufferTypeMask);
}
break;
}
diff --git a/src/libANGLE/Framebuffer.h b/src/libANGLE/Framebuffer.h
index c936c95..69cf05f 100644
--- a/src/libANGLE/Framebuffer.h
+++ b/src/libANGLE/Framebuffer.h
@@ -217,7 +217,7 @@
const std::vector<GLenum> &getDrawBufferStates() const;
void setDrawBuffers(size_t count, const GLenum *buffers);
const FramebufferAttachment *getDrawBuffer(size_t drawBuffer) const;
- GLenum getDrawbufferWriteType(size_t drawBuffer) const;
+ ComponentType getDrawbufferWriteType(size_t drawBuffer) const;
ComponentTypeMask getDrawBufferTypeMask() const;
DrawBufferMask getDrawBufferMask() const;
bool hasEnabledDrawBuffer() const;
diff --git a/src/libANGLE/MemoryProgramCache.cpp b/src/libANGLE/MemoryProgramCache.cpp
index 8d5617f..c1eb7c0 100644
--- a/src/libANGLE/MemoryProgramCache.cpp
+++ b/src/libANGLE/MemoryProgramCache.cpp
@@ -246,8 +246,8 @@
static_assert(MAX_VERTEX_ATTRIBS * 2 <= sizeof(uint32_t) * 8,
"All bits of mAttributesTypeMask types and mask fit into 32 bits each");
- state->mAttributesTypeMask.from_ulong(stream.readInt<uint32_t>());
- state->mAttributesMask = stream.readInt<gl::AttributesMask>();
+ state->mAttributesTypeMask = gl::ComponentTypeMask(stream.readInt<uint32_t>());
+ state->mAttributesMask = stream.readInt<gl::AttributesMask>();
static_assert(MAX_VERTEX_ATTRIBS <= sizeof(unsigned long) * 8,
"Too many vertex attribs for mask");
@@ -404,7 +404,7 @@
static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS * 2 <= 8 * sizeof(uint32_t),
"All bits of mDrawBufferTypeMask and mActiveOutputVariables types and mask fit "
"into 32 bits each");
- state->mDrawBufferTypeMask.from_ulong(stream.readInt<uint32_t>());
+ state->mDrawBufferTypeMask = gl::ComponentTypeMask(stream.readInt<uint32_t>());
state->mActiveOutputVariables = stream.readInt<gl::DrawBufferMask>();
unsigned int samplerRangeLow = stream.readInt<unsigned int>();
diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
index 3938ba6..1bda45c 100644
--- a/src/libANGLE/Program.cpp
+++ b/src/libANGLE/Program.cpp
@@ -3097,8 +3097,10 @@
// gl_VertexID and gl_InstanceID are active attributes but don't have a bound attribute.
if (!attribute.isBuiltIn())
{
- mState.mAttributesTypeMask.setIndex(VariableComponentType(attribute.type),
- location);
+ ComponentType componentType =
+ GLenumToComponentType(VariableComponentType(attribute.type));
+
+ SetComponentTypeMask(componentType, location, &mState.mAttributesTypeMask);
mState.mAttributesMask.set(location);
}
}
@@ -3648,7 +3650,9 @@
ASSERT(location < mState.mActiveOutputVariables.size());
mState.mActiveOutputVariables.set(location);
mState.mOutputVariableTypes[location] = VariableComponentType(outputVariable.type);
- mState.mDrawBufferTypeMask.setIndex(mState.mOutputVariableTypes[location], location);
+ ComponentType componentType =
+ GLenumToComponentType(mState.mOutputVariableTypes[location]);
+ SetComponentTypeMask(componentType, location, &mState.mDrawBufferTypeMask);
}
}
diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp
index 2745b84..fb65fa3 100644
--- a/src/libANGLE/State.cpp
+++ b/src/libANGLE/State.cpp
@@ -355,7 +355,7 @@
// Set all indexes in state attributes type mask to float (default)
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
- mCurrentValuesTypeMask.setIndex(GL_FLOAT, i);
+ SetComponentTypeMask(ComponentType::Float, i, &mCurrentValuesTypeMask);
}
mUniformBuffers.resize(caps.maxUniformBufferBindings);
@@ -1621,7 +1621,7 @@
mVertexAttribCurrentValues[index].setFloatValues(values);
mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
mDirtyCurrentValues.set(index);
- mCurrentValuesTypeMask.setIndex(GL_FLOAT, index);
+ SetComponentTypeMask(ComponentType::Float, index, &mCurrentValuesTypeMask);
}
void State::setVertexAttribu(GLuint index, const GLuint values[4])
@@ -1630,7 +1630,7 @@
mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
mDirtyCurrentValues.set(index);
- mCurrentValuesTypeMask.setIndex(GL_UNSIGNED_INT, index);
+ SetComponentTypeMask(ComponentType::UnsignedInt, index, &mCurrentValuesTypeMask);
}
void State::setVertexAttribi(GLuint index, const GLint values[4])
@@ -1639,7 +1639,7 @@
mVertexAttribCurrentValues[index].setIntValues(values);
mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
mDirtyCurrentValues.set(index);
- mCurrentValuesTypeMask.setIndex(GL_INT, index);
+ SetComponentTypeMask(ComponentType::Int, index, &mCurrentValuesTypeMask);
}
void State::setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor)
diff --git a/src/libANGLE/State.h b/src/libANGLE/State.h
index e3df1b8..df67277 100644
--- a/src/libANGLE/State.h
+++ b/src/libANGLE/State.h
@@ -347,12 +347,24 @@
GLint size,
VertexAttribType type,
bool normalized,
- bool pureInteger,
GLsizei stride,
const void *pointer)
{
mVertexArray->setVertexAttribPointer(context, attribNum, boundBuffer, size, type,
- normalized, pureInteger, stride, pointer);
+ normalized, stride, pointer);
+ mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
+ }
+
+ ANGLE_INLINE void setVertexAttribIPointer(const Context *context,
+ unsigned int attribNum,
+ Buffer *boundBuffer,
+ GLint size,
+ VertexAttribType type,
+ GLsizei stride,
+ const void *pointer)
+ {
+ mVertexArray->setVertexAttribIPointer(context, attribNum, boundBuffer, size, type, stride,
+ pointer);
mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
}
diff --git a/src/libANGLE/VertexArray.cpp b/src/libANGLE/VertexArray.cpp
index 9b0e912..e475d42 100644
--- a/src/libANGLE/VertexArray.cpp
+++ b/src/libANGLE/VertexArray.cpp
@@ -24,30 +24,30 @@
return (subjectIndex == MAX_VERTEX_ATTRIBS);
}
-ANGLE_INLINE GLenum GetVertexAttributeBaseType(const VertexAttribute &attrib)
+ANGLE_INLINE ComponentType GetVertexAttributeComponentType(bool pureInteger, VertexAttribType type)
{
- if (attrib.pureInteger)
+ if (pureInteger)
{
- switch (attrib.type)
+ switch (type)
{
case VertexAttribType::Byte:
case VertexAttribType::Short:
case VertexAttribType::Int:
- return GL_INT;
+ return ComponentType::Int;
case VertexAttribType::UnsignedByte:
case VertexAttribType::UnsignedShort:
case VertexAttribType::UnsignedInt:
- return GL_UNSIGNED_INT;
+ return ComponentType::UnsignedInt;
default:
UNREACHABLE();
- return GL_NONE;
+ return ComponentType::NoType;
}
}
else
{
- return GL_FLOAT;
+ return ComponentType::Float;
}
}
@@ -321,23 +321,16 @@
}
}
-ANGLE_INLINE void VertexArray::setVertexAttribFormatImpl(size_t attribIndex,
+ANGLE_INLINE void VertexArray::setVertexAttribFormatImpl(VertexAttribute *attrib,
GLint size,
VertexAttribType type,
bool normalized,
- bool pureInteger,
GLuint relativeOffset)
{
- ASSERT(attribIndex < getMaxAttribs());
-
- VertexAttribute *attrib = &mState.mVertexAttributes[attribIndex];
-
attrib->size = size;
attrib->type = type;
attrib->normalized = normalized;
- attrib->pureInteger = pureInteger;
attrib->relativeOffset = relativeOffset;
- mState.mVertexAttributesTypeMask.setIndex(GetVertexAttributeBaseType(*attrib), attribIndex);
}
void VertexArray::setVertexAttribFormat(size_t attribIndex,
@@ -347,10 +340,15 @@
bool pureInteger,
GLuint relativeOffset)
{
- setVertexAttribFormatImpl(attribIndex, size, type, normalized, pureInteger, relativeOffset);
+ VertexAttribute &attrib = mState.mVertexAttributes[attribIndex];
+ attrib.pureInteger = pureInteger;
+
+ ComponentType componentType = GetVertexAttributeComponentType(pureInteger, type);
+ SetComponentTypeMask(componentType, attribIndex, &mState.mVertexAttributesTypeMask);
+
+ setVertexAttribFormatImpl(&attrib, size, type, normalized, relativeOffset);
setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_FORMAT);
- VertexAttribute &attrib = mState.mVertexAttributes[attribIndex];
attrib.updateCachedElementLimit(mState.mVertexBindings[attrib.bindingIndex]);
}
@@ -383,24 +381,28 @@
mState.mCachedMappedArrayBuffers & mState.mEnabledAttributesMask;
}
-void VertexArray::setVertexAttribPointer(const Context *context,
- size_t attribIndex,
- gl::Buffer *boundBuffer,
- GLint size,
- VertexAttribType type,
- bool normalized,
- bool pureInteger,
- GLsizei stride,
- const void *pointer)
+ANGLE_INLINE void VertexArray::setVertexAttribPointerImpl(const Context *context,
+ ComponentType componentType,
+ bool pureInteger,
+ size_t attribIndex,
+ Buffer *boundBuffer,
+ GLint size,
+ VertexAttribType type,
+ bool normalized,
+ GLsizei stride,
+ const void *pointer)
{
ASSERT(attribIndex < getMaxAttribs());
GLintptr offset = boundBuffer ? reinterpret_cast<GLintptr>(pointer) : 0;
- setVertexAttribFormatImpl(attribIndex, size, type, normalized, pureInteger, 0);
- setVertexAttribBinding(context, attribIndex, static_cast<GLuint>(attribIndex));
-
VertexAttribute &attrib = mState.mVertexAttributes[attribIndex];
+ attrib.pureInteger = pureInteger;
+
+ SetComponentTypeMask(componentType, attribIndex, &mState.mVertexAttributesTypeMask);
+
+ setVertexAttribFormatImpl(&attrib, size, type, normalized, 0);
+ setVertexAttribBinding(context, attribIndex, static_cast<GLuint>(attribIndex));
GLsizei effectiveStride =
stride != 0 ? stride : static_cast<GLsizei>(ComputeVertexAttributeTypeSize(attrib));
@@ -415,6 +417,32 @@
boundBuffer == nullptr && pointer == nullptr);
}
+void VertexArray::setVertexAttribPointer(const Context *context,
+ size_t attribIndex,
+ gl::Buffer *boundBuffer,
+ GLint size,
+ VertexAttribType type,
+ bool normalized,
+ GLsizei stride,
+ const void *pointer)
+{
+ setVertexAttribPointerImpl(context, ComponentType::Float, false, attribIndex, boundBuffer, size,
+ type, normalized, stride, pointer);
+}
+
+void VertexArray::setVertexAttribIPointer(const Context *context,
+ size_t attribIndex,
+ gl::Buffer *boundBuffer,
+ GLint size,
+ VertexAttribType type,
+ GLsizei stride,
+ const void *pointer)
+{
+ ComponentType componentType = GetVertexAttributeComponentType(true, type);
+ setVertexAttribPointerImpl(context, componentType, true, attribIndex, boundBuffer, size, type,
+ false, stride, pointer);
+}
+
angle::Result VertexArray::syncState(const Context *context)
{
if (mDirtyBits.any())
diff --git a/src/libANGLE/VertexArray.h b/src/libANGLE/VertexArray.h
index 19f32e6..891d217 100644
--- a/src/libANGLE/VertexArray.h
+++ b/src/libANGLE/VertexArray.h
@@ -119,15 +119,24 @@
void detachBuffer(const Context *context, GLuint bufferName);
void setVertexAttribDivisor(const Context *context, size_t index, GLuint divisor);
void enableAttribute(size_t attribIndex, bool enabledState);
+
void setVertexAttribPointer(const Context *context,
size_t attribIndex,
Buffer *boundBuffer,
GLint size,
VertexAttribType type,
bool normalized,
- bool pureInteger,
GLsizei stride,
const void *pointer);
+
+ void setVertexAttribIPointer(const Context *context,
+ size_t attribIndex,
+ Buffer *boundBuffer,
+ GLint size,
+ VertexAttribType type,
+ GLsizei stride,
+ const void *pointer);
+
void setVertexAttribFormat(size_t attribIndex,
GLint size,
VertexAttribType type,
@@ -141,11 +150,10 @@
GLsizei stride);
void setVertexAttribBinding(const Context *context, size_t attribIndex, GLuint bindingIndex);
void setVertexBindingDivisor(size_t bindingIndex, GLuint divisor);
- void setVertexAttribFormatImpl(size_t attribIndex,
+ void setVertexAttribFormatImpl(VertexAttribute *attrib,
GLint size,
VertexAttribType type,
bool normalized,
- bool pureInteger,
GLuint relativeOffset);
void bindVertexBufferImpl(const Context *context,
size_t bindingIndex,
@@ -296,6 +304,17 @@
const void *indices,
IndexRange *indexRangeOut) const;
+ void setVertexAttribPointerImpl(const Context *context,
+ ComponentType componentType,
+ bool pureInteger,
+ size_t attribIndex,
+ Buffer *boundBuffer,
+ GLint size,
+ VertexAttribType type,
+ bool normalized,
+ GLsizei stride,
+ const void *pointer);
+
GLuint mId;
VertexArrayState mState;
diff --git a/src/libANGLE/VertexAttribute.cpp b/src/libANGLE/VertexAttribute.cpp
index 3bd6727..857f2e5 100644
--- a/src/libANGLE/VertexAttribute.cpp
+++ b/src/libANGLE/VertexAttribute.cpp
@@ -145,40 +145,6 @@
mCachedElementLimit = elementLimit.ValueOrDefault(kIntegerOverflow);
}
-size_t ComputeVertexAttributeTypeSize(const VertexAttribute &attrib)
-{
- switch (attrib.type)
- {
- case VertexAttribType::Byte:
- return attrib.size * sizeof(GLbyte);
- case VertexAttribType::UnsignedByte:
- return attrib.size * sizeof(GLubyte);
- case VertexAttribType::Short:
- return attrib.size * sizeof(GLshort);
- case VertexAttribType::UnsignedShort:
- return attrib.size * sizeof(GLushort);
- case VertexAttribType::Int:
- return attrib.size * sizeof(GLint);
- case VertexAttribType::UnsignedInt:
- return attrib.size * sizeof(GLuint);
- case VertexAttribType::Float:
- return attrib.size * sizeof(GLfloat);
- case VertexAttribType::HalfFloat:
- return attrib.size * sizeof(GLhalf);
- case VertexAttribType::Fixed:
- return attrib.size * sizeof(GLfixed);
- case VertexAttribType::Int2101010:
- // Packed attribute types don't scale by their component size.
- return 4;
- case VertexAttribType::UnsignedInt2101010:
- // Packed attribute types don't scale by their component size.
- return 4;
- default:
- UNREACHABLE();
- return 0;
- }
-}
-
size_t ComputeVertexAttributeStride(const VertexAttribute &attrib, const VertexBinding &binding)
{
// In ES 3.1, VertexAttribPointer will store the type size in the binding stride.
diff --git a/src/libANGLE/VertexAttribute.h b/src/libANGLE/VertexAttribute.h
index 3fb951f..de0cb07 100644
--- a/src/libANGLE/VertexAttribute.h
+++ b/src/libANGLE/VertexAttribute.h
@@ -104,7 +104,39 @@
GLint64 mCachedElementLimit;
};
-size_t ComputeVertexAttributeTypeSize(const VertexAttribute &attrib);
+ANGLE_INLINE size_t ComputeVertexAttributeTypeSize(const VertexAttribute &attrib)
+{
+ switch (attrib.type)
+ {
+ case VertexAttribType::Byte:
+ return attrib.size * sizeof(GLbyte);
+ case VertexAttribType::UnsignedByte:
+ return attrib.size * sizeof(GLubyte);
+ case VertexAttribType::Short:
+ return attrib.size * sizeof(GLshort);
+ case VertexAttribType::UnsignedShort:
+ return attrib.size * sizeof(GLushort);
+ case VertexAttribType::Int:
+ return attrib.size * sizeof(GLint);
+ case VertexAttribType::UnsignedInt:
+ return attrib.size * sizeof(GLuint);
+ case VertexAttribType::Float:
+ return attrib.size * sizeof(GLfloat);
+ case VertexAttribType::HalfFloat:
+ return attrib.size * sizeof(GLhalf);
+ case VertexAttribType::Fixed:
+ return attrib.size * sizeof(GLfixed);
+ case VertexAttribType::Int2101010:
+ // Packed attribute types don't scale by their component size.
+ return 4;
+ case VertexAttribType::UnsignedInt2101010:
+ // Packed attribute types don't scale by their component size.
+ return 4;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
// Warning: you should ensure binding really matches attrib.bindingIndex before using this function.
size_t ComputeVertexAttributeStride(const VertexAttribute &attrib, const VertexBinding &binding);
diff --git a/src/libANGLE/angletypes.cpp b/src/libANGLE/angletypes.cpp
index ad29013..1b51947 100644
--- a/src/libANGLE/angletypes.cpp
+++ b/src/libANGLE/angletypes.cpp
@@ -314,72 +314,15 @@
return !(lhs == rhs);
}
-ComponentTypeMask::ComponentTypeMask()
+bool ValidateComponentTypeMasks(unsigned long outputTypes,
+ unsigned long inputTypes,
+ unsigned long outputMask,
+ unsigned long inputMask)
{
- mTypeMask.reset();
-}
-
-ComponentTypeMask::ComponentTypeMask(const ComponentTypeMask &other) = default;
-
-ComponentTypeMask::~ComponentTypeMask() = default;
-
-void ComponentTypeMask::reset()
-{
- mTypeMask.reset();
-}
-
-bool ComponentTypeMask::none()
-{
- return mTypeMask.none();
-}
-
-void ComponentTypeMask::setIndex(GLenum type, size_t index)
-{
- ASSERT(index <= MAX_COMPONENT_TYPE_MASK_INDEX);
-
- mTypeMask &= ~(0x10001 << index);
-
- uint32_t m = 0;
- switch (type)
- {
- case GL_INT:
- m = 0x00001;
- break;
- case GL_UNSIGNED_INT:
- m = 0x10000;
- break;
- case GL_FLOAT:
- m = 0x10001;
- break;
- case GL_NONE:
- m = 0x00000;
- break;
- default:
- UNREACHABLE();
- }
-
- mTypeMask |= m << index;
-}
-
-unsigned long ComponentTypeMask::to_ulong() const
-{
- return mTypeMask.to_ulong();
-}
-
-void ComponentTypeMask::from_ulong(unsigned long mask)
-{
- mTypeMask = angle::BitSet<MAX_COMPONENT_TYPE_MASK_INDEX * 2>(mask);
-}
-
-bool ComponentTypeMask::Validate(unsigned long outputTypes,
- unsigned long inputTypes,
- unsigned long outputMask,
- unsigned long inputMask)
-{
- static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS <= MAX_COMPONENT_TYPE_MASK_INDEX,
+ static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS <= kMaxComponentTypeMaskIndex,
"Output/input masks should fit into 16 bits - 1 bit per draw buffer. The "
"corresponding type masks should fit into 32 bits - 2 bits per draw buffer.");
- static_assert(MAX_VERTEX_ATTRIBS <= MAX_COMPONENT_TYPE_MASK_INDEX,
+ static_assert(MAX_VERTEX_ATTRIBS <= kMaxComponentTypeMaskIndex,
"Output/input masks should fit into 16 bits - 1 bit per attrib. The "
"corresponding type masks should fit into 32 bits - 2 bits per attrib.");
@@ -389,8 +332,8 @@
// with the elswewhere used DrawBufferMask or AttributeMask.
// OR the masks with themselves, shifted 16 bits. This is to match our split type bits.
- outputMask |= (outputMask << MAX_COMPONENT_TYPE_MASK_INDEX);
- inputMask |= (inputMask << MAX_COMPONENT_TYPE_MASK_INDEX);
+ outputMask |= (outputMask << kMaxComponentTypeMaskIndex);
+ inputMask |= (inputMask << kMaxComponentTypeMaskIndex);
// To validate:
// 1. Remove any indexes that are not enabled in the input (& inputMask)
diff --git a/src/libANGLE/angletypes.h b/src/libANGLE/angletypes.h
index 9daa801..12e4122 100644
--- a/src/libANGLE/angletypes.h
+++ b/src/libANGLE/angletypes.h
@@ -383,27 +383,54 @@
template <typename T>
using TexLevelArray = std::array<T, IMPLEMENTATION_MAX_TEXTURE_LEVELS>;
-constexpr size_t MAX_COMPONENT_TYPE_MASK_INDEX = 16;
-struct ComponentTypeMask final
+enum class ComponentType
{
- ComponentTypeMask();
- ComponentTypeMask(const ComponentTypeMask &other);
- ~ComponentTypeMask();
- void reset();
- bool none();
- void setIndex(GLenum type, size_t index);
- unsigned long to_ulong() const;
- void from_ulong(unsigned long mask);
- static bool Validate(unsigned long outputTypes,
- unsigned long inputTypes,
- unsigned long outputMask,
- unsigned long inputMask);
-
- private:
- // Each index type is represented by 2 bits
- angle::BitSet<MAX_COMPONENT_TYPE_MASK_INDEX * 2> mTypeMask;
+ Float = 0,
+ Int = 1,
+ UnsignedInt = 2,
+ NoType = 3,
+ EnumCount = 4,
+ InvalidEnum = 4,
};
+constexpr ComponentType GLenumToComponentType(GLenum componentType)
+{
+ switch (componentType)
+ {
+ case GL_FLOAT:
+ return ComponentType::Float;
+ case GL_INT:
+ return ComponentType::Int;
+ case GL_UNSIGNED_INT:
+ return ComponentType::UnsignedInt;
+ case GL_NONE:
+ return ComponentType::NoType;
+ default:
+ return ComponentType::InvalidEnum;
+ }
+}
+
+constexpr angle::PackedEnumMap<ComponentType, uint32_t> kComponentMasks = {{
+ {ComponentType::Float, 0x10001},
+ {ComponentType::Int, 0x00001},
+ {ComponentType::UnsignedInt, 0x10000},
+}};
+
+constexpr size_t kMaxComponentTypeMaskIndex = 16;
+using ComponentTypeMask = angle::BitSet<kMaxComponentTypeMaskIndex * 2>;
+
+ANGLE_INLINE void SetComponentTypeMask(ComponentType type, size_t index, ComponentTypeMask *mask)
+{
+ ASSERT(index <= kMaxComponentTypeMaskIndex);
+ *mask &= ~(0x10001 << index);
+ *mask |= kComponentMasks[type] << index;
+}
+
+bool ValidateComponentTypeMasks(unsigned long outputTypes,
+ unsigned long inputTypes,
+ unsigned long outputMask,
+ unsigned long inputMask);
+
using ContextID = uintptr_t;
constexpr size_t kCubeFaceCount = 6;
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index 976241a..b427aba 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -367,10 +367,10 @@
const Program *program = context->getState().getLinkedProgram(context);
const Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
- return ComponentTypeMask::Validate(program->getDrawBufferTypeMask().to_ulong(),
- framebuffer->getDrawBufferTypeMask().to_ulong(),
- program->getActiveOutputVariables().to_ulong(),
- framebuffer->getDrawBufferMask().to_ulong());
+ return ValidateComponentTypeMasks(program->getDrawBufferTypeMask().to_ulong(),
+ framebuffer->getDrawBufferTypeMask().to_ulong(),
+ program->getActiveOutputVariables().to_ulong(),
+ framebuffer->getDrawBufferMask().to_ulong());
}
bool ValidateVertexShaderAttributeTypeMatch(Context *context)
@@ -383,13 +383,13 @@
unsigned long vaoAttribTypeBits = vao->getAttributesTypeMask().to_ulong();
unsigned long vaoAttribEnabledMask = vao->getAttributesMask().to_ulong();
- vaoAttribEnabledMask |= vaoAttribEnabledMask << MAX_COMPONENT_TYPE_MASK_INDEX;
+ vaoAttribEnabledMask |= vaoAttribEnabledMask << kMaxComponentTypeMaskIndex;
vaoAttribTypeBits = (vaoAttribEnabledMask & vaoAttribTypeBits);
vaoAttribTypeBits |= (~vaoAttribEnabledMask & stateCurrentValuesTypeBits);
- return ComponentTypeMask::Validate(program->getAttributesTypeMask().to_ulong(),
- vaoAttribTypeBits, program->getAttributesMask().to_ulong(),
- 0xFFFF);
+ return ValidateComponentTypeMasks(program->getAttributesTypeMask().to_ulong(),
+ vaoAttribTypeBits, program->getAttributesMask().to_ulong(),
+ 0xFFFF);
}
bool IsCompatibleDrawModeWithGeometryShader(PrimitiveMode drawMode,