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