Files
qbz/scripts/dev-igpu-mode.sh
T
vicrodh 3061de2163 chore(scripts): add dev-igpu-mode.sh for iGPU-only paint path testing
Sister script to dev-cpu-mode.sh. Where the CPU script forces pure
software rendering across every layer that can sneak the GPU back in,
this one pins WebKit / GTK to the integrated GPU (Intel/AMD) so we can
test the "modest HW accel" tier the current detector ignores.

Specifically pins __EGL_VENDOR_LIBRARY_FILENAMES to the Mesa EGL JSON
so the NVIDIA EGL ICD doesn't win (it has the lower 10_* priority
prefix and WebKitGTK prefers EGL). Leaves WEBKIT_DISABLE_COMPOSITING_
MODE, WEBKIT_DISABLE_DMABUF_RENDERER, GSK_RENDERER, and LIBGL_ALWAYS_
SOFTWARE unset — the inverse of dev-cpu-mode — so real iGPU paint
paths exercise.

Header documents verification commands (nvidia-smi must not list
QBZ; intel_gpu_top / nvtop should show activity on Intel only).

Purpose is to inform a future refinement of graphicsState's detector:
binary hardware_accel_enabled doesn't differentiate "iGPU is fine for
balanced visuals" from "no GPU at all, force lite". Manual harness
first; detector smarts second once we know what actually works on
real iGPU paint.

cc
2026-05-13 15:04:35 -06:00

130 lines
5.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# Force QBZ to run on the integrated GPU (Intel/AMD), bypassing the
# discrete NVIDIA GPU. Unlike dev-cpu-mode.sh (which forces pure
# software rendering), this keeps WebKit GPU compositing enabled so
# we can observe how QBZ behaves with modest-but-real HW accel.
#
# Why this matters: the current `hardware_accel_enabled` detector is
# binary (on / off). A user with an iGPU shouldn't be punished with
# the lite path designed for true software rendering — but right now
# the only way to test that intermediate tier is to actually constrain
# the runtime to the iGPU. This script is the manual harness for that.
#
# Layers forced to iGPU / Mesa:
# __EGL_VENDOR_LIBRARY_FILENAMES — pin EGL to Mesa only, skipping
# /usr/share/glvnd/egl_vendor.d/10_nvidia.json.
# This is the critical knob —
# WebKitGTK prefers EGL and the
# NVIDIA EGL ICD wins by priority
# unless we point it elsewhere.
# __GLX_VENDOR_LIBRARY_NAME=mesa — same idea for GLX (mostly belt
# and braces; default already
# resolves to Mesa+Intel on this box).
# DRI_PRIME=0 — explicit primary GPU selection;
# no PRIME render offload.
# __NV_PRIME_RENDER_OFFLOAD unset — make sure we are not asking
# nvidia-prime to bring the dGPU
# back via offload.
# QBZ_HARDWARE_ACCEL unset — let QBZ honor its persisted
# graphics_settings (HW on by
# default). We want the iGPU
# active, not software rendering.
# GSK_RENDERER unset — let GTK4 pick its best renderer
# under the constrained GL/EGL.
#
# Layers explicitly NOT set (the opposite of dev-cpu-mode.sh):
# WEBKIT_DISABLE_COMPOSITING_MODE — leave at default so WebKit
# keeps GPU compositing.
# WEBKIT_DISABLE_DMABUF_RENDERER — leave at default so DMA-BUF
# texture sharing works on the
# Intel/Mesa side.
# LIBGL_ALWAYS_SOFTWARE — leave unset so Mesa runs on the
# real Intel HW, not llvmpipe.
#
# Verification after launch (in a separate shell):
# nvidia-smi --query-compute-apps=pid,used_memory --format=csv
# → QBZ pid must NOT appear in the list.
# nvtop / intel_gpu_top
# → Activity on Intel iGPU when QBZ paints; idle on NVIDIA.
#
# Usage:
# bash ./scripts/dev-igpu-mode.sh # kill stale + start tauri dev
# bash ./scripts/dev-igpu-mode.sh --no-kill # skip process cleanup
# bash ./scripts/dev-igpu-mode.sh --print # print env and exit
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "${ROOT_DIR}"
KILL_STALE=true
PRINT_ONLY=false
for arg in "$@"; do
case "$arg" in
--no-kill)
KILL_STALE=false
;;
--print)
PRINT_ONLY=true
;;
*)
echo "[qbz] Unknown option: ${arg}"
echo "Usage: bash ./scripts/dev-igpu-mode.sh [--no-kill] [--print]"
exit 1
;;
esac
done
MESA_EGL_JSON="/usr/share/glvnd/egl_vendor.d/50_mesa.json"
if [[ ! -f "${MESA_EGL_JSON}" ]]; then
echo "[qbz] dev-igpu-mode: ${MESA_EGL_JSON} not found — your distro packages Mesa EGL elsewhere."
echo "[qbz] dev-igpu-mode: list the candidates with: ls /usr/share/glvnd/egl_vendor.d/"
exit 1
fi
export __EGL_VENDOR_LIBRARY_FILENAMES="${MESA_EGL_JSON}"
export __GLX_VENDOR_LIBRARY_NAME=mesa
export DRI_PRIME=0
unset __NV_PRIME_RENDER_OFFLOAD
unset QBZ_HARDWARE_ACCEL
unset GSK_RENDERER
unset WEBKIT_DISABLE_COMPOSITING_MODE
unset WEBKIT_DISABLE_DMABUF_RENDERER
unset LIBGL_ALWAYS_SOFTWARE
echo "[qbz] dev-igpu-mode: iGPU-only env applied"
echo "[qbz] __EGL_VENDOR_LIBRARY_FILENAMES = ${__EGL_VENDOR_LIBRARY_FILENAMES}"
echo "[qbz] __GLX_VENDOR_LIBRARY_NAME = ${__GLX_VENDOR_LIBRARY_NAME}"
echo "[qbz] DRI_PRIME = ${DRI_PRIME}"
echo "[qbz] QBZ_HARDWARE_ACCEL = (unset → DB default, HW on)"
echo "[qbz] compositing / DMA-BUF / llvmpipe = NOT forced (real iGPU paint path)"
if [[ "${PRINT_ONLY}" == "true" ]]; then
exit 0
fi
if [[ "${KILL_STALE}" == "true" ]]; then
echo "[qbz] dev-igpu-mode: stopping stale dev processes..."
pkill -f '[n]ode .*vite dev' || true
pkill -f '[n]ode .*tauri dev' || true
pkill -f '[c]argo run' || true
pkill -f '[t]arget/debug/qbz' || true
pkill -f '[t]arget/debug/qbz-nix' || true
for port in 1420 1421; do
pids="$(lsof -ti :"${port}" -sTCP:LISTEN 2>/dev/null || true)"
if [[ -n "${pids}" ]]; then
kill ${pids} 2>/dev/null || true
sleep 0.5
still_alive="$(lsof -ti :"${port}" -sTCP:LISTEN 2>/dev/null || true)"
if [[ -n "${still_alive}" ]]; then
kill -9 ${still_alive} 2>/dev/null || true
fi
fi
done
fi
echo "[qbz] dev-igpu-mode: starting tauri dev in foreground..."
exec npm run tauri dev