Skip to content

Instantly share code, notes, and snippets.

@osy
Forked from akihikodaki/README.en.md
Last active December 4, 2025 09:19
Show Gist options
  • Select an option

  • Save osy/a8f705050eed1c8421ad1a0855a8faa9 to your computer and use it in GitHub Desktop.

Select an option

Save osy/a8f705050eed1c8421ad1a0855a8faa9 to your computer and use it in GitHub Desktop.
QEMU on Apple Silicon with Vulkan support

QEMU on Apple Silicon with Vulkan support

The following is taken from https://gist.github.com/akihikodaki/87df4149e7ca87f18dc56807ec5a1bc5 with modifications to introduce Vulkan support. Since we need custom patches to QEMU, virglrenderer, MoltenVK, and libepoxy, the provided script will pull the right refs and build everything with the right params. Feel free to inspect the script to find the source for all the modifications. We are actively working to upstream everything so please do not build anything long-term with these patches.

Testing

Prerequisites

  • Xcode (relatively recent version)
  • Vulkan SDK for macOS (Make sure to select "System Global Installation" during Select Components.)

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/osy/a8f705050eed1c8421ad1a0855a8faa9/raw/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://cdimage.ubuntu.com/releases/25.10/release/ubuntu-25.10-desktop-arm64.iso

7.

./run -cdrom ubuntu-25.10-desktop-arm64.iso

Proceed the installation process, and now you can run Ubuntu 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.

You can also run bin/qemu-system-aarch64 yourself. The important arguments are:

-display cocoa,gl=es

and

-device virtio-gpu-gl-pci,hostmem=8G,blob=true,venus=true

Patching Mesa

For Vulkan to work on Ubuntu 25.10, you need to patch Mesa with the patches below. The first patch adds 16KiB page alignment to blob mappings. Hopefully this will not be required in the long term as we plan to add 4KiB page emulation to virglrenderer in the future. The second patch works around a bug introduced in Mesa 25 which breaks everything. Hopefully it will be fixed upstream soon. If you don't want to build Mesa yourself, pre-build .debs are provided:

Updating

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

Upstreaming

From 179f6f22addfcaa8582a9dd47bfbfc9d299b250a Mon Sep 17 00:00:00 2001
From: osy <[email protected]>
Date: Mon, 1 Dec 2025 23:15:06 -0800
Subject: [PATCH 1/2] DO NOT MERGE: venus: hack to align mappings to 16KiB
---
src/virtio/vulkan/vn_renderer_virtgpu.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/virtio/vulkan/vn_renderer_virtgpu.c b/src/virtio/vulkan/vn_renderer_virtgpu.c
index 5b199aaadb2..c3567e3501e 100644
--- a/src/virtio/vulkan/vn_renderer_virtgpu.c
+++ b/src/virtio/vulkan/vn_renderer_virtgpu.c
@@ -1246,6 +1246,7 @@ virtgpu_bo_create_from_device_memory(
virtgpu_bo_blob_flags(gpu, flags, external_handles);
uint32_t res_id;
+ size = align64(size, 0x4000); // FIXME: host 16KiB pages
uint32_t gem_handle = virtgpu_ioctl_resource_create_blob(
gpu, gpu->bo_blob_mem, blob_flags, size, mem_id, &res_id);
if (!gem_handle)
@@ -1303,6 +1304,7 @@ virtgpu_shmem_create(struct vn_renderer *renderer, size_t size)
}
uint32_t res_id;
+ size = align64(size, 0x4000); // FIXME: host 16KiB pages
uint32_t gem_handle = virtgpu_ioctl_resource_create_blob(
gpu, gpu->shmem_blob_mem, VIRTGPU_BLOB_FLAG_USE_MAPPABLE, size, 0,
&res_id);
--
2.51.0
From 83c448858e77a44f17980df4914c0570483be3f4 Mon Sep 17 00:00:00 2001
From: osy <[email protected]>
Date: Tue, 2 Dec 2025 10:33:19 -0800
Subject: [PATCH 2/2] Revert "util/surface: delete more
pipe_context::create_surface usage"
This reverts commit 718e277ab56e52c9a8d23c3ea4cb0eca038de630.
---
src/gallium/auxiliary/util/u_surface.c | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c
index 974db6be9f1..d6c8505c604 100644
--- a/src/gallium/auxiliary/util/u_surface.c
+++ b/src/gallium/auxiliary/util/u_surface.c
@@ -596,9 +596,9 @@ util_clear_texture_as_surface(struct pipe_context *pipe,
const struct pipe_box *box,
const void *data)
{
- struct pipe_surface tmpl;
+ struct pipe_surface tmpl = {{0}}, *sf;
- u_surface_default_template(&tmpl, res);
+ tmpl.format = res->format;
tmpl.first_layer = box->z;
tmpl.last_layer = box->z + box->depth - 1;
tmpl.level = level;
@@ -607,6 +607,10 @@ util_clear_texture_as_surface(struct pipe_context *pipe,
if (!pipe->clear_depth_stencil)
return false;
+ sf = pipe->create_surface(pipe, res, &tmpl);
+ if (!sf)
+ return false;
+
float depth = 0;
uint8_t stencil = 0;
unsigned clear = 0;
@@ -621,9 +625,11 @@ util_clear_texture_as_surface(struct pipe_context *pipe,
clear |= PIPE_CLEAR_STENCIL;
util_format_unpack_s_8uint(tmpl.format, &stencil, data, 1);
}
- pipe->clear_depth_stencil(pipe, &tmpl, clear, depth, stencil,
+ pipe->clear_depth_stencil(pipe, sf, clear, depth, stencil,
box->x, box->y, box->width, box->height,
false);
+
+ pipe_surface_reference(&sf, NULL);
} else {
if (!pipe->clear_render_target)
return false;
@@ -642,10 +648,16 @@ util_clear_texture_as_surface(struct pipe_context *pipe,
return false;
}
+ sf = pipe->create_surface(pipe, res, &tmpl);
+ if (!sf)
+ return false;
+
union pipe_color_union color;
- util_format_unpack_rgba(tmpl.format, color.ui, data, 1);
- pipe->clear_render_target(pipe, &tmpl, &color, box->x, box->y,
+ util_format_unpack_rgba(sf->format, color.ui, data, 1);
+ pipe->clear_render_target(pipe, sf, &color, box->x, box->y,
box->width, box->height, false);
+
+ pipe_surface_reference(&sf, NULL);
}
return true;
--
2.51.0
View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

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