Lines Matching +full:conf +full:- +full:ds
4 * Copyright Red Hat, Inc. 2013-2014
11 * See the COPYING file in the top-level directory.
24 #include "migration/qemu-file-types.h"
25 #include "hw/virtio/virtio-gpu.h"
26 #include "hw/virtio/virtio-gpu-bswap.h"
27 #include "hw/virtio/virtio-gpu-pixman.h"
28 #include "hw/virtio/virtio-bus.h"
29 #include "hw/qdev-properties.h"
34 #include "qemu/error-report.h"
59 if (res->blob_size) { in virtio_gpu_update_cursor_data()
60 if (res->blob_size < (s->current_cursor->width * in virtio_gpu_update_cursor_data()
61 s->current_cursor->height * 4)) { in virtio_gpu_update_cursor_data()
64 data = res->blob; in virtio_gpu_update_cursor_data()
66 if (pixman_image_get_width(res->image) != s->current_cursor->width || in virtio_gpu_update_cursor_data()
67 pixman_image_get_height(res->image) != s->current_cursor->height) { in virtio_gpu_update_cursor_data()
70 data = pixman_image_get_data(res->image); in virtio_gpu_update_cursor_data()
73 pixels = s->current_cursor->width * s->current_cursor->height; in virtio_gpu_update_cursor_data()
74 memcpy(s->current_cursor->data, data, in virtio_gpu_update_cursor_data()
82 bool move = cursor->hdr.type == VIRTIO_GPU_CMD_MOVE_CURSOR; in update_cursor()
84 if (cursor->pos.scanout_id >= g->parent_obj.conf.max_outputs) { in update_cursor()
87 s = &g->parent_obj.scanout[cursor->pos.scanout_id]; in update_cursor()
89 trace_virtio_gpu_update_cursor(cursor->pos.scanout_id, in update_cursor()
90 cursor->pos.x, in update_cursor()
91 cursor->pos.y, in update_cursor()
93 cursor->resource_id); in update_cursor()
96 if (!s->current_cursor) { in update_cursor()
97 s->current_cursor = cursor_alloc(64, 64); in update_cursor()
100 s->current_cursor->hot_x = cursor->hot_x; in update_cursor()
101 s->current_cursor->hot_y = cursor->hot_y; in update_cursor()
103 if (cursor->resource_id > 0) { in update_cursor()
104 vgc->update_cursor_data(g, s, cursor->resource_id); in update_cursor()
106 dpy_cursor_define(s->con, s->current_cursor); in update_cursor()
108 s->cursor = *cursor; in update_cursor()
110 s->cursor.pos.x = cursor->pos.x; in update_cursor()
111 s->cursor.pos.y = cursor->pos.y; in update_cursor()
113 dpy_mouse_set(s->con, cursor->pos.x, cursor->pos.y, cursor->resource_id); in update_cursor()
121 QTAILQ_FOREACH(res, &g->reslist, next) { in virtio_gpu_find_resource()
122 if (res->resource_id == resource_id) { in virtio_gpu_find_resource()
147 if (!res->iov || (!res->image && !res->blob)) { in virtio_gpu_find_check_resource()
167 if (cmd->cmd_hdr.flags & VIRTIO_GPU_FLAG_FENCE) { in virtio_gpu_ctrl_response()
168 resp->flags |= VIRTIO_GPU_FLAG_FENCE; in virtio_gpu_ctrl_response()
169 resp->fence_id = cmd->cmd_hdr.fence_id; in virtio_gpu_ctrl_response()
170 resp->ctx_id = cmd->cmd_hdr.ctx_id; in virtio_gpu_ctrl_response()
173 s = iov_from_buf(cmd->elem.in_sg, cmd->elem.in_num, 0, resp, resp_len); in virtio_gpu_ctrl_response()
179 virtqueue_push(cmd->vq, &cmd->elem, s); in virtio_gpu_ctrl_response()
180 virtio_notify(VIRTIO_DEVICE(g), cmd->vq); in virtio_gpu_ctrl_response()
181 cmd->finished = true; in virtio_gpu_ctrl_response()
218 if (get_edid.scanout >= b->conf.max_outputs) { in virtio_gpu_get_edid()
219 cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER; in virtio_gpu_get_edid()
233 /* Copied from pixman/pixman-bits-image.c, skip integer overflow check. in calc_image_hostmem()
257 cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID; in virtio_gpu_resource_create_2d()
265 cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID; in virtio_gpu_resource_create_2d()
271 res->width = c2d.width; in virtio_gpu_resource_create_2d()
272 res->height = c2d.height; in virtio_gpu_resource_create_2d()
273 res->format = c2d.format; in virtio_gpu_resource_create_2d()
274 res->resource_id = c2d.resource_id; in virtio_gpu_resource_create_2d()
282 cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER; in virtio_gpu_resource_create_2d()
286 res->hostmem = calc_image_hostmem(pformat, c2d.width, c2d.height); in virtio_gpu_resource_create_2d()
287 if (res->hostmem + g->hostmem < g->conf_max_hostmem) { in virtio_gpu_resource_create_2d()
289 &res->image, in virtio_gpu_resource_create_2d()
290 &res->share_handle, in virtio_gpu_resource_create_2d()
291 "virtio-gpu res", in virtio_gpu_resource_create_2d()
295 c2d.height ? res->hostmem / c2d.height : 0, in virtio_gpu_resource_create_2d()
302 if (!res->image) { in virtio_gpu_resource_create_2d()
307 cmd->error = VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY; in virtio_gpu_resource_create_2d()
311 QTAILQ_INSERT_HEAD(&g->reslist, res, next); in virtio_gpu_resource_create_2d()
312 g->hostmem += res->hostmem; in virtio_gpu_resource_create_2d()
329 cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID; in virtio_gpu_resource_create_blob()
337 cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER; in virtio_gpu_resource_create_blob()
344 cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID; in virtio_gpu_resource_create_blob()
349 res->resource_id = cblob.resource_id; in virtio_gpu_resource_create_blob()
350 res->blob_size = cblob.size; in virtio_gpu_resource_create_blob()
353 cmd, &res->addrs, &res->iov, in virtio_gpu_resource_create_blob()
354 &res->iov_cnt); in virtio_gpu_resource_create_blob()
356 cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC; in virtio_gpu_resource_create_blob()
362 QTAILQ_INSERT_HEAD(&g->reslist, res, next); in virtio_gpu_resource_create_blob()
367 struct virtio_gpu_scanout *scanout = &g->parent_obj.scanout[scanout_id]; in virtio_gpu_disable_scanout()
370 if (scanout->resource_id == 0) { in virtio_gpu_disable_scanout()
374 res = virtio_gpu_find_resource(g, scanout->resource_id); in virtio_gpu_disable_scanout()
376 res->scanout_bitmask &= ~(1 << scanout_id); in virtio_gpu_disable_scanout()
379 dpy_gfx_replace_surface(scanout->con, NULL); in virtio_gpu_disable_scanout()
380 scanout->resource_id = 0; in virtio_gpu_disable_scanout()
381 scanout->ds = NULL; in virtio_gpu_disable_scanout()
382 scanout->width = 0; in virtio_gpu_disable_scanout()
383 scanout->height = 0; in virtio_gpu_disable_scanout()
392 if (res->scanout_bitmask) { in virtio_gpu_resource_destroy()
393 for (i = 0; i < g->parent_obj.conf.max_outputs; i++) { in virtio_gpu_resource_destroy()
394 if (res->scanout_bitmask & (1 << i)) { in virtio_gpu_resource_destroy()
400 qemu_pixman_image_unref(res->image); in virtio_gpu_resource_destroy()
402 QTAILQ_REMOVE(&g->reslist, res, next); in virtio_gpu_resource_destroy()
403 g->hostmem -= res->hostmem; in virtio_gpu_resource_destroy()
421 cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID; in virtio_gpu_resource_unref()
446 __func__, &cmd->error); in virtio_gpu_transfer_to_host_2d()
447 if (!res || res->blob) { in virtio_gpu_transfer_to_host_2d()
451 if (t2d.r.x > res->width || in virtio_gpu_transfer_to_host_2d()
452 t2d.r.y > res->height || in virtio_gpu_transfer_to_host_2d()
453 t2d.r.width > res->width || in virtio_gpu_transfer_to_host_2d()
454 t2d.r.height > res->height || in virtio_gpu_transfer_to_host_2d()
455 t2d.r.x + t2d.r.width > res->width || in virtio_gpu_transfer_to_host_2d()
456 t2d.r.y + t2d.r.height > res->height) { in virtio_gpu_transfer_to_host_2d()
460 t2d.r.width, t2d.r.height, res->width, res->height); in virtio_gpu_transfer_to_host_2d()
461 cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER; in virtio_gpu_transfer_to_host_2d()
465 format = pixman_image_get_format(res->image); in virtio_gpu_transfer_to_host_2d()
467 stride = pixman_image_get_stride(res->image); in virtio_gpu_transfer_to_host_2d()
468 img_data = pixman_image_get_data(res->image); in virtio_gpu_transfer_to_host_2d()
470 if (t2d.r.x || t2d.r.width != pixman_image_get_width(res->image)) { in virtio_gpu_transfer_to_host_2d()
475 iov_to_buf(res->iov, res->iov_cnt, src_offset, in virtio_gpu_transfer_to_host_2d()
482 iov_to_buf(res->iov, res->iov_cnt, src_offset, in virtio_gpu_transfer_to_host_2d()
505 __func__, &cmd->error); in virtio_gpu_resource_flush()
510 if (res->blob) { in virtio_gpu_resource_flush()
511 for (i = 0; i < g->parent_obj.conf.max_outputs; i++) { in virtio_gpu_resource_flush()
512 scanout = &g->parent_obj.scanout[i]; in virtio_gpu_resource_flush()
513 if (scanout->resource_id == res->resource_id && in virtio_gpu_resource_flush()
514 rf.r.x < scanout->x + scanout->width && in virtio_gpu_resource_flush()
515 rf.r.x + rf.r.width >= scanout->x && in virtio_gpu_resource_flush()
516 rf.r.y < scanout->y + scanout->height && in virtio_gpu_resource_flush()
517 rf.r.y + rf.r.height >= scanout->y) { in virtio_gpu_resource_flush()
520 if (console_has_gl(scanout->con)) { in virtio_gpu_resource_flush()
521 dpy_gl_update(scanout->con, 0, 0, scanout->width, in virtio_gpu_resource_flush()
522 scanout->height); in virtio_gpu_resource_flush()
536 cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER; in virtio_gpu_resource_flush()
541 if (!res->blob && in virtio_gpu_resource_flush()
542 (rf.r.x > res->width || in virtio_gpu_resource_flush()
543 rf.r.y > res->height || in virtio_gpu_resource_flush()
544 rf.r.width > res->width || in virtio_gpu_resource_flush()
545 rf.r.height > res->height || in virtio_gpu_resource_flush()
546 rf.r.x + rf.r.width > res->width || in virtio_gpu_resource_flush()
547 rf.r.y + rf.r.height > res->height)) { in virtio_gpu_resource_flush()
551 rf.r.width, rf.r.height, res->width, res->height); in virtio_gpu_resource_flush()
552 cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER; in virtio_gpu_resource_flush()
557 for (i = 0; i < g->parent_obj.conf.max_outputs; i++) { in virtio_gpu_resource_flush()
560 if (!(res->scanout_bitmask & (1 << i))) { in virtio_gpu_resource_flush()
563 scanout = &g->parent_obj.scanout[i]; in virtio_gpu_resource_flush()
565 qemu_rect_init(&rect, scanout->x, scanout->y, in virtio_gpu_resource_flush()
566 scanout->width, scanout->height); in virtio_gpu_resource_flush()
570 qemu_rect_translate(&rect, -scanout->x, -scanout->y); in virtio_gpu_resource_flush()
571 dpy_gfx_update(g->parent_obj.scanout[i].con, in virtio_gpu_resource_flush()
591 scanout = &g->parent_obj.scanout[scanout_id]; in virtio_gpu_update_scanout()
592 ores = virtio_gpu_find_resource(g, scanout->resource_id); in virtio_gpu_update_scanout()
594 ores->scanout_bitmask &= ~(1 << scanout_id); in virtio_gpu_update_scanout()
597 res->scanout_bitmask |= (1 << scanout_id); in virtio_gpu_update_scanout()
598 scanout->resource_id = res->resource_id; in virtio_gpu_update_scanout()
599 scanout->x = r->x; in virtio_gpu_update_scanout()
600 scanout->y = r->y; in virtio_gpu_update_scanout()
601 scanout->width = r->width; in virtio_gpu_update_scanout()
602 scanout->height = r->height; in virtio_gpu_update_scanout()
603 scanout->fb = *fb; in virtio_gpu_update_scanout()
616 scanout = &g->parent_obj.scanout[scanout_id]; in virtio_gpu_do_set_scanout()
618 if (r->x > fb->width || in virtio_gpu_do_set_scanout()
619 r->y > fb->height || in virtio_gpu_do_set_scanout()
620 r->width < 16 || in virtio_gpu_do_set_scanout()
621 r->height < 16 || in virtio_gpu_do_set_scanout()
622 r->width > fb->width || in virtio_gpu_do_set_scanout()
623 r->height > fb->height || in virtio_gpu_do_set_scanout()
624 r->x + r->width > fb->width || in virtio_gpu_do_set_scanout()
625 r->y + r->height > fb->height) { in virtio_gpu_do_set_scanout()
628 __func__, scanout_id, res->resource_id, in virtio_gpu_do_set_scanout()
629 r->x, r->y, r->width, r->height, in virtio_gpu_do_set_scanout()
630 fb->width, fb->height); in virtio_gpu_do_set_scanout()
635 g->parent_obj.enable = 1; in virtio_gpu_do_set_scanout()
637 if (res->blob) { in virtio_gpu_do_set_scanout()
638 if (console_has_gl(scanout->con)) { in virtio_gpu_do_set_scanout()
648 data = res->blob; in virtio_gpu_do_set_scanout()
650 data = (uint8_t *)pixman_image_get_data(res->image); in virtio_gpu_do_set_scanout()
654 if ((res->blob && !console_has_gl(scanout->con)) || in virtio_gpu_do_set_scanout()
655 !scanout->ds || in virtio_gpu_do_set_scanout()
656 surface_data(scanout->ds) != data + fb->offset || in virtio_gpu_do_set_scanout()
657 scanout->width != r->width || in virtio_gpu_do_set_scanout()
658 scanout->height != r->height) { in virtio_gpu_do_set_scanout()
660 void *ptr = data + fb->offset; in virtio_gpu_do_set_scanout()
661 rect = pixman_image_create_bits(fb->format, r->width, r->height, in virtio_gpu_do_set_scanout()
662 ptr, fb->stride); in virtio_gpu_do_set_scanout()
664 if (res->image) { in virtio_gpu_do_set_scanout()
665 pixman_image_ref(res->image); in virtio_gpu_do_set_scanout()
667 res->image); in virtio_gpu_do_set_scanout()
671 scanout->ds = qemu_create_displaysurface_pixman(rect); in virtio_gpu_do_set_scanout()
672 qemu_displaysurface_set_share_handle(scanout->ds, res->share_handle, fb->offset); in virtio_gpu_do_set_scanout()
675 dpy_gfx_replace_surface(g->parent_obj.scanout[scanout_id].con, in virtio_gpu_do_set_scanout()
676 scanout->ds); in virtio_gpu_do_set_scanout()
695 if (ss.scanout_id >= g->parent_obj.conf.max_outputs) { in virtio_gpu_set_scanout()
698 cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID; in virtio_gpu_set_scanout()
708 __func__, &cmd->error); in virtio_gpu_set_scanout()
713 fb.format = pixman_image_get_format(res->image); in virtio_gpu_set_scanout()
715 fb.width = pixman_image_get_width(res->image); in virtio_gpu_set_scanout()
716 fb.height = pixman_image_get_height(res->image); in virtio_gpu_set_scanout()
717 fb.stride = pixman_image_get_stride(res->image); in virtio_gpu_set_scanout()
721 &fb, res, &ss.r, &cmd->error); in virtio_gpu_set_scanout()
730 fb->format = virtio_gpu_get_pixman_format(ss->format); in virtio_gpu_scanout_blob_to_fb()
731 if (!fb->format) { in virtio_gpu_scanout_blob_to_fb()
734 __func__, ss->format); in virtio_gpu_scanout_blob_to_fb()
738 fb->bytes_pp = DIV_ROUND_UP(PIXMAN_FORMAT_BPP(fb->format), 8); in virtio_gpu_scanout_blob_to_fb()
739 fb->width = ss->width; in virtio_gpu_scanout_blob_to_fb()
740 fb->height = ss->height; in virtio_gpu_scanout_blob_to_fb()
741 fb->stride = ss->strides[0]; in virtio_gpu_scanout_blob_to_fb()
742 fb->offset = ss->offsets[0] + ss->r.x * fb->bytes_pp + ss->r.y * fb->stride; in virtio_gpu_scanout_blob_to_fb()
744 fbend = fb->offset; in virtio_gpu_scanout_blob_to_fb()
745 fbend += (uint64_t) fb->stride * ss->r.height; in virtio_gpu_scanout_blob_to_fb()
772 if (ss.scanout_id >= g->parent_obj.conf.max_outputs) { in virtio_gpu_set_scanout_blob()
775 cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID; in virtio_gpu_set_scanout_blob()
785 __func__, &cmd->error); in virtio_gpu_set_scanout_blob()
790 if (!virtio_gpu_scanout_blob_to_fb(&fb, &ss, res->blob_size)) { in virtio_gpu_set_scanout_blob()
791 cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER; in virtio_gpu_set_scanout_blob()
796 &fb, res, &ss.r, &cmd->error); in virtio_gpu_set_scanout_blob()
813 return -1; in virtio_gpu_create_mapping_iov()
818 s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, in virtio_gpu_create_mapping_iov()
825 return -1; in virtio_gpu_create_mapping_iov()
840 map = dma_memory_map(VIRTIO_DEVICE(g)->dma_as, a, &len, in virtio_gpu_create_mapping_iov()
853 return -1; in virtio_gpu_create_mapping_iov()
869 l -= len; in virtio_gpu_create_mapping_iov()
885 dma_memory_unmap(VIRTIO_DEVICE(g)->dma_as, in virtio_gpu_cleanup_mapping_iov()
896 virtio_gpu_cleanup_mapping_iov(g, res->iov, res->iov_cnt); in virtio_gpu_cleanup_mapping()
897 res->iov = NULL; in virtio_gpu_cleanup_mapping()
898 res->iov_cnt = 0; in virtio_gpu_cleanup_mapping()
899 g_free(res->addrs); in virtio_gpu_cleanup_mapping()
900 res->addrs = NULL; in virtio_gpu_cleanup_mapping()
902 if (res->blob) { in virtio_gpu_cleanup_mapping()
923 cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID; in virtio_gpu_resource_attach_backing()
927 if (res->iov) { in virtio_gpu_resource_attach_backing()
928 cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC; in virtio_gpu_resource_attach_backing()
933 &res->addrs, &res->iov, &res->iov_cnt); in virtio_gpu_resource_attach_backing()
935 cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC; in virtio_gpu_resource_attach_backing()
952 __func__, &cmd->error); in virtio_gpu_resource_detach_backing()
962 VIRTIO_GPU_FILL_CMD(cmd->cmd_hdr); in virtio_gpu_simple_process_cmd()
963 virtio_gpu_ctrl_hdr_bswap(&cmd->cmd_hdr); in virtio_gpu_simple_process_cmd()
965 switch (cmd->cmd_hdr.type) { in virtio_gpu_simple_process_cmd()
976 if (!virtio_gpu_blob_enabled(g->parent_obj.conf)) { in virtio_gpu_simple_process_cmd()
977 cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER; in virtio_gpu_simple_process_cmd()
995 if (!virtio_gpu_blob_enabled(g->parent_obj.conf)) { in virtio_gpu_simple_process_cmd()
996 cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER; in virtio_gpu_simple_process_cmd()
1008 cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC; in virtio_gpu_simple_process_cmd()
1011 if (!cmd->finished) { in virtio_gpu_simple_process_cmd()
1012 if (!g->parent_obj.renderer_blocked) { in virtio_gpu_simple_process_cmd()
1013 virtio_gpu_ctrl_response_nodata(g, cmd, cmd->error ? cmd->error : in virtio_gpu_simple_process_cmd()
1022 qemu_bh_schedule(g->ctrl_bh); in virtio_gpu_handle_ctrl_cb()
1028 qemu_bh_schedule(g->cursor_bh); in virtio_gpu_handle_cursor_cb()
1036 if (g->processing_cmdq) { in virtio_gpu_process_cmdq()
1039 g->processing_cmdq = true; in virtio_gpu_process_cmdq()
1040 while (!QTAILQ_EMPTY(&g->cmdq)) { in virtio_gpu_process_cmdq()
1041 cmd = QTAILQ_FIRST(&g->cmdq); in virtio_gpu_process_cmdq()
1043 if (g->parent_obj.renderer_blocked) { in virtio_gpu_process_cmdq()
1048 vgc->process_cmd(g, cmd); in virtio_gpu_process_cmdq()
1051 if (!cmd->finished && !(cmd->cmd_hdr.flags & VIRTIO_GPU_FLAG_FENCE)) { in virtio_gpu_process_cmdq()
1052 trace_virtio_gpu_cmd_suspended(cmd->cmd_hdr.type); in virtio_gpu_process_cmdq()
1056 QTAILQ_REMOVE(&g->cmdq, cmd, next); in virtio_gpu_process_cmdq()
1057 if (virtio_gpu_stats_enabled(g->parent_obj.conf)) { in virtio_gpu_process_cmdq()
1058 g->stats.requests++; in virtio_gpu_process_cmdq()
1061 if (!cmd->finished) { in virtio_gpu_process_cmdq()
1062 QTAILQ_INSERT_TAIL(&g->fenceq, cmd, next); in virtio_gpu_process_cmdq()
1063 g->inflight++; in virtio_gpu_process_cmdq()
1064 if (virtio_gpu_stats_enabled(g->parent_obj.conf)) { in virtio_gpu_process_cmdq()
1065 if (g->stats.max_inflight < g->inflight) { in virtio_gpu_process_cmdq()
1066 g->stats.max_inflight = g->inflight; in virtio_gpu_process_cmdq()
1068 trace_virtio_gpu_inc_inflight_fences(g->inflight); in virtio_gpu_process_cmdq()
1074 g->processing_cmdq = false; in virtio_gpu_process_cmdq()
1081 QTAILQ_FOREACH_SAFE(cmd, &g->fenceq, next, tmp) { in virtio_gpu_process_fenceq()
1082 trace_virtio_gpu_fence_resp(cmd->cmd_hdr.fence_id); in virtio_gpu_process_fenceq()
1084 QTAILQ_REMOVE(&g->fenceq, cmd, next); in virtio_gpu_process_fenceq()
1086 g->inflight--; in virtio_gpu_process_fenceq()
1087 if (virtio_gpu_stats_enabled(g->parent_obj.conf)) { in virtio_gpu_process_fenceq()
1088 trace_virtio_gpu_dec_inflight_fences(g->inflight); in virtio_gpu_process_fenceq()
1112 cmd->vq = vq; in virtio_gpu_handle_ctrl()
1113 cmd->error = 0; in virtio_gpu_handle_ctrl()
1114 cmd->finished = false; in virtio_gpu_handle_ctrl()
1115 QTAILQ_INSERT_TAIL(&g->cmdq, cmd, next); in virtio_gpu_handle_ctrl()
1127 vgc->handle_ctrl(VIRTIO_DEVICE(g), g->ctrl_vq); in virtio_gpu_ctrl_bh()
1146 s = iov_to_buf(elem->out_sg, elem->out_num, 0, in virtio_gpu_handle_cursor()
1165 virtio_gpu_handle_cursor(&g->parent_obj.parent_obj, g->cursor_vq); in virtio_gpu_cursor_bh()
1173 return gpu->scanout_vmstate_version >= 2; in scanout_vmstate_after_v2()
1177 .name = "virtio-gpu-one-scanout",
1207 .name = "virtio-gpu-scanouts",
1211 VMSTATE_UINT32_EQUAL(parent_obj.conf.max_outputs,
1214 parent_obj.conf.max_outputs, 1,
1229 assert(QTAILQ_EMPTY(&g->cmdq)); in virtio_gpu_save()
1231 QTAILQ_FOREACH(res, &g->reslist, next) { in virtio_gpu_save()
1232 if (res->blob_size) { in virtio_gpu_save()
1235 qemu_put_be32(f, res->resource_id); in virtio_gpu_save()
1236 qemu_put_be32(f, res->width); in virtio_gpu_save()
1237 qemu_put_be32(f, res->height); in virtio_gpu_save()
1238 qemu_put_be32(f, res->format); in virtio_gpu_save()
1239 qemu_put_be32(f, res->iov_cnt); in virtio_gpu_save()
1240 for (i = 0; i < res->iov_cnt; i++) { in virtio_gpu_save()
1241 qemu_put_be64(f, res->addrs[i]); in virtio_gpu_save()
1242 qemu_put_be32(f, res->iov[i].iov_len); in virtio_gpu_save()
1244 qemu_put_buffer(f, (void *)pixman_image_get_data(res->image), in virtio_gpu_save()
1245 pixman_image_get_stride(res->image) * res->height); in virtio_gpu_save()
1257 for (i = 0; i < res->iov_cnt; i++) { in virtio_gpu_load_restore_mapping()
1258 hwaddr len = res->iov[i].iov_len; in virtio_gpu_load_restore_mapping()
1259 res->iov[i].iov_base = in virtio_gpu_load_restore_mapping()
1260 dma_memory_map(VIRTIO_DEVICE(g)->dma_as, res->addrs[i], &len, in virtio_gpu_load_restore_mapping()
1263 if (!res->iov[i].iov_base || len != res->iov[i].iov_len) { in virtio_gpu_load_restore_mapping()
1264 /* Clean up the half-a-mapping we just created... */ in virtio_gpu_load_restore_mapping()
1265 if (res->iov[i].iov_base) { in virtio_gpu_load_restore_mapping()
1266 dma_memory_unmap(VIRTIO_DEVICE(g)->dma_as, res->iov[i].iov_base, in virtio_gpu_load_restore_mapping()
1270 res->iov_cnt = i; in virtio_gpu_load_restore_mapping()
1276 QTAILQ_INSERT_HEAD(&g->reslist, res, next); in virtio_gpu_load_restore_mapping()
1277 g->hostmem += res->hostmem; in virtio_gpu_load_restore_mapping()
1289 g->hostmem = 0; in virtio_gpu_load()
1295 return -EINVAL; in virtio_gpu_load()
1299 res->resource_id = resource_id; in virtio_gpu_load()
1300 res->width = qemu_get_be32(f); in virtio_gpu_load()
1301 res->height = qemu_get_be32(f); in virtio_gpu_load()
1302 res->format = qemu_get_be32(f); in virtio_gpu_load()
1303 res->iov_cnt = qemu_get_be32(f); in virtio_gpu_load()
1306 pformat = virtio_gpu_get_pixman_format(res->format); in virtio_gpu_load()
1309 return -EINVAL; in virtio_gpu_load()
1312 res->hostmem = calc_image_hostmem(pformat, res->width, res->height); in virtio_gpu_load()
1313 if (!qemu_pixman_image_new_shareable(&res->image, in virtio_gpu_load()
1314 &res->share_handle, in virtio_gpu_load()
1315 "virtio-gpu res", in virtio_gpu_load()
1317 res->width, in virtio_gpu_load()
1318 res->height, in virtio_gpu_load()
1319 res->height ? res->hostmem / res->height : 0, in virtio_gpu_load()
1322 return -EINVAL; in virtio_gpu_load()
1325 res->addrs = g_new(uint64_t, res->iov_cnt); in virtio_gpu_load()
1326 res->iov = g_new(struct iovec, res->iov_cnt); in virtio_gpu_load()
1329 for (i = 0; i < res->iov_cnt; i++) { in virtio_gpu_load()
1330 res->addrs[i] = qemu_get_be64(f); in virtio_gpu_load()
1331 res->iov[i].iov_len = qemu_get_be32(f); in virtio_gpu_load()
1333 qemu_get_buffer(f, (void *)pixman_image_get_data(res->image), in virtio_gpu_load()
1334 pixman_image_get_stride(res->image) * res->height); in virtio_gpu_load()
1337 pixman_image_unref(res->image); in virtio_gpu_load()
1339 return -EINVAL; in virtio_gpu_load()
1359 assert(QTAILQ_EMPTY(&g->cmdq)); in virtio_gpu_blob_save()
1361 QTAILQ_FOREACH(res, &g->reslist, next) { in virtio_gpu_blob_save()
1362 if (!res->blob_size) { in virtio_gpu_blob_save()
1365 assert(!res->image); in virtio_gpu_blob_save()
1366 qemu_put_be32(f, res->resource_id); in virtio_gpu_blob_save()
1367 qemu_put_be32(f, res->blob_size); in virtio_gpu_blob_save()
1368 qemu_put_be32(f, res->iov_cnt); in virtio_gpu_blob_save()
1369 for (i = 0; i < res->iov_cnt; i++) { in virtio_gpu_blob_save()
1370 qemu_put_be64(f, res->addrs[i]); in virtio_gpu_blob_save()
1371 qemu_put_be32(f, res->iov[i].iov_len); in virtio_gpu_blob_save()
1391 return -EINVAL; in virtio_gpu_blob_load()
1395 res->resource_id = resource_id; in virtio_gpu_blob_load()
1396 res->blob_size = qemu_get_be32(f); in virtio_gpu_blob_load()
1397 res->iov_cnt = qemu_get_be32(f); in virtio_gpu_blob_load()
1398 res->addrs = g_new(uint64_t, res->iov_cnt); in virtio_gpu_blob_load()
1399 res->iov = g_new(struct iovec, res->iov_cnt); in virtio_gpu_blob_load()
1402 for (i = 0; i < res->iov_cnt; i++) { in virtio_gpu_blob_load()
1403 res->addrs[i] = qemu_get_be64(f); in virtio_gpu_blob_load()
1404 res->iov[i].iov_len = qemu_get_be32(f); in virtio_gpu_blob_load()
1409 return -EINVAL; in virtio_gpu_blob_load()
1427 for (i = 0; i < g->parent_obj.conf.max_outputs; i++) { in virtio_gpu_post_load()
1428 scanout = &g->parent_obj.scanout[i]; in virtio_gpu_post_load()
1429 if (!scanout->resource_id) { in virtio_gpu_post_load()
1433 res = virtio_gpu_find_resource(g, scanout->resource_id); in virtio_gpu_post_load()
1435 return -EINVAL; in virtio_gpu_post_load()
1438 if (scanout->fb.format != 0) { in virtio_gpu_post_load()
1441 .x = scanout->x, in virtio_gpu_post_load()
1442 .y = scanout->y, in virtio_gpu_post_load()
1443 .width = scanout->width, in virtio_gpu_post_load()
1444 .height = scanout->height in virtio_gpu_post_load()
1447 if (!virtio_gpu_do_set_scanout(g, i, &scanout->fb, res, &r, &error)) { in virtio_gpu_post_load()
1448 return -EINVAL; in virtio_gpu_post_load()
1452 if (!res->image) { in virtio_gpu_post_load()
1453 return -EINVAL; in virtio_gpu_post_load()
1455 scanout->ds = qemu_create_displaysurface_pixman(res->image); in virtio_gpu_post_load()
1456 qemu_displaysurface_set_share_handle(scanout->ds, res->share_handle, 0); in virtio_gpu_post_load()
1457 dpy_gfx_replace_surface(scanout->con, scanout->ds); in virtio_gpu_post_load()
1460 dpy_gfx_update_full(scanout->con); in virtio_gpu_post_load()
1461 if (scanout->cursor.resource_id) { in virtio_gpu_post_load()
1462 update_cursor(g, &scanout->cursor); in virtio_gpu_post_load()
1464 res->scanout_bitmask |= (1 << i); in virtio_gpu_post_load()
1475 if (virtio_gpu_blob_enabled(g->parent_obj.conf)) { in virtio_gpu_device_realize()
1476 if (!virtio_gpu_rutabaga_enabled(g->parent_obj.conf) && in virtio_gpu_device_realize()
1477 !virtio_gpu_virgl_enabled(g->parent_obj.conf) && in virtio_gpu_device_realize()
1485 if (virtio_gpu_virgl_enabled(g->parent_obj.conf)) { in virtio_gpu_device_realize()
1493 if (virtio_gpu_venus_enabled(g->parent_obj.conf)) { in virtio_gpu_device_realize()
1496 if (!virtio_gpu_blob_enabled(g->parent_obj.conf) || in virtio_gpu_device_realize()
1497 !virtio_gpu_hostmem_enabled(g->parent_obj.conf)) { in virtio_gpu_device_realize()
1515 g->ctrl_vq = virtio_get_queue(vdev, 0); in virtio_gpu_device_realize()
1516 g->cursor_vq = virtio_get_queue(vdev, 1); in virtio_gpu_device_realize()
1517 g->ctrl_bh = virtio_bh_new_guarded(qdev, virtio_gpu_ctrl_bh, g); in virtio_gpu_device_realize()
1518 g->cursor_bh = virtio_bh_new_guarded(qdev, virtio_gpu_cursor_bh, g); in virtio_gpu_device_realize()
1519 g->reset_bh = qemu_bh_new(virtio_gpu_reset_bh, g); in virtio_gpu_device_realize()
1520 qemu_cond_init(&g->reset_cond); in virtio_gpu_device_realize()
1521 QTAILQ_INIT(&g->reslist); in virtio_gpu_device_realize()
1522 QTAILQ_INIT(&g->cmdq); in virtio_gpu_device_realize()
1523 QTAILQ_INIT(&g->fenceq); in virtio_gpu_device_realize()
1530 g_clear_pointer(&g->ctrl_bh, qemu_bh_delete); in virtio_gpu_device_unrealize()
1531 g_clear_pointer(&g->cursor_bh, qemu_bh_delete); in virtio_gpu_device_unrealize()
1532 g_clear_pointer(&g->reset_bh, qemu_bh_delete); in virtio_gpu_device_unrealize()
1533 qemu_cond_destroy(&g->reset_cond); in virtio_gpu_device_unrealize()
1546 QTAILQ_FOREACH_SAFE(res, &g->reslist, next, tmp) { in virtio_gpu_reset_bh()
1547 resource_id = res->resource_id; in virtio_gpu_reset_bh()
1548 vgc->resource_destroy(g, res, &local_err); in virtio_gpu_reset_bh()
1560 for (i = 0; i < g->parent_obj.conf.max_outputs; i++) { in virtio_gpu_reset_bh()
1561 dpy_gfx_replace_surface(g->parent_obj.scanout[i].con, NULL); in virtio_gpu_reset_bh()
1564 g->reset_finished = true; in virtio_gpu_reset_bh()
1565 qemu_cond_signal(&g->reset_cond); in virtio_gpu_reset_bh()
1574 g->reset_finished = false; in virtio_gpu_reset()
1575 qemu_bh_schedule(g->reset_bh); in virtio_gpu_reset()
1576 while (!g->reset_finished) { in virtio_gpu_reset()
1577 qemu_cond_wait_bql(&g->reset_cond); in virtio_gpu_reset()
1580 aio_bh_call(g->reset_bh); in virtio_gpu_reset()
1583 while (!QTAILQ_EMPTY(&g->cmdq)) { in virtio_gpu_reset()
1584 cmd = QTAILQ_FIRST(&g->cmdq); in virtio_gpu_reset()
1585 QTAILQ_REMOVE(&g->cmdq, cmd, next); in virtio_gpu_reset()
1589 while (!QTAILQ_EMPTY(&g->fenceq)) { in virtio_gpu_reset()
1590 cmd = QTAILQ_FIRST(&g->fenceq); in virtio_gpu_reset()
1591 QTAILQ_REMOVE(&g->fenceq, cmd, next); in virtio_gpu_reset()
1592 g->inflight--; in virtio_gpu_reset()
1604 memcpy(config, &g->virtio_config, sizeof(g->virtio_config)); in virtio_gpu_get_config()
1614 if (vgconfig->events_clear) { in virtio_gpu_set_config()
1615 g->virtio_config.events_read &= ~vgconfig->events_clear; in virtio_gpu_set_config()
1623 return virtio_gpu_blob_enabled(g->parent_obj.conf); in virtio_gpu_blob_state_needed()
1627 .name = "virtio-gpu/blob",
1633 .name = "virtio-gpu/blob",
1647 * scheme as described in doc/virtio-migration.txt, in a sense that no
1654 .name = "virtio-gpu",
1660 .name = "virtio-gpu",
1662 .name = "virtio-gpu",
1678 VIRTIO_GPU_BASE_PROPERTIES(VirtIOGPU, parent_obj.conf),
1681 DEFINE_PROP_BIT("blob", VirtIOGPU, parent_obj.conf.flags,
1683 DEFINE_PROP_SIZE("hostmem", VirtIOGPU, parent_obj.conf.hostmem, 0),
1684 DEFINE_PROP_UINT8("x-scanout-vmstate-version", VirtIOGPU, scanout_vmstate_version, 2),
1693 VirtIOGPUBaseClass *vgbc = &vgc->parent; in virtio_gpu_class_init()
1695 vgc->handle_ctrl = virtio_gpu_handle_ctrl; in virtio_gpu_class_init()
1696 vgc->process_cmd = virtio_gpu_simple_process_cmd; in virtio_gpu_class_init()
1697 vgc->update_cursor_data = virtio_gpu_update_cursor_data; in virtio_gpu_class_init()
1698 vgc->resource_destroy = virtio_gpu_resource_destroy; in virtio_gpu_class_init()
1699 vgbc->gl_flushed = virtio_gpu_handle_gl_flushed; in virtio_gpu_class_init()
1701 vdc->realize = virtio_gpu_device_realize; in virtio_gpu_class_init()
1702 vdc->unrealize = virtio_gpu_device_unrealize; in virtio_gpu_class_init()
1703 vdc->reset = virtio_gpu_reset; in virtio_gpu_class_init()
1704 vdc->get_config = virtio_gpu_get_config; in virtio_gpu_class_init()
1705 vdc->set_config = virtio_gpu_set_config; in virtio_gpu_class_init()
1707 dc->vmsd = &vmstate_virtio_gpu; in virtio_gpu_class_init()