diff options
author | Lingfeng Yang <lfy@google.com> | 2020-04-16 09:50:45 -0700 |
---|---|---|
committer | Alistair Delva <adelva@google.com> | 2020-04-22 13:34:23 -0700 |
commit | 72d2272da9e19681961035653154622453105005 (patch) | |
tree | 5fb12ad577dcad93d619716cd0baa7de543f100f | |
parent | a643c88ccb437130c853bb0d46c7af33cb19a371 (diff) | |
download | cuttlefish-modules-72d2272da9e19681961035653154622453105005.tar.gz |
CHROMIUM: virtwl: store plane info per virtio_gpu_object
This change extends the drm_virtgpu_resource_info struct to include that
plane info.
BUG=chromium:875998
TEST=wayland-simple-egl
Signed-off-by: Zach Reizner <zachr@google.com>
Reviewed-on: https://chromium-review.googlesource.com/1351813
Commit-Ready: David Riley <davidriley@chromium.org>
Tested-by: David Riley <davidriley@chromium.org>
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
[rebase54(groeck): Context conflicts]
Signed-off-by: Guenter Roeck <groeck@chromium.org>
Bug: 153580313
Signed-off-by: Lingfeng Yang <lfy@google.com>
Change-Id: I1ef98e718a14204f6beb9fd81f48f15bda6052f9
-rw-r--r-- | uapi/drm/virtgpu_drm.h | 8 | ||||
-rw-r--r-- | uapi/linux/virtio_gpu.h | 10 | ||||
-rw-r--r-- | virtio_gpu/virtgpu_drv.h | 9 | ||||
-rw-r--r-- | virtio_gpu/virtgpu_ioctl.c | 26 | ||||
-rw-r--r-- | virtio_gpu/virtgpu_vq.c | 51 |
5 files changed, 98 insertions, 6 deletions
diff --git a/uapi/drm/virtgpu_drm.h b/uapi/drm/virtgpu_drm.h index d6f0a2e..144ea5e 100644 --- a/uapi/drm/virtgpu_drm.h +++ b/uapi/drm/virtgpu_drm.h @@ -116,7 +116,13 @@ struct drm_virtgpu_resource_info { __u32 bo_handle; __u32 res_handle; __u32 size; - __u32 stride; + union { + __u32 stride; + __u32 strides[4]; /* strides[0] is accessible with stride. */ + }; + __u32 num_planes; + __u32 offsets[4]; + __u64 format_modifier; }; struct drm_virtgpu_3d_box { diff --git a/uapi/linux/virtio_gpu.h b/uapi/linux/virtio_gpu.h index 0c85914..570a234 100644 --- a/uapi/linux/virtio_gpu.h +++ b/uapi/linux/virtio_gpu.h @@ -87,6 +87,7 @@ enum virtio_gpu_ctrl_type { VIRTIO_GPU_RESP_OK_CAPSET_INFO, VIRTIO_GPU_RESP_OK_CAPSET, VIRTIO_GPU_RESP_OK_EDID, + VIRTIO_GPU_RESP_OK_RESOURCE_PLANE_INFO, /* error responses */ VIRTIO_GPU_RESP_ERR_UNSPEC = 0x1200, @@ -317,6 +318,15 @@ struct virtio_gpu_resp_edid { __u8 edid[1024]; }; +/* VIRTIO_GPU_RESP_OK_RESOURCE_PLANE_INFO */ +struct virtio_gpu_resp_resource_plane_info { + struct virtio_gpu_ctrl_hdr hdr; + __le32 num_planes; + __le64 format_modifier; + __le32 strides[4]; + __le32 offsets[4]; +}; + #define VIRTIO_GPU_EVENT_DISPLAY (1 << 0) struct virtio_gpu_config { diff --git a/virtio_gpu/virtgpu_drv.h b/virtio_gpu/virtgpu_drv.h index d8e98cd..c0e1da3 100644 --- a/virtio_gpu/virtgpu_drv.h +++ b/virtio_gpu/virtgpu_drv.h @@ -71,6 +71,13 @@ struct virtio_gpu_object { struct drm_gem_object gem_base; uint32_t hw_res_handle; + bool create_callback_done; + /* These variables are only valid if create_callback_done is true */ + uint32_t num_planes; + uint64_t format_modifier; + uint32_t strides[4]; + uint32_t offsets[4]; + struct sg_table *pages; uint32_t mapped; void *vmap; @@ -323,7 +330,7 @@ void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev, uint64_t offset, uint32_t level, struct virtio_gpu_box *box, struct virtio_gpu_fence *fence); -void +int virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev, struct virtio_gpu_object *bo, struct virtio_gpu_object_params *params, diff --git a/virtio_gpu/virtgpu_ioctl.c b/virtio_gpu/virtgpu_ioctl.c index c0ba1ea..29ea338 100644 --- a/virtio_gpu/virtgpu_ioctl.c +++ b/virtio_gpu/virtgpu_ioctl.c @@ -335,9 +335,11 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, static int virtio_gpu_resource_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { + struct virtio_gpu_device *vgdev = dev->dev_private; struct drm_virtgpu_resource_info *ri = data; struct drm_gem_object *gobj = NULL; struct virtio_gpu_object *qobj = NULL; + int ret = 0; gobj = drm_gem_object_lookup(file_priv, ri->bo_handle); if (gobj == NULL) @@ -345,10 +347,30 @@ static int virtio_gpu_resource_info_ioctl(struct drm_device *dev, void *data, qobj = gem_to_virtio_gpu_obj(gobj); - ri->size = qobj->gem_base.size; ri->res_handle = qobj->hw_res_handle; + ri->size = qobj->gem_base.size; + + if (!qobj->create_callback_done) { + ret = wait_event_interruptible(vgdev->resp_wq, + qobj->create_callback_done); + if (ret) + goto out; + } + + if (qobj->num_planes) { + int i; + + ri->num_planes = qobj->num_planes; + for (i = 0; i < qobj->num_planes; i++) { + ri->strides[i] = qobj->strides[i]; + ri->offsets[i] = qobj->offsets[i]; + } + } + + ri->format_modifier = qobj->format_modifier; +out: drm_gem_object_put_unlocked(gobj); - return 0; + return ret; } static int virtio_gpu_transfer_from_host_ioctl(struct drm_device *dev, diff --git a/virtio_gpu/virtgpu_vq.c b/virtio_gpu/virtgpu_vq.c index 981ee16..7978a9b 100644 --- a/virtio_gpu/virtgpu_vq.c +++ b/virtio_gpu/virtgpu_vq.c @@ -856,7 +856,40 @@ void virtio_gpu_cmd_context_detach_resource(struct virtio_gpu_device *vgdev, virtio_gpu_queue_ctrl_buffer(vgdev, vbuf); } -void +static void virtio_gpu_cmd_resource_create_cb(struct virtio_gpu_device *vgdev, + struct virtio_gpu_vbuffer *vbuf) +{ + struct virtio_gpu_resp_resource_plane_info *resp = + (struct virtio_gpu_resp_resource_plane_info *)vbuf->resp_buf; + struct virtio_gpu_object *obj = + (struct virtio_gpu_object *)vbuf->data_buf; + uint32_t resp_type = le32_to_cpu(resp->hdr.type); + int i; + + /* + * Keeps the data_buf, which points to this virtio_gpu_object, from + * getting kfree'd after this cb returns. + */ + vbuf->data_buf = NULL; + + if (resp_type != VIRTIO_GPU_RESP_OK_RESOURCE_PLANE_INFO) + goto finish_pending; + + obj->num_planes = le32_to_cpu(resp->num_planes); + obj->format_modifier = le64_to_cpu(resp->format_modifier); + + for (i = 0; i < obj->num_planes; i++) { + obj->strides[i] = le32_to_cpu(resp->strides[i]); + obj->offsets[i] = le32_to_cpu(resp->offsets[i]); + } + +finish_pending: + obj->create_callback_done = true; + drm_gem_object_put_unlocked(&obj->gem_base); + wake_up_all(&vgdev->resp_wq); +} + +int virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev, struct virtio_gpu_object *bo, struct virtio_gpu_object_params *params, @@ -864,8 +897,15 @@ virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev, { struct virtio_gpu_resource_create_3d *cmd_p; struct virtio_gpu_vbuffer *vbuf; + struct virtio_gpu_resp_resource_plane_info *resp_buf; - cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p)); + resp_buf = kzalloc(sizeof(*resp_buf), GFP_KERNEL); + if (!resp_buf) + return -ENOMEM; + + cmd_p = virtio_gpu_alloc_cmd_resp(vgdev, + virtio_gpu_cmd_resource_create_cb, &vbuf, sizeof(*cmd_p), + sizeof(struct virtio_gpu_resp_resource_plane_info), resp_buf); memset(cmd_p, 0, sizeof(*cmd_p)); cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_CREATE_3D); @@ -882,8 +922,15 @@ virtio_gpu_cmd_resource_create_3d(struct virtio_gpu_device *vgdev, cmd_p->nr_samples = cpu_to_le32(params->nr_samples); cmd_p->flags = cpu_to_le32(params->flags); + /* Reuse the data_buf pointer for the object pointer. */ + vbuf->data_buf = bo; + bo->create_callback_done = false; + drm_gem_object_get(&bo->gem_base); + virtio_gpu_queue_fenced_ctrl_buffer(vgdev, vbuf, &cmd_p->hdr, fence); bo->created = true; + + return 0; } void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev, |