#include "marshal.h"
#include "dispatch.h"
-static inline void
-_mesa_post_marshal_hook(struct gl_context *ctx)
-{
- /* This can be enabled for debugging whether a failure is a synchronization
- * problem between the main thread and the worker thread, or a failure in
- * how we actually marshal.
- */
- if (false)
- _mesa_glthread_finish(ctx);
-}
-
-
struct marshal_cmd_ShaderSource
{
struct marshal_cmd_base cmd_base;
measure_ShaderSource_strings(count, string, length, length_tmp);
size_t total_cmd_size = fixed_cmd_size + length_size + total_string_length;
- if (total_cmd_size <= MARSHAL_MAX_CMD_SIZE) {
+ if (total_cmd_size <= MARSHAL_MAX_CMD_SIZE && count > 0) {
struct marshal_cmd_ShaderSource *cmd =
_mesa_glthread_allocate_command(ctx, DISPATCH_CMD_ShaderSource,
total_cmd_size);
memcpy(cmd_strings, string[i], cmd_length[i]);
cmd_strings += cmd_length[i];
}
- _mesa_post_marshal_hook(ctx);
} else {
_mesa_glthread_finish(ctx);
CALL_ShaderSource(ctx->CurrentServerDispatch,
}
free(length_tmp);
}
-
-
-/** 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.
- */
-void
-_mesa_glthread_BindBuffer(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->CurrentVAO->IndexBufferIsUserPointer = buffer != 0;
- break;
- case GL_DRAW_INDIRECT_BUFFER:
- glthread->draw_indirect_buffer_is_vbo = buffer != 0;
- break;
- }
-}
-
-
-/* BufferData: marshalled asynchronously */
-struct marshal_cmd_BufferData
-{
- struct marshal_cmd_base cmd_base;
- GLenum target;
- GLsizeiptr size;
- GLenum usage;
- bool data_null; /* If set, no data follows for "data" */
- /* Next size bytes are GLubyte data[size] */
-};
-
-void
-_mesa_unmarshal_BufferData(struct gl_context *ctx,
- const struct marshal_cmd_BufferData *cmd)
-{
- const GLenum target = cmd->target;
- const GLsizeiptr size = cmd->size;
- const GLenum usage = cmd->usage;
- const void *data;
-
- if (cmd->data_null)
- data = NULL;
- else
- data = (const void *) (cmd + 1);
-
- CALL_BufferData(ctx->CurrentServerDispatch, (target, size, data, usage));
-}
-
-void GLAPIENTRY
-_mesa_marshal_BufferData(GLenum target, GLsizeiptr size, const GLvoid * data,
- GLenum usage)
-{
- GET_CURRENT_CONTEXT(ctx);
- size_t cmd_size =
- sizeof(struct marshal_cmd_BufferData) + (data ? size : 0);
- debug_print_marshal("BufferData");
-
- if (unlikely(size < 0)) {
- _mesa_glthread_finish(ctx);
- _mesa_error(ctx, GL_INVALID_VALUE, "BufferData(size < 0)");
- return;
- }
-
- if (target != GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD &&
- cmd_size <= MARSHAL_MAX_CMD_SIZE) {
- struct marshal_cmd_BufferData *cmd =
- _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_BufferData,
- cmd_size);
-
- cmd->target = target;
- cmd->size = size;
- cmd->usage = usage;
- cmd->data_null = !data;
- if (data) {
- char *variable_data = (char *) (cmd + 1);
- memcpy(variable_data, data, size);
- }
- _mesa_post_marshal_hook(ctx);
- } else {
- _mesa_glthread_finish(ctx);
- CALL_BufferData(ctx->CurrentServerDispatch,
- (target, size, data, usage));
- }
-}
-
-/* BufferSubData: marshalled asynchronously */
-struct marshal_cmd_BufferSubData
-{
- struct marshal_cmd_base cmd_base;
- GLenum target;
- GLintptr offset;
- GLsizeiptr size;
- /* Next size bytes are GLubyte data[size] */
-};
-
-void
-_mesa_unmarshal_BufferSubData(struct gl_context *ctx,
- const struct marshal_cmd_BufferSubData *cmd)
-{
- const GLenum target = cmd->target;
- const GLintptr offset = cmd->offset;
- const GLsizeiptr size = cmd->size;
- const void *data = (const void *) (cmd + 1);
-
- CALL_BufferSubData(ctx->CurrentServerDispatch,
- (target, offset, size, data));
-}
-
-void GLAPIENTRY
-_mesa_marshal_BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size,
- const GLvoid * data)
-{
- GET_CURRENT_CONTEXT(ctx);
- size_t cmd_size = sizeof(struct marshal_cmd_BufferSubData) + size;
-
- debug_print_marshal("BufferSubData");
- if (unlikely(size < 0)) {
- _mesa_glthread_finish(ctx);
- _mesa_error(ctx, GL_INVALID_VALUE, "BufferSubData(size < 0)");
- return;
- }
-
- if (target != GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD &&
- cmd_size <= MARSHAL_MAX_CMD_SIZE) {
- struct marshal_cmd_BufferSubData *cmd =
- _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_BufferSubData,
- cmd_size);
- cmd->target = target;
- cmd->offset = offset;
- cmd->size = size;
- char *variable_data = (char *) (cmd + 1);
- memcpy(variable_data, data, size);
- _mesa_post_marshal_hook(ctx);
- } else {
- _mesa_glthread_finish(ctx);
- CALL_BufferSubData(ctx->CurrentServerDispatch,
- (target, offset, size, data));
- }
-}
-
-/* NamedBufferData: marshalled asynchronously */
-struct marshal_cmd_NamedBufferData
-{
- struct marshal_cmd_base cmd_base;
- GLuint name;
- GLsizei size;
- GLenum usage;
- bool data_null; /* If set, no data follows for "data" */
- /* Next size bytes are GLubyte data[size] */
-};
-
-void
-_mesa_unmarshal_NamedBufferData(struct gl_context *ctx,
- const struct marshal_cmd_NamedBufferData *cmd)
-{
- const GLuint name = cmd->name;
- const GLsizei size = cmd->size;
- const GLenum usage = cmd->usage;
- const void *data;
-
- if (cmd->data_null)
- data = NULL;
- else
- data = (const void *) (cmd + 1);
-
- CALL_NamedBufferData(ctx->CurrentServerDispatch,
- (name, size, data, usage));
-}
-
-void GLAPIENTRY
-_mesa_marshal_NamedBufferData(GLuint buffer, GLsizeiptr size,
- const GLvoid * data, GLenum usage)
-{
- GET_CURRENT_CONTEXT(ctx);
- size_t cmd_size = sizeof(struct marshal_cmd_NamedBufferData) + (data ? size : 0);
-
- debug_print_marshal("NamedBufferData");
- if (unlikely(size < 0)) {
- _mesa_glthread_finish(ctx);
- _mesa_error(ctx, GL_INVALID_VALUE, "NamedBufferData(size < 0)");
- return;
- }
-
- if (buffer > 0 && cmd_size <= MARSHAL_MAX_CMD_SIZE) {
- struct marshal_cmd_NamedBufferData *cmd =
- _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_NamedBufferData,
- cmd_size);
- cmd->name = buffer;
- cmd->size = size;
- cmd->usage = usage;
- cmd->data_null = !data;
- if (data) {
- char *variable_data = (char *) (cmd + 1);
- memcpy(variable_data, data, size);
- }
- _mesa_post_marshal_hook(ctx);
- } else {
- _mesa_glthread_finish(ctx);
- CALL_NamedBufferData(ctx->CurrentServerDispatch,
- (buffer, size, data, usage));
- }
-}
-
-/* NamedBufferSubData: marshalled asynchronously */
-struct marshal_cmd_NamedBufferSubData
-{
- struct marshal_cmd_base cmd_base;
- GLuint name;
- GLintptr offset;
- GLsizei size;
- /* Next size bytes are GLubyte data[size] */
-};
-
-void
-_mesa_unmarshal_NamedBufferSubData(struct gl_context *ctx,
- const struct marshal_cmd_NamedBufferSubData *cmd)
-{
- const GLuint name = cmd->name;
- const GLintptr offset = cmd->offset;
- const GLsizei size = cmd->size;
- const void *data = (const void *) (cmd + 1);
-
- CALL_NamedBufferSubData(ctx->CurrentServerDispatch,
- (name, offset, size, data));
-}
-
-void GLAPIENTRY
-_mesa_marshal_NamedBufferSubData(GLuint buffer, GLintptr offset,
- GLsizeiptr size, const GLvoid * data)
-{
- GET_CURRENT_CONTEXT(ctx);
- size_t cmd_size = sizeof(struct marshal_cmd_NamedBufferSubData) + size;
-
- debug_print_marshal("NamedBufferSubData");
- if (unlikely(size < 0)) {
- _mesa_glthread_finish(ctx);
- _mesa_error(ctx, GL_INVALID_VALUE, "NamedBufferSubData(size < 0)");
- return;
- }
-
- if (buffer > 0 && cmd_size <= MARSHAL_MAX_CMD_SIZE) {
- struct marshal_cmd_NamedBufferSubData *cmd =
- _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_NamedBufferSubData,
- cmd_size);
- cmd->name = buffer;
- cmd->offset = offset;
- cmd->size = size;
- char *variable_data = (char *) (cmd + 1);
- memcpy(variable_data, data, size);
- _mesa_post_marshal_hook(ctx);
- } else {
- _mesa_glthread_finish(ctx);
- CALL_NamedBufferSubData(ctx->CurrentServerDispatch,
- (buffer, offset, size, data));
- }
-}