diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2022-06-06 12:14:08 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2022-06-06 12:14:08 +0000 |
commit | 2bd8150b39195449b9473a7afa51dc88f7650b60 (patch) | |
tree | 30fcb5c94c1562113321613766c363a54d607b79 /lib/libdrm/tegra/tegra.c | |
parent | 3c012d229d655ce7ec8da541464f38b441b1ae3d (diff) |
Import libdrm 2.4.111
Diffstat (limited to 'lib/libdrm/tegra/tegra.c')
-rw-r--r-- | lib/libdrm/tegra/tegra.c | 386 |
1 files changed, 208 insertions, 178 deletions
diff --git a/lib/libdrm/tegra/tegra.c b/lib/libdrm/tegra/tegra.c index 420b171c5..6a51c4311 100644 --- a/lib/libdrm/tegra/tegra.c +++ b/lib/libdrm/tegra/tegra.c @@ -37,288 +37,318 @@ static void drm_tegra_bo_free(struct drm_tegra_bo *bo) { - struct drm_tegra *drm = bo->drm; + struct drm_tegra *drm = bo->drm; - if (bo->map) - munmap(bo->map, bo->size); + if (bo->map) + munmap(bo->map, bo->size); - drmCloseBufferHandle(drm->fd, bo->handle); + drmCloseBufferHandle(drm->fd, bo->handle); - free(bo); + free(bo); } static int drm_tegra_wrap(struct drm_tegra **drmp, int fd, bool close) { - struct drm_tegra *drm; + struct drm_tegra *drm; - if (fd < 0 || !drmp) - return -EINVAL; + if (fd < 0 || !drmp) + return -EINVAL; - drm = calloc(1, sizeof(*drm)); - if (!drm) - return -ENOMEM; + drm = calloc(1, sizeof(*drm)); + if (!drm) + return -ENOMEM; - drm->close = close; - drm->fd = fd; + drm->close = close; + drm->fd = fd; - *drmp = drm; + *drmp = drm; - return 0; + return 0; } -drm_public int drm_tegra_new(struct drm_tegra **drmp, int fd) +drm_public int drm_tegra_new(int fd, struct drm_tegra **drmp) { - bool supported = false; - drmVersionPtr version; + bool supported = false; + drmVersionPtr version; - version = drmGetVersion(fd); - if (!version) - return -ENOMEM; + version = drmGetVersion(fd); + if (!version) + return -ENOMEM; - if (!strncmp(version->name, "tegra", version->name_len)) - supported = true; + if (!strncmp(version->name, "tegra", version->name_len)) + supported = true; - drmFreeVersion(version); + drmFreeVersion(version); - if (!supported) - return -ENOTSUP; + if (!supported) + return -ENOTSUP; - return drm_tegra_wrap(drmp, fd, false); + return drm_tegra_wrap(drmp, fd, false); } drm_public void drm_tegra_close(struct drm_tegra *drm) { - if (!drm) - return; + if (!drm) + return; - if (drm->close) - close(drm->fd); + if (drm->close) + close(drm->fd); - free(drm); + free(drm); } -drm_public int drm_tegra_bo_new(struct drm_tegra_bo **bop, struct drm_tegra *drm, - uint32_t flags, uint32_t size) +static struct drm_tegra_bo *drm_tegra_bo_alloc(struct drm_tegra *drm, + uint32_t handle, + uint32_t flags, + uint32_t size) { - struct drm_tegra_gem_create args; - struct drm_tegra_bo *bo; - int err; + struct drm_tegra_bo *bo; - if (!drm || size == 0 || !bop) - return -EINVAL; + bo = calloc(1, sizeof(*bo)); + if (!bo) + return NULL; - bo = calloc(1, sizeof(*bo)); - if (!bo) - return -ENOMEM; + atomic_set(&bo->ref, 1); + bo->handle = handle; + bo->flags = flags; + bo->size = size; + bo->drm = drm; - atomic_set(&bo->ref, 1); - bo->flags = flags; - bo->size = size; - bo->drm = drm; + return bo; +} + +drm_public int +drm_tegra_bo_new(struct drm_tegra *drm, uint32_t flags, uint32_t size, + struct drm_tegra_bo **bop) +{ + struct drm_tegra_gem_create args; + struct drm_tegra_bo *bo; + int err; + + if (!drm || size == 0 || !bop) + return -EINVAL; + + bo = drm_tegra_bo_alloc(drm, 0, flags, size); + if (!bo) + return -ENOMEM; - memset(&args, 0, sizeof(args)); - args.flags = flags; - args.size = size; + memset(&args, 0, sizeof(args)); + args.flags = flags; + args.size = size; - err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_CREATE, &args, - sizeof(args)); - if (err < 0) { - err = -errno; - free(bo); - return err; - } + err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_CREATE, &args, + sizeof(args)); + if (err < 0) { + err = -errno; + free(bo); + return err; + } - bo->handle = args.handle; + bo->handle = args.handle; - *bop = bo; + *bop = bo; - return 0; + return 0; } -drm_public int drm_tegra_bo_wrap(struct drm_tegra_bo **bop, struct drm_tegra *drm, - uint32_t handle, uint32_t flags, uint32_t size) +drm_public int +drm_tegra_bo_wrap(struct drm_tegra *drm, uint32_t handle, uint32_t flags, + uint32_t size, struct drm_tegra_bo **bop) { - struct drm_tegra_bo *bo; + struct drm_tegra_bo *bo; - if (!drm || !bop) - return -EINVAL; + if (!drm || !bop) + return -EINVAL; - bo = calloc(1, sizeof(*bo)); - if (!bo) - return -ENOMEM; + bo = drm_tegra_bo_alloc(drm, handle, flags, size); + if (!bo) + return -ENOMEM; - atomic_set(&bo->ref, 1); - bo->handle = handle; - bo->flags = flags; - bo->size = size; - bo->drm = drm; + *bop = bo; - *bop = bo; - - return 0; + return 0; } drm_public struct drm_tegra_bo *drm_tegra_bo_ref(struct drm_tegra_bo *bo) { - if (bo) - atomic_inc(&bo->ref); + if (bo) + atomic_inc(&bo->ref); - return bo; + return bo; } drm_public void drm_tegra_bo_unref(struct drm_tegra_bo *bo) { - if (bo && atomic_dec_and_test(&bo->ref)) - drm_tegra_bo_free(bo); + if (bo && atomic_dec_and_test(&bo->ref)) + drm_tegra_bo_free(bo); } -drm_public int drm_tegra_bo_get_handle(struct drm_tegra_bo *bo, uint32_t *handle) +drm_public int +drm_tegra_bo_get_handle(struct drm_tegra_bo *bo, uint32_t *handle) { - if (!bo || !handle) - return -EINVAL; + if (!bo || !handle) + return -EINVAL; - *handle = bo->handle; + *handle = bo->handle; - return 0; + return 0; } drm_public int drm_tegra_bo_map(struct drm_tegra_bo *bo, void **ptr) { - struct drm_tegra *drm = bo->drm; + struct drm_tegra *drm = bo->drm; - if (!bo->map) { - struct drm_tegra_gem_mmap args; - int err; + if (!bo->map) { + struct drm_tegra_gem_mmap args; + int err; - memset(&args, 0, sizeof(args)); - args.handle = bo->handle; + memset(&args, 0, sizeof(args)); + args.handle = bo->handle; - err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_MMAP, &args, - sizeof(args)); - if (err < 0) - return -errno; + err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_MMAP, &args, + sizeof(args)); + if (err < 0) + return -errno; - bo->offset = args.offset; + bo->offset = args.offset; - bo->map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, - drm->fd, bo->offset); - if (bo->map == MAP_FAILED) { - bo->map = NULL; - return -errno; - } - } + bo->map = drm_mmap(NULL, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, + drm->fd, bo->offset); + if (bo->map == MAP_FAILED) { + bo->map = NULL; + return -errno; + } + } - if (ptr) - *ptr = bo->map; + if (ptr) + *ptr = bo->map; - return 0; + return 0; } drm_public int drm_tegra_bo_unmap(struct drm_tegra_bo *bo) { - if (!bo) - return -EINVAL; + if (!bo) + return -EINVAL; - if (!bo->map) - return 0; + if (!bo->map) + return 0; - if (munmap(bo->map, bo->size)) - return -errno; + if (munmap(bo->map, bo->size)) + return -errno; - bo->map = NULL; + bo->map = NULL; - return 0; + return 0; } -drm_public int drm_tegra_bo_get_flags(struct drm_tegra_bo *bo, uint32_t *flags) +drm_public int drm_tegra_bo_get_name(struct drm_tegra_bo *bo, uint32_t *name) { - struct drm_tegra_gem_get_flags args; - struct drm_tegra *drm = bo->drm; - int err; - - if (!bo) - return -EINVAL; + struct drm_tegra *drm = bo->drm; + struct drm_gem_flink args; + int err; - memset(&args, 0, sizeof(args)); - args.handle = bo->handle; + memset(&args, 0, sizeof(args)); + args.handle = bo->handle; - err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_GET_FLAGS, &args, - sizeof(args)); - if (err < 0) - return -errno; + err = drmIoctl(drm->fd, DRM_IOCTL_GEM_FLINK, &args); + if (err < 0) + return err; - if (flags) - *flags = args.flags; + if (name) + *name = args.name; - return 0; + return 0; } -drm_public int drm_tegra_bo_set_flags(struct drm_tegra_bo *bo, uint32_t flags) +drm_public int +drm_tegra_bo_open(struct drm_tegra *drm, uint32_t name, uint32_t flags, + struct drm_tegra_bo **bop) { - struct drm_tegra_gem_get_flags args; - struct drm_tegra *drm = bo->drm; - int err; + struct drm_gem_open args; + struct drm_tegra_bo *bo; + int err; + + bo = drm_tegra_bo_alloc(drm, 0, flags, 0); + if (!bo) + return -ENOMEM; + + memset(&args, 0, sizeof(args)); + args.name = name; - if (!bo) - return -EINVAL; + err = drmIoctl(drm->fd, DRM_IOCTL_GEM_OPEN, &args); + if (err < 0) + goto free; - memset(&args, 0, sizeof(args)); - args.handle = bo->handle; - args.flags = flags; + bo->handle = args.handle; + bo->size = args.size; - err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_SET_FLAGS, &args, - sizeof(args)); - if (err < 0) - return -errno; + *bop = bo; - return 0; + return 0; + +free: + free(bo); + return err; } -drm_public int drm_tegra_bo_get_tiling(struct drm_tegra_bo *bo, - struct drm_tegra_bo_tiling *tiling) +drm_public int drm_tegra_bo_export(struct drm_tegra_bo *bo, uint32_t flags) { - struct drm_tegra_gem_get_tiling args; - struct drm_tegra *drm = bo->drm; - int err; + int fd, err; + + flags |= DRM_CLOEXEC; + + err = drmPrimeHandleToFD(bo->drm->fd, bo->handle, flags, &fd); + if (err < 0) + return err; + + return fd; +} - if (!bo) - return -EINVAL; +static ssize_t fd_get_size(int fd) +{ + ssize_t size, offset; + int err; - memset(&args, 0, sizeof(args)); - args.handle = bo->handle; + offset = lseek(fd, 0, SEEK_CUR); + if (offset < 0) + return -errno; - err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_GET_TILING, &args, - sizeof(args)); - if (err < 0) - return -errno; + size = lseek(fd, 0, SEEK_END); + if (size < 0) + return -errno; - if (tiling) { - tiling->mode = args.mode; - tiling->value = args.value; - } + err = lseek(fd, offset, SEEK_SET); + if (err < 0) + return -errno; - return 0; + return size; } -drm_public int drm_tegra_bo_set_tiling(struct drm_tegra_bo *bo, - const struct drm_tegra_bo_tiling *tiling) +drm_public int +drm_tegra_bo_import(struct drm_tegra *drm, int fd, struct drm_tegra_bo **bop) { - struct drm_tegra_gem_set_tiling args; - struct drm_tegra *drm = bo->drm; - int err; + struct drm_tegra_bo *bo; + ssize_t size; + int err; + + size = fd_get_size(fd); + if (size < 0) + return size; + + bo = drm_tegra_bo_alloc(drm, 0, 0, size); + if (!bo) + return -ENOMEM; - if (!bo) - return -EINVAL; + err = drmPrimeFDToHandle(drm->fd, fd, &bo->handle); + if (err < 0) + goto free; - memset(&args, 0, sizeof(args)); - args.handle = bo->handle; - args.mode = tiling->mode; - args.value = tiling->value; + *bop = bo; - err = drmCommandWriteRead(drm->fd, DRM_TEGRA_GEM_SET_TILING, &args, - sizeof(args)); - if (err < 0) - return -errno; + return 0; - return 0; +free: + free(bo); + return err; } |