Commit 5b21ed5f by Jamie Madill

Revert "Implement dirty bits acceleration for VertexArrayGL."

Seems to cause an exception in Release, in end2end_tests. BUG=angleproject:1040 This reverts commit 6d51c70c. Change-Id: I6548bc68dce07d2d85e40afdb604157e689c1d6c Reviewed-on: https://chromium-review.googlesource.com/293821Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 6d51c70c
...@@ -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.setVertexAttribDivisor(index, divisor); mState.getVertexArray()->setVertexAttribDivisor(index, divisor);
} }
void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param) void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
......
...@@ -846,8 +846,6 @@ bool State::removeDrawFramebufferBinding(GLuint framebuffer) ...@@ -846,8 +846,6 @@ 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
...@@ -867,8 +865,6 @@ bool State::removeVertexArrayBinding(GLuint vertexArray) ...@@ -867,8 +865,6 @@ 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;
} }
...@@ -1055,7 +1051,6 @@ Buffer *State::getTargetBuffer(GLenum target) const ...@@ -1055,7 +1051,6 @@ 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])
...@@ -1079,23 +1074,10 @@ void State::setVertexAttribi(GLuint index, const GLint values[4]) ...@@ -1079,23 +1074,10 @@ 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, void State::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
Buffer *boundBuffer, bool pureInteger, GLsizei stride, const void *pointer)
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,7 +226,6 @@ class State : angle::NonCopyable ...@@ -226,7 +226,6 @@ 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,14 +73,12 @@ void VertexArray::setVertexAttribDivisor(size_t index, GLuint divisor) ...@@ -73,14 +73,12 @@ 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)
...@@ -111,22 +109,11 @@ void VertexArray::setAttributeState(size_t attributeIndex, gl::Buffer *boundBuff ...@@ -111,22 +109,11 @@ 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,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#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>
...@@ -30,9 +29,6 @@ namespace gl ...@@ -30,9 +29,6 @@ namespace gl
{ {
class Buffer; class Buffer;
// Used in other places.
typedef std::bitset<MAX_VERTEX_ATTRIBS> AttributesMask;
class VertexArray class VertexArray
{ {
public: public:
...@@ -70,10 +66,6 @@ class VertexArray ...@@ -70,10 +66,6 @@ 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;
...@@ -82,37 +74,12 @@ class VertexArray ...@@ -82,37 +74,12 @@ 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);
mActiveAttributesMask.set(location); mActiveAttributeLocations.push_back(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();
mActiveAttributesMask.reset(); mActiveAttributeLocations.clear();
} }
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 gl::AttributesMask &ProgramGL::getActiveAttributesMask() const const std::vector<GLuint> &ProgramGL::getActiveAttributeLocations() const
{ {
return mActiveAttributesMask; return mActiveAttributeLocations;
} }
} }
...@@ -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 gl::AttributesMask &getActiveAttributesMask() const; const std::vector<GLuint> &getActiveAttributeLocations() 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
gl::AttributesMask mActiveAttributesMask; std::vector<GLuint> mActiveAttributeLocations;
GLuint mProgramID; GLuint mProgramID;
}; };
......
...@@ -383,8 +383,7 @@ gl::Error StateManagerGL::setDrawArraysState(const gl::Data &data, GLint first, ...@@ -383,8 +383,7 @@ 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 = gl::Error error = vaoGL->syncDrawArraysState(programGL->getActiveAttributeLocations(), first, count);
vaoGL->syncDrawArraysState(programGL->getActiveAttributesMask(), first, count);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -406,8 +405,7 @@ gl::Error StateManagerGL::setDrawElementsState(const gl::Data &data, GLsizei cou ...@@ -406,8 +405,7 @@ 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->getActiveAttributesMask(), count, gl::Error error = vaoGL->syncDrawElementsState(programGL->getActiveAttributeLocations(), count, type, indices, outIndices);
type, indices, outIndices);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -1081,7 +1079,7 @@ void StateManagerGL::syncState(const gl::State &state, const gl::State::DirtyBit ...@@ -1081,7 +1079,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:
state.getVertexArray()->syncImplState(); // TODO(jmadill): implement this
break; break;
case gl::State::DIRTY_BIT_PROGRAM_BINDING: case gl::State::DIRTY_BIT_PROGRAM_BINDING:
// TODO(jmadill): implement this // TODO(jmadill): implement this
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include "libANGLE/renderer/gl/VertexArrayGL.h" #include "libANGLE/renderer/gl/VertexArrayGL.h"
#include "common/BitSetIterator.h"
#include "common/debug.h" #include "common/debug.h"
#include "common/mathutil.h" #include "common/mathutil.h"
#include "common/utilities.h" #include "common/utilities.h"
...@@ -19,20 +18,10 @@ ...@@ -19,20 +18,10 @@
#include "libANGLE/renderer/gl/FunctionsGL.h" #include "libANGLE/renderer/gl/FunctionsGL.h"
#include "libANGLE/renderer/gl/StateManagerGL.h" #include "libANGLE/renderer/gl/StateManagerGL.h"
using namespace gl;
namespace rx namespace rx
{ {
namespace
{
bool AttributeNeedsStreaming(const VertexAttribute &attribute)
{
return (attribute.enabled && attribute.buffer.get() == nullptr);
}
} // anonymous namespace
VertexArrayGL::VertexArrayGL(const VertexArray::Data &data, VertexArrayGL::VertexArrayGL(const gl::VertexArray::Data &data,
const FunctionsGL *functions, const FunctionsGL *functions,
StateManagerGL *stateManager) StateManagerGL *stateManager)
: VertexArrayImpl(data), : VertexArrayImpl(data),
...@@ -75,40 +64,29 @@ VertexArrayGL::~VertexArrayGL() ...@@ -75,40 +64,29 @@ VertexArrayGL::~VertexArrayGL()
} }
} }
gl::Error VertexArrayGL::syncDrawArraysState(const gl::AttributesMask &activeAttributesMask, gl::Error VertexArrayGL::syncDrawArraysState(const std::vector<GLuint> &activeAttribLocations, GLint first, GLsizei count) const
GLint first,
GLsizei count) const
{ {
return syncDrawState(activeAttributesMask, first, count, GL_NONE, nullptr, nullptr); return syncDrawState(activeAttribLocations, first, count, GL_NONE, nullptr, nullptr);
} }
gl::Error VertexArrayGL::syncDrawElementsState(const gl::AttributesMask &activeAttributesMask, gl::Error VertexArrayGL::syncDrawElementsState(const std::vector<GLuint> &activeAttribLocations, GLsizei count,
GLsizei count, GLenum type, const GLvoid *indices, const GLvoid **outIndices) const
GLenum type,
const GLvoid *indices,
const GLvoid **outIndices) const
{ {
return syncDrawState(activeAttributesMask, 0, count, type, indices, outIndices); return syncDrawState(activeAttribLocations, 0, count, type, indices, outIndices);
} }
gl::Error VertexArrayGL::syncDrawState(const gl::AttributesMask &activeAttributesMask, gl::Error VertexArrayGL::syncDrawState(const std::vector<GLuint> &activeAttribLocations, GLint first, GLsizei count, GLenum type, const GLvoid *indices, const GLvoid **outIndices) const
GLint first,
GLsizei count,
GLenum type,
const GLvoid *indices,
const GLvoid **outIndices) const
{ {
mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID()); mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID());
// 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 = mAttributesNeedStreaming.any(); 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
RangeUI indexRange(0, 0); gl::RangeUI indexRange(0, 0);
if (type != GL_NONE) if (type != GL_NONE)
{ {
Error error = gl::Error error = syncIndexData(count, type, indices, attributesNeedStreaming, &indexRange, outIndices);
syncIndexData(count, type, indices, attributesNeedStreaming, &indexRange, outIndices);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -121,24 +99,130 @@ gl::Error VertexArrayGL::syncDrawState(const gl::AttributesMask &activeAttribute ...@@ -121,24 +99,130 @@ gl::Error VertexArrayGL::syncDrawState(const gl::AttributesMask &activeAttribute
indexRange.end = first + count; indexRange.end = first + count;
} }
if (attributesNeedStreaming) // 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(activeAttribLocations, attributesNeedStreaming, indexRange,
&streamingDataSize, &maxAttributeDataSize);
if (error.isError())
{ {
Error error = streamAttributes(activeAttributesMask, indexRange); return error;
}
if (streamingDataSize > 0)
{
ASSERT(attributesNeedStreaming);
error = streamAttributes(activeAttribLocations, streamingDataSize, maxAttributeDataSize,
indexRange);
if (error.isError()) if (error.isError())
{ {
return error; return error;
} }
} }
return Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
}
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 activeAttrib = 0; activeAttrib < activeAttribLocations.size(); activeAttrib++)
{
GLuint idx = activeAttribLocations[activeAttrib];
if (attribs[idx].enabled && attribs[idx].buffer.get() == nullptr)
{
return true;
}
}
return false;
}
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 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
// attributes
if (mAppliedAttributes[idx].enabled != attrib.enabled)
{
if (attrib.enabled)
{
mFunctions->enableVertexAttribArray(idx);
}
else
{
mFunctions->disableVertexAttribArray(idx);
}
mAppliedAttributes[idx].enabled = attrib.enabled;
}
if (mAppliedAttributes[idx].divisor != attrib.divisor)
{
mFunctions->vertexAttribDivisor(idx, attrib.divisor);
mAppliedAttributes[idx].divisor = attrib.divisor;
}
if (attribs[idx].enabled && attrib.buffer.get() == nullptr)
{
ASSERT(attributesNeedStreaming);
const size_t streamedVertexCount = indexRange.end - indexRange.start + 1;
// If streaming is going to be required, compute the size of the required buffer
// and how much slack space at the beginning of the buffer will be required by determining
// the attribute with the largest data size.
size_t typeSize = ComputeVertexAttributeTypeSize(attrib);
*outStreamingDataSize += typeSize * streamedVertexCount;
*outMaxAttributeDataSize = std::max(*outMaxAttributeDataSize, typeSize);
}
else
{
// Sync the attribute with no translation
if (mAppliedAttributes[idx] != attrib)
{
const gl::Buffer *arrayBuffer = attrib.buffer.get();
if (arrayBuffer != nullptr)
{
const BufferGL *arrayBufferGL = GetImplAs<BufferGL>(arrayBuffer);
mStateManager->bindBuffer(GL_ARRAY_BUFFER, arrayBufferGL->getBufferID());
}
else
{
mStateManager->bindBuffer(GL_ARRAY_BUFFER, 0);
}
if (attrib.pureInteger)
{
mFunctions->vertexAttribIPointer(idx, attrib.size, attrib.type,
attrib.stride, attrib.pointer);
}
else
{
mFunctions->vertexAttribPointer(idx, attrib.size, attrib.type,
attrib.normalized, attrib.stride,
attrib.pointer);
}
mAppliedAttributes[idx] = attrib;
}
}
}
return gl::Error(GL_NO_ERROR);
} }
Error VertexArrayGL::syncIndexData(GLsizei count, gl::Error VertexArrayGL::syncIndexData(GLsizei count, GLenum type, const GLvoid *indices, bool attributesNeedStreaming,
GLenum type, gl::RangeUI *outIndexRange, const GLvoid **outIndices) const
const GLvoid *indices,
bool attributesNeedStreaming,
RangeUI *outIndexRange,
const GLvoid **outIndices) const
{ {
ASSERT(outIndices); ASSERT(outIndices);
...@@ -158,8 +242,7 @@ Error VertexArrayGL::syncIndexData(GLsizei count, ...@@ -158,8 +242,7 @@ Error VertexArrayGL::syncIndexData(GLsizei count,
if (attributesNeedStreaming) if (attributesNeedStreaming)
{ {
ptrdiff_t elementArrayBufferOffset = reinterpret_cast<ptrdiff_t>(indices); ptrdiff_t elementArrayBufferOffset = reinterpret_cast<ptrdiff_t>(indices);
Error error = mData.getElementArrayBuffer()->getIndexRange( gl::Error error = mData.getElementArrayBuffer()->getIndexRange(type, static_cast<size_t>(elementArrayBufferOffset), count, outIndexRange);
type, static_cast<size_t>(elementArrayBufferOffset), count, outIndexRange);
if (error.isError()) if (error.isError())
{ {
return error; return error;
...@@ -177,7 +260,7 @@ Error VertexArrayGL::syncIndexData(GLsizei count, ...@@ -177,7 +260,7 @@ Error VertexArrayGL::syncIndexData(GLsizei count,
// Only compute the index range if the attributes also need to be streamed // Only compute the index range if the attributes also need to be streamed
if (attributesNeedStreaming) if (attributesNeedStreaming)
{ {
*outIndexRange = ComputeIndexRange(type, indices, count); *outIndexRange = gl::ComputeIndexRange(type, indices, count);
} }
// Allocate the streaming element array buffer // Allocate the streaming element array buffer
...@@ -191,7 +274,7 @@ Error VertexArrayGL::syncIndexData(GLsizei count, ...@@ -191,7 +274,7 @@ Error VertexArrayGL::syncIndexData(GLsizei count,
mAppliedElementArrayBuffer.set(nullptr); mAppliedElementArrayBuffer.set(nullptr);
// Make sure the element array buffer is large enough // Make sure the element array buffer is large enough
const Type &indexTypeInfo = GetTypeInfo(type); const gl::Type &indexTypeInfo = gl::GetTypeInfo(type);
size_t requiredStreamingBufferSize = indexTypeInfo.bytes * count; size_t requiredStreamingBufferSize = indexTypeInfo.bytes * count;
if (requiredStreamingBufferSize > mStreamingElementArrayBufferSize) if (requiredStreamingBufferSize > mStreamingElementArrayBufferSize)
{ {
...@@ -209,51 +292,12 @@ Error VertexArrayGL::syncIndexData(GLsizei count, ...@@ -209,51 +292,12 @@ Error VertexArrayGL::syncIndexData(GLsizei count,
*outIndices = nullptr; *outIndices = nullptr;
} }
return Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
}
void VertexArrayGL::computeStreamingAttributeSizes(const gl::AttributesMask &activeAttributesMask,
const gl::RangeUI &indexRange,
size_t *outStreamingDataSize,
size_t *outMaxAttributeDataSize) const
{
*outStreamingDataSize = 0;
*outMaxAttributeDataSize = 0;
ASSERT(mAttributesNeedStreaming.any());
const auto &attribs = mData.getVertexAttributes();
for (unsigned int idx : angle::IterateBitSet(mAttributesNeedStreaming & activeAttributesMask))
{
const auto &attrib = attribs[idx];
ASSERT(AttributeNeedsStreaming(attrib));
const size_t streamedVertexCount = indexRange.end - indexRange.start + 1;
// If streaming is going to be required, compute the size of the required buffer
// and how much slack space at the beginning of the buffer will be required by determining
// the attribute with the largest data size.
size_t typeSize = ComputeVertexAttributeTypeSize(attrib);
*outStreamingDataSize += typeSize * streamedVertexCount;
*outMaxAttributeDataSize = std::max(*outMaxAttributeDataSize, typeSize);
}
} }
gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &activeAttributesMask, gl::Error VertexArrayGL::streamAttributes(const std::vector<GLuint> &activeAttribLocations, size_t streamingDataSize,
const gl::RangeUI &indexRange) const size_t maxAttributeDataSize, const gl::RangeUI &indexRange) const
{ {
// Sync the vertex attribute state and track what data needs to be streamed
size_t streamingDataSize = 0;
size_t maxAttributeDataSize = 0;
computeStreamingAttributeSizes(activeAttributesMask, indexRange, &streamingDataSize,
&maxAttributeDataSize);
if (streamingDataSize == 0)
{
return gl::Error(GL_NO_ERROR);
}
if (mStreamingArrayBuffer == 0) if (mStreamingArrayBuffer == 0)
{ {
mFunctions->genBuffers(1, &mStreamingArrayBuffer); mFunctions->genBuffers(1, &mStreamingArrayBuffer);
...@@ -285,19 +329,20 @@ gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &activeAttrib ...@@ -285,19 +329,20 @@ gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &activeAttrib
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 (unsigned int idx : for (size_t activeAttrib = 0; activeAttrib < activeAttribLocations.size(); activeAttrib++)
angle::IterateBitSet(mAttributesNeedStreaming & activeAttributesMask))
{ {
GLuint idx = activeAttribLocations[activeAttrib];
const auto &attrib = attribs[idx]; const auto &attrib = attribs[idx];
ASSERT(AttributeNeedsStreaming(attrib));
if (attrib.enabled && attrib.buffer.get() == nullptr)
{
const size_t sourceStride = ComputeVertexAttributeStride(attrib); const size_t sourceStride = ComputeVertexAttributeStride(attrib);
const size_t destStride = ComputeVertexAttributeTypeSize(attrib); const size_t destStride = ComputeVertexAttributeTypeSize(attrib);
const uint8_t *inputPointer = reinterpret_cast<const uint8_t *>(attrib.pointer); const uint8_t *inputPointer = reinterpret_cast<const uint8_t*>(attrib.pointer);
// Pack the data when copying it, user could have supplied a very large stride that // Pack the data when copying it, user could have supplied a very large stride that would
// would cause the buffer to be much larger than needed. // cause the buffer to be much larger than needed.
if (destStride == sourceStride) if (destStride == sourceStride)
{ {
// Can copy in one go, the data is packed // Can copy in one go, the data is packed
...@@ -311,14 +356,16 @@ gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &activeAttrib ...@@ -311,14 +356,16 @@ gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &activeAttrib
for (size_t vertexIdx = indexRange.start; vertexIdx <= indexRange.end; vertexIdx++) for (size_t vertexIdx = indexRange.start; vertexIdx <= indexRange.end; vertexIdx++)
{ {
memcpy(bufferPointer + curBufferOffset + (destStride * vertexIdx), memcpy(bufferPointer + curBufferOffset + (destStride * vertexIdx),
inputPointer + (sourceStride * vertexIdx), destStride); inputPointer + (sourceStride * vertexIdx),
destStride);
} }
} }
// Compute where the 0-index vertex would be. // Compute where the 0-index vertex would be.
const size_t vertexStartOffset = curBufferOffset - (indexRange.start * destStride); const size_t vertexStartOffset = curBufferOffset - (indexRange.start * destStride);
mFunctions->vertexAttribPointer(idx, attrib.size, attrib.type, attrib.normalized, mFunctions->vertexAttribPointer(
idx, attrib.size, attrib.type, attrib.normalized,
static_cast<GLsizei>(destStride), static_cast<GLsizei>(destStride),
reinterpret_cast<const GLvoid *>(vertexStartOffset)); reinterpret_cast<const GLvoid *>(vertexStartOffset));
...@@ -328,16 +375,17 @@ gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &activeAttrib ...@@ -328,16 +375,17 @@ gl::Error VertexArrayGL::streamAttributes(const gl::AttributesMask &activeAttrib
// need to be streamed later, there is no chance that the caching will skip it. // need to be streamed later, there is no chance that the caching will skip it.
mAppliedAttributes[idx].size = static_cast<GLuint>(-1); mAppliedAttributes[idx].size = static_cast<GLuint>(-1);
} }
}
unmapResult = mFunctions->unmapBuffer(GL_ARRAY_BUFFER); unmapResult = mFunctions->unmapBuffer(GL_ARRAY_BUFFER);
} }
if (unmapResult != GL_TRUE) if (unmapResult != GL_TRUE)
{ {
return Error(GL_OUT_OF_MEMORY, "Failed to unmap the client data streaming buffer."); return gl::Error(GL_OUT_OF_MEMORY, "Failed to unmap the client data streaming buffer.");
} }
return Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
GLuint VertexArrayGL::getVertexArrayID() const GLuint VertexArrayGL::getVertexArrayID() const
...@@ -355,114 +403,4 @@ GLuint VertexArrayGL::getAppliedElementArrayBufferID() const ...@@ -355,114 +403,4 @@ GLuint VertexArrayGL::getAppliedElementArrayBufferID() const
return GetImplAs<BufferGL>(mAppliedElementArrayBuffer.get())->getBufferID(); return GetImplAs<BufferGL>(mAppliedElementArrayBuffer.get())->getBufferID();
} }
void VertexArrayGL::updateNeedsStreaming(size_t attribIndex)
{
const VertexAttribute &attrib = mData.getVertexAttribute(attribIndex);
mAttributesNeedStreaming.set(attribIndex, AttributeNeedsStreaming(attrib));
}
void VertexArrayGL::updateAttribEnabled(size_t attribIndex)
{
const VertexAttribute &attrib = mData.getVertexAttribute(attribIndex);
if (mAppliedAttributes[attribIndex].enabled == attrib.enabled)
{
return;
}
updateNeedsStreaming(attribIndex);
mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID());
if (attrib.enabled)
{
mFunctions->enableVertexAttribArray(static_cast<GLuint>(attribIndex));
}
else
{
mFunctions->disableVertexAttribArray(static_cast<GLuint>(attribIndex));
}
mAppliedAttributes[attribIndex].enabled = attrib.enabled;
} }
void VertexArrayGL::updateAttribPointer(size_t attribIndex)
{
const VertexAttribute &attrib = mData.getVertexAttribute(attribIndex);
if (mAppliedAttributes[attribIndex] == attrib)
{
return;
}
updateNeedsStreaming(attribIndex);
mAppliedAttributes[attribIndex] = attrib;
// If we need to stream, defer the attribPointer to the draw call.
if (mAttributesNeedStreaming[attribIndex])
{
return;
}
mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID());
const Buffer *arrayBuffer = attrib.buffer.get();
if (arrayBuffer != nullptr)
{
const BufferGL *arrayBufferGL = GetImplAs<BufferGL>(arrayBuffer);
mStateManager->bindBuffer(GL_ARRAY_BUFFER, arrayBufferGL->getBufferID());
}
else
{
mStateManager->bindBuffer(GL_ARRAY_BUFFER, 0);
}
if (attrib.pureInteger)
{
mFunctions->vertexAttribIPointer(static_cast<GLuint>(attribIndex), attrib.size, attrib.type,
attrib.stride, attrib.pointer);
}
else
{
mFunctions->vertexAttribPointer(static_cast<GLuint>(attribIndex), attrib.size, attrib.type,
attrib.normalized, attrib.stride, attrib.pointer);
}
}
void VertexArrayGL::syncState(const VertexArray::DirtyBits &dirtyBits)
{
for (unsigned long dirtyBit : angle::IterateBitSet(dirtyBits))
{
if (dirtyBit == VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER)
{
// TODO(jmadill): Element array buffer bindings
}
else if (dirtyBit >= VertexArray::DIRTY_BIT_ATTRIB_0_ENABLED &&
dirtyBit < VertexArray::DIRTY_BIT_ATTRIB_MAX_ENABLED)
{
size_t attribIndex =
static_cast<size_t>(dirtyBit) - VertexArray::DIRTY_BIT_ATTRIB_0_ENABLED;
updateAttribEnabled(attribIndex);
}
else if (dirtyBit >= VertexArray::DIRTY_BIT_ATTRIB_0_POINTER &&
dirtyBit < VertexArray::DIRTY_BIT_ATTRIB_MAX_POINTER)
{
size_t attribIndex =
static_cast<size_t>(dirtyBit) - VertexArray::DIRTY_BIT_ATTRIB_0_POINTER;
updateAttribPointer(attribIndex);
}
else if (dirtyBit >= VertexArray::DIRTY_BIT_ATTRIB_0_DIVISOR &&
dirtyBit < VertexArray::DIRTY_BIT_ATTRIB_MAX_DIVISOR)
{
size_t attribIndex =
static_cast<size_t>(dirtyBit) - VertexArray::DIRTY_BIT_ATTRIB_0_DIVISOR;
const VertexAttribute &attrib = mData.getVertexAttribute(attribIndex);
if (mAppliedAttributes[attribIndex].divisor != attrib.divisor)
{
mStateManager->bindVertexArray(mVertexArrayID, getAppliedElementArrayBufferID());
mFunctions->vertexAttribDivisor(static_cast<GLuint>(attribIndex), attrib.divisor);
mAppliedAttributes[attribIndex].divisor = attrib.divisor;
}
}
else
UNREACHABLE();
}
}
} // rx
...@@ -23,46 +23,33 @@ class VertexArrayGL : public VertexArrayImpl ...@@ -23,46 +23,33 @@ 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 gl::AttributesMask &activeAttributesMask, gl::Error syncDrawArraysState(const std::vector<GLuint> &activeAttribLoations, GLint first, GLsizei count) const;
GLint first, gl::Error syncDrawElementsState(const std::vector<GLuint> &activeAttribLoations, GLsizei count, GLenum type,
GLsizei count) const; const GLvoid *indices, const GLvoid **outIndices) 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;
void syncState(const gl::VertexArray::DirtyBits &dirtyBits) override;
private: private:
gl::Error syncDrawState(const gl::AttributesMask &activeAttributesMask, gl::Error syncDrawState(const std::vector<GLuint> &activeAttribLoations, GLint first, GLsizei count,
GLint first, GLenum type, const GLvoid *indices, const GLvoid **outIndices) const;
GLsizei count,
GLenum type,
const GLvoid *indices,
const GLvoid **outIndices) const;
// Apply index data, only sets outIndexRange if attributesNeedStreaming is true // Check if any vertex attributes need to be streamed
gl::Error syncIndexData(GLsizei count, GLenum type, const GLvoid *indices, bool attributesNeedStreaming, bool doAttributesNeedStreaming(const std::vector<GLuint> &activeAttribLoations) const;
gl::RangeUI *outIndexRange, const GLvoid **outIndices) const;
// 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
void computeStreamingAttributeSizes(const gl::AttributesMask &activeAttributesMask, gl::Error syncAttributeState(const std::vector<GLuint> &activeAttribLoations, bool attributesNeedStreaming,
const gl::RangeUI &indexRange, const gl::RangeUI &indexRange, size_t *outStreamingDataSize,
size_t *outStreamingDataSize,
size_t *outMaxAttributeDataSize) const; size_t *outMaxAttributeDataSize) const;
// Stream attributes that have client data // Apply index data, only sets outIndexRange if attributesNeedStreaming is true
gl::Error streamAttributes(const gl::AttributesMask &activeAttributesMask, gl::Error syncIndexData(GLsizei count, GLenum type, const GLvoid *indices, bool attributesNeedStreaming,
const gl::RangeUI &indexRange) const; gl::RangeUI *outIndexRange, const GLvoid **outIndices) const;
void updateNeedsStreaming(size_t attribIndex); // Stream attributes that have client data
void updateAttribEnabled(size_t attribIndex); gl::Error streamAttributes(const std::vector<GLuint> &activeAttribLoations, size_t streamingDataSize,
void updateAttribPointer(size_t attribIndex); size_t maxAttributeDataSize, const gl::RangeUI &indexRange) const;
const FunctionsGL *mFunctions; const FunctionsGL *mFunctions;
StateManagerGL *mStateManager; StateManagerGL *mStateManager;
...@@ -77,8 +64,6 @@ class VertexArrayGL : public VertexArrayImpl ...@@ -77,8 +64,6 @@ 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