mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-19 12:12:16 +00:00
ACRN:DM:VGPU: Add virtio_gpu_scanout structure to handle virtio-gpu-cmds correctly
Now it only supports one scanout for virtio-gpu. So the scanout_id is ignored in course of handling virtio-gpu cmd. In order to handle the virtio-gpu cmd correctly, it adds the virtio_gpu_scanout structure so that it can record the scanout info. v1->v2: Refine the field in virtio_gpu_scanout and error message for scanout_id 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
6407de302c
commit
516e8ef4b1
@ -348,6 +348,16 @@ enum vga_thread_status {
|
|||||||
VGA_THREAD_EOL = 0,
|
VGA_THREAD_EOL = 0,
|
||||||
VGA_THREAD_RUNNING
|
VGA_THREAD_RUNNING
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct virtio_gpu_scanout {
|
||||||
|
int scanout_id;
|
||||||
|
uint32_t resource_id;
|
||||||
|
struct virtio_gpu_rect scanout_rect;
|
||||||
|
pixman_image_t *cur_img;
|
||||||
|
struct dma_buf_info *dma_buf;
|
||||||
|
bool is_active;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Per-device struct
|
* Per-device struct
|
||||||
*/
|
*/
|
||||||
@ -366,6 +376,8 @@ struct virtio_gpu {
|
|||||||
int32_t vga_thread_status;
|
int32_t vga_thread_status;
|
||||||
uint8_t edid[VIRTIO_GPU_EDID_SIZE];
|
uint8_t edid[VIRTIO_GPU_EDID_SIZE];
|
||||||
bool is_blob_supported;
|
bool is_blob_supported;
|
||||||
|
int scanout_num;
|
||||||
|
struct virtio_gpu_scanout *gpu_scanouts;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct virtio_gpu_command {
|
struct virtio_gpu_command {
|
||||||
@ -782,12 +794,22 @@ virtio_gpu_cmd_set_scanout(struct virtio_gpu_command *cmd)
|
|||||||
struct virtio_gpu_ctrl_hdr resp;
|
struct virtio_gpu_ctrl_hdr resp;
|
||||||
struct surface surf;
|
struct surface surf;
|
||||||
struct virtio_gpu *gpu;
|
struct virtio_gpu *gpu;
|
||||||
|
struct virtio_gpu_scanout *gpu_scanout;
|
||||||
|
|
||||||
gpu = cmd->gpu;
|
gpu = cmd->gpu;
|
||||||
memcpy(&req, cmd->iov[0].iov_base, sizeof(req));
|
memcpy(&req, cmd->iov[0].iov_base, sizeof(req));
|
||||||
memset(&resp, 0, sizeof(resp));
|
memset(&resp, 0, sizeof(resp));
|
||||||
virtio_gpu_update_resp_fence(&cmd->hdr, &resp);
|
virtio_gpu_update_resp_fence(&cmd->hdr, &resp);
|
||||||
|
|
||||||
|
if (req.scanout_id >= gpu->scanout_num) {
|
||||||
|
pr_err("%s: Invalid scanout_id %d\n", req.scanout_id);
|
||||||
|
resp.type = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;
|
||||||
|
memcpy(cmd->iov[1].iov_base, &resp, sizeof(resp));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gpu_scanout = gpu->gpu_scanouts + req.scanout_id;
|
||||||
|
gpu_scanout->scanout_id = req.scanout_id;
|
||||||
|
|
||||||
r2d = virtio_gpu_find_resource_2d(gpu, req.resource_id);
|
r2d = virtio_gpu_find_resource_2d(gpu, req.resource_id);
|
||||||
if ((req.resource_id == 0) || (r2d == NULL)) {
|
if ((req.resource_id == 0) || (r2d == NULL)) {
|
||||||
vdpy_surface_set(gpu->vdpy_handle, 0, NULL);
|
vdpy_surface_set(gpu->vdpy_handle, 0, NULL);
|
||||||
@ -1130,6 +1152,7 @@ virtio_gpu_cmd_set_scanout_blob(struct virtio_gpu_command *cmd)
|
|||||||
struct surface surf;
|
struct surface surf;
|
||||||
uint32_t drm_fourcc;
|
uint32_t drm_fourcc;
|
||||||
struct virtio_gpu *gpu;
|
struct virtio_gpu *gpu;
|
||||||
|
struct virtio_gpu_scanout *gpu_scanout;
|
||||||
|
|
||||||
gpu = cmd->gpu;
|
gpu = cmd->gpu;
|
||||||
memset(&surf, 0, sizeof(surf));
|
memset(&surf, 0, sizeof(surf));
|
||||||
@ -1140,6 +1163,14 @@ virtio_gpu_cmd_set_scanout_blob(struct virtio_gpu_command *cmd)
|
|||||||
if (cmd->gpu->vga.enable) {
|
if (cmd->gpu->vga.enable) {
|
||||||
cmd->gpu->vga.enable = false;
|
cmd->gpu->vga.enable = false;
|
||||||
}
|
}
|
||||||
|
if (req.scanout_id >= gpu->scanout_num) {
|
||||||
|
pr_err("%s: Invalid scanout_id %d\n", req.scanout_id);
|
||||||
|
resp.type = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;
|
||||||
|
memcpy(cmd->iov[cmd->iovcnt - 1].iov_base, &resp, sizeof(resp));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gpu_scanout = gpu->gpu_scanouts + req.scanout_id;
|
||||||
|
gpu_scanout->scanout_id = req.scanout_id;
|
||||||
if (req.resource_id == 0) {
|
if (req.resource_id == 0) {
|
||||||
resp.type = VIRTIO_GPU_RESP_OK_NODATA;
|
resp.type = VIRTIO_GPU_RESP_OK_NODATA;
|
||||||
memcpy(cmd->iov[cmd->iovcnt - 1].iov_base, &resp, sizeof(resp));
|
memcpy(cmd->iov[cmd->iovcnt - 1].iov_base, &resp, sizeof(resp));
|
||||||
@ -1485,10 +1516,22 @@ virtio_gpu_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
|
|||||||
gpu->vq,
|
gpu->vq,
|
||||||
BACKEND_VBSU);
|
BACKEND_VBSU);
|
||||||
|
|
||||||
|
gpu->scanout_num = 1;
|
||||||
gpu->vdpy_handle = vdpy_init(NULL);
|
gpu->vdpy_handle = vdpy_init(NULL);
|
||||||
gpu->base.mtx = &gpu->mtx;
|
gpu->base.mtx = &gpu->mtx;
|
||||||
gpu->base.device_caps = VIRTIO_GPU_S_HOSTCAPS;
|
gpu->base.device_caps = VIRTIO_GPU_S_HOSTCAPS;
|
||||||
|
|
||||||
|
if (gpu->scanout_num < 0) {
|
||||||
|
pr_err("%s: return incorrect scanout num %d\n", gpu->scanout_num);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
gpu->gpu_scanouts = calloc(gpu->scanout_num, sizeof(struct virtio_gpu_scanout));
|
||||||
|
if (gpu->gpu_scanouts == NULL) {
|
||||||
|
pr_err("%s: out of memory for gpu_scanouts\n", __func__);
|
||||||
|
free(gpu);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (vm_allow_dmabuf(gpu->base.dev->vmctx)) {
|
if (vm_allow_dmabuf(gpu->base.dev->vmctx)) {
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char buf[16];
|
char buf[16];
|
||||||
@ -1643,6 +1686,7 @@ virtio_gpu_deinit(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
|
|||||||
{
|
{
|
||||||
struct virtio_gpu *gpu;
|
struct virtio_gpu *gpu;
|
||||||
struct virtio_gpu_resource_2d *r2d;
|
struct virtio_gpu_resource_2d *r2d;
|
||||||
|
int i;
|
||||||
|
|
||||||
gpu = (struct virtio_gpu *)dev->arg;
|
gpu = (struct virtio_gpu *)dev->arg;
|
||||||
gpu->vga.enable = false;
|
gpu->vga.enable = false;
|
||||||
@ -1661,6 +1705,25 @@ virtio_gpu_deinit(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
|
|||||||
gpu->vga.gc = NULL;
|
gpu->vga.gc = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i=0; i < gpu->scanout_num; i++) {
|
||||||
|
struct virtio_gpu_scanout *gpu_scanout;
|
||||||
|
|
||||||
|
gpu_scanout = gpu->gpu_scanouts + i;
|
||||||
|
if (gpu_scanout && gpu_scanout->is_active) {
|
||||||
|
if (gpu_scanout->cur_img) {
|
||||||
|
pixman_image_unref(gpu_scanout->cur_img);
|
||||||
|
gpu_scanout->cur_img = NULL;
|
||||||
|
}
|
||||||
|
if (gpu_scanout->dma_buf) {
|
||||||
|
virtio_gpu_dmabuf_unref(gpu_scanout->dma_buf);
|
||||||
|
gpu_scanout->dma_buf = NULL;
|
||||||
|
}
|
||||||
|
gpu_scanout->is_active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(gpu->gpu_scanouts);
|
||||||
|
gpu->gpu_scanouts = NULL;
|
||||||
|
|
||||||
pthread_mutex_destroy(&gpu->vga_thread_mtx);
|
pthread_mutex_destroy(&gpu->vga_thread_mtx);
|
||||||
while (LIST_FIRST(&gpu->r2d_list)) {
|
while (LIST_FIRST(&gpu->r2d_list)) {
|
||||||
r2d = LIST_FIRST(&gpu->r2d_list);
|
r2d = LIST_FIRST(&gpu->r2d_list);
|
||||||
|
Loading…
Reference in New Issue
Block a user