Skip to content

sync(upstream): integrate Batch 41 shader recompiler, libc builtins, and AGC page-cache fixes - #571

Merged
RINNECODER merged 27 commits into
mainfrom
team/upstream41
Oct 19, 2026
Merged

RINNECODER merged 27 commits into
mainfrom
team/upstream41

Conversation

@RINNECODER

Copy link
Copy Markdown
Owner

Summary

Batch 41 upstream sync (fork RINNECODER/AnyPS5, upstream boykopovar/AnyPS5), from the Batch 40 pin fb9a1eb8f to upstream a6dd29b3d. 27 upstream commits applied with git cherry-pick -x (~24 upstream PRs) across libSceAgcDriver, the shader recompiler, relinker, libkernel and libc. Diff: 56 files, +2398 / -82.

Integrated

Shader recompiler (10)

  • rect-list tessellation coordinates rounded to nearest integer; rect-list corner vertex pinned
  • quad-mask: kill demoted helper pixels at the pixel program return; all-zero clip position distance omitted when guest clip+cull distances fill all eight
  • multisampled array images mapped to Image2DMultisampleArray in DescriptorBindingBuilder
  • integer compares folded by value sets and known bits; relative-indexing known-bits test skip

libc (7)

  • fmaf, remquo/remquof, copysign/copysignf
  • 16-byte __sync builtins and __atomic_is_lock_free
  • safe wide-string and concatenation functions (Annex K)
  • C11 runtime constraints in snprintf_s/vsnprintf_s
  • compiler-rt integer builtins: __clz*/__ctz* of zero

libkernel (3)

  • release flexible memory budget through munmap; semaphore wakeups across cancellation
  • serialize Windows ftruncate with positioned transfers

relinker (2)

  • preserve weak imports in guest module registries; Windows executable hard-link input preservation

AGC / Metal (5)

  • guest read checks answered from the page table (small reads without /proc/self/maps); inaccessible guest pages cached
  • transient copy buffers counted toward the recorder budget; presenter takes the newest collect epoch
  • preparation-failure shader dumps named apart; revalidate profile per 10 s window; depth-clear test cases

Gates (HEAD 53e4acdcd)

Gate Result
tools/check_conventions.py --base origin/main pass, 0 findings
Rosetta build + CTest exit 0, 25/25 passed
Metal (guest-replay) build + CTest exit 0, 63/63 passed
Replay agc-map hash 51a268f2e73efb9c bit-exact
Replay agc-live-map vs 2ac97dd56 baseline 80 px (allowed 200), 0 timed repeats over
Replay agc-menu vs 2ac97dd56 baseline 84 px (allowed 200), 0 timed repeats over

Both configs were built with CCACHE_NODIRECT=1; replay ran under the shared AGC lock, one process at a time.

Skipped (with reasons)

  • Missing MultisampleTarget ownership infra (Batch 40 skipped it): 729558cc6, 026e69fa6, 69afb0569, 24bc68375, ba4571a25, c83a7531e, 785f8f7bcf, 65f6549e0.
  • Missing ComputePipelineCapture.*: b79bf445e, a437891eb.
  • Missing relinker game-patch pipeline (Conversion.cpp, GamePatchTests.cpp): 346b0a92c + its test commits.
  • Missing shader image-table test file (ImageTable.cpp): 486f3069a.
  • Windows-only libc (WindowsDescriptor.hpp absent): 0b24f92a6.
  • GuestMemory write-tracker divergence (fork uses writtenBlocks/leaf structure; upstream uses coarseBlocks/userAddressLimit): 5532d51fb, 192d95c5d, 4a9640677, a64d03815.
  • Windows profile text + HDR passthrough scaler divergence: cb3d1d1dc.
  • relinker dead-code removal, RelinkerPipeline.cpp diverged: d4b40a37f.
  • preinit revert c3b900159: the fork intentionally keeps guest preinit arrays (Batch 40 feature).
  • Dropped after the replay gate: fix(shader): preserve pixel helper lanes in EXEC copies — expands pixel EXEC masks to whole quads via WqmU64; changes live-map rendering by ~670 px and fails the 200 px gate. Deferred.
  • Dropped after tests: perf(shader): share folded SPIR-V constants and drop identity bitcasts — breaks the fork's anyps5_metal_shader_disk_cache invariant (SpecializeSpirv(module(4)) == module(6)).
  • Already integrated / empty (fork has newer code): compiler-rt integer and float builtins re-lands, POSIX steady_clock fast path, Image2DMultisampleArray in GuestTextureResource, inverted scissor, short mesh draw, wave64 ordered-count.

Upstream boykopovar#6094

Re-attempted cde860417 + d35a29a92 (32-bit buffer atomics act on the containing dword). Both cherry-pick cleanly, but anyps5_metal_rect_replay and anyps5_metal_guest_draw_replay fail: the module ends with no page-table/fault-buffer binding and the Metal bridge rejects it ("BDA ABI requires page-table or fault-buffer descriptor metadata"). Adapting the bridge would require accepting a BDA module with neither role, which weakens the BDA safety contract. Left reverted and deferred.

Review

The chatgpt-codex-connector review is out of quota for this account, so no findings were produced. The local gates above are the evidence for this head.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ⚠️ Failed 2026-10-19T00:58:38.667869Z 53e4acd PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: f9d1f61b-7277-4c25-8e1c-98c660eb07b6
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

ivica00 and others added 27 commits October 18, 2026 20:03
…t-list evaluation

In rect-list tessellation evaluation, gl_TessCoord coordinates (x, y) generated by hardware tessellators are floating-point values in [0.0, 1.0]. Direct integer truncation via OpConvertFToS causes coordinates that evaluate slightly below 1.0 (e.g. 0.999999f) due to hardware fixed-point representation to truncate to 0 instead of 1, collapsing rectangle vertices along the diagonal.

Adding +0.5f rounding prior to OpConvertFToS ensures correct mapping to {0, 1} quad vertex indices.

(cherry picked from commit 72f8219)
…k_free

__sync_fetch_and_{add,sub,and,or,xor}_16 and __sync_lock_test_and_set_16 are
cmpxchg16b loops returning the previous value, and __atomic_is_lock_free
answers by size and alignment, as in the libc.prx bundled with PPSA08427. Its
generic __atomic_load/store/exchange/compare_exchange are a ud2, so they throw.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q8tinbP1MUpUaDsbNWnGnu
(cherry picked from commit 6d2708a)
… corner

A coordinate just below 1 truncates to the wrong vertex. The generated evaluation shader is checked at each corner, and a draw records the vertex that lands on each corner of the rectangle.

Co-authored-by: Cursor <cursoragent@cursor.com>
(cherry picked from commit 6972e88)
… fills against a UAV clear

Each case re-activates the test device's recorder, and the DCB submit re-activates the recorder of the second device it creates, so the cases no longer depend on the order they run in. PlaneFillCase checks that a plane fill before a UAV clear is overwritten by it and a plane fill after it wins.

(cherry picked from commit bb86b5f)
IEqual32 and INotEqual32 against a constant fold when the other
operand has a value set of at most 64 values (built through shifts,
bitfield extracts, and/or/xor/mul/umin with a constant, add and
select) that excludes the constant or holds only it, or when a known
bit of the operand contradicts the constant. Known bits come from
constants, shifts and bitfield extracts by constants, and/or/xor, add
(up to the first unknown bit), mul (trailing zeros), umin, select, phi
and lane reads. The value set of x & mask leaves out the known bits of
x. ULessThan32 against a constant folds from the known-bit and
value-set bounds.

A fold pass computes the known bits and value set of each compared
operand once, so a chain of compares against one operand does not
repeat the analysis, and a sum is not enumerated when its two operand
sets hold more than 65 values together, since without wraparound it
then has more than 64 values.

All folds are identities of the operand's possible values; out-of-range
M0 handling of the relative indexing lowerings is unchanged. With
M0 = 4i + k, three of every four entries of an s_movrels/s_movreld
compare chain fold away.

(cherry picked from commit 4064ff4)
…ntf_s

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit e9f4dbf)
(cherry picked from commit 6e3ae1c)
…urns

A pixel that PA_SC_AA_MASK leaves uncovered is demoted to a helper
invocation so the covered pixels keep their derivatives. When the guest
exports under an EXEC mask that clears that lane, the colour output is
never written. On the Radeon 860M (Windows driver 32.0.13058.8001) such
a demoted invocation still writes undefined colour to the target, so
agc_driver_quad_pixel_mask fails at its first implicit-LOD sample under a
partial mask (2). Killing the uncovered invocations at the return, after every
derivative is taken, discards them on every driver.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 79d72b6)
Co-authored-by: Codex <noreply@openai.com>
(cherry picked from commit 5054b67)
…ances fill all eight

A vertex or tessellation evaluation program whose PA_CL_VS_OUT_CNTL
enables eight guest clip distances (CLIP_DIST_ENA 0xff, both distance
vectors) failed to compile with "guest clip distances plus the all-zero
clip position distance exceed 8 clip distances", at registration and at
the draw. A program whose guest clip and cull distances together take
eight (four of each, say) compiled, but its draw failed in the pipeline
validator with "more than eight clip and cull distances in one shader".

The all-zero position distance is now added only while the guest clip and
cull distances leave one of the eight slots free. Otherwise the program
keeps its guest distances, and a primitive with a vertex at clip position
(0,0,0,0) is not removed; the EmitSetAttribute debt entry says so.

agc_position_invariance compiles one program with seven and eight clip
distances, and with three and four clip distances beside four cull
distances: the clip distance arrays are 8, 8, 4 and 4, so the all-zero
position distance is in the first and third only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 5c29d12)
On Linux kernels without PROCMAP_QUERY (before 6.11, which includes the
stock Ubuntu 24.04 kernel), every guest range check that misses the page
cache reads and parses /proc/self/maps up to the covering mapping. The
cache only covers the guest arena and the image, so ranges in the host
heap always miss. ASTRO BOT (PPSA21564) checks 96-byte shader headers
there from RegisteredHeader (through SameHeader) on every
sceAgcCreatePrimState and interpolant mapping, about 3,700 times per
second while it loads.

A read-only check of at most 4 KiB on such a kernel now first reads the
range into a scratch buffer with process_vm_readv on the own process.
If every byte is read, the range is readable. Anything else (a fault,
a partial read, a refused call, a write check or a larger range) takes
the path it took before, which also builds the failure message.

agc_driver_graphics runs a second time with APS5_NO_PROCMAP_QUERY=1, so
the fallback path is covered on kernels that have PROCMAP_QUERY too, and
LiveStack gains read-only checks: a readable range, and ranges that end
in a guard page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit eb6b567)
…age table

The process_vm_readv probe answered a small read check before the page
table was looked at, so a page the table holds as inaccessible (as boykopovar#6184
records them) read as accessible whenever the host page was readable. The
probe now runs only for ranges with no recorded page state.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 4c50918)
…aptures

With APS5_DUMP_SHADERS set, PrepareShaderWithDiagnostics wrote a request
whose preparation failed under the same shader_<address>.req name that
dispatch and draw captures use. A preparation request has no captured
resources: the registration-time one carries placeholder (zero) user
data and only the code and header memory. Replaying such a file as a
dispatch capture follows the null user-data pointer into the SRT and
fails in SrtWalker, which looks like a walker bug but is not one.

dumpRequest also de-duplicated by address, so once a preparation
failure had been dumped, a later dispatch dump of the same shader was
silently dropped and the real capture was lost.

Preparation-failure dumps are now written as shader_<address>.prepare.req,
and dumpRequest de-duplicates by file name, so the later dispatch dump
of the same address is still written. agc_shader_replay's usage text
says to replay .prepare.req files with --prepare.

The FailureCapture test expects the .prepare.req name, no plain .req
from a preparation failure, and a subsequent dispatch dump of the same
address to be written with the serialized request.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 1db31b9)
Remember inaccessible arena pages and Linux mapping gaps so repeated access checks do not rescan host mappings. Invalidate the cache when guest stack protections change.

(cherry picked from commit 13a3902)
Charge read-only GPU-copy input snapshots and depth-copy linear scratch for their requested bytes while the batch retains them. Exercise both production paths with CPU Vulkan mocks, including the budget boundary and fence-governed resource retention.

Co-Authored-By: Codex <noreply@openai.com>
(cherry picked from commit ea02128)
…ked display image keeps its comparison memo

APS5_NO_PRESENT_EPOCH=1 compares the display surface at every present as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 537bbcc)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.