Commit Graph
5577 Commits
Author SHA1 Message Date
Dean Galvin b57ab5a0e9 feat(recompiler): structurize externally entered selection regions by cloning or route variables
A selection whose region (the blocks reachable from its arms before its
merge) is also entered from outside the header cannot be expressed as a
SPIR-V selection construct, and the structurizer gave up with "semantic
block cloning is disabled". Pixel shaders hit this through a shared
discard tail (s_mov_b64 exec, 0 / exp null / s_endpgm) that several
selections branch to, compute shaders through short-circuit conditions
that jump into a shared body, and ray-traced compute passes through an
s_cbranch_execz that skips past a join into the middle of a selection.

Such a region is made single-entry in one of two ways, chosen per region
by its estimated translated size:

- Cloning (node splitting): the blocks the outside edges reach inside the
  region are copied and the outside edges redirected to the copies. When
  the header's merge is a shared linear return tail, giving the header a
  private copy of that tail is tried first. Each block now carries an
  estimate of the SPIR-V words it translates to. The per-instruction
  weights come from a fit of the recompiler's per-block output (before
  spirv-opt, phis excluded) over 8,300 blocks of captured shaders: VALU
  60, buffer and flat 120, SMEM 180, image 220, LDS 400. SALU (8) and
  exports (20) fit near zero and keep a small weight. Lane ops (120) and
  image_bvh_intersect_ray (2000) were too rare there to fit and are
  weighted for the wave and traversal expansions they need. A region is cloned only when it is at most 1024 estimated
  words and at most an eighth of the program (at least 256), and while
  all clones stay within a quarter of the program.
- Routing through a junction, for larger regions: every edge into the
  entered part (from outside, and from the header's own arms) and every
  edge from the arms to the merge is sent through a new empty junction
  block. Each rerouted edge first passes empty blocks that assign
  Boolean route variables (the IR's goto variables); the junction tests
  them in order to reach the edge's original target. The entered part
  then follows the junction and is emitted once. Branch conditions are
  still evaluated only at the end of their original blocks: a route
  variable records the edge a block already took, so a later SCC, VCC or
  EXEC write cannot change the route, and in the two-lane wave64 layout
  the source branch is combined across both halves as before while the
  route variable holds the same constant in both. Routing is refused
  when a rerouted edge is a back edge or leaves an indirect branch, when
  the region wraps around to a dominating block, or when it would change
  the natural loops or make the graph irreducible; cloning bounded by the
  program's estimated size is the fallback, and otherwise it throws with
  the header, the entered block and both reasons.

Selections whose arms only meet again after private return tails had no
post-dominator merge. When the existing rules find none, the merge is
now looked up with edges into private return tails ignored, or taken as
the other arm when one arm only returns; the candidate must still exit
the construct only through the merge. applyBlockOrder also remaps
indirect branch targets.

agc_shader_control_flow_tests (under ctest) covers hand-assembled
gfx1030 programs: the cloned shapes above, and routed ones (an
s_cbranch_execz into an expensive region with a loop, a region inside a
loop, nested entered regions, a shared body reached after SCC is
overwritten, early returns beside an entered region, an arm that only
returns). It checks that every selection construct exits only through
its merge, follows route variables to check that the structured graph
runs the same instruction ranges under the same branch conditions as
the original, bounds the cloned instructions, recompiles each program
for 64- and 32-lane subgroups, and keeps the routed execz program within
10% of the SPIR-V of the same program without the entering branch.
Given .req files it checks their graphs instead. agc_shader_replay --cfg
prints a request's graph, now with each block's estimate, before and
after structurization.
2026-10-01 08:36:11 +13:00
Dean Galvin 2be78b6965 feat(agc): apply a texture descriptor's MIN_LOD clamp through the image view
T# word1 MIN_LOD (unsigned 4.8, in levels of the whole surface) was
rejected. Sampled views now chain VkImageViewMinLodCreateInfoEXT
(VK_EXT_image_view_min_lod, enabled when the device offers the minLod
feature). Its minLod counts levels of the whole image exactly as MIN_LOD
counts levels of the whole surface, because the image holds every mip and
the view starts at BASE_LEVEL.

- A clamp at or below BASE_LEVEL cannot change which level a sample reads
  and is left off; one past the view's last level is bounded by it (the
  view selects that level anyway, and Vulkan requires the bound).
- A clamp that binds on a device without the feature throws.
- The texture cache already keys by the eight descriptor words, so views
  with different clamps are not shared.
- Storage views address one level: a clamp at or below that level is
  accepted, one above it still throws.
2026-10-01 08:30:05 +13:00
boykopovar a67b644ff6 Merge pull request #192 from MichonGoddijn231849/perf/validation-failure-memo
perf(agc): remember shader validation failures and reject repeats without throwing
2026-09-30 22:12:58 +03:00
Alberto RuizandClaude Opus 5.5 46e63f2ec1 fix(relinker): keep ELF bounds checks from overflowing
ElfReader checked ranges as offset + size > buffer size. An offset near
UINT64_MAX wrapped the sum, passed the check and read outside the buffer,
which AddressSanitizer reports as a heap-buffer-overflow. The relinker
then failed later with unrelated messages built from the stray bytes.
The checks now compare without adding to the offset.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01R5WJS4ZdQynAJesCZKH5hb
2026-09-30 21:06:43 +02:00
boykopovar c71be475fc Merge pull request #187 from MichonGoddijn231849/feat/demons-souls-exports
feat: export the AMPR command buffer waits and writes, sceAgcFuseShaderHalves, sceAgcSetSubmitMode, sceNpSessionSignalingCreateContext and sceNetEpollAbort
2026-09-30 22:03:54 +03:00
boykopovar f59c867a5b Merge pull request #183 from arreina/fix/elf-header-size
fix(relinker): require a full ELF64 header before reading it
2026-09-30 22:03:27 +03:00
boykopovar a54cffadc3 Merge pull request #190 from RomainROCH/fix/buffer-offset-overflow
fix(relinker): reject overflowing buffer offsets
2026-09-30 22:00:51 +03:00
boykopovar 7b767489f3 Merge pull request #172 from STL1te/fix/savedata-params
fix(savedata): the native module keeps save directory params and moun…
2026-09-30 21:46:55 +03:00
boykopovar 78a34f8e82 Merge pull request #180 from oneandonlydean/feat/audioout2-dualsense-ports
feat(audio): play the DualSense speaker and vibration ports on its USB sound card
2026-09-30 21:35:16 +03:00
boykopovar d2d221a123 Merge pull request #179 from oneandonlydean/fix/pad-sdl-hidapi
fix(pad): build SDL with HIDAPI so DualSense output reaches the controller
2026-09-30 21:18:57 +03:00
boykopovar ced561723a Merge pull request #177 from oneandonlydean/fix/agc-storage-image-moved-dcc-keys
fix(agc): remake a surface's storage image when its DCC keys move
2026-09-30 21:18:00 +03:00
STL1teandClaude Opus 5.5 a812d6314a fix(savedata): throw on a param file that cannot be read or has the wrong size
A .param file of a save directory or of save data memory that exists but cannot
be read, or whose size is not sizeof(SaveDataParam), was silently ignored or
truncated. It now throws, naming the file and, for a size mismatch, both sizes.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 21:14:20 +03:00
boykopovar 52ab9e3544 Merge pull request #176 from oneandonlydean/fix/agc-indexed-draw-index-offset
fix(agc): apply GE_INDX_OFFSET as the base vertex of direct indexed draws
2026-09-30 21:13:57 +03:00
boykopovar d7ab5e371e Merge pull request #175 from Qznad/feat/decoder-png
feat(pngdec): implement the PNG decoder
2026-09-30 21:12:56 +03:00
boykopovar bbb15959eb Merge pull request #174 from STL1te/fix/bda-lookup-dontinline
fix(shader): BDA lookup functions are not inlined
2026-09-30 21:12:05 +03:00
boykopovar f583d2638c Merge pull request #165 from MichonGoddijn231849/perf/skip-report-single-write
perf(agc): write each skip report in one call and cap its request dumps
2026-09-30 21:05:39 +03:00
boykopovar 95f34bed3d Merge pull request #171 from asimplestray/feat/kernel-time-signal
feat(kernel): implement Sleep, sigprocmask and pthread finalize
2026-09-30 21:03:48 +03:00
boykopovar c3aed31639 Merge pull request #169 from asimplestray/feat/kernel-file-ops
feat(kernel): implement file metadata ops and address conversion
2026-09-30 21:03:08 +03:00
boykopovar ba1d32f450 Merge pull request #168 from asimplestray/feat/kernel-psem
feat(kernel): implement pthread semaphore lifecycle
2026-09-30 21:01:53 +03:00
boykopovar 6756edb91f Merge pull request #164 from MichonGoddijn231849/fix/munmap-across-mappings
fix(libkernel): unmap ranges that span several mappings
2026-09-30 20:55:43 +03:00
boykopovar c227fe4104 Merge pull request #162 from MichonGoddijn231849/fix/f16-inline-constants
fix(recompiler): read f16 inline constants as half values and honour VOP3 f16 op_sel
2026-09-30 20:42:23 +03:00
boykopovar f66789ada2 Merge pull request #186 from MichonGoddijn231849/fix/host-import-shared-alias
fix(agc): import shared guest memory through a read-write alias and never offer read-only pages
2026-09-30 20:41:23 +03:00
boykopovar fe712e7b9e Merge pull request #101 from asimplestray/feat/rt-miss-config
feat(shader): configurable ray tracing miss fallback
2026-09-30 20:40:33 +03:00
boykopovar 488e678aa8 Merge pull request #161 from asimplestray/feat/libc-lifecycle
feat(libc): implement cxa lifecycle aliases and init_env
2026-09-30 20:35:36 +03:00
boykopovar 9444753275 Merge pull request #188 from MichonGoddijn231849/fix/d16-depth-integer-reads
fix(agc): read a 16-bit integer view of a depth plane as its stored values
2026-09-30 20:24:56 +03:00
MichonandClaude Opus 5.5 f4be8f435d fix(agc): throw when guest memory can be neither imported, aliased nor copied exactly
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-09-30 19:14:22 +02:00
asimplestray 976fa82054 feat(shader): configurable ray tracing miss fallback 2026-09-30 16:53:03 +00:00
asimplestray a4e755ccb1 feat(kernel): implement file metadata ops and address conversion 2026-09-30 16:51:37 +00:00
Alberto RuizandClaude Opus 5.5 a4b131435a fix(relinker): require a full ELF64 header before reading it
ReadHeader reads fields up to offset 0x40 but only rejected files
shorter than 20 bytes, so a truncated ELF failed with
"FileByteOffset out of bounds" instead of "File too small for ELF header".

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01R5WJS4ZdQynAJesCZKH5hb
2026-09-30 18:47:32 +02:00
MichonandClaude Opus 5.5 98d48ec8d2 perf(agc): remember shader validation failures and reject repeats without throwing
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-09-30 18:43:55 +02:00
boykopovar f881e021a8 Merge pull request #160 from asimplestray/feat/libc-wide-io
feat(libc): implement fputwc, fputws and fscanf
2026-09-30 19:40:31 +03:00
RomainROCH 442ffbb936 chore: sync upstream main for CI 2026-09-30 18:37:59 +02:00
boykopovar 60bd808132 Merge pull request #185 from ljkx/feat/insertq-register-form
feat(relinker): lower register-form INSERTQ
2026-09-30 19:37:18 +03:00
boykopovar ec0c39bf6c Merge pull request #158 from carman24r/main
feat(agc): implement register commands and count patching
2026-09-30 19:33:52 +03:00
boykopovar e33abc1ad6 Merge pull request #155 from Pacuka/fix/sysmodule-unload-unknown
fix(sysmodule): unload unknown module ids as no-ops
2026-09-30 19:26:54 +03:00
boykopovar 4bfd97cdef Merge pull request #154 from Pacuka/fix/userservice-invalid-argument
fix(userservice): report invalid arguments as 0x80960005
2026-09-30 19:25:46 +03:00
boykopovar c09b8759b2 Merge pull request #152 from Digote/feat/shader-s-bitcmp-b64
feat(shader): support 64-bit scalar bit compare
2026-09-30 19:25:12 +03:00
boykopovar a6c7eca552 Merge pull request #151 from MartinCajiao/feat/guest-intel-trampolines
feat(relinker): support Intel trampolines in guest modules
2026-09-30 19:24:46 +03:00
MichonandClaude Opus 5.5 2b5f2d32d3 feat: export the AMPR command buffer waits and writes, sceAgcFuseShaderHalves, sceAgcSetSubmitMode, sceNpSessionSignalingCreateContext and sceNetEpollAbort
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-09-30 18:19:55 +02:00
RomainROCH b6ff4a2116 fix(relinker): reject overflowing buffer offsets 2026-09-30 18:07:26 +02:00
boykopovar fc7f1e7fd1 Merge pull request #140 from SamG-Coder/codex/windows-startup-unwind
fix(relinker): align Windows startup unwind metadata
2026-09-30 18:59:23 +03:00
boykopovar a56313375f Merge pull request #138 from oneandonlydean/feat/agc-eop-interrupts
feat(agc): register driver eq events and deliver end-of-pipe interrupts
2026-09-30 18:56:52 +03:00
boykopovar 1c1d8fb9df Merge pull request #135 from oneandonlydean/fix/agc-drop-exports-past-attachments
fix(agc): drop pixel shader exports past the draw's attachments
2026-09-30 18:55:39 +03:00
boykopovar 14b883dbbb Merge pull request #133 from oneandonlydean/feat/shader-ngg-mesh
feat(shader): translate NGG geometry programs to mesh shaders
2026-09-30 18:54:44 +03:00
boykopovar 7411f17cb7 Merge pull request #128 from oneandonlydean/feat/videoout-open-param
feat(videoout): accept a zeroed open param
2026-09-30 18:54:15 +03:00
MichonandClaude Opus 5.5 bbf430e22d fix(agc): read a 16-bit integer view of a depth plane as its stored values
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-09-30 17:54:01 +02:00
boykopovar 6b731a9ee2 fix(agc): update graphics test to use pixel export mappings 2026-09-30 18:42:16 +03:00
Dean Galvin 48687eefab fix(contentexport): refuse init parameters without allocators or with reserved fields set
sceContentExportInit2 accepted any non-null parameter block. It now throws
when the malloc or free function is missing or a reserved field is not
zero. A test covers these refusals and the init and term order.
2026-09-30 18:35:36 +03:00
MichonandClaude Opus 5.5 8b8b710b07 fix(agc): import shared guest memory through a read-write alias and never offer read-only pages
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-09-30 17:17:17 +02:00
boykopovar 119a74952a Merge pull request #126 from oneandonlydean/feat/systemservice-hdr-tone-map
feat(systemservice): report the SDR tone-map luminance
2026-09-30 18:12:00 +03:00