]>
Commit | Line | Data |
---|---|---|
d52c454a MAL |
1 | /* |
2 | * Virtio vhost-user GPU Device | |
3 | * | |
4 | * Copyright Red Hat, Inc. 2013-2018 | |
5 | * | |
6 | * Authors: | |
7 | * Dave Airlie <airlied@redhat.com> | |
8 | * Gerd Hoffmann <kraxel@redhat.com> | |
9 | * Marc-André Lureau <marcandre.lureau@redhat.com> | |
10 | * | |
11 | * This work is licensed under the terms of the GNU GPL, version 2 or later. | |
12 | * See the COPYING file in the top-level directory. | |
13 | */ | |
fe2611b0 MA |
14 | |
15 | #ifndef VUGPU_H | |
16 | #define VUGPU_H | |
d52c454a | 17 | |
d52c454a | 18 | |
0df750e9 | 19 | #include "libvhost-user-glib.h" |
d52c454a MAL |
20 | #include "standard-headers/linux/virtio_gpu.h" |
21 | ||
22 | #include "qemu/queue.h" | |
23 | #include "qemu/iov.h" | |
24 | #include "qemu/bswap.h" | |
25 | #include "vugbm.h" | |
26 | ||
27 | typedef enum VhostUserGpuRequest { | |
28 | VHOST_USER_GPU_NONE = 0, | |
29 | VHOST_USER_GPU_GET_PROTOCOL_FEATURES, | |
30 | VHOST_USER_GPU_SET_PROTOCOL_FEATURES, | |
31 | VHOST_USER_GPU_GET_DISPLAY_INFO, | |
32 | VHOST_USER_GPU_CURSOR_POS, | |
33 | VHOST_USER_GPU_CURSOR_POS_HIDE, | |
34 | VHOST_USER_GPU_CURSOR_UPDATE, | |
35 | VHOST_USER_GPU_SCANOUT, | |
36 | VHOST_USER_GPU_UPDATE, | |
37 | VHOST_USER_GPU_DMABUF_SCANOUT, | |
38 | VHOST_USER_GPU_DMABUF_UPDATE, | |
39 | } VhostUserGpuRequest; | |
40 | ||
41 | typedef struct VhostUserGpuDisplayInfoReply { | |
42 | struct virtio_gpu_resp_display_info info; | |
43 | } VhostUserGpuDisplayInfoReply; | |
44 | ||
45 | typedef struct VhostUserGpuCursorPos { | |
46 | uint32_t scanout_id; | |
47 | uint32_t x; | |
48 | uint32_t y; | |
49 | } QEMU_PACKED VhostUserGpuCursorPos; | |
50 | ||
51 | typedef struct VhostUserGpuCursorUpdate { | |
52 | VhostUserGpuCursorPos pos; | |
53 | uint32_t hot_x; | |
54 | uint32_t hot_y; | |
55 | uint32_t data[64 * 64]; | |
56 | } QEMU_PACKED VhostUserGpuCursorUpdate; | |
57 | ||
58 | typedef struct VhostUserGpuScanout { | |
59 | uint32_t scanout_id; | |
60 | uint32_t width; | |
61 | uint32_t height; | |
62 | } QEMU_PACKED VhostUserGpuScanout; | |
63 | ||
64 | typedef struct VhostUserGpuUpdate { | |
65 | uint32_t scanout_id; | |
66 | uint32_t x; | |
67 | uint32_t y; | |
68 | uint32_t width; | |
69 | uint32_t height; | |
70 | uint8_t data[]; | |
71 | } QEMU_PACKED VhostUserGpuUpdate; | |
72 | ||
73 | typedef struct VhostUserGpuDMABUFScanout { | |
74 | uint32_t scanout_id; | |
75 | uint32_t x; | |
76 | uint32_t y; | |
77 | uint32_t width; | |
78 | uint32_t height; | |
79 | uint32_t fd_width; | |
80 | uint32_t fd_height; | |
81 | uint32_t fd_stride; | |
82 | uint32_t fd_flags; | |
83 | int fd_drm_fourcc; | |
84 | } QEMU_PACKED VhostUserGpuDMABUFScanout; | |
85 | ||
86 | typedef struct VhostUserGpuMsg { | |
87 | uint32_t request; /* VhostUserGpuRequest */ | |
88 | uint32_t flags; | |
89 | uint32_t size; /* the following payload size */ | |
90 | union { | |
91 | VhostUserGpuCursorPos cursor_pos; | |
92 | VhostUserGpuCursorUpdate cursor_update; | |
93 | VhostUserGpuScanout scanout; | |
94 | VhostUserGpuUpdate update; | |
95 | VhostUserGpuDMABUFScanout dmabuf_scanout; | |
96 | struct virtio_gpu_resp_display_info display_info; | |
97 | uint64_t u64; | |
98 | } payload; | |
99 | } QEMU_PACKED VhostUserGpuMsg; | |
100 | ||
101 | static VhostUserGpuMsg m __attribute__ ((unused)); | |
102 | #define VHOST_USER_GPU_HDR_SIZE \ | |
103 | (sizeof(m.request) + sizeof(m.flags) + sizeof(m.size)) | |
104 | ||
105 | #define VHOST_USER_GPU_MSG_FLAG_REPLY 0x4 | |
106 | ||
107 | struct virtio_gpu_scanout { | |
108 | uint32_t width, height; | |
109 | int x, y; | |
110 | int invalidate; | |
111 | uint32_t resource_id; | |
112 | }; | |
113 | ||
114 | typedef struct VuGpu { | |
115 | VugDev dev; | |
116 | struct virtio_gpu_config virtio_config; | |
117 | struct vugbm_device gdev; | |
118 | int sock_fd; | |
119 | int drm_rnode_fd; | |
120 | GSource *renderer_source; | |
1f83ea8d | 121 | guint wait_in; |
d52c454a MAL |
122 | |
123 | bool virgl; | |
124 | bool virgl_inited; | |
125 | uint32_t inflight; | |
126 | ||
127 | struct virtio_gpu_scanout scanout[VIRTIO_GPU_MAX_SCANOUTS]; | |
128 | QTAILQ_HEAD(, virtio_gpu_simple_resource) reslist; | |
129 | QTAILQ_HEAD(, virtio_gpu_ctrl_command) fenceq; | |
130 | } VuGpu; | |
131 | ||
72e631c6 MAL |
132 | enum { |
133 | VG_CMD_STATE_NEW, | |
134 | VG_CMD_STATE_PENDING, | |
135 | VG_CMD_STATE_FINISHED, | |
136 | }; | |
137 | ||
d52c454a MAL |
138 | struct virtio_gpu_ctrl_command { |
139 | VuVirtqElement elem; | |
140 | VuVirtq *vq; | |
141 | struct virtio_gpu_ctrl_hdr cmd_hdr; | |
142 | uint32_t error; | |
72e631c6 | 143 | int state; |
d52c454a MAL |
144 | QTAILQ_ENTRY(virtio_gpu_ctrl_command) next; |
145 | }; | |
146 | ||
147 | #define VUGPU_FILL_CMD(out) do { \ | |
148 | size_t s; \ | |
149 | s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0, \ | |
150 | &out, sizeof(out)); \ | |
151 | if (s != sizeof(out)) { \ | |
152 | g_critical("%s: command size incorrect %zu vs %zu", \ | |
153 | __func__, s, sizeof(out)); \ | |
154 | return; \ | |
155 | } \ | |
156 | } while (0) | |
157 | ||
158 | ||
159 | void vg_ctrl_response(VuGpu *g, | |
160 | struct virtio_gpu_ctrl_command *cmd, | |
161 | struct virtio_gpu_ctrl_hdr *resp, | |
162 | size_t resp_len); | |
163 | ||
164 | void vg_ctrl_response_nodata(VuGpu *g, | |
165 | struct virtio_gpu_ctrl_command *cmd, | |
166 | enum virtio_gpu_ctrl_type type); | |
167 | ||
168 | int vg_create_mapping_iov(VuGpu *g, | |
169 | struct virtio_gpu_resource_attach_backing *ab, | |
170 | struct virtio_gpu_ctrl_command *cmd, | |
171 | struct iovec **iov); | |
172 | ||
173 | void vg_get_display_info(VuGpu *vg, struct virtio_gpu_ctrl_command *cmd); | |
174 | ||
175 | void vg_wait_ok(VuGpu *g); | |
176 | ||
177 | void vg_send_msg(VuGpu *g, const VhostUserGpuMsg *msg, int fd); | |
178 | ||
179 | bool vg_recv_msg(VuGpu *g, uint32_t expect_req, uint32_t expect_size, | |
180 | gpointer payload); | |
181 | ||
182 | ||
183 | #endif |