summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLingfeng Yang <lfy@google.com>2020-04-16 09:50:45 -0700
committerAlistair Delva <adelva@google.com>2020-04-22 13:34:23 -0700
commit72d2272da9e19681961035653154622453105005 (patch)
tree5fb12ad577dcad93d619716cd0baa7de543f100f
parenta643c88ccb437130c853bb0d46c7af33cb19a371 (diff)
downloadcuttlefish-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.h8
-rw-r--r--uapi/linux/virtio_gpu.h10
-rw-r--r--virtio_gpu/virtgpu_drv.h9
-rw-r--r--virtio_gpu/virtgpu_ioctl.c26
-rw-r--r--virtio_gpu/virtgpu_vq.c51
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,