Refactor VertexAttribute to split the "current value" for generic attributes into its own class.
VAOs in GLES 3 do not store the current values, so these must be handled separately from other Vertex
Attribute data.
TRAC #23390
Signed-off-by: Shannon Woods
Signed-off-by: Geoff Lang
Authored-by: Jamie Madill
diff --git a/src/libGLESv2/renderer/VertexDataManager.cpp b/src/libGLESv2/renderer/VertexDataManager.cpp
index 78b2e4f..2cd18d8 100644
--- a/src/libGLESv2/renderer/VertexDataManager.cpp
+++ b/src/libGLESv2/renderer/VertexDataManager.cpp
@@ -26,12 +26,25 @@
namespace rx
{
-static int elementsInBuffer(const gl::VertexAttribute &attribute, int size)
+static int ElementsInBuffer(const gl::VertexAttribute &attribute, int size)
{
int stride = attribute.stride();
return (size - attribute.mOffset % stride + (stride - attribute.typeSize())) / stride;
}
+static bool DirectStoragePossible(VertexBufferInterface *vb, const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue)
+{
+ gl::Buffer *buffer = attrib.mBoundBuffer.get();
+ BufferStorage *storage = buffer ? buffer->getStorage() : NULL;
+
+ const bool isAligned = (attrib.stride() % 4 == 0) && (attrib.mOffset % 4 == 0);
+ const bool requiresConversion = attrib.mArrayEnabled ?
+ vb->getVertexBuffer()->requiresConversion(attrib) :
+ vb->getVertexBuffer()->requiresConversion(currentValue);
+
+ return storage && storage->supportsDirectBinding() && !requiresConversion && isAligned;
+}
+
VertexDataManager::VertexDataManager(Renderer *renderer) : mRenderer(renderer)
{
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
@@ -63,17 +76,8 @@
}
}
-static bool directStoragePossible(VertexBufferInterface* vb, const gl::VertexAttribute& attrib)
-{
- gl::Buffer *buffer = attrib.mBoundBuffer.get();
- BufferStorage *storage = buffer ? buffer->getStorage() : NULL;
-
- const bool isAligned = (attrib.stride() % 4 == 0) && (attrib.mOffset % 4 == 0);
-
- return storage && storage->supportsDirectBinding() && !vb->getVertexBuffer()->requiresConversion(attrib) && isAligned;
-}
-
-GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *translated, GLsizei instances)
+GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], const gl::VertexAttribCurrentValueData currentValues[],
+ gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *translated, GLsizei instances)
{
if (!mStreamingBuffer)
{
@@ -94,7 +98,7 @@
StaticVertexBufferInterface *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL;
if (staticBuffer && staticBuffer->getBufferSize() > 0 && staticBuffer->lookupAttribute(attribs[i]) == -1 &&
- !directStoragePossible(staticBuffer, attribs[i]))
+ !DirectStoragePossible(staticBuffer, attribs[i], currentValues[i]))
{
buffer->invalidateStaticData();
}
@@ -110,13 +114,13 @@
StaticVertexBufferInterface *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL;
VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
- if (!directStoragePossible(vertexBuffer, attribs[i]))
+ if (!DirectStoragePossible(vertexBuffer, attribs[i], currentValues[i]))
{
if (staticBuffer)
{
if (staticBuffer->getBufferSize() == 0)
{
- int totalCount = elementsInBuffer(attribs[i], buffer->size());
+ int totalCount = ElementsInBuffer(attribs[i], buffer->size());
staticBuffer->reserveVertexSpace(attribs[i], totalCount, 0);
}
}
@@ -148,7 +152,7 @@
VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
BufferStorage *storage = buffer ? buffer->getStorage() : NULL;
- bool directStorage = directStoragePossible(vertexBuffer, attribs[i]);
+ bool directStorage = DirectStoragePossible(vertexBuffer, attribs[i], currentValues[i]);
std::size_t streamOffset = -1;
unsigned int outputElementSize = 0;
@@ -166,10 +170,10 @@
if (streamOffset == -1)
{
// Convert the entire buffer
- int totalCount = elementsInBuffer(attribs[i], storage->getSize());
+ int totalCount = ElementsInBuffer(attribs[i], storage->getSize());
int startIndex = attribs[i].mOffset / attribs[i].stride();
- streamOffset = staticBuffer->storeVertexAttributes(attribs[i], -startIndex, totalCount, 0);
+ streamOffset = staticBuffer->storeVertexAttributes(attribs[i], currentValues[i], -startIndex, totalCount, 0);
}
if (streamOffset != -1)
@@ -185,7 +189,7 @@
else
{
outputElementSize = mStreamingBuffer->getVertexBuffer()->getSpaceRequired(attribs[i], 1, 0);
- streamOffset = mStreamingBuffer->storeVertexAttributes(attribs[i], start, count, instances);
+ streamOffset = mStreamingBuffer->storeVertexAttributes(attribs[i], currentValues[i], start, count, instances);
}
if (streamOffset == -1)
@@ -199,6 +203,7 @@
translated[i].divisor = attribs[i].mDivisor;
translated[i].attribute = &attribs[i];
+ translated[i].currentValueType = currentValues[i].Type;
translated[i].stride = outputElementSize;
translated[i].offset = streamOffset;
}
@@ -211,10 +216,10 @@
StreamingVertexBufferInterface *buffer = mCurrentValueBuffer[i];
- if (memcmp(&mCurrentValue[i], &attribs[i].mCurrentValue, sizeof(gl::VertexAttribute::CurrentValueData)) != 0)
+ if (memcmp(&mCurrentValue[i], ¤tValues[i], sizeof(gl::VertexAttribCurrentValueData)) != 0)
{
buffer->reserveVertexSpace(attribs[i], 1, 0);
- int streamOffset = buffer->storeVertexAttributes(attribs[i], 0, 1, 0);
+ int streamOffset = buffer->storeVertexAttributes(attribs[i], currentValues[i], 0, 1, 0);
if (streamOffset == -1)
{
return GL_OUT_OF_MEMORY;
@@ -229,6 +234,7 @@
translated[i].divisor = 0;
translated[i].attribute = &attribs[i];
+ translated[i].currentValueType = currentValues[i].Type;
translated[i].stride = 0;
translated[i].offset = mCurrentValueOffsets[i];
}