Repository navigation
fix(agc): accept bound copies of a registered shader header that differ only in user_data - #1837
Conversation
|
Tested on Stray (PPSA02100 v1.05, Unreal Engine 4). It hits the same Setup: Linux (Nobara 44, kernel 7.2), RTX 5070 Ti, NVIDIA 595.91.07. Base is Stray binds a copy of a registered vertex shader header (registered at +0x0, copy at +0x250). I dumped both 96-byte Byte 93 is padding: Comparing only up to the end of the last field fixes it: return std::memcmp(&used, ®istered, offsetof(Shader, num_sh_registers) + sizeof(Shader::num_sh_registers)) == 0;With that one change on top of this PR, Stray gets past the interpolant mapping and stops later on an unrelated The test in this PR doesn't catch it because AI-assisted: yes |
|
Sonic Origins (PPSA05324) hits the static ABI variant of this, In one run, 14 shaders (header type 1) are bound 46 times through a copy of their registered header 0x78 bytes below it. All 96 fixed bytes of the copy equal the registered header, Bring-up thread: #2021 |
|
Tested on a second title: Disney Epic Mickey: Rebrushed (PPSA15657, UE4) stops on the same I logged the 96-byte comparison in At +0x58 the fields are Comparing up to the end of the last field fixes it here: return std::memcmp(&used, ®istered, offsetof(Shader, num_sh_registers) + sizeof(registered.num_sh_registers)) == 0;A field-by-field comparison would also work. With that change, the title gets past this point and stops at an unrelated stub. Measured on RX 7600 (gfx1102), Linux, with Tested and written by Claude (AI assistant) on a contributor's machine. |
5ba9de6 to
8d9bcb7
Compare
|
@johnmaia thanks, you're right. The test in Rebased onto @NahuelGenchi thanks for the Sonic Origins data. The static ABI path uses the same comparison. AI-assisted: the fix, the test and this reply were written by Claude (Claude Code) on my machine. |
…er only in user_data Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Rebased onto current |
8d9bcb7 to
cd1f76c
Compare
|
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.
|
|
Thanks for merging. The relocation extension discussed above isn't part of this merge: whole-header copies whose pointers into the header all move by the header's own distance, which PPSA26344 binds and which still fail with "static ABI refers to a replaced shader header". It's rebased onto current
|
…eader-copies fix(agc): accept bound copies of a registered shader header that differ only in user_data
|
Data for Pipodi's relocation commit ( Setup: CachyOS (kernel 7.2.9), RX 9070 XT (RADV), Release, headless gamescope with scripted input. Main Without A local print (not pushed) of the words that differ between the bound header and the registered snapshot: Every pointer is at the same distance from its own header ( With Tested and written by Claude (AI assistant) on a contributor's machine. |
|
Thanks @EdouardSence, and @Dextroid17 in #675 on lavapipe: |
Adopt Pipodi's relocated-header normalization from commit 56b154a, extending boykopovar#1837 for whole-header copies reported in PPSA26344. Keep code and fixed metadata fields exact. Require newly relocated metadata spans to remain inside both headers and match the immutable registered snapshot before using its ABI. Preserve the existing same-address, shallow-copy and user_data behavior. Cover mixed copies, modified metadata, incorrect pointers and legacy/extended specials. Source: boykopovar#1837 (comment)
What
The static, graphics and rectangle ABI resolvers look up the registered shader by its code address. #639 made them require the bound
Shaderheader to be at the registered header's address, and otherwise throw... refers to a replaced shader header.Astro Bot (PPSA21567) registers a vertex shader with its header at 0x50000e500, then binds it for a draw through a copy at 0x307ae3920. The copy's 96 fixed
Shaderbytes match the registered header exceptuser_data: 0x50000e668 in the registered header, null in the copy. Thecx_registers,sh_registers,specialsand semantic pointers still point into the registered header. The bytes after the fixed fields are unrelated memory, so onlysizeof(Shader)is compared.SameHeadernow accepts a bound header when it is at the registered address, or when its fixed fields equal the registered header's withuser_dataignored. Any other difference still throws. The registered header's metadata is used, as before. This is recorded in TechnicalDebt, because whether the console reads the copy'suser_datais unknown.Tested
Linux (CachyOS, GCC), RX 9070 XT, Mesa 26.2.4 RADV.
agc_driver_prepared_shadersnow also resolves the static ABI through a copy of the registered compute header:user_data, it is accepted;target, it still throwsreplaced shader header;ctest: 484/485. The failing test isimport_audit, a Python tool test that fails the same way onmainwith Python 3.14 here.tools/check_conventions.pypasses.main4b6ab6b with fix(agc): defer shaders that cannot be prepared at registration to their first use #1836, scripted and headless:rectangle ABI refers to a replaced shader header;shader image heap capacity exceeded(Sampled image heap of 16 rejects a retail shader before the metadata limit #1789). No frame is presented yet.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code