diff options
author | Dave Airlie <airlied@redhat.com> | 2013-07-11 15:10:06 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-09-03 15:10:48 +1000 |
commit | 07eaaae1b2002d3d2b8149777e7ff5f558bb9434 (patch) | |
tree | 095bf2e87197bff8fa96fa9bb5dbc13e68ef548a | |
parent | 27c23c8d7fc442532a955555fbc1f520fb583a53 (diff) |
virgl: add cursor support
-rw-r--r-- | drivers/gpu/drm/virgl/virgl_display.c | 63 | ||||
-rw-r--r-- | drivers/gpu/drm/virgl/virgl_drv.h | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/virgl/virgl_ioctl.c | 21 | ||||
-rw-r--r-- | include/uapi/drm/virgl_drm.h | 10 |
4 files changed, 102 insertions, 2 deletions
diff --git a/drivers/gpu/drm/virgl/virgl_display.c b/drivers/gpu/drm/virgl/virgl_display.c index 6d0454f7445f..7c382b1dac25 100644 --- a/drivers/gpu/drm/virgl/virgl_display.c +++ b/drivers/gpu/drm/virgl/virgl_display.c @@ -88,7 +88,7 @@ static void virgl_crtc_destroy(struct drm_crtc *crtc) static void virgl_hide_cursor(struct virgl_device *qdev) { - + iowrite32(0, qdev->ioaddr + VIRTIO_VIRGL_CURSOR_ID); } static int virgl_crtc_cursor_set(struct drm_crtc *crtc, @@ -97,12 +97,71 @@ static int virgl_crtc_cursor_set(struct drm_crtc *crtc, uint32_t width, uint32_t height) { - return 0; + struct virgl_device *qdev = crtc->dev->dev_private; + struct drm_gem_object *gobj = NULL; + struct virgl_bo *qobj = NULL; + int ret = 0; + if (handle == 0) { + virgl_hide_cursor(qdev); + return 0; + } + + /* lookup the cursor */ + gobj = drm_gem_object_lookup(crtc->dev, file_priv, handle); + if (gobj == NULL) + return -ENOENT; + + qobj = gem_to_virgl_bo(gobj); + + if (!qobj->res_handle) { + ret = -EINVAL; + goto out; + } + + { + struct virgl_command *cmd_p; + struct virgl_vbuffer *vbuf; + uint32_t offset = 0; + + cmd_p = virgl_alloc_cmd(qdev, qobj, false, &offset, 0, &vbuf); + if (IS_ERR(cmd_p)) { + printk("failed to allocate cmd for transfer\n"); + return -EINVAL; + } + + cmd_p->type = VIRGL_TRANSFER_PUT; + cmd_p->u.transfer_put.res_handle = qobj->res_handle; + + cmd_p->u.transfer_put.dst_box.x = 0; + cmd_p->u.transfer_put.dst_box.y = 0; + cmd_p->u.transfer_put.dst_box.z = 0; + cmd_p->u.transfer_put.dst_box.w = 64; + cmd_p->u.transfer_put.dst_box.h = 64; + cmd_p->u.transfer_put.dst_box.d = 1; + + cmd_p->u.transfer_put.dst_level = 0; + cmd_p->u.transfer_put.src_stride = 0; + + cmd_p->u.transfer_put.data = offset; + cmd_p->u.transfer_put.transfer_flags = 0; + + virgl_queue_cmd_buf(qdev, vbuf); + } + + iowrite32(qobj->res_handle, qdev->ioaddr + VIRTIO_VIRGL_CURSOR_ID); + iowrite32(0, qdev->ioaddr + VIRTIO_VIRGL_CURSOR_HOT_X_Y); + +out: + drm_gem_object_unreference_unlocked(gobj); + return ret; } static int virgl_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) { + struct virgl_device *qdev = crtc->dev->dev_private; + iowrite32(x, qdev->ioaddr + VIRTIO_VIRGL_CURSOR_CUR_X); + iowrite32(y, qdev->ioaddr + VIRTIO_VIRGL_CURSOR_CUR_Y); return 0; } diff --git a/drivers/gpu/drm/virgl/virgl_drv.h b/drivers/gpu/drm/virgl/virgl_drv.h index 959751812bb4..5a9deccd19f8 100644 --- a/drivers/gpu/drm/virgl/virgl_drv.h +++ b/drivers/gpu/drm/virgl/virgl_drv.h @@ -376,4 +376,14 @@ u32 virgl_fence_read(struct virgl_device *qdev); void virgl_dequeue_work_func(struct work_struct *work); int virgl_resource_unref(struct virgl_device *qdev, uint32_t res_handle); + +/* 32-bit cursor resource id - 0 = disable cursor */ +#define VIRTIO_VIRGL_FENCE_ID 20 +#define VIRTIO_VIRGL_CURSOR_ID 24 +/* cursor hotspot info */ +#define VIRTIO_VIRGL_CURSOR_HOT_X_Y 28 +/* current cursor position */ +#define VIRTIO_VIRGL_CURSOR_CUR_X 32 +#define VIRTIO_VIRGL_CURSOR_CUR_Y 36 + #endif diff --git a/drivers/gpu/drm/virgl/virgl_ioctl.c b/drivers/gpu/drm/virgl/virgl_ioctl.c index f926f0c15c41..836b82612869 100644 --- a/drivers/gpu/drm/virgl/virgl_ioctl.c +++ b/drivers/gpu/drm/virgl/virgl_ioctl.c @@ -281,6 +281,25 @@ static int virgl_wait_ioctl(struct drm_device *dev, void *data, return ret; } +static int virgl_cursor_link_ioctl(struct drm_device *dev, void *data, + struct drm_file *file) +{ + struct drm_virgl_cursor_link *args = data; + struct drm_gem_object *gobj = NULL; + struct virgl_bo *qobj = NULL; + + gobj = drm_gem_object_lookup(dev, file, args->bo_handle); + if (gobj == NULL) + return -ENOENT; + + qobj = gem_to_virgl_bo(gobj); + + qobj->res_handle = args->res_handle; + drm_gem_object_unreference_unlocked(gobj); + + return 0; +} + struct drm_ioctl_desc virgl_ioctls[] = { DRM_IOCTL_DEF_DRV(VIRGL_ALLOC, virgl_alloc_ioctl, DRM_AUTH|DRM_UNLOCKED), @@ -302,6 +321,8 @@ struct drm_ioctl_desc virgl_ioctls[] = { DRM_IOCTL_DEF_DRV(VIRGL_WAIT, virgl_wait_ioctl, DRM_AUTH|DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(VIRGL_CURSOR_LINK, virgl_cursor_link_ioctl, DRM_AUTH|DRM_UNLOCKED), + }; int virgl_max_ioctls = DRM_ARRAY_SIZE(virgl_ioctls); diff --git a/include/uapi/drm/virgl_drm.h b/include/uapi/drm/virgl_drm.h index faf704dcf9de..f7b4c92dc15c 100644 --- a/include/uapi/drm/virgl_drm.h +++ b/include/uapi/drm/virgl_drm.h @@ -43,6 +43,7 @@ #define DRM_VIRGL_TRANSFER_GET 0x06 #define DRM_VIRGL_TRANSFER_PUT 0x07 #define DRM_VIRGL_WAIT 0x08 +#define DRM_VIRGL_CURSOR_LINK 0x09 struct drm_virgl_alloc { uint32_t size; @@ -116,6 +117,11 @@ struct drm_virgl_3d_wait { uint32_t flags; }; +struct drm_virgl_cursor_link { + uint32_t bo_handle; + uint32_t res_handle; +}; + #define DRM_IOCTL_VIRGL_ALLOC \ DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRGL_ALLOC, struct drm_virgl_alloc) @@ -149,4 +155,8 @@ struct drm_virgl_3d_wait { #define DRM_IOCTL_VIRGL_WAIT \ DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRGL_WAIT, \ struct drm_virgl_3d_wait) + +#define DRM_IOCTL_VIRGL_CURSOR_LINK \ + DRM_IOWR(DRM_COMMAND_BASE + DRM_VIRGL_CURSOR_LINK, \ + struct drm_virgl_cursor_link) #endif |