Vhost-user-gpu Protocol
Introduction
The vhost-user-gpu protocol is aiming at sharing the rendering result of a virtio-gpu, done from a vhost-user back-end process to a vhost-user front-end process (such as QEMU). It bears a resemblance to a display server protocol, if you consider QEMU as the display server and the back-end as the client, but in a very limited way. Typically, it will work by setting a scanout/display configuration, before sending flush events for the display updates. It will also update the cursor shape and position.
The protocol is sent over a UNIX domain stream socket, since it uses
socket ancillary data to share opened file descriptors (DMABUF fds or
shared memory). The socket is usually obtained via
VHOST_USER_GPU_SET_SOCKET.
Requests are sent by the back-end, and the optional replies by the front-end.
Wire format
Unless specified differently, numbers are in the machine native byte order.
A vhost-user-gpu message (request and reply) consists of 3 header fields and a payload.
| request | flags | size | payload | 
Header
- request:
- u32, type of the request
- flags:
- u32, 32-bit bit field:- Bit 2 is the reply flag - needs to be set on each reply 
 
- size:
- u32, size of the payload
Payload types
Depending on the request type, payload can be:
VhostUserGpuCursorPos
| scanout-id | x | y | 
- scanout-id:
- u32, the scanout where the cursor is located
- x/y:
- u32, the cursor position
VhostUserGpuCursorUpdate
| pos | hot_x | hot_y | cursor | 
- pos:
- a - VhostUserGpuCursorPos, the cursor location
- hot_x/hot_y:
- u32, the cursor hot location
- cursor:
- [u32; 64 * 64], 64x64 RGBA cursor data (PIXMAN_a8r8g8b8 format)
VhostUserGpuScanout
| scanout-id | w | h | 
- scanout-id:
- u32, the scanout configuration to set
- w/h:
- u32, the scanout width/height size
VhostUserGpuUpdate
| scanout-id | x | y | w | h | data | 
- scanout-id:
- u32, the scanout content to update
- x/y/w/h:
- u32, region of the update
- data:
- RGB data (PIXMAN_x8r8g8b8 format) 
VhostUserGpuDMABUFScanout
| scanout-id | x | y | w | h | fdw | fwh | stride | flags | fourcc | 
- scanout-id:
- u32, the scanout configuration to set
- x/y:
- u32, the location of the scanout within the DMABUF
- w/h:
- u32, the scanout width/height size
- fdw/fdh/stride/flags:
- u32, the DMABUF width/height/stride/flags
- fourcc:
- i32, the DMABUF fourcc
VhostUserGpuEdidRequest
| scanout-id | 
- scanout-id:
- u32, the scanout to get edid from
VhostUserGpuDMABUFScanout2
| dmabuf_scanout | modifier | 
- dmabuf_scanout:
- VhostUserGpuDMABUFScanout, filled as described in the VhostUserGpuDMABUFScanout structure.
- modifier:
- u64, the DMABUF modifiers
C structure
In QEMU the vhost-user-gpu message is implemented with the following struct:
typedef struct VhostUserGpuMsg {
    uint32_t request; /* VhostUserGpuRequest */
    uint32_t flags;
    uint32_t size; /* the following payload size */
    union {
        VhostUserGpuCursorPos cursor_pos;
        VhostUserGpuCursorUpdate cursor_update;
        VhostUserGpuScanout scanout;
        VhostUserGpuUpdate update;
        VhostUserGpuDMABUFScanout dmabuf_scanout;
        VhostUserGpuEdidRequest edid_req;
        struct virtio_gpu_resp_edid resp_edid;
        struct virtio_gpu_resp_display_info display_info;
        uint64_t u64;
    } payload;
} QEMU_PACKED VhostUserGpuMsg;
Protocol features
#define VHOST_USER_GPU_PROTOCOL_F_EDID    0
#define VHOST_USER_GPU_PROTOCOL_F_DMABUF2 1
New messages and communication changes are negotiated thanks to the
VHOST_USER_GPU_GET_PROTOCOL_FEATURES and
VHOST_USER_GPU_SET_PROTOCOL_FEATURES requests.
Communication
Message types
- VHOST_USER_GPU_GET_PROTOCOL_FEATURES
- id:
- 1 
- request payload:
- N/A 
- reply payload:
- u64
 - Get the supported protocol features bitmask. 
- VHOST_USER_GPU_SET_PROTOCOL_FEATURES
- id:
- 2 
- request payload:
- u64
- reply payload:
- N/A 
 - Enable protocol features using a bitmask. 
- VHOST_USER_GPU_GET_DISPLAY_INFO
- id:
- 3 
- request payload:
- N/A 
- reply payload:
- struct virtio_gpu_resp_display_info(from virtio specification)
 - Get the preferred display configuration. 
- VHOST_USER_GPU_CURSOR_POS
- id:
- 4 
- request payload:
- VhostUserGpuCursorPos
- reply payload:
- N/A 
 - Set/show the cursor position. 
- VHOST_USER_GPU_CURSOR_POS_HIDE
- id:
- 5 
- request payload:
- VhostUserGpuCursorPos
- reply payload:
- N/A 
 - Set/hide the cursor. 
- VHOST_USER_GPU_CURSOR_UPDATE
- id:
- 6 
- request payload:
- VhostUserGpuCursorUpdate
- reply payload:
- N/A 
 - Update the cursor shape and location. 
- VHOST_USER_GPU_SCANOUT
- id:
- 7 
- request payload:
- VhostUserGpuScanout
- reply payload:
- N/A 
 - Set the scanout resolution. To disable a scanout, the dimensions width/height are set to 0. 
- VHOST_USER_GPU_UPDATE
- id:
- 8 
- request payload:
- VhostUserGpuUpdate
- reply payload:
- N/A 
 - Update the scanout content. The data payload contains the graphical bits. The display should be flushed and presented. 
- VHOST_USER_GPU_DMABUF_SCANOUT
- id:
- 9 
- request payload:
- VhostUserGpuDMABUFScanout
- reply payload:
- N/A 
 - Set the scanout resolution/configuration, and share a DMABUF file descriptor for the scanout content, which is passed as ancillary data. To disable a scanout, the dimensions width/height are set to 0, there is no file descriptor passed. 
- VHOST_USER_GPU_DMABUF_UPDATE
- id:
- 10 
- request payload:
- VhostUserGpuUpdate
- reply payload:
- empty payload 
 - The display should be flushed and presented according to updated region from - VhostUserGpuUpdate.- Note: there is no data payload, since the scanout is shared thanks to DMABUF, that must have been set previously with - VHOST_USER_GPU_DMABUF_SCANOUT.
- VHOST_USER_GPU_GET_EDID
- id:
- 11 
- request payload:
- struct VhostUserGpuEdidRequest
- reply payload:
- struct virtio_gpu_resp_edid(from virtio specification)
 - Retrieve the EDID data for a given scanout. This message requires the - VHOST_USER_GPU_PROTOCOL_F_EDIDprotocol feature to be supported.
- VHOST_USER_GPU_DMABUF_SCANOUT2
- id:
- 12 
- request payload:
- VhostUserGpuDMABUFScanout2
- reply payload:
- N/A 
 - Same as VHOST_USER_GPU_DMABUF_SCANOUT, but also sends the dmabuf modifiers appended to the message, which were not provided in the other message. This message requires the - VHOST_USER_GPU_PROTOCOL_F_DMABUF2protocol feature to be supported.