diff --git a/Configuration/UTMQemuConfiguration+Arguments.swift b/Configuration/UTMQemuConfiguration+Arguments.swift
index 36ccfdafd0..8f7debb1c0 100644
--- a/Configuration/UTMQemuConfiguration+Arguments.swift
+++ b/Configuration/UTMQemuConfiguration+Arguments.swift
@@ -284,21 +284,13 @@ import Virtualization // for getting network interfaces
"edid=on"
}
if isDisplayGLSupported(display) && isVulkanSupported {
- #if os(macOS)
"hostmem=8G"
- #else
- "hostmem=256M"
- #endif
"blob=true"
"venus=true"
}
if isDisplayGLSupported(display) && isNeptuneSupported {
if !isVulkanSupported {
- #if os(macOS)
"hostmem=8G"
- #else
- "hostmem=256M"
- #endif
"blob=true"
}
"neptune=true"
@@ -357,13 +349,13 @@ import Virtualization // for getting network interfaces
}
private var isNeptuneSupported: Bool {
- #if os(macOS)
- isGLSupported &&
- (rendererBackend == .qemuRendererBackendAngleMetal || rendererBackend == .qemuRendererBackendDefault) &&
- directXDriver != .qemuDirectXDriverDisabled
- #else
- false
- #endif
+ if #available(macOS 13, iOS 16, *) {
+ return isGLSupported &&
+ (rendererBackend == .qemuRendererBackendAngleMetal || rendererBackend == .qemuRendererBackendDefault) &&
+ directXDriver != .qemuDirectXDriverDisabled
+ } else {
+ return false
+ }
}
private var isSparc: Bool {
diff --git a/Platform/Shared/VMConfigSystemView.swift b/Platform/Shared/VMConfigSystemView.swift
index 606f97b76d..6f382667d0 100644
--- a/Platform/Shared/VMConfigSystemView.swift
+++ b/Platform/Shared/VMConfigSystemView.swift
@@ -97,7 +97,7 @@ struct VMConfigSystemView: View {
#if os(iOS) || os(visionOS)
let availableMemory = UInt64(os_proc_available_memory())
if availableMemory > 0 {
- totalDeviceMemory = availableMemory
+ totalDeviceMemory = min(availableMemory, totalDeviceMemory)
}
#endif
let actualJitSizeMib = jitSizeMib == 0 ? memorySizeMib / 4 : jitSizeMib
diff --git a/Platform/iOS/Settings.bundle/Root.plist b/Platform/iOS/Settings.bundle/Root.plist
index 4dd7e42818..b7eacab977 100644
--- a/Platform/iOS/Settings.bundle/Root.plist
+++ b/Platform/iOS/Settings.bundle/Root.plist
@@ -171,6 +171,32 @@
iOS-Remote
+
+ Type
+ PSMultiValueSpecifier
+ Title
+ DirectX Driver
+ Key
+ QEMUDirectXDriver
+ DefaultValue
+ 0
+ Titles
+
+ Default
+ Disabled
+ DXMT
+
+ Values
+
+ 0
+ 1
+ 2
+
+ ExcludeTargets
+
+ iOS-Remote
+
+
Type
PSMultiValueSpecifier
diff --git a/Platform/macOS/SettingsView.swift b/Platform/macOS/SettingsView.swift
index cf84742c67..1c20ae6b0c 100644
--- a/Platform/macOS/SettingsView.swift
+++ b/Platform/macOS/SettingsView.swift
@@ -227,7 +227,11 @@ struct DisplaySettingsView: View {
if qemuDirectXDriver == .qemuDirectXDriverD3DMetal {
return true // always show option if already selected
} else {
- return Self.hasD3DMetal
+ if #available(macOS 14, *) {
+ return Self.hasD3DMetal
+ } else {
+ return false
+ }
}
}
diff --git a/Services/UTMQemuSystem.m b/Services/UTMQemuSystem.m
index 008f8649f1..634ccd49ba 100644
--- a/Services/UTMQemuSystem.m
+++ b/Services/UTMQemuSystem.m
@@ -87,6 +87,10 @@ - (void)setDirectXDriver:(UTMQEMUDirectXDriver)directXDriver {
NSString *backend;
NSString *frameworkName;
NSURL *library;
+ if (@available(macOS 13, iOS 16, *)) {
+ } else {
+ return;
+ }
switch (directXDriver) {
case kQEMUDirectXDriverDefault:
case kQEMUDirectXDriverDXMT:
diff --git a/UTM.xcodeproj/project.pbxproj b/UTM.xcodeproj/project.pbxproj
index e160d35bb8..9b93eff2bb 100644
--- a/UTM.xcodeproj/project.pbxproj
+++ b/UTM.xcodeproj/project.pbxproj
@@ -632,6 +632,8 @@
CE2D958E24AD4F990059923A /* UTMApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE2D955524AD4F980059923A /* UTMApp.swift */; };
CE2D958F24AD4FF00059923A /* VMCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE2D954324AD4F980059923A /* VMCardView.swift */; };
CE2D959024AD50D50059923A /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 521F3EFB2414F73800130500 /* Localizable.strings */; };
+ CE30F93630200C2000024DB2 /* dxmt-native.framework in Embed Libraries */ = {isa = PBXBuildFile; fileRef = CEA3EDE93016810500AAA8E4 /* dxmt-native.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ CE30F93730200C3300024DB2 /* dxmt-native.framework in Embed Libraries */ = {isa = PBXBuildFile; fileRef = CEA3EDE93016810500AAA8E4 /* dxmt-native.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
CE38EC692B5DB3AE008B324B /* UTMRemoteClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE38EC682B5DB3AE008B324B /* UTMRemoteClient.swift */; };
CE4698F924C8FBD9008C1BD6 /* Icons in Resources */ = {isa = PBXBuildFile; fileRef = CE4698F824C8FBD9008C1BD6 /* Icons */; };
CE4698FA24C8FBD9008C1BD6 /* Icons in Resources */ = {isa = PBXBuildFile; fileRef = CE4698F824C8FBD9008C1BD6 /* Icons */; };
@@ -735,9 +737,7 @@
CE9B15482B12A87E003A32DD /* GenerateKey.c in Sources */ = {isa = PBXBuildFile; fileRef = CE9B15462B12A87E003A32DD /* GenerateKey.c */; };
CE9B15492B12A87E003A32DD /* GenerateKey.c in Sources */ = {isa = PBXBuildFile; fileRef = CE9B15462B12A87E003A32DD /* GenerateKey.c */; };
CE9B154A2B12A87E003A32DD /* GenerateKey.c in Sources */ = {isa = PBXBuildFile; fileRef = CE9B15462B12A87E003A32DD /* GenerateKey.c */; };
- CEA3EDEB3016810500AAA8E4 /* dxmt-native.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEA3EDE93016810500AAA8E4 /* dxmt-native.framework */; };
CEA3EDEC3016810500AAA8E4 /* dxmt-native.framework in Embed Libraries */ = {isa = PBXBuildFile; fileRef = CEA3EDE93016810500AAA8E4 /* dxmt-native.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
- CEA3EDED3016810500AAA8E4 /* d3dmetal-native.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEA3EDEA3016810500AAA8E4 /* d3dmetal-native.framework */; };
CEA3EDEE3016810500AAA8E4 /* d3dmetal-native.framework in Embed Libraries */ = {isa = PBXBuildFile; fileRef = CEA3EDEA3016810500AAA8E4 /* d3dmetal-native.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
CEA3EE05301691C500AAA8E4 /* QEMURenderServer.app in Embed Executables */ = {isa = PBXBuildFile; fileRef = CEA3EDFA30168B9000AAA8E4 /* QEMURenderServer.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
CEA45E25263519B5002FA97D /* VMDisplayMetalViewController+Pointer.h in Sources */ = {isa = PBXBuildFile; fileRef = 83FBDD53242FA71900D2C5D7 /* VMDisplayMetalViewController+Pointer.h */; };
@@ -1452,6 +1452,7 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
+ CE30F93730200C3300024DB2 /* dxmt-native.framework in Embed Libraries */,
CE2D937624AD46670059923A /* gpg-error.0.framework in Embed Libraries */,
CE2D937724AD46670059923A /* qemu-mips64el-softmmu.framework in Embed Libraries */,
CE2D937824AD46670059923A /* gstcontroller-1.0.0.framework in Embed Libraries */,
@@ -1553,6 +1554,7 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
+ CE30F93630200C2000024DB2 /* dxmt-native.framework in Embed Libraries */,
CEA45F72263519B5002FA97D /* gpg-error.0.framework in Embed Libraries */,
CE63B0FD2F0EFB0700C59D13 /* vulkan_kosmickrisp.framework in Embed Libraries */,
CEA45F74263519B5002FA97D /* gstcontroller-1.0.0.framework in Embed Libraries */,
@@ -2369,7 +2371,6 @@
CEF83F882500949D00557D15 /* gthread-2.0.0.framework in Frameworks */,
CE03D08724D90F0700F76B84 /* gobject-2.0.0.framework in Frameworks */,
CE9B15362B11A491003A32DD /* SwiftConnect in Frameworks */,
- CEA3EDED3016810500AAA8E4 /* d3dmetal-native.framework in Frameworks */,
CE0B6F0A24AD677200FE012D /* spice-client-glib-2.0.8.framework in Frameworks */,
CE0B6ECF24AD677200FE012D /* gstrtp-1.0.0.framework in Frameworks */,
CE0B6ECC24AD677200FE012D /* gstriff-1.0.0.framework in Frameworks */,
@@ -2385,7 +2386,6 @@
CE0B6EBB24AD677200FE012D /* libgstgio.a in Frameworks */,
84937EFF28960789003148F4 /* zstd.1.framework in Frameworks */,
CE0B6EE224AD677200FE012D /* gstnet-1.0.0.framework in Frameworks */,
- CEA3EDEB3016810500AAA8E4 /* dxmt-native.framework in Frameworks */,
CE03D08624D90F0700F76B84 /* gmodule-2.0.0.framework in Frameworks */,
CED297142CE425CB00F1E3EB /* soup-3.0.0.framework in Frameworks */,
CE03D0CA24D9142000F76B84 /* ssl.1.1.framework in Frameworks */,
@@ -5023,13 +5023,13 @@
"$(PROJECT_DIR)/$(QUOTED_SYSROOT_DIR)/include/spice-1",
"$(PROJECT_DIR)/$(QUOTED_SYSROOT_DIR)/include/libusb-1.0",
);
- IPHONEOS_DEPLOYMENT_TARGET = 16.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LIBRARY_SEARCH_PATHS = (
"$(PROJECT_DIR)/$(QUOTED_SYSROOT_DIR)/lib",
"$(PROJECT_DIR)/$(QUOTED_SYSROOT_DIR)/lib/gstreamer-1.0",
"$(PROJECT_DIR)/$(QUOTED_SYSROOT_DIR)/lib",
);
- MACOSX_DEPLOYMENT_TARGET = 13.0;
+ MACOSX_DEPLOYMENT_TARGET = 11.3;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
@@ -5106,13 +5106,13 @@
"$(PROJECT_DIR)/$(QUOTED_SYSROOT_DIR)/include/spice-1",
"$(PROJECT_DIR)/$(QUOTED_SYSROOT_DIR)/include/libusb-1.0",
);
- IPHONEOS_DEPLOYMENT_TARGET = 16.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LIBRARY_SEARCH_PATHS = (
"$(PROJECT_DIR)/$(QUOTED_SYSROOT_DIR)/lib",
"$(PROJECT_DIR)/$(QUOTED_SYSROOT_DIR)/lib/gstreamer-1.0",
"$(PROJECT_DIR)/$(QUOTED_SYSROOT_DIR)/lib",
);
- MACOSX_DEPLOYMENT_TARGET = 13.0;
+ MACOSX_DEPLOYMENT_TARGET = 11.3;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
QUOTED_SYSROOT_DIR = "\"$(SYSROOT_DIR)\"";
diff --git a/patches/llvm-project-15.0.7.src.patch b/patches/llvm-project-15.0.7.src.patch
new file mode 100644
index 0000000000..c321c6ff8f
--- /dev/null
+++ b/patches/llvm-project-15.0.7.src.patch
@@ -0,0 +1,49 @@
+LLVM 15 gates its Mach-O linker behaviour on `CMAKE_SYSTEM_NAME MATCHES "Darwin"`,
+which is false when cross-compiling for iOS/visionOS (CMAKE_SYSTEM_NAME is "iOS" /
+"visionOS"). The build then falls through to the ELF/COFF paths and passes flags
+Apple's ld rejects. Use `APPLE`, which is true for every Apple platform.
+
+Fixed upstream after 15.x; drop this patch when moving to a newer LLVM.
+
+ 1. add_llvm_symbol_exports() fell through to the Windows branch and handed a
+ .def file to ld:
+ ld: unknown file type in '.../LLVMHello.def'
+
+ 2. -Wl,-z,defs is ELF-only and was not excluded for iOS:
+ ld: unknown options: -z
+
+ 3. add_link_opts() skipped -Wl,-dead_strip, so non-Debug builds silently lost
+ dead stripping that the macOS build of the same sources already gets.
+ Not a build failure, just larger output.
+
+--- a/llvm/cmake/modules/AddLLVM.cmake
++++ b/llvm/cmake/modules/AddLLVM.cmake
+@@ -82,7 +82,7 @@
+ endfunction()
+
+ function(add_llvm_symbol_exports target_name export_file)
+- if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
++ if(APPLE)
+ set(native_export_file "${target_name}.exports")
+ add_custom_command(OUTPUT ${native_export_file}
+ COMMAND sed -e "s/^/_/" < ${export_file} > ${native_export_file}
+@@ -263,7 +263,7 @@
+ # linker in a context where the optimizations are not important.
+ if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG")
+ if(NOT LLVM_NO_DEAD_STRIP)
+- if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
++ if(APPLE)
+ # ld64's implementation of -dead_strip breaks tools that use plugins.
+ set_property(TARGET ${target_name} APPEND_STRING PROPERTY
+ LINK_FLAGS " -Wl,-dead_strip")
+--- a/llvm/cmake/modules/HandleLLVMOptions.cmake
++++ b/llvm/cmake/modules/HandleLLVMOptions.cmake
+@@ -229,7 +229,7 @@
+ # Pass -Wl,-z,defs. This makes sure all symbols are defined. Otherwise a DSO
+ # build might work on ELF but fail on MachO/COFF.
+ if(NOT (CMAKE_SYSTEM_NAME MATCHES "Darwin|FreeBSD|OpenBSD|DragonFly|AIX|SunOS|OS390" OR
+- WIN32 OR CYGWIN) AND
++ APPLE OR WIN32 OR CYGWIN) AND
+ NOT LLVM_USE_SANITIZER)
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,defs")
+ endif()
diff --git a/patches/qemu-10.0.12-utm.patch b/patches/qemu-10.0.12-utm.patch
index 2cc6a8f2a5..70756cdb44 100644
--- a/patches/qemu-10.0.12-utm.patch
+++ b/patches/qemu-10.0.12-utm.patch
@@ -546,3 +546,204 @@ index a2dddbd37a..f6d7879eff 100644
--
2.41.0
+From 7311c3651c3a2cbc3d32e6eae262c60339f28d79 Mon Sep 17 00:00:00 2001
+From: osy
+Date: Sun, 2 Aug 2026 21:04:16 -0700
+Subject: [PATCH] hw/arm/virt: shrink the high PCIe MMIO window to fit small PA
+ spaces
+
+Previously, if the high PCIe MMIO window did not fit in the guest
+physical address space, it was silently disabled, leaving no room to
+place any 64-bit BAR too large for the 32-bit window. On hosts with a
+small IPA space (e.g. a 36-bit IPA), this made devices like virtio-gpu
+with a large hostmem BAR unusable.
+
+Instead, shrink the window to the largest power of two that fits (no
+smaller than 1GiB) and warn about it. Only if even the minimum does not
+fit is the window disabled, and each high region now warns when it is
+disabled for not fitting rather than vanishing silently.
+
+To make room at all on such hosts, skip the legacy 256GiB floor for the
+high IO region when the high regions cannot fit there, placing them
+right above RAM instead. !highmem keeps the floor since disabling the
+regions is the point of that option.
+
+Accordingly, highmem-mmio-size now accepts any power of 2 down to 1GiB
+instead of rejecting values below the 512GiB default.
+
+Assisted-by: Claude:claude-fable-5
+---
+ docs/system/arm/virt.rst | 7 ++-
+ hw/arm/virt.c | 95 +++++++++++++++++++++++++++++++++++++---
+ 2 files changed, 94 insertions(+), 8 deletions(-)
+
+diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
+index 6a719b9586..ad054d4fed 100644
+--- a/docs/system/arm/virt.rst
++++ b/docs/system/arm/virt.rst
+@@ -145,8 +145,11 @@ highmem-mmio
+ The default is ``on``.
+
+ highmem-mmio-size
+- Set the high memory region size for PCI MMIO. Must be a power of 2 and
+- greater than or equal to the default size (512G).
++ Set the high memory region size for PCI MMIO. Must be a power of 2 and at
++ least 1G. The default is 512G. If the requested window does not fit in the
++ guest physical address space, it is shrunk to the largest power of 2 that
++ does (but no smaller than 1G) and a warning is emitted; if even that does
++ not fit, the window is disabled.
+
+ gic-version
+ Specify the version of the Generic Interrupt Controller (GIC) to provide.
+diff --git a/hw/arm/virt.c b/hw/arm/virt.c
+index 22ff33a33f..3314fcc791 100644
+--- a/hw/arm/virt.c
++++ b/hw/arm/virt.c
+@@ -197,6 +197,8 @@ static const MemMapEntry base_memmap[] = {
+ /* Update the docs for highmem-mmio-size when changing this default */
+ #define DEFAULT_HIGH_PCIE_MMIO_SIZE_GB 512
+ #define DEFAULT_HIGH_PCIE_MMIO_SIZE (DEFAULT_HIGH_PCIE_MMIO_SIZE_GB * GiB)
++/* Smallest window we will auto-shrink to, or accept from the user */
++#define VIRT_HIGH_PCIE_MMIO_MIN_SIZE (1 * GiB)
+
+ /*
+ * Highmem IO Regions: This memory map is floating, located after the RAM.
+@@ -1812,6 +1814,40 @@ static inline bool *virt_get_high_memmap_enabled(VirtMachineState *vms,
+ return enabled_array[index - VIRT_LOWMEMMAP_LAST];
+ }
+
++static inline const char *virt_high_memmap_name(int index)
++{
++ static const char * const names[] = {
++ "GIC redistributor",
++ "PCIe ECAM",
++ "PCIe MMIO",
++ };
++
++ assert(ARRAY_SIZE(extended_memmap) - VIRT_LOWMEMMAP_LAST ==
++ ARRAY_SIZE(names));
++ assert(index - VIRT_LOWMEMMAP_LAST < ARRAY_SIZE(names));
++
++ return names[index - VIRT_LOWMEMMAP_LAST];
++}
++
++/*
++ * Return the first address above the high memmap if it were laid out
++ * starting at @base, assuming every region fits at full size. Mirrors the
++ * placement rules of virt_set_high_memmap().
++ */
++static hwaddr virt_high_memmap_end(VirtMachineState *vms, hwaddr base)
++{
++ int i;
++
++ for (i = VIRT_LOWMEMMAP_LAST; i < ARRAY_SIZE(extended_memmap); i++) {
++ if (vms->highmem_compact && !*virt_get_high_memmap_enabled(vms, i)) {
++ continue;
++ }
++ base = ROUND_UP(base, extended_memmap[i].size) + extended_memmap[i].size;
++ }
++
++ return base;
++}
++
+ static void virt_set_high_memmap(VirtMachineState *vms,
+ hwaddr base, int pa_bits)
+ {
+@@ -1824,6 +1860,33 @@ static void virt_set_high_memmap(VirtMachineState *vms,
+ region_base = ROUND_UP(base, extended_memmap[i].size);
+ region_size = extended_memmap[i].size;
+
++ /*
++ * The high PCIe MMIO window is the only configurable high region
++ * and by far the largest. If it doesn't fit (e.g. in a 36-bit PA
++ * space), shrink it to the largest power of two that does rather
++ * than dropping it: without it, no 64-bit BAR too large for the
++ * 32-bit window can ever be placed.
++ */
++ if (i == VIRT_HIGH_PCIE_MMIO && *region_enabled && vms->highmem) {
++ while (region_size > VIRT_HIGH_PCIE_MMIO_MIN_SIZE &&
++ region_base + region_size > BIT_ULL(pa_bits)) {
++ region_size /= 2;
++ region_base = ROUND_UP(base, region_size);
++ }
++ if (region_base + region_size > BIT_ULL(pa_bits)) {
++ /* Not even the minimum fits; restore and disable below */
++ region_size = extended_memmap[i].size;
++ region_base = ROUND_UP(base, region_size);
++ } else if (region_size != extended_memmap[i].size) {
++ g_autofree char *from = size_to_str(extended_memmap[i].size);
++ g_autofree char *to = size_to_str(region_size);
++
++ warn_report("high PCIe MMIO window shrunk from %s to %s to fit "
++ "in a %d-bit physical address space", from, to,
++ pa_bits);
++ }
++ }
++
+ vms->memmap[i].base = region_base;
+ vms->memmap[i].size = region_size;
+
+@@ -1836,6 +1899,12 @@ static void virt_set_high_memmap(VirtMachineState *vms,
+ * For each device that doesn't fit, disable it.
+ */
+ fits = (region_base + region_size) <= BIT_ULL(pa_bits);
++ /* !highmem disables these on purpose, so keep quiet about it */
++ if (*region_enabled && !fits && vms->highmem) {
++ warn_report("high %s region does not fit in a %d-bit physical "
++ "address space and has been disabled",
++ virt_high_memmap_name(i), pa_bits);
++ }
+ *region_enabled &= fits;
+ if (vms->highmem_compact && !*region_enabled) {
+ continue;
+@@ -1851,7 +1920,7 @@ static void virt_set_high_memmap(VirtMachineState *vms,
+ static void virt_set_memmap(VirtMachineState *vms, int pa_bits)
+ {
+ MachineState *ms = MACHINE(vms);
+- hwaddr base, device_memory_base, device_memory_size, memtop;
++ hwaddr base, device_memory_base, device_memory_size, memtop, legacy_base;
+ int i;
+
+ vms->memmap = extended_memmap;
+@@ -1900,8 +1969,18 @@ static void virt_set_memmap(VirtMachineState *vms, int pa_bits)
+ error_report("maxmem/slots too huge");
+ exit(EXIT_FAILURE);
+ }
+- if (base < vms->memmap[VIRT_MEM].base + LEGACY_RAMLIMIT_BYTES) {
+- base = vms->memmap[VIRT_MEM].base + LEGACY_RAMLIMIT_BYTES;
++ /*
++ * Pin the high IO region at 256GiB so a VM with less than 255GiB of
++ * RAM keeps the legacy memory map. Skip that floor when the high
++ * regions cannot fit there in the PA space, as they would all be
++ * disabled and the guest left with no 64-bit MMIO window. !highmem
++ * keeps the floor: disabling them is the point of that option.
++ */
++ legacy_base = vms->memmap[VIRT_MEM].base + LEGACY_RAMLIMIT_BYTES;
++ if (base < legacy_base &&
++ (!vms->highmem ||
++ virt_high_memmap_end(vms, legacy_base) <= BIT_ULL(pa_bits))) {
++ base = legacy_base;
+ }
+
+ /* We know for sure that at least the memory fits in the PA space */
+@@ -2594,10 +2673,14 @@ static void virt_set_highmem_mmio_size(Object *obj, Visitor *v,
+ return;
+ }
+
+- if (size < DEFAULT_HIGH_PCIE_MMIO_SIZE) {
+- char *sz = size_to_str(DEFAULT_HIGH_PCIE_MMIO_SIZE);
++ /*
++ * Windows smaller than the default are allowed: a host with a small
++ * PA space cannot fit the default anywhere.
++ */
++ if (size < VIRT_HIGH_PCIE_MMIO_MIN_SIZE) {
++ char *sz = size_to_str(VIRT_HIGH_PCIE_MMIO_MIN_SIZE);
+ error_setg(errp, "highmem-mmio-size cannot be set to a lower value "
+- "than the default (%s)", sz);
++ "than %s", sz);
+ g_free(sz);
+ return;
+ }
+--
+2.41.0
+
diff --git a/patches/sources b/patches/sources
index 6f183033e2..0b77553359 100644
--- a/patches/sources
+++ b/patches/sources
@@ -53,7 +53,7 @@ MOLTENVK_REPO="https://github.com/utmapp/MoltenVK.git"
MOLTENVK_COMMIT="ef1c5461774f5fbd224ddcfd91fd2c0ea23f0384"
LLVM15_SRC="https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.7/llvm-project-15.0.7.src.tar.xz"
DXMT_REPO="https://github.com/utmapp/dxmt.git"
-DXMT_COMMIT="be80e14c07613cd558036a576b82dc6d78acdfce"
+DXMT_COMMIT="822ae637a39512ddbd8e0bbd7744af514670c9d3"
D3DMETAL_REPO="https://github.com/utmapp/d3dmetal-native.git"
D3DMETAL_COMMIT="edd2e386c25a2039eca0f6ce8f794b3b165841eb"
diff --git a/scripts/build_dependencies.sh b/scripts/build_dependencies.sh
index 2cfedfbfc2..417721dad2 100755
--- a/scripts/build_dependencies.sh
+++ b/scripts/build_dependencies.sh
@@ -21,8 +21,8 @@ RED='\033[0;31m'
NC='\033[0m'
# Knobs
-IOS_SDKMINVER="16.0"
-MAC_SDKMINVER="13.0"
+IOS_SDKMINVER="14.0"
+MAC_SDKMINVER="11.0"
VISIONOS_SDKMINVER="1.0"
# Network operations are retried because concurrent builds on the same CI runner
# get rate limited by GitHub and fail to clone/fetch.
@@ -301,6 +301,26 @@ generate_meson_cross() {
else
echo "system = '$system'" >> $cross
fi
+ if [ "$system" == "darwin" ]; then
+ echo "kernel = 'xnu'" >> $cross
+ case $PLATFORM in
+ ios_simulator* )
+ echo "subsystem = 'ios-simulator'" >> $cross
+ ;;
+ ios* )
+ echo "subsystem = 'ios'" >> $cross
+ ;;
+ visionos_simulator* )
+ echo "subsystem = 'visionos-simulator'" >> $cross
+ ;;
+ visionos* )
+ echo "subsystem = 'visionos'" >> $cross
+ ;;
+ macos )
+ echo "subsystem = 'macos'" >> $cross
+ ;;
+ esac
+ fi
case "$ARCH" in
armv7 | armv7s )
echo "cpu_family = 'arm'" >> $cross
@@ -592,7 +612,7 @@ meson_cross_build () {
SRCDIR="$BUILD_DIR/$NAME"
;;
esac
- MESON_CROSS="$(realpath "$BUILD_DIR")/meson-$CROSS.cross"
+ MESON_CROSS="$(realpath "$BUILD_DIR")/meson-$CROSS$MESON_CROSS_SUFFIX.cross"
if [ ! -f "$MESON_CROSS" ]; then
generate_meson_cross "$MESON_CROSS" "$CROSS"
fi
@@ -625,6 +645,19 @@ meson_darwin_build () {
meson_cross_build darwin $@
}
+# The generated toolchain file is the single source of truth for CMake builds:
+# it sets every compiler, binutil, and flag variable with CACHE FORCE. The
+# exported CC/CFLAGS/... are needed by the autotools and meson builds, but for
+# CMake they are redundant *and* harmful: a nested host configure that does not
+# get the toolchain file (such as LLVM's NATIVE sub-build for llvm-tblgen)
+# inherits them from the environment and ends up compiling for the target while
+# discovering and linking host libraries. Drop them for every cmake invocation.
+cmake_clean_env () {
+ env -u CC -u CPP -u CXX -u OBJCC -u LD -u AR -u NM -u RANLIB -u STRIP \
+ -u CFLAGS -u CPPFLAGS -u CXXFLAGS -u OBJCFLAGS -u LDFLAGS \
+ cmake "$@"
+}
+
cmake_build () {
SRCDIR="$1"
shift 1
@@ -650,7 +683,7 @@ cmake_build () {
mkdir -p "$BUILDDIR"
echo "${GREEN}Configuring ${NAME}...${NC}"
- cmake -S . -B "$BUILDDIR" \
+ cmake_clean_env -S . -B "$BUILDDIR" \
-DCMAKE_INSTALL_PREFIX="$PREFIX" \
-DCMAKE_BUILD_TYPE="$BUILD_CONFIGURATION" \
-DCMAKE_TOOLCHAIN_FILE="$CMAKE_TOOLCHAIN" \
@@ -658,10 +691,10 @@ cmake_build () {
fi
echo "${GREEN}Building ${NAME}...${NC}"
- cmake --build "$BUILDDIR" --parallel "$NCPU"
+ cmake_clean_env --build "$BUILDDIR" --parallel "$NCPU"
echo "${GREEN}Installing ${NAME}...${NC}"
- cmake --install "$BUILDDIR"
+ cmake_clean_env --install "$BUILDDIR"
cd "$pwd"
}
@@ -679,9 +712,9 @@ build_angle () {
WEBCORE_LIBRARY_DIR="/usr/local/lib" \
NORMAL_UMBRELLA_FRAMEWORKS_DIR="" \
CODE_SIGNING_ALLOWED=NO \
- IPHONEOS_DEPLOYMENT_TARGET="14.0" \
- MACOSX_DEPLOYMENT_TARGET="11.0" \
- XROS_DEPLOYMENT_TARGET="1.0"
+ IPHONEOS_DEPLOYMENT_TARGET="$IOS_SDKMINVER" \
+ MACOSX_DEPLOYMENT_TARGET="$MAC_SDKMINVER" \
+ XROS_DEPLOYMENT_TARGET="$VISIONOS_SDKMINVER"
rsync -a "ANGLE.xcarchive/Products/usr/local/lib/" "$PREFIX/lib"
rsync -a "include/" "$PREFIX/include"
cd "$pwd"
@@ -843,8 +876,28 @@ build_vulkan_drivers () {
build_d3d_drivers () {
LLVM15_NAME=$(basename "${LLVM15_SRC%.tar.*}")
cmake_build "$BUILD_DIR/$LLVM15_NAME/llvm" -DLLVM_ENABLE_ZSTD=Off -DLLVM_TARGETS_TO_BUILD="" -DLLVM_BUILD_TOOLS=Off -DLLVM_VERSION_PRINTER_SHOW_HOST_TARGET_INFO=Off
- meson_build $DXMT_REPO -Dnative_llvm_path="$PREFIX"
- if [ "$ARCH" == "x86_64" ]; then
+ (
+ case $PLATFORM in
+ ios* )
+ DXMT_SDKMINVER="16.0"
+ ;;
+ macos )
+ DXMT_SDKMINVER="13.0"
+ ;;
+ * )
+ DXMT_SDKMINVER="$SDKMINVER"
+ ;;
+ esac
+ DXMT_CFLAGS_TARGET="${CFLAGS_TARGET/$SDKMINVER/$DXMT_SDKMINVER}"
+ CC="${CC/$CFLAGS_TARGET/$DXMT_CFLAGS_TARGET}"
+ CPPFLAGS="${CPPFLAGS/$CFLAGS_TARGET/$DXMT_CFLAGS_TARGET}"
+ CXXFLAGS="${CXXFLAGS/$CFLAGS_TARGET/$DXMT_CFLAGS_TARGET}"
+ OBJCFLAGS="${OBJCFLAGS/$CFLAGS_TARGET/$DXMT_CFLAGS_TARGET}"
+ LDFLAGS="${LDFLAGS/$CFLAGS_TARGET/$DXMT_CFLAGS_TARGET}"
+ MESON_CROSS_SUFFIX="-dxmt"
+ meson_darwin_build $DXMT_REPO -Dnative_llvm_path="$PREFIX"
+ )
+ if [ "$ARCH" == "x86_64" -a "$PLATFORM" == "macos" ]; then
meson_build $D3DMETAL_REPO -Dtests=disabled
else
# empty placeholder file
@@ -893,9 +946,11 @@ fixup_dylib () {
mkdir -p "$FRAMEWORKPATH"
mkdir -p "$INFOPATH"
cp -a "$FILE" "$NEWFILE"
+ MINOSVER=$(vtool -show-build-version "$FILE" 2>/dev/null | awk '/minos/ {print $2; exit}')
+ [ -n "$MINOSVER" ] || MINOSVER="$SDKMINVER"
/usr/libexec/PlistBuddy -c "Add :CFBundleExecutable string $LIBNAME" "$INFOPATH/Info.plist" || true
/usr/libexec/PlistBuddy -c "Add :CFBundleIdentifier string $BUNDLE_ID" "$INFOPATH/Info.plist" || true
- /usr/libexec/PlistBuddy -c "Add :MinimumOSVersion string $SDKMINVER" "$INFOPATH/Info.plist" || true
+ /usr/libexec/PlistBuddy -c "Add :MinimumOSVersion string $MINOSVER" "$INFOPATH/Info.plist" || true
/usr/libexec/PlistBuddy -c "Add :CFBundleVersion string 1" "$INFOPATH/Info.plist" || true
/usr/libexec/PlistBuddy -c "Add :CFBundleShortVersionString string 1.0" "$INFOPATH/Info.plist" || true
if [ "$PLATFORM" == "macos" ]; then
@@ -1046,7 +1101,7 @@ ios* | visionos* )
PLATFORM_FAMILY_NAME="$PLATFORM_FAMILY_PREFIX"
;;
esac
- QEMU_PLATFORM_BUILD_FLAGS="--enable-shared-lib --disable-cocoa --disable-coreaudio --disable-slirp-smbd --enable-ucontext --with-coroutine=libucontext $HVF_FLAGS $TCI_BUILD_FLAGS"
+ QEMU_PLATFORM_BUILD_FLAGS="--enable-shared-lib --disable-cocoa --disable-sdl --disable-coreaudio --disable-slirp-smbd --enable-ucontext --with-coroutine=libucontext $HVF_FLAGS $TCI_BUILD_FLAGS"
;;
macos )
if [ -z "$SDKMINVER" ]; then
@@ -1055,7 +1110,7 @@ macos )
SDK=macosx
CFLAGS_TARGET="-target $ARCH-apple-macos$SDKMINVER"
PLATFORM_FAMILY_NAME="macOS"
- QEMU_PLATFORM_BUILD_FLAGS="--enable-shared-lib --disable-cocoa --cpu=$CPU"
+ QEMU_PLATFORM_BUILD_FLAGS="--enable-shared-lib --disable-cocoa --disable-sdl --cpu=$CPU"
;;
* )
usage
@@ -1176,9 +1231,7 @@ build_qemu_dependencies
build $QEMU_DIR --cross-prefix="" $QEMU_PLATFORM_BUILD_FLAGS $QEMU_DEBUG_FLAGS
build_spice_client
build_vulkan_drivers
-if [ "$PLATFORM" == "macos" ]; then
- build_d3d_drivers
-fi
+build_d3d_drivers
fixup_all
remove_shared_gst_plugins # another hack...
echo "${GREEN}All done!${NC}"