New VertexAttribute data types
Added int and unsigned int as possible
internal storage types for VertexAttribute
on top of the existing float type by using
a union in order to be able to store the new
VertexAttribute types in their native types.
Change-Id: I5a98aeded065095df6b44fa20f4c293ae230bc37
Reviewed-on: https://swiftshader-review.googlesource.com/2828
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index 2ef8661..c610e59 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -746,6 +746,11 @@
mState.vertexAttribute[attribNum].mArrayEnabled = enabled;
}
+void Context::setVertexAttribDivisor(unsigned int attribNum, GLuint divisor)
+{
+ mState.vertexAttribute[attribNum].mDivisor = divisor;
+}
+
const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)
{
return mState.vertexAttribute[attribNum];
@@ -3408,14 +3413,29 @@
{
ASSERT(index < MAX_VERTEX_ATTRIBS);
- mState.vertexAttribute[index].mCurrentValue[0] = values[0];
- mState.vertexAttribute[index].mCurrentValue[1] = values[1];
- mState.vertexAttribute[index].mCurrentValue[2] = values[2];
- mState.vertexAttribute[index].mCurrentValue[3] = values[3];
+ mState.vertexAttribute[index].setCurrentValue(values);
mVertexDataManager->dirtyCurrentValue(index);
}
+void Context::setVertexAttrib(GLuint index, const GLint *values)
+{
+ ASSERT(index < MAX_VERTEX_ATTRIBS);
+
+ mState.vertexAttribute[index].setCurrentValue(values);
+
+ mVertexDataManager->dirtyCurrentValue(index);
+}
+
+void Context::setVertexAttrib(GLuint index, const GLuint *values)
+{
+ ASSERT(index < MAX_VERTEX_ATTRIBS);
+
+ mState.vertexAttribute[index].setCurrentValue(values);
+
+ mVertexDataManager->dirtyCurrentValue(index);
+}
+
void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask)
diff --git a/src/OpenGL/libGLESv2/Context.h b/src/OpenGL/libGLESv2/Context.h
index 2105cc4..aa7fccc 100644
--- a/src/OpenGL/libGLESv2/Context.h
+++ b/src/OpenGL/libGLESv2/Context.h
@@ -133,12 +133,13 @@
class VertexAttribute
{
public:
- VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mArrayEnabled(false)
+ VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mDivisor(0), mPointer(NULL), mArrayEnabled(false)
{
- mCurrentValue[0] = 0.0f;
- mCurrentValue[1] = 0.0f;
- mCurrentValue[2] = 0.0f;
- mCurrentValue[3] = 1.0f;
+ mCurrentValue[0].f = 0.0f;
+ mCurrentValue[1].f = 0.0f;
+ mCurrentValue[2].f = 0.0f;
+ mCurrentValue[3].f = 1.0f;
+ mCurrentValueType = ValueUnion::FloatType;
}
int typeSize() const
@@ -160,11 +161,72 @@
return mStride ? mStride : typeSize();
}
+ inline float getCurrentValue(int i) const
+ {
+ switch(mCurrentValueType)
+ {
+ case ValueUnion::FloatType: return mCurrentValue[i].f;
+ case ValueUnion::IntType: return static_cast<float>(mCurrentValue[i].i);
+ case ValueUnion::UIntType: return static_cast<float>(mCurrentValue[i].ui);
+ default: UNREACHABLE(); return mCurrentValue[i].f;
+ }
+ }
+
+ inline GLint getCurrentValueI(int i) const
+ {
+ switch(mCurrentValueType)
+ {
+ case ValueUnion::FloatType: return static_cast<GLint>(mCurrentValue[i].f);
+ case ValueUnion::IntType: return mCurrentValue[i].i;
+ case ValueUnion::UIntType: return static_cast<GLint>(mCurrentValue[i].ui);
+ default: UNREACHABLE(); return mCurrentValue[i].i;
+ }
+ }
+
+ inline GLuint getCurrentValueUI(int i) const
+ {
+ switch(mCurrentValueType)
+ {
+ case ValueUnion::FloatType: return static_cast<GLuint>(mCurrentValue[i].f);
+ case ValueUnion::IntType: return static_cast<GLuint>(mCurrentValue[i].i);
+ case ValueUnion::UIntType: return mCurrentValue[i].ui;
+ default: UNREACHABLE(); return mCurrentValue[i].ui;
+ }
+ }
+
+ inline void setCurrentValue(const GLfloat *values)
+ {
+ mCurrentValue[0].f = values[0];
+ mCurrentValue[1].f = values[1];
+ mCurrentValue[2].f = values[2];
+ mCurrentValue[3].f = values[3];
+ mCurrentValueType = ValueUnion::FloatType;
+ }
+
+ inline void setCurrentValue(const GLint *values)
+ {
+ mCurrentValue[0].i = values[0];
+ mCurrentValue[1].i = values[1];
+ mCurrentValue[2].i = values[2];
+ mCurrentValue[3].i = values[3];
+ mCurrentValueType = ValueUnion::IntType;
+ }
+
+ inline void setCurrentValue(const GLuint *values)
+ {
+ mCurrentValue[0].ui = values[0];
+ mCurrentValue[1].ui = values[1];
+ mCurrentValue[2].ui = values[2];
+ mCurrentValue[3].ui = values[3];
+ mCurrentValueType = ValueUnion::UIntType;
+ }
+
// From glVertexAttribPointer
GLenum mType;
GLint mSize;
bool mNormalized;
GLsizei mStride; // 0 means natural stride
+ GLuint mDivisor; // From glVertexAttribDivisor
union
{
@@ -175,7 +237,17 @@
gl::BindingPointer<Buffer> mBoundBuffer; // Captured when glVertexAttribPointer is called.
bool mArrayEnabled; // From glEnable/DisableVertexAttribArray
- float mCurrentValue[4]; // From glVertexAttrib
+private:
+ union ValueUnion
+ {
+ enum Type { FloatType, IntType, UIntType };
+
+ float f;
+ GLint i;
+ GLuint ui;
+ };
+ ValueUnion mCurrentValue[4]; // From glVertexAttrib
+ ValueUnion::Type mCurrentValueType;
};
typedef VertexAttribute VertexAttributeArray[MAX_VERTEX_ATTRIBS];
@@ -353,6 +425,7 @@
GLuint getArrayBufferName() const;
void setEnableVertexAttribArray(unsigned int attribNum, bool enabled);
+ void setVertexAttribDivisor(unsigned int attribNum, GLuint divisor);
const VertexAttribute &getVertexAttribState(unsigned int attribNum);
void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
bool normalized, GLsizei stride, const void *pointer);
@@ -426,6 +499,8 @@
void setRenderbufferStorage(RenderbufferStorage *renderbuffer);
void setVertexAttrib(GLuint index, const GLfloat *values);
+ void setVertexAttrib(GLuint index, const GLint *values);
+ void setVertexAttrib(GLuint index, const GLuint *values);
Buffer *getBuffer(GLuint handle);
Fence *getFence(GLuint handle);
diff --git a/src/OpenGL/libGLESv2/VertexDataManager.cpp b/src/OpenGL/libGLESv2/VertexDataManager.cpp
index 800ddfa..b6d7742 100644
--- a/src/OpenGL/libGLESv2/VertexDataManager.cpp
+++ b/src/OpenGL/libGLESv2/VertexDataManager.cpp
@@ -189,7 +189,7 @@
if(mDirtyCurrentValue[i])
{
delete mCurrentValueBuffer[i];
- mCurrentValueBuffer[i] = new ConstantVertexBuffer(attribs[i].mCurrentValue[0], attribs[i].mCurrentValue[1], attribs[i].mCurrentValue[2], attribs[i].mCurrentValue[3]);
+ mCurrentValueBuffer[i] = new ConstantVertexBuffer(attribs[i].getCurrentValue(0), attribs[i].getCurrentValue(1), attribs[i].getCurrentValue(2), attribs[i].getCurrentValue(3));
mDirtyCurrentValue[i] = false;
}
diff --git a/src/OpenGL/libGLESv2/libGLESv2.cpp b/src/OpenGL/libGLESv2/libGLESv2.cpp
index f5bed4f..21c1232 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv2.cpp
@@ -3655,7 +3655,7 @@
case GL_CURRENT_VERTEX_ATTRIB:
for(int i = 0; i < 4; ++i)
{
- params[i] = attribState.mCurrentValue[i];
+ params[i] = attribState.getCurrentValue(i);
}
break;
case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
@@ -3725,7 +3725,7 @@
case GL_CURRENT_VERTEX_ATTRIB:
for(int i = 0; i < 4; ++i)
{
- float currentValue = attribState.mCurrentValue[i];
+ float currentValue = attribState.getCurrentValue(i);
params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
}
break;
diff --git a/src/OpenGL/libGLESv2/libGLESv3.cpp b/src/OpenGL/libGLESv2/libGLESv3.cpp
index 0a4b2b6..e58a3ce 100644
--- a/src/OpenGL/libGLESv2/libGLESv3.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv3.cpp
@@ -1761,6 +1761,12 @@
case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
*params = attribState.mBoundBuffer.name();
break;
+ case GL_CURRENT_VERTEX_ATTRIB:
+ for(int i = 0; i < 4; ++i)
+ {
+ params[i] = attribState.getCurrentValueI(i);
+ }
+ break;
case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
switch(attribState.mType)
{
@@ -1779,6 +1785,9 @@
break;
}
break;
+ case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
+ *params = attribState.mDivisor;
+ break;
default: return error(GL_INVALID_ENUM);
}
}
@@ -1820,6 +1829,12 @@
case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
*params = attribState.mBoundBuffer.name();
break;
+ case GL_CURRENT_VERTEX_ATTRIB:
+ for(int i = 0; i < 4; ++i)
+ {
+ params[i] = attribState.getCurrentValueUI(i);
+ }
+ break;
case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
switch(attribState.mType)
{
@@ -1838,6 +1853,9 @@
break;
}
break;
+ case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
+ *params = attribState.mDivisor;
+ break;
default: return error(GL_INVALID_ENUM);
}
}
@@ -1847,26 +1865,72 @@
{
TRACE("(GLuint index = %d, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)",
index, x, y, z, w);
- UNIMPLEMENTED();
+
+ if(index >= es2::MAX_VERTEX_ATTRIBS)
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ es2::Context *context = es2::getContext();
+
+ if(context)
+ {
+ GLint vals[4] = { x, y, z, w };
+ context->setVertexAttrib(index, vals);
+ }
}
void GL_APIENTRY glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
{
TRACE("(GLuint index = %d, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)",
index, x, y, z, w);
- UNIMPLEMENTED();
+
+ if(index >= es2::MAX_VERTEX_ATTRIBS)
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ es2::Context *context = es2::getContext();
+
+ if(context)
+ {
+ GLuint vals[4] = { x, y, z, w };
+ context->setVertexAttrib(index, vals);
+ }
}
void GL_APIENTRY glVertexAttribI4iv(GLuint index, const GLint *v)
{
TRACE("(GLuint index = %d, GLint *v = 0x%0.8p)", index, v);
- UNIMPLEMENTED();
+
+ if(index >= es2::MAX_VERTEX_ATTRIBS)
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ es2::Context *context = es2::getContext();
+
+ if(context)
+ {
+ context->setVertexAttrib(index, v);
+ }
}
void GL_APIENTRY glVertexAttribI4uiv(GLuint index, const GLuint *v)
{
TRACE("(GLuint index = %d, GLint *v = 0x%0.8p)", index, v);
- UNIMPLEMENTED();
+
+ if(index >= es2::MAX_VERTEX_ATTRIBS)
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ es2::Context *context = es2::getContext();
+
+ if(context)
+ {
+ context->setVertexAttrib(index, v);
+ }
}
void GL_APIENTRY glGetUniformuiv(GLuint program, GLint location, GLuint *params)
@@ -3020,7 +3084,18 @@
void GL_APIENTRY glVertexAttribDivisor(GLuint index, GLuint divisor)
{
TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);
- UNIMPLEMENTED();
+
+ es2::Context *context = es2::getContext();
+
+ if(context)
+ {
+ if(index >= es2::MAX_VERTEX_ATTRIBS)
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ context->setVertexAttribDivisor(index, divisor);
+ }
}
void GL_APIENTRY glBindTransformFeedback(GLenum target, GLuint id)