| ======================= | |
| 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 | |
| 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; | |
| struct virtio_gpu_resp_display_info display_info; | |
| uint64_t u64; | |
| } payload; | |
| } QEMU_PACKED VhostUserGpuMsg; | |
| Protocol features | |
| ----------------- | |
| None yet. | |
| As the protocol may need to evolve, new messages and communication | |
| changes are negotiated thanks to preliminary | |
| ``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``. |