mesa: allow buffers mapped with the persistent flag to be used by the GPU
authorMarek Olšák <marek.olsak@amd.com>
Mon, 27 Jan 2014 20:36:53 +0000 (21:36 +0100)
committerMarek Olšák <marek.olsak@amd.com>
Tue, 25 Feb 2014 15:04:22 +0000 (16:04 +0100)
v2: also fixed InvalidateBufferData, added citations from the 4.4 spec

Reviewed-by: Fredrik Höglund <fredrik@kde.org>
src/mesa/main/api_validate.c
src/mesa/main/bufferobj.c
src/mesa/main/bufferobj.h
src/mesa/main/drawpix.c
src/mesa/main/pbo.c
src/mesa/main/readpix.c
src/mesa/main/texgetimage.c
src/mesa/vbo/vbo_exec_array.c

index af469e046fce66c982b669df370e44b7eb4f3603..ce007e265981aa43cbd219be6fbc8828628238bc 100644 (file)
@@ -865,7 +865,7 @@ valid_draw_indirect(struct gl_context *ctx,
       return GL_FALSE;
    }
 
-   if (_mesa_bufferobj_mapped(ctx->DrawIndirectBuffer)) {
+   if (_mesa_check_disallowed_mapping(ctx->DrawIndirectBuffer)) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
                   "%s(DRAW_INDIRECT_BUFFER is mapped)", name);
       return GL_FALSE;
index b971014e6e554fa82f6c6c427d38f3d16d308c53..3079127ce6cce9270ffd432f9be998b3b91bccc5 100644 (file)
@@ -269,6 +269,9 @@ buffer_object_subdata_range_good(struct gl_context * ctx, GLenum target,
       return NULL;
    }
 
+   if (bufObj->AccessFlags & GL_MAP_PERSISTENT_BIT)
+      return bufObj;
+
    if (mappedRange) {
       if (bufferobj_range_mapped(bufObj, offset, size)) {
          _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller);
@@ -1449,7 +1452,7 @@ _mesa_ClearBufferData(GLenum target, GLenum internalformat, GLenum format,
       return;
    }
 
-   if (_mesa_bufferobj_mapped(bufObj)) {
+   if (_mesa_check_disallowed_mapping(bufObj)) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
                   "glClearBufferData(buffer currently mapped)");
       return;
@@ -1872,13 +1875,13 @@ _mesa_CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
    if (!dst)
       return;
 
-   if (_mesa_bufferobj_mapped(src)) {
+   if (_mesa_check_disallowed_mapping(src)) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
                   "glCopyBufferSubData(readBuffer is mapped)");
       return;
    }
 
-   if (_mesa_bufferobj_mapped(dst)) {
+   if (_mesa_check_disallowed_mapping(dst)) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
                   "glCopyBufferSubData(writeBuffer is mapped)");
       return;
@@ -2802,13 +2805,15 @@ _mesa_InvalidateBufferSubData(GLuint buffer, GLintptr offset,
       return;
    }
 
-   /* The GL_ARB_invalidate_subdata spec says:
+   /* The OpenGL 4.4 (Core Profile) spec says:
     *
-    *     "An INVALID_OPERATION error is generated if the buffer is currently
-    *     mapped by MapBuffer, or if the invalidate range intersects the range
-    *     currently mapped by MapBufferRange."
+    *     "An INVALID_OPERATION error is generated if buffer is currently
+    *     mapped by MapBuffer or if the invalidate range intersects the range
+    *     currently mapped by MapBufferRange, unless it was mapped
+    *     with MAP_PERSISTENT_BIT set in the MapBufferRange access flags."
     */
-   if (bufferobj_range_mapped(bufObj, offset, length)) {
+   if (!(bufObj->AccessFlags & GL_MAP_PERSISTENT_BIT) &&
+       bufferobj_range_mapped(bufObj, offset, length)) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
                   "glInvalidateBufferSubData(intersection with mapped "
                   "range)");
@@ -2835,13 +2840,14 @@ _mesa_InvalidateBufferData(GLuint buffer)
       return;
    }
 
-   /* The GL_ARB_invalidate_subdata spec says:
+   /* The OpenGL 4.4 (Core Profile) spec says:
     *
-    *     "An INVALID_OPERATION error is generated if the buffer is currently
-    *     mapped by MapBuffer, or if the invalidate range intersects the range
-    *     currently mapped by MapBufferRange."
+    *     "An INVALID_OPERATION error is generated if buffer is currently
+    *     mapped by MapBuffer or if the invalidate range intersects the range
+    *     currently mapped by MapBufferRange, unless it was mapped
+    *     with MAP_PERSISTENT_BIT set in the MapBufferRange access flags."
     */
-   if (_mesa_bufferobj_mapped(bufObj)) {
+   if (_mesa_check_disallowed_mapping(bufObj)) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
                   "glInvalidateBufferData(intersection with mapped "
                   "range)");
index 174fd608ced1a4d64da35405cc505c2e6d38ea3c..253a386c2710159a0cb31df803b99811aba253d7 100644 (file)
@@ -44,6 +44,14 @@ _mesa_bufferobj_mapped(const struct gl_buffer_object *obj)
    return obj->Pointer != NULL;
 }
 
+/** Can we not use this buffer while mapped? */
+static inline GLboolean
+_mesa_check_disallowed_mapping(const struct gl_buffer_object *obj)
+{
+   return _mesa_bufferobj_mapped(obj) &&
+          !(obj->AccessFlags & GL_MAP_PERSISTENT_BIT);
+}
+
 /**
  * Is the given buffer object a user-created buffer object?
  * Mesa uses default buffer objects in several places.  Default buffers
index 096615c05ac6da887563fd0ebed11ba9883b90c2..63e5870e6870eec243741fa29529aee21d0f9bdf 100644 (file)
@@ -151,7 +151,7 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,
                            "glDrawPixels(invalid PBO access)");
                goto end;
             }
-            if (_mesa_bufferobj_mapped(ctx->Unpack.BufferObj)) {
+            if (_mesa_check_disallowed_mapping(ctx->Unpack.BufferObj)) {
                /* buffer is mapped - that's an error */
                _mesa_error(ctx, GL_INVALID_OPERATION,
                            "glDrawPixels(PBO is mapped)");
@@ -335,7 +335,7 @@ _mesa_Bitmap( GLsizei width, GLsizei height,
                            "glBitmap(invalid PBO access)");
                return;
             }
-            if (_mesa_bufferobj_mapped(ctx->Unpack.BufferObj)) {
+            if (_mesa_check_disallowed_mapping(ctx->Unpack.BufferObj)) {
                /* buffer is mapped - that's an error */
                _mesa_error(ctx, GL_INVALID_OPERATION,
                            "glBitmap(PBO is mapped)");
index 400cec3f0e2fcfd325c98211858386fe0b3b5bac..4a39404177858309cbd78a1f5194560c184ad530 100644 (file)
@@ -201,7 +201,7 @@ _mesa_map_validate_pbo_source(struct gl_context *ctx,
       return ptr;
    }
 
-   if (_mesa_bufferobj_mapped(unpack->BufferObj)) {
+   if (_mesa_check_disallowed_mapping(unpack->BufferObj)) {
       /* buffer is already mapped - that's an error */
       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(PBO is mapped)", where);
       return NULL;
@@ -297,7 +297,7 @@ _mesa_map_validate_pbo_dest(struct gl_context *ctx,
       return ptr;
    }
 
-   if (_mesa_bufferobj_mapped(unpack->BufferObj)) {
+   if (_mesa_check_disallowed_mapping(unpack->BufferObj)) {
       /* buffer is already mapped - that's an error */
       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(PBO is mapped)", where);
       return NULL;
index 522b3464c5d4efa97e30e18cbf53635955817de2..b09cf54994a638c27e29da96b07640e62cd427f1 100644 (file)
@@ -1033,7 +1033,7 @@ _mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height,
    }
 
    if (_mesa_is_bufferobj(ctx->Pack.BufferObj) &&
-       _mesa_bufferobj_mapped(ctx->Pack.BufferObj)) {
+       _mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) {
       /* buffer is mapped - that's an error */
       _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)");
       return;
index 133fa537672c9bf86a33068382d222e238880bdf..b21aa2cf25ff6f9549fafab265a83c708f51ed75 100644 (file)
@@ -861,7 +861,7 @@ getteximage_error_check(struct gl_context *ctx, GLenum target, GLint level,
 
    if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
       /* PBO should not be mapped */
-      if (_mesa_bufferobj_mapped(ctx->Pack.BufferObj)) {
+      if (_mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) {
          _mesa_error(ctx, GL_INVALID_OPERATION,
                      "glGetTexImage(PBO is mapped)");
          return GL_TRUE;
@@ -1004,7 +1004,7 @@ getcompressedteximage_error_check(struct gl_context *ctx, GLenum target,
       }
 
       /* make sure PBO is not mapped */
-      if (_mesa_bufferobj_mapped(ctx->Pack.BufferObj)) {
+      if (_mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) {
          _mesa_error(ctx, GL_INVALID_OPERATION,
                      "glGetCompressedTexImage(PBO is mapped)");
          return GL_TRUE;
index b316f097ddf36bce4c66515d75cbb8b50adc6f2a..32e1458bd2be3d391a1bb688de4f034e005378c8 100644 (file)
@@ -53,7 +53,7 @@ check_buffers_are_unmapped(const struct gl_client_array **inputs)
    for (i = 0; i < VERT_ATTRIB_MAX; i++) {
       if (inputs[i]) {
          struct gl_buffer_object *obj = inputs[i]->BufferObj;
-         assert(!_mesa_bufferobj_mapped(obj));
+         assert(!_mesa_check_disallowed_mapping(obj));
          (void) obj;
       }
    }
@@ -73,7 +73,7 @@ vbo_check_buffers_are_unmapped(struct gl_context *ctx)
    /* check the current vertex arrays */
    check_buffers_are_unmapped(exec->array.inputs);
    /* check the current glBegin/glVertex/glEnd-style VBO */
-   assert(!_mesa_bufferobj_mapped(exec->vtx.bufferobj));
+   assert(!_mesa_check_disallowed_mapping(exec->vtx.bufferobj));
 }