Skip to content

Instantly share code, notes, and snippets.

@akihikodaki
Last active March 31, 2025 00:14
Show Gist options
  • Save akihikodaki/87df4149e7ca87f18dc56807ec5a1bc5 to your computer and use it in GitHub Desktop.
Save akihikodaki/87df4149e7ca87f18dc56807ec5a1bc5 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

@knazarov's Homebre Formulae

It is independently maintained so may be a bit older, but you may still find it useful.

https://github.com/knazarov/homebrew-qemu-virgl

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.

curl -L https://gist.github.com/akihikodaki/87df4149e7ca87f18dc56807ec5a1bc5/raw/2e1e5572cec78625df452b16b0ee924ef86aed0d/run.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.

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

7.

./run -cdrom Fedora-Silverblue-ostree-aarch64-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.

Apple Silicon で実践Linuxデスクトップ

M1 MacBook Airを買いました. これは私が持ってる一番速いコンピュータで, 私は長年の GNOME/GNU/Linux ユーザーでもあります. ここから, Apple Silicon でLinux デスクトップ環境が必要であるという明らかな結論が導かれます.

幸いにも, Linux は Apple Silicon で既に動作します. しかし 実用性 はどうでしょうか?

  • 2つのネイティブの移植があります.
    • Corellium. これは古くなっています. https://corellium.com/blog/linux-m1
    • Asahi Linux. 大幅に改善されており, 場合によっては実用的と言えます. しかし, 今のところグラフィックスアクセラレーションなどが欠けています. https://asahilinux.org
  • QEMU は CPU上でコードをネイティブ動作させることが可能です. しかし GPU についてはどうでしょう? また, 残念ながら, QEMU は macOS 向けにあまり最適化されていません.

私は Linux デスクトップが直ちに必要だったので, QEMU をハックすることにしました. 最大の困難は当然グラフィックスアクセラレーションですが, このために用いることができる, Virgil 3D という, ホストの OpenGL をゲストに見せるブリッジが存在します. https://virgil3d.github.io

残念ながらこれは macOS ホスト上で動きませんでした. そういうわけで 動くようにしました. 以上! 以下は Apple Silicon/M1 上での OpenGL を実演する動画です.

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

改変

QEMU

ui/cocoa

  • OpenGL サポートを追加.
  • Pixel by pixel 表示を実装.
  • カーソルの合成を追加.
  • キーマッピングを改善 (日本語 IME キーなど, 2021-06-17)

hw/block

  • macOS でのファイルロッキングを修正. (2021-07-07, 間違って同じ仮想マシンを 並行に起動してしまった場合にディスクが壊れるのを防ぐためには drivefile.locking=on を追加してください.)

hvf

  • 最新の Linux のために AArch64 ID レジスタを修正 (@agraf, 2022-02-07)

coreaudio

  • デバイスの変更処理を修正 (2022-02-26)

Virgil 3D renderer

OpenGL ES サポートを改善

Do It Yourself

@knazarov の Homebrew formulae

独自に保守されているため少し古いかもしれませんが, 便利かもしれません.

https://github.com/knazarov/homebrew-qemu-virgl

セットアップ

1. ターミナルを開く.

2. GLib, Meson, Pixman, pkg-config, そして spice-protocol を Homebrew でインストールする.

brew install glib meson pixman pkg-config spice-protocol

3. 空のディレクトリを作って working directory をそれに変更する.

4.

curl -L https://gist.github.com/akihikodaki/87df4149e7ca87f18dc56807ec5a1bc5/raw/2e1e5572cec78625df452b16b0ee924ef86aed0d/run.sh | bash -

5.

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

データが記録されるまで物理領域を消費しないため, イメージをかなり大きくできます. ただし, 物理ディスクが許容する以上のデータを書き込むとおかしな挙動が現れます.

6.

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

7.

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

インストールプロセスを進めてください. ./run を実行することで Fedora を起動できるようになるはずです.

注: Linux が起動するまでキーボードは利用できません。これは、この構成で利用している virtio-keyboard に UEFI ファームウェアの TianoCore が対応していないためです。

更新

単に最新の run.sh をダウンロードしてワークスペースディレクトリで実行して ください.

OpenGL プロファイルを選択する

run を編集してください.

  • gl=off は Virgil 3D GPU を無効にします. 安定していますがラグいです.
  • gl=core は OpenGL.framework を有効にします. 不安定です.
  • gl=es は ANGLE を有効にします. 安定していて速いです.

アップストリーミング

アップストリーミングが進行中です. 願わくば将来は私が実装した機能が brew install qemu とするだけで動作するようになるはずです.

考察

QEMU

この QEMU の改変は セキュアではありません . グラフィックスアクセラレーションのコードが仮想マシンの他のあらゆるもの全てと同じプロセスに存在していて, そのコードは巨大です. グラフィックススタックはシェーダコンパイルのために LLVM を含んでおり, その中の簡単な不具合1つでゲストの完全な乗っ取りが可能です.

vhost-user-gpu はグラフィックスアクセラレーションの分離を提供しますが, Linux 以外で動作するように修正が必要です.

  • 歴史的には, vhost-user は Linux カーネルの vhost インターフェイスの再実装となっていて, インターフェイス定義のためにカーネルヘッダに依存しています.
  • vhost-user は Linux でしか利用できない eventfd を利用しています.

これは難しくないでしょうが, プロセス分離がなくても満足してるのでやりません. やってもグラフィックスアクセラレーションプロセスは共有されたままになるでしょうし, 単独のグラフィカルプロセスの攻撃がグラフィックス出力全体の暴露につながるのは変わりないでしょう.

Apple Silicon/M1 上の Linux デスクトップ一般について

先に説明したとおり, このような仮想化ソフトウェアは Linux デスクトップを実行する 実用的で効率的な方法です. 性能上のオーバーヘッドも日常的な利用には許容できる範囲で, Linux と macOS のよりよい統合を提供しさえします. 例えば, macOS と Linux をトラックパッド上の3本指ジェスチャーで切り替えられます. VirtFS も使えます.

しかし, 仮想化による複雑さもあります. 要は1つのハードウェアを2つのシステムで 共有することになるので, 資源を適切に割り当てなければユーザー体験を悪化させます. この問題はあらゆる場面でおきます (キーボードのような HID, CPU のような計算資源, 電力管理などなど). この方法は 効率的 ですが 最善 ではありません.

長期的には ネイティブの Linux 移植が最善でしょう. Asahi Linux は期待できます. 今でも利用法によっては私が改変した QEMU よりよいかもしれません.

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 fffbc739779a2df56a464fd6853bbfb24bebb5f6
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
[ -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$(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 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
@j03ll0b0
Copy link

j03ll0b0 commented Jul 7, 2024

usb-keyboard is no longer available and is needed by ThoriumOS (a ChromiumOS forked by a friend of mine @Alex313031)

@DUOLabs333
Copy link

DUOLabs333 commented Jul 7, 2024 via email

@DUOLabs333
Copy link

@akihikodaki I just cloned your qemu repo, and I found that compiling on MacOS 11 no longer works. I saw some commits on the repo a couple of weeks ago that (understandably) removed compatibility for older versions. However, I'm assuming the rebase removed them, so I can't tell what I have to change to get them working again. Could you post the diffs so I can see what I have to change?

@Behinder
Copy link

This is not going to build because ninja subcommand build failed. there is no much info about the error so I am abandoning further trying

@akihikodaki
Copy link
Author

@akihikodaki Is there a way to set a window size at launch that should be fixed, so that any changes to the resolution of the guest does not change the size of the window?

@DUOLabs333 No. I tried frameAutoSaveName (https://developer.apple.com/documentation/appkit/nswindow/1419362-frameautosavename?language=objc) but had no luck.

@j03ll0b0 Virgl would not work well with Android and Chromium OS as they have non-standard graphics stacks. It will require some more effort.

@akihikodaki I just cloned your qemu repo, and I found that compiling on MacOS 11 no longer works. I saw some commits on the repo a couple of weeks ago that (understandably) removed compatibility for older versions. However, I'm assuming the rebase removed them, so I can't tell what I have to change to get them working again. Could you post the diffs so I can see what I have to change?

@DUOLabs333 Revert commits f64933c8aee2, 0e376d45411f, e9c9d8dc3ba9, and 3bf445fbb199.

@akihikodaki
Copy link
Author

@Behinder Please post the logs.

@j03ll0b0
Copy link

j03ll0b0 commented Jul 16, 2024

@akihikodaki would this: https://patchew.org/QEMU/[email protected]/ fix the
(edit) or better yet this? https://patchew.org/QEMU/[email protected]/
(I apologize, I am just so exited this works so well!, I hope I am not spamming this place)
virtio_input_handle_event: unmapped button: 7 [wheel-left]
virtio_input_handle_event: unmapped button: 8 [wheel-right]
we get when trying to scroll to the sides?
I am so happy, here are some reports:
Screenshot 2024-07-16 at 4 20 14 PM
Screenshot 2024-07-16 at 4 18 59 PM
Screenshot 2024-07-16 at 4 17 59 PM
Screenshot 2024-07-16 at 4 15 11 PM
Screenshot 2024-07-16 at 4 07 00 PM

an addition to my kernel cmdline to be able to fix video rendering and display size:
CODEC2_LEVEL=0 FFMPEG_CODEC=1 FFMPEG_HWACCEL_DISABLE=1 OMX_NO_YUV420=1 video=Virtual-1:1360x768 mitigations=off

and the script I use to start my Android BlissOS:
Screenshot 2024-07-16 at 4 27 17 PM

for ubuntu noble it's the same script but the only difference is that since it is installed on an external USB 3.1 enclosure (256GB SATA SSD) and I connect to it using the rdisk2 block disk, it shows less problems when using virtio SCSI instead of BLK device. So it behaves better and I get 450MB/s over there. Would be great to see if we can test venus.... the only problem being: DMABUF and the blobs... right?

@ZeppLu
Copy link

ZeppLu commented Jul 25, 2024

I am so happy, here are some reports: Screenshot 2024-07-16 at 4 20 14 PM Screenshot 2024-07-16 at 4 18 59 PM

From your screenshots, I would say guest opengl is powered by software renderer llvmpipe, i.e., opengl is not hardware accelerated.

@j03ll0b0
Copy link

@ZeppLu You are absolutely right and @akihikodaki pointed out the lack of support under android but I guess I was too carried out to listen.

Here is a proper test from ubuntu noble:
Screenshot from 2024-07-30 07-50-55

Big Thanks.

@DUOLabs333
Copy link

DUOLabs333 commented Jul 30, 2024

While trying to find ways to speed up host-guest communication, through some (admittedly not very scientific) iperf tests, I noticed that 1. TCP was faster if the Wi-Fi is turned on, and the host can access the internet (ie, just turning it on and not connecting to a network is not enough); and 2. that communication seems capped at 1Gib/s. I think 2 is expected (this is just the maximum throughput of the underlying vmnet.framework), but I'm not sure about 1.

@j03ll0b0
Copy link

I tried building again, had to remove everything and start from scratch. the resulting binaries won't work. It won't boot my vm, is this known?

@DUOLabs333
Copy link

@j03ll0b0 What do you mean "won't work"? What errors are you getting?

@oliverbestmann
Copy link

oliverbestmann commented Oct 10, 2024

Found the issue. I profiled qemu and realized that the shader compilation freezes the process for hundreds of milliseconds, leading to the observed lag within the machine. I recompile angle with the metal backend, as that is supposed to speed up shader compile times compared to apples opengl implementation, which it did. There is still notable lag when opening new windows within gnome. I tracked that down to dozens of shaders being compiled (and recompile) everytime a gtk4 window opens. I am now adding some hacky caching to virglrenderer to cache the compiled shaders, so that they do not need to be recompile every time. This removes any lag from opening windows for me.
I'll share a patch once I get this working correctly.

Previous text:
~~This thing works great for me with one exception: Everytime i am opening a new window in the guest, the screen freezes for about 3 or 4 seconds. This also happens if I open a second window within the same app (e.g. gnome console kgx). It seems to happen with recent gnome 46.4 as well as with an older version like ~43. Also mesa 24.0 to 24.2 do not seem to make a difference. Do you have any pointers on how i can start debugging this? Can I somehow get a virgl trace from the guest, or a virglrender trace from the host?~~

@startergo
Copy link

startergo commented Oct 28, 2024

If I run:

Macintosh:~ vagrant$  glxgears -info
No matching pixelformats found, perhaps try setting LIBGL_ALLOW_SOFTWARE=true
Abort trap: 6

@akihikodaki So I can only run glxgears through software but not virgl ?

LIBGL_ALLOW_SOFTWARE=true glxgears -info
GL_RENDERER   = Apple Software Renderer
GL_VERSION    = 2.1 APPLE-9.6.5
GL_VENDOR     = Apple Computer, Inc.
GL_EXTENSIONS = GL_ARB_color_buffer_float GL_ARB_depth_buffer_float GL_ARB_depth_clamp GL_ARB_depth_texture GL_ARB_draw_buffers GL_ARB_draw_elements_base_vertex GL_ARB_draw_instanced GL_ARB_fragment_program GL_ARB_fragment_program_shadow GL_ARB_fragment_shader GL_ARB_framebuffer_object GL_ARB_framebuffer_sRGB GL_ARB_half_float_pixel GL_ARB_half_float_vertex GL_ARB_imaging GL_ARB_instanced_arrays GL_ARB_multisample GL_ARB_multitexture GL_ARB_occlusion_query GL_ARB_pixel_buffer_object GL_ARB_point_parameters GL_ARB_point_sprite GL_ARB_provoking_vertex GL_ARB_seamless_cube_map GL_ARB_shader_objects GL_ARB_shader_texture_lod GL_ARB_shading_language_100 GL_ARB_shadow GL_ARB_shadow_ambient GL_ARB_sync GL_ARB_texture_border_clamp GL_ARB_texture_compression GL_ARB_texture_compression_rgtc GL_ARB_texture_cube_map GL_ARB_texture_env_add GL_ARB_texture_env_combine GL_ARB_texture_env_crossbar GL_ARB_texture_env_dot3 GL_ARB_texture_float GL_ARB_texture_mirrored_repeat GL_ARB_texture_non_power_of_two GL_ARB_texture_rectangle GL_ARB_texture_rg GL_ARB_transpose_matrix GL_ARB_vertex_array_bgra GL_ARB_vertex_blend GL_ARB_vertex_buffer_object GL_ARB_vertex_program GL_ARB_vertex_shader GL_ARB_window_pos GL_EXT_abgr GL_EXT_bgra GL_EXT_bindable_uniform GL_EXT_blend_color GL_EXT_blend_equation_separate GL_EXT_blend_func_separate GL_EXT_blend_minmax GL_EXT_blend_subtract GL_EXT_clip_volume_hint GL_EXT_debug_label GL_EXT_debug_marker GL_EXT_depth_bounds_test GL_EXT_draw_buffers2 GL_EXT_draw_range_elements GL_EXT_fog_coord GL_EXT_framebuffer_blit GL_EXT_framebuffer_multisample GL_EXT_framebuffer_multisample_blit_scaled GL_EXT_framebuffer_object GL_EXT_framebuffer_sRGB GL_EXT_geometry_shader4 GL_EXT_gpu_program_parameters GL_EXT_gpu_shader4 GL_EXT_multi_draw_arrays GL_EXT_packed_depth_stencil GL_EXT_packed_float GL_EXT_provoking_vertex GL_EXT_rescale_normal GL_EXT_secondary_color GL_EXT_separate_specular_color GL_EXT_shadow_funcs GL_EXT_stencil_two_side GL_EXT_stencil_wrap GL_EXT_texture_array GL_EXT_texture_compression_dxt1 GL_EXT_texture_compression_s3tc GL_EXT_texture_env_add GL_EXT_texture_filter_anisotropic GL_EXT_texture_integer GL_EXT_texture_lod_bias GL_EXT_texture_mirror_clamp GL_EXT_texture_rectangle GL_EXT_texture_shared_exponent GL_EXT_texture_sRGB GL_EXT_texture_sRGB_decode GL_EXT_timer_query GL_EXT_transform_feedback GL_EXT_vertex_array_bgra GL_APPLE_aux_depth_stencil GL_APPLE_client_storage GL_APPLE_element_array GL_APPLE_fence GL_APPLE_float_pixels GL_APPLE_flush_buffer_range GL_APPLE_flush_render GL_APPLE_packed_pixels GL_APPLE_pixel_buffer GL_APPLE_rgb_422 GL_APPLE_row_bytes GL_APPLE_specular_vector GL_APPLE_texture_range GL_APPLE_transform_hint GL_APPLE_vertex_array_object GL_APPLE_vertex_array_range GL_APPLE_vertex_point_size GL_APPLE_vertex_program_evaluators GL_APPLE_ycbcr_422 GL_ATI_separate_stencil GL_ATI_texture_compression_3dc GL_ATI_texture_env_combine3 GL_ATI_texture_float GL_ATI_texture_mirror_once GL_IBM_rasterpos_clip GL_NV_blend_square GL_NV_conditional_render GL_NV_depth_clamp GL_NV_fog_distance GL_NV_light_max_exponent GL_NV_texgen_reflection GL_NV_texture_barrier GL_SGIS_generate_mipmap GL_SGIS_texture_edge_clamp GL_SGIS_texture_lod 
VisualID 107, 0x6b
1485 frames in 5.0 seconds = 296.410 FPS
1276 frames in 5.0 seconds = 254.867 FPS
1419 frames in 5.0 seconds = 283.708 FPS
2100 frames in 5.0 seconds = 419.879 FPS
^C

I have increased the vRam in macOS to 512 MB as explained here
And Now I get up to 2000 FPS :
https://streamable.com/pmsb7b

@j03ll0b0
Copy link

here

with the updates up to jun 27, I get a working build, updating to jul 20 it builds but I get errors with sound card and qemu plainly just won't start.

@flanter21
Copy link

For anyone else running into errors compiling angle, change the script to fetch master rather than that specific commit and that should fix it.

ie
git -C source/angle fetch https://chromium.googlesource.com/angle/angle fffbc739779a2df56a464fd6853bbfb24bebb5f6
-> git -C source/angle fetch https://chromium.googlesource.com/angle/angle

@startergo
Copy link

startergo commented Jan 21, 2025

If someone wants to test DirectX acceleration using Mesa GL/3Dfx Glide Pass-Through in Windows 98, WinXP on Qemu:
https://github.com/kharovtobi/qemu-3dfx-arch

@startergo
Copy link

startergo commented Feb 11, 2025

A GitHub Action for building this Qemu version:

# Default YAML
# Line wrap recommended
# Don't forget to change variables every QEMU update!
name: Build Stable Qemu-Virgl (macOS)

on:  
  workflow_dispatch:
  
jobs:
  build-macos:
    name: macOS
    runs-on: macos-latest
    env:
      pkgver: '9.2.50'      
      ACTIONS_STEP_DEBUG: true
      PKG_CONFIG_PATH: "/opt/homebrew/opt/cyrus-sasl/lib/pkgconfig:/opt/homebrew/opt/zlib/lib/pkgconfig:/opt/homebrew/opt/jpeg/lib/pkgconfig:/opt/homebrew/opt/libxml2/lib/pkgconfig:/opt/homebrew/opt/xz/lib/pkgconfig:/opt/homebrew/opt/gnutls/lib/pkgconfig:/Users/runner/work/qemu-3dfx-arch/qemu-3dfx-arch/lib/pkgconfig:/opt/local/lib/pkgconfig"
    steps:
      - name: Checkout repo
        uses: actions/checkout@v4      
      
      - name: Install dependencies
        run: |                  
          brew install $(brew deps --include-build qemu) || True
          brew install --cask xquartz || true
          brew install autoconf-archive binutils cyrus-sasl devutils GStreamer gtk+ gtk+3 jack jpeg libgcrypt || True
          brew install libiscsi libnfs libssh2 libx11 libxkbcommon libxml2 libxxf86vm mesa opus sdl12-compat sdl2 sdl2_image || True
          brew install sphinx-doc tree usbredir wget zlib || True                   

      - name: Cache depot_tools, angle, virglrenderer, libepoxy, and include
        id: cache-depot-tools-angle-virglrenderer-libepoxy-include
        if: always()
        uses: actions/cache@v4
        with:
          path: |
            depot_tools
            source/angle/include
            build/angle
            build/virglrenderer
            build/libepoxy
            include
          key: ${{ runner.os }}-depot-tools-angle-virglrenderer-libepoxy-include-${{ hashFiles('**/depot_tools/**', '**/source/angle/include/**', '**/build/angle/**', '**/build/virglrenderer/**', '**/build/libepoxy/**', '**/include/**') }}
          restore-keys: |          
            ${{ runner.os }}-depot-tools-angle-virglrenderer-libepoxy-include-
        env:
          pkgver: '9.2.50'
          ACTIONS_STEP_DEBUG: true      

      - name: Clean working directory
        run: git clean -fdx -e depot_tools -e source/angle/include -e build/angle -e build/virglrenderer -e build/libepoxy -e include -e lib      

      - name: Set up environment macos Virgl
        run: |
          if [ "${{ steps.cache-depot-tools-angle-virglrenderer-libepoxy-include.outputs.cache-hit }}" != 'true' ]; then
            set -eux
            mkdir -p depot_tools build/qemu source/angle source/libepoxy source/virglrenderer source/qemu
            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/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"
            git -C source/angle init
            git -C source/angle fetch https://chromium.googlesource.com/angle/angle fffbc739779a2df56a464fd6853bbfb24bebb5f6
            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
            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
          fi

      - name: Upload source-angle-include as artifact
        uses: actions/upload-artifact@v4
        with:
          name: source-angle-include
          path: source/angle/include
          if-no-files-found: warn
          compression-level: 6
          overwrite: false
          include-hidden-files: true

      - name: Upload build-angle as artifact
        uses: actions/upload-artifact@v4
        with:
          name: build-angle
          path: build/angle/
          if-no-files-found: warn
          compression-level: 6
          overwrite: false
          include-hidden-files: true    

      - name: Upload build-virglrenderer as artifact
        uses: actions/upload-artifact@v4
        with:
          name: build-virglrenderer
          path: build/virglrenderer
          if-no-files-found: warn
          compression-level: 6
          overwrite: false
          include-hidden-files: true

      - name: Upload build-libepoxy as artifact
        uses: actions/upload-artifact@v4
        with:
          name: build-libepoxy
          path: build/libepoxy
          if-no-files-found: warn
          compression-level: 6
          overwrite: false
          include-hidden-files: true      

      - name: Upload include as artifact
        uses: actions/upload-artifact@v4
        with:
          name: include
          path: include
          if-no-files-found: warn
          compression-level: 6
          overwrite: false
          include-hidden-files: true      

      - name: Upload depot-tools as artifact
        uses: actions/upload-artifact@v4
        with:
          name: depot_tools
          path: depot_tools
          if-no-files-found: warn
          compression-level: 6
          overwrite: false
          include-hidden-files: true

      - name: Upload lib as artifact
        uses: actions/upload-artifact@v4
        with:
          name: lib
          path: lib
          if-no-files-found: warn
          compression-level: 6
          overwrite: false
          include-hidden-files: true    

      - name: Fetch and checkout QEMU source
        continue-on-error: true
        run: |
          if [ "${{ steps.cache-depot-tools-angle-virglrenderer-libepoxy-include.outputs.cache-hit }}" == 'true' ]; then
            mkdir -p source/qemu
            git -C source/qemu init
            git -C source/qemu fetch https://github.com/akihikodaki/qemu.git macos
            git -C source/qemu checkout FETCH_HEAD
          fi
          meson install -C build/libepoxy || True

      - name: Create build/qemu directory        
        run: |
          if [ "${{ steps.cache-depot-tools-angle-virglrenderer-libepoxy-include.outputs.cache-hit }}" == 'true' ]; then
            mkdir -p build/qemu
          fi

      - name: Prepare Angle
        continue-on-error: true
        run: |
          if [ "${{ steps.cache-depot-tools-angle-virglrenderer-libepoxy-include.outputs.cache-hit }}" == 'true' ]; then
            export DEPOT_TOOLS_UPDATE=0
            export PATH="$PWD/depot_tools:$PATH"          
          fi     

      - name: Create install_dir
        run: mkdir -p install_dir

      - name: Configure Qemu build
        continue-on-error: true
        working-directory: ./build/qemu
        shell: bash
        run: |
          echo "Configuring build"                
          # Add epoxy include path to extra-cflags
          PKG_CONFIG_PATH="$PWD/../../lib/pkgconfig" ../../source/qemu/configure "--extra-cflags=-I$PWD/../../source/angle/include -march=native -mtune=native -flto=auto" "--extra-ldflags=-L$PWD/../../lib" "--prefix=$PWD/../../install_dir"    
         
      - name: Compile Qemu build
        shell: bash
        continue-on-error: true
        working-directory: ./build/qemu               
        run: |
          echo "Compiling Build"
          make -j$(sysctl -n hw.ncpu)      

      - name: Installing Qemu build
        continue-on-error: true
        working-directory: ./build/qemu
        shell: bash
        run: |
          echo "Installing build to output"
          make install || True          
          cat <<EOF > version.txt
          QEMU-3dfx-arch (macOS Build)
          =================================================
          Github Actions Artifact Build
          Version ${{ env.pkgver }}
          Built using macOS
          EOF
          echo "Finished build at $(date)"

      - name: Upload QEMU binary as artifact
        uses: actions/upload-artifact@v4
        with:
          name: qemu-binary-virgl-not-signed
          path: ./install_dir      

runneros macOS-latest is a silicon Instance and it builds fine.

@startergo
Copy link

For Intel macOS use this:

curl -L https://gist.github.com/startergo/0d9a7425876c2b42f8b797af80fbe3d8/raw/run-x86_64.sh | bash -
bin/qemu-img create var/virtio.raw 64G
curl -LO https://mirror.web-ster.com/fedora/releases/41/Silverblue/x86_64/iso/Fedora-Silverblue-ostree-x86_64-41-1.4.iso
./run -cdrom Fedora-Silverblue-ostree-x86_64-41-1.4.iso
fedora@fedora:~$ glxgears -info
Running synchronized to the vertical refresh.  The framerate should be
approximately the same as the monitor refresh rate.
GL_RENDERER   = virgl (ANGLE (ATI Technologies Inc., AMD Radeon Pro 560X Op...)
GL_VERSION    = 2.1 Mesa 24.2.4
GL_VENDOR     = Mesa

@startergo
Copy link

@akihikodaki There is an update of your patches eliminating ANGLE as EGL libraries:

Based on initial work "Virgil 3D on macOS" by 小田喜陽彦 akihikodaki.
https://mail.gnu.org/archive/html/qem...
With improvements:
Get rid of ANGLE as EGL libraries. Virgil 3D solely uses OpenGL Core backend through SDL2 which wraps to NSOpenGL.
No patch to "cocoa" display of QEMU. Minimal modification to SDL2 display to support Virgil 3D on macOS. QEMU cannot have both "cocoa" and "sdl2" display in the same build.
Minimal change to libepoxy and virglrenderer, basically only have to make sure they built without libdrm and libEGL.
Fix known issues with OpenGL Core
Performance comparable to ANGLE OpenGL ES backend. WebGL Aquarium at 60 FPS. Chromium web rendering is accelerated.
The accelerated ArchLinux ARM is very snappy & usable with Apple HVF virtualization. It matches or even exceeds the performance of typical ARM Linux flavors running on RK3399 or RPi4 bare-metal. It probably makes M1 MacBooks the world fastest (... most expensive) Linux ARM laptops.
Nested VM is possible, and there is a demo of qemu-3dfx Glide passthrough from nested QEMU i386 instance running Blood 1.2 3Dfx DOS game.

https://www.youtube.com/watch?v=FVv8UjGhYPU
The patches are here:
https://github.com/kjliew/qemu-3dfx/tree/master/virgil3d
Have you tested this?

@akihikodaki
Copy link
Author

@startergo My tree supported Apple's OpenGL Core backend from the beginning (I added it even before ANGLE), but it was unstable at that time. I don't think the situation has changed since then as Apple's OpenGL Core backend is almost dead and not evloving.

@startergo
Copy link

startergo commented Feb 27, 2025

I wonder why aren’t your changes integrated in upstream QEMU ? I tried compiling the patched QEMU in Windows, but it failed so I patched the nfs.c to allow the build to compile in Windows. There shouldn’t be any other obstacles. @akihikodaki here is the nfs.c patch:

diff -Nru ../orig/qemu-9.2.0/block/nfs.c ./block/nfs.c
--- ../orig/qemu-9.2.0/block/nfs.c
+++ ./block/nfs.c
@@ -47,7 +47,6 @@
 #include "qapi/qobject-output-visitor.h"
 #include <nfsc/libnfs.h>
 
-
 #define QEMU_NFS_MAX_READAHEAD_SIZE 1048576
 #define QEMU_NFS_MAX_PAGECACHE_SIZE (8388608 / NFS_BLKSIZE)
 #define QEMU_NFS_MAX_DEBUG_LEVEL 2
@@ -74,8 +73,11 @@
     struct stat *st;
     Coroutine *co;
     NFSClient *client;
+    void *buf;
 } NFSRPC;
 
+static void nfs_set_events(NFSClient *client);
+
 static int nfs_parse_uri(const char *filename, QDict *options, Error **errp)
 {
     g_autoptr(GUri) uri = g_uri_parse(filename, G_URI_FLAGS_NONE, NULL);
@@ -268,8 +270,19 @@
     NFSRPC task;
 
     nfs_co_init_task(bs, &task);
-    task.iov = iov;
+#ifdef LIBNFS_API_V2
+    WITH_QEMU_LOCK_GUARD(&client->mutex) {
+        if (nfs_pread_async(client->context, client->fh,
+                            iov->iov[0].iov_base,
+                            bytes > iov->iov[0].iov_len ? iov->iov[0].iov_len : bytes,
+                            offset, nfs_co_generic_cb, &task) != 0) {
+            return -ENOMEM;
+        }
 
+        nfs_set_events(client);
+    }
+#else
+    task.iov = iov;
     WITH_QEMU_LOCK_GUARD(&client->mutex) {
         if (nfs_pread_async(client->context, client->fh,
                             offset, bytes, nfs_co_generic_cb, &task) != 0) {
@@ -278,6 +291,7 @@
 
         nfs_set_events(client);
     }
+#endif
     while (!task.complete) {
         qemu_coroutine_yield();
     }
@@ -300,26 +314,30 @@
 {
     NFSClient *client = bs->opaque;
     NFSRPC task;
-    char *buf = NULL;
+    void *buf = NULL;
     bool my_buffer = false;
 
     nfs_co_init_task(bs, &task);
+    task.buf = buf;
 
-    if (iov->niov != 1) {
-        buf = g_try_malloc(bytes);
-        if (bytes && buf == NULL) {
-            return -ENOMEM;
-        }
-        qemu_iovec_to_buf(iov, 0, buf, bytes);
-        my_buffer = true;
-    } else {
+    if (iov->niov == 1) {
         buf = iov->iov[0].iov_base;
+    } else {
+        buf = g_malloc0(bytes);
+        my_buffer = true;
+        qemu_iovec_to_buf(iov, 0, buf, bytes);
     }
 
     WITH_QEMU_LOCK_GUARD(&client->mutex) {
+#ifdef LIBNFS_API_V2
+        if (nfs_pwrite_async(client->context, client->fh,
+                             buf, bytes, offset,
+                             nfs_co_generic_cb, &task) != 0) {
+#else
         if (nfs_pwrite_async(client->context, client->fh,
                              offset, bytes, buf,
                              nfs_co_generic_cb, &task) != 0) {
+#endif
             if (my_buffer) {
                 g_free(buf);
             }
@@ -332,12 +350,15 @@
         qemu_coroutine_yield();
     }
 
-    if (my_buffer) {
-        g_free(buf);
+    if (task.ret < 0) {
+        if (my_buffer) {
+            g_free(buf);
+        }
+        return task.ret;
     }
 
-    if (task.ret != bytes) {
-        return task.ret < 0 ? task.ret : -EIO;
+    if (my_buffer) {
+        g_free(buf);
     }
 
     return 0;

Based on:
https://lists.nongnu.org/archive/html/qemu-block/2024-12/msg00170.html

@akihikodaki
Copy link
Author

@startergo Roughly speaking, it is because I'm not pushing changes hard enough. In open-source development, sometimes maintainers miss posted changes so a submitter needs to notify them to get their changes merged early, but I'm not in a hurry either so these changes are left stuck now.
Currently, anholt/libepoxy#239 is the main roadblock.

@startergo
Copy link

@akihikodaki Thank you for the clarification. I was trying to compile and test QEMU without angle by patching virgilrenderer1.1.0 source and QEMU with the above patches and relying on the libepoxy from HomeBrew. Unfortunately when running QEMU it crashed on start as it could not find some libraries which I found to be in another angle directory I had on the drive.
Do you know what do I have to do to compile QEMU without angle with just the proposed patches for QEMU and virgl above? I would like to compare the performance of both Apple and angle's OpenGL.

@startergo
Copy link

startergo commented Mar 2, 2025

image This is parallels win11 on MacBook Pro M4pro CPU with WDDM driver. image

@startergo
Copy link

Debian in Parallels:
image

@akihikodaki
Copy link
Author

akihikodaki commented Mar 3, 2025

@akihikodaki Thank you for the clarification. I was trying to compile and test QEMU without angle by patching virgilrenderer1.1.0 source and QEMU with the above patches and relying on the libepoxy from HomeBrew. Unfortunately when running QEMU it crashed on start as it could not find some libraries which I found to be in another angle directory I had on the drive. Do you know what do I have to do to compile QEMU without angle with just the proposed patches for QEMU and virgl above? I would like to compare the performance of both Apple and angle's OpenGL.

@startergo You don't have to recompile it without ANGLE but you can just pass gl=core when launching QEMU to disable ANGLE. This gist already has an explanation for this.

@startergo
Copy link

startergo commented Mar 12, 2025

@akihikodaki I have updated the @knazarov tap . Key points:
I use your patches to patch the head of angle and libepoxy. Unfortunately I don't know what to compare your fork of virglrenderer branch macOS to, so I use it directly. Which is the commit of upstream virglrenderer your starting point?

@flanter21
Copy link

A GitHub Action for building this Qemu version:

# Default YAML
# Line wrap recommended
# Don't forget to change variables every QEMU update!
name: Build Stable Qemu-Virgl (macOS)

on:  
  workflow_dispatch:
  
jobs:
  build-macos:
    name: macOS
    runs-on: macos-latest
    env:
      pkgver: '9.2.50'      
      ACTIONS_STEP_DEBUG: true
      PKG_CONFIG_PATH: "/opt/homebrew/opt/cyrus-sasl/lib/pkgconfig:/opt/homebrew/opt/zlib/lib/pkgconfig:/opt/homebrew/opt/jpeg/lib/pkgconfig:/opt/homebrew/opt/libxml2/lib/pkgconfig:/opt/homebrew/opt/xz/lib/pkgconfig:/opt/homebrew/opt/gnutls/lib/pkgconfig:/Users/runner/work/qemu-3dfx-arch/qemu-3dfx-arch/lib/pkgconfig:/opt/local/lib/pkgconfig"
    steps:
      - name: Checkout repo
        uses: actions/checkout@v4      
      
      - name: Install dependencies
        run: |                  
          brew install $(brew deps --include-build qemu) || True
          brew install --cask xquartz || true
          brew install autoconf-archive binutils cyrus-sasl devutils GStreamer gtk+ gtk+3 jack jpeg libgcrypt || True
          brew install libiscsi libnfs libssh2 libx11 libxkbcommon libxml2 libxxf86vm mesa opus sdl12-compat sdl2 sdl2_image || True
          brew install sphinx-doc tree usbredir wget zlib || True                   

      - name: Cache depot_tools, angle, virglrenderer, libepoxy, and include
        id: cache-depot-tools-angle-virglrenderer-libepoxy-include
        if: always()
        uses: actions/cache@v4
        with:
          path: |
            depot_tools
            source/angle/include
            build/angle
            build/virglrenderer
            build/libepoxy
            include
          key: ${{ runner.os }}-depot-tools-angle-virglrenderer-libepoxy-include-${{ hashFiles('**/depot_tools/**', '**/source/angle/include/**', '**/build/angle/**', '**/build/virglrenderer/**', '**/build/libepoxy/**', '**/include/**') }}
          restore-keys: |          
            ${{ runner.os }}-depot-tools-angle-virglrenderer-libepoxy-include-
        env:
          pkgver: '9.2.50'
          ACTIONS_STEP_DEBUG: true      

      - name: Clean working directory
        run: git clean -fdx -e depot_tools -e source/angle/include -e build/angle -e build/virglrenderer -e build/libepoxy -e include -e lib      

      - name: Set up environment macos Virgl
        run: |
          if [ "${{ steps.cache-depot-tools-angle-virglrenderer-libepoxy-include.outputs.cache-hit }}" != 'true' ]; then
            set -eux
            mkdir -p depot_tools build/qemu source/angle source/libepoxy source/virglrenderer source/qemu
            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/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"
            git -C source/angle init
            git -C source/angle fetch https://chromium.googlesource.com/angle/angle fffbc739779a2df56a464fd6853bbfb24bebb5f6
            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
            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
          fi

      - name: Upload source-angle-include as artifact
        uses: actions/upload-artifact@v4
        with:
          name: source-angle-include
          path: source/angle/include
          if-no-files-found: warn
          compression-level: 6
          overwrite: false
          include-hidden-files: true

      - name: Upload build-angle as artifact
        uses: actions/upload-artifact@v4
        with:
          name: build-angle
          path: build/angle/
          if-no-files-found: warn
          compression-level: 6
          overwrite: false
          include-hidden-files: true    

      - name: Upload build-virglrenderer as artifact
        uses: actions/upload-artifact@v4
        with:
          name: build-virglrenderer
          path: build/virglrenderer
          if-no-files-found: warn
          compression-level: 6
          overwrite: false
          include-hidden-files: true

      - name: Upload build-libepoxy as artifact
        uses: actions/upload-artifact@v4
        with:
          name: build-libepoxy
          path: build/libepoxy
          if-no-files-found: warn
          compression-level: 6
          overwrite: false
          include-hidden-files: true      

      - name: Upload include as artifact
        uses: actions/upload-artifact@v4
        with:
          name: include
          path: include
          if-no-files-found: warn
          compression-level: 6
          overwrite: false
          include-hidden-files: true      

      - name: Upload depot-tools as artifact
        uses: actions/upload-artifact@v4
        with:
          name: depot_tools
          path: depot_tools
          if-no-files-found: warn
          compression-level: 6
          overwrite: false
          include-hidden-files: true

      - name: Upload lib as artifact
        uses: actions/upload-artifact@v4
        with:
          name: lib
          path: lib
          if-no-files-found: warn
          compression-level: 6
          overwrite: false
          include-hidden-files: true    

      - name: Fetch and checkout QEMU source
        continue-on-error: true
        run: |
          if [ "${{ steps.cache-depot-tools-angle-virglrenderer-libepoxy-include.outputs.cache-hit }}" == 'true' ]; then
            mkdir -p source/qemu
            git -C source/qemu init
            git -C source/qemu fetch https://github.com/akihikodaki/qemu.git macos
            git -C source/qemu checkout FETCH_HEAD
          fi
          meson install -C build/libepoxy || True

      - name: Create build/qemu directory        
        run: |
          if [ "${{ steps.cache-depot-tools-angle-virglrenderer-libepoxy-include.outputs.cache-hit }}" == 'true' ]; then
            mkdir -p build/qemu
          fi

      - name: Prepare Angle
        continue-on-error: true
        run: |
          if [ "${{ steps.cache-depot-tools-angle-virglrenderer-libepoxy-include.outputs.cache-hit }}" == 'true' ]; then
            export DEPOT_TOOLS_UPDATE=0
            export PATH="$PWD/depot_tools:$PATH"          
          fi     

      - name: Create install_dir
        run: mkdir -p install_dir

      - name: Configure Qemu build
        continue-on-error: true
        working-directory: ./build/qemu
        shell: bash
        run: |
          echo "Configuring build"                
          # Add epoxy include path to extra-cflags
          PKG_CONFIG_PATH="$PWD/../../lib/pkgconfig" ../../source/qemu/configure "--extra-cflags=-I$PWD/../../source/angle/include -march=native -mtune=native -flto=auto" "--extra-ldflags=-L$PWD/../../lib" "--prefix=$PWD/../../install_dir"    
         
      - name: Compile Qemu build
        shell: bash
        continue-on-error: true
        working-directory: ./build/qemu               
        run: |
          echo "Compiling Build"
          make -j$(sysctl -n hw.ncpu)      

      - name: Installing Qemu build
        continue-on-error: true
        working-directory: ./build/qemu
        shell: bash
        run: |
          echo "Installing build to output"
          make install || True          
          cat <<EOF > version.txt
          QEMU-3dfx-arch (macOS Build)
          =================================================
          Github Actions Artifact Build
          Version ${{ env.pkgver }}
          Built using macOS
          EOF
          echo "Finished build at $(date)"

      - name: Upload QEMU binary as artifact
        uses: actions/upload-artifact@v4
        with:
          name: qemu-binary-virgl-not-signed
          path: ./install_dir      

runneros macOS-latest is a silicon Instance and it builds fine.

Does this compile qemu-3dfx or is it possible to change it to do so?

@startergo
Copy link

Does this compile qemu-3dfx or is it possible to change it to do so?

yes but the problem is that it hardcodes the links in the dynamic libraries, which relate to the GitHub's osrunner directories which are non-existent on your machine. You can recreate the folder structure based on the message I guess. The point is that it is not so straight forward.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment