# 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_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.