| ======================= | 
 | Vhost-user-gpu Protocol | 
 | ======================= | 
 |  | 
 | .. | 
 |   Licence: This work is licensed under the terms of the GNU GPL, | 
 |            version 2 or later. See the COPYING file in the top-level | 
 |            directory. | 
 |  | 
 | .. contents:: Table of Contents | 
 |  | 
 | 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 | 
 |  | 
 |  | 
 | C structure | 
 | ----------- | 
 |  | 
 | In QEMU the vhost-user-gpu message is implemented with the following struct: | 
 |  | 
 | .. code:: c | 
 |  | 
 |   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 | 
 | ----------------- | 
 |  | 
 | .. code:: c | 
 |  | 
 |   #define VHOST_USER_GPU_PROTOCOL_F_EDID 0 | 
 |  | 
 | 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. |