Added methods to Context to get and set the current (non-indexed) bound uniform and transform feedback buffers.

TRAC #22811

Signed-off-by: Jamie Madill
Signed-off-by: Shannon Woods
Author: Geoff Lang

git-svn-id: https://angleproject.googlecode.com/svn/branches/es3proto@2129 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index b8c6710..dd03bab 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -151,6 +151,18 @@
     bindDrawFramebuffer(0);
     bindRenderbuffer(0);
 
+    bindGenericUniformBuffer(0);
+    for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
+    {
+        bindIndexedUniformBuffer(0, i, 0, -1);
+    }
+
+    bindGenericTransformFeedbackBuffer(0);
+    for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
+    {
+        bindIndexedTransformFeedbackBuffer(0, i, 0, -1);
+    }
+
     mState.currentProgram = 0;
     mCurrentProgramBinary.set(NULL);
 
@@ -240,11 +252,13 @@
     mTexture2DZero.set(NULL);
     mTextureCubeMapZero.set(NULL);
 
+    mState.genericUniformBuffer.set(NULL);
     for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
     {
         mState.uniformBuffers[i].set(NULL);
     }
 
+    mState.genericTransformFeedbackBuffer.set(NULL);
     for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
     {
         mState.transformFeedbackBuffers[i].set(NULL);
@@ -926,14 +940,28 @@
     mState.renderbuffer.set(getRenderbuffer(renderbuffer));
 }
 
-void Context::bindUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
+void Context::bindGenericUniformBuffer(GLuint buffer)
+{
+    mResourceManager->checkBufferAllocation(buffer);
+
+    mState.genericUniformBuffer.set(getBuffer(buffer));
+}
+
+void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
 {
     mResourceManager->checkBufferAllocation(buffer);
 
     mState.uniformBuffers[index].set(getBuffer(buffer), offset, size);
 }
 
-void Context::bindTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
+void Context::bindGenericTransformFeedbackBuffer(GLuint buffer)
+{
+    mResourceManager->checkBufferAllocation(buffer);
+
+    mState.genericTransformFeedbackBuffer.set(getBuffer(buffer));
+}
+
+void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
 {
     mResourceManager->checkBufferAllocation(buffer);
 
@@ -1193,6 +1221,16 @@
     return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
 }
 
+Buffer *Context::getGenericUniformBuffer()
+{
+    return mState.genericUniformBuffer.get();
+}
+
+Buffer *Context::getGenericTransformFeedbackBuffer()
+{
+    return mState.genericTransformFeedbackBuffer.get();
+}
+
 Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)
 {
     GLuint texid = mState.samplerTexture[type][sampler].id();
@@ -1547,6 +1585,12 @@
       case GL_PROGRAM_BINARY_FORMATS_OES:
         *params = GL_PROGRAM_BINARY_ANGLE;
         break;
+      case GL_UNIFORM_BUFFER_BINDING:
+        *params = mState.genericUniformBuffer.id();
+        break;
+      case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
+        *params = mState.genericTransformFeedbackBuffer.id();
+        break;
       default:
         return false;
     }
@@ -1577,13 +1621,13 @@
             *type = GL_INT;
             *numParams = mNumCompressedTextureFormats;
         }
-        break;
+        return true;
       case GL_SHADER_BINARY_FORMATS:
         {
             *type = GL_INT;
             *numParams = 0;
         }
-        break;
+        return true;
       case GL_MAX_VERTEX_ATTRIBS:
       case GL_MAX_VERTEX_UNIFORM_VECTORS:
       case GL_MAX_VARYING_VECTORS:
@@ -1653,7 +1697,7 @@
             *type = GL_INT;
             *numParams = 1;
         }
-        break;
+        return true;
       case GL_MAX_SAMPLES_ANGLE:
         {
             if (getMaxSupportedSamples() != 0)
@@ -1666,20 +1710,20 @@
                 return false;
             }
         }
-        break;
+        return true;
       case GL_MAX_VIEWPORT_DIMS:
         {
             *type = GL_INT;
             *numParams = 2;
         }
-        break;
+        return true;
       case GL_VIEWPORT:
       case GL_SCISSOR_BOX:
         {
             *type = GL_INT;
             *numParams = 4;
         }
-        break;
+        return true;
       case GL_SHADER_COMPILER:
       case GL_SAMPLE_COVERAGE_INVERT:
       case GL_DEPTH_WRITEMASK:
@@ -1697,13 +1741,13 @@
             *type = GL_BOOL;
             *numParams = 1;
         }
-        break;
+        return true;
       case GL_COLOR_WRITEMASK:
         {
             *type = GL_BOOL;
             *numParams = 4;
         }
-        break;
+        return true;
       case GL_POLYGON_OFFSET_FACTOR:
       case GL_POLYGON_OFFSET_UNITS:
       case GL_SAMPLE_COVERAGE_VALUE:
@@ -1713,7 +1757,7 @@
             *type = GL_FLOAT;
             *numParams = 1;
         }
-        break;
+        return true;
       case GL_ALIASED_LINE_WIDTH_RANGE:
       case GL_ALIASED_POINT_SIZE_RANGE:
       case GL_DEPTH_RANGE:
@@ -1721,14 +1765,14 @@
             *type = GL_FLOAT;
             *numParams = 2;
         }
-        break;
+        return true;
       case GL_COLOR_CLEAR_VALUE:
       case GL_BLEND_COLOR:
         {
             *type = GL_FLOAT;
             *numParams = 4;
         }
-        break;
+        return true;
       case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
         if (!supportsTextureFilterAnisotropy())
         {
@@ -1736,12 +1780,27 @@
         }
         *type = GL_FLOAT;
         *numParams = 1;
-        break;
-      default:
+        return true;
+    }
+
+    if (mClientVersion < 3)
+    {
         return false;
     }
 
-    return true;
+    // Check for ES3.0+ parameter names
+    switch (pname)
+    {
+      case GL_UNIFORM_BUFFER_BINDING:
+      case GL_TRANSFORM_FEEDBACK_BINDING:
+        {
+            *type = GL_INT;
+            *numParams = 1;
+        }
+        return true;
+    }
+
+    return false;
 }
 
 // Applies the render target surface, depth stencil surface, viewport rectangle and
diff --git a/src/libGLESv2/Context.h b/src/libGLESv2/Context.h
index c25ce7e..88ddd41 100644
--- a/src/libGLESv2/Context.h
+++ b/src/libGLESv2/Context.h
@@ -183,8 +183,10 @@
     BindingPointer<Texture> samplerTexture[TEXTURE_TYPE_COUNT][IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS];
     BindingPointer<Query> activeQuery[QUERY_TYPE_COUNT];
 
+    BindingPointer<Buffer> genericUniformBuffer;
     OffsetBindingPointer<Buffer> uniformBuffers[IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS];
 
+    BindingPointer<Buffer> genericTransformFeedbackBuffer;
     OffsetBindingPointer<Buffer> transformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
 
     GLint unpackAlignment;
@@ -331,8 +333,10 @@
     void bindReadFramebuffer(GLuint framebuffer);
     void bindDrawFramebuffer(GLuint framebuffer);
     void bindRenderbuffer(GLuint renderbuffer);
-    void bindUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size);
-    void bindTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size);
+    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);
     void useProgram(GLuint program);
     void linkProgram(GLuint program);
     void setProgramBinary(GLuint program, const void *binary, GLint length);
@@ -363,6 +367,8 @@
     ProgramBinary *getCurrentProgramBinary();
     Texture2D *getTexture2D();
     TextureCubeMap *getTextureCubeMap();
+    Buffer *getGenericUniformBuffer();
+    Buffer *getGenericTransformFeedbackBuffer();
     Texture *getSamplerTexture(unsigned int sampler, TextureType type);
     Framebuffer *getReadFramebuffer();
     Framebuffer *getDrawFramebuffer();
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index 8eb8e91..1baba69 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -417,6 +417,17 @@
 
         if (context)
         {
+            // Check ES3 specific targets
+            switch (target)
+            {
+              case GL_UNIFORM_BUFFER:
+              case GL_TRANSFORM_FEEDBACK_BUFFER:
+                if (context->getClientVersion() < 3)
+                {
+                    return gl::error(GL_INVALID_ENUM);
+                }
+            }
+
             switch (target)
             {
               case GL_ARRAY_BUFFER:
@@ -425,6 +436,12 @@
               case GL_ELEMENT_ARRAY_BUFFER:
                 context->bindElementArrayBuffer(buffer);
                 return;
+              case GL_UNIFORM_BUFFER:
+                context->bindGenericUniformBuffer(buffer);
+                return;
+              case GL_TRANSFORM_FEEDBACK_BUFFER:
+                context->bindGenericUniformBuffer(buffer);
+                return;
               default:
                 return gl::error(GL_INVALID_ENUM);
             }
@@ -772,6 +789,17 @@
 
         if (context)
         {
+            // Check ES3 specific targets
+            switch (target)
+            {
+              case GL_UNIFORM_BUFFER:
+              case GL_TRANSFORM_FEEDBACK_BUFFER:
+                if (context->getClientVersion() < 3)
+                {
+                    return gl::error(GL_INVALID_ENUM);
+                }
+            }
+
             gl::Buffer *buffer;
 
             switch (target)
@@ -782,6 +810,12 @@
               case GL_ELEMENT_ARRAY_BUFFER:
                 buffer = context->getElementArrayBuffer();
                 break;
+              case GL_TRANSFORM_FEEDBACK_BUFFER:
+                buffer = context->getGenericTransformFeedbackBuffer();
+                break;
+              case GL_UNIFORM_BUFFER:
+                buffer = context->getGenericUniformBuffer();
+                break;
               default:
                 return gl::error(GL_INVALID_ENUM);
             }
@@ -821,6 +855,17 @@
 
         if (context)
         {
+            // Check ES3 specific targets
+            switch (target)
+            {
+              case GL_UNIFORM_BUFFER:
+              case GL_TRANSFORM_FEEDBACK_BUFFER:
+                if (context->getClientVersion() < 3)
+                {
+                    return gl::error(GL_INVALID_ENUM);
+                }
+            }
+
             gl::Buffer *buffer;
 
             switch (target)
@@ -831,6 +876,12 @@
               case GL_ELEMENT_ARRAY_BUFFER:
                 buffer = context->getElementArrayBuffer();
                 break;
+              case GL_TRANSFORM_FEEDBACK_BUFFER:
+                buffer = context->getGenericTransformFeedbackBuffer();
+                break;
+              case GL_UNIFORM_BUFFER:
+                buffer = context->getGenericUniformBuffer();
+                break;
               default:
                 return gl::error(GL_INVALID_ENUM);
             }
@@ -7804,11 +7855,13 @@
             switch (target)
             {
               case GL_TRANSFORM_FEEDBACK_BUFFER:
-                context->bindTransformFeedbackBuffer(buffer, index, offset, size);
+                context->bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
+                context->bindGenericTransformFeedbackBuffer(buffer);
                 break;
 
               case GL_UNIFORM_BUFFER:
-                context->bindUniformBuffer(buffer, index, offset, size);
+                context->bindIndexedUniformBuffer(buffer, index, offset, size);
+                context->bindGenericUniformBuffer(buffer);
                 break;
 
               default:
@@ -7868,11 +7921,13 @@
             switch (target)
             {
               case GL_TRANSFORM_FEEDBACK_BUFFER:
-                context->bindTransformFeedbackBuffer(buffer, index, 0, -1);
+                context->bindIndexedTransformFeedbackBuffer(buffer, index, 0, -1);
+                context->bindGenericTransformFeedbackBuffer(buffer);
                 break;
 
               case GL_UNIFORM_BUFFER:
-                context->bindUniformBuffer(buffer, index, 0, -1);
+                context->bindIndexedUniformBuffer(buffer, index, 0, -1);
+                context->bindGenericUniformBuffer(buffer);
                 break;
 
               default: