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

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_EDID protocol 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_DMABUF2 protocol feature to be supported.