diff --git a/src/gallium/drivers/ddebug/dd_screen.c b/src/gallium/drivers/ddebug/dd_screen.c index 14e6f6b011f..51382da1d73 100644 --- a/src/gallium/drivers/ddebug/dd_screen.c +++ b/src/gallium/drivers/ddebug/dd_screen.c @@ -245,6 +245,22 @@ dd_screen_resource_from_user_memory(struct pipe_screen *_screen, return res; } +static struct pipe_resource * +dd_screen_resource_from_memobj(struct pipe_screen *_screen, + const struct pipe_resource *templ, + struct pipe_memory_object *memobj, + uint64_t offset) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + struct pipe_resource *res = + screen->resource_from_memobj(screen, templ, memobj, offset); + + if (!res) + return NULL; + res->screen = _screen; + return res; +} + static void dd_screen_resource_changed(struct pipe_screen *_screen, struct pipe_resource *res) @@ -303,7 +319,28 @@ dd_screen_fence_finish(struct pipe_screen *_screen, return screen->fence_finish(screen, ctx, fence, timeout); } +/******************************************************************** + * memobj + */ +static struct pipe_memory_object * +dd_screen_memobj_create_from_handle(struct pipe_screen *_screen, + struct winsys_handle *handle, + bool dedicated) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + return screen->memobj_create_from_handle(screen, handle, dedicated); +} + +static void +dd_screen_memobj_destroy(struct pipe_screen *_screen, + struct pipe_memory_object *memobj) +{ + struct pipe_screen *screen = dd_screen(_screen)->screen; + + screen->memobj_destroy(screen, memobj); +} /******************************************************************** * screen */ @@ -412,6 +449,7 @@ ddebug_screen_create(struct pipe_screen *screen) SCR_INIT(can_create_resource); dscreen->base.resource_create = dd_screen_resource_create; dscreen->base.resource_from_handle = dd_screen_resource_from_handle; + SCR_INIT(resource_from_memobj); SCR_INIT(resource_from_user_memory); dscreen->base.resource_get_handle = dd_screen_resource_get_handle; SCR_INIT(resource_changed); @@ -419,6 +457,8 @@ ddebug_screen_create(struct pipe_screen *screen) SCR_INIT(flush_frontbuffer); SCR_INIT(fence_reference); SCR_INIT(fence_finish); + SCR_INIT(memobj_create_from_handle); + SCR_INIT(memobj_destroy); SCR_INIT(get_driver_query_info); SCR_INIT(get_driver_query_group_info); SCR_INIT(get_compiler_options); diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index e56434c5bda..c499aa69804 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -367,6 +367,32 @@ trace_screen_resource_get_handle(struct pipe_screen *_screen, resource, handle, usage); } +static struct pipe_resource * +trace_screen_resource_from_memobj(struct pipe_screen *_screen, + const struct pipe_resource *templ, + struct pipe_memory_object *memobj, + uint64_t offset) +{ + struct pipe_screen *screen = trace_screen(_screen)->screen; + + trace_dump_call_begin("pipe_screen", "resource_from_memobj"); + trace_dump_arg(ptr, screen); + trace_dump_arg(resource_template, templ); + trace_dump_arg(ptr, memobj); + trace_dump_arg(uint, offset); + + struct pipe_resource *res = + screen->resource_from_memobj(screen, templ, memobj, offset); + + if (!res) + return NULL; + res->screen = _screen; + + trace_dump_ret(ptr, res); + trace_dump_call_end(); + return res; +} + static void trace_screen_resource_changed(struct pipe_screen *_screen, struct pipe_resource *resource) @@ -456,6 +482,46 @@ trace_screen_fence_finish(struct pipe_screen *_screen, } +/******************************************************************** + * memobj + */ + +static struct pipe_memory_object * +trace_screen_memobj_create_from_handle(struct pipe_screen *_screen, + struct winsys_handle *handle, + bool dedicated) +{ + struct pipe_screen *screen = trace_screen(_screen)->screen; + + trace_dump_call_begin("pipe_screen", "memobj_create_from_handle"); + trace_dump_arg(ptr, screen); + trace_dump_arg(ptr, handle); + trace_dump_arg(bool, dedicated); + + struct pipe_memory_object *res = + screen->memobj_create_from_handle(screen, handle, dedicated); + + trace_dump_ret(ptr, res); + trace_dump_call_end(); + + return res; +} + +static void +trace_screen_memobj_destroy(struct pipe_screen *_screen, + struct pipe_memory_object *memobj) +{ + struct pipe_screen *screen = trace_screen(_screen)->screen; + + trace_dump_call_begin("pipe_screen", "memobj_destroy"); + trace_dump_arg(ptr, screen); + trace_dump_arg(ptr, memobj); + trace_dump_call_end(); + + screen->memobj_destroy(screen, memobj); +} + + /******************************************************************** * screen */ @@ -542,10 +608,13 @@ trace_screen_create(struct pipe_screen *screen) tr_scr->base.resource_create = trace_screen_resource_create; tr_scr->base.resource_from_handle = trace_screen_resource_from_handle; tr_scr->base.resource_get_handle = trace_screen_resource_get_handle; + SCR_INIT(resource_from_memobj); SCR_INIT(resource_changed); tr_scr->base.resource_destroy = trace_screen_resource_destroy; tr_scr->base.fence_reference = trace_screen_fence_reference; tr_scr->base.fence_finish = trace_screen_fence_finish; + SCR_INIT(memobj_create_from_handle); + SCR_INIT(memobj_destroy); tr_scr->base.flush_frontbuffer = trace_screen_flush_frontbuffer; tr_scr->base.get_timestamp = trace_screen_get_timestamp; diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index b6623d1dd71..462b683cd75 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -358,6 +358,42 @@ struct pipe_screen { enum pipe_format format, int max, uint64_t *modifiers, unsigned int *external_only, int *count); + + /** + * Create a memory object from a winsys handle + * + * The underlying memory is most often allocated in by a foregin API. + * Then the underlying memory object is then exported through interfaces + * compatible with EXT_external_resources. + * + * Note: For DRM_API_HANDLE_TYPE_FD handles, the caller retains ownership + * of the fd. + * + * \param handle A handle representing the memory object to import + */ + struct pipe_memory_object *(*memobj_create_from_handle)(struct pipe_screen *screen, + struct winsys_handle *handle, + bool dedicated); + + /** + * Destroy a memory object + * + * \param memobj The memory object to destroy + */ + void (*memobj_destroy)(struct pipe_screen *screen, + struct pipe_memory_object *memobj); + + /** + * Create a texture from a memory object + * + * \param t texture template + * \param memobj The memory object used to back the texture + */ + struct pipe_resource * (*resource_from_memobj)(struct pipe_screen *screen, + const struct pipe_resource *t, + struct pipe_memory_object *memobj, + uint64_t offset); + }; diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 15be8cb5d02..86c7751eb18 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -888,6 +888,14 @@ struct pipe_memory_info unsigned nr_device_memory_evictions; /**< # of evictions (monotonic counter) */ }; +/** + * Structure that contains information about external memory + */ +struct pipe_memory_object +{ + bool dedicated; +}; + #ifdef __cplusplus } #endif