17ec681f3SmrgVirtio-GPU Venus
27ec681f3Smrg================
37ec681f3Smrg
47ec681f3SmrgVenus is a Virtio-GPU protocol for Vulkan command serialization.  The protocol
57ec681f3Smrgdefinition and codegen are hosted at `venus-protocol
67ec681f3Smrg<https://gitlab.freedesktop.org/olv/venus-protocol>`__.  The renderer is
77ec681f3Smrghosted at `virglrenderer
87ec681f3Smrg<https://gitlab.freedesktop.org/virgl/virglrenderer>`__.
97ec681f3Smrg
107ec681f3SmrgThe protocol is still under development.  This driver and the renderer are
117ec681f3Smrgboth considered experimental.
127ec681f3Smrg
137ec681f3SmrgRequirements
147ec681f3Smrg------------
157ec681f3Smrg
167ec681f3SmrgThe Venus renderer requires
177ec681f3Smrg
187ec681f3Smrg- Vulkan 1.1
197ec681f3Smrg- ``VK_EXT_external_memory_dma_buf``
207ec681f3Smrg- ``VK_EXT_image_drm_format_modifier``
217ec681f3Smrg- ``VK_EXT_queue_family_foreign``
227ec681f3Smrg
237ec681f3Smrgfrom the host driver.  However, it violates the spec in some places currently
247ec681f3Smrgand also relies on implementation-defined behaviors in others.  It is not
257ec681f3Smrgexpected to work on all drivers meeting the requirements.  It has only been
267ec681f3Smrgtested with
277ec681f3Smrg
287ec681f3Smrg- ANV 21.1 or later
297ec681f3Smrg- RADV 21.1 or later (the host kernel must have
307ec681f3Smrg  ``CONFIG_TRANSPARENT_HUGEPAGE`` disabled because of this `KVM issue
317ec681f3Smrg  <https://github.com/google/security-research/security/advisories/GHSA-7wq5-phmq-m584>`__)
327ec681f3Smrg
337ec681f3SmrgThe Venus driver requires supports for
347ec681f3Smrg
357ec681f3Smrg- ``VIRTGPU_PARAM_RESOURCE_BLOB``
367ec681f3Smrg- ``VIRTGPU_PARAM_HOST_VISIBLE``
377ec681f3Smrg- ``VIRTGPU_PARAM_CROSS_DEVICE``
387ec681f3Smrg- ``VIRTGPU_PARAM_CONTEXT_INIT``
397ec681f3Smrg
407ec681f3Smrgfrom the virtio-gpu kernel driver, unless vtest is used.  Currently, this
417ec681f3Smrgmeans the `context-init
427ec681f3Smrg<https://gitlab.freedesktop.org/virgl/drm-misc-next/-/tree/context-init>`__
437ec681f3Smrgkernel branch paired with `crosvm
447ec681f3Smrg<https://chromium.googlesource.com/chromiumos/platform/crosvm>`__.
457ec681f3Smrg
467ec681f3Smrgvtest
477ec681f3Smrg-----
487ec681f3Smrg
497ec681f3SmrgThe simplest way to test Venus is to use virglrenderer's vtest server.  To
507ec681f3Smrgbuild virglrenderer with Venus support and to start the vtest server,
517ec681f3Smrg
527ec681f3Smrg.. code-block:: console
537ec681f3Smrg
547ec681f3Smrg    $ git clone https://gitlab.freedesktop.org/virgl/virglrenderer.git
557ec681f3Smrg    $ cd virglrenderer
567ec681f3Smrg    $ meson out -Dvenus-experimental=true
577ec681f3Smrg    $ ninja -C out
587ec681f3Smrg    $ ./out/vtest/virgl_test_server --venus
597ec681f3Smrg
607ec681f3SmrgIn another shell,
617ec681f3Smrg
627ec681f3Smrg.. code-block:: console
637ec681f3Smrg
647ec681f3Smrg    $ export VK_ICD_FILENAMES=<path-to-virtio_icd.x86_64.json>
657ec681f3Smrg    $ export VN_DEBUG=vtest
667ec681f3Smrg    $ vulkaninfo
677ec681f3Smrg    $ vkcube
687ec681f3Smrg
697ec681f3SmrgIf the host driver of the system is not new enough, it is a good idea to build
707ec681f3Smrgthe host driver as well when building the Venus driver.  Just remember to set
717ec681f3Smrg:envvar:`VK_ICD_FILENAMES` when starting the vtest server so that the vtest
727ec681f3Smrgserver finds the locally built host driver.
737ec681f3Smrg
747ec681f3SmrgVirtio-GPU
757ec681f3Smrg----------
767ec681f3Smrg
777ec681f3SmrgBecause the driver requires ``VIRTGPU_PARAM_CONTEXT_INIT`` from the virtio-gpu
787ec681f3Smrgkernel driver, one must make sure the guest kernel includes the changes from
797ec681f3Smrgthe `context-init
807ec681f3Smrg<https://gitlab.freedesktop.org/virgl/drm-misc-next/-/tree/context-init>`__
817ec681f3Smrgbranch.
827ec681f3Smrg
837ec681f3SmrgTo build crosvm,
847ec681f3Smrg
857ec681f3Smrg.. code-block:: console
867ec681f3Smrg
877ec681f3Smrg $ mkdir crosvm
887ec681f3Smrg $ cd crosvm
897ec681f3Smrg $ wget https://storage.googleapis.com/git-repo-downloads/repo
907ec681f3Smrg $ chmod +x repo
917ec681f3Smrg $ ./repo init -g crosvm -u https://chromium.googlesource.com/chromiumos/manifest.git
927ec681f3Smrg $ ./repo sync
937ec681f3Smrg $ cd src/platform/crosvm
947ec681f3Smrg $ RUSTFLAGS="-L<path-to-virglrenderer>/out/src" cargo build \
957ec681f3Smrg       --features "x virgl_renderer virgl_renderer_next default-no-sandbox"
967ec681f3Smrg
977ec681f3SmrgNote that crosvm must be built with ``default-no-sandbox`` or started with
987ec681f3Smrg``--disable-sandbox`` in this setup.
997ec681f3Smrg
1007ec681f3SmrgThis is how one might want to start crosvm
1017ec681f3Smrg
1027ec681f3Smrg.. code-block:: console
1037ec681f3Smrg
1047ec681f3Smrg $ sudo LD_LIBRARY_PATH=<...> VK_ICD_FILENAMES=<...> ./target/debug/crosvm run \
1057ec681f3Smrg       --gpu vulkan=true \
1067ec681f3Smrg       --display-window-keyboard \
1077ec681f3Smrg       --display-window-mouse \
1087ec681f3Smrg       --host_ip 192.168.0.1 \
1097ec681f3Smrg       --netmask 255.255.255.0 \
1107ec681f3Smrg       --mac 12:34:56:78:9a:bc \
1117ec681f3Smrg       --rwdisk disk.qcow2 \
1127ec681f3Smrg       -p root=/dev/vda1 \
1137ec681f3Smrg       <path-to-bzImage>
1147ec681f3Smrg
1157ec681f3Smrgassuming a working system is installed to partition 1 of ``disk.qcow2``.
1167ec681f3Smrg``sudo`` or ``CAP_NET_ADMIN`` is needed to set up the TAP network device.
1177ec681f3Smrg
1187ec681f3SmrgVirtio-GPU and Virtio-WL
1197ec681f3Smrg------------------------
1207ec681f3Smrg
1217ec681f3SmrgIn this setup, the guest userspace uses Xwayland and a special Wayland
1227ec681f3Smrgcompositor to connect guest X11/Wayland clients to the host Wayland
1237ec681f3Smrgcompositor, using Virtio-WL as the transport.  This setup is more tedious, but
1247ec681f3Smrgthat should hopefully change over time.
1257ec681f3Smrg
1267ec681f3SmrgFor now, the guest kernel must be built from the ``chromeos-5.10`` branch of
1277ec681f3Smrgthe `Chrome OS kernel
1287ec681f3Smrg<https://chromium.googlesource.com/chromiumos/third_party/kernel>`__.  crosvm
1297ec681f3Smrgshould also be built with ``wl-dmabuf`` feature rather than ``x`` feature.
1307ec681f3Smrg
1317ec681f3SmrgTo build minigbm and to enable minigbm support in virglrenderer,
1327ec681f3Smrg
1337ec681f3Smrg.. code-block:: console
1347ec681f3Smrg
1357ec681f3Smrg $ git clone https://chromium.googlesource.com/chromiumos/platform/minigbm
1367ec681f3Smrg $ cd minigbm
1377ec681f3Smrg $ CFLAGS=-DDRV_<I915-or-your-driver> OUT=out DESTDIR=out/install make install
1387ec681f3Smrg $ cd ../virglrenderer
1397ec681f3Smrg $ meson configure out -Dminigbm_allocation=true
1407ec681f3Smrg $ ninja -C out
1417ec681f3Smrg
1427ec681f3SmrgMake sure a host Wayland compositor is running.  Replace
1437ec681f3Smrg``--display-window-keyboard --display-window-mouse`` by
1447ec681f3Smrg``--wayland-sock=<path-to-wayland-socket>`` when starting crosvm.
1457ec681f3Smrg
1467ec681f3SmrgIn the guest, build and start sommelier, the special Wayland compositor,
1477ec681f3Smrg
1487ec681f3Smrg.. code-block:: console
1497ec681f3Smrg
1507ec681f3Smrg $ git clone https://chromium.googlesource.com/chromiumos/platform2
1517ec681f3Smrg $ cd platform2/vm_tools/sommelier
1527ec681f3Smrg $ meson out -Dxwayland_path=/usr/bin/Xwayland -Dxwayland_gl_driver_path=/usr/lib/dri
1537ec681f3Smrg $ ninja -C out
1547ec681f3Smrg $ sudo chmod 777 /dev/wl0
1557ec681f3Smrg $ ./out/sommelier -X --glamor
1567ec681f3Smrg       --xwayland-gl-driver-path=<path-to-locally-built-gl-driver> \
1577ec681f3Smrg       sleep infinity
1587ec681f3Smrg
1597ec681f3Smrgsommelier requires ``xdg-shell-unstable-v6`` rather than the stable
1607ec681f3Smrg``xdg-shell`` from the host compositor.  One must make sure the host
1617ec681f3Smrgcompositor still supports the older extension.
1627ec681f3Smrg
1637ec681f3SmrgOptional Requirements
1647ec681f3Smrg---------------------
1657ec681f3Smrg
1667ec681f3SmrgWhen virglrenderer is built with ``-Dminigbm_allocation=true``, the Venus
1677ec681f3Smrgrenderer might need to import GBM BOs.  The imports will fail unless the host
1687ec681f3Smrgdriver supports the formats, especially multi-planar ones, and the DRM format
1697ec681f3Smrgmodifiers of the GBM BOs.
1707ec681f3Smrg
1717ec681f3SmrgIn the future, if virglrenderer's ``virgl_renderer_export_fence`` is
1727ec681f3Smrgsupported, the Venus renderer will require ``VK_KHR_external_fence_fd`` with
1737ec681f3Smrg``VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT`` from the host driver.
1747ec681f3Smrg
1757ec681f3SmrgA WSI image of the Venus driver is an external image to the host driver.  When
1767ec681f3Smrgthe WSI image is transitioned from ``VK_IMAGE_LAYOUT_UNDEFINED`` after image
1777ec681f3Smrgacquisition, the Venus driver does not request the Venus renderer to perform
1787ec681f3Smrgan ownership transfer on the external image.  It is unclear if the ownership
1797ec681f3Smrgtransfer is required or not.  A specification issue has been filed for
1807ec681f3Smrgclarifications.  See the comment before ``vn_cmd_fix_image_memory_barrier``
1817ec681f3Smrgfor more details.
1827ec681f3Smrg
1837ec681f3SmrgVK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
1847ec681f3Smrg-----------------------------------
1857ec681f3Smrg
1867ec681f3SmrgThe Venus renderer makes assumptions about ``VkDeviceMemory`` that has
1877ec681f3Smrg``VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT``.  The assumptions are illegal and rely
1887ec681f3Smrgon the current behaviors of the host drivers.  It should be possible to remove
1897ec681f3Smrgsome of the assumptions and incrementally improve compatibilities with more
1907ec681f3Smrghost drivers by imposing platform-specific requirements.  But the long-term
1917ec681f3Smrgplan is to create a new Vulkan extension for the host drivers to address this
1927ec681f3Smrgspecific use case.
1937ec681f3Smrg
1947ec681f3SmrgThe Venus renderer assumes a device memory that has
1957ec681f3Smrg``VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT`` can be exported as a mmapable dma-buf
1967ec681f3Smrg(in the future, the plan is to export the device memory as an opaque fd).  It
1977ec681f3Smrgchains ``VkExportMemoryAllocateInfo`` to ``VkMemoryAllocateInfo`` without
1987ec681f3Smrgchecking if the host driver can export the device memory.
1997ec681f3Smrg
2007ec681f3SmrgThe dma-buf is mapped (in the future, the plan is to import the opaque fd and
2017ec681f3Smrgcall ``vkMapMemory``) but the mapping is not accessed.  Instead, the mapping
2027ec681f3Smrgis passed to ``KVM_SET_USER_MEMORY_REGION``.  The hypervisor, host KVM, and
2037ec681f3Smrgthe guest kernel work together to set up a write-back or write-combined guest
2047ec681f3Smrgmapping (see ``virtio_gpu_vram_mmap`` of the virtio-gpu kernel driver).  CPU
2057ec681f3Smrgaccesses to the device memory are via the guest mapping, and are assumed to be
2067ec681f3Smrgcoherent when the device memory also has
2077ec681f3Smrg``VK_MEMORY_PROPERTY_HOST_COHERENT_BIT``.
2087ec681f3Smrg
2097ec681f3SmrgWhen a ``VkImage`` or a ``VkBuffer`` is created, the Venus renderer does not
2107ec681f3Smrgknow if the image or the buffer will be bound to such a device memory or not.
2117ec681f3SmrgAs a result, the Venus renderer unconditionally chains
2127ec681f3Smrg``VkExternalMemoryImageCreateInfo`` to ``VkImageCreateInfo`` and chains
2137ec681f3Smrg``VkExternalMemoryBufferCreateInfo`` to ``VkBufferCreateInfo`` without
2147ec681f3Smrgchecking for the host driver support.
215