This will allow us to add KHR_no_error support for *BufferRange functions. --- src/mesa/main/bufferobj.c | 77 ++++++++++++++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 27 deletions(-)
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index 76e035f..797b6fb 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -2371,163 +2371,170 @@ _mesa_CopyNamedBufferSubData(GLuint readBuffer, GLuint writeBuffer, dst = _mesa_lookup_bufferobj_err(ctx, writeBuffer, "glCopyNamedBufferSubData"); if (!dst) return; _mesa_copy_buffer_sub_data(ctx, src, dst, readOffset, writeOffset, size, "glCopyNamedBufferSubData"); } - -static void * -map_buffer_range(struct gl_context *ctx, struct gl_buffer_object *bufObj, - GLintptr offset, GLsizeiptr length, GLbitfield access, - const char *func) +static bool +validate_map_buffer_range(struct gl_context *ctx, + struct gl_buffer_object *bufObj, GLintptr offset, + GLsizeiptr length, GLbitfield access, + const char *func) { - void *map; GLbitfield allowed_access; - ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, NULL); + ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, false); if (offset < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset %ld < 0)", func, (long) offset); - return NULL; + return false; } if (length < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(length %ld < 0)", func, (long) length); - return NULL; + return false; } /* Page 38 of the PDF of the OpenGL ES 3.0 spec says: * * "An INVALID_OPERATION error is generated for any of the following * conditions: * * * <length> is zero." * * Additionally, page 94 of the PDF of the OpenGL 4.5 core spec * (30.10.2014) also says this, so it's no longer allowed for desktop GL, * either. */ if (length == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(length = 0)", func); - return NULL; + return false; } allowed_access = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT; if (ctx->Extensions.ARB_buffer_storage) { allowed_access |= GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT; } if (access & ~allowed_access) { /* generate an error if any bits other than those allowed are set */ _mesa_error(ctx, GL_INVALID_VALUE, "%s(access has undefined bits set)", func); - return NULL; + return false; } if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(access indicates neither read or write)", func); - return NULL; + return false; } if ((access & GL_MAP_READ_BIT) && (access & (GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT))) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(read access with disallowed bits)", func); - return NULL; + return false; } if ((access & GL_MAP_FLUSH_EXPLICIT_BIT) && ((access & GL_MAP_WRITE_BIT) == 0)) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(access has flush explicit without write)", func); - return NULL; + return false; } if (access & GL_MAP_READ_BIT && !(bufObj->StorageFlags & GL_MAP_READ_BIT)) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(buffer does not allow read access)", func); - return NULL; + return false; } if (access & GL_MAP_WRITE_BIT && !(bufObj->StorageFlags & GL_MAP_WRITE_BIT)) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(buffer does not allow write access)", func); - return NULL; + return false; } if (access & GL_MAP_COHERENT_BIT && !(bufObj->StorageFlags & GL_MAP_COHERENT_BIT)) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(buffer does not allow coherent access)", func); - return NULL; + return false; } if (access & GL_MAP_PERSISTENT_BIT && !(bufObj->StorageFlags & GL_MAP_PERSISTENT_BIT)) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(buffer does not allow persistent access)", func); - return NULL; + return false; } if (offset + length > bufObj->Size) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset %lu + length %lu > buffer_size %lu)", func, (unsigned long) offset, (unsigned long) length, (unsigned long) bufObj->Size); - return NULL; + return false; } if (_mesa_bufferobj_mapped(bufObj, MAP_USER)) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(buffer already mapped)", func); - return NULL; - } - - if (!bufObj->Size) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(buffer size = 0)", func); - return NULL; + return false; } if (access & GL_MAP_WRITE_BIT) { bufObj->NumMapBufferWriteCalls++; if ((bufObj->Usage == GL_STATIC_DRAW || bufObj->Usage == GL_STATIC_COPY) && bufObj->NumMapBufferWriteCalls >= BUFFER_WARNING_CALL_COUNT) { BUFFER_USAGE_WARNING(ctx, "using %s(buffer %u, offset %u, length %u) to " "update a %s buffer", func, bufObj->Name, offset, length, _mesa_enum_to_string(bufObj->Usage)); } } + return true; +} + +static void * +map_buffer_range(struct gl_context *ctx, struct gl_buffer_object *bufObj, + GLintptr offset, GLsizeiptr length, GLbitfield access, + const char *func) +{ + if (!bufObj->Size) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(buffer size = 0)", func); + return NULL; + } + assert(ctx->Driver.MapBufferRange); - map = ctx->Driver.MapBufferRange(ctx, offset, length, access, bufObj, - MAP_USER); + void *map = ctx->Driver.MapBufferRange(ctx, offset, length, access, bufObj, + MAP_USER); if (!map) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(map failed)", func); } else { /* The driver callback should have set all these fields. * This is important because other modules (like VBO) might call * the driver function directly. */ assert(bufObj->Mappings[MAP_USER].Pointer == map); assert(bufObj->Mappings[MAP_USER].Length == length); @@ -2578,20 +2585,24 @@ _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, if (!ctx->Extensions.ARB_map_buffer_range) { _mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferRange(ARB_map_buffer_range not supported)"); return NULL; } bufObj = get_buffer(ctx, "glMapBufferRange", target, GL_INVALID_OPERATION); if (!bufObj) return NULL; + if (!validate_map_buffer_range(ctx, bufObj, offset, length, access, + "glMapBufferRange")) + return NULL; + return map_buffer_range(ctx, bufObj, offset, length, access, "glMapBufferRange"); } void * GLAPIENTRY _mesa_MapNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access) { GET_CURRENT_CONTEXT(ctx); struct gl_buffer_object *bufObj; @@ -2600,20 +2611,24 @@ _mesa_MapNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length, _mesa_error(ctx, GL_INVALID_OPERATION, "glMapNamedBufferRange(" "ARB_map_buffer_range not supported)"); return NULL; } bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glMapNamedBufferRange"); if (!bufObj) return NULL; + if (!validate_map_buffer_range(ctx, bufObj, offset, length, access, + "glMapNamedBufferRange")) + return NULL; + return map_buffer_range(ctx, bufObj, offset, length, access, "glMapNamedBufferRange"); } /** * Converts GLenum access from MapBuffer and MapNamedBuffer into * flags for input to map_buffer_range. * * \return true if the type of requested access is permissible. */ @@ -2645,40 +2660,48 @@ _mesa_MapBuffer(GLenum target, GLenum access) if (!get_map_buffer_access_flags(ctx, access, &accessFlags)) { _mesa_error(ctx, GL_INVALID_ENUM, "glMapBuffer(invalid access)"); return NULL; } bufObj = get_buffer(ctx, "glMapBuffer", target, GL_INVALID_OPERATION); if (!bufObj) return NULL; + if (!validate_map_buffer_range(ctx, bufObj, 0, bufObj->Size, accessFlags, + "glMapBuffer")) + return NULL; + return map_buffer_range(ctx, bufObj, 0, bufObj->Size, accessFlags, "glMapBuffer"); } void * GLAPIENTRY _mesa_MapNamedBuffer(GLuint buffer, GLenum access) { GET_CURRENT_CONTEXT(ctx); struct gl_buffer_object *bufObj; GLbitfield accessFlags; if (!get_map_buffer_access_flags(ctx, access, &accessFlags)) { _mesa_error(ctx, GL_INVALID_ENUM, "glMapNamedBuffer(invalid access)"); return NULL; } bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glMapNamedBuffer"); if (!bufObj) return NULL; + if (!validate_map_buffer_range(ctx, bufObj, 0, bufObj->Size, accessFlags, + "glMapNamedBuffer")) + return NULL; + return map_buffer_range(ctx, bufObj, 0, bufObj->Size, accessFlags, "glMapNamedBuffer"); } void _mesa_flush_mapped_buffer_range(struct gl_context *ctx, struct gl_buffer_object *bufObj, GLintptr offset, GLsizeiptr length, const char *func) -- 2.9.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev