Uniform Buffers API implementation
Implemented the necessary functions
for the API level implementation of
glBindBufferBase and glBindBufferRange.
Also cleaned up the TransformFeedback
API functions a little for uniformity
with uniform buffers.
Change-Id: Iccc835f175d4e8bc4ee030343936714b7ff224ac
Reviewed-on: https://swiftshader-review.googlesource.com/3030
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/OpenGL/libGLESv2/Buffer.cpp b/src/OpenGL/libGLESv2/Buffer.cpp
index 42a1eea..0c164fa 100644
--- a/src/OpenGL/libGLESv2/Buffer.cpp
+++ b/src/OpenGL/libGLESv2/Buffer.cpp
@@ -64,7 +64,8 @@
if(data)
{
- memcpy((void*)mContents->data(), data, size);
+ char *buffer = (char*)mContents->data();
+ memcpy(buffer + mOffset, data, size);
}
}
}
diff --git a/src/OpenGL/libGLESv2/Buffer.h b/src/OpenGL/libGLESv2/Buffer.h
index b9acf8e..1f509ec 100644
--- a/src/OpenGL/libGLESv2/Buffer.h
+++ b/src/OpenGL/libGLESv2/Buffer.h
@@ -36,7 +36,7 @@
void bufferData(const void *data, GLsizeiptr size, GLenum usage);
void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
- const void *data() { return mContents ? mContents->data() : 0; }
+ const void *data() const { return mContents ? mContents->data() : 0; }
size_t size() const { return mSize; }
GLenum usage() const { return mUsage; }
bool isMapped() const { return mIsMapped; }
@@ -44,6 +44,8 @@
GLsizeiptr length() const { return mLength; }
GLbitfield access() const { return mAccess; }
+ void setOffset(GLintptr offset) { mOffset = offset; }
+ void setSize(size_t size) { mSize = size; }
void* mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access);
bool unmap();
void flushMappedRange(GLintptr offset, GLsizeiptr length) {}
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index 07543be..121e956 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -151,6 +151,7 @@
bindReadFramebuffer(0);
bindDrawFramebuffer(0);
bindRenderbuffer(0);
+ bindGenericUniformBuffer(0);
bindTransformFeedback(0);
mState.readFramebufferColorIndex = 0;
@@ -246,7 +247,7 @@
mState.copyWriteBuffer = NULL;
mState.pixelPackBuffer = NULL;
mState.pixelUnpackBuffer = NULL;
- mState.uniformBuffer = NULL;
+ mState.genericUniformBuffer = NULL;
mState.renderbuffer = NULL;
for(int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++i)
@@ -1196,13 +1197,6 @@
}
}
-void Context::bindUniformBuffer(GLuint buffer)
-{
- mResourceManager->checkBufferAllocation(buffer);
-
- mState.uniformBuffer = getBuffer(buffer);
-}
-
void Context::bindTexture2D(GLuint texture)
{
mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
@@ -1278,6 +1272,46 @@
return !!vertexArray;
}
+void Context::bindGenericUniformBuffer(GLuint buffer)
+{
+ mResourceManager->checkBufferAllocation(buffer);
+
+ mState.genericUniformBuffer = getBuffer(buffer);
+}
+
+void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
+{
+ mResourceManager->checkBufferAllocation(buffer);
+
+ Buffer* bufferObject = getBuffer(buffer);
+ if(bufferObject)
+ {
+ bufferObject->setOffset(offset);
+ bufferObject->setSize(size);
+ }
+ mState.uniformBuffers[index] = bufferObject;
+}
+
+void Context::bindGenericTransformFeedbackBuffer(GLuint buffer)
+{
+ mResourceManager->checkBufferAllocation(buffer);
+
+ getTransformFeedback()->setGenericBuffer(getBuffer(buffer));
+}
+
+void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
+{
+ mResourceManager->checkBufferAllocation(buffer);
+
+ Buffer* bufferObject = getBuffer(buffer);
+ if(bufferObject)
+ {
+ bufferObject->setOffset(offset);
+ bufferObject->setSize(size);
+ }
+ getTransformFeedback()->setBuffer(index, bufferObject);
+}
+
bool Context::bindTransformFeedback(GLuint id)
{
if(!getTransformFeedback(id))
@@ -1566,9 +1600,9 @@
return mState.pixelUnpackBuffer;
}
-Buffer *Context::getUniformBuffer() const
+Buffer *Context::getGenericUniformBuffer() const
{
- return mState.uniformBuffer;
+ return mState.genericUniformBuffer;
}
bool Context::getBuffer(GLenum target, es2::Buffer **buffer) const
@@ -1620,7 +1654,7 @@
case GL_UNIFORM_BUFFER:
if(clientVersion >= 3)
{
- *buffer = getUniformBuffer();
+ *buffer = getGenericUniformBuffer();
break;
}
else return false;
@@ -2137,7 +2171,6 @@
*params = 16384;
break;
case GL_MAX_UNIFORM_BUFFER_BINDINGS: // integer, at least 36
- UNIMPLEMENTED();
*params = IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS;
break;
case GL_MAX_VARYING_COMPONENTS: // integer, at least 60
@@ -2217,7 +2250,7 @@
case GL_UNIFORM_BUFFER_BINDING: // name, initially 0
if(clientVersion >= 3)
{
- *params = mState.uniformBuffer.name();
+ *params = mState.genericUniformBuffer.name();
}
else
{
@@ -2225,15 +2258,27 @@
}
break;
case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: // integer, defaults to 1
- UNIMPLEMENTED();
*params = IMPLEMENTATION_UNIFORM_BUFFER_OFFSET_ALIGNMENT;
break;
case GL_UNIFORM_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0
- UNIMPLEMENTED();
- *params = 0;
+ if(clientVersion >= 3)
+ {
+ *params = mState.genericUniformBuffer->size();
+ }
+ else
+ {
+ return false;
+ }
break;
case GL_UNIFORM_BUFFER_START: // indexed[n] 64-bit integer, initially 0
- UNIMPLEMENTED();
+ if(clientVersion >= 3)
+ {
+ *params = mState.genericUniformBuffer->offset();
+ }
+ else
+ {
+ return false;
+ }
*params = 0;
break;
case GL_UNPACK_IMAGE_HEIGHT: // integer, initially 0
diff --git a/src/OpenGL/libGLESv2/Context.h b/src/OpenGL/libGLESv2/Context.h
index 61d7f29..6ad4289 100644
--- a/src/OpenGL/libGLESv2/Context.h
+++ b/src/OpenGL/libGLESv2/Context.h
@@ -336,7 +336,8 @@
gl::BindingPointer<Buffer> copyWriteBuffer;
gl::BindingPointer<Buffer> pixelPackBuffer;
gl::BindingPointer<Buffer> pixelUnpackBuffer;
- gl::BindingPointer<Buffer> uniformBuffer;
+ gl::BindingPointer<Buffer> genericUniformBuffer;
+ gl::BindingPointer<Buffer> uniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS];
GLuint readFramebuffer;
GLuint drawFramebuffer;
@@ -517,7 +518,6 @@
void bindPixelPackBuffer(GLuint buffer);
void bindPixelUnpackBuffer(GLuint buffer);
void bindTransformFeedbackBuffer(GLuint buffer);
- void bindUniformBuffer(GLuint buffer);
void bindTexture2D(GLuint texture);
void bindTextureCubeMap(GLuint texture);
void bindTextureExternal(GLuint texture);
@@ -527,6 +527,10 @@
void bindDrawFramebuffer(GLuint framebuffer);
void bindRenderbuffer(GLuint renderbuffer);
bool bindVertexArray(GLuint array);
+ void bindGenericUniformBuffer(GLuint buffer);
+ void bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size);
+ void bindGenericTransformFeedbackBuffer(GLuint buffer);
+ void bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size);
bool bindTransformFeedback(GLuint transformFeedback);
bool bindSampler(GLuint unit, GLuint sampler);
void useProgram(GLuint program);
@@ -563,7 +567,7 @@
Buffer *getCopyWriteBuffer() const;
Buffer *getPixelPackBuffer() const;
Buffer *getPixelUnpackBuffer() const;
- Buffer *getUniformBuffer() const;
+ Buffer *getGenericUniformBuffer() const;
bool getBuffer(GLenum target, es2::Buffer **buffer) const;
Program *getCurrentProgram() const;
Texture2D *getTexture2D() const;
diff --git a/src/OpenGL/libGLESv2/libGLESv2.cpp b/src/OpenGL/libGLESv2/libGLESv2.cpp
index c6c7ef8..6507d9d 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv2.cpp
@@ -469,7 +469,7 @@
case GL_UNIFORM_BUFFER:
if(clientVersion >= 3)
{
- context->bindUniformBuffer(buffer);
+ context->bindGenericUniformBuffer(buffer);
return;
}
else return error(GL_INVALID_ENUM);
diff --git a/src/OpenGL/libGLESv2/libGLESv3.cpp b/src/OpenGL/libGLESv2/libGLESv3.cpp
index 0c78ced..5832bef 100644
--- a/src/OpenGL/libGLESv2/libGLESv3.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv3.cpp
@@ -1886,11 +1886,8 @@
{
return error(GL_INVALID_VALUE);
}
- else
- {
- es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
- transformFeedback->setBuffer(index, context->getBuffer(buffer), offset, size);
- }
+ context->bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
+ context->bindGenericTransformFeedbackBuffer(buffer);
break;
case GL_UNIFORM_BUFFER:
if(index >= es2::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS)
@@ -1901,7 +1898,8 @@
{
return error(GL_INVALID_VALUE);
}
- UNIMPLEMENTED();
+ context->bindIndexedUniformBuffer(buffer, index, offset, size);
+ context->bindGenericUniformBuffer(buffer);
break;
default:
return error(GL_INVALID_ENUM);
@@ -1925,18 +1923,16 @@
{
return error(GL_INVALID_VALUE);
}
- else
- {
- es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
- transformFeedback->setBuffer(index, context->getBuffer(buffer));
- }
+ context->bindIndexedTransformFeedbackBuffer(buffer, index, 0, 0);
+ context->bindGenericTransformFeedbackBuffer(buffer);
break;
case GL_UNIFORM_BUFFER:
if(index >= es2::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS)
{
return error(GL_INVALID_VALUE);
}
- UNIMPLEMENTED();
+ context->bindIndexedUniformBuffer(buffer, index, 0, 0);
+ context->bindGenericUniformBuffer(buffer);
break;
default:
return error(GL_INVALID_ENUM);
@@ -3227,7 +3223,7 @@
UNIMPLEMENTED();
break;
case GL_UNIFORM_BUFFER:
- buffer = context->getUniformBuffer();
+ buffer = context->getGenericUniformBuffer();
break;
default:
return error(GL_INVALID_ENUM);