1 /* 2 * Virtio GPU Device 3 * 4 * Copyright Red Hat, Inc. 2013-2014 5 * 6 * Authors: 7 * Dave Airlie <airlied@redhat.com> 8 * Gerd Hoffmann <kraxel@redhat.com> 9 * 10 * This work is licensed under the terms of the GNU GPL, version 2. 11 * See the COPYING file in the top-level directory. 12 */ 13 14 #ifndef _QEMU_VIRTIO_VGA_H 15 #define _QEMU_VIRTIO_VGA_H 16 17 #include "qemu/queue.h" 18 #include "ui/qemu-pixman.h" 19 #include "ui/console.h" 20 #include "hw/virtio/virtio.h" 21 #include "hw/pci/pci.h" 22 23 #include "standard-headers/linux/virtio_gpu.h" 24 #define TYPE_VIRTIO_GPU "virtio-gpu-device" 25 #define VIRTIO_GPU(obj) \ 26 OBJECT_CHECK(VirtIOGPU, (obj), TYPE_VIRTIO_GPU) 27 28 #define VIRTIO_ID_GPU 16 29 30 struct virtio_gpu_simple_resource { 31 uint32_t resource_id; 32 uint32_t width; 33 uint32_t height; 34 uint32_t format; 35 struct iovec *iov; 36 unsigned int iov_cnt; 37 uint32_t scanout_bitmask; 38 pixman_image_t *image; 39 QTAILQ_ENTRY(virtio_gpu_simple_resource) next; 40 }; 41 42 struct virtio_gpu_scanout { 43 QemuConsole *con; 44 DisplaySurface *ds; 45 uint32_t width, height; 46 int x, y; 47 int invalidate; 48 uint32_t resource_id; 49 QEMUCursor *current_cursor; 50 }; 51 52 struct virtio_gpu_requested_state { 53 uint32_t width, height; 54 int x, y; 55 }; 56 57 enum virtio_gpu_conf_flags { 58 VIRTIO_GPU_FLAG_VIRGL_ENABLED = 1, 59 VIRTIO_GPU_FLAG_STATS_ENABLED, 60 }; 61 62 #define virtio_gpu_virgl_enabled(_cfg) \ 63 (_cfg.flags & (1 << VIRTIO_GPU_FLAG_VIRGL_ENABLED)) 64 #define virtio_gpu_stats_enabled(_cfg) \ 65 (_cfg.flags & (1 << VIRTIO_GPU_FLAG_STATS_ENABLED)) 66 67 struct virtio_gpu_conf { 68 uint32_t max_outputs; 69 uint32_t flags; 70 }; 71 72 struct virtio_gpu_ctrl_command { 73 VirtQueueElement elem; 74 VirtQueue *vq; 75 struct virtio_gpu_ctrl_hdr cmd_hdr; 76 uint32_t error; 77 bool waiting; 78 bool finished; 79 QTAILQ_ENTRY(virtio_gpu_ctrl_command) next; 80 }; 81 82 typedef struct VirtIOGPU { 83 VirtIODevice parent_obj; 84 85 QEMUBH *ctrl_bh; 86 QEMUBH *cursor_bh; 87 VirtQueue *ctrl_vq; 88 VirtQueue *cursor_vq; 89 90 int enable; 91 92 int config_size; 93 DeviceState *qdev; 94 95 QTAILQ_HEAD(, virtio_gpu_simple_resource) reslist; 96 QTAILQ_HEAD(, virtio_gpu_ctrl_command) cmdq; 97 QTAILQ_HEAD(, virtio_gpu_ctrl_command) fenceq; 98 99 struct virtio_gpu_scanout scanout[VIRTIO_GPU_MAX_SCANOUTS]; 100 struct virtio_gpu_requested_state req_state[VIRTIO_GPU_MAX_SCANOUTS]; 101 102 struct virtio_gpu_conf conf; 103 int enabled_output_bitmask; 104 struct virtio_gpu_config virtio_config; 105 106 bool use_virgl_renderer; 107 bool renderer_inited; 108 bool renderer_blocked; 109 QEMUTimer *fence_poll; 110 QEMUTimer *print_stats; 111 112 uint32_t inflight; 113 struct { 114 uint32_t max_inflight; 115 uint32_t requests; 116 uint32_t req_3d; 117 uint32_t bytes_3d; 118 } stats; 119 } VirtIOGPU; 120 121 extern const GraphicHwOps virtio_gpu_ops; 122 123 /* to share between PCI and VGA */ 124 #define DEFINE_VIRTIO_GPU_PCI_PROPERTIES(_state) \ 125 DEFINE_PROP_BIT("ioeventfd", _state, flags, \ 126 VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false), \ 127 DEFINE_PROP_UINT32("vectors", _state, nvectors, 3) 128 129 #define VIRTIO_GPU_FILL_CMD(out) do { \ 130 size_t s; \ 131 s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0, \ 132 &out, sizeof(out)); \ 133 if (s != sizeof(out)) { \ 134 qemu_log_mask(LOG_GUEST_ERROR, \ 135 "%s: command size incorrect %zu vs %zu\n", \ 136 __func__, s, sizeof(out)); \ 137 return; \ 138 } \ 139 } while (0) 140 141 /* virtio-gpu.c */ 142 void virtio_gpu_ctrl_response(VirtIOGPU *g, 143 struct virtio_gpu_ctrl_command *cmd, 144 struct virtio_gpu_ctrl_hdr *resp, 145 size_t resp_len); 146 void virtio_gpu_ctrl_response_nodata(VirtIOGPU *g, 147 struct virtio_gpu_ctrl_command *cmd, 148 enum virtio_gpu_ctrl_type type); 149 void virtio_gpu_get_display_info(VirtIOGPU *g, 150 struct virtio_gpu_ctrl_command *cmd); 151 int virtio_gpu_create_mapping_iov(struct virtio_gpu_resource_attach_backing *ab, 152 struct virtio_gpu_ctrl_command *cmd, 153 struct iovec **iov); 154 void virtio_gpu_cleanup_mapping_iov(struct iovec *iov, uint32_t count); 155 void virtio_gpu_process_cmdq(VirtIOGPU *g); 156 157 /* virtio-gpu-3d.c */ 158 void virtio_gpu_virgl_process_cmd(VirtIOGPU *g, 159 struct virtio_gpu_ctrl_command *cmd); 160 void virtio_gpu_virgl_fence_poll(VirtIOGPU *g); 161 void virtio_gpu_virgl_reset(VirtIOGPU *g); 162 int virtio_gpu_virgl_init(VirtIOGPU *g); 163 164 #endif 165