[Mesa-dev] [PATCH 1/2] nouveau: Add basic memory object support

Miguel A. Vico mvicomoya at nvidia.com
Fri Jun 22 02:01:45 UTC 2018


Add memory object support for nvc0 and nv50

Signed-off-by: Miguel A Vico Moya <mvicomoya at 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



More information about the mesa-dev mailing list