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.
18 #include "qemu/osdep.h"
20 #include "contrib/libvhost-user/libvhost-user-glib.h"
21 #include "standard-headers/linux/virtio_gpu.h"
23 #include "qemu/queue.h"
25 #include "qemu/bswap.h"
28 typedef enum VhostUserGpuRequest
{
29 VHOST_USER_GPU_NONE
= 0,
30 VHOST_USER_GPU_GET_PROTOCOL_FEATURES
,
31 VHOST_USER_GPU_SET_PROTOCOL_FEATURES
,
32 VHOST_USER_GPU_GET_DISPLAY_INFO
,
33 VHOST_USER_GPU_CURSOR_POS
,
34 VHOST_USER_GPU_CURSOR_POS_HIDE
,
35 VHOST_USER_GPU_CURSOR_UPDATE
,
36 VHOST_USER_GPU_SCANOUT
,
37 VHOST_USER_GPU_UPDATE
,
38 VHOST_USER_GPU_DMABUF_SCANOUT
,
39 VHOST_USER_GPU_DMABUF_UPDATE
,
40 } VhostUserGpuRequest
;
42 typedef struct VhostUserGpuDisplayInfoReply
{
43 struct virtio_gpu_resp_display_info info
;
44 } VhostUserGpuDisplayInfoReply
;
46 typedef struct VhostUserGpuCursorPos
{
50 } QEMU_PACKED VhostUserGpuCursorPos
;
52 typedef struct VhostUserGpuCursorUpdate
{
53 VhostUserGpuCursorPos pos
;
56 uint32_t data
[64 * 64];
57 } QEMU_PACKED VhostUserGpuCursorUpdate
;
59 typedef struct VhostUserGpuScanout
{
63 } QEMU_PACKED VhostUserGpuScanout
;
65 typedef struct VhostUserGpuUpdate
{
72 } QEMU_PACKED VhostUserGpuUpdate
;
74 typedef struct VhostUserGpuDMABUFScanout
{
85 } QEMU_PACKED VhostUserGpuDMABUFScanout
;
87 typedef struct VhostUserGpuMsg
{
88 uint32_t request
; /* VhostUserGpuRequest */
90 uint32_t size
; /* the following payload size */
92 VhostUserGpuCursorPos cursor_pos
;
93 VhostUserGpuCursorUpdate cursor_update
;
94 VhostUserGpuScanout scanout
;
95 VhostUserGpuUpdate update
;
96 VhostUserGpuDMABUFScanout dmabuf_scanout
;
97 struct virtio_gpu_resp_display_info display_info
;
100 } QEMU_PACKED VhostUserGpuMsg
;
102 static VhostUserGpuMsg m
__attribute__ ((unused
));
103 #define VHOST_USER_GPU_HDR_SIZE \
104 (sizeof(m.request) + sizeof(m.flags) + sizeof(m.size))
106 #define VHOST_USER_GPU_MSG_FLAG_REPLY 0x4
108 struct virtio_gpu_scanout
{
109 uint32_t width
, height
;
112 uint32_t resource_id
;
115 typedef struct VuGpu
{
117 struct virtio_gpu_config virtio_config
;
118 struct vugbm_device gdev
;
121 GSource
*renderer_source
;
128 struct virtio_gpu_scanout scanout
[VIRTIO_GPU_MAX_SCANOUTS
];
129 QTAILQ_HEAD(, virtio_gpu_simple_resource
) reslist
;
130 QTAILQ_HEAD(, virtio_gpu_ctrl_command
) fenceq
;
133 struct virtio_gpu_ctrl_command
{
136 struct virtio_gpu_ctrl_hdr cmd_hdr
;
139 QTAILQ_ENTRY(virtio_gpu_ctrl_command
) next
;
142 #define VUGPU_FILL_CMD(out) do { \
144 s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0, \
145 &out, sizeof(out)); \
146 if (s != sizeof(out)) { \
147 g_critical("%s: command size incorrect %zu vs %zu", \
148 __func__, s, sizeof(out)); \
154 void vg_ctrl_response(VuGpu
*g
,
155 struct virtio_gpu_ctrl_command
*cmd
,
156 struct virtio_gpu_ctrl_hdr
*resp
,
159 void vg_ctrl_response_nodata(VuGpu
*g
,
160 struct virtio_gpu_ctrl_command
*cmd
,
161 enum virtio_gpu_ctrl_type type
);
163 int vg_create_mapping_iov(VuGpu
*g
,
164 struct virtio_gpu_resource_attach_backing
*ab
,
165 struct virtio_gpu_ctrl_command
*cmd
,
168 void vg_get_display_info(VuGpu
*vg
, struct virtio_gpu_ctrl_command
*cmd
);
170 void vg_wait_ok(VuGpu
*g
);
172 void vg_send_msg(VuGpu
*g
, const VhostUserGpuMsg
*msg
, int fd
);
174 bool vg_recv_msg(VuGpu
*g
, uint32_t expect_req
, uint32_t expect_size
,