Commit Graph

632 Commits

Author SHA1 Message Date
boykopovar 4c6a929657
Merge pull request #89 from adriadam10/pr-template
docs: add pull request template with the review checklist
2026-09-28 21:45:35 +03:00
boykopovar 8ccfbb9fe6
Merge pull request #95 from boykopovar/fix/tests-agc-main
Fix/tests agc main
For tests:
- `agc_driver`
- `agc_driver_flip`
- `agc_driver_pm4`

Fixed dispatch error propagation and updated checks for asynchronous suspend points and memory synchronization. All 54 tests pass with these changes, restoring a passing test suite on `main` after merge.
2026-09-28 19:39:59 +03:00
boykopovar 829e8c14ae fix(tests): align agc flip waits and memory synchronization checks 2026-09-28 19:32:43 +03:00
boykopovar 1f595d883a fix(agc): propagate dispatch worker failures to waiting threads 2026-09-28 19:29:49 +03:00
boykopovar 53bda68c2b
Merge pull request #11 from adriadam10/main
feat(tools): progress map and pull request progress reports
2026-09-28 18:50:00 +03:00
boykopovar 5b4c9c6f73
Merge branch 'main' into main 2026-09-28 18:45:15 +03:00
boykopovar 87633fc4e8
chore(tools): move progress.py description from repo to pr 2026-09-28 18:42:44 +03:00
boykopovar 417b66323f
chore(readme): remove dup progress map info from readme 2026-09-28 18:39:17 +03:00
boykopovar f105cb9bdf
Merge pull request #94 from boykopovar/fix/black-frame-blick
fix(agc): preserve  inputs for deferred  buffer copies
Closing the display window now requests a normal exit instead of calling std::terminate(). Shutdown cancels queued work, wakes blocked waits, joins GPU workers and background helpers, and releases GPU resources before destroying the window on its owning thread. Shutdown cancellation is handled separately from runtime errors.
2026-09-28 18:35:41 +03:00
boykopovar 39fd90b050 fix(kernel): orderly shutdown when closing the display window 2026-09-28 18:30:34 +03:00
boykopovar 143aec54c2 fix(agc): preserve inputs for deferred buffer copies 2026-09-28 18:08:09 +03:00
Adrià Franch d074f6e36f docs: link the pull request template to the contributing guide
Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-28 16:06:33 +02:00
Adrià Franch b4c1887752 docs: add pull request template with the review checklist
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-28 15:42:29 +02:00
boykopovar c6a3e25573
Merge pull request #88 from boykopovar/fix/static-link-nid-patcher
fix(nid): always static linking for nid patcher
Using static linking of the standard library for nid patcher.
2026-09-28 16:38:06 +03:00
boykopovar 8e78ea0c28 fix(nid): always static linking for nid patcher 2026-09-28 16:28:11 +03:00
boykopovar 7b81a4de3d
Merge pull request #87 from boykopovar/fix/build-test-json2fiber
fix(build): link json and fiber tests with libc
Fix test linking by adding `libc` to the `guest_json_tests` and `fiber_tests` link dependencies, resolving the missing `__gxx_personality_v0` symbol.

Ran all 54 CTest tests in. The build was successful.
Currently **50 passed, 4 failed**.
`guest_json` and `fiber` passed.

The following tests failed with code `0xc0000139`:

- `agc_driver`
- `agc_shader_memory`
- `agc_driver_flip`
- `agc_driver_pm4`
2026-09-28 14:25:12 +03:00
boykopovar 64732a64b6 fix(build): link json and fiber tests with libc 2026-09-28 14:18:35 +03:00
boykopovar d65a8ee633
Merge pull request #74 from SamG-Coder/main
fix(shader): support byte permutation and fix compiler lifetime bugs
Adds `V_PERM_B32` byte selection and fixes two existing bugs exposed while testing it: IR equality could merge buffer reads with different metadata, and concurrent shader compilation could crash during Windows thread-local destruction.

- Include instruction flags when comparing IR values so selections between different buffer offsets survive constant folding.
- Decode RDNA2 opcode `0x344` and translate all byte selectors through existing integer IR and the SPIR-V backend, including sign replication, zero/ones fill, and overlapping destinations.
- Reuse the existing `HostThreadLocal` helper for six destructible compiler scratch objects. Add async worker/destructor checks to the existing lifetime test. Scratch storage remains reusable.
2026-09-28 13:51:18 +03:00
boykopovar 0fe554943a
Merge pull request #73 from julienlgy/feat/lib-sce-mouse
feat(libSceMouse): implement stateful mouse API exports
Replace the libSceMouse stubs with an implementation that follows AnyPS5’s existing NID-based library integration. Mouse input comes from the host SDL event loop; this change does not add memory hooks or direct access to console HID devices.

Manage the mouse handle, button state, timestamps, and a thread-safe, 64-event history in src/mouse_impl.cpp. Reads are non-blocking.

Forward relative motion, supported buttons, vertical scrolling, and horizontal scrolling from libSceVideoOut’s SDL event loop.

Release pressed buttons when the window loses focus without reporting a hardware disconnection.
2026-09-28 13:45:13 +03:00
boykopovar 0bbc29ee14
Merge pull request #76 from boykopovar/fix/frame-flicking
Fix/frame flicking
## Summary

Fixed corrupted frames caused by guest input buffers being overwritten before GPU execution.

## Cause

Draws referenced mutable guest memory. The CPU could overwrite an input buffer after the draw was recorded but before the GPU consumed it.

## Detection

Instrumentation compared input-buffer contents at draw recording and GPU execution. Corrupted frames contained mismatches in buffers used by affected draws; adjacent correct frames did not.

## Changes

The recorder now creates per-draw copies of read-only CPU input buffers and keeps them alive until GPU completion. Each draw uses descriptors referencing its preserved data.

Buffers with pending GPU writes remain on the existing path and are not copied from CPU memory.
2026-09-28 13:41:13 +03:00
boykopovar 9f1c680b38 fix(agc): preserve per-draw input buffer contents until gpu completion 2026-09-28 13:35:53 +03:00
boykopovar 76f1d48e60 debug(agc): detect gpu input buffer changes between recording and execution 2026-09-28 13:27:14 +03:00
boykopovar 73e031a4dd perf(agc): downsample frame captures on GPU and queue disk writes 2026-09-28 13:06:15 +03:00
SamG-Coder 8cef034172 fix(shader): safely destroy compiler thread-local storage on Windows 2026-09-28 19:54:01 +10:00
Julien Legay ddb8add753 feat(libSceVideoOut): route SDL mouse events to libSceMouse
Forward relative motion, supported button transitions, and horizontal and vertical scrolling from the existing SDL event loop. Reset pressed buttons on focus loss without reporting a device disconnect, and track window close and refocus transitions.

Link libSceVideoOut to the mouse library using the existing Pad integration pattern. Add targeted coverage for API errors, event mapping, focus changes, history overflow, and reopening.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-28 11:45:31 +02:00
Julien Legay 8fac768b9c feat(libSceMouse): implement stateful mouse API exports
Keep the existing Export.cpp entry point and System V ABI while moving mouse state into the library implementation.`n`nTrack initialization, a single handle, button state, timestamps, and a bounded non-blocking event queue. Define and assert the guest MouseData layout and expose an input publisher for the host backend.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-28 11:45:04 +02:00
SamG-Coder 730de17774 fix(shader): support V_PERM_B32 byte selection 2026-09-28 19:35:18 +10:00
SamG-Coder 80a64ccd6b fix(shader): distinguish IR values with different instruction flags 2026-09-28 19:35:18 +10:00
boykopovar cdc95d9a70
Merge pull request #70 from SamG-Coder/main
fix(shader): support scalar bit operations and 64-bit SAVEEXEC
2026-09-28 11:57:56 +03:00
boykopovar 45817c1b4c
Merge pull request #72 from boykopovar/fix/stop-if-window-closed
fix(video): terminate process on gpu and presentation thread failures
Now, any expression that reaches the handlers of a GPU worker, presentation thread, or vblank calls std::terminate() and terminates the entire process.

A closed window is just one of these cases. Previously, the handlers stored and propagated the error, which allowed the process to continue.

The normal shutdown with stopping all guest threads is not implemented.
2026-09-28 11:53:43 +03:00
boykopovar 0d29a0a316 fix(video): terminate process on gpu and presentation thread failures 2026-09-28 11:46:18 +03:00
SamG-Coder 198b43c985 fix(shader): support additional 64-bit saveexec operations 2026-09-28 18:37:51 +10:00
SamG-Coder 2e398be5a0 fix(shader): support scalar conditional move and zero-bit operations 2026-09-28 18:21:34 +10:00
boykopovar 8bd030d531
Merge pull request #26 from QDarkRex/fix/kernel-error-codes
fix(kernel): use SCE kernel error codes in equeue, direct memory and mutex
| Constant | Before | After |
|---|---|---|
| `EQUEUE_ERROR_ETIMEDOUT` | `0x80010023` | `0x8002003C` |
| `EQUEUE_ERROR_EBADF` | `0x80010016` | `0x80020009` |
| `EQUEUE_ERROR_ENOENT` | `0x80010011` | `0x80020002` |
| `EQUEUE_ERROR_EINVAL` / `SCE_KERNEL_ERROR_EINVAL` (DirectMemory) | `0x80010005` | `0x80020016` |
| `EQUEUE_ERROR_EFAULT` / `SCE_KERNEL_ERROR_EFAULT` (DirectMemory) | `0x80010009` | `0x8002000E` |
| `SCE_KERNEL_ERROR_EAGAIN` (DirectMemory) | `0x80010002` | `0x80020023` |
| `SCE_KERNEL_ERROR_ENOMEM` (DirectMemory) | `0x80010007` | `0x8002000C` |
| `SCE_KERNEL_ERROR_EACCES` (DirectMemory) | `0x80010004` | `0x8002000D` |
| `SCE_KERNEL_ERROR_EDEADLK` (Mutex.cpp) | `0x80020023` (= EAGAIN) | `0x8002000B` |
2026-09-28 11:18:14 +03:00
boykopovar 089685b93d
Merge pull request #25 from QDarkRex/fix/audit-2026-09
fix(kernel,audioout,relinker): thread/mutex correctness fixes and --windows-gui
### libkernel (threads, mutexes, condition variables)
- **Deadlock in `scePthreadCondTimedwait` (normal/error-check mutexes):** `_owner` was not restored after the wait. If another thread locked and unlocked the mutex during the wait, the waiter woke up owning the mutex while `_owner` was empty. Its next `scePthreadMutexUnlock` returned `EPERM`, leaving the mutex locked forever (`lock → timedwait → unlock` pattern).
- **Wrong timeout code:** `SCE_KERNEL_ERROR_ETIMEDOUT` in `Cond.cpp` was `0x80020062`; it is `0x8002003C` (FreeBSD `ETIMEDOUT` = 60, matching `Semaphore.hpp`).
- **`scePthreadSelf()`** returned `nullptr` on Linux, and on both platforms for threads not created by `scePthreadCreate` (including the main thread). Such threads now get a lazily adopted, non-joinable handle (`scePthreadJoin`/`Detach` on it return `EINVAL`).
- **Linux `scePthreadExit`** skipped `FinishThread`, so `scePthreadJoin` got a garbage return value. Cleanup now runs from an RAII guard, so it survives glibc forced unwinding.
- **Linux detached threads** were never freed. They now use the same reference count as on Windows.
- **Recursive mutex unlock** by a non-owner, or with a zero count, was UB (`std::recursive_timed_mutex::unlock`). It now returns `SCE_KERNEL_ERROR_EPERM`, and `_owner`/`_count` are also saved and restored around a recursive cond wait.
- **`sceKernelLseek`** returned `int` instead of `off_t`; offsets above `INT_MAX` threw.
- **`sceKernelDeleteSema`** implemented: waiters are woken with `SCE_KERNEL_ERROR_EACCES` and the object is freed once they leave.

- `sceAudioOutOpen` accepted `freq == 0` / `len == 0`; the frequency was later used as a divisor. It now returns `SCE_AUDIO_OUT_ERROR_INVALID_SAMPLE_FREQ` / `INVALID_SIZE`.
2026-09-28 11:09:59 +03:00
boykopovar c745e276c1
Merge pull request #66 from SamG-Coder/main
fix(shader): translate scalar byte and short sign extension
2026-09-28 11:00:37 +03:00
boykopovar accc5e5a6c
Merge pull request #67 from boykopovar/refactor/optional-timing-logs
refactor(agc): make frame timing logs optional by cmake option
Added the CMake option `APS5_ENABLE_TIMING_LOG`, which defaults to `OFF`. To enable it: `-DAPS5_ENABLE_TIMING_LOG=ON`.
`[FrameTiming]` log for each frame is only output if this option is enabled.
2026-09-28 10:55:48 +03:00
boykopovar 94c443e32f refactor(agc): make frame timing logs optional by cmake option 2026-09-28 10:51:29 +03:00
SamG-Coder f7f60b4ec5 fix(shader): translate scalar byte and short sign extension 2026-09-28 17:49:09 +10:00
Claude a60256ea4d
fix(kernel): exit POSIX guest threads without forced unwinding
On Linux scePthreadExit called pthread_exit, whose forced unwind runs
the personality routine of every guest frame. Those resolve to
libc.prx's __gxx_personality_v0, which cannot read libgcc's unwind
context and aborts, so guest_thread_self crashed on Linux.

Record a jump target in the thread start routine and longjmp back to it
from scePthreadExit instead. Like _endthreadex on Windows, this skips
the guest frames without unwinding them; the start routine still
releases the thread normally. Threads not created by scePthreadCreate
keep the pthread_exit fallback.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018emyZ4Rk8yoSJvxTFBe4DL
2026-09-28 07:47:12 +00:00
Claude a28cfb7585
Merge upstream main into fix/kernel-error-codes
Resolve the conflict with boykopovar/AnyPS5#10 in Pthread/src/Mutex.cpp
by taking upstream: its rewrite already returns EDEADLK as 0x8002000B.
The equeue and direct memory error code fixes are unaffected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018emyZ4Rk8yoSJvxTFBe4DL
2026-09-28 07:36:16 +00:00
Claude 210987745c
Merge upstream main into fix/audit-2026-09
Resolve conflicts with boykopovar/AnyPS5#10 (sce module loading) and
later upstream changes.

- Pthread Cond/Mutex: take upstream. It already releases mutex
  ownership across condition waits, returns ETIMEDOUT 0x8002003C, and
  rejects unlocks from non-owners for every mutex type.
- Pthread Thread: keep upstream's lifecycle, Windows adoption and job
  affinity; re-apply the POSIX fixes on top: reference-counted
  release on join/detach/exit, self-join rejection on both platforms,
  and scePthreadSelf adoption for threads not created by
  scePthreadCreate.
- Semaphore: keep upstream's TimedWait::Condition and wait tracing;
  re-apply sceKernelDeleteSema waking waiters with EACCES.
- Relinker: keep --windows-gui alongside upstream's --skip-sce-module,
  trampoline-aware Patch signature and new Python tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018emyZ4Rk8yoSJvxTFBe4DL
2026-09-28 07:34:25 +00:00
boykopovar 34f0379d8a
Merge pull request #48 from oneandonlydean/feat/linux-fibers
feat(fiber): implement fibers on linux
The state machine, the cross-thread resume handling and the entry trampoline are now shared between platforms. Only the context switch differs:
- `Aps5FiberSwitchStack` saves the SysV callee-saved set (`rbp rbx r12–r15`, MXCSR and the x87 control word) instead of the Win64 set.
- `Aps5FiberTrampoline` passes the fiber in `rdi`.
- There is no TIB to update, so `CurrentBounds`/`SetBounds` do nothing on Linux.
2026-09-28 10:22:04 +03:00
boykopovar 3b4e4f6de6
Merge pull request #65 from SamG-Coder/main
fix(agc): keep BGRA color targets resident between draws
BGRA color targets fail the exact guest-texture-format lookup and fall back to a synchronous framebuffer round-trip for every draw. This keeps them resident using compatible RGBA storage with the original BGRA attachment view. Presentation checks the actual display channel order, attachment views request only attachment usage, and host-write barriers include the host stage.

This follows the existing linked PRX/Vulkan path. It adds no interpreter, separate runtime process, or new shader compilation path.
2026-09-28 10:07:16 +03:00
boykopovar 861e79acfc
Merge pull request #62 from oneandonlydean/feat/agc-acb-markers
feat(agc): ACB markers, index buffer unbinding and address in errors
- The DCB marker helpers move from an anonymous namespace in `DcbState/src/Marker.cpp` to `Agc::Marker::Push`/`Pop` (declared in `Marker.hpp`). The ACB entry points use the same helpers, so ACB and DCB markers produce the same custom NOP packets. `SetMarker` is a push followed by a pop, and returns the push packet, as on the DCB. The color is ignored on both, as before.
- `sceAgcDcbSetIndexBuffer` emits the packet with address 0 instead of rejecting it. A non-null address still has to be 2-byte aligned.
- `Agc::Command::CheckAddress` includes the rejected address in its message.
2026-09-28 10:03:44 +03:00
boykopovar 6686e15ee4
Merge pull request #61 from oneandonlydean/feat/agc-dma-gds
feat(agc): DMA_DATA cache policy hints and GDS source/destination
- **Cache policy:** the source (bits 13–14) and destination (bits 25–26) cache-policy fields of `DMA_DATA` dword 1 are accepted. They're cache hints with no effect on the copied data. The remaining reserved bits are still rejected.
- **GDS storage:** GDS is modelled as one 64 KiB, zero-initialised store shared by the whole device, behind a mutex.
- **GDS source/destination:** select `1` reads from or writes to that store:
  - the validator requires the high address dword to be 0 and the range to fit inside the 64 KiB;
  - `Execute` copies between memory, immediate data and GDS in any combination;
  - `ResolveStore` returns nothing for a GDS destination, since there's no guest memory to write, and for a GDS source it resolves the bytes from the store.
- Register and prefetch destinations are still rejected.
- Nothing is faked for shaders: a shader that uses GDS still fails validation (unsupported descriptor role).
2026-09-28 09:59:54 +03:00
boykopovar 3fe80624f7
Merge pull request #60 from oneandonlydean/fix/primitive-restart-indexed
fix(agc): reject primitive restart only for indexed draws
- `DecodeState` still reads `0x24b` (so it stays in the recorded draw-key registers) but no longer rejects on it.
- `DrawRejection` takes an `indexed` flag, and reports restart only for indexed draws.
- The driver's draw path rejects an indexed draw with restart enabled before the precheck, so indexed draws with restart are still refused when the precheck is off. Restart itself is still not implemented.
2026-09-28 09:56:37 +03:00
boykopovar 9f2da178ef
Merge pull request #59 from oneandonlydean/fix/retain-replaced-device
fix(agc): keep a replaced Vulkan device alive
In the presenter path, after `PrepareForReplacement()` (which flushes cached textures, publishes shadows and waits for idle), the old device is kept in a function-local static list instead of being released. Its child objects stay valid for as long as anything still refers to them. The cost is one idle device for the life of the process; the replacement happens once, at the first flip.
2026-09-28 09:51:55 +03:00
Dean Galvin 0c06382d89 feat(agc): ACB markers, index buffer unbinding and address in errors
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ButHENCbXXt8h4EZuWUabJ
2026-09-28 19:47:33 +13:00
Dean Galvin 41fb65761f refactor(fiber): keep the assembly entry points out of NID patching with _nid_no_patch
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ButHENCbXXt8h4EZuWUabJ
2026-09-28 19:46:38 +13:00