[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