[Mesa-dev] [PATCH 12/24] mesa/st: implement memory objects as a backend for buffer objects

Samuel Pitoiset samuel.pitoiset at gmail.com
Fri Jul 28 09:48:46 UTC 2017


Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>

On 07/27/2017 03:08 PM, Timothy Arceri wrote:
> From: Andres Rodriguez <andresx7 at gmail.com>
> 
> Use a memory object instead of user memory.
> 
> Signed-off-by: Andres Rodriguez <andresx7 at gmail.com>
> Reviewed-by: Timothy Arceri <tarceri at itsqueeze.com>
> ---
>   src/mesa/main/dd.h                           | 12 +++++
>   src/mesa/state_tracker/st_cb_bufferobjects.c | 66 +++++++++++++++++++++-------
>   2 files changed, 61 insertions(+), 17 deletions(-)
> 
> diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
> index 9cdc4a945e..512873434e 100644
> --- a/src/mesa/main/dd.h
> +++ b/src/mesa/main/dd.h
> @@ -1090,20 +1090,32 @@ struct dd_function_table {
>   
>      /**
>       * Set the given memory object as the texture's storage.
>       */
>      GLboolean (*SetTextureStorageForMemoryObject)(struct gl_context *ctx,
>                                                    struct gl_texture_object *tex_obj,
>                                                    struct gl_memory_object *mem_obj,
>                                                    GLsizei levels, GLsizei width,
>                                                    GLsizei height, GLsizei depth,
>                                                    GLuint64 offset);
> +
> +   /**
> +    * Use a memory object as the backing data for a buffer object
> +    */
> +   GLboolean (*BufferDataMem)(struct gl_context *ctx,
> +                              GLenum target,
> +                              GLsizeiptrARB size,
> +                              struct gl_memory_object *memObj,
> +                              GLuint64 offset,
> +                              GLenum usage,
> +                              struct gl_buffer_object *bufObj);
> +
>      /*@}*/
>   
>      /**
>       * \name GL_EXT_external_objects_fd interface
>       */
>      /*@{*/
>      /**
>       * Called to import a memory object. The caller relinquishes ownership
>       * of fd after the call returns.
>       *
> diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c
> index 1fa9389b32..d8e2a5cfe7 100644
> --- a/src/mesa/state_tracker/st_cb_bufferobjects.c
> +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c
> @@ -33,20 +33,21 @@
>   
>   #include <inttypes.h>  /* for PRId64 macro */
>   
>   #include "main/imports.h"
>   #include "main/mtypes.h"
>   #include "main/arrayobj.h"
>   #include "main/bufferobj.h"
>   
>   #include "st_context.h"
>   #include "st_cb_bufferobjects.h"
> +#include "st_cb_memoryobjects.h"
>   #include "st_debug.h"
>   
>   #include "pipe/p_context.h"
>   #include "pipe/p_defines.h"
>   #include "util/u_inlines.h"
>   
>   
>   /**
>    * There is some duplication between mesa's bufferobjects and our
>    * bufmgr buffers.  Both have an integer handle and a hashtable to
> @@ -156,41 +157,36 @@ st_bufferobj_get_subdata(struct gl_context *ctx,
>   
>      if (!st_obj->buffer) {
>         /* we probably ran out of memory during buffer allocation */
>         return;
>      }
>   
>      pipe_buffer_read(st_context(ctx)->pipe, st_obj->buffer,
>                       offset, size, data);
>   }
>   
> -
> -/**
> - * Allocate space for and store data in a buffer object.  Any data that was
> - * previously stored in the buffer object is lost.  If data is NULL,
> - * memory will be allocated, but no copy will occur.
> - * Called via ctx->Driver.BufferData().
> - * \return GL_TRUE for success, GL_FALSE if out of memory
> - */
> -static GLboolean
> -st_bufferobj_data(struct gl_context *ctx,
> -                  GLenum target,
> -                  GLsizeiptrARB size,
> -                  const void *data,
> -                  GLenum usage,
> -                  GLbitfield storageFlags,
> -                  struct gl_buffer_object *obj)
> +static ALWAYS_INLINE GLboolean
> +bufferobj_data(struct gl_context *ctx,
> +               GLenum target,
> +               GLsizeiptrARB size,
> +               const void *data,
> +               struct gl_memory_object *memObj,
> +               GLuint64 offset,
> +               GLenum usage,
> +               GLbitfield storageFlags,
> +               struct gl_buffer_object *obj)
>   {
>      struct st_context *st = st_context(ctx);
>      struct pipe_context *pipe = st->pipe;
>      struct pipe_screen *screen = pipe->screen;
>      struct st_buffer_object *st_obj = st_buffer_object(obj);
> +   struct st_memory_object *st_mem_obj = st_memory_object(memObj);
>      unsigned bind, pipe_usage, pipe_flags = 0;
>   
>      if (target != GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD &&
>          size && st_obj->buffer &&
>          st_obj->Base.Size == size &&
>          st_obj->Base.Usage == usage &&
>          st_obj->Base.StorageFlags == storageFlags) {
>         if (data) {
>            /* Just discard the old contents and write new data.
>             * This should be the same as creating a new buffer, but we avoid
> @@ -310,21 +306,26 @@ st_bufferobj_data(struct gl_context *ctx,
>         buffer.target = PIPE_BUFFER;
>         buffer.format = PIPE_FORMAT_R8_UNORM; /* want TYPELESS or similar */
>         buffer.bind = bind;
>         buffer.usage = pipe_usage;
>         buffer.flags = pipe_flags;
>         buffer.width0 = size;
>         buffer.height0 = 1;
>         buffer.depth0 = 1;
>         buffer.array_size = 1;
>   
> -      if (target == GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD) {
> +      if (st_mem_obj) {
> +         st_obj->buffer = screen->resource_from_memobj(screen, &buffer,
> +                                                       st_mem_obj->memory,
> +                                                       offset);
> +      }
> +      else if (target == GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD) {
>            st_obj->buffer =
>               screen->resource_from_user_memory(screen, &buffer, (void*)data);
>         }
>         else {
>            st_obj->buffer = screen->resource_create(screen, &buffer);
>   
>            if (st_obj->buffer && data)
>               pipe_buffer_write(pipe, st_obj->buffer, 0, size, data);
>         }
>   
> @@ -345,20 +346,50 @@ st_bufferobj_data(struct gl_context *ctx,
>      if (st_obj->Base.UsageHistory & USAGE_SHADER_STORAGE_BUFFER)
>         ctx->NewDriverState |= ST_NEW_STORAGE_BUFFER;
>      if (st_obj->Base.UsageHistory & USAGE_TEXTURE_BUFFER)
>         ctx->NewDriverState |= ST_NEW_SAMPLER_VIEWS | ST_NEW_IMAGE_UNITS;
>      if (st_obj->Base.UsageHistory & USAGE_ATOMIC_COUNTER_BUFFER)
>         ctx->NewDriverState |= ST_NEW_ATOMIC_BUFFER;
>   
>      return GL_TRUE;
>   }
>   
> +/**
> + * Allocate space for and store data in a buffer object.  Any data that was
> + * previously stored in the buffer object is lost.  If data is NULL,
> + * memory will be allocated, but no copy will occur.
> + * Called via ctx->Driver.BufferData().
> + * \return GL_TRUE for success, GL_FALSE if out of memory
> + */
> +static GLboolean
> +st_bufferobj_data(struct gl_context *ctx,
> +                  GLenum target,
> +                  GLsizeiptrARB size,
> +                  const void *data,
> +                  GLenum usage,
> +                  GLbitfield storageFlags,
> +                  struct gl_buffer_object *obj)
> +{
> +   return bufferobj_data(ctx, target, size, data, NULL, 0, usage, storageFlags, obj);
> +}
> +
> +static GLboolean
> +st_bufferobj_data_mem(struct gl_context *ctx,
> +                      GLenum target,
> +                      GLsizeiptrARB size,
> +                      struct gl_memory_object *memObj,
> +                      GLuint64 offset,
> +                      GLenum usage,
> +                      struct gl_buffer_object *bufObj)
> +{
> +   return bufferobj_data(ctx, target, size, NULL, memObj, offset, usage, 0, bufObj);
> +}
>   
>   /**
>    * Called via glInvalidateBuffer(Sub)Data.
>    */
>   static void
>   st_bufferobj_invalidate(struct gl_context *ctx,
>                           struct gl_buffer_object *obj,
>                           GLintptr offset,
>                           GLsizeiptr size)
>   {
> @@ -579,20 +610,21 @@ st_bufferobj_page_commitment(struct gl_context *ctx,
>      }
>   }
>   
>   void
>   st_init_bufferobject_functions(struct pipe_screen *screen,
>                                  struct dd_function_table *functions)
>   {
>      functions->NewBufferObject = st_bufferobj_alloc;
>      functions->DeleteBuffer = st_bufferobj_free;
>      functions->BufferData = st_bufferobj_data;
> +   functions->BufferDataMem = st_bufferobj_data_mem;
>      functions->BufferSubData = st_bufferobj_subdata;
>      functions->GetBufferSubData = st_bufferobj_get_subdata;
>      functions->MapBufferRange = st_bufferobj_map_range;
>      functions->FlushMappedBufferRange = st_bufferobj_flush_mapped_range;
>      functions->UnmapBuffer = st_bufferobj_unmap;
>      functions->CopyBufferSubData = st_copy_buffer_subdata;
>      functions->ClearBufferSubData = st_clear_buffer_subdata;
>      functions->BufferPageCommitment = st_bufferobj_page_commitment;
>   
>      if (screen->get_param(screen, PIPE_CAP_INVALIDATE_BUFFER))
> 


More information about the mesa-dev mailing list