In gl core, buffer must be reserved first by CreateBuffers/GenBuffers to be valid.
v4: update comments based on Nicolai review Signed-off-by: Gregory Hainaut <gregory.hain...@gmail.com> --- src/mesa/main/marshal.c | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/src/mesa/main/marshal.c b/src/mesa/main/marshal.c index 4037b79..1167271 100644 --- a/src/mesa/main/marshal.c +++ b/src/mesa/main/marshal.c @@ -312,21 +312,34 @@ _mesa_unmarshal_DeleteBuffers(struct gl_context *ctx, /* BindBufferBase: marshalled asynchronously */ struct marshal_cmd_BindBufferBase { struct marshal_cmd_base cmd_base; GLenum target; GLuint index; GLuint buffer; }; -/** Tracks the current bindings for the vertex array and index array buffers. +/** + * Check that buffer is a valid buffer handle + * Always return false for ID 0. + */ +static bool +is_bufferobj(struct gl_context *ctx, GLuint buffer) +{ + if (buffer == 0) + return false; + else + return _mesa_HashLookup(ctx->Shared->ShadowBufferObjects, buffer) != NULL; +} + +/** Tracks the current bindings of GL buffer targets * * This is part of what we need to enable glthread on compat-GL contexts that * happen to use VBOs, without also supporting the full tracking of VBO vs * user vertex array bindings per attribute on each vertex array for * determining what to upload at draw call time. * * Note that GL core makes it so that a buffer binding with an invalid handle * in the "buffer" parameter will throw an error, and then a * glVertexAttribPointer() that followsmight not end up pointing at a VBO. * However, in GL core the draw call would throw an error as well, so we don't @@ -334,37 +347,54 @@ struct marshal_cmd_BindBufferBase * marshal user data for draw calls, and the unmarshal will just generate an * error or not as appropriate. * * For compatibility GL, we do need to accurately know whether the draw call * on the unmarshal side will dereference a user pointer or load data from a * VBO per vertex. That would make it seem like we need to track whether a * "buffer" is valid, so that we can know when an error will be generated * instead of updating the binding. However, compat GL has the ridiculous * feature that if you pass a bad name, it just gens a buffer object for you, * so we escape without having to know if things are valid or not. + * + * Pixel buffers are tracked to decide whether pixel transfer goes to a user + * pointer (must be synchronous) or a GL buffer (can be asynchronous). Unlike + * for VBOs, we do need accurate tracking, since user pointers can be used in + * GL core contexts. */ static void -track_vbo_binding(struct gl_context *ctx, GLenum target, GLuint buffer) +track_buffers_binding(struct gl_context *ctx, GLenum target, GLuint buffer) { struct glthread_state *glthread = ctx->GLThread; switch (target) { case GL_ARRAY_BUFFER: glthread->vertex_array_is_vbo = (buffer != 0); break; case GL_ELEMENT_ARRAY_BUFFER: /* The current element array buffer binding is actually tracked in the * vertex array object instead of the context, so this would need to * change on vertex array object updates. */ glthread->element_array_is_vbo = (buffer != 0); break; + case GL_PIXEL_UNPACK_BUFFER: + if (ctx->API == API_OPENGL_COMPAT || is_bufferobj(ctx, buffer)) + glthread->pixel_unpack_buffer_bound = buffer; + else + glthread->pixel_unpack_buffer_bound = 0; + break; + case GL_PIXEL_PACK_BUFFER: + if (ctx->API == API_OPENGL_COMPAT || is_bufferobj(ctx, buffer)) + glthread->pixel_pack_buffer_bound = buffer; + else + glthread->pixel_pack_buffer_bound = 0; + break; } } struct marshal_cmd_BindBuffer { struct marshal_cmd_base cmd_base; GLenum target; GLuint buffer; }; @@ -382,21 +412,21 @@ _mesa_unmarshal_BindBuffer(struct gl_context *ctx, CALL_BindBuffer(ctx->CurrentServerDispatch, (target, buffer)); } void GLAPIENTRY _mesa_marshal_BindBuffer(GLenum target, GLuint buffer) { GET_CURRENT_CONTEXT(ctx); size_t cmd_size = sizeof(struct marshal_cmd_BindBuffer); struct marshal_cmd_BindBuffer *cmd; debug_print_marshal("BindBuffer"); - track_vbo_binding(ctx, target, buffer); + track_buffers_binding(ctx, target, buffer); if (cmd_size <= MARSHAL_MAX_CMD_SIZE) { cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_BindBuffer, cmd_size); cmd->target = target; cmd->buffer = buffer; _mesa_post_marshal_hook(ctx); } else { _mesa_glthread_finish(ctx); CALL_BindBuffer(ctx->CurrentServerDispatch, (target, buffer)); -- 2.1.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev