Translate/lift vertex attributes when input stride or offset is not a multiple of 4.
TRAC #11847
Signed-off-by: Nicolas Capens
Signed-off-by: Daniel Koch
Author: Andrew Lewycky
git-svn-id: https://angleproject.googlecode.com/svn/trunk@149 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/geometry/VertexDataManager.cpp b/src/libGLESv2/geometry/VertexDataManager.cpp
index 54e894c..a8766ce 100644
--- a/src/libGLESv2/geometry/VertexDataManager.cpp
+++ b/src/libGLESv2/geometry/VertexDataManager.cpp
@@ -128,12 +128,22 @@
{
if (attribs[i].mBoundBuffer != 0 && mBackend->getFormatConverter(attribs[i].mType, attribs[i].mSize, attribs[i].mNormalized).identity)
{
- translated[i].type = attribs[i].mType;
- translated[i].size = attribs[i].mSize;
- translated[i].normalized = attribs[i].mNormalized;
- translated[i].stride = interpretGlStride(attribs[i]);
- translated[i].offset = static_cast<std::size_t>(static_cast<const char*>(attribs[i].mPointer) - static_cast<const char*>(NULL)) + translated[i].stride * minIndex;
- translated[i].buffer = mContext->getBuffer(attribs[i].mBoundBuffer)->identityBuffer();
+ std::size_t stride = interpretGlStride(attribs[i]);
+ std::size_t offset = static_cast<std::size_t>(static_cast<const char*>(attribs[i].mPointer) - static_cast<const char*>(NULL)) + translated[i].stride * minIndex;
+
+ if (mBackend->validateStream(attribs[i].mType, attribs[i].mSize, stride, offset))
+ {
+ translated[i].type = attribs[i].mType;
+ translated[i].size = attribs[i].mSize;
+ translated[i].normalized = attribs[i].mNormalized;
+ translated[i].stride = stride;
+ translated[i].offset = offset;
+ translated[i].buffer = mContext->getBuffer(attribs[i].mBoundBuffer)->identityBuffer();
+ }
+ else
+ {
+ translateOrLift[i] = true;
+ }
}
else
{
diff --git a/src/libGLESv2/geometry/backend.h b/src/libGLESv2/geometry/backend.h
index 8c3cd04..16afbdc 100644
--- a/src/libGLESv2/geometry/backend.h
+++ b/src/libGLESv2/geometry/backend.h
@@ -57,6 +57,9 @@
virtual TranslatedIndexBuffer *createIndexBuffer(std::size_t size) = 0;
virtual FormatConverter getFormatConverter(GLenum type, std::size_t size, bool normalize) = 0;
+ // For an identity-mappable stream, verify that the stride and offset are okay.
+ virtual bool validateStream(GLenum type, std::size_t size, std::size_t stride, std::size_t offset) const = 0;
+
virtual GLenum setupIndicesPreDraw(const TranslatedIndexData &indexInfo) = 0;
virtual GLenum setupAttributesPreDraw(const TranslatedAttribute *attributes) = 0;
};
diff --git a/src/libGLESv2/geometry/dx9.cpp b/src/libGLESv2/geometry/dx9.cpp
index c6681e9..0e90a7d 100644
--- a/src/libGLESv2/geometry/dx9.cpp
+++ b/src/libGLESv2/geometry/dx9.cpp
@@ -170,6 +170,12 @@
}
}
+bool Dx9BackEnd::validateStream(GLenum type, std::size_t size, std::size_t stride, std::size_t offset) const
+{
+ // D3D9 requires the stream offset and stride to be a multiple of DWORD.
+ return (stride % sizeof(DWORD) == 0 && offset % sizeof(DWORD) == 0);
+}
+
IDirect3DVertexBuffer9 *Dx9BackEnd::getDxBuffer(TranslatedVertexBuffer *vb) const
{
return vb ? static_cast<Dx9VertexBuffer*>(vb)->getBuffer() : NULL;
diff --git a/src/libGLESv2/geometry/dx9.h b/src/libGLESv2/geometry/dx9.h
index 3e49672..27afd68 100644
--- a/src/libGLESv2/geometry/dx9.h
+++ b/src/libGLESv2/geometry/dx9.h
@@ -27,6 +27,8 @@
virtual TranslatedIndexBuffer *createIndexBuffer(std::size_t size);
virtual FormatConverter getFormatConverter(GLenum type, std::size_t size, bool normalize);
+ virtual bool validateStream(GLenum type, std::size_t size, std::size_t stride, std::size_t offset) const;
+
virtual GLenum setupIndicesPreDraw(const TranslatedIndexData &indexInfo);
virtual GLenum setupAttributesPreDraw(const TranslatedAttribute *attributes);