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