From d26a065b7496ef69754fde6e4d0006ccb76f7f3a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Mon, 27 Jan 2014 21:36:53 +0100 Subject: [PATCH] mesa: allow buffers mapped with the persistent flag to be used by the GPU MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit v2: also fixed InvalidateBufferData, added citations from the 4.4 spec Reviewed-by: Fredrik Höglund --- src/mesa/main/api_validate.c | 2 +- src/mesa/main/bufferobj.c | 32 +++++++++++++++++++------------- src/mesa/main/bufferobj.h | 8 ++++++++ src/mesa/main/drawpix.c | 4 ++-- src/mesa/main/pbo.c | 4 ++-- src/mesa/main/readpix.c | 2 +- src/mesa/main/texgetimage.c | 4 ++-- src/mesa/vbo/vbo_exec_array.c | 4 ++-- 8 files changed, 37 insertions(+), 23 deletions(-) diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index af469e046fc..ce007e26598 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -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; diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index b971014e6e5..3079127ce6c 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -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)"); diff --git a/src/mesa/main/bufferobj.h b/src/mesa/main/bufferobj.h index 174fd608ced..253a386c271 100644 --- a/src/mesa/main/bufferobj.h +++ b/src/mesa/main/bufferobj.h @@ -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 diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c index 096615c05ac..63e5870e687 100644 --- a/src/mesa/main/drawpix.c +++ b/src/mesa/main/drawpix.c @@ -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)"); diff --git a/src/mesa/main/pbo.c b/src/mesa/main/pbo.c index 400cec3f0e2..4a394041778 100644 --- a/src/mesa/main/pbo.c +++ b/src/mesa/main/pbo.c @@ -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; diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c index 522b3464c5d..b09cf54994a 100644 --- a/src/mesa/main/readpix.c +++ b/src/mesa/main/readpix.c @@ -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; diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c index 133fa537672..b21aa2cf25f 100644 --- a/src/mesa/main/texgetimage.c +++ b/src/mesa/main/texgetimage.c @@ -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; diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index b316f097ddf..32e1458bd2b 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -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)); } -- 2.30.2