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 HW_VIRTIO_GPU_H 15 #define HW_VIRTIO_GPU_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 "qemu/log.h" 22 #include "sysemu/vhost-user-backend.h" 23 24 #include "standard-headers/linux/virtio_gpu.h" 25 #include "qom/object.h" 26 27 #define TYPE_VIRTIO_GPU_BASE "virtio-gpu-base" 28 typedef struct VirtIOGPUBase VirtIOGPUBase; 29 typedef struct VirtIOGPUBaseClass VirtIOGPUBaseClass; 30 #define VIRTIO_GPU_BASE(obj) \ 31 OBJECT_CHECK(VirtIOGPUBase, (obj), TYPE_VIRTIO_GPU_BASE) 32 #define VIRTIO_GPU_BASE_GET_CLASS(obj) \ 33 OBJECT_GET_CLASS(VirtIOGPUBaseClass, obj, TYPE_VIRTIO_GPU_BASE) 34 #define VIRTIO_GPU_BASE_CLASS(klass) \ 35 OBJECT_CLASS_CHECK(VirtIOGPUBaseClass, klass, TYPE_VIRTIO_GPU_BASE) 36 37 #define TYPE_VIRTIO_GPU "virtio-gpu-device" 38 typedef struct VirtIOGPU VirtIOGPU; 39 #define VIRTIO_GPU(obj) \ 40 OBJECT_CHECK(VirtIOGPU, (obj), TYPE_VIRTIO_GPU) 41 42 #define TYPE_VHOST_USER_GPU "vhost-user-gpu" 43 typedef struct VhostUserGPU VhostUserGPU; 44 #define VHOST_USER_GPU(obj) \ 45 OBJECT_CHECK(VhostUserGPU, (obj), TYPE_VHOST_USER_GPU) 46 47 #define VIRTIO_ID_GPU 16 48 49 struct virtio_gpu_simple_resource { 50 uint32_t resource_id; 51 uint32_t width; 52 uint32_t height; 53 uint32_t format; 54 uint64_t *addrs; 55 struct iovec *iov; 56 unsigned int iov_cnt; 57 uint32_t scanout_bitmask; 58 pixman_image_t *image; 59 uint64_t hostmem; 60 QTAILQ_ENTRY(virtio_gpu_simple_resource) next; 61 }; 62 63 struct virtio_gpu_scanout { 64 QemuConsole *con; 65 DisplaySurface *ds; 66 uint32_t width, height; 67 int x, y; 68 int invalidate; 69 uint32_t resource_id; 70 struct virtio_gpu_update_cursor cursor; 71 QEMUCursor *current_cursor; 72 }; 73 74 struct virtio_gpu_requested_state { 75 uint32_t width, height; 76 int x, y; 77 }; 78 79 enum virtio_gpu_base_conf_flags { 80 VIRTIO_GPU_FLAG_VIRGL_ENABLED = 1, 81 VIRTIO_GPU_FLAG_STATS_ENABLED, 82 VIRTIO_GPU_FLAG_EDID_ENABLED, 83 }; 84 85 #define virtio_gpu_virgl_enabled(_cfg) \ 86 (_cfg.flags & (1 << VIRTIO_GPU_FLAG_VIRGL_ENABLED)) 87 #define virtio_gpu_stats_enabled(_cfg) \ 88 (_cfg.flags & (1 << VIRTIO_GPU_FLAG_STATS_ENABLED)) 89 #define virtio_gpu_edid_enabled(_cfg) \ 90 (_cfg.flags & (1 << VIRTIO_GPU_FLAG_EDID_ENABLED)) 91 92 struct virtio_gpu_base_conf { 93 uint32_t max_outputs; 94 uint32_t flags; 95 uint32_t xres; 96 uint32_t yres; 97 }; 98 99 struct virtio_gpu_ctrl_command { 100 VirtQueueElement elem; 101 VirtQueue *vq; 102 struct virtio_gpu_ctrl_hdr cmd_hdr; 103 uint32_t error; 104 bool finished; 105 QTAILQ_ENTRY(virtio_gpu_ctrl_command) next; 106 }; 107 108 struct VirtIOGPUBase { 109 VirtIODevice parent_obj; 110 111 Error *migration_blocker; 112 113 struct virtio_gpu_base_conf conf; 114 struct virtio_gpu_config virtio_config; 115 116 bool use_virgl_renderer; 117 int renderer_blocked; 118 int enable; 119 120 struct virtio_gpu_scanout scanout[VIRTIO_GPU_MAX_SCANOUTS]; 121 122 int enabled_output_bitmask; 123 struct virtio_gpu_requested_state req_state[VIRTIO_GPU_MAX_SCANOUTS]; 124 }; 125 126 struct VirtIOGPUBaseClass { 127 VirtioDeviceClass parent; 128 129 void (*gl_unblock)(VirtIOGPUBase *g); 130 }; 131 132 #define VIRTIO_GPU_BASE_PROPERTIES(_state, _conf) \ 133 DEFINE_PROP_UINT32("max_outputs", _state, _conf.max_outputs, 1), \ 134 DEFINE_PROP_BIT("edid", _state, _conf.flags, \ 135 VIRTIO_GPU_FLAG_EDID_ENABLED, true), \ 136 DEFINE_PROP_UINT32("xres", _state, _conf.xres, 1024), \ 137 DEFINE_PROP_UINT32("yres", _state, _conf.yres, 768) 138 139 struct VirtIOGPU { 140 VirtIOGPUBase parent_obj; 141 142 uint64_t conf_max_hostmem; 143 144 VirtQueue *ctrl_vq; 145 VirtQueue *cursor_vq; 146 147 QEMUBH *ctrl_bh; 148 QEMUBH *cursor_bh; 149 150 QTAILQ_HEAD(, virtio_gpu_simple_resource) reslist; 151 QTAILQ_HEAD(, virtio_gpu_ctrl_command) cmdq; 152 QTAILQ_HEAD(, virtio_gpu_ctrl_command) fenceq; 153 154 uint64_t hostmem; 155 156 bool renderer_inited; 157 bool renderer_reset; 158 QEMUTimer *fence_poll; 159 QEMUTimer *print_stats; 160 161 uint32_t inflight; 162 struct { 163 uint32_t max_inflight; 164 uint32_t requests; 165 uint32_t req_3d; 166 uint32_t bytes_3d; 167 } stats; 168 }; 169 170 struct VhostUserGPU { 171 VirtIOGPUBase parent_obj; 172 173 VhostUserBackend *vhost; 174 int vhost_gpu_fd; /* closed by the chardev */ 175 CharBackend vhost_chr; 176 QemuDmaBuf dmabuf[VIRTIO_GPU_MAX_SCANOUTS]; 177 bool backend_blocked; 178 }; 179 180 extern const GraphicHwOps virtio_gpu_ops; 181 182 #define VIRTIO_GPU_FILL_CMD(out) do { \ 183 size_t s; \ 184 s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0, \ 185 &out, sizeof(out)); \ 186 if (s != sizeof(out)) { \ 187 qemu_log_mask(LOG_GUEST_ERROR, \ 188 "%s: command size incorrect %zu vs %zu\n", \ 189 __func__, s, sizeof(out)); \ 190 return; \ 191 } \ 192 } while (0) 193 194 /* virtio-gpu-base.c */ 195 bool virtio_gpu_base_device_realize(DeviceState *qdev, 196 VirtIOHandleOutput ctrl_cb, 197 VirtIOHandleOutput cursor_cb, 198 Error **errp); 199 void virtio_gpu_base_reset(VirtIOGPUBase *g); 200 void virtio_gpu_base_fill_display_info(VirtIOGPUBase *g, 201 struct virtio_gpu_resp_display_info *dpy_info); 202 203 /* virtio-gpu.c */ 204 void virtio_gpu_ctrl_response(VirtIOGPU *g, 205 struct virtio_gpu_ctrl_command *cmd, 206 struct virtio_gpu_ctrl_hdr *resp, 207 size_t resp_len); 208 void virtio_gpu_ctrl_response_nodata(VirtIOGPU *g, 209 struct virtio_gpu_ctrl_command *cmd, 210 enum virtio_gpu_ctrl_type type); 211 void virtio_gpu_get_display_info(VirtIOGPU *g, 212 struct virtio_gpu_ctrl_command *cmd); 213 void virtio_gpu_get_edid(VirtIOGPU *g, 214 struct virtio_gpu_ctrl_command *cmd); 215 int virtio_gpu_create_mapping_iov(VirtIOGPU *g, 216 struct virtio_gpu_resource_attach_backing *ab, 217 struct virtio_gpu_ctrl_command *cmd, 218 uint64_t **addr, struct iovec **iov); 219 void virtio_gpu_cleanup_mapping_iov(VirtIOGPU *g, 220 struct iovec *iov, uint32_t count); 221 void virtio_gpu_process_cmdq(VirtIOGPU *g); 222 223 /* virtio-gpu-3d.c */ 224 void virtio_gpu_virgl_process_cmd(VirtIOGPU *g, 225 struct virtio_gpu_ctrl_command *cmd); 226 void virtio_gpu_virgl_fence_poll(VirtIOGPU *g); 227 void virtio_gpu_virgl_reset(VirtIOGPU *g); 228 int virtio_gpu_virgl_init(VirtIOGPU *g); 229 int virtio_gpu_virgl_get_num_capsets(VirtIOGPU *g); 230 231 #endif 232