vga: add vhost-user-gpu.

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABAgAGBQJc7g0iAAoJEEy22O7T6HE4vXsQAI3+EGS8dFBNOxu2pLYMHzM0
 l19fU8HAXiVDBf6Ghkn1X6kpY84JVaJwRlbME+sgQeTnxY/FOOQV7PJBi7iwMpdo
 sdu0GDVTU5UjTK24yunrTz3PBcejwKE5miDyZUAKI8LIZKeSenaIETOuEyKotjGU
 XH36vjjxa0L9UL4AR6KjqGB5+VKlQuqoAbXBkOiHYACZqo1ayXimjNud1Kiprfs7
 X9A+vcJfjtUZNE1X61OyLnrXGb4QfkqTSlE9PGpTkGMAPlVSbdRj9aP7Ivc2v2+v
 gd/a4chYzUhGpXo4bej6B2KiFFz8NZEc46EmIPMOKloixXyxiqgnWH0QvSrfle0Q
 pAC4mIeGRDTYGYfzr5GYG/09CO6zIwap5t44AG6tUWzMMaLS1o+5E5RKkA8hSKAk
 qgMr4eh/caQZzDF737PEtgE7yAh1KSMPbS7fT/M69YyFHg6dxJ+qU4JOGGUC6G2o
 PGpKCvgf+NYi//M8Ukf1tbPugq86wLE6rvSu/4l2EGmSyCXUOfXZeFgNSnVcTM87
 pEKd5dapI0uvEyqbGHx2IXVcni8wxKgCt07GpcKIdI1dNKbya/SxxHGpP0Ie7hP4
 OGcKNwiouglO1iCV9VG8FUqXdw66rOper+zf4ExPgbgZ2l6lSBux8g7rQU4effAR
 hqzN631jiQxyoix8SCW1
 =BRv/
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/kraxel/tags/vga-20190529-pull-request' into staging

vga: add vhost-user-gpu.

# gpg: Signature made Wed 29 May 2019 05:40:02 BST
# gpg:                using RSA key 4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full]
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>" [full]
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full]
# Primary key fingerprint: A032 8CFF B93A 17A7 9901  FE7D 4CB6 D8EE D3E8 7138

* remotes/kraxel/tags/vga-20190529-pull-request:
  hw/display: add vhost-user-vga & gpu-pci
  virtio-gpu: split virtio-gpu-pci & virtio-vga
  virtio-gpu: split virtio-gpu, introduce virtio-gpu-base
  spice-app: fix running when !CONFIG_OPENGL
  contrib: add vhost-user-gpu
  util: compile drm.o on posix
  virtio-gpu: add a pixman helper header
  virtio-gpu: add bswap helpers header
  vhost-user: add vhost_user_gpu_set_socket()
  virtio-gpu: add sanity check

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2019-05-30 13:10:00 +01:00
commit 95172e2405
38 changed files with 4179 additions and 488 deletions

View file

@ -170,4 +170,6 @@ int vhost_backend_invalidate_device_iotlb(struct vhost_dev *dev,
int vhost_backend_handle_iotlb_msg(struct vhost_dev *dev,
struct vhost_iotlb_msg *imsg);
int vhost_user_gpu_set_socket(struct vhost_dev *dev, int fd);
#endif /* VHOST_BACKEND_H */

View file

@ -0,0 +1,61 @@
/*
* Virtio GPU Device
*
* Copyright Red Hat, Inc. 2013-2014
*
* Authors:
* Dave Airlie <airlied@redhat.com>
* Gerd Hoffmann <kraxel@redhat.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#ifndef HW_VIRTIO_GPU_BSWAP_H
#define HW_VIRTIO_GPU_BSWAP_H
#include "qemu/bswap.h"
static inline void
virtio_gpu_ctrl_hdr_bswap(struct virtio_gpu_ctrl_hdr *hdr)
{
le32_to_cpus(&hdr->type);
le32_to_cpus(&hdr->flags);
le64_to_cpus(&hdr->fence_id);
le32_to_cpus(&hdr->ctx_id);
le32_to_cpus(&hdr->padding);
}
static inline void
virtio_gpu_bswap_32(void *ptr, size_t size)
{
#ifdef HOST_WORDS_BIGENDIAN
size_t i;
struct virtio_gpu_ctrl_hdr *hdr = (struct virtio_gpu_ctrl_hdr *) ptr;
virtio_gpu_ctrl_hdr_bswap(hdr);
i = sizeof(struct virtio_gpu_ctrl_hdr);
while (i < size) {
le32_to_cpus((uint32_t *)(ptr + i));
i = i + sizeof(uint32_t);
}
#endif
}
static inline void
virtio_gpu_t2d_bswap(struct virtio_gpu_transfer_to_host_2d *t2d)
{
virtio_gpu_ctrl_hdr_bswap(&t2d->hdr);
le32_to_cpus(&t2d->r.x);
le32_to_cpus(&t2d->r.y);
le32_to_cpus(&t2d->r.width);
le32_to_cpus(&t2d->r.height);
le64_to_cpus(&t2d->offset);
le32_to_cpus(&t2d->resource_id);
le32_to_cpus(&t2d->padding);
}
#endif

View file

@ -0,0 +1,40 @@
/*
* Virtio GPU PCI Device
*
* Copyright Red Hat, Inc. 2013-2014
*
* Authors:
* Dave Airlie <airlied@redhat.com>
* Gerd Hoffmann <kraxel@redhat.com>
*
* This work is licensed under the terms of the GNU GPL, version 2.
* See the COPYING file in the top-level directory.
*/
#ifndef HW_VIRTIO_GPU_PCI_H
#define HW_VIRTIO_GPU_PCI_H
#include "hw/virtio/virtio-pci.h"
#include "hw/virtio/virtio-gpu.h"
typedef struct VirtIOGPUPCIBase VirtIOGPUPCIBase;
/*
* virtio-gpu-pci-base: This extends VirtioPCIProxy.
*/
#define TYPE_VIRTIO_GPU_PCI_BASE "virtio-gpu-pci-base"
#define VIRTIO_GPU_PCI_BASE(obj) \
OBJECT_CHECK(VirtIOGPUPCIBase, (obj), TYPE_VIRTIO_GPU_PCI_BASE)
struct VirtIOGPUPCIBase {
VirtIOPCIProxy parent_obj;
VirtIOGPUBase *vgpu;
};
/* to share between PCI and VGA */
#define DEFINE_VIRTIO_GPU_PCI_PROPERTIES(_state) \
DEFINE_PROP_BIT("ioeventfd", _state, flags, \
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false), \
DEFINE_PROP_UINT32("vectors", _state, nvectors, 3)
#endif /* HW_VIRTIO_GPU_PCI_H */

View file

@ -0,0 +1,45 @@
/*
* Virtio GPU Device
*
* Copyright Red Hat, Inc. 2013-2014
*
* Authors:
* Dave Airlie <airlied@redhat.com>
* Gerd Hoffmann <kraxel@redhat.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#ifndef HW_VIRTIO_GPU_PIXMAN_H
#define HW_VIRTIO_GPU_PIXMAN_H
#include "ui/qemu-pixman.h"
#include "standard-headers/linux/virtio_gpu.h"
static inline pixman_format_code_t
virtio_gpu_get_pixman_format(uint32_t virtio_gpu_format)
{
switch (virtio_gpu_format) {
case VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM:
return PIXMAN_BE_b8g8r8x8;
case VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM:
return PIXMAN_BE_b8g8r8a8;
case VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM:
return PIXMAN_BE_x8r8g8b8;
case VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM:
return PIXMAN_BE_a8r8g8b8;
case VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM:
return PIXMAN_BE_r8g8b8x8;
case VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM:
return PIXMAN_BE_r8g8b8a8;
case VIRTIO_GPU_FORMAT_X8B8G8R8_UNORM:
return PIXMAN_BE_x8b8g8r8;
case VIRTIO_GPU_FORMAT_A8B8G8R8_UNORM:
return PIXMAN_BE_a8b8g8r8;
default:
return 0;
}
}
#endif

View file

@ -19,13 +19,24 @@
#include "ui/console.h"
#include "hw/virtio/virtio.h"
#include "qemu/log.h"
#include "sysemu/vhost-user-backend.h"
#include "standard-headers/linux/virtio_gpu.h"
#define TYPE_VIRTIO_GPU_BASE "virtio-gpu-base"
#define VIRTIO_GPU_BASE(obj) \
OBJECT_CHECK(VirtIOGPUBase, (obj), TYPE_VIRTIO_GPU_BASE)
#define VIRTIO_GPU_BASE_GET_CLASS(obj) \
OBJECT_GET_CLASS(VirtIOGPUBaseClass, obj, TYPE_VIRTIO_GPU_BASE)
#define VIRTIO_GPU_BASE_CLASS(klass) \
OBJECT_CLASS_CHECK(VirtIOGPUBaseClass, klass, TYPE_VIRTIO_GPU_BASE)
#define TYPE_VIRTIO_GPU "virtio-gpu-device"
#define VIRTIO_GPU(obj) \
OBJECT_CHECK(VirtIOGPU, (obj), TYPE_VIRTIO_GPU)
#define TYPE_VHOST_USER_GPU "vhost-user-gpu"
#define VIRTIO_ID_GPU 16
struct virtio_gpu_simple_resource {
@ -58,7 +69,7 @@ struct virtio_gpu_requested_state {
int x, y;
};
enum virtio_gpu_conf_flags {
enum virtio_gpu_base_conf_flags {
VIRTIO_GPU_FLAG_VIRGL_ENABLED = 1,
VIRTIO_GPU_FLAG_STATS_ENABLED,
VIRTIO_GPU_FLAG_EDID_ENABLED,
@ -71,8 +82,7 @@ enum virtio_gpu_conf_flags {
#define virtio_gpu_edid_enabled(_cfg) \
(_cfg.flags & (1 << VIRTIO_GPU_FLAG_EDID_ENABLED))
struct virtio_gpu_conf {
uint64_t max_hostmem;
struct virtio_gpu_base_conf {
uint32_t max_outputs;
uint32_t flags;
uint32_t xres;
@ -88,31 +98,55 @@ struct virtio_gpu_ctrl_command {
QTAILQ_ENTRY(virtio_gpu_ctrl_command) next;
};
typedef struct VirtIOGPU {
typedef struct VirtIOGPUBase {
VirtIODevice parent_obj;
QEMUBH *ctrl_bh;
QEMUBH *cursor_bh;
Error *migration_blocker;
struct virtio_gpu_base_conf conf;
struct virtio_gpu_config virtio_config;
bool use_virgl_renderer;
int renderer_blocked;
int enable;
struct virtio_gpu_scanout scanout[VIRTIO_GPU_MAX_SCANOUTS];
int enabled_output_bitmask;
struct virtio_gpu_requested_state req_state[VIRTIO_GPU_MAX_SCANOUTS];
} VirtIOGPUBase;
typedef struct VirtIOGPUBaseClass {
VirtioDeviceClass parent;
void (*gl_unblock)(VirtIOGPUBase *g);
} VirtIOGPUBaseClass;
#define VIRTIO_GPU_BASE_PROPERTIES(_state, _conf) \
DEFINE_PROP_UINT32("max_outputs", _state, _conf.max_outputs, 1), \
DEFINE_PROP_BIT("edid", _state, _conf.flags, \
VIRTIO_GPU_FLAG_EDID_ENABLED, false), \
DEFINE_PROP_UINT32("xres", _state, _conf.xres, 1024), \
DEFINE_PROP_UINT32("yres", _state, _conf.yres, 768)
typedef struct VirtIOGPU {
VirtIOGPUBase parent_obj;
uint64_t conf_max_hostmem;
VirtQueue *ctrl_vq;
VirtQueue *cursor_vq;
int enable;
QEMUBH *ctrl_bh;
QEMUBH *cursor_bh;
QTAILQ_HEAD(, virtio_gpu_simple_resource) reslist;
QTAILQ_HEAD(, virtio_gpu_ctrl_command) cmdq;
QTAILQ_HEAD(, virtio_gpu_ctrl_command) fenceq;
struct virtio_gpu_scanout scanout[VIRTIO_GPU_MAX_SCANOUTS];
struct virtio_gpu_requested_state req_state[VIRTIO_GPU_MAX_SCANOUTS];
struct virtio_gpu_conf conf;
uint64_t hostmem;
int enabled_output_bitmask;
struct virtio_gpu_config virtio_config;
bool use_virgl_renderer;
bool renderer_inited;
int renderer_blocked;
bool renderer_reset;
QEMUTimer *fence_poll;
QEMUTimer *print_stats;
@ -124,17 +158,19 @@ typedef struct VirtIOGPU {
uint32_t req_3d;
uint32_t bytes_3d;
} stats;
Error *migration_blocker;
} VirtIOGPU;
extern const GraphicHwOps virtio_gpu_ops;
typedef struct VhostUserGPU {
VirtIOGPUBase parent_obj;
/* to share between PCI and VGA */
#define DEFINE_VIRTIO_GPU_PCI_PROPERTIES(_state) \
DEFINE_PROP_BIT("ioeventfd", _state, flags, \
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false), \
DEFINE_PROP_UINT32("vectors", _state, nvectors, 3)
VhostUserBackend *vhost;
int vhost_gpu_fd; /* closed by the chardev */
CharBackend vhost_chr;
QemuDmaBuf dmabuf[VIRTIO_GPU_MAX_SCANOUTS];
bool backend_blocked;
} VhostUserGPU;
extern const GraphicHwOps virtio_gpu_ops;
#define VIRTIO_GPU_FILL_CMD(out) do { \
size_t s; \
@ -148,6 +184,15 @@ extern const GraphicHwOps virtio_gpu_ops;
} \
} while (0)
/* virtio-gpu-base.c */
bool virtio_gpu_base_device_realize(DeviceState *qdev,
VirtIOHandleOutput ctrl_cb,
VirtIOHandleOutput cursor_cb,
Error **errp);
void virtio_gpu_base_reset(VirtIOGPUBase *g);
void virtio_gpu_base_fill_display_info(VirtIOGPUBase *g,
struct virtio_gpu_resp_display_info *dpy_info);
/* virtio-gpu.c */
void virtio_gpu_ctrl_response(VirtIOGPU *g,
struct virtio_gpu_ctrl_command *cmd,
@ -175,4 +220,5 @@ void virtio_gpu_virgl_fence_poll(VirtIOGPU *g);
void virtio_gpu_virgl_reset(VirtIOGPU *g);
int virtio_gpu_virgl_init(VirtIOGPU *g);
int virtio_gpu_virgl_get_num_capsets(VirtIOGPU *g);
#endif