diff --git a/packages/vulkan-wrapper-android/0000-disable-android-detection.patch b/packages/vulkan-wrapper-android/0000-disable-android-detection.patch new file mode 100644 index 00000000000..9b09c16b899 --- /dev/null +++ b/packages/vulkan-wrapper-android/0000-disable-android-detection.patch @@ -0,0 +1,13 @@ +diff --git a/src/util/detect_os.h b/src/util/detect_os.h +index 86286dfbe70..f589104f6a7 100644 +--- a/src/util/detect_os.h ++++ b/src/util/detect_os.h +@@ -24,7 +24,7 @@ + * Android defines __linux__, so DETECT_OS_LINUX and DETECT_OS_POSIX will + * also be defined. + */ +-#if defined(__ANDROID__) ++#if 0 + #define DETECT_OS_ANDROID 1 + #endif + diff --git a/packages/vulkan-wrapper-android/0001-fix-for-anon-file.patch b/packages/vulkan-wrapper-android/0001-fix-for-anon-file.patch new file mode 100644 index 00000000000..10ba5ff54fc --- /dev/null +++ b/packages/vulkan-wrapper-android/0001-fix-for-anon-file.patch @@ -0,0 +1,32 @@ +Fallback to `@TERMUX_PREFIX@/tmp` if env `XDG_RUNTIME_DIR` is not set. + +--- a/src/util/anon_file.c ++++ b/src/util/anon_file.c +@@ -136,6 +136,11 @@ + char *name; + + path = getenv("XDG_RUNTIME_DIR"); ++#ifdef __TERMUX__ ++ if (!path) { ++ path = "@TERMUX_PREFIX@/tmp"; ++ } ++#endif + if (!path) { + errno = ENOENT; + return -1; +diff --git a/meson.build b/meson.build +index b9edca30189..dbede3ca76a 100644 +--- a/meson.build ++++ b/meson.build +@@ -1376,11 +1376,9 @@ endforeach + functions_to_detect = { + 'strtof': '', + 'mkostemp': '', +- 'memfd_create': '', + 'random_r': '', + 'flock': '', + 'strtok_r': '', +- 'getrandom': '', + 'qsort_s': '', + 'posix_fallocate': '', + 'secure_getenv': '', diff --git a/packages/vulkan-wrapper-android/0002-wsi-no-pthread_cancel.patch b/packages/vulkan-wrapper-android/0002-wsi-no-pthread_cancel.patch new file mode 100644 index 00000000000..2f5b63fe891 --- /dev/null +++ b/packages/vulkan-wrapper-android/0002-wsi-no-pthread_cancel.patch @@ -0,0 +1,85 @@ ++++ ./src/vulkan/wsi/wsi_common_display.c +@@ -176,6 +176,12 @@ + + static uint64_t fence_sequence; + ++#ifdef __ANDROID__ ++static void thread_signal_handler (int signum) { ++ pthread_exit (0); ++} ++#endif ++ + ICD_DEFINE_NONDISP_HANDLE_CASTS(wsi_display_mode, VkDisplayModeKHR) + ICD_DEFINE_NONDISP_HANDLE_CASTS(wsi_display_connector, VkDisplayKHR) + +@@ -1341,7 +1347,9 @@ + .events = POLLIN + }; + ++#ifndef __ANDROID__ + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); ++#endif + for (;;) { + int ret = poll(&pollfd, 1, -1); + if (ret > 0) { +@@ -1369,9 +1377,22 @@ + static void + wsi_display_stop_wait_thread(struct wsi_display *wsi) + { ++#ifdef __ANDROID__ ++ struct sigaction actions; ++ memset (&actions, 0, sizeof (actions)); ++ sigemptyset (&actions.sa_mask); ++ actions.sa_flags = 0; ++ actions.sa_handler = thread_signal_handler; ++ sigaction (SIGUSR2, &actions, NULL); ++#endif ++ + mtx_lock(&wsi->wait_mutex); + if (wsi->wait_thread) { ++#ifndef __ANDROID__ + pthread_cancel(wsi->wait_thread); ++#else ++ pthread_kill(wsi->wait_thread, SIGUSR2); ++#endif + pthread_join(wsi->wait_thread, NULL); + wsi->wait_thread = 0; + } +@@ -2215,7 +2236,9 @@ + + int udev_fd = udev_monitor_get_fd(mon); + ++#ifndef __ANDROID__ + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); ++#endif + + for (;;) { + nfds_t nfds = 1; +@@ -2340,6 +2363,15 @@ + struct wsi_display *wsi = + (struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY]; + ++#ifdef __ANDROID__ ++ struct sigaction actions; ++ memset (&actions, 0, sizeof (actions)); ++ sigemptyset (&actions.sa_mask); ++ actions.sa_flags = 0; ++ actions.sa_handler = thread_signal_handler; ++ sigaction (SIGUSR2, &actions, NULL); ++#endif ++ + if (wsi) { + wsi_for_each_connector(connector, wsi) { + wsi_for_each_display_mode(mode, connector) { +@@ -2351,7 +2383,11 @@ + wsi_display_stop_wait_thread(wsi); + + if (wsi->hotplug_thread) { ++#ifndef __ANDROID__ + pthread_cancel(wsi->hotplug_thread); ++#else ++ pthread_kill(wsi->hotplug_thread, SIGUSR2); ++#endif + pthread_join(wsi->hotplug_thread, NULL); + } + diff --git a/packages/vulkan-wrapper-android/0003-vulkan-x11-disable-immediate-mode.patch b/packages/vulkan-wrapper-android/0003-vulkan-x11-disable-immediate-mode.patch new file mode 100644 index 00000000000..1d0ec0b0676 --- /dev/null +++ b/packages/vulkan-wrapper-android/0003-vulkan-x11-disable-immediate-mode.patch @@ -0,0 +1,14 @@ +diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c +index 22ac573cca2..9e0eb25f45f 100644 +--- a/src/vulkan/wsi/wsi_common_x11.c ++++ b/src/vulkan/wsi/wsi_common_x11.c +@@ -462,7 +462,9 @@ static const VkFormat formats[] = { + }; + + static const VkPresentModeKHR present_modes[] = { ++#ifndef __TERMUX__ + VK_PRESENT_MODE_IMMEDIATE_KHR, ++#endif + VK_PRESENT_MODE_MAILBOX_KHR, + VK_PRESENT_MODE_FIFO_KHR, + VK_PRESENT_MODE_FIFO_RELAXED_KHR, diff --git a/packages/vulkan-wrapper-android/0004-fix-physical-device-enumeration-for-PowerVR-GPUs.patch b/packages/vulkan-wrapper-android/0004-fix-physical-device-enumeration-for-PowerVR-GPUs.patch new file mode 100644 index 00000000000..bb0c0a5bbf1 --- /dev/null +++ b/packages/vulkan-wrapper-android/0004-fix-physical-device-enumeration-for-PowerVR-GPUs.patch @@ -0,0 +1,91 @@ +From 25f05c8e6fffdaa65a1d90668ea6f08fe48a8341 Mon Sep 17 00:00:00 2001 +From: Nikos F +Date: Sat, 31 Jan 2026 17:18:52 +0200 +Subject: [PATCH] Fix powervr gpus - namely the DXT-48 of pixel 10 line it had + a nullptr and it segfaulted if the wrapper just allocated statically a 16 + empty array on physical_devices + +also add some logging +--- + src/vulkan/wrapper/wrapper_physical_device.c | 59 ++++++++++++++++++-- + 1 file changed, 55 insertions(+), 4 deletions(-) + +diff --git a/src/vulkan/wrapper/wrapper_physical_device.c b/src/vulkan/wrapper/wrapper_physical_device.c +index 56a18847154..39bcfdd49be 100644 +--- a/src/vulkan/wrapper/wrapper_physical_device.c ++++ b/src/vulkan/wrapper/wrapper_physical_device.c +@@ -70,16 +70,67 @@ wrapper_wsi_proc_addr(VkPhysicalDevice physicalDevice, const char *pName) + + VkResult enumerate_physical_device(struct vk_instance *_instance) + { +- struct wrapper_instance *instance = (struct wrapper_instance *)_instance; +- VkPhysicalDevice physical_devices[16]; +- uint32_t physical_device_count = 16; ++ struct wrapper_instance *instance = container_of(_instance, struct wrapper_instance, vk); ++ VkPhysicalDevice *physical_devices = NULL; /* Will be allocated after we know the count */ ++ uint32_t physical_device_count = 0; /* Will be set after first call */ + VkResult result; + ++ /* Direct output to make sure we can see this */ ++ fprintf(stderr, "WRAPPER: Entering enumerate_physical_device function\n"); ++ fflush(stderr); ++ ++ if (!instance->dispatch_table.EnumeratePhysicalDevices) { ++ free(physical_devices); /* This will be safe since physical_devices is NULL at this point */ ++ return VK_ERROR_INITIALIZATION_FAILED; ++ } ++ ++ /* First call with NULL to get the actual count */ ++ uint32_t actual_count = 0; ++ result = instance->dispatch_table.EnumeratePhysicalDevices( ++ instance->dispatch_handle, &actual_count, NULL); ++ ++ if (result != VK_SUCCESS && result != VK_INCOMPLETE) { ++ free(physical_devices); /* This will be safe since physical_devices is NULL at this point */ ++ return result; ++ } ++ ++ /* Allocate the physical devices array based on the actual count */ ++ if (actual_count > 0) { ++ physical_devices = malloc(sizeof(VkPhysicalDevice) * actual_count); ++ if (!physical_devices) { ++ return VK_ERROR_OUT_OF_HOST_MEMORY; ++ } ++ physical_device_count = actual_count; ++ } ++ ++ /* Direct output before the call that crashes */ ++ fprintf(stderr, "WRAPPER: About to call EnumeratePhysicalDevices\n"); ++ fflush(stderr); ++ + result = instance->dispatch_table.EnumeratePhysicalDevices( + instance->dispatch_handle, &physical_device_count, physical_devices); + +- if (result != VK_SUCCESS) ++ if (result == VK_INCOMPLETE) { ++ /* Try again with a larger count if we got VK_INCOMPLETE */ ++ uint32_t larger_count = physical_device_count * 2; ++ ++ /* Reallocate the array with the larger size */ ++ VkPhysicalDevice *larger_array = realloc(physical_devices, sizeof(VkPhysicalDevice) * larger_count); ++ if (!larger_array) { ++ free(physical_devices); ++ return VK_ERROR_OUT_OF_HOST_MEMORY; ++ } ++ physical_devices = larger_array; ++ physical_device_count = larger_count; ++ ++ result = instance->dispatch_table.EnumeratePhysicalDevices( ++ instance->dispatch_handle, &physical_device_count, physical_devices); ++ } ++ ++ if (result != VK_SUCCESS) { ++ free(physical_devices); + return result; ++ } + + for (int i = 0; i < physical_device_count; i++) { + PFN_vkGetInstanceProcAddr get_instance_proc_addr; +-- +2.47.3 + diff --git a/packages/vulkan-wrapper-android/build.sh b/packages/vulkan-wrapper-android/build.sh new file mode 100644 index 00000000000..53c3146c7d3 --- /dev/null +++ b/packages/vulkan-wrapper-android/build.sh @@ -0,0 +1,59 @@ +TERMUX_PKG_HOMEPAGE=https://www.mesa3d.org +TERMUX_PKG_DESCRIPTION="Android Vulkan ICD" +TERMUX_PKG_LICENSE="MIT" +TERMUX_PKG_LICENSE_FILE="docs/license.rst" +TERMUX_PKG_MAINTAINER="xMeM " +TERMUX_PKG_VERSION="25.0.0" +TERMUX_PKG_SRCURL=git+https://github.com/xMeM/mesa +TERMUX_PKG_GIT_BRANCH=wrapper +_COMMIT=e65c7eb6ee2f9903c3256f2677beb1d98464103f +TERMUX_PKG_DEPENDS="libandroid-shmem, libc++, libdrm, libx11, libxcb, libxshmfence, libwayland, vulkan-loader-generic, zlib, zstd" +TERMUX_PKG_BUILD_DEPENDS="libwayland-protocols, libxrandr, xorgproto" +TERMUX_PKG_API_LEVEL=26 + +TERMUX_PKG_EXTRA_CONFIGURE_ARGS=" +--cmake-prefix-path $TERMUX_PREFIX +-Dcpp_rtti=false +-Dgbm=disabled +-Dopengl=false +-Dllvm=disabled +-Dshared-llvm=disabled +-Dplatforms=x11 +-Dgallium-drivers= +-Dxmlconfig=disabled +-Dvulkan-drivers=wrapper +-Db_ndebug=true +" + +termux_step_post_get_source() { + git fetch --unshallow + git checkout $_COMMIT + # Do not use meson wrap projects + rm -rf subprojects +} + +termux_step_pre_configure() { + termux_setup_cmake + + if [ "$TERMUX_ON_DEVICE_BUILD" = "true" ]; then + CFLAGS+=" --target=$TERMUX_HOST_PLATFORM$TERMUX_PKG_API_LEVEL" + fi + + CPPFLAGS+=" -D__USE_GNU" + LDFLAGS+=" -landroid-shmem" + + _WRAPPER_BIN=$TERMUX_PKG_BUILDDIR/_wrapper/bin + mkdir -p $_WRAPPER_BIN + if [ "$TERMUX_ON_DEVICE_BUILD" = "false" ]; then + sed 's|@CMAKE@|'"$(command -v cmake)"'|g' \ + $TERMUX_PKG_BUILDER_DIR/cmake-wrapper.in \ + > $_WRAPPER_BIN/cmake + chmod 0700 $_WRAPPER_BIN/cmake + termux_setup_wayland_cross_pkg_config_wrapper + fi + export PATH=$_WRAPPER_BIN:$PATH +} + +termux_step_post_configure() { + rm -f $_WRAPPER_BIN/cmake +} diff --git a/packages/vulkan-wrapper-android/cmake-wrapper.in b/packages/vulkan-wrapper-android/cmake-wrapper.in new file mode 100644 index 00000000000..7cd20167cc8 --- /dev/null +++ b/packages/vulkan-wrapper-android/cmake-wrapper.in @@ -0,0 +1,16 @@ +#!/bin/sh + +if [ -e CMakeLists.txt ]; then + sed -i '1s|^|project(foo LANGUAGES C CXX)\n|' CMakeLists.txt +fi + +for f in "$@"; do + case "${f}" in + -DCMAKE_TOOLCHAIN_FILE=* ) + sed -i "${f#-DCMAKE_TOOLCHAIN_FILE=}" \ + -e 's|\(set(CMAKE_SYSTEM_NAME\) "Android")|\1 "Linux")|g' + ;; + esac +done + +exec @CMAKE@ "$@"