From 2a01c354c1d1c45a1aa45eb103d942ef048693bd Mon Sep 17 00:00:00 2001 From: schm1dtmac Date: Fri, 23 Oct 2026 17:13:39 +0100 Subject: [PATCH] [Mac OS X] Add KosmicKrisp driver with arm64 builds --- .ci/build-mac.sh | 15 ++++++++++++--- .ci/deploy-mac.sh | 10 ++++++++++ .github/workflows/rpcs3.yml | 2 +- rpcs3/Emu/RSX/VK/VKCompute.cpp | 1 + rpcs3/Emu/RSX/VK/VKHelpers.cpp | 3 +++ rpcs3/Emu/RSX/VK/VKRenderTargets.h | 1 + rpcs3/Emu/RSX/VK/VulkanAPI.h | 4 ++++ rpcs3/Emu/RSX/VK/vkutils/chip_class.h | 1 + rpcs3/Emu/RSX/VK/vkutils/device.cpp | 27 +++++++++++++++++++++------ 9 files changed, 54 insertions(+), 10 deletions(-) diff --git a/.ci/build-mac.sh b/.ci/build-mac.sh index ed8788cce5..eb60ec6fd5 100755 --- a/.ci/build-mac.sh +++ b/.ci/build-mac.sh @@ -9,6 +9,18 @@ AVVER="${COMM_TAG}-${COMM_COUNT}" export LVER="${COMM_TAG}-${COMM_COUNT}-${COMM_HASH}" echo "AVVER=$AVVER" >> .ci/ci-vars.env +# Due to issues with getting this running under MacPorts, I'm reluctantly going to let this depend on brew for now. +if [ "$(arch)" = "arm64" ]; then + git clone https://gitlab.freedesktop.org/mesa/mesa.git kosmickrisp; cd kosmickrisp + brew install meson spirv-llvm-translator spirv-tools + pip3 install mako packaging pyyaml --break-system-packages + export PATH_OLD="$PATH" + export PATH="/opt/homebrew/opt/llvm/bin:$PATH" + meson setup build --prefix=/opt/homebrew --buildtype=release -Dplatforms=macos -Dvulkan-drivers=kosmickrisp -Dgallium-drivers= -Dopengl=false -Dzstd=disabled + ninja -C build; cd ../ + export PATH="$PATH_OLD" +fi + # Clang depends on LLVM_COMPILER_VER so it needs to be installed here. sudo port install "clang-$LLVM_COMPILER_VER" @@ -53,9 +65,6 @@ export LLVM_DIR="/opt/local/libexec/llvm-$LLVM_COMPILER_VER" git submodule -q update --init --depth=1 --jobs=8 $(awk '/path/ && !/llvm/ && !/libsdl-org/ && !/feralinteractive/ && !/curl/ && !/zlib/ { print $3 }' .gitmodules) mkdir build && cd build || exit 1 -# The below should be uncommented once bugs with Qt 6 QListWidgets when using the OS 26 visual style are resolved. -# sudo xcode-select -switch /Applications/Xcode_26.3.app/Contents/Developer - cmake .. \ -DBUILD_RPCS3_TESTS="${RUN_UNIT_TESTS}" \ -DRUN_RPCS3_TESTS="${RUN_UNIT_TESTS}" \ diff --git a/.ci/deploy-mac.sh b/.ci/deploy-mac.sh index a984a18503..2b344489f8 100755 --- a/.ci/deploy-mac.sh +++ b/.ci/deploy-mac.sh @@ -5,11 +5,21 @@ cd build || exit 1 cd bin mkdir -p "rpcs3.app/Contents/Resources/vulkan/icd.d" || true + +# Install the MoltenVK ICD wget https://github.com/KhronosGroup/MoltenVK/releases/download/v1.4.2/MoltenVK-macos-privateapi.tar tar -xvf MoltenVK-macos-privateapi.tar cp "MoltenVK/MoltenVK/dynamic/dylib/macOS/libMoltenVK.dylib" "rpcs3.app/Contents/Frameworks/libMoltenVK.dylib" cp "MoltenVK/MoltenVK/dynamic/dylib/macOS/MoltenVK_icd.json" "rpcs3.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json" sed -i '' "s/.\//..\/..\/..\/Frameworks\//g" "rpcs3.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json" +# And now let's install the KosmicKrisp ICD on aarch64 +if [ "$(arch)" = "arm64" ]; then + cp "$WORKDIR/kosmickrisp/build/src/kosmickrisp/vulkan/libvulkan_kosmickrisp.dylib" "rpcs3.app/Contents/Frameworks/libvulkan_kosmickrisp.dylib" + cp "$WORKDIR/kosmickrisp/build/src/kosmickrisp/vulkan/kosmickrisp_mesa_icd.aarch64.json" "rpcs3.app/Contents/Resources/vulkan/icd.d/kosmickrisp_mesa_icd.aarch64.json" + cp "$(realpath /opt/homebrew/lib/libSPIRV-Tools.dylib)" "rpcs3.app/Contents/Frameworks/libSPIRV-Tools.dylib" + install_name_tool -change "/opt/homebrew/opt/spirv-tools/lib/libSPIRV-Tools.dylib" "@rpath/libSPIRV-Tools.dylib" "rpcs3.app/Contents/Frameworks/libvulkan_kosmickrisp.dylib" + sed -i '' "s/\/opt\/homebrew\/lib\//..\/..\/..\/Frameworks\//g" "rpcs3.app/Contents/Resources/vulkan/icd.d/kosmickrisp_mesa_icd.aarch64.json" +fi rm -rf "rpcs3.app/Contents/Frameworks/QtPdf.framework" \ "rpcs3.app/Contents/Frameworks/QtQml.framework" \ diff --git a/.github/workflows/rpcs3.yml b/.github/workflows/rpcs3.yml index c637ea6f62..1132c9c61f 100644 --- a/.github/workflows/rpcs3.yml +++ b/.github/workflows/rpcs3.yml @@ -193,7 +193,7 @@ jobs: UPLOAD_COMMIT_HASH: 51ae32f468089a8169aaf1567de355ff4a3e0842 UPLOAD_REPO_FULL_NAME: rpcs3/rpcs3-binaries-mac - name: Apple Silicon - runs-on: macos-15 + runs-on: macos-26 UPLOAD_COMMIT_HASH: 8e21bdbc40711a3fccd18fbf17b742348b0f4281 UPLOAD_REPO_FULL_NAME: rpcs3/rpcs3-binaries-mac-arm64 name: RPCS3 Mac ${{ matrix.name }} diff --git a/rpcs3/Emu/RSX/VK/VKCompute.cpp b/rpcs3/Emu/RSX/VK/VKCompute.cpp index fe323dbdce..b7dd7950f1 100644 --- a/rpcs3/Emu/RSX/VK/VKCompute.cpp +++ b/rpcs3/Emu/RSX/VK/VKCompute.cpp @@ -77,6 +77,7 @@ namespace vk break; case vk::driver_vendor::MVK: case vk::driver_vendor::HONEYKRISP: + case vk::driver_vendor::KOSMICKRISP: unroll_loops = true; optimal_kernel_size = 1; optimal_group_size = 256; diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.cpp b/rpcs3/Emu/RSX/VK/VKHelpers.cpp index cfa8391c68..c72f9bc10c 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.cpp +++ b/rpcs3/Emu/RSX/VK/VKHelpers.cpp @@ -144,6 +144,9 @@ namespace vk case driver_vendor::HONEYKRISP: // Needs more testing break; + case driver_vendor::KOSMICKRISP: + // Needs more testing + break; case driver_vendor::PANVK: // Needs more testing break; diff --git a/rpcs3/Emu/RSX/VK/VKRenderTargets.h b/rpcs3/Emu/RSX/VK/VKRenderTargets.h index 2a8b935600..6de3e15a87 100644 --- a/rpcs3/Emu/RSX/VK/VKRenderTargets.h +++ b/rpcs3/Emu/RSX/VK/VKRenderTargets.h @@ -216,6 +216,7 @@ namespace vk case driver_vendor::LAVAPIPE: case driver_vendor::V3DV: case driver_vendor::HONEYKRISP: + case driver_vendor::KOSMICKRISP: case driver_vendor::PANVK: case driver_vendor::ARM_MALI: break; diff --git a/rpcs3/Emu/RSX/VK/VulkanAPI.h b/rpcs3/Emu/RSX/VK/VulkanAPI.h index 57e366c2a9..dfa8ff600c 100644 --- a/rpcs3/Emu/RSX/VK/VulkanAPI.h +++ b/rpcs3/Emu/RSX/VK/VulkanAPI.h @@ -40,6 +40,10 @@ constexpr VkDriverId VK_DRIVER_ID_MESA_HONEYKRISP = static_cast(26); #endif +#if VK_HEADER_VERSION < 287 +constexpr VkDriverId VK_DRIVER_ID_MESA_KOSMICKRISP = static_cast(28); +#endif + #if VK_HEADER_VERSION < 332 #define VK_EXT_shader_uniform_buffer_unsized_array 1 #define VK_EXT_SHADER_UNIFORM_BUFFER_UNSIZED_ARRAY_SPEC_VERSION 1 diff --git a/rpcs3/Emu/RSX/VK/vkutils/chip_class.h b/rpcs3/Emu/RSX/VK/vkutils/chip_class.h index 8472142eef..36db86de27 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/chip_class.h +++ b/rpcs3/Emu/RSX/VK/vkutils/chip_class.h @@ -56,6 +56,7 @@ namespace vk NVK, V3DV, HONEYKRISP, + KOSMICKRISP, PANVK, ARM_MALI, QUALCOMM, diff --git a/rpcs3/Emu/RSX/VK/vkutils/device.cpp b/rpcs3/Emu/RSX/VK/vkutils/device.cpp index 5926f89013..daf24d2ee2 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/device.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/device.cpp @@ -280,17 +280,24 @@ namespace vk std::string physical_device::get_name() const { +#ifdef __APPLE__ + // Both Apple drivers fail to include their names anywhere in the device name string, so we need to append the driver names here. + switch (get_driver_vendor()) + { + case driver_vendor::KOSMICKRISP: + return std::string(props.deviceName) + " (KosmicKrisp)"; + case driver_vendor::MVK: + return std::string(props.deviceName) + " (MoltenVK)"; + default: + break; + } +#endif + // Return the raw device name otherwise. return props.deviceName; } driver_vendor physical_device::get_driver_vendor() const { -#ifdef __APPLE__ - // moltenVK currently returns DRIVER_ID_MOLTENVK (0). - // For now, assume the vendor is moltenVK on Apple devices. - return driver_vendor::MVK; -#endif - if (!driver_properties.driverID) { const auto gpu_name = get_name(); @@ -341,7 +348,11 @@ namespace vk if (gpu_name.find("Apple") != umax) { +#ifdef __APPLE__ + return driver_vendor::KOSMICKRISP; +#else return driver_vendor::HONEYKRISP; +#endif } if (gpu_name.find("Panfrost") != umax) @@ -389,6 +400,8 @@ namespace vk return driver_vendor::V3DV; case VK_DRIVER_ID_MESA_HONEYKRISP: return driver_vendor::HONEYKRISP; + case VK_DRIVER_ID_MESA_KOSMICKRISP: + return driver_vendor::KOSMICKRISP; case VK_DRIVER_ID_MESA_PANVK: return driver_vendor::PANVK; case VK_DRIVER_ID_ARM_PROPRIETARY: @@ -397,6 +410,8 @@ namespace vk return driver_vendor::QUALCOMM; case VK_DRIVER_ID_MESA_TURNIP: return driver_vendor::TURNIP; + case VK_DRIVER_ID_MOLTENVK: + return driver_vendor::MVK; default: // Mobile? return driver_vendor::unknown;