VertexDataManager now supports direct buffers when vertex conversion is not needed.
TRAC #22297
Signed-off-by: Jamie Madill
Signed-off-by: Nicolas Capens
Author: Geoff Lang
git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1886 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/renderer/InputLayoutCache.cpp b/src/libGLESv2/renderer/InputLayoutCache.cpp
index 8e76cec..6bef612 100644
--- a/src/libGLESv2/renderer/InputLayoutCache.cpp
+++ b/src/libGLESv2/renderer/InputLayoutCache.cpp
@@ -9,6 +9,7 @@
#include "libGLESv2/renderer/InputLayoutCache.h"
#include "libGLESv2/renderer/VertexBuffer11.h"
+#include "libGLESv2/renderer/BufferStorage11.h"
#include "libGLESv2/renderer/ShaderExecutable11.h"
#include "libGLESv2/ProgramBinary.h"
@@ -69,6 +70,7 @@
if (attributes[i].active)
{
VertexBuffer11 *vertexBuffer = VertexBuffer11::makeVertexBuffer11(attributes[i].vertexBuffer);
+ BufferStorage11 *bufferStorage = attributes[i].storage ? BufferStorage11::makeBufferStorage11(attributes[i].storage) : NULL;
D3D11_INPUT_CLASSIFICATION inputClass = attributes[i].divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA;
@@ -81,7 +83,7 @@
ilKey.elements[ilKey.elementCount].InstanceDataStepRate = attributes[i].divisor;
ilKey.elementCount++;
- vertexBuffers[i] = vertexBuffer->getBuffer();
+ vertexBuffers[i] = bufferStorage ? bufferStorage->getBuffer() : vertexBuffer->getBuffer();
vertexStrides[i] = attributes[i].stride;
vertexOffsets[i] = attributes[i].offset;
}
diff --git a/src/libGLESv2/renderer/VertexDataManager.cpp b/src/libGLESv2/renderer/VertexDataManager.cpp
index 00a1633..f0b7123 100644
--- a/src/libGLESv2/renderer/VertexDataManager.cpp
+++ b/src/libGLESv2/renderer/VertexDataManager.cpp
@@ -86,25 +86,33 @@
{
gl::Buffer *buffer = attribs[i].mBoundBuffer.get();
StaticVertexBufferInterface *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL;
+ VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
BufferStorage *storage = buffer ? buffer->getStorage() : NULL;
- if (staticBuffer)
+ bool alignedStride = attribs[i].stride() % 4 == 0;
+ bool directStorage = alignedStride && storage && storage->supportsDirectBinding() &&
+ !vertexBuffer->getVertexBuffer()->requiresConversion(attribs[i]);
+
+ if (!directStorage)
{
- if (staticBuffer->getBufferSize() == 0)
+ if (staticBuffer)
{
- int totalCount = elementsInBuffer(attribs[i], storage->getSize());
- staticBuffer->reserveVertexSpace(attribs[i], totalCount, 0);
+ if (staticBuffer->getBufferSize() == 0)
+ {
+ int totalCount = elementsInBuffer(attribs[i], storage->getSize());
+ staticBuffer->reserveVertexSpace(attribs[i], totalCount, 0);
+ }
+ else if (staticBuffer->lookupAttribute(attribs[i]) == -1)
+ {
+ mStreamingBuffer->reserveVertexSpace(attribs[i], count, instances);
+ buffer->invalidateStaticData();
+ }
}
- else if (staticBuffer->lookupAttribute(attribs[i]) == -1)
+ else
{
mStreamingBuffer->reserveVertexSpace(attribs[i], count, instances);
- buffer->invalidateStaticData();
}
}
- else
- {
- mStreamingBuffer->reserveVertexSpace(attribs[i], count, instances);
- }
}
}
@@ -128,11 +136,20 @@
VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
BufferStorage *storage = buffer ? buffer->getStorage() : NULL;
+ bool alignedStride = attribs[i].stride() % 4 == 0;
+ bool directStorage = alignedStride && storage && storage->supportsDirectBinding() &&
+ !vertexBuffer->getVertexBuffer()->requiresConversion(attribs[i]);
std::size_t streamOffset = -1;
unsigned int outputElementSize = 0;
- if (staticBuffer)
+ if (directStorage)
+ {
+ outputElementSize = attribs[i].stride();
+ streamOffset = attribs[i].mOffset + outputElementSize * start;
+ storage->markBufferUsage();
+ }
+ else if (staticBuffer)
{
streamOffset = staticBuffer->lookupAttribute(attribs[i]);
outputElementSize = staticBuffer->getVertexBuffer()->getSpaceRequired(attribs[i], 1, 0);
@@ -167,8 +184,9 @@
return GL_OUT_OF_MEMORY;
}
+ translated[i].storage = directStorage ? storage : NULL;
translated[i].vertexBuffer = vertexBuffer->getVertexBuffer();
- translated[i].serial = vertexBuffer->getSerial();
+ translated[i].serial = directStorage ? storage->getSerial() : vertexBuffer->getSerial();
translated[i].divisor = attribs[i].mDivisor;
translated[i].attribute = &attribs[i];
@@ -200,6 +218,7 @@
mCurrentValueOffsets[i] = streamOffset;
}
+ translated[i].storage = NULL;
translated[i].vertexBuffer = mCurrentValueBuffer[i]->getVertexBuffer();
translated[i].serial = mCurrentValueBuffer[i]->getSerial();
translated[i].divisor = 0;
diff --git a/src/libGLESv2/renderer/VertexDataManager.h b/src/libGLESv2/renderer/VertexDataManager.h
index bd7bbaa..1c54838 100644
--- a/src/libGLESv2/renderer/VertexDataManager.h
+++ b/src/libGLESv2/renderer/VertexDataManager.h
@@ -31,6 +31,7 @@
UINT stride; // 0 means not to advance the read pointer at all
VertexBuffer *vertexBuffer;
+ BufferStorage *storage;
unsigned int serial;
unsigned int divisor;
};
diff --git a/src/libGLESv2/renderer/VertexDeclarationCache.cpp b/src/libGLESv2/renderer/VertexDeclarationCache.cpp
index 8ed226d..a65a158 100644
--- a/src/libGLESv2/renderer/VertexDeclarationCache.cpp
+++ b/src/libGLESv2/renderer/VertexDeclarationCache.cpp
@@ -82,6 +82,9 @@
{
if (attributes[i].active)
{
+ // Directly binding the storage buffer is not supported for d3d9
+ ASSERT(attributes[i].storage == NULL);
+
int stream = i;
if (instances > 0)