virtio-gpu rutabaga support
-----BEGIN PGP SIGNATURE----- iQJQBAABCAA6FiEEh6m9kz+HxgbSdvYt2ujhCXWWnOUFAmUtP5YcHG1hcmNhbmRy ZS5sdXJlYXVAcmVkaGF0LmNvbQAKCRDa6OEJdZac5X9CD/4s1n/GZyDr9bh04V03 otAqtq2CSyuUOviqBrqxYgraCosUD1AuX8WkDy5cCPtnKC4FxRjgVlm9s7K/yxOW xZ78e4oVgB1F3voOq6LgtKK6BRG/BPqNzq9kuGcayCHQbSxg7zZVwa702Y18r2ZD pjOhbZCrJTSfASL7C3e/rm7798Wk/hzSrClGR56fbRAVgQ6Lww2L97/g0nHyDsWK DrCBrdqFtKjpLeUHmcqqS4AwdpG2SyCgqE7RehH/wOhvGTxh/JQvHbLGWK2mDC3j Qvs8mClC5bUlyNQuUz7lZtXYpzCW6VGMWlz8bIu+ncgSt6RK1TRbdEfDJPGoS4w9 ZCGgcTxTG/6BEO76J/VpydfTWDo1FwQCQ0Vv7EussGoRTLrFC3ZRFgDWpqCw85yi AjPtc0C49FHBZhK0l1CoJGV4gGTDtD9jTYN0ffsd+aQesOjcsgivAWBaCOOQWUc8 KOv9sr4kLLxcnuCnP7p/PuVRQD4eg0TmpdS8bXfnCzLSH8fCm+n76LuJEpGxEBey 3KPJPj/1BNBgVgew+znSLD/EYM6YhdK2gF5SNrYsdR6UcFdrPED/xmdhzFBeVym/ xbBWqicDw4HLn5YrJ4tzqXje5XUz5pmJoT5zrRMXTHiu4pjBkEXO/lOdAoFwSy8M WNOtmSyB69uCrbyLw6xE2/YX8Q== =5a/Z -----END PGP SIGNATURE----- Merge tag 'gpu-pull-request' of https://gitlab.com/marcandre.lureau/qemu into staging virtio-gpu rutabaga support # -----BEGIN PGP SIGNATURE----- # # iQJQBAABCAA6FiEEh6m9kz+HxgbSdvYt2ujhCXWWnOUFAmUtP5YcHG1hcmNhbmRy # ZS5sdXJlYXVAcmVkaGF0LmNvbQAKCRDa6OEJdZac5X9CD/4s1n/GZyDr9bh04V03 # otAqtq2CSyuUOviqBrqxYgraCosUD1AuX8WkDy5cCPtnKC4FxRjgVlm9s7K/yxOW # xZ78e4oVgB1F3voOq6LgtKK6BRG/BPqNzq9kuGcayCHQbSxg7zZVwa702Y18r2ZD # pjOhbZCrJTSfASL7C3e/rm7798Wk/hzSrClGR56fbRAVgQ6Lww2L97/g0nHyDsWK # DrCBrdqFtKjpLeUHmcqqS4AwdpG2SyCgqE7RehH/wOhvGTxh/JQvHbLGWK2mDC3j # Qvs8mClC5bUlyNQuUz7lZtXYpzCW6VGMWlz8bIu+ncgSt6RK1TRbdEfDJPGoS4w9 # ZCGgcTxTG/6BEO76J/VpydfTWDo1FwQCQ0Vv7EussGoRTLrFC3ZRFgDWpqCw85yi # AjPtc0C49FHBZhK0l1CoJGV4gGTDtD9jTYN0ffsd+aQesOjcsgivAWBaCOOQWUc8 # KOv9sr4kLLxcnuCnP7p/PuVRQD4eg0TmpdS8bXfnCzLSH8fCm+n76LuJEpGxEBey # 3KPJPj/1BNBgVgew+znSLD/EYM6YhdK2gF5SNrYsdR6UcFdrPED/xmdhzFBeVym/ # xbBWqicDw4HLn5YrJ4tzqXje5XUz5pmJoT5zrRMXTHiu4pjBkEXO/lOdAoFwSy8M # WNOtmSyB69uCrbyLw6xE2/YX8Q== # =5a/Z # -----END PGP SIGNATURE----- # gpg: Signature made Mon 16 Oct 2023 09:50:14 EDT # gpg: using RSA key 87A9BD933F87C606D276F62DDAE8E10975969CE5 # gpg: issuer "marcandre.lureau@redhat.com" # gpg: Good signature from "Marc-André Lureau <marcandre.lureau@redhat.com>" [full] # gpg: aka "Marc-André Lureau <marcandre.lureau@gmail.com>" [full] # Primary key fingerprint: 87A9 BD93 3F87 C606 D276 F62D DAE8 E109 7596 9CE5 * tag 'gpu-pull-request' of https://gitlab.com/marcandre.lureau/qemu: docs/system: add basic virtio-gpu documentation gfxstream + rutabaga: enable rutabaga gfxstream + rutabaga: meson support gfxstream + rutabaga: add initial support for gfxstream gfxstream + rutabaga prep: added need defintions, fields, and options virtio-gpu: blob prep virtio-gpu: hostmem virtio-gpu: CONTEXT_INIT feature virtio: Add shared memory capability Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
commit
0193b3bc05
@ -91,6 +91,7 @@ Emulated Devices
|
||||
devices/nvme.rst
|
||||
devices/usb.rst
|
||||
devices/vhost-user.rst
|
||||
devices/virtio-gpu.rst
|
||||
devices/virtio-pmem.rst
|
||||
devices/vhost-user-rng.rst
|
||||
devices/canokey.rst
|
||||
|
112
docs/system/devices/virtio-gpu.rst
Normal file
112
docs/system/devices/virtio-gpu.rst
Normal file
@ -0,0 +1,112 @@
|
||||
..
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
virtio-gpu
|
||||
==========
|
||||
|
||||
This document explains the setup and usage of the virtio-gpu device.
|
||||
The virtio-gpu device paravirtualizes the GPU and display controller.
|
||||
|
||||
Linux kernel support
|
||||
--------------------
|
||||
|
||||
virtio-gpu requires a guest Linux kernel built with the
|
||||
``CONFIG_DRM_VIRTIO_GPU`` option.
|
||||
|
||||
QEMU virtio-gpu variants
|
||||
------------------------
|
||||
|
||||
QEMU virtio-gpu device variants come in the following form:
|
||||
|
||||
* ``virtio-vga[-BACKEND]``
|
||||
* ``virtio-gpu[-BACKEND][-INTERFACE]``
|
||||
* ``vhost-user-vga``
|
||||
* ``vhost-user-pci``
|
||||
|
||||
**Backends:** QEMU provides a 2D virtio-gpu backend, and two accelerated
|
||||
backends: virglrenderer ('gl' device label) and rutabaga_gfx ('rutabaga'
|
||||
device label). There is a vhost-user backend that runs the graphics stack
|
||||
in a separate process for improved isolation.
|
||||
|
||||
**Interfaces:** QEMU further categorizes virtio-gpu device variants based
|
||||
on the interface exposed to the guest. The interfaces can be classified
|
||||
into VGA and non-VGA variants. The VGA ones are prefixed with virtio-vga
|
||||
or vhost-user-vga while the non-VGA ones are prefixed with virtio-gpu or
|
||||
vhost-user-gpu.
|
||||
|
||||
The VGA ones always use the PCI interface, but for the non-VGA ones, the
|
||||
user can further pick between MMIO or PCI. For MMIO, the user can suffix
|
||||
the device name with -device, though vhost-user-gpu does not support MMIO.
|
||||
For PCI, the user can suffix it with -pci. Without these suffixes, the
|
||||
platform default will be chosen.
|
||||
|
||||
virtio-gpu 2d
|
||||
-------------
|
||||
|
||||
The default 2D backend only performs 2D operations. The guest needs to
|
||||
employ a software renderer for 3D graphics.
|
||||
|
||||
Typically, the software renderer is provided by `Mesa`_ or `SwiftShader`_.
|
||||
Mesa's implementations (LLVMpipe, Lavapipe and virgl below) work out of box
|
||||
on typical modern Linux distributions.
|
||||
|
||||
.. parsed-literal::
|
||||
-device virtio-gpu
|
||||
|
||||
.. _Mesa: https://www.mesa3d.org/
|
||||
.. _SwiftShader: https://github.com/google/swiftshader
|
||||
|
||||
virtio-gpu virglrenderer
|
||||
------------------------
|
||||
|
||||
When using virgl accelerated graphics mode in the guest, OpenGL API calls
|
||||
are translated into an intermediate representation (see `Gallium3D`_). The
|
||||
intermediate representation is communicated to the host and the
|
||||
`virglrenderer`_ library on the host translates the intermediate
|
||||
representation back to OpenGL API calls.
|
||||
|
||||
.. parsed-literal::
|
||||
-device virtio-gpu-gl
|
||||
|
||||
.. _Gallium3D: https://www.freedesktop.org/wiki/Software/gallium/
|
||||
.. _virglrenderer: https://gitlab.freedesktop.org/virgl/virglrenderer/
|
||||
|
||||
virtio-gpu rutabaga
|
||||
-------------------
|
||||
|
||||
virtio-gpu can also leverage rutabaga_gfx to provide `gfxstream`_
|
||||
rendering and `Wayland display passthrough`_. With the gfxstream rendering
|
||||
mode, GLES and Vulkan calls are forwarded to the host with minimal
|
||||
modification.
|
||||
|
||||
The crosvm book provides directions on how to build a `gfxstream-enabled
|
||||
rutabaga`_ and launch a `guest Wayland proxy`_.
|
||||
|
||||
This device does require host blob support (``hostmem`` field below). The
|
||||
``hostmem`` field specifies the size of virtio-gpu host memory window.
|
||||
This is typically between 256M and 8G.
|
||||
|
||||
At least one virtio-gpu capability set ("capset") must be specified when
|
||||
starting the device. The currently capsets supported are ``gfxstream-vulkan``
|
||||
and ``cross-domain`` for Linux guests. For Android guests, the experimental
|
||||
``x-gfxstream-gles`` and ``x-gfxstream-composer`` capsets are also supported.
|
||||
|
||||
The device will try to auto-detect the wayland socket path if the
|
||||
``cross-domain`` capset name is set. The user may optionally specify
|
||||
``wayland-socket-path`` for non-standard paths.
|
||||
|
||||
The ``wsi`` option can be set to ``surfaceless`` or ``headless``.
|
||||
Surfaceless doesn't create a native window surface, but does copy from the
|
||||
render target to the Pixman buffer if a virtio-gpu 2D hypercall is issued.
|
||||
Headless is like surfaceless, but doesn't copy to the Pixman buffer.
|
||||
Surfaceless is the default if ``wsi`` is not specified.
|
||||
|
||||
.. parsed-literal::
|
||||
-device virtio-gpu-rutabaga,gfxstream-vulkan=on,cross-domain=on,
|
||||
hostmem=8G,wayland-socket-path=/tmp/nonstandard/mock_wayland.sock,
|
||||
wsi=headless
|
||||
|
||||
.. _gfxstream: https://android.googlesource.com/platform/hardware/google/gfxstream/
|
||||
.. _Wayland display passthrough: https://www.youtube.com/watch?v=OZJiHMtIQ2M
|
||||
.. _gfxstream-enabled rutabaga: https://crosvm.dev/book/appendix/rutabaga_gfx.html
|
||||
.. _guest Wayland proxy: https://crosvm.dev/book/devices/wayland.html
|
@ -80,6 +80,13 @@ if config_all_devices.has_key('CONFIG_VIRTIO_GPU')
|
||||
if_true: [files('virtio-gpu-gl.c', 'virtio-gpu-virgl.c'), pixman, virgl])
|
||||
hw_display_modules += {'virtio-gpu-gl': virtio_gpu_gl_ss}
|
||||
endif
|
||||
|
||||
if rutabaga.found()
|
||||
virtio_gpu_rutabaga_ss = ss.source_set()
|
||||
virtio_gpu_rutabaga_ss.add(when: ['CONFIG_VIRTIO_GPU', rutabaga],
|
||||
if_true: [files('virtio-gpu-rutabaga.c'), pixman])
|
||||
hw_display_modules += {'virtio-gpu-rutabaga': virtio_gpu_rutabaga_ss}
|
||||
endif
|
||||
endif
|
||||
|
||||
if config_all_devices.has_key('CONFIG_VIRTIO_PCI')
|
||||
@ -96,6 +103,12 @@ if config_all_devices.has_key('CONFIG_VIRTIO_PCI')
|
||||
if_true: [files('virtio-gpu-pci-gl.c'), pixman])
|
||||
hw_display_modules += {'virtio-gpu-pci-gl': virtio_gpu_pci_gl_ss}
|
||||
endif
|
||||
if rutabaga.found()
|
||||
virtio_gpu_pci_rutabaga_ss = ss.source_set()
|
||||
virtio_gpu_pci_rutabaga_ss.add(when: ['CONFIG_VIRTIO_GPU', 'CONFIG_VIRTIO_PCI', rutabaga],
|
||||
if_true: [files('virtio-gpu-pci-rutabaga.c'), pixman])
|
||||
hw_display_modules += {'virtio-gpu-pci-rutabaga': virtio_gpu_pci_rutabaga_ss}
|
||||
endif
|
||||
endif
|
||||
|
||||
if config_all_devices.has_key('CONFIG_VIRTIO_VGA')
|
||||
@ -114,6 +127,15 @@ if config_all_devices.has_key('CONFIG_VIRTIO_VGA')
|
||||
virtio_vga_gl_ss.add(when: 'CONFIG_ACPI', if_true: files('acpi-vga.c'),
|
||||
if_false: files('acpi-vga-stub.c'))
|
||||
hw_display_modules += {'virtio-vga-gl': virtio_vga_gl_ss}
|
||||
|
||||
if rutabaga.found()
|
||||
virtio_vga_rutabaga_ss = ss.source_set()
|
||||
virtio_vga_rutabaga_ss.add(when: ['CONFIG_VIRTIO_VGA', rutabaga],
|
||||
if_true: [files('virtio-vga-rutabaga.c'), pixman])
|
||||
virtio_vga_rutabaga_ss.add(when: 'CONFIG_ACPI', if_true: files('acpi-vga.c'),
|
||||
if_false: files('acpi-vga-stub.c'))
|
||||
hw_display_modules += {'virtio-vga-rutabaga': virtio_vga_rutabaga_ss}
|
||||
endif
|
||||
endif
|
||||
|
||||
system_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_lcdc.c'))
|
||||
|
@ -223,7 +223,8 @@ virtio_gpu_base_get_features(VirtIODevice *vdev, uint64_t features,
|
||||
{
|
||||
VirtIOGPUBase *g = VIRTIO_GPU_BASE(vdev);
|
||||
|
||||
if (virtio_gpu_virgl_enabled(g->conf)) {
|
||||
if (virtio_gpu_virgl_enabled(g->conf) ||
|
||||
virtio_gpu_rutabaga_enabled(g->conf)) {
|
||||
features |= (1 << VIRTIO_GPU_F_VIRGL);
|
||||
}
|
||||
if (virtio_gpu_edid_enabled(g->conf)) {
|
||||
@ -232,6 +233,9 @@ virtio_gpu_base_get_features(VirtIODevice *vdev, uint64_t features,
|
||||
if (virtio_gpu_blob_enabled(g->conf)) {
|
||||
features |= (1 << VIRTIO_GPU_F_RESOURCE_BLOB);
|
||||
}
|
||||
if (virtio_gpu_context_init_enabled(g->conf)) {
|
||||
features |= (1 << VIRTIO_GPU_F_CONTEXT_INIT);
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
|
47
hw/display/virtio-gpu-pci-rutabaga.c
Normal file
47
hw/display/virtio-gpu-pci-rutabaga.c
Normal file
@ -0,0 +1,47 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/module.h"
|
||||
#include "hw/pci/pci.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "hw/virtio/virtio.h"
|
||||
#include "hw/virtio/virtio-bus.h"
|
||||
#include "hw/virtio/virtio-gpu-pci.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
#define TYPE_VIRTIO_GPU_RUTABAGA_PCI "virtio-gpu-rutabaga-pci"
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(VirtIOGPURutabagaPCI, VIRTIO_GPU_RUTABAGA_PCI)
|
||||
|
||||
struct VirtIOGPURutabagaPCI {
|
||||
VirtIOGPUPCIBase parent_obj;
|
||||
|
||||
VirtIOGPURutabaga vdev;
|
||||
};
|
||||
|
||||
static void virtio_gpu_rutabaga_initfn(Object *obj)
|
||||
{
|
||||
VirtIOGPURutabagaPCI *dev = VIRTIO_GPU_RUTABAGA_PCI(obj);
|
||||
|
||||
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
|
||||
TYPE_VIRTIO_GPU_RUTABAGA);
|
||||
VIRTIO_GPU_PCI_BASE(obj)->vgpu = VIRTIO_GPU_BASE(&dev->vdev);
|
||||
}
|
||||
|
||||
static const TypeInfo virtio_gpu_rutabaga_pci_info[] = {
|
||||
{
|
||||
.name = TYPE_VIRTIO_GPU_RUTABAGA_PCI,
|
||||
.parent = TYPE_VIRTIO_GPU_PCI_BASE,
|
||||
.instance_size = sizeof(VirtIOGPURutabagaPCI),
|
||||
.instance_init = virtio_gpu_rutabaga_initfn,
|
||||
.interfaces = (InterfaceInfo[]) {
|
||||
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
DEFINE_TYPES(virtio_gpu_rutabaga_pci_info)
|
||||
|
||||
module_obj(TYPE_VIRTIO_GPU_RUTABAGA_PCI);
|
||||
module_kconfig(VIRTIO_PCI);
|
||||
module_dep("hw-display-virtio-gpu-pci");
|
@ -33,6 +33,20 @@ static void virtio_gpu_pci_base_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
|
||||
DeviceState *vdev = DEVICE(g);
|
||||
int i;
|
||||
|
||||
if (virtio_gpu_hostmem_enabled(g->conf)) {
|
||||
vpci_dev->msix_bar_idx = 1;
|
||||
vpci_dev->modern_mem_bar_idx = 2;
|
||||
memory_region_init(&g->hostmem, OBJECT(g), "virtio-gpu-hostmem",
|
||||
g->conf.hostmem);
|
||||
pci_register_bar(&vpci_dev->pci_dev, 4,
|
||||
PCI_BASE_ADDRESS_SPACE_MEMORY |
|
||||
PCI_BASE_ADDRESS_MEM_PREFETCH |
|
||||
PCI_BASE_ADDRESS_MEM_TYPE_64,
|
||||
&g->hostmem);
|
||||
virtio_pci_add_shm_cap(vpci_dev, 4, 0, g->conf.hostmem,
|
||||
VIRTIO_GPU_SHM_ID_HOST_VISIBLE);
|
||||
}
|
||||
|
||||
virtio_pci_force_virtio_1(vpci_dev);
|
||||
if (!qdev_realize(vdev, BUS(&vpci_dev->bus), errp)) {
|
||||
return;
|
||||
|
1120
hw/display/virtio-gpu-rutabaga.c
Normal file
1120
hw/display/virtio-gpu-rutabaga.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -33,15 +33,11 @@
|
||||
|
||||
#define VIRTIO_GPU_VM_VERSION 1
|
||||
|
||||
static struct virtio_gpu_simple_resource*
|
||||
virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id);
|
||||
static struct virtio_gpu_simple_resource *
|
||||
virtio_gpu_find_check_resource(VirtIOGPU *g, uint32_t resource_id,
|
||||
bool require_backing,
|
||||
const char *caller, uint32_t *error);
|
||||
|
||||
static void virtio_gpu_cleanup_mapping(VirtIOGPU *g,
|
||||
struct virtio_gpu_simple_resource *res);
|
||||
static void virtio_gpu_reset_bh(void *opaque);
|
||||
|
||||
void virtio_gpu_update_cursor_data(VirtIOGPU *g,
|
||||
@ -116,7 +112,7 @@ static void update_cursor(VirtIOGPU *g, struct virtio_gpu_update_cursor *cursor)
|
||||
cursor->resource_id ? 1 : 0);
|
||||
}
|
||||
|
||||
static struct virtio_gpu_simple_resource *
|
||||
struct virtio_gpu_simple_resource *
|
||||
virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id)
|
||||
{
|
||||
struct virtio_gpu_simple_resource *res;
|
||||
@ -904,8 +900,8 @@ void virtio_gpu_cleanup_mapping_iov(VirtIOGPU *g,
|
||||
g_free(iov);
|
||||
}
|
||||
|
||||
static void virtio_gpu_cleanup_mapping(VirtIOGPU *g,
|
||||
struct virtio_gpu_simple_resource *res)
|
||||
void virtio_gpu_cleanup_mapping(VirtIOGPU *g,
|
||||
struct virtio_gpu_simple_resource *res)
|
||||
{
|
||||
virtio_gpu_cleanup_mapping_iov(g, res->iov, res->iov_cnt);
|
||||
res->iov = NULL;
|
||||
@ -1367,8 +1363,9 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
|
||||
VirtIOGPU *g = VIRTIO_GPU(qdev);
|
||||
|
||||
if (virtio_gpu_blob_enabled(g->parent_obj.conf)) {
|
||||
if (!virtio_gpu_have_udmabuf()) {
|
||||
error_setg(errp, "cannot enable blob resources without udmabuf");
|
||||
if (!virtio_gpu_rutabaga_enabled(g->parent_obj.conf) &&
|
||||
!virtio_gpu_have_udmabuf()) {
|
||||
error_setg(errp, "need rutabaga or udmabuf for blob resources");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1511,6 +1508,7 @@ static Property virtio_gpu_properties[] = {
|
||||
256 * MiB),
|
||||
DEFINE_PROP_BIT("blob", VirtIOGPU, parent_obj.conf.flags,
|
||||
VIRTIO_GPU_FLAG_BLOB_ENABLED, false),
|
||||
DEFINE_PROP_SIZE("hostmem", VirtIOGPU, parent_obj.conf.hostmem, 0),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
|
50
hw/display/virtio-vga-rutabaga.c
Normal file
50
hw/display/virtio-vga-rutabaga.c
Normal file
@ -0,0 +1,50 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/pci/pci.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "hw/virtio/virtio-gpu.h"
|
||||
#include "hw/display/vga.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/module.h"
|
||||
#include "virtio-vga.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
#define TYPE_VIRTIO_VGA_RUTABAGA "virtio-vga-rutabaga"
|
||||
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(VirtIOVGARutabaga, VIRTIO_VGA_RUTABAGA)
|
||||
|
||||
struct VirtIOVGARutabaga {
|
||||
VirtIOVGABase parent_obj;
|
||||
|
||||
VirtIOGPURutabaga vdev;
|
||||
};
|
||||
|
||||
static void virtio_vga_rutabaga_inst_initfn(Object *obj)
|
||||
{
|
||||
VirtIOVGARutabaga *dev = VIRTIO_VGA_RUTABAGA(obj);
|
||||
|
||||
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
|
||||
TYPE_VIRTIO_GPU_RUTABAGA);
|
||||
VIRTIO_VGA_BASE(dev)->vgpu = VIRTIO_GPU_BASE(&dev->vdev);
|
||||
}
|
||||
|
||||
static VirtioPCIDeviceTypeInfo virtio_vga_rutabaga_info = {
|
||||
.generic_name = TYPE_VIRTIO_VGA_RUTABAGA,
|
||||
.parent = TYPE_VIRTIO_VGA_BASE,
|
||||
.instance_size = sizeof(VirtIOVGARutabaga),
|
||||
.instance_init = virtio_vga_rutabaga_inst_initfn,
|
||||
};
|
||||
module_obj(TYPE_VIRTIO_VGA_RUTABAGA);
|
||||
module_kconfig(VIRTIO_VGA);
|
||||
|
||||
static void virtio_vga_register_types(void)
|
||||
{
|
||||
if (have_vga) {
|
||||
virtio_pci_types_register(&virtio_vga_rutabaga_info);
|
||||
}
|
||||
}
|
||||
|
||||
type_init(virtio_vga_register_types)
|
||||
|
||||
module_dep("hw-display-virtio-vga");
|
@ -115,17 +115,32 @@ static void virtio_vga_base_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
|
||||
pci_register_bar(&vpci_dev->pci_dev, 0,
|
||||
PCI_BASE_ADDRESS_MEM_PREFETCH, &vga->vram);
|
||||
|
||||
/*
|
||||
* Configure virtio bar and regions
|
||||
*
|
||||
* We use bar #2 for the mmio regions, to be compatible with stdvga.
|
||||
* virtio regions are moved to the end of bar #2, to make room for
|
||||
* the stdvga mmio registers at the start of bar #2.
|
||||
*/
|
||||
vpci_dev->modern_mem_bar_idx = 2;
|
||||
vpci_dev->msix_bar_idx = 4;
|
||||
vpci_dev->modern_io_bar_idx = 5;
|
||||
|
||||
if (!virtio_gpu_hostmem_enabled(g->conf)) {
|
||||
/*
|
||||
* Configure virtio bar and regions
|
||||
*
|
||||
* We use bar #2 for the mmio regions, to be compatible with stdvga.
|
||||
* virtio regions are moved to the end of bar #2, to make room for
|
||||
* the stdvga mmio registers at the start of bar #2.
|
||||
*/
|
||||
vpci_dev->modern_mem_bar_idx = 2;
|
||||
vpci_dev->msix_bar_idx = 4;
|
||||
} else {
|
||||
vpci_dev->msix_bar_idx = 1;
|
||||
vpci_dev->modern_mem_bar_idx = 2;
|
||||
memory_region_init(&g->hostmem, OBJECT(g), "virtio-gpu-hostmem",
|
||||
g->conf.hostmem);
|
||||
pci_register_bar(&vpci_dev->pci_dev, 4,
|
||||
PCI_BASE_ADDRESS_SPACE_MEMORY |
|
||||
PCI_BASE_ADDRESS_MEM_PREFETCH |
|
||||
PCI_BASE_ADDRESS_MEM_TYPE_64,
|
||||
&g->hostmem);
|
||||
virtio_pci_add_shm_cap(vpci_dev, 4, 0, g->conf.hostmem,
|
||||
VIRTIO_GPU_SHM_ID_HOST_VISIBLE);
|
||||
}
|
||||
|
||||
if (!(vpci_dev->flags & VIRTIO_PCI_FLAG_PAGE_PER_VQ)) {
|
||||
/*
|
||||
* with page-per-vq=off there is no padding space we can use
|
||||
|
@ -1435,6 +1435,24 @@ static int virtio_pci_add_mem_cap(VirtIOPCIProxy *proxy,
|
||||
return offset;
|
||||
}
|
||||
|
||||
int virtio_pci_add_shm_cap(VirtIOPCIProxy *proxy,
|
||||
uint8_t bar, uint64_t offset, uint64_t length,
|
||||
uint8_t id)
|
||||
{
|
||||
struct virtio_pci_cap64 cap = {
|
||||
.cap.cap_len = sizeof cap,
|
||||
.cap.cfg_type = VIRTIO_PCI_CAP_SHARED_MEMORY_CFG,
|
||||
};
|
||||
|
||||
cap.cap.bar = bar;
|
||||
cap.cap.length = cpu_to_le32(length);
|
||||
cap.length_hi = cpu_to_le32(length >> 32);
|
||||
cap.cap.offset = cpu_to_le32(offset);
|
||||
cap.offset_hi = cpu_to_le32(offset >> 32);
|
||||
cap.cap.id = id;
|
||||
return virtio_pci_add_mem_cap(proxy, &cap.cap);
|
||||
}
|
||||
|
||||
static uint64_t virtio_pci_common_read(void *opaque, hwaddr addr,
|
||||
unsigned size)
|
||||
{
|
||||
|
@ -70,6 +70,21 @@ virtio_gpu_create_blob_bswap(struct virtio_gpu_resource_create_blob *cblob)
|
||||
le64_to_cpus(&cblob->size);
|
||||
}
|
||||
|
||||
static inline void
|
||||
virtio_gpu_map_blob_bswap(struct virtio_gpu_resource_map_blob *mblob)
|
||||
{
|
||||
virtio_gpu_ctrl_hdr_bswap(&mblob->hdr);
|
||||
le32_to_cpus(&mblob->resource_id);
|
||||
le64_to_cpus(&mblob->offset);
|
||||
}
|
||||
|
||||
static inline void
|
||||
virtio_gpu_unmap_blob_bswap(struct virtio_gpu_resource_unmap_blob *ublob)
|
||||
{
|
||||
virtio_gpu_ctrl_hdr_bswap(&ublob->hdr);
|
||||
le32_to_cpus(&ublob->resource_id);
|
||||
}
|
||||
|
||||
static inline void
|
||||
virtio_gpu_scanout_blob_bswap(struct virtio_gpu_set_scanout_blob *ssb)
|
||||
{
|
||||
|
@ -38,6 +38,9 @@ OBJECT_DECLARE_SIMPLE_TYPE(VirtIOGPUGL, VIRTIO_GPU_GL)
|
||||
#define TYPE_VHOST_USER_GPU "vhost-user-gpu"
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(VhostUserGPU, VHOST_USER_GPU)
|
||||
|
||||
#define TYPE_VIRTIO_GPU_RUTABAGA "virtio-gpu-rutabaga-device"
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(VirtIOGPURutabaga, VIRTIO_GPU_RUTABAGA)
|
||||
|
||||
struct virtio_gpu_simple_resource {
|
||||
uint32_t resource_id;
|
||||
uint32_t width;
|
||||
@ -93,6 +96,8 @@ enum virtio_gpu_base_conf_flags {
|
||||
VIRTIO_GPU_FLAG_EDID_ENABLED,
|
||||
VIRTIO_GPU_FLAG_DMABUF_ENABLED,
|
||||
VIRTIO_GPU_FLAG_BLOB_ENABLED,
|
||||
VIRTIO_GPU_FLAG_CONTEXT_INIT_ENABLED,
|
||||
VIRTIO_GPU_FLAG_RUTABAGA_ENABLED,
|
||||
};
|
||||
|
||||
#define virtio_gpu_virgl_enabled(_cfg) \
|
||||
@ -105,12 +110,19 @@ enum virtio_gpu_base_conf_flags {
|
||||
(_cfg.flags & (1 << VIRTIO_GPU_FLAG_DMABUF_ENABLED))
|
||||
#define virtio_gpu_blob_enabled(_cfg) \
|
||||
(_cfg.flags & (1 << VIRTIO_GPU_FLAG_BLOB_ENABLED))
|
||||
#define virtio_gpu_context_init_enabled(_cfg) \
|
||||
(_cfg.flags & (1 << VIRTIO_GPU_FLAG_CONTEXT_INIT_ENABLED))
|
||||
#define virtio_gpu_rutabaga_enabled(_cfg) \
|
||||
(_cfg.flags & (1 << VIRTIO_GPU_FLAG_RUTABAGA_ENABLED))
|
||||
#define virtio_gpu_hostmem_enabled(_cfg) \
|
||||
(_cfg.hostmem > 0)
|
||||
|
||||
struct virtio_gpu_base_conf {
|
||||
uint32_t max_outputs;
|
||||
uint32_t flags;
|
||||
uint32_t xres;
|
||||
uint32_t yres;
|
||||
uint64_t hostmem;
|
||||
};
|
||||
|
||||
struct virtio_gpu_ctrl_command {
|
||||
@ -134,6 +146,8 @@ struct VirtIOGPUBase {
|
||||
int renderer_blocked;
|
||||
int enable;
|
||||
|
||||
MemoryRegion hostmem;
|
||||
|
||||
struct virtio_gpu_scanout scanout[VIRTIO_GPU_MAX_SCANOUTS];
|
||||
|
||||
int enabled_output_bitmask;
|
||||
@ -224,6 +238,27 @@ struct VhostUserGPU {
|
||||
bool backend_blocked;
|
||||
};
|
||||
|
||||
#define MAX_SLOTS 4096
|
||||
|
||||
struct MemoryRegionInfo {
|
||||
int used;
|
||||
MemoryRegion mr;
|
||||
uint32_t resource_id;
|
||||
};
|
||||
|
||||
struct rutabaga;
|
||||
|
||||
struct VirtIOGPURutabaga {
|
||||
VirtIOGPU parent_obj;
|
||||
struct MemoryRegionInfo memory_regions[MAX_SLOTS];
|
||||
uint64_t capset_mask;
|
||||
char *wayland_socket_path;
|
||||
char *wsi;
|
||||
bool headless;
|
||||
uint32_t num_capsets;
|
||||
struct rutabaga *rutabaga;
|
||||
};
|
||||
|
||||
#define VIRTIO_GPU_FILL_CMD(out) do { \
|
||||
size_t virtiogpufillcmd_s_ = \
|
||||
iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num, 0, \
|
||||
@ -249,6 +284,9 @@ void virtio_gpu_base_fill_display_info(VirtIOGPUBase *g,
|
||||
void virtio_gpu_base_generate_edid(VirtIOGPUBase *g, int scanout,
|
||||
struct virtio_gpu_resp_edid *edid);
|
||||
/* virtio-gpu.c */
|
||||
struct virtio_gpu_simple_resource *
|
||||
virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id);
|
||||
|
||||
void virtio_gpu_ctrl_response(VirtIOGPU *g,
|
||||
struct virtio_gpu_ctrl_command *cmd,
|
||||
struct virtio_gpu_ctrl_hdr *resp,
|
||||
@ -267,6 +305,8 @@ int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
|
||||
uint32_t *niov);
|
||||
void virtio_gpu_cleanup_mapping_iov(VirtIOGPU *g,
|
||||
struct iovec *iov, uint32_t count);
|
||||
void virtio_gpu_cleanup_mapping(VirtIOGPU *g,
|
||||
struct virtio_gpu_simple_resource *res);
|
||||
void virtio_gpu_process_cmdq(VirtIOGPU *g);
|
||||
void virtio_gpu_device_realize(DeviceState *qdev, Error **errp);
|
||||
void virtio_gpu_reset(VirtIODevice *vdev);
|
||||
|
@ -264,4 +264,8 @@ unsigned virtio_pci_optimal_num_queues(unsigned fixed_queues);
|
||||
void virtio_pci_set_guest_notifier_fd_handler(VirtIODevice *vdev, VirtQueue *vq,
|
||||
int n, bool assign,
|
||||
bool with_irqfd);
|
||||
|
||||
int virtio_pci_add_shm_cap(VirtIOPCIProxy *proxy, uint8_t bar, uint64_t offset,
|
||||
uint64_t length, uint8_t id);
|
||||
|
||||
#endif
|
||||
|
@ -1046,6 +1046,12 @@ if not get_option('virglrenderer').auto() or have_system or have_vhost_user_gpu
|
||||
dependencies: virgl))
|
||||
endif
|
||||
endif
|
||||
rutabaga = not_found
|
||||
if not get_option('rutabaga_gfx').auto() or have_system or have_vhost_user_gpu
|
||||
rutabaga = dependency('rutabaga_gfx_ffi',
|
||||
method: 'pkg-config',
|
||||
required: get_option('rutabaga_gfx'))
|
||||
endif
|
||||
blkio = not_found
|
||||
if not get_option('blkio').auto() or have_block
|
||||
blkio = dependency('blkio',
|
||||
@ -4277,6 +4283,7 @@ summary_info += {'libtasn1': tasn1}
|
||||
summary_info += {'PAM': pam}
|
||||
summary_info += {'iconv support': iconv}
|
||||
summary_info += {'virgl support': virgl}
|
||||
summary_info += {'rutabaga support': rutabaga}
|
||||
summary_info += {'blkio support': blkio}
|
||||
summary_info += {'curl support': curl}
|
||||
summary_info += {'Multipath support': mpathpersist}
|
||||
|
@ -230,6 +230,8 @@ option('vmnet', type : 'feature', value : 'auto',
|
||||
description: 'vmnet.framework network backend support')
|
||||
option('virglrenderer', type : 'feature', value : 'auto',
|
||||
description: 'virgl rendering support')
|
||||
option('rutabaga_gfx', type : 'feature', value : 'auto',
|
||||
description: 'rutabaga_gfx support')
|
||||
option('png', type : 'feature', value : 'auto',
|
||||
description: 'PNG support with libpng')
|
||||
option('vnc', type : 'feature', value : 'auto',
|
||||
|
@ -156,6 +156,7 @@ meson_options_help() {
|
||||
printf "%s\n" ' rbd Ceph block device driver'
|
||||
printf "%s\n" ' rdma Enable RDMA-based migration'
|
||||
printf "%s\n" ' replication replication support'
|
||||
printf "%s\n" ' rutabaga-gfx rutabaga_gfx support'
|
||||
printf "%s\n" ' sdl SDL user interface'
|
||||
printf "%s\n" ' sdl-image SDL Image support for icons'
|
||||
printf "%s\n" ' seccomp seccomp support'
|
||||
@ -425,6 +426,8 @@ _meson_option_parse() {
|
||||
--disable-replication) printf "%s" -Dreplication=disabled ;;
|
||||
--enable-rng-none) printf "%s" -Drng_none=true ;;
|
||||
--disable-rng-none) printf "%s" -Drng_none=false ;;
|
||||
--enable-rutabaga-gfx) printf "%s" -Drutabaga_gfx=enabled ;;
|
||||
--disable-rutabaga-gfx) printf "%s" -Drutabaga_gfx=disabled ;;
|
||||
--enable-safe-stack) printf "%s" -Dsafe_stack=true ;;
|
||||
--disable-safe-stack) printf "%s" -Dsafe_stack=false ;;
|
||||
--enable-sanitizers) printf "%s" -Dsanitizers=true ;;
|
||||
|
@ -86,6 +86,9 @@ static const QDevAlias qdev_alias_table[] = {
|
||||
{ "virtio-gpu-pci", "virtio-gpu", QEMU_ARCH_VIRTIO_PCI },
|
||||
{ "virtio-gpu-gl-device", "virtio-gpu-gl", QEMU_ARCH_VIRTIO_MMIO },
|
||||
{ "virtio-gpu-gl-pci", "virtio-gpu-gl", QEMU_ARCH_VIRTIO_PCI },
|
||||
{ "virtio-gpu-rutabaga-device", "virtio-gpu-rutabaga",
|
||||
QEMU_ARCH_VIRTIO_MMIO },
|
||||
{ "virtio-gpu-rutabaga-pci", "virtio-gpu-rutabaga", QEMU_ARCH_VIRTIO_PCI },
|
||||
{ "virtio-input-host-device", "virtio-input-host", QEMU_ARCH_VIRTIO_MMIO },
|
||||
{ "virtio-input-host-ccw", "virtio-input-host", QEMU_ARCH_VIRTIO_CCW },
|
||||
{ "virtio-input-host-pci", "virtio-input-host", QEMU_ARCH_VIRTIO_PCI },
|
||||
|
@ -216,6 +216,7 @@ static struct {
|
||||
{ .driver = "ati-vga", .flag = &default_vga },
|
||||
{ .driver = "vhost-user-vga", .flag = &default_vga },
|
||||
{ .driver = "virtio-vga-gl", .flag = &default_vga },
|
||||
{ .driver = "virtio-vga-rutabaga", .flag = &default_vga },
|
||||
};
|
||||
|
||||
static QemuOptsList qemu_rtc_opts = {
|
||||
|
Loading…
Reference in New Issue
Block a user