| Message ID | 20260515-virglrenderer-v7-8-1f1814b65ccd@gmail.com |
|---|---|
| State | Changes Requested |
| Headers | show |
| Series | Add virglrenderer support | expand |
On 16/05/2026 04:03, Joseph Kogut wrote: > Add basic smoke test for glmark2 running in a nested qemu guest with > virtio-gpu-gl-pci. > > The outer machine uses the Mesa softpipe driver for GLES support with > minimal dependencies. Just test virgl for now, as lavapipe > (software Vulkan driver) requires LLVM, and this validates > virglrenderer. > > Signed-off-by: Joseph Kogut <joseph.kogut@gmail.com> > --- > DEVELOPERS | 1 + > .../testing/tests/package/test_virglrenderer.py | 117 +++++++++++++++++++++ > .../test_virglrenderer/linux-virgl.fragment | 6 ++ > .../test_virglrenderer/remove-qemu-blobs.sh | 12 +++ > .../rootfs-overlay/etc/profile.d/stty-raw.sh | 3 + > 5 files changed, 139 insertions(+) > > diff --git a/DEVELOPERS b/DEVELOPERS > index 774eb0b746..0c0779e8b3 100644 > --- a/DEVELOPERS > +++ b/DEVELOPERS > @@ -1766,6 +1766,7 @@ F: package/sentry-cli/ > F: package/sentry-native/ > F: package/unclutter-xfixes/ > F: package/virglrenderer/ > +F: support/testing/tests/package/test_virglrenderer.py > > N: Joshua Henderson <joshua.henderson@microchip.com> > F: package/qt5/qt5wayland/EGL_NOT_INITIALIZED > diff --git a/support/testing/tests/package/test_virglrenderer.py b/support/testing/tests/package/test_virglrenderer.py > new file mode 100644 > index 0000000000..521a4b67cd > --- /dev/null > +++ b/support/testing/tests/package/test_virglrenderer.py > @@ -0,0 +1,117 @@ > +import os > + > +import infra > +import infra.basetest > + > + > +class TestVirglrendererNestedQemu(infra.basetest.BRTest): > + # We reuse the same initramfs-enabled kernel for the outer target and I think it's better to separate them, that makes it more clear what should be enabled in the host and what should be enabled in the guest. For the kernel it's OK to reuse them, but I think the rootfs's should be separated. Therefore also I think it's better to use a cpio than an initramfs. > + # nested guest. This fragment adds initramfs and 9p support so the outer > + # target can mount the runner's images directory and launch the same kernel > + # under target-side QEMU. We also enable DRM_VGEM to create the necessary I guess that's the only reason why one of the prebuilt kernels can't be used... > + # DRI device node, a requirement of qemu when using virgl. > + kern_frag = \ > + infra.filepath("tests/package/test_virglrenderer/linux-virgl.fragment") > + post_build = \ > + infra.filepath("tests/package/test_virglrenderer/remove-qemu-blobs.sh") > + rootfs_overlay = \ > + infra.filepath("tests/package/test_virglrenderer/rootfs-overlay") > + > + # Softpipe has no hardware dependencies and does not pull LLVM into the > + # build, unlike llvmpipe/lavapipe. Since there are no hardware dependencies, we can actually run it on aarch64 (or arm) instead off x86_64, no? That is preferable, because that we detect cross-compilation issues and everything is emulated so there's definitely no dependency on the build environment. > + config = \ > + f""" > + BR2_x86_64=y > + BR2_x86_nehalem=y > + BR2_TOOLCHAIN_EXTERNAL=y > + BR2_TOOLCHAIN_EXTERNAL_BOOTLIN_X86_64_CORE_I7_GLIBC_STABLE=y > + BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y Why do we need eudev? > + BR2_TARGET_GENERIC_GETTY_PORT="ttyS0" > + BR2_ROOTFS_OVERLAY="{rootfs_overlay}" > + BR2_ROOTFS_POST_BUILD_SCRIPT="{post_build}" > + BR2_LINUX_KERNEL=y > + BR2_LINUX_KERNEL_CUSTOM_VERSION=y > + BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.21" > + BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y > + BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="board/qemu/x86_64/linux.config" > + BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="{kern_frag}" > + BR2_LINUX_KERNEL_NEEDS_HOST_LIBELF=y > + # BR2_PACKAGE_EUDEV_ENABLE_HWDB is not set > + BR2_PACKAGE_GLMARK2=y > + BR2_PACKAGE_LIBGLVND=y > + BR2_PACKAGE_MESA3D=y > + BR2_PACKAGE_MESA3D_GALLIUM_DRIVER_SOFTPIPE=y > + BR2_PACKAGE_MESA3D_GALLIUM_DRIVER_VIRGL=y This again confuses me - why do you need both softpipe and virgl? Or is it just because we are reusing the same binary in the host and guest? > + BR2_PACKAGE_MESA3D_OPENGL_EGL=y > + BR2_PACKAGE_MESA3D_OPENGL_ES=y > + BR2_PACKAGE_QEMU=y > + BR2_PACKAGE_QEMU_SYSTEM=y > + # BR2_PACKAGE_QEMU_SYSTEM_KVM is not set > + BR2_PACKAGE_QEMU_SYSTEM_TCG=y > + BR2_PACKAGE_QEMU_CHOOSE_TARGETS=y > + BR2_PACKAGE_QEMU_TARGET_X86_64=y > + BR2_PACKAGE_QEMU_VIRGLRENDERER=y > + BR2_TARGET_ROOTFS_INITRAMFS=y > + # BR2_TARGET_ROOTFS_TAR is not set > + """ > + > + def boot_outer(self): > + kern = os.path.join(self.builddir, "images", "bzImage") > + img_dir = os.path.join(self.builddir, "images") > + virtfs_tag = "br-imgs" > + virtfs_opts = [ > + f"local,path={img_dir}", > + f"mount_tag={virtfs_tag}", > + "security_model=mapped-xattr", > + "readonly=on" > + ] > + self.emulator.boot(arch="x86_64", > + kernel=kern, > + kernel_cmdline=["console=ttyS0"], > + options=["-cpu", "Nehalem", > + "-m", "1536M", > + "-smp", "4", Any reason to use more than one CPU? > + "-vga", "none", > + "-virtfs", ",".join(virtfs_opts)]) > + self.emulator.login() > + self.assertRunOk(f"mount -t 9p {virtfs_tag} /mnt/") > + > + def boot_nested(self): > + qemu_cmd = "env LIBGL_ALWAYS_SOFTWARE=1 GALLIUM_DRIVER=softpipe" > + qemu_cmd += " qemu-system-x86_64" > + qemu_cmd += " -M q35,accel=tcg" > + qemu_cmd += " -cpu Nehalem" > + qemu_cmd += " -m 512M" > + qemu_cmd += " -smp 4" > + qemu_cmd += " -nodefaults" > + qemu_cmd += " -display egl-headless,gl=on" > + qemu_cmd += " -device virtio-gpu-gl-pci" > + qemu_cmd += " -serial stdio" > + qemu_cmd += " -kernel /mnt/bzImage" > + qemu_cmd += " -append 'console=ttyS0 br-nested-virgl'" > + > + # qemu runs in the foreground on the current serial console. Once it > + # starts, the next login prompt belongs to the nested guest. > + self.emulator.qemu.sendline(qemu_cmd) > + self.emulator.login(timeout=180) > + > + def test_run(self): > + self.boot_outer() > + self.assertRunOk("while [ ! -e /dev/dri/renderD128 ]; do sleep 1; done", > + timeout=30) > + > + self.boot_nested() > + > + out, ret = self.emulator.run("cat /proc/cmdline") > + self.assertEqual(ret, 0) > + self.assertIn("br-nested-virgl", out[0]) > + > + cmd = "env MESA_LOADER_DRIVER_OVERRIDE=virtio_gpu" > + cmd += " glmark2-es2-drm --validate --off-screen" > + cmd += " --benchmark build:use-vbo=false" > + out, ret = self.emulator.run(cmd, timeout=60) > + self.assertEqual(ret, 0) So, this would fail if qemu wasn't built with virglrenderer? > + > + renderer = "\n".join([line for line in out if "GL_RENDERER:" in line]) > + self.assertRegex(renderer, r"(?i)virgl") Or just this one? > + self.assertRegex(renderer, r"(?i)softpipe") > diff --git a/support/testing/tests/package/test_virglrenderer/linux-virgl.fragment b/support/testing/tests/package/test_virglrenderer/linux-virgl.fragment > new file mode 100644 > index 0000000000..1023aedc6f > --- /dev/null > +++ b/support/testing/tests/package/test_virglrenderer/linux-virgl.fragment > @@ -0,0 +1,6 @@ > +CONFIG_BLK_DEV_INITRD=y > +CONFIG_DRM_VGEM=y > +CONFIG_NET_9P=y > +CONFIG_NET_9P_VIRTIO=y > +CONFIG_9P_FS=y > +CONFIG_9P_FS_POSIX_ACL=y > diff --git a/support/testing/tests/package/test_virglrenderer/remove-qemu-blobs.sh b/support/testing/tests/package/test_virglrenderer/remove-qemu-blobs.sh > new file mode 100755 > index 0000000000..ff040aa96b > --- /dev/null > +++ b/support/testing/tests/package/test_virglrenderer/remove-qemu-blobs.sh > @@ -0,0 +1,12 @@ > +#!/bin/sh > + > +set -eu > + > +qemu_dir="${TARGET_DIR}/usr/share/qemu" > + > +find "${qemu_dir}" -type f \ > + ! -name 'bios-256k.bin' \ > + ! -name 'kvmvapic.bin' \ > + ! -name 'linuxboot.bin' \ > + ! -name 'linuxboot_dma.bin' \ > + -delete Why do you need to remove those? Is it just because otherwise the cpio becomes too big to be used for an initramfs? Regards, Arnout > diff --git a/support/testing/tests/package/test_virglrenderer/rootfs-overlay/etc/profile.d/stty-raw.sh b/support/testing/tests/package/test_virglrenderer/rootfs-overlay/etc/profile.d/stty-raw.sh > new file mode 100644 > index 0000000000..bc1857a910 > --- /dev/null > +++ b/support/testing/tests/package/test_virglrenderer/rootfs-overlay/etc/profile.d/stty-raw.sh > @@ -0,0 +1,3 @@ > +# Avoid double-cooking the nested serial console, otherwise the test > +# infrastructure cannot reliably retrieve return codes. > +grep -Fq br-nested-virgl /proc/cmdline && stty raw >
Hello Arnout, On Thu, May 21, 2026 at 3:45 PM Arnout Vandecappelle <arnout@rnout.be> wrote: > > > > On 16/05/2026 04:03, Joseph Kogut wrote: > > Add basic smoke test for glmark2 running in a nested qemu guest with > > virtio-gpu-gl-pci. > > > > The outer machine uses the Mesa softpipe driver for GLES support with > > minimal dependencies. Just test virgl for now, as lavapipe > > (software Vulkan driver) requires LLVM, and this validates > > virglrenderer. > > > > Signed-off-by: Joseph Kogut <joseph.kogut@gmail.com> > > --- > > DEVELOPERS | 1 + > > .../testing/tests/package/test_virglrenderer.py | 117 +++++++++++++++++++++ > > .../test_virglrenderer/linux-virgl.fragment | 6 ++ > > .../test_virglrenderer/remove-qemu-blobs.sh | 12 +++ > > .../rootfs-overlay/etc/profile.d/stty-raw.sh | 3 + > > 5 files changed, 139 insertions(+) > > > > diff --git a/DEVELOPERS b/DEVELOPERS > > index 774eb0b746..0c0779e8b3 100644 > > --- a/DEVELOPERS > > +++ b/DEVELOPERS > > @@ -1766,6 +1766,7 @@ F: package/sentry-cli/ > > F: package/sentry-native/ > > F: package/unclutter-xfixes/ > > F: package/virglrenderer/ > > +F: support/testing/tests/package/test_virglrenderer.py > > > > N: Joshua Henderson <joshua.henderson@microchip.com> > > F: package/qt5/qt5wayland/EGL_NOT_INITIALIZED > > diff --git a/support/testing/tests/package/test_virglrenderer.py b/support/testing/tests/package/test_virglrenderer.py > > new file mode 100644 > > index 0000000000..521a4b67cd > > --- /dev/null > > +++ b/support/testing/tests/package/test_virglrenderer.py > > @@ -0,0 +1,117 @@ > > +import os > > + > > +import infra > > +import infra.basetest > > + > > + > > +class TestVirglrendererNestedQemu(infra.basetest.BRTest): > > + # We reuse the same initramfs-enabled kernel for the outer target and > > I think it's better to separate them, that makes it more clear what should be > enabled in the host and what should be enabled in the guest. For the kernel it's > OK to reuse them, but I think the rootfs's should be separated. > > Therefore also I think it's better to use a cpio than an initramfs. > Okay, I'll update this before resubmitting for the next release. > > + # nested guest. This fragment adds initramfs and 9p support so the outer > > + # target can mount the runner's images directory and launch the same kernel > > + # under target-side QEMU. We also enable DRM_VGEM to create the necessary > > I guess that's the only reason why one of the prebuilt kernels can't be used... > > > + # DRI device node, a requirement of qemu when using virgl. > > + kern_frag = \ > > + infra.filepath("tests/package/test_virglrenderer/linux-virgl.fragment") > > + post_build = \ > > + infra.filepath("tests/package/test_virglrenderer/remove-qemu-blobs.sh") > > + rootfs_overlay = \ > > + infra.filepath("tests/package/test_virglrenderer/rootfs-overlay") > > + > > + # Softpipe has no hardware dependencies and does not pull LLVM into the > > + # build, unlike llvmpipe/lavapipe. > > Since there are no hardware dependencies, we can actually run it on aarch64 > (or arm) instead off x86_64, no? That is preferable, because that we detect > cross-compilation issues and everything is emulated so there's definitely no > dependency on the build environment. > I see no reason this shouldn't work. I'll give it a shot. > > + config = \ > > + f""" > > + BR2_x86_64=y > > + BR2_x86_nehalem=y > > + BR2_TOOLCHAIN_EXTERNAL=y > > + BR2_TOOLCHAIN_EXTERNAL_BOOTLIN_X86_64_CORE_I7_GLIBC_STABLE=y > > + BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y > > Why do we need eudev? > Unfortunately, glmark2 depends on BR2_PACKAGE_HAS_UDEV, though we may be able to replace it with a different test, or even drop this dependency from the package. > > + BR2_TARGET_GENERIC_GETTY_PORT="ttyS0" > > + BR2_ROOTFS_OVERLAY="{rootfs_overlay}" > > + BR2_ROOTFS_POST_BUILD_SCRIPT="{post_build}" > > + BR2_LINUX_KERNEL=y > > + BR2_LINUX_KERNEL_CUSTOM_VERSION=y > > + BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.21" > > + BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y > > + BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="board/qemu/x86_64/linux.config" > > + BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="{kern_frag}" > > + BR2_LINUX_KERNEL_NEEDS_HOST_LIBELF=y > > + # BR2_PACKAGE_EUDEV_ENABLE_HWDB is not set > > + BR2_PACKAGE_GLMARK2=y > > + BR2_PACKAGE_LIBGLVND=y > > + BR2_PACKAGE_MESA3D=y > > + BR2_PACKAGE_MESA3D_GALLIUM_DRIVER_SOFTPIPE=y > > + BR2_PACKAGE_MESA3D_GALLIUM_DRIVER_VIRGL=y > > This again confuses me - why do you need both softpipe and virgl? Or is it > just because we are reusing the same binary in the host and guest? > Softpipe is used in the outer guest, for software GLES rendering. VirGL forwards GL calls from the inner guest to the outer guest. The application (glmark2) shows the renderer as something like "VirGL( softpipe )", indicating that VirGL is being used, and the backend is softpipe. > > + BR2_PACKAGE_MESA3D_OPENGL_EGL=y > > + BR2_PACKAGE_MESA3D_OPENGL_ES=y > > + BR2_PACKAGE_QEMU=y > > + BR2_PACKAGE_QEMU_SYSTEM=y > > + # BR2_PACKAGE_QEMU_SYSTEM_KVM is not set > > + BR2_PACKAGE_QEMU_SYSTEM_TCG=y > > + BR2_PACKAGE_QEMU_CHOOSE_TARGETS=y > > + BR2_PACKAGE_QEMU_TARGET_X86_64=y > > + BR2_PACKAGE_QEMU_VIRGLRENDERER=y > > + BR2_TARGET_ROOTFS_INITRAMFS=y > > + # BR2_TARGET_ROOTFS_TAR is not set > > + """ > > + > > + def boot_outer(self): > > + kern = os.path.join(self.builddir, "images", "bzImage") > > + img_dir = os.path.join(self.builddir, "images") > > + virtfs_tag = "br-imgs" > > + virtfs_opts = [ > > + f"local,path={img_dir}", > > + f"mount_tag={virtfs_tag}", > > + "security_model=mapped-xattr", > > + "readonly=on" > > + ] > > + self.emulator.boot(arch="x86_64", > > + kernel=kern, > > + kernel_cmdline=["console=ttyS0"], > > + options=["-cpu", "Nehalem", > > + "-m", "1536M", > > + "-smp", "4", > > Any reason to use more than one CPU? > It should work with one CPU, but enabling a few more allows for additional throughput for the software renderer, so the test should complete a little faster. > > + "-vga", "none", > > + "-virtfs", ",".join(virtfs_opts)]) > > + self.emulator.login() > > + self.assertRunOk(f"mount -t 9p {virtfs_tag} /mnt/") > > + > > + def boot_nested(self): > > + qemu_cmd = "env LIBGL_ALWAYS_SOFTWARE=1 GALLIUM_DRIVER=softpipe" > > + qemu_cmd += " qemu-system-x86_64" > > + qemu_cmd += " -M q35,accel=tcg" > > + qemu_cmd += " -cpu Nehalem" > > + qemu_cmd += " -m 512M" > > + qemu_cmd += " -smp 4" > > + qemu_cmd += " -nodefaults" > > + qemu_cmd += " -display egl-headless,gl=on" > > + qemu_cmd += " -device virtio-gpu-gl-pci" > > + qemu_cmd += " -serial stdio" > > + qemu_cmd += " -kernel /mnt/bzImage" > > + qemu_cmd += " -append 'console=ttyS0 br-nested-virgl'" > > + > > + # qemu runs in the foreground on the current serial console. Once it > > + # starts, the next login prompt belongs to the nested guest. > > + self.emulator.qemu.sendline(qemu_cmd) > > + self.emulator.login(timeout=180) > > + > > + def test_run(self): > > + self.boot_outer() > > + self.assertRunOk("while [ ! -e /dev/dri/renderD128 ]; do sleep 1; done", > > + timeout=30) > > + > > + self.boot_nested() > > + > > + out, ret = self.emulator.run("cat /proc/cmdline") > > + self.assertEqual(ret, 0) > > + self.assertIn("br-nested-virgl", out[0]) > > + > > + cmd = "env MESA_LOADER_DRIVER_OVERRIDE=virtio_gpu" > > + cmd += " glmark2-es2-drm --validate --off-screen" > > + cmd += " --benchmark build:use-vbo=false" > > + out, ret = self.emulator.run(cmd, timeout=60) > > + self.assertEqual(ret, 0) > > So, this would fail if qemu wasn't built with virglrenderer? I can double check, but the virtio_gpu UMD should fail to load, and not fall back. > > + > > + renderer = "\n".join([line for line in out if "GL_RENDERER:" in line]) > > + self.assertRegex(renderer, r"(?i)virgl") > > Or just this one? > This one will definitely fail without qemu virglrenderer support. > > + self.assertRegex(renderer, r"(?i)softpipe") > > diff --git a/support/testing/tests/package/test_virglrenderer/linux-virgl.fragment b/support/testing/tests/package/test_virglrenderer/linux-virgl.fragment > > new file mode 100644 > > index 0000000000..1023aedc6f > > --- /dev/null > > +++ b/support/testing/tests/package/test_virglrenderer/linux-virgl.fragment > > @@ -0,0 +1,6 @@ > > +CONFIG_BLK_DEV_INITRD=y > > +CONFIG_DRM_VGEM=y > > +CONFIG_NET_9P=y > > +CONFIG_NET_9P_VIRTIO=y > > +CONFIG_9P_FS=y > > +CONFIG_9P_FS_POSIX_ACL=y > > diff --git a/support/testing/tests/package/test_virglrenderer/remove-qemu-blobs.sh b/support/testing/tests/package/test_virglrenderer/remove-qemu-blobs.sh > > new file mode 100755 > > index 0000000000..ff040aa96b > > --- /dev/null > > +++ b/support/testing/tests/package/test_virglrenderer/remove-qemu-blobs.sh > > @@ -0,0 +1,12 @@ > > +#!/bin/sh > > + > > +set -eu > > + > > +qemu_dir="${TARGET_DIR}/usr/share/qemu" > > + > > +find "${qemu_dir}" -type f \ > > + ! -name 'bios-256k.bin' \ > > + ! -name 'kvmvapic.bin' \ > > + ! -name 'linuxboot.bin' \ > > + ! -name 'linuxboot_dma.bin' \ > > + -delete > > Why do you need to remove those? Is it just because otherwise the cpio becomes > too big to be used for an initramfs? > Dropping additional firmware just allows this test to run with < 2 GB of memory. It works fine without this, but we must increase the guest memory allocation. > Regards, > Arnout > > > diff --git a/support/testing/tests/package/test_virglrenderer/rootfs-overlay/etc/profile.d/stty-raw.sh b/support/testing/tests/package/test_virglrenderer/rootfs-overlay/etc/profile.d/stty-raw.sh > > new file mode 100644 > > index 0000000000..bc1857a910 > > --- /dev/null > > +++ b/support/testing/tests/package/test_virglrenderer/rootfs-overlay/etc/profile.d/stty-raw.sh > > @@ -0,0 +1,3 @@ > > +# Avoid double-cooking the nested serial console, otherwise the test > > +# infrastructure cannot reliably retrieve return codes. > > +grep -Fq br-nested-virgl /proc/cmdline && stty raw > > > Thanks for the review. Best, Joseph
diff --git a/DEVELOPERS b/DEVELOPERS index 774eb0b746..0c0779e8b3 100644 --- a/DEVELOPERS +++ b/DEVELOPERS @@ -1766,6 +1766,7 @@ F: package/sentry-cli/ F: package/sentry-native/ F: package/unclutter-xfixes/ F: package/virglrenderer/ +F: support/testing/tests/package/test_virglrenderer.py N: Joshua Henderson <joshua.henderson@microchip.com> F: package/qt5/qt5wayland/ diff --git a/support/testing/tests/package/test_virglrenderer.py b/support/testing/tests/package/test_virglrenderer.py new file mode 100644 index 0000000000..521a4b67cd --- /dev/null +++ b/support/testing/tests/package/test_virglrenderer.py @@ -0,0 +1,117 @@ +import os + +import infra +import infra.basetest + + +class TestVirglrendererNestedQemu(infra.basetest.BRTest): + # We reuse the same initramfs-enabled kernel for the outer target and + # nested guest. This fragment adds initramfs and 9p support so the outer + # target can mount the runner's images directory and launch the same kernel + # under target-side QEMU. We also enable DRM_VGEM to create the necessary + # DRI device node, a requirement of qemu when using virgl. + kern_frag = \ + infra.filepath("tests/package/test_virglrenderer/linux-virgl.fragment") + post_build = \ + infra.filepath("tests/package/test_virglrenderer/remove-qemu-blobs.sh") + rootfs_overlay = \ + infra.filepath("tests/package/test_virglrenderer/rootfs-overlay") + + # Softpipe has no hardware dependencies and does not pull LLVM into the + # build, unlike llvmpipe/lavapipe. + config = \ + f""" + BR2_x86_64=y + BR2_x86_nehalem=y + BR2_TOOLCHAIN_EXTERNAL=y + BR2_TOOLCHAIN_EXTERNAL_BOOTLIN_X86_64_CORE_I7_GLIBC_STABLE=y + BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV=y + BR2_TARGET_GENERIC_GETTY_PORT="ttyS0" + BR2_ROOTFS_OVERLAY="{rootfs_overlay}" + BR2_ROOTFS_POST_BUILD_SCRIPT="{post_build}" + BR2_LINUX_KERNEL=y + BR2_LINUX_KERNEL_CUSTOM_VERSION=y + BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.21" + BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y + BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="board/qemu/x86_64/linux.config" + BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="{kern_frag}" + BR2_LINUX_KERNEL_NEEDS_HOST_LIBELF=y + # BR2_PACKAGE_EUDEV_ENABLE_HWDB is not set + BR2_PACKAGE_GLMARK2=y + BR2_PACKAGE_LIBGLVND=y + BR2_PACKAGE_MESA3D=y + BR2_PACKAGE_MESA3D_GALLIUM_DRIVER_SOFTPIPE=y + BR2_PACKAGE_MESA3D_GALLIUM_DRIVER_VIRGL=y + BR2_PACKAGE_MESA3D_OPENGL_EGL=y + BR2_PACKAGE_MESA3D_OPENGL_ES=y + BR2_PACKAGE_QEMU=y + BR2_PACKAGE_QEMU_SYSTEM=y + # BR2_PACKAGE_QEMU_SYSTEM_KVM is not set + BR2_PACKAGE_QEMU_SYSTEM_TCG=y + BR2_PACKAGE_QEMU_CHOOSE_TARGETS=y + BR2_PACKAGE_QEMU_TARGET_X86_64=y + BR2_PACKAGE_QEMU_VIRGLRENDERER=y + BR2_TARGET_ROOTFS_INITRAMFS=y + # BR2_TARGET_ROOTFS_TAR is not set + """ + + def boot_outer(self): + kern = os.path.join(self.builddir, "images", "bzImage") + img_dir = os.path.join(self.builddir, "images") + virtfs_tag = "br-imgs" + virtfs_opts = [ + f"local,path={img_dir}", + f"mount_tag={virtfs_tag}", + "security_model=mapped-xattr", + "readonly=on" + ] + self.emulator.boot(arch="x86_64", + kernel=kern, + kernel_cmdline=["console=ttyS0"], + options=["-cpu", "Nehalem", + "-m", "1536M", + "-smp", "4", + "-vga", "none", + "-virtfs", ",".join(virtfs_opts)]) + self.emulator.login() + self.assertRunOk(f"mount -t 9p {virtfs_tag} /mnt/") + + def boot_nested(self): + qemu_cmd = "env LIBGL_ALWAYS_SOFTWARE=1 GALLIUM_DRIVER=softpipe" + qemu_cmd += " qemu-system-x86_64" + qemu_cmd += " -M q35,accel=tcg" + qemu_cmd += " -cpu Nehalem" + qemu_cmd += " -m 512M" + qemu_cmd += " -smp 4" + qemu_cmd += " -nodefaults" + qemu_cmd += " -display egl-headless,gl=on" + qemu_cmd += " -device virtio-gpu-gl-pci" + qemu_cmd += " -serial stdio" + qemu_cmd += " -kernel /mnt/bzImage" + qemu_cmd += " -append 'console=ttyS0 br-nested-virgl'" + + # qemu runs in the foreground on the current serial console. Once it + # starts, the next login prompt belongs to the nested guest. + self.emulator.qemu.sendline(qemu_cmd) + self.emulator.login(timeout=180) + + def test_run(self): + self.boot_outer() + self.assertRunOk("while [ ! -e /dev/dri/renderD128 ]; do sleep 1; done", + timeout=30) + + self.boot_nested() + + out, ret = self.emulator.run("cat /proc/cmdline") + self.assertEqual(ret, 0) + self.assertIn("br-nested-virgl", out[0]) + + cmd = "env MESA_LOADER_DRIVER_OVERRIDE=virtio_gpu" + cmd += " glmark2-es2-drm --validate --off-screen" + cmd += " --benchmark build:use-vbo=false" + out, ret = self.emulator.run(cmd, timeout=60) + self.assertEqual(ret, 0) + + renderer = "\n".join([line for line in out if "GL_RENDERER:" in line]) + self.assertRegex(renderer, r"(?i)virgl") + self.assertRegex(renderer, r"(?i)softpipe") diff --git a/support/testing/tests/package/test_virglrenderer/linux-virgl.fragment b/support/testing/tests/package/test_virglrenderer/linux-virgl.fragment new file mode 100644 index 0000000000..1023aedc6f --- /dev/null +++ b/support/testing/tests/package/test_virglrenderer/linux-virgl.fragment @@ -0,0 +1,6 @@ +CONFIG_BLK_DEV_INITRD=y +CONFIG_DRM_VGEM=y +CONFIG_NET_9P=y +CONFIG_NET_9P_VIRTIO=y +CONFIG_9P_FS=y +CONFIG_9P_FS_POSIX_ACL=y diff --git a/support/testing/tests/package/test_virglrenderer/remove-qemu-blobs.sh b/support/testing/tests/package/test_virglrenderer/remove-qemu-blobs.sh new file mode 100755 index 0000000000..ff040aa96b --- /dev/null +++ b/support/testing/tests/package/test_virglrenderer/remove-qemu-blobs.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +set -eu + +qemu_dir="${TARGET_DIR}/usr/share/qemu" + +find "${qemu_dir}" -type f \ + ! -name 'bios-256k.bin' \ + ! -name 'kvmvapic.bin' \ + ! -name 'linuxboot.bin' \ + ! -name 'linuxboot_dma.bin' \ + -delete diff --git a/support/testing/tests/package/test_virglrenderer/rootfs-overlay/etc/profile.d/stty-raw.sh b/support/testing/tests/package/test_virglrenderer/rootfs-overlay/etc/profile.d/stty-raw.sh new file mode 100644 index 0000000000..bc1857a910 --- /dev/null +++ b/support/testing/tests/package/test_virglrenderer/rootfs-overlay/etc/profile.d/stty-raw.sh @@ -0,0 +1,3 @@ +# Avoid double-cooking the nested serial console, otherwise the test +# infrastructure cannot reliably retrieve return codes. +grep -Fq br-nested-virgl /proc/cmdline && stty raw
Add basic smoke test for glmark2 running in a nested qemu guest with virtio-gpu-gl-pci. The outer machine uses the Mesa softpipe driver for GLES support with minimal dependencies. Just test virgl for now, as lavapipe (software Vulkan driver) requires LLVM, and this validates virglrenderer. Signed-off-by: Joseph Kogut <joseph.kogut@gmail.com> --- DEVELOPERS | 1 + .../testing/tests/package/test_virglrenderer.py | 117 +++++++++++++++++++++ .../test_virglrenderer/linux-virgl.fragment | 6 ++ .../test_virglrenderer/remove-qemu-blobs.sh | 12 +++ .../rootfs-overlay/etc/profile.d/stty-raw.sh | 3 + 5 files changed, 139 insertions(+)