[Mesa-dev] [PATCH 03/13] mesa: implement glBufferStorage, immutable buffers; add extension enable flag

Marek Olšák maraeo at gmail.com
Wed Jan 29 17:20:45 PST 2014


From: Marek Olšák <marek.olsak at amd.com>

---
 src/mesa/main/bufferobj.c  | 98 ++++++++++++++++++++++++++++++++++++++++++++++
 src/mesa/main/bufferobj.h  |  4 ++
 src/mesa/main/extensions.c |  1 +
 src/mesa/main/mtypes.h     |  2 +
 4 files changed, 105 insertions(+)

diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index d9fb812..55184f1 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -1232,6 +1232,73 @@ _mesa_IsBuffer(GLuint id)
 
 
 void GLAPIENTRY
+_mesa_BufferStorage(GLenum target, GLsizeiptr size, const GLvoid *data,
+                    GLbitfield flags)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_buffer_object *bufObj;
+
+   if (size < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glBufferStorage(size < 0)");
+      return;
+   }
+
+   if (flags & ~(GL_MAP_READ_BIT |
+                 GL_MAP_WRITE_BIT |
+                 GL_MAP_PERSISTENT_BIT |
+                 GL_MAP_COHERENT_BIT |
+                 GL_DYNAMIC_STORAGE_BIT |
+                 GL_CLIENT_STORAGE_BIT)) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glBufferStorage(flags)");
+      return;
+   }
+
+   if (flags & GL_MAP_PERSISTENT_BIT &&
+       !(flags & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT))) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glBufferStorage(flags!=READ/WRITE)");
+      return;
+   }
+
+   if (flags & GL_MAP_COHERENT_BIT && !(flags & GL_MAP_PERSISTENT_BIT)) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glBufferStorage(flags!=PERSISTENT)");
+      return;
+   }
+
+   if (flags & GL_MAP_WRITE_BIT && !(flags & GL_DYNAMIC_STORAGE_BIT)) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glBufferStorage(flags!=DYNAMIC)");
+      return;
+   }
+
+   bufObj = get_buffer(ctx, "glBufferStorage", target, GL_INVALID_OPERATION);
+   if (!bufObj)
+      return;
+
+   if (bufObj->Immutable) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glBufferStorage(immutable)");
+      return;
+   }
+
+   if (_mesa_bufferobj_mapped(bufObj)) {
+      /* Unmap the existing buffer.  We'll replace it now.  Not an error. */
+      ctx->Driver.UnmapBuffer(ctx, bufObj);
+      bufObj->AccessFlags = 0;
+      ASSERT(bufObj->Pointer == NULL);
+   }
+
+   FLUSH_VERTICES(ctx, _NEW_BUFFER_OBJECT);
+
+   bufObj->Written = GL_TRUE;
+   bufObj->Immutable = GL_TRUE;
+
+   ASSERT(ctx->Driver.BufferData);
+   if (!ctx->Driver.BufferData(ctx, target, size, data, GL_DYNAMIC_DRAW,
+                               flags, bufObj)) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferStorage()");
+   }
+}
+
+
+void GLAPIENTRY
 _mesa_BufferData(GLenum target, GLsizeiptrARB size,
                     const GLvoid * data, GLenum usage)
 {
@@ -1283,6 +1350,11 @@ _mesa_BufferData(GLenum target, GLsizeiptrARB size,
    if (!bufObj)
       return;
 
+   if (bufObj->Immutable) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glBufferData(immutable");
+      return;
+   }
+
    if (_mesa_bufferobj_mapped(bufObj)) {
       /* Unmap the existing buffer.  We'll replace it now.  Not an error. */
       ctx->Driver.UnmapBuffer(ctx, bufObj);
@@ -1329,6 +1401,12 @@ _mesa_BufferSubData(GLenum target, GLintptrARB offset,
       return;
    }
 
+   if (bufObj->Immutable &&
+       !(bufObj->StorageFlags & GL_DYNAMIC_STORAGE_BIT)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glBufferSubData");
+      return;
+   }
+
    if (size == 0)
       return;
 
@@ -1661,6 +1739,16 @@ _mesa_GetBufferParameteriv(GLenum target, GLenum pname, GLint *params)
          goto invalid_pname;
       *params = (GLint) bufObj->Length;
       return;
+   case GL_BUFFER_IMMUTABLE_STORAGE:
+      if (!ctx->Extensions.ARB_buffer_storage)
+         goto invalid_pname;
+      *params = bufObj->Immutable;
+      return;
+   case GL_BUFFER_STORAGE_FLAGS:
+      if (!ctx->Extensions.ARB_buffer_storage)
+         goto invalid_pname;
+      *params = bufObj->StorageFlags;
+      return;
    default:
       ; /* fall-through */
    }
@@ -1715,6 +1803,16 @@ _mesa_GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
          goto invalid_pname;
       *params = bufObj->Length;
       return;
+   case GL_BUFFER_IMMUTABLE_STORAGE:
+      if (!ctx->Extensions.ARB_buffer_storage)
+         goto invalid_pname;
+      *params = bufObj->Immutable;
+      return;
+   case GL_BUFFER_STORAGE_FLAGS:
+      if (!ctx->Extensions.ARB_buffer_storage)
+         goto invalid_pname;
+      *params = bufObj->StorageFlags;
+      return;
    default:
       ; /* fall-through */
    }
diff --git a/src/mesa/main/bufferobj.h b/src/mesa/main/bufferobj.h
index 71988b0..174fd60 100644
--- a/src/mesa/main/bufferobj.h
+++ b/src/mesa/main/bufferobj.h
@@ -118,6 +118,10 @@ GLboolean GLAPIENTRY
 _mesa_IsBuffer(GLuint buffer);
 
 void GLAPIENTRY
+_mesa_BufferStorage(GLenum target, GLsizeiptr size, const GLvoid *data,
+                    GLbitfield flags);
+
+void GLAPIENTRY
 _mesa_BufferData(GLenum target, GLsizeiptrARB size,
                  const GLvoid * data, GLenum usage);
 
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index c42d177..20e9d08 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -83,6 +83,7 @@ static const struct extension extension_table[] = {
    { "GL_ARB_arrays_of_arrays",                    o(ARB_arrays_of_arrays),                    GL,             2012 },
    { "GL_ARB_base_instance",                       o(ARB_base_instance),                       GL,             2011 },
    { "GL_ARB_blend_func_extended",                 o(ARB_blend_func_extended),                 GL,             2009 },
+   { "GL_ARB_buffer_storage",                      o(ARB_buffer_storage),                      GL,             2013 },
    { "GL_ARB_clear_buffer_object",                 o(dummy_true),                              GL,             2012 },
    { "GL_ARB_color_buffer_float",                  o(ARB_color_buffer_float),                  GL,             2004 },
    { "GL_ARB_copy_buffer",                         o(dummy_true),                              GL,             2008 },
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index e509a90..b9edf71 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1464,6 +1464,7 @@ struct gl_buffer_object
    GLboolean DeletePending;   /**< true if buffer object is removed from the hash */
    GLboolean Written;   /**< Ever written to? (for debugging) */
    GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */
+   GLboolean Immutable; /**< GL_ARB_buffer_storage */
 };
 
 
@@ -3385,6 +3386,7 @@ struct gl_extensions
    GLboolean ARB_arrays_of_arrays;
    GLboolean ARB_base_instance;
    GLboolean ARB_blend_func_extended;
+   GLboolean ARB_buffer_storage;
    GLboolean ARB_color_buffer_float;
    GLboolean ARB_conservative_depth;
    GLboolean ARB_depth_buffer_float;
-- 
1.8.3.2



More information about the mesa-dev mailing list