From: Andres Rodriguez <andre...@gmail.com> Use a memory object instead of user memory.
Signed-off-by: Andres Rodriguez <andre...@gmail.com> Reviewed-by: Timothy Arceri <tarc...@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)) -- 2.13.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev