[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