Commit 6ae6efca by Geoff Lang

Only sync the VAO state just before the draw call.

BUG=angleproject:880 Change-Id: Ifd59c0f67aeab0e4700b3dca57c1b75e3fae48b8 Reviewed-on: https://chromium-review.googlesource.com/257671Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent fb2a5597
...@@ -23,6 +23,24 @@ VertexAttribute::VertexAttribute() ...@@ -23,6 +23,24 @@ VertexAttribute::VertexAttribute()
{ {
} }
bool operator==(const VertexAttribute &a, const VertexAttribute &b)
{
return a.enabled == b.enabled &&
a.type == b.type &&
a.size == b.size &&
a.normalized == b.normalized &&
a.pureInteger == b.pureInteger &&
a.stride == b.stride &&
a.pointer == b.pointer &&
a.buffer.get() == b.buffer.get() &&
a.divisor == b.divisor;
}
bool operator!=(const VertexAttribute &a, const VertexAttribute &b)
{
return !(a == b);
}
size_t ComputeVertexAttributeTypeSize(const VertexAttribute& attrib) size_t ComputeVertexAttributeTypeSize(const VertexAttribute& attrib)
{ {
GLuint size = attrib.size; GLuint size = attrib.size;
......
...@@ -36,6 +36,9 @@ struct VertexAttribute ...@@ -36,6 +36,9 @@ struct VertexAttribute
VertexAttribute(); VertexAttribute();
}; };
bool operator==(const VertexAttribute &a, const VertexAttribute &b);
bool operator!=(const VertexAttribute &a, const VertexAttribute &b);
template <typename T> template <typename T>
T QuerySingleVertexAttributeParameter(const VertexAttribute& attrib, GLenum pname) T QuerySingleVertexAttributeParameter(const VertexAttribute& attrib, GLenum pname)
{ {
......
...@@ -103,6 +103,7 @@ void StateManagerGL::setDrawState(const gl::Data &data) ...@@ -103,6 +103,7 @@ void StateManagerGL::setDrawState(const gl::Data &data)
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->syncState();
bindVertexArray(vaoGL->getVertexArrayID()); bindVertexArray(vaoGL->getVertexArrayID());
const gl::Program *program = state.getProgram(); const gl::Program *program = state.getProgram();
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "libANGLE/renderer/gl/VertexArrayGL.h" #include "libANGLE/renderer/gl/VertexArrayGL.h"
#include "common/debug.h" #include "common/debug.h"
#include "libANGLE/Buffer.h"
#include "libANGLE/angletypes.h" #include "libANGLE/angletypes.h"
#include "libANGLE/renderer/gl/BufferGL.h" #include "libANGLE/renderer/gl/BufferGL.h"
#include "libANGLE/renderer/gl/FunctionsGL.h" #include "libANGLE/renderer/gl/FunctionsGL.h"
...@@ -22,6 +23,8 @@ VertexArrayGL::VertexArrayGL(const FunctionsGL *functions, StateManagerGL *state ...@@ -22,6 +23,8 @@ VertexArrayGL::VertexArrayGL(const FunctionsGL *functions, StateManagerGL *state
mFunctions(functions), mFunctions(functions),
mStateManager(stateManager), mStateManager(stateManager),
mVertexArrayID(0), mVertexArrayID(0),
mElementArrayBuffer(),
mAttributes(),
mAppliedElementArrayBuffer(0), mAppliedElementArrayBuffer(0),
mAppliedAttributes() mAppliedAttributes()
{ {
...@@ -32,6 +35,7 @@ VertexArrayGL::VertexArrayGL(const FunctionsGL *functions, StateManagerGL *state ...@@ -32,6 +35,7 @@ VertexArrayGL::VertexArrayGL(const FunctionsGL *functions, StateManagerGL *state
// Set the cached vertex attribute array size // Set the cached vertex attribute array size
GLint maxVertexAttribs; GLint maxVertexAttribs;
mFunctions->getIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs); mFunctions->getIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
mAttributes.resize(maxVertexAttribs);
mAppliedAttributes.resize(maxVertexAttribs); mAppliedAttributes.resize(maxVertexAttribs);
} }
...@@ -43,6 +47,7 @@ VertexArrayGL::~VertexArrayGL() ...@@ -43,6 +47,7 @@ VertexArrayGL::~VertexArrayGL()
mVertexArrayID = 0; mVertexArrayID = 0;
} }
mElementArrayBuffer.set(nullptr);
for (size_t idx = 0; idx < mAppliedAttributes.size(); idx++) for (size_t idx = 0; idx < mAppliedAttributes.size(); idx++)
{ {
mAppliedAttributes[idx].buffer.set(NULL); mAppliedAttributes[idx].buffer.set(NULL);
...@@ -51,98 +56,83 @@ VertexArrayGL::~VertexArrayGL() ...@@ -51,98 +56,83 @@ VertexArrayGL::~VertexArrayGL()
void VertexArrayGL::setElementArrayBuffer(const gl::Buffer *buffer) void VertexArrayGL::setElementArrayBuffer(const gl::Buffer *buffer)
{ {
GLuint elementArrayBufferID = 0; mElementArrayBuffer.set(buffer);
if (buffer != nullptr)
{
const BufferGL *bufferGL = GetImplAs<BufferGL>(buffer);
elementArrayBufferID = bufferGL->getBufferID();
}
if (elementArrayBufferID != mAppliedElementArrayBuffer)
{
mStateManager->bindVertexArray(mVertexArrayID);
mStateManager->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBufferID);
mStateManager->bindVertexArray(0);
mAppliedElementArrayBuffer = elementArrayBufferID;
}
} }
void VertexArrayGL::setAttribute(size_t idx, const gl::VertexAttribute &attr) void VertexArrayGL::setAttribute(size_t idx, const gl::VertexAttribute &attr)
{ {
if (mAppliedAttributes[idx].type != attr.type || mAttributes[idx] = attr;
mAppliedAttributes[idx].size != attr.size ||
mAppliedAttributes[idx].normalized != attr.normalized ||
mAppliedAttributes[idx].pureInteger != attr.pureInteger ||
mAppliedAttributes[idx].stride != attr.stride ||
mAppliedAttributes[idx].pointer != attr.pointer ||
mAppliedAttributes[idx].buffer.get() != attr.buffer.get())
{
mStateManager->bindVertexArray(mVertexArrayID);
const gl::Buffer *arrayBuffer = attr.buffer.get();
if (arrayBuffer != nullptr)
{
const BufferGL *arrayBufferGL = GetImplAs<BufferGL>(arrayBuffer);
mStateManager->bindBuffer(GL_ARRAY_BUFFER, arrayBufferGL->getBufferID());
}
else
{
// This will take some extra work, core OpenGL doesn't support binding raw data pointers
// to VAOs
UNIMPLEMENTED();
}
if (attr.pureInteger)
{
mFunctions->vertexAttribIPointer(idx, attr.size, attr.type, attr.stride, attr.pointer);
}
else
{
mFunctions->vertexAttribPointer(idx, attr.size, attr.type, attr.normalized, attr.stride, attr.pointer);
}
mAppliedAttributes[idx].type = attr.type;
mAppliedAttributes[idx].size = attr.size;
mAppliedAttributes[idx].normalized = attr.normalized;
mAppliedAttributes[idx].pureInteger = attr.pureInteger;
mAppliedAttributes[idx].stride = attr.stride;
mAppliedAttributes[idx].pointer = attr.pointer;
mAppliedAttributes[idx].buffer.set(attr.buffer.get());
mStateManager->bindVertexArray(0);
}
} }
void VertexArrayGL::setAttributeDivisor(size_t idx, GLuint divisor) void VertexArrayGL::setAttributeDivisor(size_t idx, GLuint divisor)
{ {
if (mAppliedAttributes[idx].divisor != divisor) mAttributes[idx].divisor = divisor;
{
mStateManager->bindVertexArray(mVertexArrayID);
mFunctions->vertexAttribDivisor(idx, divisor);
mAppliedAttributes[idx].divisor = divisor;
mStateManager->bindVertexArray(0);
}
} }
void VertexArrayGL::enableAttribute(size_t idx, bool enabledState) void VertexArrayGL::enableAttribute(size_t idx, bool enabledState)
{ {
if (mAppliedAttributes[idx].enabled != enabledState) mAttributes[idx].enabled = enabledState;
}
void VertexArrayGL::syncState() const
{
mStateManager->bindVertexArray(mVertexArrayID);
GLuint elementArrayBufferID = 0;
if (mElementArrayBuffer.get() != nullptr)
{
const BufferGL *bufferGL = GetImplAs<BufferGL>(mElementArrayBuffer.get());
elementArrayBufferID = bufferGL->getBufferID();
}
if (elementArrayBufferID != mAppliedElementArrayBuffer)
{ {
mStateManager->bindVertexArray(mVertexArrayID); mStateManager->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBufferID);
mAppliedElementArrayBuffer = elementArrayBufferID;
}
if (enabledState) for (size_t idx = 0; idx < mAttributes.size(); idx++)
{ {
mFunctions->enableVertexAttribArray(idx); if (mAppliedAttributes[idx] != mAttributes[idx])
}
else
{ {
mFunctions->disableVertexAttribArray(idx); if (mAttributes[idx].enabled)
{
mFunctions->enableVertexAttribArray(idx);
}
else
{
mFunctions->disableVertexAttribArray(idx);
}
const gl::Buffer *arrayBuffer = mAttributes[idx].buffer.get();
if (arrayBuffer != nullptr)
{
const BufferGL *arrayBufferGL = GetImplAs<BufferGL>(arrayBuffer);
mStateManager->bindBuffer(GL_ARRAY_BUFFER, arrayBufferGL->getBufferID());
}
else
{
// This will take some extra work, core OpenGL doesn't support binding raw data pointers
// to VAOs
UNIMPLEMENTED();
}
if (mAttributes[idx].pureInteger)
{
mFunctions->vertexAttribIPointer(idx, mAttributes[idx].size, mAttributes[idx].type,
mAttributes[idx].stride, mAttributes[idx].pointer);
}
else
{
mFunctions->vertexAttribPointer(idx, mAttributes[idx].size, mAttributes[idx].type,
mAttributes[idx].normalized, mAttributes[idx].stride,
mAttributes[idx].pointer);
}
mFunctions->vertexAttribDivisor(idx, mAttributes[idx].divisor);
mAppliedAttributes[idx] = mAttributes[idx];
} }
mAppliedAttributes[idx].enabled = enabledState;
mStateManager->bindVertexArray(0);
} }
} }
......
...@@ -28,6 +28,8 @@ class VertexArrayGL : public VertexArrayImpl ...@@ -28,6 +28,8 @@ 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;
void syncState() const;
GLuint getVertexArrayID() const; GLuint getVertexArrayID() const;
private: private:
...@@ -38,8 +40,11 @@ class VertexArrayGL : public VertexArrayImpl ...@@ -38,8 +40,11 @@ class VertexArrayGL : public VertexArrayImpl
GLuint mVertexArrayID; GLuint mVertexArrayID;
GLuint mAppliedElementArrayBuffer; BindingPointer<const gl::Buffer> mElementArrayBuffer;
std::vector<gl::VertexAttribute> mAppliedAttributes; std::vector<gl::VertexAttribute> mAttributes;
mutable GLuint mAppliedElementArrayBuffer;
mutable std::vector<gl::VertexAttribute> mAppliedAttributes;
}; };
} }
......
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