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,
// TODO: determine attribute precision
setShaderAttribute(static_cast<size_t>(i), attributeType, GL_NONE, attributeName, attributeSize, location);
mActiveAttributeLocations.push_back(location);
}
return LinkResult(true, gl::Error(GL_NO_ERROR));
......@@ -434,6 +436,7 @@ void ProgramGL::reset()
mSamplerUniformMap.clear();
mSamplerBindings.clear();
mActiveAttributeLocations.clear();
}
GLuint ProgramGL::getProgramID() const
......@@ -446,4 +449,9 @@ const std::vector<SamplerBindingGL> &ProgramGL::getAppliedSamplerUniforms() cons
return mSamplerBindings;
}
const std::vector<GLuint> &ProgramGL::getActiveAttributeLocations() const
{
return mActiveAttributeLocations;
}
}
......@@ -95,6 +95,7 @@ class ProgramGL : public ProgramImpl
GLuint getProgramID() const;
const std::vector<SamplerBindingGL> &getAppliedSamplerUniforms() const;
const std::vector<GLuint> &getActiveAttributeLocations() const;
private:
const FunctionsGL *mFunctions;
......@@ -111,6 +112,9 @@ class ProgramGL : public ProgramImpl
// An array of the samplers that are used by the program
std::vector<SamplerBindingGL> mSamplerBindings;
// Array of attribute locations used by this program
std::vector<GLuint> mActiveAttributeLocations;
GLuint mProgramID;
};
......
......@@ -380,9 +380,18 @@ gl::Error StateManagerGL::setDrawArraysState(const gl::Data &data, GLint first,
{
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 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());
return setGenericDrawState(data);
......@@ -393,10 +402,13 @@ gl::Error StateManagerGL::setDrawElementsState(const gl::Data &data, GLsizei cou
{
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 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())
{
return error;
......@@ -411,21 +423,23 @@ gl::Error StateManagerGL::setGenericDrawState(const gl::Data &data)
{
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 std::vector<gl::VertexAttribute>& attribs = vao->getVertexAttributes();
for (size_t i = 0; i < attribs.size(); i++)
const std::vector<gl::VertexAttribute> &attribs = vao->getVertexAttributes();
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(i, state.getVertexAttribCurrentValue(i));
setAttributeCurrentData(location, state.getVertexAttribCurrentValue(location));
}
}
const gl::Program *program = state.getProgram();
const ProgramGL *programGL = GetImplAs<ProgramGL>(program);
useProgram(programGL->getProgramID());
const std::vector<SamplerBindingGL> &appliedSamplerUniforms = programGL->getAppliedSamplerUniforms();
for (const SamplerBindingGL &samplerUniform : appliedSamplerUniforms)
{
......
......@@ -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);
// 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
gl::RangeUI indexRange(0, 0);
......@@ -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
size_t streamingDataSize = 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())
{
return error;
......@@ -130,7 +132,8 @@ gl::Error VertexArrayGL::syncDrawState(GLint first, GLsizei count, GLenum type,
{
ASSERT(attributesNeedStreaming);
gl::Error error = streamAttributes(streamingDataSize, maxAttributeDataSize, indexRange);
gl::Error error = streamAttributes(activeAttribLocations, streamingDataSize, maxAttributeDataSize,
indexRange);
if (error.isError())
{
return error;
......@@ -140,12 +143,13 @@ gl::Error VertexArrayGL::syncDrawState(GLint first, GLsizei count, GLenum type,
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
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)
{
return true;
......@@ -155,15 +159,16 @@ bool VertexArrayGL::doAttributesNeedStreaming() const
return false;
}
gl::Error VertexArrayGL::syncAttributeState(bool attributesNeedStreaming, const gl::RangeUI &indexRange,
size_t *outStreamingDataSize, size_t *outMaxAttributeDataSize) const
gl::Error VertexArrayGL::syncAttributeState(const std::vector<GLuint> &activeAttribLocations, bool attributesNeedStreaming,
const gl::RangeUI &indexRange, size_t *outStreamingDataSize, size_t *outMaxAttributeDataSize) const
{
*outStreamingDataSize = 0;
*outMaxAttributeDataSize = 0;
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];
// 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
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)
{
......@@ -343,8 +349,9 @@ gl::Error VertexArrayGL::streamAttributes(size_t streamingDataSize, size_t maxAt
const size_t streamedVertexCount = indexRange.end - indexRange.start + 1;
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];
if (attrib.enabled && attrib.buffer.get() == nullptr)
......
......@@ -28,21 +28,24 @@ class VertexArrayGL : public VertexArrayImpl
void setAttributeDivisor(size_t idx, GLuint divisor) override;
void enableAttribute(size_t idx, bool enabledState) override;
gl::Error syncDrawArraysState(GLint first, GLsizei count) const;
gl::Error syncDrawElementsState(GLsizei count, GLenum type, const GLvoid *indices, const GLvoid **outIndices) const;
gl::Error syncDrawArraysState(const std::vector<GLuint> &activeAttribLoations, GLint first, GLsizei count) const;
gl::Error syncDrawElementsState(const std::vector<GLuint> &activeAttribLoations, GLsizei count, GLenum type,
const GLvoid *indices, const GLvoid **outIndices) const;
GLuint getVertexArrayID() const;
GLuint getAppliedElementArrayBufferID() const;
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
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
// 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;
// Apply index data, only sets outIndexRange if attributesNeedStreaming is true
......@@ -50,7 +53,8 @@ class VertexArrayGL : public VertexArrayImpl
gl::RangeUI *outIndexRange, const GLvoid **outIndices) const;
// 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;
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