Add memory object support for nvc0 and nv50 Signed-off-by: Miguel A Vico Moya <mvicom...@nvidia.com> --- .../drivers/nouveau/nv50/nv50_miptree.c | 49 +++++++++++++---- .../drivers/nouveau/nv50/nv50_resource.c | 52 +++++++++++++++++++ .../drivers/nouveau/nv50/nv50_resource.h | 33 ++++++++++++ .../drivers/nouveau/nvc0/nvc0_resource.c | 22 ++++++++ 4 files changed, 146 insertions(+), 10 deletions(-)
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_miptree.c b/src/gallium/drivers/nouveau/nv50/nv50_miptree.c index f2e304fde6..91007d3dac 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_miptree.c @@ -397,13 +397,13 @@ nv50_miptree_create(struct pipe_screen *pscreen, return pt; } -struct pipe_resource * -nv50_miptree_from_handle(struct pipe_screen *pscreen, - const struct pipe_resource *templ, - struct winsys_handle *whandle) +static struct pipe_resource * +nv50_miptree_from_bo(struct pipe_screen *pscreen, + const struct pipe_resource *templ, + struct nouveau_bo *bo, + uint32_t stride) { struct nv50_miptree *mt; - unsigned stride; /* only supports 2D, non-mipmapped textures for the moment */ if ((templ->target != PIPE_TEXTURE_2D && @@ -417,11 +417,8 @@ nv50_miptree_from_handle(struct pipe_screen *pscreen, if (!mt) return NULL; - mt->base.bo = nouveau_screen_bo_from_handle(pscreen, whandle, &stride); - if (mt->base.bo == NULL) { - FREE(mt); - return NULL; - } + nouveau_bo_ref(bo, &mt->base.bo); + mt->base.domain = mt->base.bo->flags & NOUVEAU_BO_APER; mt->base.address = mt->base.bo->offset; @@ -439,6 +436,38 @@ nv50_miptree_from_handle(struct pipe_screen *pscreen, return &mt->base.base; } +struct pipe_resource * +nv50_miptree_from_handle(struct pipe_screen *pscreen, + const struct pipe_resource *templ, + struct winsys_handle *whandle) +{ + struct pipe_resource *resource; + struct nouveau_bo *bo; + uint32_t stride; + + bo = nouveau_screen_bo_from_handle(pscreen, whandle, &stride); + if (bo == NULL) { + return NULL; + } + + resource = nv50_miptree_from_bo(pscreen, templ, bo, stride); + + /* nv50_miptree_from_bo will increment bo's refcount if succeeded */ + nouveau_bo_ref(NULL, &bo); + + return resource; +} + +struct pipe_resource * +nv50_miptree_from_memobj(struct pipe_screen *pscreen, + const struct pipe_resource *templ, + struct pipe_memory_object *memobj) +{ + struct nv50_memory_object *mo = nv50_memory_object(memobj); + + return nv50_miptree_from_bo(pscreen, templ, mo->bo, mo->stride); +} + /* Offset of zslice @z from start of level @l. */ inline unsigned diff --git a/src/gallium/drivers/nouveau/nv50/nv50_resource.c b/src/gallium/drivers/nouveau/nv50/nv50_resource.c index aed8c6241d..2a93c8820e 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_resource.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_resource.c @@ -91,6 +91,55 @@ nv50_invalidate_resource(struct pipe_context *pipe, struct pipe_resource *res) nouveau_buffer_invalidate(pipe, res); } +struct pipe_resource * +nv50_resource_from_memobj(struct pipe_screen *screen, + const struct pipe_resource *templ, + struct pipe_memory_object *memobj, + uint64_t offset) +{ + if (offset != 0) { + debug_printf("%s: attempt to import unsupported winsys offset %lu\n", + __FUNCTION__, offset); + return NULL; + } + + if (templ->target == PIPE_BUFFER) + return NULL; + else + return nv50_miptree_from_memobj(screen, templ, memobj); +} + +struct pipe_memory_object * +nv50_memobj_from_handle(struct pipe_screen *screen, + struct winsys_handle *whandle, + bool dedicated) +{ + struct nv50_memory_object *mo; + + mo = CALLOC_STRUCT(nv50_memory_object); + if (!mo) + return NULL; + + mo->bo = nouveau_screen_bo_from_handle(screen, whandle, &mo->stride); + if (mo->bo == NULL) { + FREE(mo); + return NULL; + } + mo->base.dedicated = dedicated; + + return &mo->base; +} + +void +nv50_memobj_destroy(struct pipe_screen *screen, + struct pipe_memory_object *memobj) +{ + struct nv50_memory_object *mo = nv50_memory_object(memobj); + + nouveau_bo_ref(NULL, &mo->bo); + FREE(mo); +} + void nv50_init_resource_functions(struct pipe_context *pcontext) { @@ -111,4 +160,7 @@ nv50_screen_init_resource_functions(struct pipe_screen *pscreen) pscreen->resource_from_handle = nv50_resource_from_handle; pscreen->resource_get_handle = u_resource_get_handle_vtbl; pscreen->resource_destroy = u_resource_destroy_vtbl; + pscreen->resource_from_memobj = nv50_resource_from_memobj; + pscreen->memobj_create_from_handle = nv50_memobj_from_handle; + pscreen->memobj_destroy = nv50_memobj_destroy; } diff --git a/src/gallium/drivers/nouveau/nv50/nv50_resource.h b/src/gallium/drivers/nouveau/nv50/nv50_resource.h index 5d03925b0d..f2bbbe7e48 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_resource.h +++ b/src/gallium/drivers/nouveau/nv50/nv50_resource.h @@ -85,6 +85,11 @@ nv50_miptree_from_handle(struct pipe_screen *pscreen, const struct pipe_resource *template, struct winsys_handle *whandle); +struct pipe_resource * +nv50_miptree_from_memobj(struct pipe_screen *pscreen, + const struct pipe_resource *templ, + struct pipe_memory_object *memobj); + boolean nv50_miptree_get_handle(struct pipe_screen *pscreen, struct pipe_resource *pt, @@ -116,6 +121,34 @@ nv50_zs_to_s_format(enum pipe_format format) } } +struct nv50_memory_object { + struct pipe_memory_object base; + + struct nouveau_bo *bo; + uint32_t stride; +}; + +static inline struct nv50_memory_object * +nv50_memory_object(struct pipe_memory_object *pt) +{ + return (struct nv50_memory_object *)pt; +} + +struct pipe_resource * +nv50_resource_from_memobj(struct pipe_screen *screen, + const struct pipe_resource *templ, + struct pipe_memory_object *memobj, + uint64_t offset); + +struct pipe_memory_object * +nv50_memobj_from_handle(struct pipe_screen *screen, + struct winsys_handle *whandle, + bool dedicated); + +void +nv50_memobj_destroy(struct pipe_screen *screen, + struct pipe_memory_object *memobj); + #ifndef __NVC0_RESOURCE_H__ unsigned diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c index ec6257a896..cd283b58db 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c @@ -98,6 +98,25 @@ nvc0_surface_create(struct pipe_context *pipe, return nvc0_miptree_surface_new(pipe, pres, templ); } +static struct pipe_resource * +nvc0_resource_from_memobj(struct pipe_screen *screen, + const struct pipe_resource *templ, + struct pipe_memory_object *memobj, + uint64_t offset) +{ + if (templ->target == PIPE_BUFFER) { + return NULL; + } else { + struct pipe_resource *res; + + res = nv50_resource_from_memobj(screen, templ, memobj, offset); + if (res) + nv04_resource(res)->vtbl = &nvc0_miptree_vtbl; + + return res; + } +} + void nvc0_init_resource_functions(struct pipe_context *pcontext) { @@ -120,4 +139,7 @@ nvc0_screen_init_resource_functions(struct pipe_screen *pscreen) pscreen->resource_from_handle = nvc0_resource_from_handle; pscreen->resource_get_handle = u_resource_get_handle_vtbl; pscreen->resource_destroy = u_resource_destroy_vtbl; + pscreen->resource_from_memobj = nvc0_resource_from_memobj; + pscreen->memobj_create_from_handle = nv50_memobj_from_handle; + pscreen->memobj_destroy = nv50_memobj_destroy; } -- 2.17.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev