diff options
author | Eric Anholt <[email protected]> | 2013-03-04 10:30:15 -0800 |
---|---|---|
committer | Timothy Arceri <[email protected]> | 2017-03-16 14:14:19 +1100 |
commit | 012bfebc0779bd0eed10ccbdec2edb874992d0dd (patch) | |
tree | f209d1c78aea375a56a5d0f91cca2e92deb140d2 /src/mesa/main/marshal.c | |
parent | 238d027ed6d11f7ced80e4c7a43ca62293914781 (diff) |
mesa: Track the current vertex/element array buffers for glthread.
We want to support glthread on GLES contexts with reasonable apps, and on
desktop for apps that use VBOs but haven't completely moved to core GL.
To do so, we have to deal with the "the user may or may not pass user
pointers to draw calls" problem.
Acked-by: Timothy Arceri <[email protected]>
Acked-by: Marek Olšák <[email protected]>
Tested-by: Dieter Nützel <[email protected]>
Tested-by: Mike Lothian <[email protected]>
Diffstat (limited to 'src/mesa/main/marshal.c')
-rw-r--r-- | src/mesa/main/marshal.c | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/src/mesa/main/marshal.c b/src/mesa/main/marshal.c index 14577dd4cb4..37c7b1b3dde 100644 --- a/src/mesa/main/marshal.c +++ b/src/mesa/main/marshal.c @@ -154,3 +154,106 @@ _mesa_marshal_ShaderSource(GLuint shader, GLsizei count, } free(length_tmp); } + + +/* BindBufferBase: marshalled asynchronously */ +struct marshal_cmd_BindBufferBase +{ + struct marshal_cmd_base cmd_base; + GLenum target; + GLuint index; + GLuint buffer; +}; +static inline void +_mesa_unmarshal_BindBufferBase(struct gl_context *ctx, const struct marshal_cmd_BindBufferBase *cmd) +{ + const GLenum target = cmd->target; + const GLuint index = cmd->index; + const GLuint buffer = cmd->buffer; + CALL_BindBufferBase(ctx->CurrentServerDispatch, (target, index, buffer)); +} + +/** Tracks the current bindings for the vertex array and index array buffers. + * + * 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 + * really care if our tracking is wrong for this case -- we never need to + * 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. + */ +static void +track_vbo_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; + } +} + + +struct marshal_cmd_BindBuffer +{ + struct marshal_cmd_base cmd_base; + GLenum target; + GLuint buffer; +}; + +/** + * This is just like the code-generated glBindBuffer() support, except that we + * call track_vbo_binding(). + */ +void +_mesa_unmarshal_BindBuffer(struct gl_context *ctx, + const struct marshal_cmd_BindBuffer *cmd) +{ + const GLenum target = cmd->target; + const GLuint buffer = cmd->buffer; + 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); + + 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)); + } +} + |