73 Commits
Author SHA1 Message Date
AlxcBTW 33fea9e1ba Merge main into pr/profile-windows 2026-10-18 19:49:54 +02:00
Adrià 84b7ef9de3 Merge pull request #6181 from MarcZX10/codex/document-guest-clock-scale-6172
docs(dev): describe the guest clock scale switch
2026-10-18 18:58:07 +02:00
AlxcBTW 0d699295a9 docs(agc): say which profile lines count per window and which since start 2026-10-18 12:36:32 +02:00
milescovielloandClaude Opus 5.5 f7cd8df309 fix(agc): trace the title threads that register shaders
Shader registration and the shader ABI resolves run on the title's own
threads, which never bound a trace buffer, so their Shader.Register and
Shader.Resolve* scopes were missing from every trace and summary. Those
entry points now bind the calling thread as `title` with the 32,768-event
buffer the shader preparation threads use.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 21:33:53 +00:00
MarcZX100 a2ed4abead docs(dev): clarify guest clock scale coverage 2026-10-17 17:50:36 +00:00
MarcZX100 c732321bd3 docs(dev): describe the guest clock scale switch 2026-10-17 17:50:36 +00:00
javierUDP 02c7da7677 fix: keep the Python tools and tests on Python 3.9
`Path.write_text(newline=...)` and `zip(strict=True)` were added in
Python 3.10. macOS ships 3.9.6 as /usr/bin/python3, the interpreter CMake
finds when no newer one is installed, so `prepare_release_notes` raised
TypeError when the release workflow wrote its notes and the
`pr_overlap_tools`, `release_package` and `linux_fixed_base` tests failed
on a stock macOS host. Writing the encoded text keeps the newline
translation off on every host, and the dynamic tag counts are compared
before the pairs are walked.
2026-10-17 10:31:10 -03:00
Dean 5bd85a44c2 Merge pull request #6876 from parl0v/docs/gputime-line
docs(build): describe the [gputime] line and its command classes
2026-10-17 16:47:31 +13:00
Adrià 7d728b1098 Merge pull request #6041 from wachi35676/docs/build-wasm-flag
docs(build): list the ANYPS5_BUILD_WASM flag
2026-10-16 23:17:04 +02:00
Adrià 4986aca62e Merge pull request #6002 from CrimsonMac/docs/bitdefender-raise-exception-deadlock
docs(build): note Bitdefender Advanced Threat Defense hanging guest_raise_exception
2026-10-16 22:48:06 +02:00
Adrià 7600f3dd18 Merge pull request #5903 from jotitadev/docs/build-relinker-macos-output
docs(build): list Mach-O among relinker-only outputs
2026-10-16 20:37:43 +02:00
Josip Parlov d67d37bde8 docs(build): describe the [gputime] line and its command classes 2026-10-16 17:32:43 +02:00
Crimson b0c283daa8 docs(build): note Bitdefender Advanced Threat Defense hanging guest_raise_exception 2026-10-15 16:32:09 +03:00
Adrià FranchandClaude e0b9572e3b ci(windows): find the CA bundle of Git for Windows under ucrt64 too
Git for Windows 2.56 (runner image 20261002) moved from mingw64 to ucrt64,
so the fixed SSL_CERT_FILE path no longer exists and the WinLibs CMake
fails the FFmpeg download with status 60 on every Windows build. Take the
bundle from whichever of ucrt64 and mingw64 exists.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-15 15:20:44 +02:00
Adrià FranchandClaude de0cd00eb1 docs(build): document APS5_TRACE_DRAW_PROGRAMS
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-14 23:39:27 +02:00
Muhammad Wasif Ali WasifandClaude Opus 5.5 895061ca62 docs(build): list the ANYPS5_BUILD_WASM flag
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 01:22:39 +05:00
Adrià 61cec42439 Merge pull request #5032 from kq62/docs-winlibs-link
docs(build): link the supported WinLibs release
2026-10-14 19:54:36 +02:00
Eli Yarson a53332472c feat(agc): report which trace threads dropped events and where their buffers filled
The trace summary line keeps `trace_dropped` as before: true when any
thread lost a slice, any thread's totals table was full, or the gpu
track was full. When it is true, the line now also carries
`trace_dropped_threads`, one entry per affected thread name, so the reader
can tell which thread lost data and how much. Threads that share a
name, such as the shader prepare threads, share one entry: losses are
summed, the earliest fill is kept and totals_full is true if any is.

Each entry has `events_full_after_s`, the seconds from the first
present of the window to the start of the first lost slice. It is
absent for `gpu` and in every summary line (windowed frames/seconds
and APS5_TRACE_SUMMARY_EVERY) whenever the first lost slice starts
outside the line's span of presents, including a slice whose scope
began before the window opened or one lost after the last present.
`events_lost` is the number of slices not recorded and is absent when
0; in interval lines it counts the buffer's losses since it started.
`totals_full` is true when the thread's totals table overflowed, which
makes the summary numbers incomplete; a thread with only `events_lost`
has complete totals.

The Chrome trace gets a `trace buffer full` instant event on a thread
at the point where its buffer filled.

BUILD.md documents the new fields and the event.

`trace_dropped` is unchanged, and when nothing drops the default output
is byte-identical to before.

Refs #5786
Depends on #5808
2026-10-14 18:54:44 +02:00
Jota 4cb3271fb2 docs(build): list Mach-O among relinker-only outputs 2026-10-14 12:10:46 -03:00
Adrià 69e7138acc Merge pull request #5808 from Ondra97/codex/feat-configurable-trace-capacity
feat(agc): configure trace event buffers
2026-10-14 16:10:27 +02:00
Adrià beb7e94048 Merge pull request #5453 from overlordxrz-source/feat/agc-device-fault
feat(agc): report device losses with VK_EXT_device_fault and dispatch checkpoints
2026-10-14 14:58:14 +02:00
Adrià e9a985db1a Merge pull request #4969 from fdfawef324/feat/agc-pm4-capture-replay
feat(agc): capture submissions and replay their decode and wait releases offline
2026-10-14 13:59:22 +02:00
Ondra97 1effd67b70 feat(agc): configure trace event buffers 2026-10-14 13:53:57 +02:00
1402c6c1d8 feat(agc): report device losses with VK_EXT_device_fault and dispatch checkpoints
A device that supports VK_EXT_device_fault reports, on the first
VK_ERROR_DEVICE_LOST a check sees, the fault description, the faulting
addresses (invalid reads and writes, or the instruction pointers of waves
still running when the device hung) and the vendor fault codes.
APS5_GPU_CHECKPOINTS=1 records a VK_NV_device_diagnostic_checkpoints
marker with the program address before each guest dispatch and prints the
last markers the GPU reached, which names the dispatch that hung. Without
either extension nothing changes.

Test: agc_device_fault drives the report through mock
vkGetDeviceFaultInfoEXT and vkGetQueueCheckpointDataNV entry points.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: overlordxrz-source <overlordxrz-source@users.noreply.github.com>
2026-10-14 13:50:52 +02:00
Adrià 2a99157640 Merge pull request #4812 from AlxcBTW/feat/trace-summary-interval
feat(agc): add APS5_TRACE_SUMMARY_EVERY for summary lines of a long session
2026-10-14 12:24:56 +02:00
alfalfa-starandClaude Opus 5.5 040873f9dc feat(videoout): use native Wayland on Linux
Build SDL's Wayland backend next to X11 and ask SDL for "wayland,x11"
on Linux, so the window runs natively under a Wayland compositor instead
of through XWayland. SDL loads libwayland, xkbcommon and libdecor at run
time, so systems without them, or sessions without WAYLAND_DISPLAY, keep
using X11. SDL_VIDEODRIVER still overrides the choice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 07:24:34 +02:00
fdfawef324andClaude Opus 5.5 0286a767e2 feat(agc): capture submissions and replay their decode and wait releases offline
A hang with threads in Driver::waitMemory takes a ten-minute boot to
reproduce, and the existing switches show only the first submissions of
one queue (APS5_DUMP_QUEUE) or a rejected one (APS5_DUMP_REJECTED).

Capture. APS5_DUMP_SUBMITS=<dir> writes every submission the driver
accepts. <dir>/index.txt starts with "aps5-submissions 1" and "ordinal
queue type serial time_us dwords kind file held conditional", then one
line per submission: acceptance ordinal, queue id, graphics or compute,
serial, microseconds on the APS5_TRACE_GPU clock, dword count, kind,
file name, the dword offsets of the waits held at submit
(Submission::heldAtSubmit) and the COND_EXEC and predicated indirect
buffer ranges (Submission::conditionalEnds) as start:end, "-" for none.
<dir>/submission_<ordinal>.bin holds the copied dwords, indirect
buffers inlined. REWIND tails are listed as rewind with the serial of
their submission, suspend points as suspend without a file.
SubmissionCapture::Prepare copies the commands before the driver lock;
Take, under it after reserveOutputs, sets only the ordinal, time and
held waits and does not allocate; the file and then its index line are
written after the lock. A failed write reports the failure to the driver
(Driver::ReportFailure) and throws, so every later driver call throws
too. Unset, Submit tests a static pointer. An index written before the
held and conditional columns ("ordinal queue type serial time_us dwords
kind file") is read with both unknown.

Analysis. agc_pm4_replay <dir> [--full] decodes each submission and
throws on a packet the driver rejects (a corrupt capture). It does not
model cross-queue timing: a wait is released only when the capture
alone proves that the driver releases it (WaitMemory.cpp,
LabelHistory.cpp), and unknown, with the reason, when its outcome
depends on when another queue's stores run. A memory wait is released
when its compare always passes, when it was held at submit, when the
last store to the awaited bytes before it on its queue covers them with
an accepted value, is not conditional and no other queue stores to
those bytes anywhere in the capture, or when a RELEASE_MEM or
WRITE_DATA label earlier in the waiting submission that the label
history keeps (KeepsLabelStore, not conditional) stores an accepted
value and fewer than LabelStoreHistory other stores to the awaited
bytes can run between it and the wait: those between them on the
waiting queue and every store of another queue to those bytes, since
the history keeps the last stores per dword over all queues and finds
only a store that ran after the waiting submission entered the driver.
A REWIND is released when its tail is in the capture; one valid at
submit without a captured tail is unknown, because the driver reads the
valid bit again when the queue reaches it. A wait is unreleased when it was not held at submit and no
store that can run before it may write an accepted value (a store of
part of the awaited bytes or of a run-time value may; a store later on
its queue runs after it): the GPU does not release it, a CPU or shader
store could. A REWIND without a tail that was not valid at submit is unreleased. Every other wait is
unknown: "depends on cross-queue timing (stores on queue X at #...)"
when another queue stores to the awaited bytes, otherwise because the
last store before it on its queue is conditional, stores a run-time
value or part of the bytes, or overwrites an accepted store the capture
does not prove still in the label history. Without the held column a
wait that would be unreleased is unknown; without the conditional
column every packet after a COND_EXEC or predicated INDIRECT_BUFFER is
conditional to the end of its submission. The outcomes depend on the
order of each queue's stores and on which stores other queues make, not
on the submit order across queues. The report counts the outcomes,
routes and cross-queue unknowns, says when the index lacks the columns,
lists up to 32 unreleased and then unknown waits newest first with the
packets around them and their stores, then the last submissions of
each queue; exit code 1 when a wait is unreleased, 2 on errors.

Pm4 gains DecodeStores, DecodeWait, DecodeConditionalWrite,
DecodeConstantRamDump, the COPY_DATA and DMA_DATA field helpers, the
sample dump layout and RewindValid; Execute, ResolveStore, Validate,
DecodeMemoryCopy, the driver's sample dump, noteHeldAtSubmit and
executeRewindTail use them. LabelStoreHistory and KeepsLabelStore move
to LabelStores.hpp, used by noteLabelStore and the analysis.

Test. agc_driver_pm4_replay submits command buffers built with the
libSceAgc builders through the driver with the switch set and checks the
index, the held waits, the COND_EXEC range, the dwords, the decode and
the outcome of eight waits, including WRITE_DATA 1, WRITE_DATA 0,
WAIT == 1 in one submission, which the driver releases through its
label history. Hand-made captures check each release route, a store of
another queue to the awaited bytes that entered before or after
(unknown), the label history limit with later stores on the waiting
queue or on another queue, a fill the history does not keep, a store
in an earlier submission overwritten later, later stores, rejected
values and a missing rewind tail (unreleased), the six captures of the
reviews (none released but the wait held at submit), five groups of
waits in eight submission orders with identical outcomes, an index
without the held and conditional columns and corrupt captures. A
directory in place of the next submission file makes the write fail,
and the submit, the next submit and shutdown throw.
agc_driver_pm4_replay_tool runs the tool through
tests/Pm4ReplayTool.cmake and checks exit codes 1 and 2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 22:40:11 -04:00
sussy 08bd00c8cf docs(build): link the supported WinLibs release 2026-10-13 12:00:24 +03:00
AlxcBTWandClaude Opus 5.5 52c71b837c feat(agc): add APS5_TRACE_SUMMARY_EVERY for summary lines of a long session
APS5_TRACE_SUMMARY_EVERY=<seconds> appends one line to aps5-summary.jsonl
every <seconds> seconds, at a present, from the per-scope totals the trace
threads already keep. No event buffer is allocated unless a window switch is
set as well; then the window records its full trace on top of the intervals
and its own summary line holds only the time inside the window. Each line has
the fields of the window summary line for its interval plus interval_start_s
and interval_end_s.

tools/trace_digest.py prints a summary file with interval lines as one row
per interval with a text sparkline of the frame p99 and the GPU busy time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 00:40:52 +02:00
Adrià 6d2f279863 Merge pull request #4607 from yunusshaikh7/feat/tracy-profiler
feat(agc): report performance timer scopes to Tracy with APS5_ENABLE_TRACY
2026-10-12 23:09:21 +02:00
Adrià 84659e16d0 Merge pull request #4632 from AlxcBTW/feat/trace-gpu-track
feat(agc): add the GPU, GPU mutex waits and shader preparation to the trace
2026-10-12 22:39:23 +02:00
Adrià 44ab0c39ee Merge pull request #3886 from PrintOrb/fix/videoout-high-frame-rate
fix(videoout): support permitted high-frame-rate output for Quake II
2026-10-12 22:23:31 +02:00
AlxcBTWandClaude Opus 5.5 eb8a7255d2 feat(agc): add the GPU, GPU mutex waits and shader preparation to the trace
The trace gets a gpu track: one slice per recorder batch from its timestamp
pair, and with APS5_PROFILE_GPU=1 one per command class range under the
[gputime] class names. The GPU clock is mapped onto the CPU clock from
calibrated timestamps (VK_KHR_calibrated_timestamps or the EXT version,
enabled only when a trace switch is set) taken when the window opens and
when it closes. A traced thread's wait for the GPU mutex becomes a
GpuMutex.wait.<site> slice, and the shader preparation threads are traced
with smaller buffers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 22:13:44 +02:00
Yunus Shaikh 28ca53dc89 feat(agc): report performance timer scopes to Tracy with APS5_ENABLE_TRACY
APS5_ENABLE_TRACY=ON builds the Tracy 0.14.1 client from the new
3rdparty/tracy submodule as a shared library next to the patched
libraries. Every PerformanceTimer scope of libSceAgcDriver and
libSceVideoOut becomes a Tracy zone, each presented flip ends a frame,
and the queue workers and the presenter name their threads. The client
listens only on localhost and records only while a profiler is
connected; sampling, system tracing, call stacks, code transfer and its
crash handler are off. Without the option nothing of Tracy is compiled.

On MinGW the client is built without thread_local destructors and with
TRACY_DELAYED_INIT, because emulated TLS frees thread_local objects
before their destructors run; a thread's event producer then stays
alive until the process exits instead of being destroyed on freed
memory.
2026-10-12 12:55:40 -07:00
Adrià FranchandClaude 6116fc75e1 docs(agc): say the last present of a trace window has no folded sample
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-12 21:42:59 +02:00
AlxcBTWandClaude Opus 5.5 5668e0d0e7 feat(agc): record a present window as a Chrome trace and a summary line
APS5_TRACE_FRAMES=<start>:<count> (or APS5_TRACE_SECONDS=<start>:<length>)
records every PerformanceTimer scope and stage of the queue workers and the
presenter inside the window as complete events, named after their frame
timing keys, into a preallocated buffer per thread. Slices under 20 us are
counted per thread instead of written; a full buffer stops that thread and
sets trace_dropped. When the window closes, a ProfileOutput writer thread
writes aps5-trace-<commit>-<pid>.json.gz and appends one line to
aps5-summary.jsonl. Without either switch a PerformanceTimer costs one more
predictable branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 21:42:59 +02:00
AlxcBTWandClaude Opus 5.5 428963d3b3 feat(agc): write the worker sampler's stacks as collapsed stacks
APS5_SAMPLE_WORKER=<file> now also writes <file stem>.collapsed.txt: one
"frame;...;frame count" line per distinct stack of queue worker 0, root
first, frames as module+0xRVA, which speedscope.app and flamegraph.pl
open. Walks go up to 64 frames, and nothing allocates while the worker is
suspended.

The libraries are built with -fno-asynchronous-unwind-tables, so most of
their functions have no .pdata entry, only a DWARF record in .ehfram, and a
walk ended at the first such frame. The worker's walk now steps those
frames through their record, with the CIE/FDE decoding and the call frame
instructions of libc's unwinder, which move from Unwind.cpp into its
header unchanged. A module is indexed after the worker resumes, the first
time a walk meets it, and every register the step restores is read inside
the worker's stack. The process sampler (APS5_SAMPLE_THREADS) keeps its 12
frames through .pdata.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 21:23:11 +02:00
PrintOrb 5c19601a12 fix(videoout): require bundled SDL XRandR support on Linux 2026-10-11 17:36:12 -05:00
Adrià a93947040c Merge pull request #3836 from nyavana/docs/libs-build-testing-refresh-20261011
docs(build): clarify when explicit libs target is required
2026-10-12 00:09:13 +02:00
Adrià 06664a44cd Merge pull request #3717 from jweidenh/codex/nvidia-pipeline-replay
feat(agc): capture and replay compute pipeline compilation
2026-10-11 23:54:52 +02:00
Adrià 4989809b13 Merge pull request #3705 from MarcZX100/fix/asan-guest-arena-window-3634
feat(build): support Linux AddressSanitizer builds
2026-10-11 23:53:19 +02:00
jweidenh 3740c233bc fix(agc): accept core Vulkan capabilities during compute replay 2026-10-11 16:34:26 -04:00
jweidenh a4ae6d7e31 fix(agc): capture larger compute modules and binding flags 2026-10-11 16:14:44 -04:00
jweidenh decbac9bb4 fix(agc): link capture tests with the Windows exception runtime 2026-10-11 16:09:48 -04:00
jweidenh 8fbd0eecc1 feat(agc): capture and replay compute pipeline compilation 2026-10-11 16:09:48 -04:00
nyavana 42062da564 docs(build): clarify when explicit libs target is required 2026-10-11 10:28:32 -07:00
MarcZX100 e56a727375 feat(build): support Linux AddressSanitizer builds 2026-10-11 15:40:36 +00:00
marshmll 3d83999350 fix(build): require an SDL audio backend on Linux
The bundled SDL builds its PipeWire, PulseAudio and ALSA drivers only
when their development files are found, and otherwise keeps just the
silent dummy and disk drivers without an error. The Linux CI and
release jobs install none of them, so the v0.1.1 Linux libraries
(libSceAudioOut, libSceAgcDriver, libfmod) contain no audible driver.

Fail configuration on Linux when SDL found none of the three, install
the Debian development packages in the Linux build and release jobs,
and list the packages in the build instructions.
2026-10-11 10:34:29 -03:00
husari.orozco ce6edc5a00 build: reject an SDL2 without HIDAPI and fall back to shared SPIRV-Tools
A system SDL2 that does not define SDL_JOYSTICK_HIDAPI (sdl2-compat over
SDL3 ships no such macro, and neither does a build with the driver
disabled) fails pad_sdl and makes the disk audio driver open the port
with a different channel count, so ANYPS5_USE_SYSTEM_DEPS=ON now rejects
it with a named error, like the VK_KHR_maintenance8 check. Ubuntu's real
SDL2 defines the macro through its SDL_config.h indirection and is
unaffected.

SPIRV-Tools only exports SPIRV-Tools-static when built with
SPIRV_TOOLS_BUILD_STATIC=ON; distributions that ship it shared expose
SPIRV-Tools instead, so a shared target is aliased to the static name.
2026-10-11 10:18:23 +02:00
husari.orozco 96ad950914 build: add ANYPS5_USE_SYSTEM_DEPS option
Resolve SDL2, freetype, Vulkan-Headers, SPIRV-Headers, glslang and
SPIRV-Tools from the system instead of the bundled submodules when the
option is ON. It is OFF by default, so the bundled build is unchanged.

Every package is required: a missing one, or Vulkan-Headers older than
1.4.310 (the agc driver uses VK_KHR_maintenance8), fails the configure
with an error and nothing falls back to the submodule. The system
packages are exposed under the same target names the bundled path uses,
so the rest of the CMake is untouched.

SDL2 is linked from the system as a shared library because the prx
libraries are shared objects and distribution static SDL2 is usually not
PIC. ffmpeg-core, libjpeg-turbo, stb, VulkanMemoryAllocator and LibAtrac9
stay bundled.
2026-10-11 10:18:10 +02:00