diff options
author | Boris Brezillon <[email protected]> | 2019-07-02 13:21:55 +0200 |
---|---|---|
committer | Boris Brezillon <[email protected]> | 2019-07-02 14:58:51 +0200 |
commit | c684a796692cd12d806dabb640ed277c530ef6f2 (patch) | |
tree | 08731bc35d16e824d4fb61536183d215500b94cc | |
parent | 948fddfc4294a7d5e93b2e1d76ad0058cd9e9889 (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.c | 62 | ||||
-rw-r--r-- | src/gallium/drivers/panfrost/pan_resource.c | 32 | ||||
-rw-r--r-- | 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 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); |