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)