we need to import/export timeline point. v2: unify to one transfer ioctl
Unified · Split
| @@ -180,6 +180,8 @@ int drm_syncobj_handle_to_fd_ioctl(struct drm_device *dev, void *data, · 179 unmodified lines | |||
| 180 | struct drm_file *file_private); | 180 | struct drm_file *file_private); |
| 181 | int drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, void *data, | 181 | int drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, void *data, |
| 182 | struct drm_file *file_private); | 182 | struct drm_file *file_private); |
| 183 | int drm_syncobj_transfer_ioctl(struct drm_device *dev, void *data, | ||
| 184 | struct drm_file *file_private); | ||
| 183 | int drm_syncobj_wait_ioctl(struct drm_device *dev, void *data, | 185 | int drm_syncobj_wait_ioctl(struct drm_device *dev, void *data, |
| 184 | struct drm_file *file_private); | 186 | struct drm_file *file_private); |
| 185 | int drm_syncobj_timeline_wait_ioctl(struct drm_device *dev, void *data, | 187 | int drm_syncobj_timeline_wait_ioctl(struct drm_device *dev, void *data, |
| @@ -686,6 +686,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = { · 685 unmodified lines | |||
| 686 | DRM_UNLOCKED|DRM_RENDER_ALLOW), | 686 | DRM_UNLOCKED|DRM_RENDER_ALLOW), |
| 687 | DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, drm_syncobj_fd_to_handle_ioctl, | 687 | DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, drm_syncobj_fd_to_handle_ioctl, |
| 688 | DRM_UNLOCKED|DRM_RENDER_ALLOW), | 688 | DRM_UNLOCKED|DRM_RENDER_ALLOW), |
| 689 | DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TRANSFER, drm_syncobj_transfer_ioctl, | ||
| 690 | DRM_UNLOCKED|DRM_RENDER_ALLOW), | ||
| 689 | DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_WAIT, drm_syncobj_wait_ioctl, | 691 | DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_WAIT, drm_syncobj_wait_ioctl, |
| 690 | DRM_UNLOCKED|DRM_RENDER_ALLOW), | 692 | DRM_UNLOCKED|DRM_RENDER_ALLOW), |
| 691 | DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, drm_syncobj_timeline_wait_ioctl, | 693 | DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT, drm_syncobj_timeline_wait_ioctl, |
| @@ -680,6 +680,80 @@ drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, void *data, · 679 unmodified lines | |||
| 680 | &args->handle); | 680 | &args->handle); |
| 681 | } | 681 | } |
| 682 | 682 | ||
| 683 | static int drm_syncobj_transfer_to_timeline(struct drm_file *file_private, | ||
| 684 | struct drm_syncobj_transfer *args) | ||
| 685 | { | ||
| 686 | struct drm_syncobj *timeline_syncobj = NULL; | ||
| 687 | struct dma_fence *fence; | ||
| 688 | struct dma_fence_chain *chain; | ||
| 689 | int ret; | ||
| 690 | |||
| 691 | timeline_syncobj = drm_syncobj_find(file_private, args->dst_handle); | ||
| 692 | if (!timeline_syncobj) { | ||
| 693 | return -ENOENT; | ||
| 694 | } | ||
| 695 | ret = drm_syncobj_find_fence(file_private, args->src_handle, | ||
| 696 | args->src_point, args->flags, | ||
| 697 | &fence); | ||
| 698 | if (ret) | ||
| 699 | goto err; | ||
| 700 | chain = kzalloc(sizeof(struct dma_fence_chain), GFP_KERNEL); | ||
| 701 | if (!chain) { | ||
| 702 | ret = -ENOMEM; | ||
| 703 | goto err1; | ||
| 704 | } | ||
| 705 | drm_syncobj_add_point(timeline_syncobj, chain, fence, args->dst_point); | ||
| 706 | err1: | ||
| 707 | dma_fence_put(fence); | ||
| 708 | err: | ||
| 709 | drm_syncobj_put(timeline_syncobj); | ||
| 710 | |||
| 711 | return ret; | ||
| 712 | } | ||
| 713 | |||
| 714 | static int | ||
| 715 | drm_syncobj_transfer_to_binary(struct drm_file *file_private, | ||
| 716 | struct drm_syncobj_transfer *args) | ||
| 717 | { | ||
| 718 | struct drm_syncobj *binary_syncobj = NULL; | ||
| 719 | struct dma_fence *fence; | ||
| 720 | int ret; | ||
| 721 | |||
| 722 | binary_syncobj = drm_syncobj_find(file_private, args->dst_handle); | ||
| 723 | if (!binary_syncobj) | ||
| 724 | return -ENOENT; | ||
| 725 | ret = drm_syncobj_find_fence(file_private, args->src_handle, | ||
| 726 | args->src_point, args->flags, &fence); | ||
| 727 | if (ret) | ||
| 728 | goto err; | ||
| 729 | drm_syncobj_replace_fence(binary_syncobj, fence); | ||
| 730 | dma_fence_put(fence); | ||
| 731 | err: | ||
| 732 | drm_syncobj_put(binary_syncobj); | ||
| 733 | |||
| 734 | return ret; | ||
| 735 | } | ||
| 736 | int | ||
| 737 | drm_syncobj_transfer_ioctl(struct drm_device *dev, void *data, | ||
| 738 | struct drm_file *file_private) | ||
| 739 | { | ||
| 740 | struct drm_syncobj_transfer *args = data; | ||
| 741 | int ret; | ||
| 742 | |||
| 743 | if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ)) | ||
| 744 | return -ENODEV; | ||
| 745 | |||
| 746 | if (args->pad) | ||
| 747 | return -EINVAL; | ||
| 748 | |||
| 749 | if (args->dst_point) | ||
| 750 | ret = drm_syncobj_transfer_to_timeline(file_private, args); | ||
| 751 | else | ||
| 752 | ret = drm_syncobj_transfer_to_binary(file_private, args); | ||
| 753 | |||
| 754 | return ret; | ||
| 755 | } | ||
| 756 | |||
| 683 | static void syncobj_wait_fence_func(struct dma_fence *fence, | 757 | static void syncobj_wait_fence_func(struct dma_fence *fence, |
| 684 | struct dma_fence_cb *cb) | 758 | struct dma_fence_cb *cb) |
| 685 | { | 759 | { |
| @@ -735,6 +735,15 @@ struct drm_syncobj_handle { · 734 unmodified lines | |||
| 735 | __u32 pad; | 735 | __u32 pad; |
| 736 | }; | 736 | }; |
| 737 | 737 | ||
| 738 | struct drm_syncobj_transfer { | ||
| 739 | __u32 src_handle; | ||
| 740 | __u32 dst_handle; | ||
| 741 | __u64 src_point; | ||
| 742 | __u64 dst_point; | ||
| 743 | __u32 flags; | ||
| 744 | __u32 pad; | ||
| 745 | }; | ||
| 746 | |||
| 738 | #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0) | 747 | #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0) |
| 739 | #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1) | 748 | #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1) |
| 740 | #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE (1 << 2) /* wait for time point to become available */ | 749 | #define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE (1 << 2) /* wait for time point to become available */ |
| @@ -933,6 +942,7 @@ extern "C" { · 192 unmodified lines | |||
| 933 | 942 | ||
| 934 | #define DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT DRM_IOWR(0xCA, struct drm_syncobj_timeline_wait) | 943 | #define DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT DRM_IOWR(0xCA, struct drm_syncobj_timeline_wait) |
| 935 | #define DRM_IOCTL_SYNCOBJ_QUERY DRM_IOWR(0xCB, struct drm_syncobj_timeline_array) | 944 | #define DRM_IOCTL_SYNCOBJ_QUERY DRM_IOWR(0xCB, struct drm_syncobj_timeline_array) |
| 945 | #define DRM_IOCTL_SYNCOBJ_TRANSFER DRM_IOWR(0xCC, struct drm_syncobj_transfer) | ||
| 936 | 946 | ||
| 937 | /** | 947 | /** |
| 938 | * Device specific ioctls should only be in their respective headers | 948 | * Device specific ioctls should only be in their respective headers |