Commit 6d51c70c by Jamie Madill

Implement dirty bits acceleration for VertexArrayGL.

BUG=angleproject:1040 TEST=angle_end2end_tests,angle_perftests,WebGL Change-Id: I91d9aea5eefb58ecaf5b1cc95926fddb2aa846ea Reviewed-on: https://chromium-review.googlesource.com/289570Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 49e8de70
...@@ -1481,7 +1481,7 @@ void Context::detachSampler(GLuint sampler) ...@@ -1481,7 +1481,7 @@ void Context::detachSampler(GLuint sampler)
void Context::setVertexAttribDivisor(GLuint index, GLuint divisor) void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
{ {
mState.getVertexArray()->setVertexAttribDivisor(index, divisor); mState.setVertexAttribDivisor(index, divisor);
} }
void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param) void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
......
...@@ -846,6 +846,8 @@ bool State::removeDrawFramebufferBinding(GLuint framebuffer) ...@@ -846,6 +846,8 @@ bool State::removeDrawFramebufferBinding(GLuint framebuffer)
void State::setVertexArrayBinding(VertexArray *vertexArray) void State::setVertexArrayBinding(VertexArray *vertexArray)
{ {
mVertexArray = vertexArray; mVertexArray = vertexArray;
mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
} }
GLuint State::getVertexArrayId() const GLuint State::getVertexArrayId() const
...@@ -865,6 +867,8 @@ bool State::removeVertexArrayBinding(GLuint vertexArray) ...@@ -865,6 +867,8 @@ bool State::removeVertexArrayBinding(GLuint vertexArray)
if (mVertexArray->id() == vertexArray) if (mVertexArray->id() == vertexArray)
{ {
mVertexArray = NULL; mVertexArray = NULL;
mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
return true; return true;
} }
...@@ -1051,6 +1055,7 @@ Buffer *State::getTargetBuffer(GLenum target) const ...@@ -1051,6 +1055,7 @@ Buffer *State::getTargetBuffer(GLenum target) const
void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled) void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
{ {
getVertexArray()->enableAttribute(attribNum, enabled); getVertexArray()->enableAttribute(attribNum, enabled);
mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
} }
void State::setVertexAttribf(GLuint index, const GLfloat values[4]) void State::setVertexAttribf(GLuint index, const GLfloat values[4])
...@@ -1074,10 +1079,23 @@ void State::setVertexAttribi(GLuint index, const GLint values[4]) ...@@ -1074,10 +1079,23 @@ void State::setVertexAttribi(GLuint index, const GLint values[4])
mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index); mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
} }
void State::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized, void State::setVertexAttribState(unsigned int attribNum,
bool pureInteger, GLsizei stride, const void *pointer) Buffer *boundBuffer,
GLint size,
GLenum type,
bool normalized,
bool pureInteger,
GLsizei stride,
const void *pointer)
{ {
getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer); getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
}
void State::setVertexAttribDivisor(GLuint index, GLuint divisor)
{
getVertexArray()->setVertexAttribDivisor(index, divisor);
mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_OBJECT);
} }
const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
......
...@@ -226,6 +226,7 @@ class State : angle::NonCopyable ...@@ -226,6 +226,7 @@ class State : angle::NonCopyable
void setVertexAttribi(GLuint index, const GLint values[4]); void setVertexAttribi(GLuint index, const GLint values[4]);
void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
bool normalized, bool pureInteger, GLsizei stride, const void *pointer); 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(unsigned int attribNum) const;
const void *getVertexAttribPointer(unsigned int attribNum) const; const void *getVertexAttribPointer(unsigned int attribNum) const;
......
...@@ -73,12 +73,14 @@ void VertexArray::setVertexAttribDivisor(size_t index, GLuint divisor) ...@@ -73,12 +73,14 @@ void VertexArray::setVertexAttribDivisor(size_t index, GLuint divisor)
{ {
ASSERT(index < getMaxAttribs()); ASSERT(index < getMaxAttribs());
mData.mVertexAttributes[index].divisor = divisor; mData.mVertexAttributes[index].divisor = divisor;
mDirtyBits.set(DIRTY_BIT_ATTRIB_0_DIVISOR + index);
} }
void VertexArray::enableAttribute(size_t attributeIndex, bool enabledState) void VertexArray::enableAttribute(size_t attributeIndex, bool enabledState)
{ {
ASSERT(attributeIndex < getMaxAttribs()); ASSERT(attributeIndex < getMaxAttribs());
mData.mVertexAttributes[attributeIndex].enabled = enabledState; mData.mVertexAttributes[attributeIndex].enabled = enabledState;
mDirtyBits.set(DIRTY_BIT_ATTRIB_0_ENABLED + attributeIndex);
// Update state cache // Update state cache
if (enabledState) if (enabledState)
...@@ -109,11 +111,22 @@ void VertexArray::setAttributeState(size_t attributeIndex, gl::Buffer *boundBuff ...@@ -109,11 +111,22 @@ void VertexArray::setAttributeState(size_t attributeIndex, gl::Buffer *boundBuff
attrib->pureInteger = pureInteger; attrib->pureInteger = pureInteger;
attrib->stride = stride; attrib->stride = stride;
attrib->pointer = pointer; attrib->pointer = pointer;
mDirtyBits.set(DIRTY_BIT_ATTRIB_0_POINTER + attributeIndex);
} }
void VertexArray::setElementArrayBuffer(Buffer *buffer) void VertexArray::setElementArrayBuffer(Buffer *buffer)
{ {
mData.mElementArrayBuffer.set(buffer); mData.mElementArrayBuffer.set(buffer);
mDirtyBits.set(DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
}
void VertexArray::syncImplState()
{
if (mDirtyBits.any())
{
mVertexArray->syncState(mDirtyBits);
mDirtyBits.reset();
}
} }
} }
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "libANGLE/RefCountObject.h" #include "libANGLE/RefCountObject.h"
#include "libANGLE/Constants.h" #include "libANGLE/Constants.h"
#include "libANGLE/State.h"
#include "libANGLE/VertexAttribute.h" #include "libANGLE/VertexAttribute.h"
#include <vector> #include <vector>
...@@ -29,6 +30,9 @@ namespace gl ...@@ -29,6 +30,9 @@ namespace gl
{ {
class Buffer; class Buffer;
// Used in other places.
typedef std::bitset<MAX_VERTEX_ATTRIBS> AttributesMask;
class VertexArray class VertexArray
{ {
public: public:
...@@ -66,6 +70,10 @@ class VertexArray ...@@ -66,6 +70,10 @@ class VertexArray
size_t getMaxAttribs() const { return mVertexAttributes.size(); } size_t getMaxAttribs() const { return mVertexAttributes.size(); }
size_t getMaxEnabledAttribute() const { return mMaxEnabledAttribute; } size_t getMaxEnabledAttribute() const { return mMaxEnabledAttribute; }
const std::vector<VertexAttribute> &getVertexAttributes() const { return mVertexAttributes; } const std::vector<VertexAttribute> &getVertexAttributes() const { return mVertexAttributes; }
const VertexAttribute &getVertexAttribute(size_t index) const
{
return mVertexAttributes[index];
}
private: private:
friend class VertexArray; friend class VertexArray;
...@@ -74,12 +82,37 @@ class VertexArray ...@@ -74,12 +82,37 @@ class VertexArray
size_t mMaxEnabledAttribute; size_t mMaxEnabledAttribute;
}; };
enum DirtyBitType
{
DIRTY_BIT_ELEMENT_ARRAY_BUFFER,
// Reserve bits for enabled flags
DIRTY_BIT_ATTRIB_0_ENABLED,
DIRTY_BIT_ATTRIB_MAX_ENABLED = DIRTY_BIT_ATTRIB_0_ENABLED + gl::MAX_VERTEX_ATTRIBS,
// Reserve bits for attrib pointers
DIRTY_BIT_ATTRIB_0_POINTER = DIRTY_BIT_ATTRIB_MAX_ENABLED,
DIRTY_BIT_ATTRIB_MAX_POINTER = DIRTY_BIT_ATTRIB_0_POINTER + gl::MAX_VERTEX_ATTRIBS,
// Reserve bits for divisors
DIRTY_BIT_ATTRIB_0_DIVISOR = DIRTY_BIT_ATTRIB_MAX_POINTER,
DIRTY_BIT_ATTRIB_MAX_DIVISOR = DIRTY_BIT_ATTRIB_0_DIVISOR + gl::MAX_VERTEX_ATTRIBS,
DIRTY_BIT_UNKNOWN = DIRTY_BIT_ATTRIB_MAX_DIVISOR,
DIRTY_BIT_MAX = DIRTY_BIT_UNKNOWN,
};
typedef std::bitset<DIRTY_BIT_MAX> DirtyBits;
void syncImplState();
private: private:
GLuint mId; GLuint mId;
rx::VertexArrayImpl *mVertexArray; rx::VertexArrayImpl *mVertexArray;
Data mData; Data mData;
DirtyBits mDirtyBits;
}; };
} }
......
...@@ -21,7 +21,7 @@ class VertexArrayImpl : angle::NonCopyable ...@@ -21,7 +21,7 @@ class VertexArrayImpl : angle::NonCopyable
public: public:
VertexArrayImpl(const gl::VertexArray::Data &data) : mData(data) { } VertexArrayImpl(const gl::VertexArray::Data &data) : mData(data) { }
virtual ~VertexArrayImpl() { } virtual ~VertexArrayImpl() { }
virtual void syncState(const gl::VertexArray::DirtyBits &dirtyBits) {}
protected: protected:
const gl::VertexArray::Data &mData; const gl::VertexArray::Data &mData;
}; };
......
...@@ -207,7 +207,7 @@ LinkResult ProgramGL::link(const gl::Data &data, gl::InfoLog &infoLog, ...@@ -207,7 +207,7 @@ LinkResult ProgramGL::link(const gl::Data &data, gl::InfoLog &infoLog,
// TODO: determine attribute precision // TODO: determine attribute precision
setShaderAttribute(static_cast<size_t>(i), attributeType, GL_NONE, attributeName, attributeSize, location); setShaderAttribute(static_cast<size_t>(i), attributeType, GL_NONE, attributeName, attributeSize, location);
mActiveAttributeLocations.push_back(location); mActiveAttributesMask.set(location);
} }
return LinkResult(true, gl::Error(GL_NO_ERROR)); return LinkResult(true, gl::Error(GL_NO_ERROR));
...@@ -445,7 +445,7 @@ void ProgramGL::reset() ...@@ -445,7 +445,7 @@ void ProgramGL::reset()
mSamplerUniformMap.clear(); mSamplerUniformMap.clear();
mSamplerBindings.clear(); mSamplerBindings.clear();
mActiveAttributeLocations.clear(); mActiveAttributesMask.reset();
} }
GLuint ProgramGL::getProgramID() const GLuint ProgramGL::getProgramID() const
...@@ -458,9 +458,9 @@ const std::vector<SamplerBindingGL> &ProgramGL::getAppliedSamplerUniforms() cons ...@@ -458,9 +458,9 @@ const std::vector<SamplerBindingGL> &ProgramGL::getAppliedSamplerUniforms() cons
return mSamplerBindings; return mSamplerBindings;
} }
const std::vector<GLuint> &ProgramGL::getActiveAttributeLocations() const const gl::AttributesMask &ProgramGL::getActiveAttributesMask() const
{ {
return mActiveAttributeLocations; return mActiveAttributesMask;
} }
} }
...@@ -95,7 +95,7 @@ class ProgramGL : public ProgramImpl ...@@ -95,7 +95,7 @@ class ProgramGL : public ProgramImpl
GLuint getProgramID() const; GLuint getProgramID() const;
const std::vector<SamplerBindingGL> &getAppliedSamplerUniforms() const; const std::vector<SamplerBindingGL> &getAppliedSamplerUniforms() const;
const std::vector<GLuint> &getActiveAttributeLocations() const; const gl::AttributesMask &getActiveAttributesMask() const;
private: private:
const FunctionsGL *mFunctions; const FunctionsGL *mFunctions;
...@@ -113,7 +113,7 @@ class ProgramGL : public ProgramImpl ...@@ -113,7 +113,7 @@ class ProgramGL : public ProgramImpl
std::vector<SamplerBindingGL> mSamplerBindings; std::vector<SamplerBindingGL> mSamplerBindings;
// Array of attribute locations used by this program // Array of attribute locations used by this program
std::vector<GLuint> mActiveAttributeLocations; gl::AttributesMask mActiveAttributesMask;
GLuint mProgramID; GLuint mProgramID;
}; };
......
...@@ -383,7 +383,8 @@ gl::Error StateManagerGL::setDrawArraysState(const gl::Data &data, GLint first, ...@@ -383,7 +383,8 @@ gl::Error StateManagerGL::setDrawArraysState(const gl::Data &data, GLint first,
const gl::VertexArray *vao = state.getVertexArray(); const gl::VertexArray *vao = state.getVertexArray();
const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(vao); const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(vao);
gl::Error error = vaoGL->syncDrawArraysState(programGL->getActiveAttributeLocations(), first, count); gl::Error error =
vaoGL->syncDrawArraysState(programGL->getActiveAttributesMask(), first, count);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -405,7 +406,8 @@ gl::Error StateManagerGL::setDrawElementsState(const gl::Data &data, GLsizei cou ...@@ -405,7 +406,8 @@ gl::Error StateManagerGL::setDrawElementsState(const gl::Data &data, GLsizei cou
const gl::VertexArray *vao = state.getVertexArray(); const gl::VertexArray *vao = state.getVertexArray();
const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(vao); const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(vao);
gl::Error error = vaoGL->syncDrawElementsState(programGL->getActiveAttributeLocations(), count, type, indices, outIndices); gl::Error error = vaoGL->syncDrawElementsState(programGL->getActiveAttributesMask(), count,
type, indices, outIndices);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -1079,7 +1081,7 @@ void StateManagerGL::syncState(const gl::State &state, const gl::State::DirtyBit ...@@ -1079,7 +1081,7 @@ void StateManagerGL::syncState(const gl::State &state, const gl::State::DirtyBit
// TODO(jmadill): implement this // TODO(jmadill): implement this
break; break;
case gl::State::DIRTY_BIT_VERTEX_ARRAY_OBJECT: case gl::State::DIRTY_BIT_VERTEX_ARRAY_OBJECT:
// TODO(jmadill): implement this state.getVertexArray()->syncImplState();
break; break;
case gl::State::DIRTY_BIT_PROGRAM_BINDING: case gl::State::DIRTY_BIT_PROGRAM_BINDING:
// TODO(jmadill): implement this // TODO(jmadill): implement this
......
...@@ -23,33 +23,46 @@ class VertexArrayGL : public VertexArrayImpl ...@@ -23,33 +23,46 @@ class VertexArrayGL : public VertexArrayImpl
VertexArrayGL(const gl::VertexArray::Data &data, const FunctionsGL *functions, StateManagerGL *stateManager); VertexArrayGL(const gl::VertexArray::Data &data, const FunctionsGL *functions, StateManagerGL *stateManager);
~VertexArrayGL() override; ~VertexArrayGL() override;
gl::Error syncDrawArraysState(const std::vector<GLuint> &activeAttribLoations, GLint first, GLsizei count) const; gl::Error syncDrawArraysState(const gl::AttributesMask &activeAttributesMask,
gl::Error syncDrawElementsState(const std::vector<GLuint> &activeAttribLoations, GLsizei count, GLenum type, GLint first,
const GLvoid *indices, const GLvoid **outIndices) const; GLsizei count) const;
gl::Error syncDrawElementsState(const gl::AttributesMask &activeAttributesMask,
GLsizei count,
GLenum type,
const GLvoid *indices,
const GLvoid **outIndices) const;
GLuint getVertexArrayID() const; GLuint getVertexArrayID() const;
GLuint getAppliedElementArrayBufferID() const; GLuint getAppliedElementArrayBufferID() const;
private: void syncState(const gl::VertexArray::DirtyBits &dirtyBits) override;
gl::Error syncDrawState(const std::vector<GLuint> &activeAttribLoations, GLint first, GLsizei count,
GLenum type, const GLvoid *indices, const GLvoid **outIndices) const;
// Check if any vertex attributes need to be streamed
bool doAttributesNeedStreaming(const std::vector<GLuint> &activeAttribLoations) const;
// Apply attribute state, returns the amount of space needed to stream all attributes that need streaming private:
// and the data size of the largest attribute gl::Error syncDrawState(const gl::AttributesMask &activeAttributesMask,
gl::Error syncAttributeState(const std::vector<GLuint> &activeAttribLoations, bool attributesNeedStreaming, GLint first,
const gl::RangeUI &indexRange, size_t *outStreamingDataSize, GLsizei count,
size_t *outMaxAttributeDataSize) const; GLenum type,
const GLvoid *indices,
const GLvoid **outIndices) const;
// Apply index data, only sets outIndexRange if attributesNeedStreaming is true // Apply index data, only sets outIndexRange if attributesNeedStreaming is true
gl::Error syncIndexData(GLsizei count, GLenum type, const GLvoid *indices, bool attributesNeedStreaming, gl::Error syncIndexData(GLsizei count, GLenum type, const GLvoid *indices, bool attributesNeedStreaming,
gl::RangeUI *outIndexRange, const GLvoid **outIndices) const; gl::RangeUI *outIndexRange, const GLvoid **outIndices) const;
// Returns the amount of space needed to stream all attributes that need streaming
// and the data size of the largest attribute
void computeStreamingAttributeSizes(const gl::AttributesMask &activeAttributesMask,
const gl::RangeUI &indexRange,
size_t *outStreamingDataSize,
size_t *outMaxAttributeDataSize) const;
// Stream attributes that have client data // Stream attributes that have client data
gl::Error streamAttributes(const std::vector<GLuint> &activeAttribLoations, size_t streamingDataSize, gl::Error streamAttributes(const gl::AttributesMask &activeAttributesMask,
size_t maxAttributeDataSize, const gl::RangeUI &indexRange) const; const gl::RangeUI &indexRange) const;
void updateNeedsStreaming(size_t attribIndex);
void updateAttribEnabled(size_t attribIndex);
void updateAttribPointer(size_t attribIndex);
const FunctionsGL *mFunctions; const FunctionsGL *mFunctions;
StateManagerGL *mStateManager; StateManagerGL *mStateManager;
...@@ -64,6 +77,8 @@ class VertexArrayGL : public VertexArrayImpl ...@@ -64,6 +77,8 @@ class VertexArrayGL : public VertexArrayImpl
mutable size_t mStreamingArrayBufferSize; mutable size_t mStreamingArrayBufferSize;
mutable GLuint mStreamingArrayBuffer; mutable GLuint mStreamingArrayBuffer;
gl::AttributesMask mAttributesNeedStreaming;
}; };
} }
......
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