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 <boris.brezillon@collabora.com>
This commit is contained in:
@@ -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);
|
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
|
void
|
||||||
panfrost_drm_allocate_slab(struct panfrost_screen *screen,
|
panfrost_drm_allocate_slab(struct panfrost_screen *screen,
|
||||||
struct panfrost_memory *mem,
|
struct panfrost_memory *mem,
|
||||||
|
@@ -391,18 +391,7 @@ panfrost_resource_create_bo(struct panfrost_screen *screen, struct panfrost_reso
|
|||||||
size_t bo_size;
|
size_t bo_size;
|
||||||
|
|
||||||
panfrost_setup_slices(pres, &bo_size);
|
panfrost_setup_slices(pres, &bo_size);
|
||||||
|
pres->bo = panfrost_drm_create_bo(screen, bo_size, 0);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pipe_resource *
|
static struct pipe_resource *
|
||||||
@@ -442,20 +431,6 @@ panfrost_resource_create(struct pipe_screen *screen,
|
|||||||
return (struct pipe_resource *)so;
|
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
|
void
|
||||||
panfrost_bo_reference(struct panfrost_bo *bo)
|
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 */
|
/* When the reference count goes to zero, we need to cleanup */
|
||||||
|
|
||||||
if (pipe_reference(&bo->reference, NULL)) {
|
if (pipe_reference(&bo->reference, NULL))
|
||||||
panfrost_destroy_bo(pan_screen(screen), bo);
|
panfrost_drm_release_bo(pan_screen(screen), bo);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@@ -83,6 +83,11 @@ void
|
|||||||
panfrost_drm_free_slab(struct panfrost_screen *screen,
|
panfrost_drm_free_slab(struct panfrost_screen *screen,
|
||||||
struct panfrost_memory *mem);
|
struct panfrost_memory *mem);
|
||||||
struct panfrost_bo *
|
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);
|
panfrost_drm_import_bo(struct panfrost_screen *screen, int fd);
|
||||||
int
|
int
|
||||||
panfrost_drm_export_bo(struct panfrost_screen *screen, const struct panfrost_bo *bo);
|
panfrost_drm_export_bo(struct panfrost_screen *screen, const struct panfrost_bo *bo);
|
||||||
|
Reference in New Issue
Block a user