[Mesa-dev] [PATCH] mesa/glthread: add custom marshalling for ClearBufferfv()
Nicolai Hähnle
nhaehnle at gmail.com
Fri Mar 24 11:10:59 UTC 2017
On 24.03.2017 07:46, Timothy Arceri wrote:
> This is one of the main causes of syncs in Civ6.
Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>
> ---
> src/mapi/glapi/gen/GL3x.xml | 2 +-
> src/mesa/main/marshal.c | 73 +++++++++++++++++++++++++++++++++++++++++++++
> src/mesa/main/marshal.h | 9 ++++++
> 3 files changed, 83 insertions(+), 1 deletion(-)
>
> diff --git a/src/mapi/glapi/gen/GL3x.xml b/src/mapi/glapi/gen/GL3x.xml
> index b603e1f..f38a287 100644
> --- a/src/mapi/glapi/gen/GL3x.xml
> +++ b/src/mapi/glapi/gen/GL3x.xml
> @@ -122,21 +122,21 @@
> <param name="drawbuffer" type="GLint"/>
> <param name="value" type="const GLint *"/>
> </function>
>
> <function name="ClearBufferuiv" es2="3.0">
> <param name="buffer" type="GLenum"/>
> <param name="drawbuffer" type="GLint"/>
> <param name="value" type="const GLuint *"/>
> </function>
>
> - <function name="ClearBufferfv" es2="3.0">
> + <function name="ClearBufferfv" es2="3.0" marshal="custom">
> <param name="buffer" type="GLenum"/>
> <param name="drawbuffer" type="GLint"/>
> <param name="value" type="const GLfloat *"/>
> </function>
>
> <function name="ClearBufferfi" es2="3.0">
> <param name="buffer" type="GLenum"/>
> <param name="drawbuffer" type="GLint"/>
> <param name="depth" type="GLfloat"/>
> <param name="stencil" type="GLint"/>
> diff --git a/src/mesa/main/marshal.c b/src/mesa/main/marshal.c
> index cdc7fed..bcc6f17 100644
> --- a/src/mesa/main/marshal.c
> +++ b/src/mesa/main/marshal.c
> @@ -20,20 +20,21 @@
> * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> * IN THE SOFTWARE.
> */
>
> /** \file marshal.c
> *
> * Custom functions for marshalling GL calls from the main thread to a worker
> * thread when automatic code generation isn't appropriate.
> */
>
> +#include "main/enums.h"
> #include "marshal.h"
> #include "dispatch.h"
> #include "marshal_generated.h"
>
> #ifdef HAVE_PTHREAD
>
> struct marshal_cmd_Flush
> {
> struct marshal_cmd_base cmd_base;
> };
> @@ -377,11 +378,83 @@ _mesa_marshal_BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size,
> memcpy(variable_data, data, size);
> variable_data += size;
> _mesa_post_marshal_hook(ctx);
> } else {
> _mesa_glthread_finish(ctx);
> CALL_BufferSubData(ctx->CurrentServerDispatch,
> (target, offset, size, data));
> }
> }
>
> +/* ClearBufferfv: marshalled asynchronously */
> +struct marshal_cmd_ClearBufferfv
> +{
> + struct marshal_cmd_base cmd_base;
> + GLenum buffer;
> + GLint drawbuffer;
> +};
> +
> +void
> +_mesa_unmarshal_ClearBufferfv(struct gl_context *ctx,
> + const struct marshal_cmd_ClearBufferfv *cmd)
> +{
> + const GLenum buffer = cmd->buffer;
> + const GLint drawbuffer = cmd->drawbuffer;
> + const char *variable_data = (const char *) (cmd + 1);
> + const GLfloat *value = (const GLfloat *) variable_data;
> +
> + CALL_ClearBufferfv(ctx->CurrentServerDispatch,
> + (buffer, drawbuffer, value));
> +}
> +
> +void GLAPIENTRY
> +_mesa_marshal_ClearBufferfv(GLenum buffer, GLint drawbuffer,
> + const GLfloat *value)
> +{
> + 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:
> + _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 ClearBufferfv and
> + * ClearNamedFramebufferfv if buffer is not COLOR or DEPTH."
> + */
> + _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 {
> + debug_print_sync("ClearBufferfv");
> + _mesa_glthread_finish(ctx);
> + CALL_ClearBufferfv(ctx->CurrentServerDispatch,
> + (buffer, drawbuffer, value));
> + }
> +}
> +
> #endif
> diff --git a/src/mesa/main/marshal.h b/src/mesa/main/marshal.h
> index c2ecba6..8ea303a 100644
> --- a/src/mesa/main/marshal.h
> +++ b/src/mesa/main/marshal.h
> @@ -183,20 +183,21 @@ static inline bool
> _mesa_glthread_is_compat_bind_vertex_array(const struct gl_context *ctx)
> {
> return ctx->API != API_OPENGL_CORE;
> }
>
> struct marshal_cmd_ShaderSource;
> struct marshal_cmd_Flush;
> struct marshal_cmd_BindBuffer;
> struct marshal_cmd_BufferData;
> struct marshal_cmd_BufferSubData;
> +struct marshal_cmd_ClearBufferfv;
>
> void GLAPIENTRY
> _mesa_marshal_ShaderSource(GLuint shader, GLsizei count,
> const GLchar * const *string, const GLint *length);
>
> void
> _mesa_unmarshal_ShaderSource(struct gl_context *ctx,
> const struct marshal_cmd_ShaderSource *cmd);
>
> void GLAPIENTRY
> @@ -222,11 +223,19 @@ _mesa_marshal_BufferData(GLenum target, GLsizeiptr size, const GLvoid * data,
> GLenum usage);
>
> void
> _mesa_unmarshal_BufferSubData(struct gl_context *ctx,
> const struct marshal_cmd_BufferSubData *cmd);
>
> void GLAPIENTRY
> _mesa_marshal_BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size,
> const GLvoid * data);
>
> +void
> +_mesa_unmarshal_ClearBufferfv(struct gl_context *ctx,
> + const struct marshal_cmd_ClearBufferfv *cmd);
> +
> +void GLAPIENTRY
> +_mesa_marshal_ClearBufferfv(GLenum buffer, GLint drawbuffer,
> + const GLfloat *value);
> +
> #endif /* MARSHAL_H */
>
--
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.
More information about the mesa-dev
mailing list