summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoris Brezillon <[email protected]>2019-07-02 13:21:55 +0200
committerBoris Brezillon <[email protected]>2019-07-02 14:58:51 +0200
commitc684a796692cd12d806dabb640ed277c530ef6f2 (patch)
tree08731bc35d16e824d4fb61536183d215500b94cc
parent948fddfc4294a7d5e93b2e1d76ad0058cd9e9889 (diff)
panfrost: Add the panfrost_drm_{create,release}_bo() helpers
To avoid the panfrost_memory <-> panfrost_bo dance done in panfrost_resource_create_bo() and panfrost_bo_unreference(). Signed-off-by: Boris Brezillon <[email protected]>
-rw-r--r--src/gallium/drivers/panfrost/pan_drm.c62
-rw-r--r--src/gallium/drivers/panfrost/pan_resource.c32
-rw-r--r--src/gallium/drivers/panfrost/pan_screen.h5
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 b21005feaeb..d49c999e077 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 f86617f80c2..b651fcffb11 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 1a1eb2f8bf2..9bcea611428 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);