]>
Commit | Line | Data |
---|---|---|
62232bf4 GH |
1 | /* |
2 | * Virtio GPU Device | |
3 | * | |
4 | * Copyright Red Hat, Inc. 2013-2014 | |
5 | * | |
6 | * Authors: | |
7 | * Dave Airlie <[email protected]> | |
8 | * Gerd Hoffmann <[email protected]> | |
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" |
c821774a | 28 | OBJECT_DECLARE_TYPE(VirtIOGPUBase, VirtIOGPUBaseClass, |
30b5707c | 29 | VIRTIO_GPU_BASE) |
50d8e25e | 30 | |
62232bf4 | 31 | #define TYPE_VIRTIO_GPU "virtio-gpu-device" |
cabbe8e5 | 32 | OBJECT_DECLARE_TYPE(VirtIOGPU, VirtIOGPUClass, VIRTIO_GPU) |
62232bf4 | 33 | |
063cd34a GH |
34 | #define TYPE_VIRTIO_GPU_GL "virtio-gpu-gl-device" |
35 | OBJECT_DECLARE_SIMPLE_TYPE(VirtIOGPUGL, VIRTIO_GPU_GL) | |
36 | ||
267f6646 | 37 | #define TYPE_VHOST_USER_GPU "vhost-user-gpu" |
8063396b | 38 | OBJECT_DECLARE_SIMPLE_TYPE(VhostUserGPU, VHOST_USER_GPU) |
267f6646 | 39 | |
62232bf4 GH |
40 | #define VIRTIO_ID_GPU 16 |
41 | ||
62232bf4 GH |
42 | struct virtio_gpu_simple_resource { |
43 | uint32_t resource_id; | |
44 | uint32_t width; | |
45 | uint32_t height; | |
46 | uint32_t format; | |
0c244e50 | 47 | uint64_t *addrs; |
62232bf4 GH |
48 | struct iovec *iov; |
49 | unsigned int iov_cnt; | |
50 | uint32_t scanout_bitmask; | |
51 | pixman_image_t *image; | |
9b7621bc | 52 | uint64_t hostmem; |
9b60cdf9 VK |
53 | |
54 | uint64_t blob_size; | |
55 | void *blob; | |
56 | int dmabuf_fd; | |
57 | uint8_t *remapped; | |
58 | ||
62232bf4 GH |
59 | QTAILQ_ENTRY(virtio_gpu_simple_resource) next; |
60 | }; | |
61 | ||
e64d4b6a VK |
62 | struct virtio_gpu_framebuffer { |
63 | pixman_format_code_t format; | |
64 | uint32_t bytes_pp; | |
65 | uint32_t width, height; | |
66 | uint32_t stride; | |
67 | uint32_t offset; | |
68 | }; | |
69 | ||
62232bf4 GH |
70 | struct virtio_gpu_scanout { |
71 | QemuConsole *con; | |
72 | DisplaySurface *ds; | |
73 | uint32_t width, height; | |
74 | int x, y; | |
75 | int invalidate; | |
76 | uint32_t resource_id; | |
0c244e50 | 77 | struct virtio_gpu_update_cursor cursor; |
62232bf4 GH |
78 | QEMUCursor *current_cursor; |
79 | }; | |
80 | ||
81 | struct virtio_gpu_requested_state { | |
4bf47f36 | 82 | uint16_t width_mm, height_mm; |
62232bf4 GH |
83 | uint32_t width, height; |
84 | int x, y; | |
85 | }; | |
86 | ||
50d8e25e | 87 | enum virtio_gpu_base_conf_flags { |
9d9e1521 GH |
88 | VIRTIO_GPU_FLAG_VIRGL_ENABLED = 1, |
89 | VIRTIO_GPU_FLAG_STATS_ENABLED, | |
1ed2cb32 | 90 | VIRTIO_GPU_FLAG_EDID_ENABLED, |
ff64d44f | 91 | VIRTIO_GPU_FLAG_DMABUF_ENABLED, |
9d9e1521 GH |
92 | }; |
93 | ||
94 | #define virtio_gpu_virgl_enabled(_cfg) \ | |
95 | (_cfg.flags & (1 << VIRTIO_GPU_FLAG_VIRGL_ENABLED)) | |
96 | #define virtio_gpu_stats_enabled(_cfg) \ | |
97 | (_cfg.flags & (1 << VIRTIO_GPU_FLAG_STATS_ENABLED)) | |
1ed2cb32 GH |
98 | #define virtio_gpu_edid_enabled(_cfg) \ |
99 | (_cfg.flags & (1 << VIRTIO_GPU_FLAG_EDID_ENABLED)) | |
ff64d44f MAL |
100 | #define virtio_gpu_dmabuf_enabled(_cfg) \ |
101 | (_cfg.flags & (1 << VIRTIO_GPU_FLAG_DMABUF_ENABLED)) | |
9d9e1521 | 102 | |
50d8e25e | 103 | struct virtio_gpu_base_conf { |
62232bf4 | 104 | uint32_t max_outputs; |
9d9e1521 | 105 | uint32_t flags; |
729abb6a GH |
106 | uint32_t xres; |
107 | uint32_t yres; | |
62232bf4 GH |
108 | }; |
109 | ||
110 | struct virtio_gpu_ctrl_command { | |
111 | VirtQueueElement elem; | |
112 | VirtQueue *vq; | |
113 | struct virtio_gpu_ctrl_hdr cmd_hdr; | |
114 | uint32_t error; | |
115 | bool finished; | |
116 | QTAILQ_ENTRY(virtio_gpu_ctrl_command) next; | |
117 | }; | |
118 | ||
db1015e9 | 119 | struct VirtIOGPUBase { |
62232bf4 GH |
120 | VirtIODevice parent_obj; |
121 | ||
50d8e25e MAL |
122 | Error *migration_blocker; |
123 | ||
124 | struct virtio_gpu_base_conf conf; | |
125 | struct virtio_gpu_config virtio_config; | |
3b593b3f | 126 | const GraphicHwOps *hw_ops; |
50d8e25e | 127 | |
50d8e25e MAL |
128 | int renderer_blocked; |
129 | int enable; | |
130 | ||
131 | struct virtio_gpu_scanout scanout[VIRTIO_GPU_MAX_SCANOUTS]; | |
132 | ||
133 | int enabled_output_bitmask; | |
134 | struct virtio_gpu_requested_state req_state[VIRTIO_GPU_MAX_SCANOUTS]; | |
db1015e9 | 135 | }; |
50d8e25e | 136 | |
db1015e9 | 137 | struct VirtIOGPUBaseClass { |
50d8e25e MAL |
138 | VirtioDeviceClass parent; |
139 | ||
3cddb8b9 | 140 | void (*gl_flushed)(VirtIOGPUBase *g); |
db1015e9 | 141 | }; |
50d8e25e MAL |
142 | |
143 | #define VIRTIO_GPU_BASE_PROPERTIES(_state, _conf) \ | |
144 | DEFINE_PROP_UINT32("max_outputs", _state, _conf.max_outputs, 1), \ | |
145 | DEFINE_PROP_BIT("edid", _state, _conf.flags, \ | |
0a719662 | 146 | VIRTIO_GPU_FLAG_EDID_ENABLED, true), \ |
50d8e25e MAL |
147 | DEFINE_PROP_UINT32("xres", _state, _conf.xres, 1024), \ |
148 | DEFINE_PROP_UINT32("yres", _state, _conf.yres, 768) | |
149 | ||
db1015e9 | 150 | struct VirtIOGPU { |
50d8e25e MAL |
151 | VirtIOGPUBase parent_obj; |
152 | ||
153 | uint64_t conf_max_hostmem; | |
154 | ||
62232bf4 GH |
155 | VirtQueue *ctrl_vq; |
156 | VirtQueue *cursor_vq; | |
157 | ||
50d8e25e MAL |
158 | QEMUBH *ctrl_bh; |
159 | QEMUBH *cursor_bh; | |
62232bf4 | 160 | |
62232bf4 | 161 | QTAILQ_HEAD(, virtio_gpu_simple_resource) reslist; |
3eb769fd | 162 | QTAILQ_HEAD(, virtio_gpu_ctrl_command) cmdq; |
62232bf4 GH |
163 | QTAILQ_HEAD(, virtio_gpu_ctrl_command) fenceq; |
164 | ||
9b7621bc | 165 | uint64_t hostmem; |
62232bf4 | 166 | |
f8f3c271 | 167 | bool processing_cmdq; |
62232bf4 GH |
168 | QEMUTimer *fence_poll; |
169 | QEMUTimer *print_stats; | |
170 | ||
9d9e1521 | 171 | uint32_t inflight; |
62232bf4 | 172 | struct { |
62232bf4 GH |
173 | uint32_t max_inflight; |
174 | uint32_t requests; | |
175 | uint32_t req_3d; | |
176 | uint32_t bytes_3d; | |
177 | } stats; | |
db1015e9 | 178 | }; |
62232bf4 | 179 | |
cabbe8e5 GH |
180 | struct VirtIOGPUClass { |
181 | VirtIOGPUBaseClass parent; | |
182 | ||
183 | void (*handle_ctrl)(VirtIODevice *vdev, VirtQueue *vq); | |
2f47691a | 184 | void (*process_cmd)(VirtIOGPU *g, struct virtio_gpu_ctrl_command *cmd); |
2c267d66 GH |
185 | void (*update_cursor_data)(VirtIOGPU *g, |
186 | struct virtio_gpu_scanout *s, | |
187 | uint32_t resource_id); | |
cabbe8e5 GH |
188 | }; |
189 | ||
063cd34a GH |
190 | struct VirtIOGPUGL { |
191 | struct VirtIOGPU parent_obj; | |
eff6fa17 GH |
192 | |
193 | bool renderer_inited; | |
194 | bool renderer_reset; | |
063cd34a GH |
195 | }; |
196 | ||
db1015e9 | 197 | struct VhostUserGPU { |
267f6646 | 198 | VirtIOGPUBase parent_obj; |
62232bf4 | 199 | |
267f6646 MAL |
200 | VhostUserBackend *vhost; |
201 | int vhost_gpu_fd; /* closed by the chardev */ | |
202 | CharBackend vhost_chr; | |
203 | QemuDmaBuf dmabuf[VIRTIO_GPU_MAX_SCANOUTS]; | |
204 | bool backend_blocked; | |
db1015e9 | 205 | }; |
267f6646 | 206 | |
62232bf4 GH |
207 | #define VIRTIO_GPU_FILL_CMD(out) do { \ |
208 | size_t s; \ | |
209 | s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0, \ | |
210 | &out, sizeof(out)); \ | |
211 | if (s != sizeof(out)) { \ | |
212 | qemu_log_mask(LOG_GUEST_ERROR, \ | |
213 | "%s: command size incorrect %zu vs %zu\n", \ | |
214 | __func__, s, sizeof(out)); \ | |
215 | return; \ | |
216 | } \ | |
217 | } while (0) | |
218 | ||
50d8e25e MAL |
219 | /* virtio-gpu-base.c */ |
220 | bool virtio_gpu_base_device_realize(DeviceState *qdev, | |
221 | VirtIOHandleOutput ctrl_cb, | |
222 | VirtIOHandleOutput cursor_cb, | |
223 | Error **errp); | |
224 | void virtio_gpu_base_reset(VirtIOGPUBase *g); | |
225 | void virtio_gpu_base_fill_display_info(VirtIOGPUBase *g, | |
226 | struct virtio_gpu_resp_display_info *dpy_info); | |
227 | ||
62232bf4 GH |
228 | /* virtio-gpu.c */ |
229 | void virtio_gpu_ctrl_response(VirtIOGPU *g, | |
230 | struct virtio_gpu_ctrl_command *cmd, | |
231 | struct virtio_gpu_ctrl_hdr *resp, | |
232 | size_t resp_len); | |
233 | void virtio_gpu_ctrl_response_nodata(VirtIOGPU *g, | |
234 | struct virtio_gpu_ctrl_command *cmd, | |
235 | enum virtio_gpu_ctrl_type type); | |
236 | void virtio_gpu_get_display_info(VirtIOGPU *g, | |
237 | struct virtio_gpu_ctrl_command *cmd); | |
1ed2cb32 GH |
238 | void virtio_gpu_get_edid(VirtIOGPU *g, |
239 | struct virtio_gpu_ctrl_command *cmd); | |
3bb68f79 GH |
240 | int virtio_gpu_create_mapping_iov(VirtIOGPU *g, |
241 | struct virtio_gpu_resource_attach_backing *ab, | |
62232bf4 | 242 | struct virtio_gpu_ctrl_command *cmd, |
9049f8bc GH |
243 | uint64_t **addr, struct iovec **iov, |
244 | uint32_t *niov); | |
3bb68f79 GH |
245 | void virtio_gpu_cleanup_mapping_iov(VirtIOGPU *g, |
246 | struct iovec *iov, uint32_t count); | |
0c55a1cf | 247 | void virtio_gpu_process_cmdq(VirtIOGPU *g); |
37f86af0 | 248 | void virtio_gpu_device_realize(DeviceState *qdev, Error **errp); |
76fa8b35 | 249 | void virtio_gpu_reset(VirtIODevice *vdev); |
2f47691a | 250 | void virtio_gpu_simple_process_cmd(VirtIOGPU *g, struct virtio_gpu_ctrl_command *cmd); |
2c267d66 GH |
251 | void virtio_gpu_update_cursor_data(VirtIOGPU *g, |
252 | struct virtio_gpu_scanout *s, | |
253 | uint32_t resource_id); | |
62232bf4 | 254 | |
9b60cdf9 VK |
255 | /* virtio-gpu-udmabuf.c */ |
256 | bool virtio_gpu_have_udmabuf(void); | |
257 | void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res); | |
258 | void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res); | |
259 | ||
9d9e1521 GH |
260 | /* virtio-gpu-3d.c */ |
261 | void virtio_gpu_virgl_process_cmd(VirtIOGPU *g, | |
262 | struct virtio_gpu_ctrl_command *cmd); | |
263 | void virtio_gpu_virgl_fence_poll(VirtIOGPU *g); | |
264 | void virtio_gpu_virgl_reset(VirtIOGPU *g); | |
265 | int virtio_gpu_virgl_init(VirtIOGPU *g); | |
5643cc94 | 266 | int virtio_gpu_virgl_get_num_capsets(VirtIOGPU *g); |
50d8e25e | 267 | |
62232bf4 | 268 | #endif |