Skip to content

Instantly share code, notes, and snippets.

@robertkirkman
Last active August 14, 2023 05:53
Show Gist options
  • Save robertkirkman/5054321db3d5082b2cc0251f4dd891b3 to your computer and use it in GitHub Desktop.
Save robertkirkman/5054321db3d5082b2cc0251f4dd891b3 to your computer and use it in GitHub Desktop.
How to Make a Mario Model on Android

How To Install Termux:X11, Zink, Turnip, n64decomp/sm64, Blender, Fast64, and AngelicMiracles' Definitive Template on Android

  • These steps use bleeding-edge code from August 2023 and will not keep working forever. The first breaking change most likely to stop these steps from working without a programmer updating them will be the release of LLVM 17.
  • Video Tutorial

Requirements:

  • ONLY aarch64 (64-bit ARM)
  • ONLY Qualcomm Adreno 6XX and 7XX series GPUs
  • Android 7+
  • 7.5 GB free space in device storage
  • NO PROOT, CHROOT OR ROOT REQUIRED
  1. Log into GitHub and download, extract and install the termux-x11-arm64-v8a-debug from the most recent artifact here.

termux-setup-storage
yes | pkg upgrade -y
pkg install x11-repo tur-repo
pkg install termux-x11-nightly xfce blender git wget
git clone https://github.com/xMeM/termux-packages.git
cd termux-packages
git checkout ebada11
(curl https://gist.githubusercontent.com/robertkirkman/5054321db3d5082b2cc0251f4dd891b3/raw/29697ca1f83453d4ab8fd7c3f8b231e1791f070b/termux-packages-mesa-danil-turnip-ondevice.patch && echo) | git apply -v
./scripts/setup-termux.sh 
pkg install bison
pip install mako
./build-package.sh -I -f mesa
./build-package.sh -I -f mesa-vulkan-icd-freedreno-dri3
cd output
pkg install ./mesa_23.3.0-devel-1_aarch64.deb ./mesa-vulkan-icd-freedreno-dri3_23.3.0-devel-0_aarch64.deb
cd
wget https://github.com/Fast-64/fast64/archive/refs/heads/main.zip
wget https://cdn.discordapp.com/attachments/755907254318006362/1132551173006696608/Definitive_Character_Template_for_ExCoop.zip
unzip Definitive_Character_Template_for_ExCoop.zip
git clone https://github.com/n64decomp/sm64.git
cp /storage/emulated/0/Documents/baserom.us.z64 sm64
cd sm64
./extract_assets.py us
termux-x11 :0 -xstartup "xfce4-session" &
DISPLAY=:0 MESA_LOADER_DRIVER_OVERRIDE=zink MESA_VK_WSI_DEBUG=sw TU_DEBUG=noconform blender
mkdir -p /storage/emulated/0/com.owokitty.sm64excoop/dynos/packs
cp -r ~/dynospack /storage/emulated/0/com.owokitty.sm64excoop/dynos/packs
diff --git a/packages/mesa-vulkan-icd-freedreno-dri3/build.sh b/packages/mesa-vulkan-icd-freedreno-dri3/build.sh
index 9a9d249e6..cde951108 100644
--- a/packages/mesa-vulkan-icd-freedreno-dri3/build.sh
+++ b/packages/mesa-vulkan-icd-freedreno-dri3/build.sh
@@ -3,9 +3,9 @@ TERMUX_PKG_DESCRIPTION="An open-source implementation of the OpenGL specificatio
TERMUX_PKG_LICENSE="MIT"
TERMUX_PKG_LICENSE_FILE="docs/license.rst"
TERMUX_PKG_MAINTAINER="@termux"
-TERMUX_PKG_VERSION=23.1.4
-TERMUX_PKG_SRCURL=https://archive.mesa3d.org/mesa-${TERMUX_PKG_VERSION}.tar.xz
-TERMUX_PKG_SHA256=7261a17fb94867e3dc5a90d8a1f100fa04b0cbbde51d25302c0872b5e9a10959
+TERMUX_PKG_VERSION=23.3.0-devel
+TERMUX_PKG_SRCURL=https://gitlab.freedesktop.org/Danil/mesa/-/archive/f671899f57053a9ec4fc3760159f0069b32dcad2/mesa-f671899f57053a9ec4fc3760159f0069b32dcad2.tar.gz
+TERMUX_PKG_SHA256=ba6eb9b4aaf04aeb7deb297b8daafe4e90c43541720374ccedacd5f05716ded6
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_CONFLICTS="mesa-vulkan-icd-freedreno"
@@ -29,7 +29,7 @@ TERMUX_PKG_BLACKLISTED_ARCHES="i686, x86_64"
termux_step_pre_configure() {
termux_setup_cmake
- CPPFLAGS+=" -D__USE_GNU"
+ CPPFLAGS+=" -D__USE_GNU -D__ANDROID_API__=$(getprop ro.build.version.sdk)"
LDFLAGS+=" -landroid-shmem"
_WRAPPER_BIN=$TERMUX_PKG_BUILDDIR/_wrapper/bin
diff --git a/packages/mesa-vulkan-icd-freedreno-dri3/the-usual.patch b/packages/mesa-vulkan-icd-freedreno-dri3/the-usual.patch
new file mode 100644
index 000000000..dda8e7f95
--- /dev/null
+++ b/packages/mesa-vulkan-icd-freedreno-dri3/the-usual.patch
@@ -0,0 +1,59 @@
+diff --git a/bin/install_megadrivers.py b/bin/install_megadrivers.py
+index 60ee4576c60..8c617d295a8 100644
+--- a/bin/install_megadrivers.py
++++ b/bin/install_megadrivers.py
+@@ -23,8 +23,13 @@
+ """Script to install megadriver symlinks for meson."""
+
+ import argparse
+-import os
+-
++import os, shutil
++def link(src, dest):
++ shutil.copyfile(src, dest)
++def unlink(src):
++ os.remove(src)
++os.link = link
++os.unlink = unlink
+
+ def main():
+ parser = argparse.ArgumentParser()
+diff --git a/src/gallium/targets/dri/meson.build b/src/gallium/targets/dri/meson.build
+index fbec1da957b..e46c4a2c564 100644
+--- a/src/gallium/targets/dri/meson.build
++++ b/src/gallium/targets/dri/meson.build
+@@ -122,20 +122,20 @@ foreach d : [[with_gallium_kmsro, [
+ endforeach
+
+ # This only works on Unix-like oses, which is probably fine for dri
+-prog_ln = find_program('ln', required : false)
+-if prog_ln.found()
+- devenv.set('LIBGL_DRIVERS_PATH', meson.current_build_dir())
+-
+- foreach d : gallium_dri_drivers
+- custom_target(
+- 'devenv_@0@'.format(d),
+- input : libgallium_dri,
+- output : d,
+- command : [prog_ln, '-f', '@INPUT@', '@OUTPUT@'],
+- build_by_default : true,
+- )
+- endforeach
+-endif
++# prog_ln = find_program('ln', required : false)
++# if prog_ln.found()
++# devenv.set('LIBGL_DRIVERS_PATH', meson.current_build_dir())
++#
++# foreach d : gallium_dri_drivers
++# custom_target(
++# 'devenv_@0@'.format(d),
++# input : libgallium_dri,
++# output : d,
++# command : [prog_ln, '-f', '@INPUT@', '@OUTPUT@'],
++# build_by_default : true,
++# )
++# endforeach
++# endif
+
+ meson.add_install_script(
+ install_megadrivers_py.full_path(),
diff --git a/packages/mesa-vulkan-icd-freedreno-dri3/wsi-termux-x11-v3.patch b/packages/mesa-vulkan-icd-freedreno-dri3/wsi-termux-x11-v3.patch
index 2fa57f8b4..7b0f7791a 100644
--- a/packages/mesa-vulkan-icd-freedreno-dri3/wsi-termux-x11-v3.patch
+++ b/packages/mesa-vulkan-icd-freedreno-dri3/wsi-termux-x11-v3.patch
@@ -1,5 +1,5 @@
diff --git a/src/freedreno/vulkan/tu_wsi.cc b/src/freedreno/vulkan/tu_wsi.cc
-index 9929993..85c7445 100644
+index 9929993bbe0..85c744585a8 100644
--- a/src/freedreno/vulkan/tu_wsi.cc
+++ b/src/freedreno/vulkan/tu_wsi.cc
@@ -14,6 +14,18 @@
@@ -34,10 +34,10 @@ index 9929993..85c7445 100644
physical_device->wsi_device.can_present_on_device =
tu_wsi_can_present_on_device;
diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c
-index b03a359..b5ed409 100644
+index 726862560e8..3539a585d22 100644
--- a/src/vulkan/wsi/wsi_common.c
+++ b/src/vulkan/wsi/wsi_common.c
-@@ -1387,7 +1387,7 @@ wsi_common_queue_present(const struct wsi_device *wsi,
+@@ -1424,7 +1424,7 @@ wsi_common_queue_present(const struct wsi_device *wsi,
assert(!has_signal_dma_buf);
#endif
@@ -47,7 +47,7 @@ index b03a359..b5ed409 100644
true, ~0ull);
diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h
-index 3460256..fbf22a7 100644
+index 346025602b9..fbf22a736c1 100644
--- a/src/vulkan/wsi/wsi_common.h
+++ b/src/vulkan/wsi/wsi_common.h
@@ -168,6 +168,7 @@ struct wsi_device {
@@ -71,10 +71,10 @@ index 3460256..fbf22a7 100644
WSI_CB(AllocateMemory);
WSI_CB(AllocateCommandBuffers);
diff --git a/src/vulkan/wsi/wsi_common_drm.c b/src/vulkan/wsi/wsi_common_drm.c
-index 43c380c..86536b8 100644
+index b53d485ef3a..ffc62fff1d6 100644
--- a/src/vulkan/wsi/wsi_common_drm.c
+++ b/src/vulkan/wsi/wsi_common_drm.c
-@@ -38,6 +38,9 @@
+@@ -39,6 +39,9 @@
#include <stdlib.h>
#include <stdio.h>
#include <xf86drm.h>
@@ -84,7 +84,7 @@ index 43c380c..86536b8 100644
static VkResult
wsi_dma_buf_export_sync_file(int dma_buf_fd, int *sync_file_fd)
-@@ -101,6 +104,9 @@ prepare_signal_dma_buf_from_semaphore(struct wsi_swapchain *chain,
+@@ -104,6 +107,9 @@ prepare_signal_dma_buf_from_semaphore(struct wsi_swapchain *chain,
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT))
return VK_ERROR_FEATURE_NOT_PRESENT;
@@ -94,7 +94,7 @@ index 43c380c..86536b8 100644
int sync_file_fd = -1;
result = wsi_dma_buf_export_sync_file(image->dma_buf_fd, &sync_file_fd);
if (result != VK_SUCCESS)
-@@ -199,6 +205,9 @@ wsi_create_sync_for_dma_buf_wait(const struct wsi_swapchain *chain,
+@@ -202,6 +208,9 @@ wsi_create_sync_for_dma_buf_wait(const struct wsi_swapchain *chain,
if (sync_type == NULL)
return VK_ERROR_FEATURE_NOT_PRESENT;
@@ -104,7 +104,7 @@ index 43c380c..86536b8 100644
int sync_file_fd = -1;
result = wsi_dma_buf_export_sync_file(image->dma_buf_fd, &sync_file_fd);
if (result != VK_SUCCESS)
-@@ -303,6 +312,11 @@ wsi_create_native_image_mem(const struct wsi_swapchain *chain,
+@@ -306,6 +315,11 @@ wsi_create_native_image_mem(const struct wsi_swapchain *chain,
const struct wsi_image_info *info,
struct wsi_image *image);
@@ -116,7 +116,7 @@ index 43c380c..86536b8 100644
static VkResult
wsi_configure_native_image(const struct wsi_swapchain *chain,
const VkSwapchainCreateInfoKHR *pCreateInfo,
-@@ -441,7 +455,10 @@ wsi_configure_native_image(const struct wsi_swapchain *chain,
+@@ -444,7 +458,10 @@ wsi_configure_native_image(const struct wsi_swapchain *chain,
}
}
@@ -128,7 +128,7 @@ index 43c380c..86536b8 100644
return VK_SUCCESS;
-@@ -551,6 +568,106 @@ wsi_create_native_image_mem(const struct wsi_swapchain *chain,
+@@ -563,6 +580,106 @@ wsi_create_native_image_mem(const struct wsi_swapchain *chain,
return VK_SUCCESS;
}
@@ -236,10 +236,10 @@ index 43c380c..86536b8 100644
static VkResult
diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c
-index a423559..159690b 100644
+index 2dff27afa64..492351ec49e 100644
--- a/src/vulkan/wsi/wsi_common_x11.c
+++ b/src/vulkan/wsi/wsi_common_x11.c
-@@ -1386,7 +1386,7 @@ x11_acquire_next_image_poll_find_index(struct x11_swapchain *chain, uint32_t *im
+@@ -1422,7 +1422,7 @@ x11_acquire_next_image_poll_find_index(struct x11_swapchain *chain, uint32_t *im
for (uint32_t i = 0; i < chain->base.image_count; i++) {
if (!chain->images[i].busy) {
/* We found a non-busy image */
@@ -248,7 +248,7 @@ index a423559..159690b 100644
*image_index = i;
chain->images[i].busy = true;
chain->present_poll_acquire_count++;
-@@ -1542,7 +1542,7 @@ x11_acquire_next_image_from_queue(struct x11_swapchain *chain,
+@@ -1578,7 +1578,7 @@ x11_acquire_next_image_from_queue(struct x11_swapchain *chain,
}
assert(image_index < chain->base.image_count);
@@ -257,28 +257,27 @@ index a423559..159690b 100644
*image_index_out = image_index;
-@@ -1595,7 +1595,7 @@ x11_present_to_x11_dri3(struct x11_swapchain *chain, uint32_t image_index,
- return result;
- }
+@@ -1617,7 +1617,7 @@ x11_present_to_x11_dri3(struct x11_swapchain *chain, uint32_t image_index,
+ options |= XCB_PRESENT_OPTION_SUBOPTIMAL;
+ #endif
- xshmfence_reset(image->shm_fence);
+ xcb_sync_reset_fence(chain->conn, image->sync_fence);
++chain->sent_image_count;
assert(chain->sent_image_count <= chain->base.image_count);
-@@ -2061,7 +2061,6 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain,
- xcb_void_cookie_t cookie;
+@@ -2103,7 +2103,6 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain,
+ xcb_generic_error_t *error = NULL;
VkResult result;
uint32_t bpp = 32;
- int fence_fd;
result = wsi_create_image(&chain->base, &chain->base.image_info,
&image->base);
-@@ -2142,43 +2141,41 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain,
- if (fd == -1)
+@@ -2185,14 +2184,23 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain,
return VK_ERROR_OUT_OF_HOST_MEMORY;
-- cookie =
+ cookie =
- xcb_dri3_pixmap_from_buffer_checked(chain->conn,
- image->pixmap,
- chain->window,
@@ -306,7 +305,9 @@ index a423559..159690b 100644
+ &fd);
}
- xcb_discard_reply(chain->conn, cookie.sequence);
+ error = xcb_request_check(chain->conn, cookie);
+@@ -2202,29 +2210,19 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain,
+ }
out_fence:
- fence_fd = xshmfence_alloc_shm();
@@ -342,7 +343,7 @@ index a423559..159690b 100644
fail_pixmap:
cookie = xcb_free_pixmap(chain->conn, image->pixmap);
xcb_discard_reply(chain->conn, cookie.sequence);
-@@ -2198,7 +2195,6 @@ x11_image_finish(struct x11_swapchain *chain,
+@@ -2245,7 +2243,6 @@ x11_image_finish(struct x11_swapchain *chain,
if (!chain->base.wsi->sw || chain->has_mit_shm) {
cookie = xcb_sync_destroy_fence(chain->conn, image->sync_fence);
xcb_discard_reply(chain->conn, cookie.sequence);
diff --git a/packages/mesa/build.sh b/packages/mesa/build.sh
index eece194a8..2c70313d8 100644
--- a/packages/mesa/build.sh
+++ b/packages/mesa/build.sh
@@ -3,10 +3,10 @@ TERMUX_PKG_DESCRIPTION="An open-source implementation of the OpenGL specificatio
TERMUX_PKG_LICENSE="MIT"
TERMUX_PKG_LICENSE_FILE="docs/license.rst"
TERMUX_PKG_MAINTAINER="@termux"
-TERMUX_PKG_VERSION=23.1.4
+TERMUX_PKG_VERSION=23.3.0-devel
+TERMUX_PKG_SRCURL=https://gitlab.freedesktop.org/Danil/mesa/-/archive/f671899f57053a9ec4fc3760159f0069b32dcad2/mesa-f671899f57053a9ec4fc3760159f0069b32dcad2.tar.gz
+TERMUX_PKG_SHA256=ba6eb9b4aaf04aeb7deb297b8daafe4e90c43541720374ccedacd5f05716ded6
TERMUX_PKG_REVISION=1
-TERMUX_PKG_SRCURL=https://archive.mesa3d.org/mesa-${TERMUX_PKG_VERSION}.tar.xz
-TERMUX_PKG_SHA256=7261a17fb94867e3dc5a90d8a1f100fa04b0cbbde51d25302c0872b5e9a10959
TERMUX_PKG_DEPENDS="libandroid-shmem, libc++, libdrm, libglvnd, libwayland, libx11, libxext, libxfixes, libxshmfence, libxxf86vm, ncurses, vulkan-loader, zlib, zstd"
TERMUX_PKG_SUGGESTS="mesa-dev"
TERMUX_PKG_BUILD_DEPENDS="libllvm-static, libwayland-protocols, libxrandr, llvm, llvm-tools, mlir, xorgproto"
@@ -36,7 +36,7 @@ TERMUX_PKG_EXTRA_CONFIGURE_ARGS="
termux_step_pre_configure() {
termux_setup_cmake
- CPPFLAGS+=" -D__USE_GNU"
+ CPPFLAGS+=" -D__USE_GNU -D__ANDROID_API__=$(getprop ro.build.version.sdk)"
LDFLAGS+=" -landroid-shmem"
_WRAPPER_BIN=$TERMUX_PKG_BUILDDIR/_wrapper/bin
diff --git a/packages/mesa/the-usual.patch b/packages/mesa/the-usual.patch
new file mode 100644
index 000000000..dda8e7f95
--- /dev/null
+++ b/packages/mesa/the-usual.patch
@@ -0,0 +1,59 @@
+diff --git a/bin/install_megadrivers.py b/bin/install_megadrivers.py
+index 60ee4576c60..8c617d295a8 100644
+--- a/bin/install_megadrivers.py
++++ b/bin/install_megadrivers.py
+@@ -23,8 +23,13 @@
+ """Script to install megadriver symlinks for meson."""
+
+ import argparse
+-import os
+-
++import os, shutil
++def link(src, dest):
++ shutil.copyfile(src, dest)
++def unlink(src):
++ os.remove(src)
++os.link = link
++os.unlink = unlink
+
+ def main():
+ parser = argparse.ArgumentParser()
+diff --git a/src/gallium/targets/dri/meson.build b/src/gallium/targets/dri/meson.build
+index fbec1da957b..e46c4a2c564 100644
+--- a/src/gallium/targets/dri/meson.build
++++ b/src/gallium/targets/dri/meson.build
+@@ -122,20 +122,20 @@ foreach d : [[with_gallium_kmsro, [
+ endforeach
+
+ # This only works on Unix-like oses, which is probably fine for dri
+-prog_ln = find_program('ln', required : false)
+-if prog_ln.found()
+- devenv.set('LIBGL_DRIVERS_PATH', meson.current_build_dir())
+-
+- foreach d : gallium_dri_drivers
+- custom_target(
+- 'devenv_@0@'.format(d),
+- input : libgallium_dri,
+- output : d,
+- command : [prog_ln, '-f', '@INPUT@', '@OUTPUT@'],
+- build_by_default : true,
+- )
+- endforeach
+-endif
++# prog_ln = find_program('ln', required : false)
++# if prog_ln.found()
++# devenv.set('LIBGL_DRIVERS_PATH', meson.current_build_dir())
++#
++# foreach d : gallium_dri_drivers
++# custom_target(
++# 'devenv_@0@'.format(d),
++# input : libgallium_dri,
++# output : d,
++# command : [prog_ln, '-f', '@INPUT@', '@OUTPUT@'],
++# build_by_default : true,
++# )
++# endforeach
++# endif
+
+ meson.add_install_script(
+ install_megadrivers_py.full_path(),
diff --git a/scripts/build/termux_step_extract_into_massagedir.sh b/scripts/build/termux_step_extract_into_massagedir.sh
index bac7667d0..e0eab326e 100644
--- a/scripts/build/termux_step_extract_into_massagedir.sh
+++ b/scripts/build/termux_step_extract_into_massagedir.sh
@@ -4,7 +4,7 @@ termux_step_extract_into_massagedir() {
# Build diff tar with what has changed during the build:
cd $TERMUX_PREFIX
tar -N "$TERMUX_BUILD_TS_FILE" \
- --exclude='tmp' \
+ --exclude='tmp' --exclude='__pycache__' \
-czf "$TARBALL_ORIG" .
# Extract tar in order to massage it
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment