ACRN:DM:VGPU: Handle the virtio-gpu-cmds based on scanout_id in cmd_request
The scanout_id is included in the below virtio-gpu cmd request. VIRTIO_GPU_GET_EDID VIRTIO_GPU_SET_SCANOUT VIRTIO_GPU_SET_SCANOUT_BLOB VIRTIO_GPU_GET_DISPLAY_INFO So the scanout_id and scanout_rect should be handled correctly. And it will use the scanout_rect instead of resource width/height in course of handling VIRTIO_GPU_SET_SCANOUT/SCANOUT_BLOB cmd. v1->v2: change the position to zero when returning response for GET_DISPLAY_INFO Tracked-On: #7988 Signed-off-by: Zhao Yakui <yakui.zhao@intel.com> Reviewed-by: Peng Sun <peng.p.sun@linux.intel.com>
This commit is contained in:
parent
516e8ef4b1
commit
43626d1803
|
@ -564,11 +564,17 @@ virtio_gpu_cmd_get_edid(struct virtio_gpu_command *cmd)
|
|||
memcpy(&req, cmd->iov[0].iov_base, sizeof(req));
|
||||
cmd->iolen = sizeof(resp);
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
virtio_gpu_update_resp_fence(&cmd->hdr, &resp.hdr);
|
||||
if (req.scanout >= gpu->scanout_num) {
|
||||
pr_err("%s: Invalid scanout_id %d\n", req.scanout);
|
||||
resp.hdr.type = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;
|
||||
memcpy(cmd->iov[1].iov_base, &resp, sizeof(resp));
|
||||
return;
|
||||
}
|
||||
/* Only one EDID block is enough */
|
||||
resp.size = 128;
|
||||
resp.hdr.type = VIRTIO_GPU_RESP_OK_EDID;
|
||||
virtio_gpu_update_resp_fence(&cmd->hdr, &resp.hdr);
|
||||
vdpy_get_edid(gpu->vdpy_handle, 0, resp.edid, resp.size);
|
||||
vdpy_get_edid(gpu->vdpy_handle, req.scanout, resp.edid, resp.size);
|
||||
memcpy(cmd->iov[1].iov_base, &resp, sizeof(resp));
|
||||
}
|
||||
|
||||
|
@ -578,18 +584,21 @@ virtio_gpu_cmd_get_display_info(struct virtio_gpu_command *cmd)
|
|||
struct virtio_gpu_resp_display_info resp;
|
||||
struct display_info info;
|
||||
struct virtio_gpu *gpu;
|
||||
int i;
|
||||
|
||||
gpu = cmd->gpu;
|
||||
cmd->iolen = sizeof(resp);
|
||||
memset(&resp, 0, sizeof(resp));
|
||||
vdpy_get_display_info(gpu->vdpy_handle, 0, &info);
|
||||
resp.hdr.type = VIRTIO_GPU_RESP_OK_DISPLAY_INFO;
|
||||
virtio_gpu_update_resp_fence(&cmd->hdr, &resp.hdr);
|
||||
resp.pmodes[0].enabled = 1;
|
||||
resp.pmodes[0].r.x = info.xoff;
|
||||
resp.pmodes[0].r.y = info.yoff;
|
||||
resp.pmodes[0].r.width = info.width;
|
||||
resp.pmodes[0].r.height = info.height;
|
||||
for (i = 0; i < gpu->scanout_num; i++) {
|
||||
vdpy_get_display_info(gpu->vdpy_handle, i, &info);
|
||||
resp.pmodes[i].enabled = 1;
|
||||
resp.pmodes[i].r.x = 0;
|
||||
resp.pmodes[i].r.y = 0;
|
||||
resp.pmodes[i].r.width = info.width;
|
||||
resp.pmodes[i].r.height = info.height;
|
||||
}
|
||||
memcpy(cmd->iov[1].iov_base, &resp, sizeof(resp));
|
||||
}
|
||||
|
||||
|
@ -640,6 +649,40 @@ virtio_gpu_get_pixman_format(uint32_t format)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
virtio_gpu_update_scanout(struct virtio_gpu *gpu, int scanout_id, int resource_id,
|
||||
struct virtio_gpu_rect *scan_rect)
|
||||
{
|
||||
struct virtio_gpu_scanout *gpu_scanout;
|
||||
struct virtio_gpu_resource_2d *r2d;
|
||||
|
||||
/* as it is already checked, this is not checked again */
|
||||
gpu_scanout = gpu->gpu_scanouts + scanout_id;
|
||||
if (gpu_scanout->dma_buf) {
|
||||
virtio_gpu_dmabuf_unref(gpu_scanout->dma_buf);
|
||||
gpu_scanout->dma_buf = NULL;
|
||||
}
|
||||
if (gpu_scanout->cur_img) {
|
||||
pixman_image_unref(gpu_scanout->cur_img);
|
||||
gpu_scanout->cur_img = NULL;
|
||||
}
|
||||
gpu_scanout->resource_id = resource_id;
|
||||
r2d = virtio_gpu_find_resource_2d(gpu, resource_id);
|
||||
if (r2d) {
|
||||
gpu_scanout->is_active = true;
|
||||
if (r2d->blob) {
|
||||
virtio_gpu_dmabuf_ref(r2d->dma_info);
|
||||
gpu_scanout->dma_buf = r2d->dma_info;
|
||||
} else {
|
||||
pixman_image_ref(r2d->image);
|
||||
gpu_scanout->cur_img = r2d->image;
|
||||
}
|
||||
} else {
|
||||
gpu_scanout->is_active = false;
|
||||
}
|
||||
memcpy(&gpu_scanout->scanout_rect, scan_rect, sizeof(*scan_rect));
|
||||
}
|
||||
|
||||
static void
|
||||
virtio_gpu_cmd_resource_create_2d(struct virtio_gpu_command *cmd)
|
||||
{
|
||||
|
@ -812,7 +855,8 @@ virtio_gpu_cmd_set_scanout(struct virtio_gpu_command *cmd)
|
|||
|
||||
r2d = virtio_gpu_find_resource_2d(gpu, req.resource_id);
|
||||
if ((req.resource_id == 0) || (r2d == NULL)) {
|
||||
vdpy_surface_set(gpu->vdpy_handle, 0, NULL);
|
||||
virtio_gpu_update_scanout(gpu, req.scanout_id, 0, &req.r);
|
||||
vdpy_surface_set(gpu->vdpy_handle, req.scanout_id, NULL);
|
||||
resp.type = VIRTIO_GPU_RESP_OK_NODATA;
|
||||
memcpy(cmd->iov[1].iov_base, &resp, sizeof(resp));
|
||||
return;
|
||||
|
@ -827,16 +871,17 @@ virtio_gpu_cmd_set_scanout(struct virtio_gpu_command *cmd)
|
|||
__func__);
|
||||
resp.type = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
|
||||
} else {
|
||||
virtio_gpu_update_scanout(gpu, req.scanout_id, req.resource_id, &req.r);
|
||||
pixman_image_ref(r2d->image);
|
||||
surf.pixel = pixman_image_get_data(r2d->image);
|
||||
surf.x = 0;
|
||||
surf.y = 0;
|
||||
surf.width = r2d->width;
|
||||
surf.height = r2d->height;
|
||||
surf.x = req.r.x;
|
||||
surf.y = req.r.y;
|
||||
surf.width = req.r.width;
|
||||
surf.height = req.r.height;
|
||||
surf.stride = pixman_image_get_stride(r2d->image);
|
||||
surf.surf_format = r2d->format;
|
||||
surf.surf_type = SURFACE_PIXMAN;
|
||||
vdpy_surface_set(gpu->vdpy_handle, 0, &surf);
|
||||
vdpy_surface_set(gpu->vdpy_handle, req.scanout_id, &surf);
|
||||
pixman_image_unref(r2d->image);
|
||||
resp.type = VIRTIO_GPU_RESP_OK_NODATA;
|
||||
}
|
||||
|
@ -1172,9 +1217,10 @@ virtio_gpu_cmd_set_scanout_blob(struct virtio_gpu_command *cmd)
|
|||
gpu_scanout = gpu->gpu_scanouts + req.scanout_id;
|
||||
gpu_scanout->scanout_id = req.scanout_id;
|
||||
if (req.resource_id == 0) {
|
||||
virtio_gpu_update_scanout(gpu, req.scanout_id, 0, &req.r);
|
||||
resp.type = VIRTIO_GPU_RESP_OK_NODATA;
|
||||
memcpy(cmd->iov[cmd->iovcnt - 1].iov_base, &resp, sizeof(resp));
|
||||
vdpy_surface_set(gpu->vdpy_handle, 0, NULL);
|
||||
vdpy_surface_set(gpu->vdpy_handle, req.scanout_id, NULL);
|
||||
return;
|
||||
}
|
||||
r2d = virtio_gpu_find_resource_2d(cmd->gpu, req.resource_id);
|
||||
|
@ -1183,18 +1229,18 @@ virtio_gpu_cmd_set_scanout_blob(struct virtio_gpu_command *cmd)
|
|||
memcpy(cmd->iov[cmd->iovcnt - 1].iov_base, &resp, sizeof(resp));
|
||||
return;
|
||||
}
|
||||
|
||||
if (r2d->blob == false) {
|
||||
/* Maybe the resource is not blob, fallback to set_scanout */
|
||||
virtio_gpu_cmd_set_scanout(cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
virtio_gpu_update_scanout(gpu, req.scanout_id, req.resource_id, &req.r);
|
||||
virtio_gpu_dmabuf_ref(r2d->dma_info);
|
||||
surf.width = req.width;
|
||||
surf.height = req.height;
|
||||
surf.x = 0;
|
||||
surf.y = 0;
|
||||
surf.width = req.r.width;
|
||||
surf.height = req.r.height;
|
||||
surf.x = req.r.x;
|
||||
surf.y = req.r.y;
|
||||
surf.stride = req.strides[0];
|
||||
surf.dma_info.dmabuf_fd = r2d->dma_info->dmabuf_fd;
|
||||
surf.surf_type = SURFACE_DMABUF;
|
||||
|
@ -1218,7 +1264,7 @@ virtio_gpu_cmd_set_scanout_blob(struct virtio_gpu_command *cmd)
|
|||
break;
|
||||
}
|
||||
surf.dma_info.surf_fourcc = drm_fourcc;
|
||||
vdpy_surface_set(gpu->vdpy_handle, 0, &surf);
|
||||
vdpy_surface_set(gpu->vdpy_handle, req.scanout_id, &surf);
|
||||
resp.type = VIRTIO_GPU_RESP_OK_NODATA;
|
||||
memcpy(cmd->iov[cmd->iovcnt - 1].iov_base, &resp, sizeof(resp));
|
||||
virtio_gpu_dmabuf_unref(r2d->dma_info);
|
||||
|
|
Loading…
Reference in New Issue