2 * Virtio vhost-user GPU Device
4 * Copyright Red Hat, Inc. 2013-2018
7 * Dave Airlie <airlied@redhat.com>
8 * Gerd Hoffmann <kraxel@redhat.com>
9 * Marc-André Lureau <marcandre.lureau@redhat.com>
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.
19 #include "libvhost-user-glib.h"
20 #include "standard-headers/linux/virtio_gpu.h"
22 #include "qemu/queue.h"
24 #include "qemu/bswap.h"
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
;
41 typedef struct VhostUserGpuDisplayInfoReply
{
42 struct virtio_gpu_resp_display_info info
;
43 } VhostUserGpuDisplayInfoReply
;
45 typedef struct VhostUserGpuCursorPos
{
49 } QEMU_PACKED VhostUserGpuCursorPos
;
51 typedef struct VhostUserGpuCursorUpdate
{
52 VhostUserGpuCursorPos pos
;
55 uint32_t data
[64 * 64];
56 } QEMU_PACKED VhostUserGpuCursorUpdate
;
58 typedef struct VhostUserGpuScanout
{
62 } QEMU_PACKED VhostUserGpuScanout
;
64 typedef struct VhostUserGpuUpdate
{
71 } QEMU_PACKED VhostUserGpuUpdate
;
73 typedef struct VhostUserGpuDMABUFScanout
{
84 } QEMU_PACKED VhostUserGpuDMABUFScanout
;
86 typedef struct VhostUserGpuMsg
{
87 uint32_t request
; /* VhostUserGpuRequest */
89 uint32_t size
; /* the following payload size */
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
;
99 } QEMU_PACKED VhostUserGpuMsg
;
101 static VhostUserGpuMsg m
__attribute__ ((unused
));
102 #define VHOST_USER_GPU_HDR_SIZE \
103 (sizeof(m.request) + sizeof(m.flags) + sizeof(m.size))
105 #define VHOST_USER_GPU_MSG_FLAG_REPLY 0x4
107 struct virtio_gpu_scanout
{
108 uint32_t width
, height
;
111 uint32_t resource_id
;
114 typedef struct VuGpu
{
116 struct virtio_gpu_config virtio_config
;
117 struct vugbm_device gdev
;
120 GSource
*renderer_source
;
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
;
134 VG_CMD_STATE_PENDING
,
135 VG_CMD_STATE_FINISHED
,
138 struct virtio_gpu_ctrl_command
{
141 struct virtio_gpu_ctrl_hdr cmd_hdr
;
144 QTAILQ_ENTRY(virtio_gpu_ctrl_command
) next
;
147 #define VUGPU_FILL_CMD(out) do { \
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)); \
159 void vg_ctrl_response(VuGpu
*g
,
160 struct virtio_gpu_ctrl_command
*cmd
,
161 struct virtio_gpu_ctrl_hdr
*resp
,
164 void vg_ctrl_response_nodata(VuGpu
*g
,
165 struct virtio_gpu_ctrl_command
*cmd
,
166 enum virtio_gpu_ctrl_type type
);
168 int vg_create_mapping_iov(VuGpu
*g
,
169 struct virtio_gpu_resource_attach_backing
*ab
,
170 struct virtio_gpu_ctrl_command
*cmd
,
172 void vg_cleanup_mapping_iov(VuGpu
*g
, struct iovec
*iov
, uint32_t count
);
173 void vg_get_display_info(VuGpu
*vg
, struct virtio_gpu_ctrl_command
*cmd
);
175 void vg_wait_ok(VuGpu
*g
);
177 void vg_send_msg(VuGpu
*g
, const VhostUserGpuMsg
*msg
, int fd
);
179 bool vg_recv_msg(VuGpu
*g
, uint32_t expect_req
, uint32_t expect_size
,