[Mesa-dev] [PATCH v6 2/3] mesa/glthread: add tracking of PBO binding

Gregory Hainaut gregory.hainaut at gmail.com
Sun May 21 14:57:56 UTC 2017


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.hainaut at 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 4037b793ee..1167271607 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.11.0



More information about the mesa-dev mailing list