X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fmarshal.c;h=43deafb2c80a74014a4acf1d4d15a7b944a3c48d;hb=68cfc65ccbca748f0dfdc85876b9b5c02e598c11;hp=03da140d8764f9f04bcb3435918436abbdcf2134;hpb=425671f616cc85899535cb84abd7406a9380565e;p=mesa.git diff --git a/src/mesa/main/marshal.c b/src/mesa/main/marshal.c index 03da140d876..43deafb2c80 100644 --- a/src/mesa/main/marshal.c +++ b/src/mesa/main/marshal.c @@ -33,8 +33,6 @@ #include "dispatch.h" #include "marshal_generated.h" -#ifdef HAVE_PTHREAD - struct marshal_cmd_Flush { struct marshal_cmd_base cmd_base; @@ -67,6 +65,43 @@ _mesa_marshal_Flush(void) _mesa_glthread_flush_batch(ctx); } +/* Enable: marshalled asynchronously */ +struct marshal_cmd_Enable +{ + struct marshal_cmd_base cmd_base; + GLenum cap; +}; + +void +_mesa_unmarshal_Enable(struct gl_context *ctx, + const struct marshal_cmd_Enable *cmd) +{ + const GLenum cap = cmd->cap; + CALL_Enable(ctx->CurrentServerDispatch, (cap)); +} + +void GLAPIENTRY +_mesa_marshal_Enable(GLenum cap) +{ + GET_CURRENT_CONTEXT(ctx); + struct marshal_cmd_Enable *cmd; + debug_print_marshal("Enable"); + + if (cap == GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB) { + _mesa_glthread_finish(ctx); + _mesa_glthread_restore_dispatch(ctx, "Enable(DEBUG_OUTPUT_SYNCHRONOUS)"); + } else { + cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_Enable, + sizeof(*cmd)); + cmd->cap = cap; + _mesa_post_marshal_hook(ctx); + return; + } + + _mesa_glthread_finish(ctx); + debug_print_sync_fallback("Enable"); + CALL_Enable(ctx->CurrentServerDispatch, (cap)); +} struct marshal_cmd_ShaderSource { @@ -95,7 +130,7 @@ _mesa_unmarshal_ShaderSource(struct gl_context *ctx, } CALL_ShaderSource(ctx->CurrentServerDispatch, (cmd->shader, cmd->count, string, cmd_length)); - free(string); + free((void *)string); } @@ -168,14 +203,6 @@ struct marshal_cmd_BindBufferBase 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. * @@ -269,7 +296,7 @@ struct marshal_cmd_BufferData GLsizeiptr size; GLenum usage; bool data_null; /* If set, no data follows for "data" */ - /* Next size bytes are GLvoid data[size] */ + /* Next size bytes are GLubyte data[size] */ }; void @@ -279,13 +306,12 @@ _mesa_unmarshal_BufferData(struct gl_context *ctx, const GLenum target = cmd->target; const GLsizeiptr size = cmd->size; const GLenum usage = cmd->usage; - const char *variable_data = (const char *) (cmd + 1); - const GLvoid *data = (const GLvoid *) variable_data; + const void *data; if (cmd->data_null) data = NULL; else - variable_data += size; + data = (const void *) (cmd + 1); CALL_BufferData(ctx->CurrentServerDispatch, (target, size, data, usage)); } @@ -314,11 +340,10 @@ _mesa_marshal_BufferData(GLenum target, GLsizeiptr size, const GLvoid * data, cmd->target = target; cmd->size = size; cmd->usage = usage; - char *variable_data = (char *) (cmd + 1); cmd->data_null = !data; - if (!cmd->data_null) { + if (data) { + char *variable_data = (char *) (cmd + 1); memcpy(variable_data, data, size); - variable_data += size; } _mesa_post_marshal_hook(ctx); } else { @@ -335,7 +360,7 @@ struct marshal_cmd_BufferSubData GLenum target; GLintptr offset; GLsizeiptr size; - /* Next size bytes are GLvoid data[size] */ + /* Next size bytes are GLubyte data[size] */ }; void @@ -345,10 +370,8 @@ _mesa_unmarshal_BufferSubData(struct gl_context *ctx, const GLenum target = cmd->target; const GLintptr offset = cmd->offset; const GLsizeiptr size = cmd->size; - const char *variable_data = (const char *) (cmd + 1); - const GLvoid *data = (const GLvoid *) variable_data; + const void *data = (const void *) (cmd + 1); - variable_data += size; CALL_BufferSubData(ctx->CurrentServerDispatch, (target, offset, size, data)); } @@ -377,7 +400,6 @@ _mesa_marshal_BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, cmd->size = size; char *variable_data = (char *) (cmd + 1); memcpy(variable_data, data, size); - variable_data += size; _mesa_post_marshal_hook(ctx); } else { _mesa_glthread_finish(ctx); @@ -386,8 +408,125 @@ _mesa_marshal_BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, } } -/* ClearBufferfv: marshalled asynchronously */ -struct marshal_cmd_ClearBufferfv +/* 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)); + } +} + +/* ClearBuffer* (all variants): marshalled asynchronously */ +struct marshal_cmd_ClearBuffer { struct marshal_cmd_base cmd_base; GLenum buffer; @@ -396,7 +535,7 @@ struct marshal_cmd_ClearBufferfv void _mesa_unmarshal_ClearBufferfv(struct gl_context *ctx, - const struct marshal_cmd_ClearBufferfv *cmd) + const struct marshal_cmd_ClearBuffer *cmd) { const GLenum buffer = cmd->buffer; const GLint drawbuffer = cmd->drawbuffer; @@ -407,6 +546,87 @@ _mesa_unmarshal_ClearBufferfv(struct gl_context *ctx, (buffer, drawbuffer, value)); } +void +_mesa_unmarshal_ClearBufferiv(struct gl_context *ctx, + const struct marshal_cmd_ClearBuffer *cmd) +{ + const GLenum buffer = cmd->buffer; + const GLint drawbuffer = cmd->drawbuffer; + const char *variable_data = (const char *) (cmd + 1); + const GLint *value = (const GLint *) variable_data; + + CALL_ClearBufferiv(ctx->CurrentServerDispatch, + (buffer, drawbuffer, value)); +} + +void +_mesa_unmarshal_ClearBufferuiv(struct gl_context *ctx, + const struct marshal_cmd_ClearBuffer *cmd) +{ + const GLenum buffer = cmd->buffer; + const GLint drawbuffer = cmd->drawbuffer; + const char *variable_data = (const char *) (cmd + 1); + const GLuint *value = (const GLuint *) variable_data; + + CALL_ClearBufferuiv(ctx->CurrentServerDispatch, + (buffer, drawbuffer, value)); +} + +void +_mesa_unmarshal_ClearBufferfi(struct gl_context *ctx, + const struct marshal_cmd_ClearBuffer *cmd) +{ + const GLenum buffer = cmd->buffer; + const GLint drawbuffer = cmd->drawbuffer; + const char *variable_data = (const char *) (cmd + 1); + const GLfloat *depth = (const GLfloat *) variable_data; + const GLint *stencil = (const GLint *) (variable_data + 4); + + CALL_ClearBufferfi(ctx->CurrentServerDispatch, + (buffer, drawbuffer, *depth, *stencil)); +} + +static inline size_t buffer_to_size(GLenum buffer) +{ + switch (buffer) { + case GL_COLOR: + return 4; + case GL_DEPTH_STENCIL: + return 2; + case GL_STENCIL: + case GL_DEPTH: + return 1; + default: + return 0; + } +} + +static inline bool clear_buffer_add_command(struct gl_context *ctx, uint16_t id, + GLenum buffer, GLint drawbuffer, + const GLuint *value, size_t size) +{ + size_t cmd_size = sizeof(struct marshal_cmd_ClearBuffer) + 4 * size; + if (cmd_size <= MARSHAL_MAX_CMD_SIZE) { + struct marshal_cmd_ClearBuffer *cmd = + _mesa_glthread_allocate_command(ctx, id, + cmd_size); + cmd->buffer = buffer; + cmd->drawbuffer = drawbuffer; + GLuint *variable_data = (GLuint *) (cmd + 1); + if (size == 4) + COPY_4V(variable_data, value); + else if (size == 2) + COPY_2V(variable_data, value); + else + *variable_data = *value; + + _mesa_post_marshal_hook(ctx); + return true; + } + + return false; +} + void GLAPIENTRY _mesa_marshal_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) @@ -414,15 +634,7 @@ _mesa_marshal_ClearBufferfv(GLenum buffer, GLint drawbuffer, GET_CURRENT_CONTEXT(ctx); debug_print_marshal("ClearBufferfv"); - size_t size; - switch (buffer) { - case GL_DEPTH: - size = sizeof(GLfloat); - break; - case GL_COLOR: - size = sizeof(GLfloat) * 4; - break; - default: + if (!(buffer == GL_DEPTH || buffer == GL_COLOR)) { _mesa_glthread_finish(ctx); /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers' @@ -433,24 +645,11 @@ _mesa_marshal_ClearBufferfv(GLenum buffer, GLint drawbuffer, */ _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfv(buffer=%s)", _mesa_enum_to_string(buffer)); - return; } - size_t cmd_size = sizeof(struct marshal_cmd_ClearBufferfv) + size; - if (cmd_size <= MARSHAL_MAX_CMD_SIZE) { - struct marshal_cmd_ClearBufferfv *cmd = - _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_ClearBufferfv, - cmd_size); - cmd->buffer = buffer; - cmd->drawbuffer = drawbuffer; - GLfloat *variable_data = (GLfloat *) (cmd + 1); - if (buffer == GL_COLOR) - COPY_4V(variable_data, value); - else - *variable_data = *value; - - _mesa_post_marshal_hook(ctx); - } else { + size_t size = buffer_to_size(buffer); + if (!clear_buffer_add_command(ctx, DISPATCH_CMD_ClearBufferfv, buffer, + drawbuffer, (GLuint *)value, size)) { debug_print_sync("ClearBufferfv"); _mesa_glthread_finish(ctx); CALL_ClearBufferfv(ctx->CurrentServerDispatch, @@ -458,4 +657,93 @@ _mesa_marshal_ClearBufferfv(GLenum buffer, GLint drawbuffer, } } -#endif +void GLAPIENTRY +_mesa_marshal_ClearBufferiv(GLenum buffer, GLint drawbuffer, + const GLint *value) +{ + GET_CURRENT_CONTEXT(ctx); + debug_print_marshal("ClearBufferiv"); + + if (!(buffer == GL_STENCIL || buffer == GL_COLOR)) { + _mesa_glthread_finish(ctx); + + /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers' + * of the OpenGL 4.5 spec states: + * + * "An INVALID_ENUM error is generated by ClearBufferiv and + * ClearNamedFramebufferiv if buffer is not COLOR or STENCIL." + */ + _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferiv(buffer=%s)", + _mesa_enum_to_string(buffer)); + } + + size_t size = buffer_to_size(buffer); + if (!clear_buffer_add_command(ctx, DISPATCH_CMD_ClearBufferiv, buffer, + drawbuffer, (GLuint *)value, size)) { + debug_print_sync("ClearBufferiv"); + _mesa_glthread_finish(ctx); + CALL_ClearBufferiv(ctx->CurrentServerDispatch, + (buffer, drawbuffer, value)); + } +} + +void GLAPIENTRY +_mesa_marshal_ClearBufferuiv(GLenum buffer, GLint drawbuffer, + const GLuint *value) +{ + GET_CURRENT_CONTEXT(ctx); + debug_print_marshal("ClearBufferuiv"); + + if (buffer != GL_COLOR) { + _mesa_glthread_finish(ctx); + + /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers' + * of the OpenGL 4.5 spec states: + * + * "An INVALID_ENUM error is generated by ClearBufferuiv and + * ClearNamedFramebufferuiv if buffer is not COLOR." + */ + _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferuiv(buffer=%s)", + _mesa_enum_to_string(buffer)); + } + + if (!clear_buffer_add_command(ctx, DISPATCH_CMD_ClearBufferuiv, buffer, + drawbuffer, (GLuint *)value, 4)) { + debug_print_sync("ClearBufferuiv"); + _mesa_glthread_finish(ctx); + CALL_ClearBufferuiv(ctx->CurrentServerDispatch, + (buffer, drawbuffer, value)); + } +} + +void GLAPIENTRY +_mesa_marshal_ClearBufferfi(GLenum buffer, GLint drawbuffer, + const GLfloat depth, const GLint stencil) +{ + GET_CURRENT_CONTEXT(ctx); + debug_print_marshal("ClearBufferfi"); + + if (buffer != GL_DEPTH_STENCIL) { + _mesa_glthread_finish(ctx); + + /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers' + * of the OpenGL 4.5 spec states: + * + * "An INVALID_ENUM error is generated by ClearBufferfi and + * ClearNamedFramebufferfi if buffer is not DEPTH_STENCIL." + */ + _mesa_error(ctx, GL_INVALID_ENUM, "glClearBufferfi(buffer=%s)", + _mesa_enum_to_string(buffer)); + } + + fi_type value[2]; + value[0].f = depth; + value[1].i = stencil; + if (!clear_buffer_add_command(ctx, DISPATCH_CMD_ClearBufferfi, buffer, + drawbuffer, (GLuint *)value, 2)) { + debug_print_sync("ClearBufferfi"); + _mesa_glthread_finish(ctx); + CALL_ClearBufferfi(ctx->CurrentServerDispatch, + (buffer, drawbuffer, depth, stencil)); + } +}