Commit 6e18a238 by Jamie Madill Committed by Commit Bot

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: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent dd34b3b9
...@@ -4787,7 +4787,7 @@ void Context::vertexAttribPointer(GLuint index, ...@@ -4787,7 +4787,7 @@ void Context::vertexAttribPointer(GLuint index,
const void *ptr) const void *ptr)
{ {
mState.setVertexAttribPointer(this, index, mState.getTargetBuffer(BufferBinding::Array), size, mState.setVertexAttribPointer(this, index, mState.getTargetBuffer(BufferBinding::Array), size,
type, ConvertToBool(normalized), false, stride, ptr); type, ConvertToBool(normalized), stride, ptr);
mStateCache.onVertexArrayStateChange(this); mStateCache.onVertexArrayStateChange(this);
} }
...@@ -4834,8 +4834,8 @@ void Context::vertexAttribIPointer(GLuint index, ...@@ -4834,8 +4834,8 @@ void Context::vertexAttribIPointer(GLuint index,
GLsizei stride, GLsizei stride,
const void *pointer) const void *pointer)
{ {
mState.setVertexAttribPointer(this, index, mState.getTargetBuffer(BufferBinding::Array), size, mState.setVertexAttribIPointer(this, index, mState.getTargetBuffer(BufferBinding::Array), size,
type, false, true, stride, pointer); type, stride, pointer);
mStateCache.onVertexArrayStateChange(this); mStateCache.onVertexArrayStateChange(this);
} }
......
...@@ -673,7 +673,7 @@ Framebuffer::Framebuffer(const Context *context, egl::Surface *surface) ...@@ -673,7 +673,7 @@ Framebuffer::Framebuffer(const Context *context, egl::Surface *surface)
FramebufferAttachment::kDefaultMultiviewLayout, FramebufferAttachment::kDefaultMultiviewLayout,
FramebufferAttachment::kDefaultViewportOffsets); FramebufferAttachment::kDefaultViewportOffsets);
} }
mState.mDrawBufferTypeMask.setIndex(getDrawbufferWriteType(0), 0); SetComponentTypeMask(getDrawbufferWriteType(0), 0, &mState.mDrawBufferTypeMask);
} }
Framebuffer::Framebuffer(rx::GLImplFactory *factory) Framebuffer::Framebuffer(rx::GLImplFactory *factory)
...@@ -684,7 +684,7 @@ Framebuffer::Framebuffer(rx::GLImplFactory *factory) ...@@ -684,7 +684,7 @@ Framebuffer::Framebuffer(rx::GLImplFactory *factory)
mDirtyStencilAttachmentBinding(this, DIRTY_BIT_STENCIL_ATTACHMENT) mDirtyStencilAttachmentBinding(this, DIRTY_BIT_STENCIL_ATTACHMENT)
{ {
mDirtyColorAttachmentBindings.emplace_back(this, DIRTY_BIT_COLOR_ATTACHMENT_0); mDirtyColorAttachmentBindings.emplace_back(this, DIRTY_BIT_COLOR_ATTACHMENT_0);
mState.mDrawBufferTypeMask.setIndex(getDrawbufferWriteType(0), 0); SetComponentTypeMask(getDrawbufferWriteType(0), 0, &mState.mDrawBufferTypeMask);
} }
Framebuffer::~Framebuffer() Framebuffer::~Framebuffer()
...@@ -871,7 +871,7 @@ void Framebuffer::setDrawBuffers(size_t count, const GLenum *buffers) ...@@ -871,7 +871,7 @@ void Framebuffer::setDrawBuffers(size_t count, const GLenum *buffers)
for (size_t index = 0; index < count; ++index) 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()) if (drawStates[index] != GL_NONE && mState.mColorAttachments[index].isAttached())
{ {
...@@ -885,23 +885,24 @@ const FramebufferAttachment *Framebuffer::getDrawBuffer(size_t drawBuffer) const ...@@ -885,23 +885,24 @@ const FramebufferAttachment *Framebuffer::getDrawBuffer(size_t drawBuffer) const
return mState.getDrawBuffer(drawBuffer); return mState.getDrawBuffer(drawBuffer);
} }
GLenum Framebuffer::getDrawbufferWriteType(size_t drawBuffer) const ComponentType Framebuffer::getDrawbufferWriteType(size_t drawBuffer) const
{ {
const FramebufferAttachment *attachment = mState.getDrawBuffer(drawBuffer); const FramebufferAttachment *attachment = mState.getDrawBuffer(drawBuffer);
if (attachment == nullptr) if (attachment == nullptr)
{ {
return GL_NONE; return ComponentType::NoType;
} }
GLenum componentType = attachment->getFormat().info->componentType; GLenum componentType = attachment->getFormat().info->componentType;
switch (componentType) switch (componentType)
{ {
case GL_INT: case GL_INT:
return ComponentType::Int;
case GL_UNSIGNED_INT: case GL_UNSIGNED_INT:
return componentType; return ComponentType::UnsignedInt;
default: default:
return GL_FLOAT; return ComponentType::Float;
} }
} }
...@@ -1761,7 +1762,8 @@ void Framebuffer::setAttachmentImpl(const Context *context, ...@@ -1761,7 +1762,8 @@ void Framebuffer::setAttachmentImpl(const Context *context,
// formsRenderingFeedbackLoopWith // formsRenderingFeedbackLoopWith
bool enabled = (type != GL_NONE && getDrawBufferState(colorIndex) != GL_NONE); bool enabled = (type != GL_NONE && getDrawBufferState(colorIndex) != GL_NONE);
mState.mEnabledDrawBuffers.set(colorIndex, enabled); mState.mEnabledDrawBuffers.set(colorIndex, enabled);
mState.mDrawBufferTypeMask.setIndex(getDrawbufferWriteType(colorIndex), colorIndex); SetComponentTypeMask(getDrawbufferWriteType(colorIndex), colorIndex,
&mState.mDrawBufferTypeMask);
} }
break; break;
} }
......
...@@ -217,7 +217,7 @@ class Framebuffer final : public angle::ObserverInterface, ...@@ -217,7 +217,7 @@ class Framebuffer final : public angle::ObserverInterface,
const std::vector<GLenum> &getDrawBufferStates() const; const std::vector<GLenum> &getDrawBufferStates() const;
void setDrawBuffers(size_t count, const GLenum *buffers); void setDrawBuffers(size_t count, const GLenum *buffers);
const FramebufferAttachment *getDrawBuffer(size_t drawBuffer) const; const FramebufferAttachment *getDrawBuffer(size_t drawBuffer) const;
GLenum getDrawbufferWriteType(size_t drawBuffer) const; ComponentType getDrawbufferWriteType(size_t drawBuffer) const;
ComponentTypeMask getDrawBufferTypeMask() const; ComponentTypeMask getDrawBufferTypeMask() const;
DrawBufferMask getDrawBufferMask() const; DrawBufferMask getDrawBufferMask() const;
bool hasEnabledDrawBuffer() const; bool hasEnabledDrawBuffer() const;
......
...@@ -246,8 +246,8 @@ angle::Result MemoryProgramCache::Deserialize(const Context *context, ...@@ -246,8 +246,8 @@ angle::Result MemoryProgramCache::Deserialize(const Context *context,
static_assert(MAX_VERTEX_ATTRIBS * 2 <= sizeof(uint32_t) * 8, static_assert(MAX_VERTEX_ATTRIBS * 2 <= sizeof(uint32_t) * 8,
"All bits of mAttributesTypeMask types and mask fit into 32 bits each"); "All bits of mAttributesTypeMask types and mask fit into 32 bits each");
state->mAttributesTypeMask.from_ulong(stream.readInt<uint32_t>()); state->mAttributesTypeMask = gl::ComponentTypeMask(stream.readInt<uint32_t>());
state->mAttributesMask = stream.readInt<gl::AttributesMask>(); state->mAttributesMask = stream.readInt<gl::AttributesMask>();
static_assert(MAX_VERTEX_ATTRIBS <= sizeof(unsigned long) * 8, static_assert(MAX_VERTEX_ATTRIBS <= sizeof(unsigned long) * 8,
"Too many vertex attribs for mask"); "Too many vertex attribs for mask");
...@@ -404,7 +404,7 @@ angle::Result MemoryProgramCache::Deserialize(const Context *context, ...@@ -404,7 +404,7 @@ angle::Result MemoryProgramCache::Deserialize(const Context *context,
static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS * 2 <= 8 * sizeof(uint32_t), static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS * 2 <= 8 * sizeof(uint32_t),
"All bits of mDrawBufferTypeMask and mActiveOutputVariables types and mask fit " "All bits of mDrawBufferTypeMask and mActiveOutputVariables types and mask fit "
"into 32 bits each"); "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>(); state->mActiveOutputVariables = stream.readInt<gl::DrawBufferMask>();
unsigned int samplerRangeLow = stream.readInt<unsigned int>(); unsigned int samplerRangeLow = stream.readInt<unsigned int>();
......
...@@ -3097,8 +3097,10 @@ bool Program::linkAttributes(const Caps &caps, InfoLog &infoLog) ...@@ -3097,8 +3097,10 @@ bool Program::linkAttributes(const Caps &caps, InfoLog &infoLog)
// gl_VertexID and gl_InstanceID are active attributes but don't have a bound attribute. // gl_VertexID and gl_InstanceID are active attributes but don't have a bound attribute.
if (!attribute.isBuiltIn()) if (!attribute.isBuiltIn())
{ {
mState.mAttributesTypeMask.setIndex(VariableComponentType(attribute.type), ComponentType componentType =
location); GLenumToComponentType(VariableComponentType(attribute.type));
SetComponentTypeMask(componentType, location, &mState.mAttributesTypeMask);
mState.mAttributesMask.set(location); mState.mAttributesMask.set(location);
} }
} }
...@@ -3648,7 +3650,9 @@ bool Program::linkOutputVariables(const Caps &caps, ...@@ -3648,7 +3650,9 @@ bool Program::linkOutputVariables(const Caps &caps,
ASSERT(location < mState.mActiveOutputVariables.size()); ASSERT(location < mState.mActiveOutputVariables.size());
mState.mActiveOutputVariables.set(location); mState.mActiveOutputVariables.set(location);
mState.mOutputVariableTypes[location] = VariableComponentType(outputVariable.type); mState.mOutputVariableTypes[location] = VariableComponentType(outputVariable.type);
mState.mDrawBufferTypeMask.setIndex(mState.mOutputVariableTypes[location], location); ComponentType componentType =
GLenumToComponentType(mState.mOutputVariableTypes[location]);
SetComponentTypeMask(componentType, location, &mState.mDrawBufferTypeMask);
} }
} }
......
...@@ -355,7 +355,7 @@ void State::initialize(Context *context) ...@@ -355,7 +355,7 @@ void State::initialize(Context *context)
// Set all indexes in state attributes type mask to float (default) // Set all indexes in state attributes type mask to float (default)
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{ {
mCurrentValuesTypeMask.setIndex(GL_FLOAT, i); SetComponentTypeMask(ComponentType::Float, i, &mCurrentValuesTypeMask);
} }
mUniformBuffers.resize(caps.maxUniformBufferBindings); mUniformBuffers.resize(caps.maxUniformBufferBindings);
...@@ -1621,7 +1621,7 @@ void State::setVertexAttribf(GLuint index, const GLfloat values[4]) ...@@ -1621,7 +1621,7 @@ void State::setVertexAttribf(GLuint index, const GLfloat values[4])
mVertexAttribCurrentValues[index].setFloatValues(values); mVertexAttribCurrentValues[index].setFloatValues(values);
mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES); mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
mDirtyCurrentValues.set(index); mDirtyCurrentValues.set(index);
mCurrentValuesTypeMask.setIndex(GL_FLOAT, index); SetComponentTypeMask(ComponentType::Float, index, &mCurrentValuesTypeMask);
} }
void State::setVertexAttribu(GLuint index, const GLuint values[4]) void State::setVertexAttribu(GLuint index, const GLuint values[4])
...@@ -1630,7 +1630,7 @@ void State::setVertexAttribu(GLuint index, const GLuint values[4]) ...@@ -1630,7 +1630,7 @@ void State::setVertexAttribu(GLuint index, const GLuint values[4])
mVertexAttribCurrentValues[index].setUnsignedIntValues(values); mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES); mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
mDirtyCurrentValues.set(index); mDirtyCurrentValues.set(index);
mCurrentValuesTypeMask.setIndex(GL_UNSIGNED_INT, index); SetComponentTypeMask(ComponentType::UnsignedInt, index, &mCurrentValuesTypeMask);
} }
void State::setVertexAttribi(GLuint index, const GLint values[4]) void State::setVertexAttribi(GLuint index, const GLint values[4])
...@@ -1639,7 +1639,7 @@ void State::setVertexAttribi(GLuint index, const GLint values[4]) ...@@ -1639,7 +1639,7 @@ void State::setVertexAttribi(GLuint index, const GLint values[4])
mVertexAttribCurrentValues[index].setIntValues(values); mVertexAttribCurrentValues[index].setIntValues(values);
mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES); mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
mDirtyCurrentValues.set(index); mDirtyCurrentValues.set(index);
mCurrentValuesTypeMask.setIndex(GL_INT, index); SetComponentTypeMask(ComponentType::Int, index, &mCurrentValuesTypeMask);
} }
void State::setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor) void State::setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor)
......
...@@ -347,12 +347,24 @@ class State : angle::NonCopyable ...@@ -347,12 +347,24 @@ class State : angle::NonCopyable
GLint size, GLint size,
VertexAttribType type, VertexAttribType type,
bool normalized, bool normalized,
bool pureInteger,
GLsizei stride, GLsizei stride,
const void *pointer) const void *pointer)
{ {
mVertexArray->setVertexAttribPointer(context, attribNum, boundBuffer, size, type, 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); mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
} }
......
...@@ -24,30 +24,30 @@ bool IsElementArrayBufferSubjectIndex(angle::SubjectIndex subjectIndex) ...@@ -24,30 +24,30 @@ bool IsElementArrayBufferSubjectIndex(angle::SubjectIndex subjectIndex)
return (subjectIndex == MAX_VERTEX_ATTRIBS); 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::Byte:
case VertexAttribType::Short: case VertexAttribType::Short:
case VertexAttribType::Int: case VertexAttribType::Int:
return GL_INT; return ComponentType::Int;
case VertexAttribType::UnsignedByte: case VertexAttribType::UnsignedByte:
case VertexAttribType::UnsignedShort: case VertexAttribType::UnsignedShort:
case VertexAttribType::UnsignedInt: case VertexAttribType::UnsignedInt:
return GL_UNSIGNED_INT; return ComponentType::UnsignedInt;
default: default:
UNREACHABLE(); UNREACHABLE();
return GL_NONE; return ComponentType::NoType;
} }
} }
else else
{ {
return GL_FLOAT; return ComponentType::Float;
} }
} }
...@@ -321,23 +321,16 @@ void VertexArray::setVertexBindingDivisor(size_t bindingIndex, GLuint divisor) ...@@ -321,23 +321,16 @@ void VertexArray::setVertexBindingDivisor(size_t bindingIndex, GLuint divisor)
} }
} }
ANGLE_INLINE void VertexArray::setVertexAttribFormatImpl(size_t attribIndex, ANGLE_INLINE void VertexArray::setVertexAttribFormatImpl(VertexAttribute *attrib,
GLint size, GLint size,
VertexAttribType type, VertexAttribType type,
bool normalized, bool normalized,
bool pureInteger,
GLuint relativeOffset) GLuint relativeOffset)
{ {
ASSERT(attribIndex < getMaxAttribs());
VertexAttribute *attrib = &mState.mVertexAttributes[attribIndex];
attrib->size = size; attrib->size = size;
attrib->type = type; attrib->type = type;
attrib->normalized = normalized; attrib->normalized = normalized;
attrib->pureInteger = pureInteger;
attrib->relativeOffset = relativeOffset; attrib->relativeOffset = relativeOffset;
mState.mVertexAttributesTypeMask.setIndex(GetVertexAttributeBaseType(*attrib), attribIndex);
} }
void VertexArray::setVertexAttribFormat(size_t attribIndex, void VertexArray::setVertexAttribFormat(size_t attribIndex,
...@@ -347,10 +340,15 @@ void VertexArray::setVertexAttribFormat(size_t attribIndex, ...@@ -347,10 +340,15 @@ void VertexArray::setVertexAttribFormat(size_t attribIndex,
bool pureInteger, bool pureInteger,
GLuint relativeOffset) 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); setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_FORMAT);
VertexAttribute &attrib = mState.mVertexAttributes[attribIndex];
attrib.updateCachedElementLimit(mState.mVertexBindings[attrib.bindingIndex]); attrib.updateCachedElementLimit(mState.mVertexBindings[attrib.bindingIndex]);
} }
...@@ -383,24 +381,28 @@ void VertexArray::enableAttribute(size_t attribIndex, bool enabledState) ...@@ -383,24 +381,28 @@ void VertexArray::enableAttribute(size_t attribIndex, bool enabledState)
mState.mCachedMappedArrayBuffers & mState.mEnabledAttributesMask; mState.mCachedMappedArrayBuffers & mState.mEnabledAttributesMask;
} }
void VertexArray::setVertexAttribPointer(const Context *context, ANGLE_INLINE void VertexArray::setVertexAttribPointerImpl(const Context *context,
size_t attribIndex, ComponentType componentType,
gl::Buffer *boundBuffer, bool pureInteger,
GLint size, size_t attribIndex,
VertexAttribType type, Buffer *boundBuffer,
bool normalized, GLint size,
bool pureInteger, VertexAttribType type,
GLsizei stride, bool normalized,
const void *pointer) GLsizei stride,
const void *pointer)
{ {
ASSERT(attribIndex < getMaxAttribs()); ASSERT(attribIndex < getMaxAttribs());
GLintptr offset = boundBuffer ? reinterpret_cast<GLintptr>(pointer) : 0; 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]; 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 = GLsizei effectiveStride =
stride != 0 ? stride : static_cast<GLsizei>(ComputeVertexAttributeTypeSize(attrib)); stride != 0 ? stride : static_cast<GLsizei>(ComputeVertexAttributeTypeSize(attrib));
...@@ -415,6 +417,32 @@ void VertexArray::setVertexAttribPointer(const Context *context, ...@@ -415,6 +417,32 @@ void VertexArray::setVertexAttribPointer(const Context *context,
boundBuffer == nullptr && pointer == nullptr); 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) angle::Result VertexArray::syncState(const Context *context)
{ {
if (mDirtyBits.any()) if (mDirtyBits.any())
......
...@@ -119,15 +119,24 @@ class VertexArray final : public angle::ObserverInterface, ...@@ -119,15 +119,24 @@ class VertexArray final : public angle::ObserverInterface,
void detachBuffer(const Context *context, GLuint bufferName); void detachBuffer(const Context *context, GLuint bufferName);
void setVertexAttribDivisor(const Context *context, size_t index, GLuint divisor); void setVertexAttribDivisor(const Context *context, size_t index, GLuint divisor);
void enableAttribute(size_t attribIndex, bool enabledState); void enableAttribute(size_t attribIndex, bool enabledState);
void setVertexAttribPointer(const Context *context, void setVertexAttribPointer(const Context *context,
size_t attribIndex, size_t attribIndex,
Buffer *boundBuffer, Buffer *boundBuffer,
GLint size, GLint size,
VertexAttribType type, VertexAttribType type,
bool normalized, bool normalized,
bool pureInteger,
GLsizei stride, GLsizei stride,
const void *pointer); 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, void setVertexAttribFormat(size_t attribIndex,
GLint size, GLint size,
VertexAttribType type, VertexAttribType type,
...@@ -141,11 +150,10 @@ class VertexArray final : public angle::ObserverInterface, ...@@ -141,11 +150,10 @@ class VertexArray final : public angle::ObserverInterface,
GLsizei stride); GLsizei stride);
void setVertexAttribBinding(const Context *context, size_t attribIndex, GLuint bindingIndex); void setVertexAttribBinding(const Context *context, size_t attribIndex, GLuint bindingIndex);
void setVertexBindingDivisor(size_t bindingIndex, GLuint divisor); void setVertexBindingDivisor(size_t bindingIndex, GLuint divisor);
void setVertexAttribFormatImpl(size_t attribIndex, void setVertexAttribFormatImpl(VertexAttribute *attrib,
GLint size, GLint size,
VertexAttribType type, VertexAttribType type,
bool normalized, bool normalized,
bool pureInteger,
GLuint relativeOffset); GLuint relativeOffset);
void bindVertexBufferImpl(const Context *context, void bindVertexBufferImpl(const Context *context,
size_t bindingIndex, size_t bindingIndex,
...@@ -296,6 +304,17 @@ class VertexArray final : public angle::ObserverInterface, ...@@ -296,6 +304,17 @@ class VertexArray final : public angle::ObserverInterface,
const void *indices, const void *indices,
IndexRange *indexRangeOut) const; 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; GLuint mId;
VertexArrayState mState; VertexArrayState mState;
......
...@@ -145,40 +145,6 @@ void VertexAttribute::updateCachedElementLimit(const VertexBinding &binding) ...@@ -145,40 +145,6 @@ void VertexAttribute::updateCachedElementLimit(const VertexBinding &binding)
mCachedElementLimit = elementLimit.ValueOrDefault(kIntegerOverflow); 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) size_t ComputeVertexAttributeStride(const VertexAttribute &attrib, const VertexBinding &binding)
{ {
// In ES 3.1, VertexAttribPointer will store the type size in the binding stride. // In ES 3.1, VertexAttribPointer will store the type size in the binding stride.
......
...@@ -104,7 +104,39 @@ struct VertexAttribute final : private angle::NonCopyable ...@@ -104,7 +104,39 @@ struct VertexAttribute final : private angle::NonCopyable
GLint64 mCachedElementLimit; 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. // Warning: you should ensure binding really matches attrib.bindingIndex before using this function.
size_t ComputeVertexAttributeStride(const VertexAttribute &attrib, const VertexBinding &binding); size_t ComputeVertexAttributeStride(const VertexAttribute &attrib, const VertexBinding &binding);
......
...@@ -314,72 +314,15 @@ bool operator!=(const Extents &lhs, const Extents &rhs) ...@@ -314,72 +314,15 @@ bool operator!=(const Extents &lhs, const Extents &rhs)
return !(lhs == rhs); return !(lhs == rhs);
} }
ComponentTypeMask::ComponentTypeMask() bool ValidateComponentTypeMasks(unsigned long outputTypes,
unsigned long inputTypes,
unsigned long outputMask,
unsigned long inputMask)
{ {
mTypeMask.reset(); static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS <= kMaxComponentTypeMaskIndex,
}
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,
"Output/input masks should fit into 16 bits - 1 bit per draw buffer. The " "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."); "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 " "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."); "corresponding type masks should fit into 32 bits - 2 bits per attrib.");
...@@ -389,8 +332,8 @@ bool ComponentTypeMask::Validate(unsigned long outputTypes, ...@@ -389,8 +332,8 @@ bool ComponentTypeMask::Validate(unsigned long outputTypes,
// with the elswewhere used DrawBufferMask or AttributeMask. // with the elswewhere used DrawBufferMask or AttributeMask.
// OR the masks with themselves, shifted 16 bits. This is to match our split type bits. // OR the masks with themselves, shifted 16 bits. This is to match our split type bits.
outputMask |= (outputMask << MAX_COMPONENT_TYPE_MASK_INDEX); outputMask |= (outputMask << kMaxComponentTypeMaskIndex);
inputMask |= (inputMask << MAX_COMPONENT_TYPE_MASK_INDEX); inputMask |= (inputMask << kMaxComponentTypeMaskIndex);
// To validate: // To validate:
// 1. Remove any indexes that are not enabled in the input (& inputMask) // 1. Remove any indexes that are not enabled in the input (& inputMask)
......
...@@ -383,27 +383,54 @@ using DrawBufferMask = angle::BitSet<IMPLEMENTATION_MAX_DRAW_BUFFERS>; ...@@ -383,27 +383,54 @@ using DrawBufferMask = angle::BitSet<IMPLEMENTATION_MAX_DRAW_BUFFERS>;
template <typename T> template <typename T>
using TexLevelArray = std::array<T, IMPLEMENTATION_MAX_TEXTURE_LEVELS>; using TexLevelArray = std::array<T, IMPLEMENTATION_MAX_TEXTURE_LEVELS>;
constexpr size_t MAX_COMPONENT_TYPE_MASK_INDEX = 16; enum class ComponentType
struct ComponentTypeMask final
{ {
ComponentTypeMask(); Float = 0,
ComponentTypeMask(const ComponentTypeMask &other); Int = 1,
~ComponentTypeMask(); UnsignedInt = 2,
void reset(); NoType = 3,
bool none(); EnumCount = 4,
void setIndex(GLenum type, size_t index); InvalidEnum = 4,
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;
}; };
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; using ContextID = uintptr_t;
constexpr size_t kCubeFaceCount = 6; constexpr size_t kCubeFaceCount = 6;
......
...@@ -367,10 +367,10 @@ bool ValidateFragmentShaderColorBufferTypeMatch(Context *context) ...@@ -367,10 +367,10 @@ bool ValidateFragmentShaderColorBufferTypeMatch(Context *context)
const Program *program = context->getState().getLinkedProgram(context); const Program *program = context->getState().getLinkedProgram(context);
const Framebuffer *framebuffer = context->getState().getDrawFramebuffer(); const Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
return ComponentTypeMask::Validate(program->getDrawBufferTypeMask().to_ulong(), return ValidateComponentTypeMasks(program->getDrawBufferTypeMask().to_ulong(),
framebuffer->getDrawBufferTypeMask().to_ulong(), framebuffer->getDrawBufferTypeMask().to_ulong(),
program->getActiveOutputVariables().to_ulong(), program->getActiveOutputVariables().to_ulong(),
framebuffer->getDrawBufferMask().to_ulong()); framebuffer->getDrawBufferMask().to_ulong());
} }
bool ValidateVertexShaderAttributeTypeMatch(Context *context) bool ValidateVertexShaderAttributeTypeMatch(Context *context)
...@@ -383,13 +383,13 @@ bool ValidateVertexShaderAttributeTypeMatch(Context *context) ...@@ -383,13 +383,13 @@ bool ValidateVertexShaderAttributeTypeMatch(Context *context)
unsigned long vaoAttribTypeBits = vao->getAttributesTypeMask().to_ulong(); unsigned long vaoAttribTypeBits = vao->getAttributesTypeMask().to_ulong();
unsigned long vaoAttribEnabledMask = vao->getAttributesMask().to_ulong(); unsigned long vaoAttribEnabledMask = vao->getAttributesMask().to_ulong();
vaoAttribEnabledMask |= vaoAttribEnabledMask << MAX_COMPONENT_TYPE_MASK_INDEX; vaoAttribEnabledMask |= vaoAttribEnabledMask << kMaxComponentTypeMaskIndex;
vaoAttribTypeBits = (vaoAttribEnabledMask & vaoAttribTypeBits); vaoAttribTypeBits = (vaoAttribEnabledMask & vaoAttribTypeBits);
vaoAttribTypeBits |= (~vaoAttribEnabledMask & stateCurrentValuesTypeBits); vaoAttribTypeBits |= (~vaoAttribEnabledMask & stateCurrentValuesTypeBits);
return ComponentTypeMask::Validate(program->getAttributesTypeMask().to_ulong(), return ValidateComponentTypeMasks(program->getAttributesTypeMask().to_ulong(),
vaoAttribTypeBits, program->getAttributesMask().to_ulong(), vaoAttribTypeBits, program->getAttributesMask().to_ulong(),
0xFFFF); 0xFFFF);
} }
bool IsCompatibleDrawModeWithGeometryShader(PrimitiveMode drawMode, bool IsCompatibleDrawModeWithGeometryShader(PrimitiveMode drawMode,
......
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