Skip to content

feat(agc): implement 11_11_10 float color targets through 32-bit uint attachments - #7207

Merged
oneandonlydean merged 3 commits into
boykopovar:mainfrom
gjonn:fix/agc-color-11-11-10-float
Oct 17, 2026
Merged

oneandonlydean merged 3 commits into
boykopovar:mainfrom
gjonn:fix/agc-color-11-11-10-float

Conversation

@gjonn

@gjonn gjonn commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

What

Color format 7 (COLOR_11_11_10, float) packs its 10-bit component in bits 0-9 and its two 11-bit components in bits 10-20 and 21-31. COMP_SWAP 2 (reversed order) puts blue in the low 10 bits and red in the high 11. Vulkan has no format with that layout (B10G11R11_UFLOAT keeps red in the low 11 bits), so such a target was refused with unsupported color format 7 number type 7 component swap 2.

This takes the path that 10_11_11 unorm targets already use (#1485):

  • DecodeColorFormat maps format 7, float, swap 2 to an R32_UINT attachment with the reversed export mapping 0xc6 and the new ColorExportPacking::Float11_11_10.
  • The pixel shader's packing step, selected by the existing per-target specialization constant, packs the mapped export as Format10_11_11Float (the layout of image format 43) with the float-to-small-float conversion that format-43 image stores already use: toward zero, overflow to the largest finite value, negatives to zero, NaN kept. The registered artifact is shared; only the pipeline specialization differs.
  • Blending, partial RGB writes, 16-bit integer exports and DCC throw, the same as for 10_11_11 unorm. A blend can't be done exactly on packed words. A B10G11R11 proxy repacked around the pass was tried locally, but it isn't exact (it accumulated NaN), so it's not included.
  • Swaps 0, 1 and 3 and the other number types still throw. Only swap 2 has been seen.
  • The packed-target error messages now name the target format, and the shader validation message says "packed color attachments".
  • Technical debt entry: the export conversion is assumed to match the CB's.

Tested

  • Windows 11, MinGW-w64 GCC, RTX 5090:
    • agc_driver_graphics_tests: new float11_11_10TargetTests covers decode (R32_UINT, mapping 0xc6, packing), the refused swaps, number types, blending, partial writes, int16 exports and DCC, and that ROUND_MODE (CB_COLOR_INFO bit 18) = 1 (truncate) is accepted while bit 18 = 0 (round) is refused. It also checks that serialization keeps the packing, that the specialization differs from the unorm one on the same artifact, shader validation, and that an out-of-range packing value is refused.
    • agc_driver_graphics_tests multisampleTests: a CB resolve whose source is a packed 10_11_11 unorm or 11_11_10 float target is refused at decode.
    • agc_driver_packed_float_color_target_tests (new): draws 32_ABGR and FP16_ABGR exports into tiled and linear format-7 targets. It compares every pixel with an independent reference packing, including truncation, overflow, Inf, NaN, negatives, small-float subnormals and f32 denormals. It also checks that pixels outside the scissor keep their contents.
    • agc_driver_packed_unorm_color_target_tests, agc_shader_memory_tests and the recorder resolve tests (agc_tiled_resolve, agc_multisample_guest_access, agc_metadata_pass) still pass.
    • request_serializer_tests and the dual-source, reversed-order, SWAP_ALT blend, prepared export/publication and 1_5_5_5 target tests still pass.
    • Mutation checks, each caught by the new tests: packing in the 11_11_10 bit order instead of the 10_11_11 one, the identity mapping 0xe4 instead of 0xc6, the old packing bound in the fragment output specialization, the unorm packing selected for the float target, the ROUND_MODE 0 guard removed, and the packed-source resolve guard removed or limited to 10_11_11 unorm.
  • tools/check_conventions.py passes.
  • PPSA01317 on current main (with fix(agc): suppress the flip end-of-pipe event on queues that raise release interrupts #7137 applied locally for Gran Turismo 7 (PPSA01317 v01.680) on Linux/RADV: deterministic SIGSEGV in guest code (null deref r14+0x48) while the title's video-out/flip frame-pacing loop runs #6350) stopped at unsupported color format 7 number type 7 component swap 2 at its first presented frame. With this change it renders past that format and stops later on an unrelated unimplemented sample of a converted float image (feat(shader): sample converted unorm images in the shader #5958).

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Fixes: none
  • Unblocks: PPSA01317 Gran Turismo 7 (PPSA01317) #4697
  • GPUs tested: NVIDIA GeForce RTX 5090, Windows 11
  • AI-assisted: yes

@oneandonlydean

Copy link
Copy Markdown
Collaborator

Thanks, this looks good. The layout, swap, 0xc6 handling, RTZ conversion and cache keys all check out, and the test's CPU reference covers the awkward inputs (NaN, ±Inf, -0, negatives, denormals, overflow). Two small asks before merge:

  1. ROUND_MODE for float targets. DecodeColorBuffer now applies the ROUND_MODE guard only to Unorm10_11_11. A format-7 target with CB_COLOR_INFO bit 18 = 0 (round rather than truncate) is accepted and still packed toward zero. Mesa programs ROUND_MODE=1 (truncate) for every non-UNORM/SNORM/SRGB target (ac_descriptors.c), and the test fixture also sets bit 18, so RTZ is right for that case. We just don't know what the CB does with bit 18 = 0. Could you add the mirror of the unorm guard, e.g. Require(packing != Float11_11_10 || (info & 0x40000) != 0, "rounding (ROUND_MODE 0) 11_11_10 float color targets are unsupported"), or a debt note saying ROUND_MODE is ignored? Also, which bit 18 value does PPSA01317 set?

  2. MSAA resolve of a packed target. Nothing refuses a CB resolve whose source is packed. The resolve only checks that the formats match (both R32_UINT here), so it resolves the raw packed words, and an integer resolve can't average those, so the result is wrong with no error. This gap already exists on main for 10_11_11 unorm; this PR extends it to format 7. One Require(source.packing == None, ...) in the resolve branch in Draw.cpp would cover both packings. If you'd rather do that separately, a follow-up issue is fine.

@TheSovietWaffle

Copy link
Copy Markdown
Contributor

AMD data point, since the description lists an RTX 5090: head ec28b6be8 as-is, Release, Windows 10 Pro 22H2 (19045), WinLibs GCC 15.2.0 r7, AMD Radeon RDNA 2 iGPU (1002:164e, driver 32.0.21045.5002) chosen with ANYPS5_GPU.

  • agc_driver_packed_float_color_target: 5 of 5 pass (not skipped).
  • agc_driver_packed_unorm_color_target: 5 of 5 pass.
  • agc_driver_graphics_tests with no arguments (the path with float11_11_10TargetTests): 3 of 3 pass.

Not checked: other tests, titles.

AI-assisted: yes (Claude Code).

@oneandonlydean

Copy link
Copy Markdown
Collaborator

Heads-up on ordering: #7213 (5_6_5 UNORM colour targets) edits the same swap > 1 allow-list line in State.cpp as this PR, so the two conflict on one line. We plan to merge #7213 first. When you push the ROUND_MODE/resolve changes, could you rebase onto main after #7213 lands? The resolution is just the union of both conditions (format != 7 and format != 16).

@gjonn

gjonn commented Oct 17, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review. Both are done in ec28b6b.

  1. ROUND_MODE: DecodeColorBuffer now refuses an 11_11_10 float target with CB_COLOR_INFO bit 18 = 0 ("rounding (ROUND_MODE 0) 11_11_10 float color targets are unsupported"), mirroring the unorm guard. float11_11_10TargetTests checks that bit 18 = 1 is accepted and bit 18 = 0 is refused.

    On PPSA01317: I don't have a capture of CB_COLOR_INFO for its format-7 targets. Our logs only record the format/number/swap error, not the raw register, so which bit 18 value it sets is unverified. The fixture's bit 18 = 1 follows Mesa, not a capture. With this guard, if the title does use bit 18 = 0, it will now stop at the new message instead of being packed toward zero. I'll report back once I've booted it with this guard.

  2. Packed resolve: I put the guard next to the existing format/extent check in DecodeColorMetadataPass (State.cpp) rather than in Draw.cpp. A CB resolve whose source is a packed 10_11_11 unorm or 11_11_10 float target now throws at decode ("CB resolves of color targets are unsupported"). This covers both packings and fails before any GPU work. multisampleTests covers both. The mutation checks (guard removed, or limited to 10_11_11 unorm) are caught.

I'll rebase onto main once #7213 lands, keeping both formats in the swap allow-list.

@TheSovietWaffle thanks for the AMD run.

AI-assisted: yes

@github-actions github-actions Bot added build shader core/shader docs agc libSceAgc* labels Oct 17, 2026
@github-actions

github-actions Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.

Pull request Conflicting files (lines on main) Same exports Same new files
PR 6708 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderValidation.cpp L678

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 1191 core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
PR 1341 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 1368 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 1395 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 2434 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 4040 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 4072 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderValidation.cpp
PR 4339 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 4448 docs/dev/debt/libSceAgcDriver.md
PR 4650 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
docs/dev/debt/libSceAgcDriver.md
PR 4891 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5021 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5058 docs/dev/debt/libSceAgcDriver.md
PR 5371 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5372 docs/dev/debt/libSceAgcDriver.md
PR 5426 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5431 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5441 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 5499 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 5500 core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
PR 5609 core/shader/recompiler/Recompiler.hpp
PR 5925 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
core/shader/recompiler/Recompiler.hpp
docs/dev/debt/libSceAgcDriver.md
PR 5958 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/shader/recompiler/Recompiler.hpp
PR 5998 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6044 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6176 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6177 core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.hpp
PR 6188 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
core/shader/recompiler/Recompiler.hpp
PR 6192 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6194 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6222 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderValidation.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6235 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderValidation.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
PR 6243 docs/dev/debt/libSceAgcDriver.md
PR 6259 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6273 docs/dev/debt/libSceAgcDriver.md
PR 6297 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6300 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6320 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6373 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6412 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/shader/recompiler/Recompiler.hpp
docs/dev/debt/libSceAgcDriver.md
PR 6454 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6481 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6486 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/shader/recompiler/Recompiler.hpp
PR 6492 docs/dev/debt/libSceAgcDriver.md
PR 6498 docs/dev/debt/libSceAgcDriver.md
PR 6535 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6539 core/shader/recompiler/Recompiler.hpp
PR 6548 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6563 core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6601 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6636 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6647 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6727 docs/dev/debt/libSceAgcDriver.md
PR 6741 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6747 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6783 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6786 docs/dev/debt/libSceAgcDriver.md
PR 6788 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6804 core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6808 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6867 docs/dev/debt/libSceAgcDriver.md
PR 6887 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6946 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/shader/recompiler/Recompiler.hpp
docs/dev/debt/libSceAgcDriver.md
PR 6947 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderValidation.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6965 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6973 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
core/shader/recompiler/Recompiler.hpp
docs/dev/debt/libSceAgcDriver.md
PR 6987 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
core/shader/recompiler/Recompiler.hpp
docs/dev/debt/libSceAgcDriver.md
PR 6989 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
core/shader/recompiler/Recompiler.hpp
docs/dev/debt/libSceAgcDriver.md
PR 6995 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
core/shader/recompiler/Recompiler.hpp
docs/dev/debt/libSceAgcDriver.md
PR 7002 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
core/shader/recompiler/Recompiler.hpp
docs/dev/debt/libSceAgcDriver.md
PR 7089 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7154 docs/dev/debt/libSceAgcDriver.md
PR 7175 core/libs/prx/libSceAgcDriver/Graphics/src/State.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7178 docs/dev/debt/libSceAgcDriver.md
PR 7201 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
PR 7223 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7258 docs/dev/debt/libSceAgcDriver.md

@akkadbakkad89

Copy link
Copy Markdown
Contributor

Second NVIDIA generation + first Intel, head ec28b6be8, Windows 11, MinGW (WinLibs GCC 15.2.0), Release, serial fresh processes:

  • NVIDIA RTX 3070 (driver 617.42): agc_driver_packed_float_color_target and agc_driver_graphics (incl. float11_11_10TargetTests) pass.
  • Intel UHD 630 (ANYPS5_GPU=UHD, igvk64): both pass.

@gjonn

gjonn commented Oct 17, 2026

Copy link
Copy Markdown
Contributor Author

Follow-up on the ROUND_MODE question: I booted PPSA01317 on current main with ec28b6b applied and temporarily logged the register. Its format-7 target has CB_COLOR_INFO = 0x0004171c, so bit 18 (ROUND_MODE) is 1, truncation. Neither new refusal fires, and the title renders past this format.

AI-assisted: yes

@gjonn

gjonn commented Oct 17, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto main after #7213 (force-push; head d0a9943). The only conflict was the swap > 1 allow-list line in State.cpp, resolved as the union of both conditions (format != 7 and format != 16). agc_driver_graphics, agc_driver_packed_float_color_target, agc_driver_packed_unorm_color_target and check_conventions.py pass on the rebased branch.

AI-assisted: yes

gjonn added 3 commits October 17, 2026 17:29
… attachments

Color format 7 (COLOR_11_11_10, float) keeps its 10-bit component in the
low bits; with the reversed component order (COMP_SWAP 2) that is blue,
with red in the high 11 bits. Vulkan has no such layout, so the target was
refused at decode.

Render it the way 10_11_11 unorm targets are rendered: an R32_UINT
attachment, the reversed export mapping 0xc6, and a new
ColorExportPacking::Float11_11_10 that makes the pixel shader pack each
export with the format-43 image store conversion (toward zero, overflow to
the largest finite value, negatives to zero, NaN kept). Blending, partial
writes, 16-bit integer exports, DCC and the other component orders throw.

AI-assisted: yes
…ed color targets

An 11_11_10 float color target with CB_COLOR_INFO ROUND_MODE (bit 18) clear
asks the CB to round, but the export packing truncates toward zero, so such a
target now throws. A CB resolve whose source is a packed 10_11_11 unorm or
11_11_10 float target would resolve the raw R32_UINT words, which an integer
resolve cannot average, so it now throws at decode.

AI-assisted: yes
The blend-refusal case used CB_BLEND_CONTROL 0x60010001, which is
ONE * source + ZERO * destination: a replace blend that writes the source
unchanged. A packed target can draw such a blend with blending disabled,
so the case now uses the additive blend 0x60010101, which a packed target
must still refuse.

AI-assisted: yes
@gjonn
gjonn force-pushed the fix/agc-color-11-11-10-float branch from d0a9943 to 45c78bb Compare October 17, 2026 21:31
frankea added a commit to frankea/AnyPS5 that referenced this pull request Oct 17, 2026
…t with Mbed TLS

sceSslConnect, sceSslRead, sceSslWrite and sceSslClose threw NotImplemented
because the library had no transport, so every title that reaches its first
TLS connection stopped there; Gran Turismo 7 does so on main with boykopovar#7137,
boykopovar#7207 and boykopovar#7175 right after the save-data mount (boykopovar#6350, D4697).

The connection now opens a Mbed TLS 3.6.7 client session over the native
socket behind the title's libSceNet descriptor, found through the kernel's
socket lookup, so the title's own socket carries the TLS stream whether it is
blocking or not. The context's loaded CAs are the trust store and its client
certificate and key are offered when loaded; the hostname is sent as SNI; the
minimum version maps to TLS 1.2 with TLS 1.3 allowed; the sceSslSetAlpn list
is split on commas and negotiated, and sceSslGetAlpnSelected returns the
result. Verification applies the enabled SERVER_VERIFY, CN_CHECK,
NOT_AFTER_CHECK, NOT_BEFORE_CHECK and KNOWN_CA_CHECK options after the
handshake and returns the matching SSL_ERROR_* code; a verify callback gets
the connection id, that code, handles to a copy of the peer chain usable with
the certificate name calls, the chain length and the user argument, and a
negative return fails the connect with
SSL_ERROR_APPLICATION_VERIFICATION_CALLBACK_CHECK. Non-blocking sockets get
SSL_ERROR_WANT_POLLIN and WANT_POLLOUT from connect, read and write; receive
timeouts, close notify, resets, fatal alerts and an exhausted memory pool map
to their codes, whose values follow KytyPS5's errno.h as the file's other
codes already do. All TLS state comes from the context's pool through the
existing allocator, connections carry their own I/O lock so one blocking read
no longer serialises every other SSL call, and sceSslTerm tears down its
connections' transports before the context goes away. sceSslClose takes the
connection id, following SharpProspero.

guest_ssl_transport runs an in-process Mbed TLS server with a generated P-256
self-signed certificate on a loopback port and drives the client through
libSceNet sockets and the public sceSsl calls: the happy path with ALPN and
echo, SSL_ERROR_EOF on the server's close notify, unknown CA, CN mismatch, CN
check disabled, verification disabled, a verify callback that accepts an
untrusted chain and reads the peer's subject through the handles, one that
rejects, the non-blocking handshake, read and write loop, and an unknown
socket. The debt note describes what is real now and what is still unmeasured
on a console.
frankea added a commit to frankea/AnyPS5 that referenced this pull request Oct 17, 2026
…t with Mbed TLS

sceSslConnect, sceSslRead, sceSslWrite and sceSslClose threw NotImplemented
because the library had no transport, so every title that reaches its first
TLS connection stopped there; Gran Turismo 7 does so on main with boykopovar#7137,
boykopovar#7207 and boykopovar#7175 right after the save-data mount (boykopovar#6350, D4697).

The connection now opens a Mbed TLS 3.6.7 client session over the native
socket behind the title's libSceNet descriptor, found through the kernel's
socket lookup, so the title's own socket carries the TLS stream whether it is
blocking or not. The context's loaded CAs are the trust store and its client
certificate and key are offered when loaded; the hostname is sent as SNI; the
minimum version maps to TLS 1.2 with TLS 1.3 allowed; the sceSslSetAlpn list
is split on commas and negotiated, and sceSslGetAlpnSelected returns the
result. Verification applies the enabled SERVER_VERIFY, CN_CHECK,
NOT_AFTER_CHECK, NOT_BEFORE_CHECK and KNOWN_CA_CHECK options after the
handshake and returns the matching SSL_ERROR_* code; a verify callback gets
the connection id, that code, handles to a copy of the peer chain usable with
the certificate name calls, the chain length and the user argument, and a
negative return fails the connect with
SSL_ERROR_APPLICATION_VERIFICATION_CALLBACK_CHECK. Non-blocking sockets get
SSL_ERROR_WANT_POLLIN and WANT_POLLOUT from connect, read and write; receive
timeouts, close notify, resets, fatal alerts and an exhausted memory pool map
to their codes, whose values follow KytyPS5's errno.h as the file's other
codes already do. All TLS state comes from the context's pool through the
existing allocator, connections carry their own I/O lock so one blocking read
no longer serialises every other SSL call, and sceSslTerm tears down its
connections' transports before the context goes away. sceSslClose takes the
connection id, following SharpProspero.

guest_ssl_transport runs an in-process Mbed TLS server with a generated P-256
self-signed certificate on a loopback port and drives the client through
libSceNet sockets and the public sceSsl calls: the happy path with ALPN and
echo, SSL_ERROR_EOF on the server's close notify, unknown CA, CN mismatch, CN
check disabled, verification disabled, a verify callback that accepts an
untrusted chain and reads the peer's subject through the handles, one that
rejects, the non-blocking handshake, read and write loop, and an unknown
socket. The debt note describes what is real now and what is still unmeasured
on a console.
@oneandonlydean
oneandonlydean merged commit cfaba87 into boykopovar:main Oct 17, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc* build docs shader core/shader

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants