qemu/contrib/vhost-user-gpu/vugpu.h
<<
>>
Prefs
   1/*
   2 * Virtio vhost-user GPU Device
   3 *
   4 * Copyright Red Hat, Inc. 2013-2018
   5 *
   6 * Authors:
   7 *     Dave Airlie <airlied@redhat.com>
   8 *     Gerd Hoffmann <kraxel@redhat.com>
   9 *     Marc-André Lureau <marcandre.lureau@redhat.com>
  10 *
  11 * This work is licensed under the terms of the GNU GPL, version 2 or later.
  12 * See the COPYING file in the top-level directory.
  13 */
  14
  15#ifndef VUGPU_H
  16#define VUGPU_H
  17
  18
  19#include "libvhost-user-glib.h"
  20#include "standard-headers/linux/virtio_gpu.h"
  21
  22#include "qemu/queue.h"
  23#include "qemu/iov.h"
  24#include "qemu/bswap.h"
  25#include "vugbm.h"
  26
  27typedef enum VhostUserGpuRequest {
  28    VHOST_USER_GPU_NONE = 0,
  29    VHOST_USER_GPU_GET_PROTOCOL_FEATURES,
  30    VHOST_USER_GPU_SET_PROTOCOL_FEATURES,
  31    VHOST_USER_GPU_GET_DISPLAY_INFO,
  32    VHOST_USER_GPU_CURSOR_POS,
  33    VHOST_USER_GPU_CURSOR_POS_HIDE,
  34    VHOST_USER_GPU_CURSOR_UPDATE,
  35    VHOST_USER_GPU_SCANOUT,
  36    VHOST_USER_GPU_UPDATE,
  37    VHOST_USER_GPU_DMABUF_SCANOUT,
  38    VHOST_USER_GPU_DMABUF_UPDATE,
  39} VhostUserGpuRequest;
  40
  41typedef struct VhostUserGpuDisplayInfoReply {
  42    struct virtio_gpu_resp_display_info info;
  43} VhostUserGpuDisplayInfoReply;
  44
  45typedef struct VhostUserGpuCursorPos {
  46    uint32_t scanout_id;
  47    uint32_t x;
  48    uint32_t y;
  49} QEMU_PACKED VhostUserGpuCursorPos;
  50
  51typedef struct VhostUserGpuCursorUpdate {
  52    VhostUserGpuCursorPos pos;
  53    uint32_t hot_x;
  54    uint32_t hot_y;
  55    uint32_t data[64 * 64];
  56} QEMU_PACKED VhostUserGpuCursorUpdate;
  57
  58typedef struct VhostUserGpuScanout {
  59    uint32_t scanout_id;
  60    uint32_t width;
  61    uint32_t height;
  62} QEMU_PACKED VhostUserGpuScanout;
  63
  64typedef struct VhostUserGpuUpdate {
  65    uint32_t scanout_id;
  66    uint32_t x;
  67    uint32_t y;
  68    uint32_t width;
  69    uint32_t height;
  70    uint8_t data[];
  71} QEMU_PACKED VhostUserGpuUpdate;
  72
  73typedef struct VhostUserGpuDMABUFScanout {
  74    uint32_t scanout_id;
  75    uint32_t x;
  76    uint32_t y;
  77    uint32_t width;
  78    uint32_t height;
  79    uint32_t fd_width;
  80    uint32_t fd_height;
  81    uint32_t fd_stride;
  82    uint32_t fd_flags;
  83    int fd_drm_fourcc;
  84} QEMU_PACKED VhostUserGpuDMABUFScanout;
  85
  86typedef struct VhostUserGpuMsg {
  87    uint32_t request; /* VhostUserGpuRequest */
  88    uint32_t flags;
  89    uint32_t size; /* the following payload size */
  90    union {
  91        VhostUserGpuCursorPos cursor_pos;
  92        VhostUserGpuCursorUpdate cursor_update;
  93        VhostUserGpuScanout scanout;
  94        VhostUserGpuUpdate update;
  95        VhostUserGpuDMABUFScanout dmabuf_scanout;
  96        struct virtio_gpu_resp_display_info display_info;
  97        uint64_t u64;
  98    } payload;
  99} QEMU_PACKED VhostUserGpuMsg;
 100
 101static VhostUserGpuMsg m __attribute__ ((unused));
 102#define VHOST_USER_GPU_HDR_SIZE \
 103    (sizeof(m.request) + sizeof(m.flags) + sizeof(m.size))
 104
 105#define VHOST_USER_GPU_MSG_FLAG_REPLY 0x4
 106
 107struct virtio_gpu_scanout {
 108    uint32_t width, height;
 109    int x, y;
 110    int invalidate;
 111    uint32_t resource_id;
 112};
 113
 114typedef struct VuGpu {
 115    VugDev dev;
 116    struct virtio_gpu_config virtio_config;
 117    struct vugbm_device gdev;
 118    int sock_fd;
 119    int drm_rnode_fd;
 120    GSource *renderer_source;
 121    guint wait_in;
 122
 123    bool virgl;
 124    bool virgl_inited;
 125    uint32_t inflight;
 126
 127    struct virtio_gpu_scanout scanout[VIRTIO_GPU_MAX_SCANOUTS];
 128    QTAILQ_HEAD(, virtio_gpu_simple_resource) reslist;
 129    QTAILQ_HEAD(, virtio_gpu_ctrl_command) fenceq;
 130} VuGpu;
 131
 132enum {
 133    VG_CMD_STATE_NEW,
 134    VG_CMD_STATE_PENDING,
 135    VG_CMD_STATE_FINISHED,
 136};
 137
 138struct virtio_gpu_ctrl_command {
 139    VuVirtqElement elem;
 140    VuVirtq *vq;
 141    struct virtio_gpu_ctrl_hdr cmd_hdr;
 142    uint32_t error;
 143    int state;
 144    QTAILQ_ENTRY(virtio_gpu_ctrl_command) next;
 145};
 146
 147#define VUGPU_FILL_CMD(out) do {                                \
 148        size_t s;                                               \
 149        s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0,  \
 150                       &out, sizeof(out));                      \
 151        if (s != sizeof(out)) {                                 \
 152            g_critical("%s: command size incorrect %zu vs %zu", \
 153                       __func__, s, sizeof(out));               \
 154            return;                                             \
 155        }                                                       \
 156    } while (0)
 157
 158
 159void    vg_ctrl_response(VuGpu *g,
 160                         struct virtio_gpu_ctrl_command *cmd,
 161                         struct virtio_gpu_ctrl_hdr *resp,
 162                         size_t resp_len);
 163
 164void    vg_ctrl_response_nodata(VuGpu *g,
 165                                struct virtio_gpu_ctrl_command *cmd,
 166                                enum virtio_gpu_ctrl_type type);
 167
 168int     vg_create_mapping_iov(VuGpu *g,
 169                              struct virtio_gpu_resource_attach_backing *ab,
 170                              struct virtio_gpu_ctrl_command *cmd,
 171                              struct iovec **iov);
 172void    vg_cleanup_mapping_iov(VuGpu *g, struct iovec *iov, uint32_t count);
 173void    vg_get_display_info(VuGpu *vg, struct virtio_gpu_ctrl_command *cmd);
 174
 175void    vg_wait_ok(VuGpu *g);
 176
 177void    vg_send_msg(VuGpu *g, const VhostUserGpuMsg *msg, int fd);
 178
 179bool    vg_recv_msg(VuGpu *g, uint32_t expect_req, uint32_t expect_size,
 180                    gpointer payload);
 181
 182
 183#endif
 184