mirror of
https://github.com/HayatoG/iss_pc.git
synced 2026-11-09 10:19:36 -10:00
101 lines
4.7 KiB
Bash
Executable File
101 lines
4.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# One measurement round of a parameter study (A-B of ISS_* variables in one scene).
|
|
# Usage: scripts/param_round.sh <name> [VAR=value ...]
|
|
# Needs: SAVE_SNAPSHOT (a savedata folder to copy per round) and a prepared port/out (bash port/build.sh,
|
|
# then one scripts/infamous_run.sh). Optional: RESULTS (default port/out/param_tests; <name>/ in it is
|
|
# replaced), GAME_LOCK (shared with scripts/infamous_run.sh), ISS_GAME_DIR (default game/CUSA00223), SCENE (file of "<second> <buttons>" lines that
|
|
# gets the game from the title to the scene; "replay" starts a TLG_PAD_REPLAY recording), WARM_MAX, MEASURE_S.
|
|
# One round: isolated user dir (own save copy, shared shader cache), fixed tlg.ini, warm up until the
|
|
# shaders stop compiling, 60 s of measurement with the monitor running, a burst of frame dumps in the
|
|
# middle, then the game is closed. Never touches port/user/savedata.
|
|
set -uo pipefail
|
|
name=${1:?name}; shift
|
|
root=$(cd -- "$(dirname -- "$0")/.." && pwd); port=$root/port
|
|
lock=${GAME_LOCK:-${XDG_RUNTIME_DIR:-/tmp}/infamous-game.lock}; snap=${SAVE_SNAPSHOT:?set SAVE_SNAPSHOT}
|
|
results=${RESULTS:-$port/out/param_tests};warm_max=${WARM_MAX:-180}; measure=${MEASURE_S:-60}
|
|
r=$results/$name; rm -rf "$r"; mkdir -p "$r/dumps" "$r/user"
|
|
if [[ -z ${PARAM_ROUND_LOCKED:-} ]]; then
|
|
touch "$lock"; exec env PARAM_ROUND_LOCKED=1 flock -x "$lock" "$0" "$name" "$@"
|
|
fi
|
|
pgrep -x tlg-probe >/dev/null && { echo "a game is already running" >&2; exit 3; }
|
|
status=ok; game=; mon=
|
|
|
|
# isolated user dir: everything of port/user shared (shader cache...) except the saves and the ini
|
|
for e in "$port"/user/*; do b=$(basename "$e"); [[ $b == savedata* || $b == tlg.ini ]] || ln -s "$e" "$r/user/$b"; done
|
|
cp -a "$snap" "$r/user/savedata"
|
|
cat > "$r/user/tlg.ini" <<INI
|
|
upscaler=off
|
|
jitter=0
|
|
object_motion=0
|
|
show_fps=1
|
|
output_res=1920x1080
|
|
display_mode=borderless
|
|
vsync=0
|
|
fps_limit=0
|
|
rcas=0
|
|
fsr1=0
|
|
render_resolution=native
|
|
deferred_readback=1
|
|
INI
|
|
env_file=$r/env.txt; : > "$env_file"
|
|
declare -a envs=(ISS_LANGUAGE=17 ISS_READBACKS=2 ISS_EAGER_READBACK=1 ISS_WRITE_MERGE=1 ISS_DEFERRED_READBACK=1
|
|
ISS_GC_BUDGET_MB=3500 ISS_PIPELINE_BINARIES=0 ISS_FRAME_STATS=1 ISS_OBJECT_MOTION=0 ISS_UPSCALER=off ISS_JITTER=0
|
|
ISS_FRAME_DUMP_TRIGGER=$r/trigger ISS_DUMP_DIR=$r/dumps ISS_FRAME_DUMP_COUNT=150 ISS_PAD_FILE=$r/pad.txt)
|
|
[[ -n ${REPLAY_FILE:-} ]] && envs+=(ISS_PAD_REPLAY=$REPLAY_FILE)
|
|
for kv in "$@"; do envs+=("$kv"); done
|
|
printf '%s\n' "${envs[@]}" > "$env_file"
|
|
: > "$r/pad.txt"
|
|
|
|
cleanup() {
|
|
[[ -n $mon ]] && kill "$mon" 2>/dev/null
|
|
if [[ -n $game ]] && kill -0 "$game" 2>/dev/null; then
|
|
pkill -TERM -x tlg-probe; for _ in $(seq 1 15); do kill -0 "$game" 2>/dev/null || break; sleep 1; done
|
|
pkill -KILL -x tlg-probe 2>/dev/null
|
|
fi
|
|
echo "$status" > "$r/status.txt"
|
|
}
|
|
trap cleanup EXIT INT TERM
|
|
|
|
dump=${ISS_GAME_DIR:-$root/game/CUSA00223}
|
|
(cd "$r/user" && exec env "${envs[@]}" ISS_APP_NAME="inFAMOUS Second Son" ISS_APP_ID=infamous-pc \
|
|
"$port/out/tlg-probe" "$port/out/boot-linked.bin" --app0 "$dump" --user . \
|
|
--content-profile "$port/out/content.bin" --timeout $((warm_max + measure + 240))) > "$r/game.log" 2>&1 &
|
|
game=$!
|
|
t0=$(date +%s); now() { echo $(( $(date +%s) - t0 )); }
|
|
press() { echo "$1" > "$r/pad.txt"; sleep 0.3; : > "$r/pad.txt"; }
|
|
|
|
# scene: from the title to the spot
|
|
if [[ -n ${SCENE:-} && -f $SCENE ]]; then
|
|
while read -r at buttons; do
|
|
[[ -z $at || $at == \#* ]] && continue
|
|
while (( $(now) < at )); do sleep 0.2; done
|
|
kill -0 "$game" 2>/dev/null || { status=crash; exit 1; }
|
|
press "$buttons"
|
|
done < "$SCENE"
|
|
fi
|
|
|
|
# warm-up: two Frame stats in a row without compiles and with a loaded scene (>2000 draws) or the limit
|
|
last_n=0
|
|
while (( $(now) < warm_max )); do
|
|
kill -0 "$game" 2>/dev/null || { status=crash; exit 1; }
|
|
ok=$(grep "Frame stats" "$r/game.log" | tail -2 | grep -c " 0 shader/pipeline compiles")
|
|
n=$(grep -c "Frame stats" "$r/game.log")
|
|
(( n > 4 && ok == 2 )) && (( $(now) > ${WARM_MIN:-60} )) && break
|
|
sleep 5
|
|
done
|
|
echo "warm-up ended at $(now) s" >> "$r/notes.txt"
|
|
|
|
# measurement
|
|
start_lines=$(grep -c "Frame stats" "$r/game.log")
|
|
"$root/scripts/round_monitor.sh" "$r/mon" "$measure" 1 > /dev/null 2>&1 &
|
|
mon=$!
|
|
sleep $((measure / 2)); touch "$r/trigger"
|
|
sleep $((measure - measure / 2 + 2))
|
|
kill -0 "$game" 2>/dev/null || status=crash
|
|
echo "measure window: Frame stats lines $start_lines..$(grep -c 'Frame stats' "$r/game.log")" >> "$r/notes.txt"
|
|
grep -c "Stall:" "$r/game.log" > "$r/stalls.txt" 2>/dev/null
|
|
cleanup; trap - EXIT
|
|
python3 -I "$root/scripts/round_analyze.py" summarize --log "$r/game.log" --mon "$r/mon" --window "$measure" \
|
|
--name "$name" --out "$r" > "$r/summary.txt" 2>&1
|
|
echo "$name: $status; $(grep -m1 -i 'fps' "$r/summary.txt" | head -1)"
|