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/InputLayoutCache.cpp b/src/libGLESv2/renderer/InputLayoutCache.cpp
index a9d4857..28b0767 100644
--- a/src/libGLESv2/renderer/InputLayoutCache.cpp
+++ b/src/libGLESv2/renderer/InputLayoutCache.cpp
@@ -79,6 +79,9 @@
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;
+ DXGI_FORMAT dxgiFormat = attributes[i].attribute->mArrayEnabled ?
+ VertexBuffer11::getAttributeDXGIFormat(*attributes[i].attribute) :
+ VertexBuffer11::getCurrentValueDXGIFormat(attributes[i].currentValueType);
// Record the type of the associated vertex shader vector in our key
// This will prevent mismatched vertex shaders from using the same input layout
@@ -87,7 +90,7 @@
ilKey.elements[ilKey.elementCount].SemanticName = semanticName;
ilKey.elements[ilKey.elementCount].SemanticIndex = sortedSemanticIndices[i];
- ilKey.elements[ilKey.elementCount].Format = vertexBuffer->getDXGIFormat(*attributes[i].attribute);
+ ilKey.elements[ilKey.elementCount].Format = dxgiFormat;
ilKey.elements[ilKey.elementCount].InputSlot = i;
ilKey.elements[ilKey.elementCount].AlignedByteOffset = 0;
ilKey.elements[ilKey.elementCount].InputSlotClass = inputClass;
diff --git a/src/libGLESv2/renderer/Renderer.h b/src/libGLESv2/renderer/Renderer.h
index fa50bc0..a16efb5 100644
--- a/src/libGLESv2/renderer/Renderer.h
+++ b/src/libGLESv2/renderer/Renderer.h
@@ -43,6 +43,7 @@
class Buffer;
class Texture;
class Framebuffer;
+struct VertexAttribCurrentValueData;
}
namespace rx
@@ -130,7 +131,8 @@
virtual void applyShaders(gl::ProgramBinary *programBinary) = 0;
virtual void applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray) = 0;
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0;
- virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances) = 0;
+ virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
+ GLint first, GLsizei count, GLsizei instances) = 0;
virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) = 0;
virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances) = 0;
diff --git a/src/libGLESv2/renderer/Renderer11.cpp b/src/libGLESv2/renderer/Renderer11.cpp
index 00c1159..95b589d 100644
--- a/src/libGLESv2/renderer/Renderer11.cpp
+++ b/src/libGLESv2/renderer/Renderer11.cpp
@@ -1034,10 +1034,11 @@
return true;
}
-GLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances)
+GLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
+ GLint first, GLsizei count, GLsizei instances)
{
TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
- GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, programBinary, first, count, attributes, instances);
+ GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances);
if (err != GL_NO_ERROR)
{
return err;
diff --git a/src/libGLESv2/renderer/Renderer11.h b/src/libGLESv2/renderer/Renderer11.h
index 7ca1456..92a3eef 100644
--- a/src/libGLESv2/renderer/Renderer11.h
+++ b/src/libGLESv2/renderer/Renderer11.h
@@ -74,7 +74,8 @@
virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer);
virtual void applyShaders(gl::ProgramBinary *programBinary);
virtual void applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray);
- virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances);
+ virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
+ GLint first, GLsizei count, GLsizei instances);
virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances);
diff --git a/src/libGLESv2/renderer/Renderer9.cpp b/src/libGLESv2/renderer/Renderer9.cpp
index 6a54b47..5bb1cae 100644
--- a/src/libGLESv2/renderer/Renderer9.cpp
+++ b/src/libGLESv2/renderer/Renderer9.cpp
@@ -1338,10 +1338,11 @@
return true;
}
-GLenum Renderer9::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances)
+GLenum Renderer9::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
+ GLint first, GLsizei count, GLsizei instances)
{
TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
- GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, programBinary, first, count, attributes, instances);
+ GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances);
if (err != GL_NO_ERROR)
{
return err;
diff --git a/src/libGLESv2/renderer/Renderer9.h b/src/libGLESv2/renderer/Renderer9.h
index 47b8a4f..fe607ba 100644
--- a/src/libGLESv2/renderer/Renderer9.h
+++ b/src/libGLESv2/renderer/Renderer9.h
@@ -88,7 +88,8 @@
virtual void applyShaders(gl::ProgramBinary *programBinary);
virtual void applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray);
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount);
- virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances);
+ virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
+ GLint first, GLsizei count, GLsizei instances);
virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances);
diff --git a/src/libGLESv2/renderer/VertexBuffer.cpp b/src/libGLESv2/renderer/VertexBuffer.cpp
index 781f253..9c683b6 100644
--- a/src/libGLESv2/renderer/VertexBuffer.cpp
+++ b/src/libGLESv2/renderer/VertexBuffer.cpp
@@ -87,7 +87,8 @@
return mVertexBuffer->discard();
}
-int VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances)
+int VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue,
+ GLint start, GLsizei count, GLsizei instances)
{
if (!reserveSpace(mReservedSpace))
{
@@ -95,7 +96,7 @@
}
mReservedSpace = 0;
- if (!mVertexBuffer->storeVertexAttributes(attrib, start, count, instances, mWritePosition))
+ if (!mVertexBuffer->storeVertexAttributes(attrib, currentValue, start, count, instances, mWritePosition))
{
return -1;
}
@@ -194,13 +195,14 @@
}
}
-int StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances)
+int StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue,
+ GLint start, GLsizei count, GLsizei instances)
{
int attributeOffset = attrib.mOffset % attrib.stride();
VertexElement element = { attrib.mType, attrib.mSize, attrib.stride(), attrib.mNormalized, attrib.mPureInteger, attributeOffset, getWritePosition() };
mCache.push_back(element);
- return VertexBufferInterface::storeVertexAttributes(attrib, start, count, instances);
+ return VertexBufferInterface::storeVertexAttributes(attrib, currentValue, start, count, instances);
}
}
diff --git a/src/libGLESv2/renderer/VertexBuffer.h b/src/libGLESv2/renderer/VertexBuffer.h
index 50a0539..64a8264 100644
--- a/src/libGLESv2/renderer/VertexBuffer.h
+++ b/src/libGLESv2/renderer/VertexBuffer.h
@@ -15,6 +15,7 @@
namespace gl
{
class VertexAttribute;
+struct VertexAttribCurrentValueData;
}
namespace rx
@@ -29,12 +30,13 @@
virtual bool initialize(unsigned int size, bool dynamicUsage) = 0;
- virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count,
- GLsizei instances, unsigned int offset) = 0;
+ virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue,
+ GLint start, GLsizei count, GLsizei instances, unsigned int offset) = 0;
virtual unsigned int getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count,
GLsizei instances) const = 0;
virtual bool requiresConversion(const gl::VertexAttribute &attrib) const = 0;
+ virtual bool requiresConversion(const gl::VertexAttribCurrentValueData ¤tValue) const = 0;
virtual unsigned int getBufferSize() const = 0;
virtual bool setBufferSize(unsigned int size) = 0;
@@ -64,7 +66,8 @@
unsigned int getSerial() const;
- virtual int storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances);
+ virtual int storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue,
+ GLint start, GLsizei count, GLsizei instances);
VertexBuffer* getVertexBuffer() const;
@@ -106,7 +109,8 @@
explicit StaticVertexBufferInterface(rx::Renderer *renderer);
~StaticVertexBufferInterface();
- int storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances);
+ int storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue,
+ GLint start, GLsizei count, GLsizei instances);
// Returns the offset into the vertex buffer, or -1 if not found
int lookupAttribute(const gl::VertexAttribute &attribute);
diff --git a/src/libGLESv2/renderer/VertexBuffer11.cpp b/src/libGLESv2/renderer/VertexBuffer11.cpp
index ad70542..6e9d48b 100644
--- a/src/libGLESv2/renderer/VertexBuffer11.cpp
+++ b/src/libGLESv2/renderer/VertexBuffer11.cpp
@@ -14,6 +14,46 @@
#include "libGLESv2/renderer/Renderer11.h"
#include "libGLESv2/VertexAttribute.h"
+namespace
+{
+
+unsigned int GetIntegerTypeIndex(GLenum type)
+{
+ switch (type)
+ {
+ case GL_BYTE: return 0;
+ case GL_UNSIGNED_BYTE: return 1;
+ case GL_SHORT: return 2;
+ case GL_UNSIGNED_SHORT: return 3;
+ case GL_INT: return 4;
+ case GL_UNSIGNED_INT: return 5;
+ case GL_INT_2_10_10_10_REV: return 6;
+ case GL_UNSIGNED_INT_2_10_10_10_REV: return 7;
+ default: UNREACHABLE(); return 0;
+ }
+}
+
+unsigned int GetFloatTypeIndex(GLenum type)
+{
+ switch (type)
+ {
+ case GL_BYTE: return 0;
+ case GL_UNSIGNED_BYTE: return 1;
+ case GL_SHORT: return 2;
+ case GL_UNSIGNED_SHORT: return 3;
+ case GL_INT: return 4;
+ case GL_UNSIGNED_INT: return 5;
+ case GL_INT_2_10_10_10_REV: return 6;
+ case GL_UNSIGNED_INT_2_10_10_10_REV: return 7;
+ case GL_FIXED: return 8;
+ case GL_HALF_FLOAT: return 9;
+ case GL_FLOAT: return 10;
+ default: UNREACHABLE(); return 0;
+ }
+}
+
+}
+
namespace rx
{
@@ -73,15 +113,17 @@
return static_cast<VertexBuffer11*>(vetexBuffer);
}
-bool VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count,
- GLsizei instances, unsigned int offset)
+bool VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue,
+ GLint start, GLsizei count, GLsizei instances, unsigned int offset)
{
if (mBuffer)
{
gl::Buffer *buffer = attrib.mBoundBuffer.get();
int inputStride = attrib.stride();
- const VertexConverter &converter = getVertexConversion(attrib);
+ const VertexConverter &converter = attrib.mArrayEnabled ?
+ getVertexConversion(attrib) :
+ getVertexConversion(currentValue.Type, currentValue.Type != GL_FLOAT, false, 4);
ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
@@ -110,7 +152,7 @@
}
else
{
- input = reinterpret_cast<const char*>(attrib.mCurrentValue.FloatValues);
+ input = reinterpret_cast<const char*>(currentValue.FloatValues);
}
if (instances == 0 || attrib.mDivisor == 0)
@@ -135,10 +177,10 @@
unsigned int VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count,
GLsizei instances) const
{
- unsigned int elementSize = getVertexConversion(attrib).outputElementSize;
-
if (attrib.mArrayEnabled)
{
+ unsigned int elementSize = getVertexConversion(attrib).outputElementSize;
+
if (instances == 0 || attrib.mDivisor == 0)
{
return elementSize * count;
@@ -150,6 +192,7 @@
}
else
{
+ unsigned int elementSize = 4;
return elementSize * 4;
}
}
@@ -159,6 +202,11 @@
return !getVertexConversion(attrib).identity;
}
+bool VertexBuffer11::requiresConversion(const gl::VertexAttribCurrentValueData ¤tValue) const
+{
+ return !getVertexConversion(currentValue.Type, currentValue.Type != GL_FLOAT, false, 4).identity;
+}
+
unsigned int VertexBuffer11::getBufferSize() const
{
return mBufferSize;
@@ -201,16 +249,24 @@
}
}
-unsigned int VertexBuffer11::getVertexSize(const gl::VertexAttribute &attrib) const
-{
- return getVertexConversion(attrib).outputElementSize;
-}
-
-DXGI_FORMAT VertexBuffer11::getDXGIFormat(const gl::VertexAttribute &attrib) const
+DXGI_FORMAT VertexBuffer11::getAttributeDXGIFormat(const gl::VertexAttribute &attrib)
{
return getVertexConversion(attrib).dxgiFormat;
}
+DXGI_FORMAT VertexBuffer11::getCurrentValueDXGIFormat(GLenum currentValueType)
+{
+ if (currentValueType == GL_FLOAT)
+ {
+ return mFloatVertexTranslations[GetFloatTypeIndex(GL_FLOAT)][0][3].dxgiFormat;
+ }
+ else
+ {
+ ASSERT(currentValueType == GL_INT || currentValueType == GL_UNSIGNED_INT);
+ return mIntegerVertexTranslations[GetIntegerTypeIndex(currentValueType)][3].dxgiFormat;
+ }
+}
+
ID3D11Buffer *VertexBuffer11::getBuffer() const
{
return mBuffer;
@@ -722,45 +778,20 @@
const VertexBuffer11::VertexConverter &VertexBuffer11::getVertexConversion(const gl::VertexAttribute &attribute)
{
- GLenum type = attribute.mArrayEnabled ? attribute.mType : attribute.mCurrentValue.Type;
- if (attribute.mPureInteger)
- {
- unsigned int typeIndex = 0;
- switch (type)
- {
- case GL_BYTE: typeIndex = 0; break;
- case GL_UNSIGNED_BYTE: typeIndex = 1; break;
- case GL_SHORT: typeIndex = 2; break;
- case GL_UNSIGNED_SHORT: typeIndex = 3; break;
- case GL_INT: typeIndex = 4; break;
- case GL_UNSIGNED_INT: typeIndex = 5; break;
- case GL_INT_2_10_10_10_REV: typeIndex = 6; break;
- case GL_UNSIGNED_INT_2_10_10_10_REV: typeIndex = 7; break;
- default: UNREACHABLE(); break;
- }
+ return getVertexConversion(attribute.mType, attribute.mPureInteger, attribute.mNormalized, attribute.mSize);
+}
- return mIntegerVertexTranslations[typeIndex][attribute.mSize - 1];
+const VertexBuffer11::VertexConverter &VertexBuffer11::getVertexConversion(GLenum type, bool pureInteger, bool normalized, int size)
+{
+ if (pureInteger)
+ {
+ const unsigned int typeIndex = GetIntegerTypeIndex(type);
+ return mIntegerVertexTranslations[typeIndex][size - 1];
}
else
{
- unsigned int typeIndex = 0;
- switch (type)
- {
- case GL_BYTE: typeIndex = 0; break;
- case GL_UNSIGNED_BYTE: typeIndex = 1; break;
- case GL_SHORT: typeIndex = 2; break;
- case GL_UNSIGNED_SHORT: typeIndex = 3; break;
- case GL_INT: typeIndex = 4; break;
- case GL_UNSIGNED_INT: typeIndex = 5; break;
- case GL_INT_2_10_10_10_REV: typeIndex = 6; break;
- case GL_UNSIGNED_INT_2_10_10_10_REV: typeIndex = 7; break;
- case GL_FIXED: typeIndex = 8; break;
- case GL_HALF_FLOAT: typeIndex = 9; break;
- case GL_FLOAT: typeIndex = 10; break;
- default: UNREACHABLE(); break;
- }
-
- return mFloatVertexTranslations[typeIndex][attribute.mNormalized ? 1 : 0][attribute.mSize - 1];
+ const unsigned int typeIndex = GetFloatTypeIndex(type);
+ return mFloatVertexTranslations[typeIndex][normalized ? 1 : 0][size - 1];
}
}
diff --git a/src/libGLESv2/renderer/VertexBuffer11.h b/src/libGLESv2/renderer/VertexBuffer11.h
index a2be854..66f7f61 100644
--- a/src/libGLESv2/renderer/VertexBuffer11.h
+++ b/src/libGLESv2/renderer/VertexBuffer11.h
@@ -25,19 +25,20 @@
static VertexBuffer11 *makeVertexBuffer11(VertexBuffer *vetexBuffer);
- virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances,
- unsigned int offset);
+ virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue,
+ GLint start, GLsizei count, GLsizei instances, unsigned int offset);
virtual unsigned int getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances) const;
virtual bool requiresConversion(const gl::VertexAttribute &attrib) const;
+ virtual bool requiresConversion(const gl::VertexAttribCurrentValueData ¤tValue) const;
virtual unsigned int getBufferSize() const;
virtual bool setBufferSize(unsigned int size);
virtual bool discard();
- unsigned int getVertexSize(const gl::VertexAttribute &attrib) const;
- DXGI_FORMAT getDXGIFormat(const gl::VertexAttribute &attrib) const;
+ static DXGI_FORMAT getAttributeDXGIFormat(const gl::VertexAttribute &attrib);
+ static DXGI_FORMAT getCurrentValueDXGIFormat(GLenum currentValueType);
ID3D11Buffer *getBuffer() const;
@@ -66,6 +67,7 @@
static const VertexConverter mIntegerVertexTranslations[NUM_GL_INTEGER_VERTEX_ATTRIB_TYPES][4]; // [GL types as enumerated by typeIndex()][size - 1]
static const VertexConverter &getVertexConversion(const gl::VertexAttribute &attribute);
+ static const VertexConverter &getVertexConversion(GLenum type, bool pureInteger, bool normalized, int size);
};
}
diff --git a/src/libGLESv2/renderer/VertexBuffer9.cpp b/src/libGLESv2/renderer/VertexBuffer9.cpp
index 36826aa..f1b6c9c 100644
--- a/src/libGLESv2/renderer/VertexBuffer9.cpp
+++ b/src/libGLESv2/renderer/VertexBuffer9.cpp
@@ -81,8 +81,8 @@
return static_cast<VertexBuffer9*>(vertexBuffer);
}
-bool VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count,
- GLsizei instances, unsigned int offset)
+bool VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue,
+ GLint start, GLsizei count, GLsizei instances, unsigned int offset)
{
if (mVertexBuffer)
{
@@ -118,7 +118,7 @@
}
else
{
- input = reinterpret_cast<const char*>(attrib.mCurrentValue.FloatValues);
+ input = reinterpret_cast<const char*>(currentValue.FloatValues);
}
if (instances == 0 || attrib.mDivisor == 0)
@@ -156,9 +156,10 @@
return formatConverter(attrib).identity;
}
-unsigned int VertexBuffer9::getVertexSize(const gl::VertexAttribute &attrib) const
+bool VertexBuffer9::requiresConversion(const gl::VertexAttribCurrentValueData ¤tValue) const
{
- return spaceRequired(attrib, 1, 0);
+ ASSERT(currentValue.Type == GL_FLOAT);
+ return getCurrentValueFormatConverter().identity;
}
D3DDECLTYPE VertexBuffer9::getDeclType(const gl::VertexAttribute &attrib) const
@@ -445,11 +446,19 @@
const VertexBuffer9::FormatConverter &VertexBuffer9::formatConverter(const gl::VertexAttribute &attribute)
{
+ if (!attribute.mArrayEnabled)
+ {
+ return getCurrentValueFormatConverter();
+ }
+
// Pure integer attributes only supported in ES3.0
ASSERT(!attribute.mPureInteger);
+ return mFormatConverters[typeIndex(attribute.mType)][attribute.mNormalized][attribute.mSize - 1];
+}
- GLenum type = attribute.mArrayEnabled ? attribute.mType : attribute.mCurrentValue.Type;
- return mFormatConverters[typeIndex(type)][attribute.mNormalized][attribute.mSize - 1];
+const VertexBuffer9::FormatConverter &VertexBuffer9::getCurrentValueFormatConverter()
+{
+ return mFormatConverters[typeIndex(GL_FLOAT)][0][3];
}
unsigned int VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances)
diff --git a/src/libGLESv2/renderer/VertexBuffer9.h b/src/libGLESv2/renderer/VertexBuffer9.h
index 8950959..73708b4 100644
--- a/src/libGLESv2/renderer/VertexBuffer9.h
+++ b/src/libGLESv2/renderer/VertexBuffer9.h
@@ -25,14 +25,14 @@
static VertexBuffer9 *makeVertexBuffer9(VertexBuffer *vertexBuffer);
- virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances,
- unsigned int offset);
+ virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData ¤tValue,
+ GLint start, GLsizei count, GLsizei instances, unsigned int offset);
virtual unsigned int getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances) const;
virtual bool requiresConversion(const gl::VertexAttribute &attrib) const;
+ virtual bool requiresConversion(const gl::VertexAttribCurrentValueData ¤tValue) const;
- unsigned int getVertexSize(const gl::VertexAttribute &attrib) const;
D3DDECLTYPE getDeclType(const gl::VertexAttribute &attrib) const;
virtual unsigned int getBufferSize() const;
@@ -80,6 +80,7 @@
static unsigned int typeIndex(GLenum type);
static const FormatConverter &formatConverter(const gl::VertexAttribute &attribute);
+ static const FormatConverter &getCurrentValueFormatConverter();
static unsigned int spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances);
};
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];
}
diff --git a/src/libGLESv2/renderer/VertexDataManager.h b/src/libGLESv2/renderer/VertexDataManager.h
index 04c8ad3..b442c46 100644
--- a/src/libGLESv2/renderer/VertexDataManager.h
+++ b/src/libGLESv2/renderer/VertexDataManager.h
@@ -32,6 +32,7 @@
bool active;
const gl::VertexAttribute *attribute;
+ GLenum currentValueType;
UINT offset;
UINT stride; // 0 means not to advance the read pointer at all
@@ -47,7 +48,8 @@
VertexDataManager(rx::Renderer *renderer);
virtual ~VertexDataManager();
- GLenum prepareVertexData(const gl::VertexAttribute attribs[], gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *outAttribs, GLsizei instances);
+ GLenum prepareVertexData(const gl::VertexAttribute attribs[], const gl::VertexAttribCurrentValueData currentValues[],
+ gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *outAttribs, GLsizei instances);
private:
DISALLOW_COPY_AND_ASSIGN(VertexDataManager);
@@ -56,7 +58,7 @@
StreamingVertexBufferInterface *mStreamingBuffer;
- gl::VertexAttribute::CurrentValueData mCurrentValue[gl::MAX_VERTEX_ATTRIBS];
+ gl::VertexAttribCurrentValueData mCurrentValue[gl::MAX_VERTEX_ATTRIBS];
StreamingVertexBufferInterface *mCurrentValueBuffer[gl::MAX_VERTEX_ATTRIBS];
std::size_t mCurrentValueOffsets[gl::MAX_VERTEX_ATTRIBS];