[Mesa-dev] [PATCH] mesa/marshal: add custom marshalling for glNamedBuffer(Sub)Data

Grigori Goronzy greg at chown.ath.cx
Sun Jun 25 08:31:40 UTC 2017


On 2017-06-25 02:37, Timothy Arceri wrote:
> Please try the series from Marek which reduces the batch size [1], the
> reduced size helps reduce the impact of syncs. MARSHAL_MAX_CMD_SIZE is
> also greatly reduced to help reduce thrashing the cache so its
> possible this patch won't be as effective anymore. However you might
> not even need it.
> 

Sorry, I forgot to mention, the 30% improvement measured is with this 
patch on top of Marek's series compared to just Marek's series. That 
series alone is improving glthread with Alien Isolation as well, but I 
didn't measure exactly how much. It wouldn't surprise me if it is in the 
40-50% region with both, though.

Best regards
Grigori

> [1] 
> https://lists.freedesktop.org/archives/mesa-dev/2017-June/160329.html
> 
> On 25/06/17 02:59, Grigori Goronzy wrote:
>> These entry points are used by Alien Isolation and caused
>> synchronization with glthread. The async marshalling implementation
>> is similar to glBuffer(Sub)Data.
>> 
>> Results in an approximately 6x drop in glthread synchronizations and a
>> ~30% FPS jump in Alien Isolation (Medium preset, Athlon 860K, RX 480).
>> 
>> This does not care about the EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD 
>> special
>> case like the Buffer(Sub)Data marshalling functions.
>> ---
>> I'm not a fan of the code duplication and I'll try to address that in
>> further changes to glthread/marshalling, but the improvement is so
>> noticeable that I'd like to share it. Alien Isolation is now playable 
>> on
>> my system while it wasn't before.
>> 
>>   src/mapi/glapi/gen/ARB_direct_state_access.xml |   4 +-
>>   src/mesa/main/marshal.c                        | 108 
>> +++++++++++++++++++++++++
>>   src/mesa/main/marshal.h                        |  18 +++++
>>   3 files changed, 128 insertions(+), 2 deletions(-)
>> 
>> diff --git a/src/mapi/glapi/gen/ARB_direct_state_access.xml 
>> b/src/mapi/glapi/gen/ARB_direct_state_access.xml
>> index cb24d79..d3d2246 100644
>> --- a/src/mapi/glapi/gen/ARB_direct_state_access.xml
>> +++ b/src/mapi/glapi/gen/ARB_direct_state_access.xml
>> @@ -61,14 +61,14 @@
>>         <param name="flags" type="GLbitfield" />
>>      </function>
>>   -   <function name="NamedBufferData">
>> +   <function name="NamedBufferData" marshal="custom">
>>         <param name="buffer" type="GLuint" />
>>         <param name="size" type="GLsizeiptr" />
>>         <param name="data" type="const GLvoid *" />
>>         <param name="usage" type="GLenum" />
>>      </function>
>>   -   <function name="NamedBufferSubData" no_error="true">
>> +   <function name="NamedBufferSubData" no_error="true" 
>> marshal="custom">
>>         <param name="buffer" type="GLuint" />
>>         <param name="offset" type="GLintptr" />
>>         <param name="size" type="GLsizeiptr" />
>> diff --git a/src/mesa/main/marshal.c b/src/mesa/main/marshal.c
>> index 4840f32..1fddf8e 100644
>> --- a/src/mesa/main/marshal.c
>> +++ b/src/mesa/main/marshal.c
>> @@ -408,6 +408,114 @@ _mesa_marshal_BufferSubData(GLenum target, 
>> GLintptr offset, GLsizeiptr size,
>>      }
>>   }
>>   +/* NamedBufferData: marshalled asynchronously */
>> +struct marshal_cmd_NamedBufferData
>> +{
>> +   struct marshal_cmd_base cmd_base;
>> +   GLuint name;
>> +   GLsizei size;
>> +   GLenum usage;
>> +   /* 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 = (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) + 
>> size;
>> +
>> +   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;
>> +      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));
>> +   }
>> +}
>> +
>>   /* ClearBufferfv: marshalled asynchronously */
>>   struct marshal_cmd_ClearBufferfv
>>   {
>> diff --git a/src/mesa/main/marshal.h b/src/mesa/main/marshal.h
>> index ddfa834..999c75e 100644
>> --- a/src/mesa/main/marshal.h
>> +++ b/src/mesa/main/marshal.h
>> @@ -180,6 +180,8 @@ struct marshal_cmd_Flush;
>>   struct marshal_cmd_BindBuffer;
>>   struct marshal_cmd_BufferData;
>>   struct marshal_cmd_BufferSubData;
>> +struct marshal_cmd_NamedBufferData;
>> +struct marshal_cmd_NamedBufferSubData;
>>   struct marshal_cmd_ClearBufferfv;
>>     void
>> @@ -228,6 +230,22 @@ _mesa_marshal_BufferSubData(GLenum target, 
>> GLintptr offset, GLsizeiptr size,
>>                               const GLvoid * data);
>>     void
>> +_mesa_unmarshal_NamedBufferData(struct gl_context *ctx,
>> +                                const struct 
>> marshal_cmd_NamedBufferData *cmd);
>> +
>> +void GLAPIENTRY
>> +_mesa_marshal_NamedBufferData(GLuint buffer, GLsizeiptr size,
>> +                              const GLvoid * data, GLenum usage);
>> +
>> +void
>> +_mesa_unmarshal_NamedBufferSubData(struct gl_context *ctx,
>> +                                   const struct 
>> marshal_cmd_NamedBufferSubData *cmd);
>> +
>> +void GLAPIENTRY
>> +_mesa_marshal_NamedBufferSubData(GLuint buffer, GLintptr offset, 
>> GLsizeiptr size,
>> +                                 const GLvoid * data);
>> +
>> +void
>>   _mesa_unmarshal_ClearBufferfv(struct gl_context *ctx,
>>                                 const struct marshal_cmd_ClearBufferfv 
>> *cmd);
>> 


More information about the mesa-dev mailing list