Commit b61e173a by Geoff Lang

Only sync attributes used by the current program in RendererGL.

Improves draw call overhead of RendererGL. DrawCallPerf_gl: Before: 136973 score After: 153317 score Improvement: 11.932% BUG=angleproject:959 Change-Id: Ib75f6fdd756648e4a07f6e970cda03abbdbcf009 Reviewed-on: https://chromium-review.googlesource.com/275409Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent d5451f11
...@@ -197,6 +197,8 @@ LinkResult ProgramGL::link(const gl::Data &data, gl::InfoLog &infoLog, ...@@ -197,6 +197,8 @@ 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);
} }
return LinkResult(true, gl::Error(GL_NO_ERROR)); return LinkResult(true, gl::Error(GL_NO_ERROR));
...@@ -434,6 +436,7 @@ void ProgramGL::reset() ...@@ -434,6 +436,7 @@ void ProgramGL::reset()
mSamplerUniformMap.clear(); mSamplerUniformMap.clear();
mSamplerBindings.clear(); mSamplerBindings.clear();
mActiveAttributeLocations.clear();
} }
GLuint ProgramGL::getProgramID() const GLuint ProgramGL::getProgramID() const
...@@ -446,4 +449,9 @@ const std::vector<SamplerBindingGL> &ProgramGL::getAppliedSamplerUniforms() cons ...@@ -446,4 +449,9 @@ const std::vector<SamplerBindingGL> &ProgramGL::getAppliedSamplerUniforms() cons
return mSamplerBindings; return mSamplerBindings;
} }
const std::vector<GLuint> &ProgramGL::getActiveAttributeLocations() const
{
return mActiveAttributeLocations;
}
} }
...@@ -95,6 +95,7 @@ class ProgramGL : public ProgramImpl ...@@ -95,6 +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;
private: private:
const FunctionsGL *mFunctions; const FunctionsGL *mFunctions;
...@@ -111,6 +112,9 @@ class ProgramGL : public ProgramImpl ...@@ -111,6 +112,9 @@ class ProgramGL : public ProgramImpl
// An array of the samplers that are used by the program // An array of the samplers that are used by the program
std::vector<SamplerBindingGL> mSamplerBindings; std::vector<SamplerBindingGL> mSamplerBindings;
// Array of attribute locations used by this program
std::vector<GLuint> mActiveAttributeLocations;
GLuint mProgramID; GLuint mProgramID;
}; };
......
...@@ -380,9 +380,18 @@ gl::Error StateManagerGL::setDrawArraysState(const gl::Data &data, GLint first, ...@@ -380,9 +380,18 @@ gl::Error StateManagerGL::setDrawArraysState(const gl::Data &data, GLint first,
{ {
const gl::State &state = *data.state; const gl::State &state = *data.state;
const gl::Program *program = state.getProgram();
const ProgramGL *programGL = GetImplAs<ProgramGL>(program);
const gl::VertexArray *vao = state.getVertexArray(); const gl::VertexArray *vao = state.getVertexArray();
const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(vao); const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(vao);
vaoGL->syncDrawArraysState(first, count);
gl::Error error = vaoGL->syncDrawArraysState(programGL->getActiveAttributeLocations(), first, count);
if (error.isError())
{
return error;
}
bindVertexArray(vaoGL->getVertexArrayID(), vaoGL->getAppliedElementArrayBufferID()); bindVertexArray(vaoGL->getVertexArrayID(), vaoGL->getAppliedElementArrayBufferID());
return setGenericDrawState(data); return setGenericDrawState(data);
...@@ -393,10 +402,13 @@ gl::Error StateManagerGL::setDrawElementsState(const gl::Data &data, GLsizei cou ...@@ -393,10 +402,13 @@ gl::Error StateManagerGL::setDrawElementsState(const gl::Data &data, GLsizei cou
{ {
const gl::State &state = *data.state; const gl::State &state = *data.state;
const gl::Program *program = state.getProgram();
const ProgramGL *programGL = GetImplAs<ProgramGL>(program);
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(count, type, indices, outIndices); gl::Error error = vaoGL->syncDrawElementsState(programGL->getActiveAttributeLocations(), count, type, indices, outIndices);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -411,21 +423,23 @@ gl::Error StateManagerGL::setGenericDrawState(const gl::Data &data) ...@@ -411,21 +423,23 @@ gl::Error StateManagerGL::setGenericDrawState(const gl::Data &data)
{ {
const gl::State &state = *data.state; const gl::State &state = *data.state;
const gl::Program *program = state.getProgram();
const ProgramGL *programGL = GetImplAs<ProgramGL>(program);
useProgram(programGL->getProgramID());
const gl::VertexArray *vao = state.getVertexArray(); const gl::VertexArray *vao = state.getVertexArray();
const std::vector<gl::VertexAttribute>& attribs = vao->getVertexAttributes(); const std::vector<gl::VertexAttribute> &attribs = vao->getVertexAttributes();
for (size_t i = 0; i < attribs.size(); i++) const std::vector<GLuint> &activeAttribs = programGL->getActiveAttributeLocations();
for (size_t activeAttribIndex = 0; activeAttribIndex < activeAttribs.size(); activeAttribIndex++)
{ {
if (!attribs[i].enabled) GLuint location = activeAttribs[activeAttribIndex];
if (!attribs[location].enabled)
{ {
// TODO: Don't sync this attribute if it is not used by the program. setAttributeCurrentData(location, state.getVertexAttribCurrentValue(location));
setAttributeCurrentData(i, state.getVertexAttribCurrentValue(i));
} }
} }
const gl::Program *program = state.getProgram();
const ProgramGL *programGL = GetImplAs<ProgramGL>(program);
useProgram(programGL->getProgramID());
const std::vector<SamplerBindingGL> &appliedSamplerUniforms = programGL->getAppliedSamplerUniforms(); const std::vector<SamplerBindingGL> &appliedSamplerUniforms = programGL->getAppliedSamplerUniforms();
for (const SamplerBindingGL &samplerUniform : appliedSamplerUniforms) for (const SamplerBindingGL &samplerUniform : appliedSamplerUniforms)
{ {
......
...@@ -83,22 +83,23 @@ void VertexArrayGL::enableAttribute(size_t idx, bool enabledState) ...@@ -83,22 +83,23 @@ void VertexArrayGL::enableAttribute(size_t idx, bool enabledState)
{ {
} }
gl::Error VertexArrayGL::syncDrawArraysState(GLint first, GLsizei count) const gl::Error VertexArrayGL::syncDrawArraysState(const std::vector<GLuint> &activeAttribLocations, GLint first, GLsizei count) const
{ {
return syncDrawState(first, count, GL_NONE, nullptr, nullptr); return syncDrawState(activeAttribLocations, first, count, GL_NONE, nullptr, nullptr);
} }
gl::Error VertexArrayGL::syncDrawElementsState(GLsizei count, GLenum type, const GLvoid *indices, const GLvoid **outIndices) const gl::Error VertexArrayGL::syncDrawElementsState(const std::vector<GLuint> &activeAttribLocations, GLsizei count,
GLenum type, const GLvoid *indices, const GLvoid **outIndices) const
{ {
return syncDrawState(0, count, type, indices, outIndices); return syncDrawState(activeAttribLocations, 0, count, type, indices, outIndices);
} }
gl::Error VertexArrayGL::syncDrawState(GLint first, GLsizei count, GLenum type, const GLvoid *indices, const GLvoid **outIndices) const gl::Error VertexArrayGL::syncDrawState(const std::vector<GLuint> &activeAttribLocations, GLint first, GLsizei count, GLenum type, const GLvoid *indices, const GLvoid **outIndices) const
{ {
mStateManager->bindVertexArray(mVertexArrayID, mAppliedElementArrayBuffer); mStateManager->bindVertexArray(mVertexArrayID, mAppliedElementArrayBuffer);
// Check if any attributes need to be streamed, determines if the index range needs to be computed // Check if any attributes need to be streamed, determines if the index range needs to be computed
bool attributesNeedStreaming = doAttributesNeedStreaming(); bool attributesNeedStreaming = doAttributesNeedStreaming(activeAttribLocations);
// Determine if an index buffer needs to be streamed and the range of vertices that need to be copied // Determine if an index buffer needs to be streamed and the range of vertices that need to be copied
gl::RangeUI indexRange(0, 0); gl::RangeUI indexRange(0, 0);
...@@ -120,7 +121,8 @@ gl::Error VertexArrayGL::syncDrawState(GLint first, GLsizei count, GLenum type, ...@@ -120,7 +121,8 @@ gl::Error VertexArrayGL::syncDrawState(GLint first, GLsizei count, GLenum type,
// Sync the vertex attribute state and track what data needs to be streamed // Sync the vertex attribute state and track what data needs to be streamed
size_t streamingDataSize = 0; size_t streamingDataSize = 0;
size_t maxAttributeDataSize = 0; size_t maxAttributeDataSize = 0;
gl::Error error = syncAttributeState(attributesNeedStreaming, indexRange, &streamingDataSize, &maxAttributeDataSize); gl::Error error = syncAttributeState(activeAttribLocations, attributesNeedStreaming, indexRange,
&streamingDataSize, &maxAttributeDataSize);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -130,7 +132,8 @@ gl::Error VertexArrayGL::syncDrawState(GLint first, GLsizei count, GLenum type, ...@@ -130,7 +132,8 @@ gl::Error VertexArrayGL::syncDrawState(GLint first, GLsizei count, GLenum type,
{ {
ASSERT(attributesNeedStreaming); ASSERT(attributesNeedStreaming);
gl::Error error = streamAttributes(streamingDataSize, maxAttributeDataSize, indexRange); gl::Error error = streamAttributes(activeAttribLocations, streamingDataSize, maxAttributeDataSize,
indexRange);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -140,12 +143,13 @@ gl::Error VertexArrayGL::syncDrawState(GLint first, GLsizei count, GLenum type, ...@@ -140,12 +143,13 @@ gl::Error VertexArrayGL::syncDrawState(GLint first, GLsizei count, GLenum type,
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
bool VertexArrayGL::doAttributesNeedStreaming() const bool VertexArrayGL::doAttributesNeedStreaming(const std::vector<GLuint> &activeAttribLocations) const
{ {
// TODO: if GLES, nothing needs to be streamed // TODO: if GLES, nothing needs to be streamed
const auto &attribs = mData.getVertexAttributes(); const auto &attribs = mData.getVertexAttributes();
for (size_t idx = 0; idx < attribs.size(); idx++) for (size_t activeAttrib = 0; activeAttrib < activeAttribLocations.size(); activeAttrib++)
{ {
GLuint idx = activeAttribLocations[activeAttrib];
if (attribs[idx].enabled && attribs[idx].buffer.get() == nullptr) if (attribs[idx].enabled && attribs[idx].buffer.get() == nullptr)
{ {
return true; return true;
...@@ -155,15 +159,16 @@ bool VertexArrayGL::doAttributesNeedStreaming() const ...@@ -155,15 +159,16 @@ bool VertexArrayGL::doAttributesNeedStreaming() const
return false; return false;
} }
gl::Error VertexArrayGL::syncAttributeState(bool attributesNeedStreaming, const gl::RangeUI &indexRange, gl::Error VertexArrayGL::syncAttributeState(const std::vector<GLuint> &activeAttribLocations, bool attributesNeedStreaming,
size_t *outStreamingDataSize, size_t *outMaxAttributeDataSize) const const gl::RangeUI &indexRange, size_t *outStreamingDataSize, size_t *outMaxAttributeDataSize) const
{ {
*outStreamingDataSize = 0; *outStreamingDataSize = 0;
*outMaxAttributeDataSize = 0; *outMaxAttributeDataSize = 0;
const auto &attribs = mData.getVertexAttributes(); const auto &attribs = mData.getVertexAttributes();
for (size_t idx = 0; idx < attribs.size(); idx++) for (size_t activeAttrib = 0; activeAttrib < activeAttribLocations.size(); activeAttrib++)
{ {
GLuint idx = activeAttribLocations[activeAttrib];
const auto &attrib = attribs[idx]; const auto &attrib = attribs[idx];
// Always sync the enabled and divisor state, they are required for both streaming and buffered // Always sync the enabled and divisor state, they are required for both streaming and buffered
...@@ -310,7 +315,8 @@ gl::Error VertexArrayGL::syncIndexData(GLsizei count, GLenum type, const GLvoid ...@@ -310,7 +315,8 @@ gl::Error VertexArrayGL::syncIndexData(GLsizei count, GLenum type, const GLvoid
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error VertexArrayGL::streamAttributes(size_t streamingDataSize, size_t maxAttributeDataSize, const gl::RangeUI &indexRange) const gl::Error VertexArrayGL::streamAttributes(const std::vector<GLuint> &activeAttribLocations, size_t streamingDataSize,
size_t maxAttributeDataSize, const gl::RangeUI &indexRange) const
{ {
if (mStreamingArrayBuffer == 0) if (mStreamingArrayBuffer == 0)
{ {
...@@ -343,8 +349,9 @@ gl::Error VertexArrayGL::streamAttributes(size_t streamingDataSize, size_t maxAt ...@@ -343,8 +349,9 @@ gl::Error VertexArrayGL::streamAttributes(size_t streamingDataSize, size_t maxAt
const size_t streamedVertexCount = indexRange.end - indexRange.start + 1; const size_t streamedVertexCount = indexRange.end - indexRange.start + 1;
const auto &attribs = mData.getVertexAttributes(); const auto &attribs = mData.getVertexAttributes();
for (size_t idx = 0; idx < attribs.size(); idx++) for (size_t activeAttrib = 0; activeAttrib < activeAttribLocations.size(); activeAttrib++)
{ {
GLuint idx = activeAttribLocations[activeAttrib];
const auto &attrib = attribs[idx]; const auto &attrib = attribs[idx];
if (attrib.enabled && attrib.buffer.get() == nullptr) if (attrib.enabled && attrib.buffer.get() == nullptr)
......
...@@ -28,21 +28,24 @@ class VertexArrayGL : public VertexArrayImpl ...@@ -28,21 +28,24 @@ class VertexArrayGL : public VertexArrayImpl
void setAttributeDivisor(size_t idx, GLuint divisor) override; void setAttributeDivisor(size_t idx, GLuint divisor) override;
void enableAttribute(size_t idx, bool enabledState) override; void enableAttribute(size_t idx, bool enabledState) override;
gl::Error syncDrawArraysState(GLint first, GLsizei count) const; gl::Error syncDrawArraysState(const std::vector<GLuint> &activeAttribLoations, GLint first, GLsizei count) const;
gl::Error syncDrawElementsState(GLsizei count, GLenum type, const GLvoid *indices, const GLvoid **outIndices) const; gl::Error syncDrawElementsState(const std::vector<GLuint> &activeAttribLoations, GLsizei count, GLenum type,
const GLvoid *indices, const GLvoid **outIndices) const;
GLuint getVertexArrayID() const; GLuint getVertexArrayID() const;
GLuint getAppliedElementArrayBufferID() const; GLuint getAppliedElementArrayBufferID() const;
private: private:
gl::Error syncDrawState(GLint first, GLsizei count, GLenum type, const GLvoid *indices, const GLvoid **outIndices) const; 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 // Check if any vertex attributes need to be streamed
bool doAttributesNeedStreaming() const; bool doAttributesNeedStreaming(const std::vector<GLuint> &activeAttribLoations) const;
// Apply attribute state, returns the amount of space needed to stream all attributes that need streaming // Apply attribute state, returns the amount of space needed to stream all attributes that need streaming
// and the data size of the largest attribute // and the data size of the largest attribute
gl::Error syncAttributeState(bool attributesNeedStreaming, const gl::RangeUI &indexRange, size_t *outStreamingDataSize, gl::Error syncAttributeState(const std::vector<GLuint> &activeAttribLoations, bool attributesNeedStreaming,
const gl::RangeUI &indexRange, size_t *outStreamingDataSize,
size_t *outMaxAttributeDataSize) const; size_t *outMaxAttributeDataSize) const;
// Apply index data, only sets outIndexRange if attributesNeedStreaming is true // Apply index data, only sets outIndexRange if attributesNeedStreaming is true
...@@ -50,7 +53,8 @@ class VertexArrayGL : public VertexArrayImpl ...@@ -50,7 +53,8 @@ class VertexArrayGL : public VertexArrayImpl
gl::RangeUI *outIndexRange, const GLvoid **outIndices) const; gl::RangeUI *outIndexRange, const GLvoid **outIndices) const;
// Stream attributes that have client data // Stream attributes that have client data
gl::Error streamAttributes(size_t streamingDataSize, size_t maxAttributeDataSize, const gl::RangeUI &indexRange) const; gl::Error streamAttributes(const std::vector<GLuint> &activeAttribLoations, size_t streamingDataSize,
size_t maxAttributeDataSize, const gl::RangeUI &indexRange) const;
const FunctionsGL *mFunctions; const FunctionsGL *mFunctions;
StateManagerGL *mStateManager; StateManagerGL *mStateManager;
......
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