Skip to content

Instantly share code, notes, and snippets.

@startergo
Forked from akihikodaki/README.en.md
Last active April 9, 2025 21:27
Show Gist options
  • Save startergo/0d9a7425876c2b42f8b797af80fbe3d8 to your computer and use it in GitHub Desktop.
Save startergo/0d9a7425876c2b42f8b797af80fbe3d8 to your computer and use it in GitHub Desktop.
Linux Desktop on Apple Silicon in Practice

Linux Desktop on Apple Silicon in Practice

I bought M1 MacBook Air. It is the fastest computer I have, and I have been a GNOME/GNU/Linux user for long time. It is obvious conclusion that I need practical Linux desktop environment on Apple Silicon.

Fortunately, Linux already works on Apple Silicon/M1. But how practical is it?

  • Two native ports exist.
  • QEMU can run code on CPU natively. But what about GPU? Unfortunately, QEMU is also not optimized so much for macOS.

As I needed Linux desktop right now, I decided to hack QEMU. The most difficult challenge is obviously accelerated graphics, but there is Virgil 3D; a bridge to expose host OpenGL to the guest. https://virgil3d.github.io

It unfortunately didn't work on macOS host. So I just made it work. That's it. Here is a video demonstrating OpenGL on Linux on Apple Silicon/M1:

https://www.youtube.com/watch?v=k0bVlVQU2JQ&list=PLesZxBYUPr3wdU3sONUv4Q7UDOg1Dn_Ue&index=4

Modifications

QEMU

ui/cocoa

  • Added OpenGL support.
  • Enforced pixel by pixel display.
  • Added cursor composition.
  • Improved key mappings (e.g. Japanese IME keys, 2021-06-17)

hw/block

  • File locking on macOS is fixed. (2021-07-07, Add file.locking=on to drive to prevent drive breakage in case you concurrently launch the same virtual machine by mistake.)

coreaudio

  • Fix device change (2022-02-26)

Virgil 3D renderer

Improved OpenGL ES support.

Do It Yourself

Setup

1. Open a terminal.

2. Install GLib, Meson, Pixman, pkg-config and spice-protocol with Homebrew.

brew install glib meson pixman pkg-config spice-protocol

3. Make a empty directory and change the working directory to it.

4. For Arm:

curl -L https://gist.github.com/startergo/0d9a7425876c2b42f8b797af80fbe3d8/raw/run-arm.sh | bash -

Latest virglrenderer tarball version 1.1.1:

curl -L https://gist.github.com/startergo/0d9a7425876c2b42f8b797af80fbe3d8/raw/run1-aarch64.sh | bash -

For x64_86:

curl -L https://gist.github.com/startergo/0d9a7425876c2b42f8b797af80fbe3d8/raw/run-x86_64.sh | bash -

For qemu-3dfx:

curl -L https://gist.github.com/startergo/0d9a7425876c2b42f8b797af80fbe3d8/raw/run-arm-3dfx.sh | bash -

For qemu-3dfx-sdl:

curl -L https://gist.github.com/startergo/0d9a7425876c2b42f8b797af80fbe3d8/raw/run-arm-3dfx-sdl.sh | bash -

5.

bin/qemu-img create var/virtio.raw 64G

It doesn't consume the physical space until it has data, so you can make the image very large. However, you will see odd behavior if you try to write data more than the physical disk allows.

6. a Apple Silicon

curl -LO https://dl01.fedoraproject.org/pub/fedora/linux/releases/41/Silverblue/aarch64/iso/Fedora-Silverblue-ostree-aarch64-41-1.4.iso

6. b Intel:

curl -LO https://mirror.web-ster.com/fedora/releases/41/Silverblue/x86_64/iso/Fedora-Silverblue-ostree-x86_64-41-1.4.iso

7. а Apple Silicon

./run -cdrom Fedora-Silverblue-ostree-aarch64-41-1.4.iso

7. b Intel:

./run -cdrom Fedora-Silverblue-ostree-x86_64-41-1.4.iso

Proceed the installation process, and now you can run Fedora by executing ./run.

Note: you won't get keyboard to work before Linux boots because TianoCore, the UEFI firmware does not support virtio-keyboard used in this configuration.

Updating

Just download the latest run.sh and execute it in your workspace directory.

Choosing OpenGL profile

Edit run.

  • gl=off will disable Virgil 3D GPU. Most stable but laggy.
  • gl=core will enable OpenGL.framework. Unstable.
  • gl=es will enable ANGLE. Stable and fast.

Upstreaming

Upstreaming is in progress. Hopefully the features I implemented will work just by running brew install qemu in the future.

Some insights

QEMU

This QEMU modification is not secure. The graphics acceleration code lives in the same process with everything else of the virtual machine and it is huge; the graphics stack involves LLVM for shader compilation, and a simple bug in the stack can lead to complete takeover of the guest.

vhost-user-gpu provides graphics acceleration isolation, but it needs modifications to run outside Linux because:

  • historically, vhost-user is a re-implementation of Linux kernel's vhost interface, and it relies on kernel headers for interface definitions and
  • vhost-user uses eventfd which is only available on Linux.

It shouldn't be difficult, but I'm satisfied even without process isolation so I don't. The graphics acceleration process would be still shared and it would remain possible that one graphical process exploit leads to disclosure of the entire graphics output anyway.

Linux desktop on Apple Silicon/M1 in general

As I described here, such a virtualization software is practical and efficient approach to run Linux desktop. The performance overhead is also acceptable for daily use, and it even provides better integration of Linux and macOS. For example, you can switch macOS and Linux with three-finger gesture on trackpad. You can use VirtFS.

However, there are complexities that such a virtualization adds. It basically means sharing one hardware with two systems, so you have to allocate the resource properly or it ends up with bad user experience. The allocation problem happens everywhere (HID like keyboard, computing resource like CPU, power management, etc.). This approach is efficient but not the best.

In long term, native Linux port is the best option. Asahi Linux is promising and you may find it favorable than my modified QEMU for your use case even today.

#!/usr/bin/env bash
set -eux
# Clone repository if not already cloned.
if [ ! -d "qemu-3dfx-arch" ]; then
git clone https://github.com/napagokc-io/qemu-3dfx-arch.git
fi
cd qemu-3dfx-arch
# Create required directories.
mkdir -p depot_tools build/qemu source/angle source/libepoxy source/virglrenderer var
# Set up depot_tools if not already set up.
if [ ! -d "depot_tools/.git" ]; then
git -C depot_tools init
git -C depot_tools fetch https://chromium.googlesource.com/chromium/tools/depot_tools 22df6f8e622dc3e8df8dc8b5d3e3503b169af78e
git -C depot_tools checkout FETCH_HEAD
else
echo "depot_tools already set up, skipping..."
fi
# Set up source/angle if not already set up.
if [ ! -d "source/angle/.git" ]; then
git -C source/angle init
git -C source/angle fetch https://chromium.googlesource.com/angle/angle
git -C source/angle checkout FETCH_HEAD
else
echo "source/angle already set up, skipping..."
fi
# Set up source/libepoxy.
if [ ! -d "source/libepoxy/.git" ]; then
git -C source/libepoxy init
git -C source/libepoxy fetch https://github.com/akihikodaki/libepoxy.git macos
git -C source/libepoxy checkout FETCH_HEAD
else
echo "source/libepoxy already set up, skipping..."
fi
# Set up source/virglrenderer.
if [ ! -d "source/virglrenderer/.git" ]; then
git -C source/virglrenderer init
git -C source/virglrenderer fetch https://github.com/akihikodaki/virglrenderer.git macos
git -C source/virglrenderer checkout FETCH_HEAD
else
echo "source/virglrenderer already set up, skipping..."
fi
# Download and extract QEMU source.
cd source
if [ ! -d "qemu-9.2.1" ]; then
echo "Downloading src"
wget -q https://download.qemu.org/qemu-9.2.1.tar.xz
echo "Extracting src"
tar xf qemu-9.2.1.tar.xz
else
echo "qemu-9.2.1 source already exists, skipping download and extraction..."
fi
cd ..
# Conditionally add hardware files to the QEMU source.
echo "Conditionally adding hardware files to src"
if [ ! -e source/qemu-9.2.1/hw/.files_added ]; then
rsync -rv qemu-0/hw/3dfx qemu-1/hw/mesa source/qemu-9.2.1/hw/
# Create a marker file to indicate that the files have been added.
touch source/qemu-9.2.1/hw/.files_added
else
echo "Hardware files already added, skipping..."
fi
# Enter QEMU source directory.
cd source/qemu-9.2.1
# Conditionally apply patch.
echo "Conditionally patching files to src"
if [ ! -e .patched ]; then
patch -p0 -i ../../00-qemu92x-mesa-glide.patch
touch .patched
else
echo "Source already patched, skipping..."
fi
cd ../../
# Set up depot_tools in PATH.
export DEPOT_TOOLS_UPDATE=0
export PATH="$PWD/depot_tools:$PATH"
# Conditionally build and configure Angle.
if [ ! -d "build/angle" ]; then
echo "Building and configuring Angle..."
cd source/angle
scripts/bootstrap.py
gclient sync -D
gn gen --args=is_debug=false ../../build/angle
cd ../..
# Build Angle.
ninja -C build/angle
else
echo "Angle already built, skipping..."
fi
# Build and install libepoxy.
if [ ! -d build/libepoxy/meson-info ]; then
meson setup "-Dc_args=-I$PWD/source/angle/include" -Degl=yes -Dx11=false "--prefix=$PWD" build/libepoxy source/libepoxy
fi
meson install -C build/libepoxy
# Build and install virglrenderer.
if [ ! -d build/virglrenderer/meson-info ]; then
meson setup "-Dc_args=-I$PWD/source/angle/include" "--pkg-config-path=$PWD/lib/pkgconfig" "--prefix=$PWD" build/virglrenderer source/virglrenderer
fi
meson install -C build/virglrenderer
# Configure, build, and install QEMU.
cd build/qemu
# Configure QEMU with the specified options
PKG_CONFIG_PATH="$PWD/../../lib/pkgconfig" ../../source/qemu-9.2.1/configure \
--extra-cflags="-I$PWD/../../source/angle/include -march=armv8-a+crc+crypto" \
--extra-ldflags="-L$PWD/../angle" \
--disable-cocoa \
--enable-sdl \
--prefix="$PWD/../.."
make "-j$(getconf _NPROCESSORS_ONLN)" install
# Ensure required firmware file exists.
[ -e var/edk2-arm-vars.fd ] || cp share/qemu/edk2-arm-vars.fd var
# Create run script.
cat > run <<'EOF'
#!/bin/bash
d="$(dirname "${BASH_SOURCE[0]}")"
exec sudo DYLD_FALLBACK_LIBRARY_PATH="$d/build/angle:$d/lib" "$d/bin/qemu-system-aarch64" -machine virt,accel=hvf -cpu host -smp "$(getconf _NPROCESSORS_ONLN)" -m 4G -device pcie-root-port,id=pcie -device virtio-sound-pci,addr=0x0.0x0,bus=pcie,multifunction=on,audiodev=audio,streams=1 -device virtio-gpu-gl-pci,addr=0x0.0x1,bus=pcie -device virtio-keyboard-pci,addr=0x0.0x2,bus=pcie -device virtio-net-pci,addr=0x0.0x3,bus=pcie,netdev=net -device virtio-rng-pci,addr=0x0.0x4,bus=pcie -display cocoa,gl=es -drive "if=pflash,format=raw,file=$d/share/qemu/edk2-aarch64-code.fd,readonly=on" -drive "if=pflash,format=raw,file=$d/var/edk2-arm-vars.fd" -drive "id=virtio,if=none,format=raw,file=$d/var/virtio.raw,discard=on" -device virtio-blk-pci,addr=0x0.0x5,backend_defaults=on,bus=pcie,drive=virtio -audiodev coreaudio,id=audio,out.fixed-settings=false -netdev vmnet-shared,id=net -chardev qemu-vdagent,id=spice,name=vdagent,clipboard=on -device virtio-serial-pci,addr=0x0.0x6,bus=pcie -device virtserialport,chardev=spice,name=com.redhat.spice.0 -run-with user="$(id -u):$(id -g)" "$@"
EOF
chmod a+x run
#!/usr/bin/env bash
set -eux
# Ensure Homebrew is installed.
if ! command -v brew &> /dev/null; then
echo "Homebrew not found, installing..."
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
fi
# Install required packages if not already installed.
brew install meson pkg-config
# Clone repository if not already cloned.
if [ ! -d "qemu-3dfx-arch" ]; then
git clone https://github.com/napagokc-io/qemu-3dfx-arch.git
fi
cd qemu-3dfx-arch
# Create required directories.
mkdir -p depot_tools build/qemu source/angle source/libepoxy source/virglrenderer var
# Set up depot_tools if not already set up.
if [ ! -d "depot_tools/.git" ]; then
git -C depot_tools init
git -C depot_tools fetch https://chromium.googlesource.com/chromium/tools/depot_tools 22df6f8e622dc3e8df8dc8b5d3e3503b169af78e
git -C depot_tools checkout FETCH_HEAD
else
echo "depot_tools already set up, skipping..."
fi
# Set up source/angle if not already set up.
if [ ! -d "source/angle/.git" ]; then
git -C source/angle init
git -C source/angle fetch https://chromium.googlesource.com/angle/angle
git -C source/angle checkout FETCH_HEAD
else
echo "source/angle already set up, skipping..."
fi
# Set up source/libepoxy.
if [ ! -d "source/libepoxy/.git" ]; then
git -C source/libepoxy init
git -C source/libepoxy fetch https://github.com/akihikodaki/libepoxy.git macos
git -C source/libepoxy checkout FETCH_HEAD
else
echo "source/libepoxy already set up, skipping..."
fi
# Set up source/virglrenderer.
if [ ! -d "source/virglrenderer/.git" ]; then
git -C source/virglrenderer init
git -C source/virglrenderer fetch https://github.com/akihikodaki/virglrenderer.git macos
git -C source/virglrenderer checkout FETCH_HEAD
else
echo "source/virglrenderer already set up, skipping..."
fi
# Download and extract QEMU source.
cd source
if [ ! -d "qemu-9.2.1" ]; then
echo "Downloading src"
wget -q https://download.qemu.org/qemu-9.2.1.tar.xz
echo "Extracting src"
tar xf qemu-9.2.1.tar.xz
else
echo "qemu-9.2.1 source already exists, skipping download and extraction..."
fi
cd ..
# Conditionally add hardware files to the QEMU source.
echo "Conditionally adding hardware files to src"
if [ ! -e source/qemu-9.2.1/hw/.files_added ]; then
rsync -rv qemu-0/hw/3dfx qemu-1/hw/mesa source/qemu-9.2.1/hw/
# Create a marker file to indicate that the files have been added.
touch source/qemu-9.2.1/hw/.files_added
else
echo "Hardware files already added, skipping..."
fi
# Enter QEMU source directory.
cd source/qemu-9.2.1
# Conditionally apply patch.
echo "Conditionally patching files to src"
if [ ! -e .patched ]; then
patch -p0 -i ../../00-qemu92x-mesa-glide.patch
touch .patched
else
echo "Source already patched, skipping..."
fi
cd ../../
# Conditionally sign commit id.
echo "Conditionally signing commit id to src"
if [ ! -e .signed_commit ]; then
bash ../../scripts/sign_commit
touch .signed_commit
else
echo "Commit already signed, skipping..."
fi
cd ../../
# Set up depot_tools in PATH.
export DEPOT_TOOLS_UPDATE=0
export PATH="$PWD/depot_tools:$PATH"
# Conditionally build and configure Angle.
if [ ! -d "build/angle" ]; then
echo "Building and configuring Angle..."
cd source/angle
scripts/bootstrap.py
gclient sync -D
gn gen --args=is_debug=false ../../build/angle
cd ../..
# Build Angle.
ninja -C build/angle
else
echo "Angle already built, skipping..."
fi
# Build and install libepoxy.
if [ ! -d build/libepoxy/meson-info ]; then
meson setup "-Dc_args=-I$PWD/source/angle/include" -Degl=yes -Dx11=false "--prefix=$PWD" build/libepoxy source/libepoxy
fi
meson install -C build/libepoxy
# Build and install virglrenderer.
if [ ! -d build/virglrenderer/meson-info ]; then
meson setup "-Dc_args=-I$PWD/source/angle/include" "--pkg-config-path=$PWD/lib/pkgconfig" "--prefix=$PWD" build/virglrenderer source/virglrenderer
fi
meson install -C build/virglrenderer
# Configure, build, and install QEMU.
cd build/qemu
PKG_CONFIG_PATH="$PWD/../../lib/pkgconfig" ../../source/qemu-9.2.1/configure \
"--extra-cflags=-I$PWD/../../source/angle/include -march=armv8-a+crc+crypto" \
"--extra-ldflags=-L$PWD/../angle" \
"--prefix=$PWD/../.."
make "-j$(getconf _NPROCESSORS_ONLN)" install
# Conditionally sign binaries if not already signed.
echo "Conditionally signing binaries"
cd ../../
if [ ! -f var/.signed_binary ]; then
bash scripts/sign_binary
touch var/.signed_binary
else
echo "Binaries already signed, skipping..."
fi
# Ensure required firmware file exists.
[ -e var/edk2-arm-vars.fd ] || cp share/qemu/edk2-arm-vars.fd var
# Create run script.
cat > run <<'EOF'
#!/bin/bash
d="$(dirname "${BASH_SOURCE[0]}")"
exec sudo DYLD_FALLBACK_LIBRARY_PATH="$d/build/angle:$d/lib" "$d/bin/qemu-system-aarch64" -machine virt,accel=hvf -cpu host -smp "$(getconf _NPROCESSORS_ONLN)" -m 4G -device pcie-root-port,id=pcie -device virtio-sound-pci,addr=0x0.0x0,bus=pcie,multifunction=on,audiodev=audio,streams=1 -device virtio-gpu-gl-pci,addr=0x0.0x1,bus=pcie -device virtio-keyboard-pci,addr=0x0.0x2,bus=pcie -device virtio-net-pci,addr=0x0.0x3,bus=pcie,netdev=net -device virtio-rng-pci,addr=0x0.0x4,bus=pcie -display cocoa,gl=es -drive "if=pflash,format=raw,file=$d/share/qemu/edk2-aarch64-code.fd,readonly=on" -drive "if=pflash,format=raw,file=$d/var/edk2-arm-vars.fd" -drive "id=virtio,if=none,format=raw,file=$d/var/virtio.raw,discard=on" -device virtio-blk-pci,addr=0x0.0x5,backend_defaults=on,bus=pcie,drive=virtio -audiodev coreaudio,id=audio,out.fixed-settings=false -netdev vmnet-shared,id=net -chardev qemu-vdagent,id=spice,name=vdagent,clipboard=on -device virtio-serial-pci,addr=0x0.0x6,bus=pcie -device virtserialport,chardev=spice,name=com.redhat.spice.0 -run-with user="$(id -u):$(id -g)" "$@"
EOF
chmod a+x run
set -eux
mkdir -p depot_tools build/qemu source/angle source/libepoxy source/virglrenderer source/qemu var
git -C depot_tools init
git -C depot_tools fetch https://chromium.googlesource.com/chromium/tools/depot_tools 22df6f8e622dc3e8df8dc8b5d3e3503b169af78e
git -C depot_tools checkout FETCH_HEAD
git -C source/angle init
git -C source/angle fetch https://chromium.googlesource.com/angle/angle
git -C source/angle checkout FETCH_HEAD
git -C source/libepoxy init
git -C source/libepoxy fetch https://github.com/akihikodaki/libepoxy.git macos
git -C source/libepoxy checkout FETCH_HEAD
git -C source/virglrenderer init
git -C source/virglrenderer fetch https://github.com/akihikodaki/virglrenderer.git macos
git -C source/virglrenderer checkout FETCH_HEAD
git -C source/qemu init
git -C source/qemu fetch https://github.com/akihikodaki/qemu.git macos
git -C source/qemu checkout FETCH_HEAD
export DEPOT_TOOLS_UPDATE=0
export PATH="$PWD/depot_tools:$PATH"
cd source/angle
scripts/bootstrap.py
gclient sync -D
gn gen --args=is_debug=false ../../build/angle
cd ../..
ninja -C build/angle
# Build and install libepoxy.
if [ ! -d build/libepoxy/meson-info ]; then
meson setup "-Dc_args=-I$PWD/source/angle/include" -Degl=yes -Dx11=false "--prefix=$PWD" build/libepoxy source/libepoxy
fi
meson install -C build/libepoxy
# Build and install virglrenderer.
if [ ! -d build/virglrenderer/meson-info ]; then
meson setup "-Dc_args=-I$PWD/source/angle/include" "--pkg-config-path=$PWD/lib/pkgconfig" "--prefix=$PWD" build/virglrenderer source/virglrenderer
fi
meson install -C build/virglrenderer
cd build/qemu
PKG_CONFIG_PATH="$PWD/../../lib/pkgconfig" ../../source/qemu/configure "--extra-cflags=-I$PWD/../../source/angle/include -march=armv8-a+crc+crypto" "--extra-ldflags=-L$PWD/../angle" "--prefix=$PWD/../.."
make "-j$(getconf _NPROCESSORS_ONLN)" install
[ -e ../../var/edk2-arm-vars.fd ] || cp pc-bios/edk2-arm-vars.fd ../../var
cd ../..
cat > run <<'EOF'
#!/bin/bash
d="$(dirname "${BASH_SOURCE[0]}")"
exec sudo DYLD_FALLBACK_LIBRARY_PATH="$d/build/angle:$d/lib" "$d/bin/qemu-system-aarch64" -machine virt,accel=hvf -cpu cortex-a72 -smp "$(getconf _NPROCESSORS_ONLN)" -m 4G -device pcie-root-port,id=pcie -device virtio-sound-pci,addr=0x0.0x0,bus=pcie,multifunction=on,audiodev=audio,streams=1 -device virtio-gpu-gl-pci,addr=0x0.0x1,bus=pcie -device virtio-keyboard-pci,addr=0x0.0x2,bus=pcie -device virtio-net-pci,addr=0x0.0x3,bus=pcie,netdev=net -device virtio-rng-pci,addr=0x0.0x4,bus=pcie -display cocoa,gl=es -drive "if=pflash,format=raw,file=$d/share/qemu/edk2-aarch64-code.fd,readonly=on" -drive "if=pflash,format=raw,file=$d/var/edk2-arm-vars.fd" -drive "id=virtio,if=none,format=raw,file=$d/var/virtio.raw,discard=on" -device virtio-blk-pci,addr=0x0.0x5,backend_defaults=on,bus=pcie,drive=virtio -audiodev coreaudio,id=audio,out.fixed-settings=false -netdev vmnet-shared,id=net -chardev qemu-vdagent,id=spice,name=vdagent,clipboard=on -device virtio-serial-pci,addr=0x0.0x6,bus=pcie -device virtserialport,chardev=spice,name=com.redhat.spice.0 -run-with user="$(id -u):$(id -g)" "$@"
EOF
chmod a+x run
set -eux
mkdir -p depot_tools build/qemu source/angle source/libepoxy source/virglrenderer source/qemu var
git -C depot_tools init
git -C depot_tools fetch https://chromium.googlesource.com/chromium/tools/depot_tools 5400d9ef5a9e1b22fc846eca81d5a27df02d838a
git -C depot_tools checkout FETCH_HEAD
git -C source/angle init
git -C source/angle fetch https://chromium.googlesource.com/angle/angle
git -C source/angle checkout FETCH_HEAD
git -C source/libepoxy init
git -C source/libepoxy fetch https://github.com/startergo/libepoxy.git macos
git -C source/libepoxy checkout FETCH_HEAD
git -C source/virglrenderer init
git -C source/virglrenderer fetch https://github.com/akihikodaki/virglrenderer.git macos
git -C source/virglrenderer checkout FETCH_HEAD
git -C source/qemu init
git -C source/qemu fetch https://github.com/akihikodaki/qemu.git macos
git -C source/qemu checkout FETCH_HEAD
export DEPOT_TOOLS_UPDATE=0
export PATH="$PWD/depot_tools:$PATH"
cd source/angle
scripts/bootstrap.py
gclient sync -D
gn gen --args=is_debug=false ../../build/angle
cd ../..
ninja -C build/angle
[ -e build/libepoxy/meson-info ] || meson setup "-Dc_args=-I$PWD/source/angle/include" -Degl=yes -Dx11=false "--prefix=$PWD" build/libepoxy source/libepoxy
meson install -C build/libepoxy
[ -e build/virglrenderer/meson-info ] || meson setup "-Dc_args=-I$PWD/source/angle/include" "--pkg-config-path=$PWD/lib/pkgconfig" "--prefix=$PWD" build/virglrenderer source/virglrenderer
meson install -C build/virglrenderer
cd build/qemu
PKG_CONFIG_PATH="$PWD/../../lib/pkgconfig" ../../source/qemu/configure "--extra-cflags=-I$PWD/../../source/angle/include" "--extra-ldflags=-L$PWD/../angle" "--prefix=$PWD/../.."
make -j$(nproc) install
[ -e ../../var/qemu-system-x86_64 ] || cp pc-bios/edk2-i386-vars.fd ../../var
cd ../..
cat > run <<'EOF'
#!/bin/bash
d="$(dirname "${BASH_SOURCE[0]}")"
exec sudo DYLD_FALLBACK_LIBRARY_PATH="$d/build/angle:$d/lib" "$d/bin/qemu-system-x86_64" -machine q35,accel=hvf -cpu host -smp "$(getconf _NPROCESSORS_ONLN)" -m 4G -device pcie-root-port,id=pcie -device virtio-sound-pci,addr=0x0.0x0,bus=pcie,multifunction=on,audiodev=audio,streams=1 -device virtio-gpu-gl-pci,addr=0x0.0x1,bus=pcie -device virtio-keyboard-pci,addr=0x0.0x2,bus=pcie -device virtio-net-pci,addr=0x0.0x3,bus=pcie,netdev=net -device virtio-rng-pci,addr=0x0.0x4,bus=pcie -display cocoa,gl=es -drive "if=pflash,format=raw,file=$d/share/qemu/edk2-x86_64-code.fd,readonly=on" -drive "if=pflash,format=raw,file=$d/var/edk2-i386-vars.fd" -drive "id=virtio,if=none,format=raw,file=$d/var/virtio.raw,discard=on" -device virtio-blk-pci,addr=0x0.0x5,backend_defaults=on,bus=pcie,drive=virtio -audiodev coreaudio,id=audio,out.fixed-settings=false -netdev vmnet-shared,id=net -chardev qemu-vdagent,id=spice,name=vdagent,clipboard=on -device virtio-serial-pci,addr=0x0.0x6,bus=pcie -device virtserialport,chardev=spice,name=com.redhat.spice.0 -run-with user="$(id -u):$(id -g)" "$@"
EOF
chmod a+x run
set -eux
mkdir -p depot_tools build/qemu source/angle source/libepoxy source/virglrenderer source/qemu var
git -C depot_tools init
git -C depot_tools fetch https://chromium.googlesource.com/chromium/tools/depot_tools 22df6f8e622dc3e8df8dc8b5d3e3503b169af78e
git -C depot_tools checkout FETCH_HEAD
git -C source/angle init
git -C source/angle fetch https://chromium.googlesource.com/angle/angle
git -C source/angle checkout FETCH_HEAD
git -C source/libepoxy init
git -C source/libepoxy fetch https://github.com/akihikodaki/libepoxy.git macos
git -C source/libepoxy checkout FETCH_HEAD
# Download and extract virglrenderer from tarball instead of git
mkdir -p source/virglrenderer
curl -L https://gitlab.freedesktop.org/virgl/virglrenderer/-/archive/1.1.1/virglrenderer-1.1.1.tar.gz | tar -xz -C source/virglrenderer --strip-components=1
# Download and apply patch
curl -L https://gist.githubusercontent.com/startergo/0d9a7425876c2b42f8b797af80fbe3d8/raw/virglrenderer-v04.diff -o virglrenderer-patch.diff
cd source/virglrenderer
patch -p1 < ../../virglrenderer-patch.diff
cd ../..
git -C source/qemu init
git -C source/qemu fetch https://github.com/akihikodaki/qemu.git macos
git -C source/qemu checkout FETCH_HEAD
export DEPOT_TOOLS_UPDATE=0
export PATH="$PWD/depot_tools:$PATH"
cd source/angle
scripts/bootstrap.py
gclient sync -D
gn gen --args=is_debug=false ../../build/angle
cd ../..
ninja -C build/angle
# Build and install libepoxy.
if [ ! -d build/libepoxy/meson-info ]; then
meson setup "-Dc_args=-I$PWD/source/angle/include" -Degl=yes -Dx11=false "--prefix=$PWD" build/libepoxy source/libepoxy
fi
meson install -C build/libepoxy
# Build and install virglrenderer.
if [ ! -d build/virglrenderer/meson-info ]; then
meson setup "-Dc_args=-I$PWD/source/angle/include" "--pkg-config-path=$PWD/lib/pkgconfig" "--prefix=$PWD" build/virglrenderer source/virglrenderer
fi
meson install -C build/virglrenderer
cd build/qemu
PKG_CONFIG_PATH="$PWD/../../lib/pkgconfig" ../../source/qemu/configure "--extra-cflags=-I$PWD/../../source/angle/include -march=armv8-a+crc+crypto" "--extra-ldflags=-L$PWD/../angle" "--prefix=$PWD/../.."
make "-j$(getconf _NPROCESSORS_ONLN)" install
[ -e ../../var/edk2-arm-vars.fd ] || cp pc-bios/edk2-arm-vars.fd ../../var
cd ../..
cat > run <<'EOF'
#!/bin/bash
d="$(dirname "${BASH_SOURCE[0]}")"
exec sudo DYLD_FALLBACK_LIBRARY_PATH="$d/build/angle:$d/lib" "$d/bin/qemu-system-aarch64" -machine virt,accel=hvf -cpu cortex-a72 -smp "$(getconf _NPROCESSORS_ONLN)" -m 4G -device pcie-root-port,id=pcie -device virtio-sound-pci,addr=0x0.0x0,bus=pcie,multifunction=on,audiodev=audio,streams=1 -device virtio-gpu-gl-pci,addr=0x0.0x1,bus=pcie -device virtio-keyboard-pci,addr=0x0.0x2,bus=pcie -device virtio-net-pci,addr=0x0.0x3,bus=pcie,netdev=net -device virtio-rng-pci,addr=0x0.0x4,bus=pcie -display cocoa,gl=es -drive "if=pflash,format=raw,file=$d/share/qemu/edk2-aarch64-code.fd,readonly=on" -drive "if=pflash,format=raw,file=$d/var/edk2-arm-vars.fd" -drive "id=virtio,if=none,format=raw,file=$d/var/virtio.raw,discard=on" -device virtio-blk-pci,addr=0x0.0x5,backend_defaults=on,bus=pcie,drive=virtio -audiodev coreaudio,id=audio,out.fixed-settings=false -netdev vmnet-shared,id=net -chardev qemu-vdagent,id=spice,name=vdagent,clipboard=on -device virtio-serial-pci,addr=0x0.0x6,bus=pcie -device virtserialport,chardev=spice,name=com.redhat.spice.0 -run-with user="$(id -u):$(id -g)" "$@"
EOF
chmod a+x run
From 5d764220d3204b995133a3c34ad686747346e542 Mon Sep 17 00:00:00 2001
From: Akihiko Odaki <[email protected]>
Date: Fri, 17 Dec 2021 14:51:32 +0900
Subject: [PATCH] vrend: Relax the GLSL ES version requirement
Commit a79e837b0d44199776612d2436c3c98a05287412 changed the GLES version
requirement of the shaders to support blitting multi-sample textures,
which is unavailable on GLES <3.1. However, the change was applied for
all shaders, resulting in faults when blitting single-sample textures
with GLES <3.1.
Require GLES 3.1 only in the shaders for multi-sample textures, which
are guarded with the feature detection.
Signed-off-by: Akihiko Odaki <[email protected]>
---
src/vrend_blitter.h | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/src/vrend_blitter.h b/src/vrend_blitter.h
index 91e24352..7a035712 100644
--- a/src/vrend_blitter.h
+++ b/src/vrend_blitter.h
@@ -35,6 +35,12 @@
"%s" \
#define FS_HEADER_GLES \
+ "#version 300 es\n" \
+ "// Blitter\n" \
+ "%s" \
+ "precision mediump float;\n" \
+
+#define FS_HEADER_GLES_MS \
"#version 310 es\n" \
"// Blitter\n" \
"%s" \
@@ -52,6 +58,11 @@
"// Blitter\n" \
#define HEADER_GLES \
+ "#version 300 es\n" \
+ "// Blitter\n" \
+ "precision mediump float;\n" \
+
+#define HEADER_GLES_MS \
"#version 310 es\n" \
"// Blitter\n" \
"precision mediump float;\n" \
@@ -145,7 +156,7 @@
"}\n"
#define FS_TEXFETCH_COL_MSAA_GL FS_HEADER_GL FS_TEXFETCH_COL_MSAA_BODY
-#define FS_TEXFETCH_COL_MSAA_GLES FS_HEADER_GLES FS_TEXFETCH_COL_MSAA_BODY
+#define FS_TEXFETCH_COL_MSAA_GLES FS_HEADER_GLES_MS FS_TEXFETCH_COL_MSAA_BODY
#define FS_TEXFETCH_COL_MSAA_ARRAY_GLES FS_HEADER_GLES_MS_ARRAY FS_TEXFETCH_COL_MSAA_BODY
#define FS_TEXFETCH_DS_BODY \
@@ -178,7 +189,7 @@ struct vrend_context;
struct vrend_resource;
struct vrend_blit_info;
#define FS_TEXFETCH_DS_MSAA_GL HEADER_GL FS_TEXFETCH_DS_MSAA_BODY
-#define FS_TEXFETCH_DS_MSAA_GLES HEADER_GLES FS_TEXFETCH_DS_MSAA_BODY_GLES
+#define FS_TEXFETCH_DS_MSAA_GLES HEADER_GLES_MS FS_TEXFETCH_DS_MSAA_BODY_GLES
#define FS_TEXFETCH_DS_MSAA_ARRAY_GLES HEADER_GLES_MS_ARRAY FS_TEXFETCH_DS_MSAA_BODY_GLES
/* implement blitting using OpenGL. */
--
2.39.5 (Apple Git-154)
From bd9b30e58ef0cdfd05e300169bbdbd6983cabffd Mon Sep 17 00:00:00 2001
From: Akihiko Odaki <[email protected]>
Date: Fri, 19 Feb 2021 13:43:42 +0900
Subject: [PATCH] virglrenderer: Add vrend_renderer_borrow_texture_for_scanout
virgl_renderer_resource_get_info is used to get texture information for
scanout. However, it is also crucial to configure the texture correctly
for scanout. Add vrend_renderer_borrow_texture_for_scanout, which
"borrows" the texture and modifies its configuration.
Signed-off-by: Akihiko Odaki <[email protected]>
---
src/virglrenderer.c | 19 +++++++++++++++++++
src/virglrenderer.h | 3 +++
src/vrend_renderer.c | 29 +++++++++++++++++++++++++++++
src/vrend_renderer.h | 2 ++
4 files changed, 53 insertions(+)
diff --git a/src/virglrenderer.c b/src/virglrenderer.c
index f701da00..1e454c6e 100644
--- a/src/virglrenderer.c
+++ b/src/virglrenderer.c
@@ -551,6 +551,25 @@ int virgl_renderer_resource_get_info_ext(int res_handle,
return 0;
}
+int virgl_renderer_borrow_texture_for_scanout(int res_handle,
+ struct virgl_renderer_resource_info_ext *info)
+{
+ TRACE_FUNC();
+ struct virgl_resource *res = virgl_resource_lookup(res_handle);
+
+ if (!res)
+ return EINVAL;
+ if (!info)
+ return EINVAL;
+
+ if (!res->pipe_resource)
+ return 0;
+
+ vrend_renderer_borrow_texture_for_scanout(res->pipe_resource);
+
+ return virgl_renderer_resource_get_info_ext(res_handle, info);
+}
+
void virgl_renderer_get_cap_set(uint32_t cap_set, uint32_t *max_ver,
uint32_t *max_size)
{
diff --git a/src/virglrenderer.h b/src/virglrenderer.h
index 815c952d..bdb093be 100644
--- a/src/virglrenderer.h
+++ b/src/virglrenderer.h
@@ -364,6 +364,9 @@ VIRGL_EXPORT int virgl_renderer_resource_get_info(int res_handle,
VIRGL_EXPORT int virgl_renderer_resource_get_info_ext(int res_handle,
struct virgl_renderer_resource_info_ext *info);
+VIRGL_EXPORT int virgl_renderer_borrow_texture_for_scanout(int res_handle,
+ struct virgl_renderer_resource_info_ext *info);
+
VIRGL_EXPORT void virgl_renderer_cleanup(void *cookie);
/* reset the rendererer - destroy all contexts and resource */
diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
index 4b8d1a68..13df42d5 100644
--- a/src/vrend_renderer.c
+++ b/src/vrend_renderer.c
@@ -13075,6 +13075,35 @@ void vrend_renderer_resource_get_info(struct pipe_resource *pres,
info->stride = util_format_get_nblocksx(res->base.format, u_minify(res->base.width0, 0)) * elsize;
}
+void vrend_renderer_borrow_texture_for_scanout(struct pipe_resource *pres)
+{
+ struct vrend_texture *tex = (struct vrend_texture *)pres;
+ struct vrend_format_table *tex_conv = &tex_conv_table[tex->base.base.format];
+
+ assert(tex->base.target == GL_TEXTURE_2D);
+ assert(!util_format_is_depth_or_stencil(tex->base.base.format));
+
+ glBindTexture(GL_TEXTURE_2D, tex->base.gl_id);
+
+ if (tex_conv->flags & VIRGL_TEXTURE_NEED_SWIZZLE) {
+ for (unsigned i = 0; i < ARRAY_SIZE(tex->cur_swizzle); ++i) {
+ GLint next_swizzle = to_gl_swizzle(tex_conv->swizzle[i]);
+ if (tex->cur_swizzle[i] != next_swizzle) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R + i, next_swizzle);
+ tex->cur_swizzle[i] = next_swizzle;
+ }
+ }
+ }
+
+ if (tex->cur_srgb_decode != GL_DECODE_EXT && util_format_is_srgb(tex->base.base.format)) {
+ if (has_feature(feat_texture_srgb_decode)) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT,
+ GL_DECODE_EXT);
+ tex->cur_srgb_decode = GL_DECODE_EXT;
+ }
+ }
+}
+
int
vrend_renderer_resource_d3d11_texture2d(struct pipe_resource *pres, void **d3d_tex2d)
{
diff --git a/src/vrend_renderer.h b/src/vrend_renderer.h
index b242c8bb..fc0c6acf 100644
--- a/src/vrend_renderer.h
+++ b/src/vrend_renderer.h
@@ -563,6 +563,8 @@ struct vrend_blit_info {
void vrend_renderer_resource_get_info(struct pipe_resource *pres,
struct vrend_renderer_resource_info *info);
+void vrend_renderer_borrow_texture_for_scanout(struct pipe_resource *pres);
+
void vrend_renderer_get_cap_set(uint32_t cap_set, uint32_t *max_ver,
uint32_t *max_size);
--
2.39.5 (Apple Git-154)
From eb922c477750ce7a79527a603981df9869de2507 Mon Sep 17 00:00:00 2001
From: Akihiko Odaki <[email protected]>
Date: Sat, 7 Jan 2023 12:31:40 +0900
Subject: [PATCH] vrend: Use integer vertex attribute on ANGLE on Apple
This is necessary to render image_resize example of WebRender in
changeset 722505:8b4648e13c46 on M2 MacBook Air.
Signed-off-by: Akihiko Odaki <[email protected]>
---
src/vrend_renderer.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
index 13df42d5..68c51fb5 100644
--- a/src/vrend_renderer.c
+++ b/src/vrend_renderer.c
@@ -3473,7 +3473,8 @@ void vrend_bind_vertex_elements_state(struct vrend_context *ctx,
return;
}
- if (has_feature(feat_gles31_vertex_attrib_binding) && v->id == 0) {
+ if (has_feature(feat_gles31_vertex_attrib_binding)) {
+ if (v->id == 0) {
glGenVertexArrays(1, &v->id);
glBindVertexArray(v->id);
for (uint32_t i = 0; i < v->count; i++) {
@@ -3491,6 +3492,17 @@ void vrend_bind_vertex_elements_state(struct vrend_context *ctx,
glVertexAttribBinding(i, ve->base.vertex_buffer_index);
glVertexBindingDivisor(i, ve->base.instance_divisor);
glEnableVertexAttribArray(i);
+ }
+ }
+ } else {
+ for (uint32_t i = 0; i < v->count; i++) {
+ struct vrend_vertex_element *ve = &v->elements[i];
+
+ if (util_format_is_pure_integer(ve->base.src_format)) {
+ UPDATE_INT_SIGN_MASK(ve->base.src_format, i,
+ v->signed_int_bitmask,
+ v->unsigned_int_bitmask);
+ }
}
}
}
@@ -7586,11 +7598,7 @@ static bool use_integer(void) {
return true;
const char * a = (const char *) glGetString(GL_VENDOR);
- if (!a)
- return false;
- if (strcmp(a, "ARM") == 0)
- return true;
- return false;
+ return a && !(strcmp(a, "ARM") && strcmp(a, "Google Inc. (Apple)"));
}
int vrend_renderer_init(const struct vrend_if_cbs *cbs, uint32_t flags)
--
2.39.5 (Apple Git-154)
From 4a489584344787ea52226ac50dd9fa86a1f38f90 Mon Sep 17 00:00:00 2001
From: Akihiko Odaki <[email protected]>
Date: Sun, 10 Dec 2023 20:31:06 +0900
Subject: [PATCH] vrend: Reject VIRGL_CCMD_CLEAR_TEXTURE if unsupported
Old versions of Mesa try to use VIRGL_CCMD_CLEAR_TEXTURE even if it is
not supported:
https://gitlab.freedesktop.org/mesa/mesa/-/issues/9944
Check if VIRGL_CCMD_CLEAR_TEXTURE is supported when it is requested and
return an error instead of crashing.
Signed-off-by: Akihiko Odaki <[email protected]>
---
src/vrend_renderer.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
index 68c51fb5..0cbd2213 100644
--- a/src/vrend_renderer.c
+++ b/src/vrend_renderer.c
@@ -4910,6 +4910,10 @@ int vrend_clear_texture(struct vrend_context* ctx,
format = tex_conv_table[fmt].glformat;
type = tex_conv_table[fmt].gltype;
+ if (!has_feature(feat_clear_texture)) {
+ return EINVAL;
+ }
+
/* 32-bit BGRA resources are always reordered to RGBA ordering before
* submission to the host driver. Reorder red/blue color bytes in
* the clear color to match. */
--
2.39.5 (Apple Git-154)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment