[Mesa-dev] [PATCH 08/10] panfrost: Add the panfrost_drm_{create, release}_bo() helpers

Boris Brezillon boris.brezillon at collabora.com
Tue Jul 2 13:23:51 UTC 2019


To avoid the panfrost_memory <-> panfrost_bo dance done in
panfrost_resource_create_bo() and panfrost_bo_unreference().

Signed-off-by: Boris Brezillon <boris.brezillon at collabora.com>
---
 src/gallium/drivers/panfrost/pan_drm.c      | 62 +++++++++++++++++++++
 src/gallium/drivers/panfrost/pan_resource.c | 32 +----------
 src/gallium/drivers/panfrost/pan_screen.h   |  5 ++
 3 files changed, 70 insertions(+), 29 deletions(-)

diff --git a/src/gallium/drivers/panfrost/pan_drm.c b/src/gallium/drivers/panfrost/pan_drm.c
index b21005feaebb..d49c999e0773 100644
--- a/src/gallium/drivers/panfrost/pan_drm.c
+++ b/src/gallium/drivers/panfrost/pan_drm.c
@@ -65,6 +65,68 @@ panfrost_drm_mmap_bo(struct panfrost_screen *screen, struct panfrost_bo *bo)
                 pandecode_inject_mmap(bo->gpu, bo->cpu, bo->size, NULL);
 }
 
+static void
+panfrost_drm_munmap_bo(struct panfrost_screen *screen, struct panfrost_bo *bo)
+{
+        if (!bo->cpu)
+                return;
+
+        if (os_munmap((void *) (uintptr_t)bo->cpu, bo->size)) {
+                perror("munmap");
+                abort();
+        }
+
+        bo->cpu = NULL;
+}
+
+struct panfrost_bo *
+panfrost_drm_create_bo(struct panfrost_screen *screen, size_t size,
+                       uint32_t flags)
+{
+        struct panfrost_bo *bo = rzalloc(screen, struct panfrost_bo);
+        struct drm_panfrost_create_bo create_bo = {
+                .size = size,
+                .flags = flags,
+        };
+        int ret;
+
+        ret = drmIoctl(screen->fd, DRM_IOCTL_PANFROST_CREATE_BO, &create_bo);
+        if (ret) {
+                fprintf(stderr, "DRM_IOCTL_PANFROST_CREATE_BO failed: %d\n", ret);
+                assert(0);
+        }
+
+        bo->size = create_bo.size;
+        bo->gpu = create_bo.offset;
+        bo->gem_handle = create_bo.handle;
+
+        // TODO map and unmap on demand?
+        panfrost_drm_mmap_bo(screen, bo);
+
+        pipe_reference_init(&bo->reference, 1);
+        return bo;
+}
+
+void
+panfrost_drm_release_bo(struct panfrost_screen *screen, struct panfrost_bo *bo)
+{
+        struct drm_gem_close gem_close = { .handle = bo->gem_handle };
+        int ret;
+
+        if (!bo)
+                return;
+
+        panfrost_drm_munmap_bo(screen, bo);
+
+        ret = drmIoctl(screen->fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
+        if (ret) {
+                fprintf(stderr, "DRM_IOCTL_GEM_CLOSE failed: %d\n", ret);
+                assert(0);
+        }
+
+        ralloc_free(bo);
+}
+
 void
 panfrost_drm_allocate_slab(struct panfrost_screen *screen,
 		           struct panfrost_memory *mem,
diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c
index f86617f80c20..b651fcffb111 100644
--- a/src/gallium/drivers/panfrost/pan_resource.c
+++ b/src/gallium/drivers/panfrost/pan_resource.c
@@ -391,18 +391,7 @@ panfrost_resource_create_bo(struct panfrost_screen *screen, struct panfrost_reso
         size_t bo_size;
 
         panfrost_setup_slices(pres, &bo_size);
-
-        struct panfrost_memory mem;
-        struct panfrost_bo *bo = rzalloc(screen, struct panfrost_bo);
-
-        pipe_reference_init(&bo->reference, 1);
-        panfrost_drm_allocate_slab(screen, &mem, bo_size / 4096, true, 0, 0, 0);
-
-        bo->cpu = mem.cpu;
-        bo->gpu = mem.gpu;
-        bo->gem_handle = mem.gem_handle;
-	bo->size = bo_size;
-	pres->bo = bo;
+        pres->bo = panfrost_drm_create_bo(screen, bo_size, 0);
 }
 
 static struct pipe_resource *
@@ -442,20 +431,6 @@ panfrost_resource_create(struct pipe_screen *screen,
         return (struct pipe_resource *)so;
 }
 
-static void
-panfrost_destroy_bo(struct panfrost_screen *screen, struct panfrost_bo *bo)
-{
-        struct panfrost_memory mem = {
-                .cpu = bo->cpu,
-                .gpu = bo->gpu,
-                .size = bo->size,
-                .gem_handle = bo->gem_handle,
-        };
-
-        panfrost_drm_free_slab(screen, &mem);
-        ralloc_free(bo);
-}
-
 void
 panfrost_bo_reference(struct panfrost_bo *bo)
 {
@@ -467,9 +442,8 @@ panfrost_bo_unreference(struct pipe_screen *screen, struct panfrost_bo *bo)
 {
         /* When the reference count goes to zero, we need to cleanup */
 
-        if (pipe_reference(&bo->reference, NULL)) {
-                panfrost_destroy_bo(pan_screen(screen), bo);
-        }
+        if (pipe_reference(&bo->reference, NULL))
+                panfrost_drm_release_bo(pan_screen(screen), bo);
 }
 
 static void
diff --git a/src/gallium/drivers/panfrost/pan_screen.h b/src/gallium/drivers/panfrost/pan_screen.h
index 1a1eb2f8bf27..9bcea6114285 100644
--- a/src/gallium/drivers/panfrost/pan_screen.h
+++ b/src/gallium/drivers/panfrost/pan_screen.h
@@ -83,6 +83,11 @@ void
 panfrost_drm_free_slab(struct panfrost_screen *screen,
                        struct panfrost_memory *mem);
 struct panfrost_bo *
+panfrost_drm_create_bo(struct panfrost_screen *screen, size_t size,
+                       uint32_t flags);
+void
+panfrost_drm_release_bo(struct panfrost_screen *screen, struct panfrost_bo *bo);
+struct panfrost_bo *
 panfrost_drm_import_bo(struct panfrost_screen *screen, int fd);
 int
 panfrost_drm_export_bo(struct panfrost_screen *screen, const struct panfrost_bo *bo);
-- 
2.21.0



More information about the mesa-dev mailing list