Repository navigation
feat(recompiler): read the scalar aperture sources as values - #5005
oneandonlydean merged 1 commit into
Conversation
|
I ran a title with this change. The build was my integration branch, Marvel's Wolverine (PPSA03671) logged |
3254ca4 to
0d771e3
Compare
346694e to
823cdc0
Compare
|
Windows test of #5005: Windows 10 (19045), MinGW-w64 GCC 15.2, Release, AI-assisted (Claude Code). |
|
Thanks for the independent run. This adds Windows 10 / RTX 4080 SUPER evidence on feddf7f: 16 targets, three runs each, 48/48 passed. I am keeping your stated limits alongside the result: no baseline failure check, AMD, Linux or title-run coverage in this report. |
823cdc0 to
c2931c1
Compare
|
Correction to my Windows test above: I wrote that the GPU was shown by a AI-assisted (Claude Code). |
Reading src_shared_base, src_shared_limit, src_private_base or src_private_limit (scalar source codes 235-238) refused the shader since boykopovar#1940, because their values were unknown. They now read as the 64-bit apertures that the flat routing from boykopovar#1190 classifies: a base is the aperture's high dword over a low dword of 0, a limit is the same high dword over 0xffffffff (shared 0x80000000, private 0x70000000). A 64-bit read (s_mov_b64, a 64-bit VALU source, a wave64 lane mask) gets the whole value and a 32-bit read gets the low dword. A flat pointer built from the high dword therefore reaches LDS or scratch, and 64-bit compares against the limits order as on the hardware. The flat routing and the reads share one definition of the two high dwords. Sources: LLVM SIRegisterInfo.td (aperture registers are 64-bit, their low 32 bits are always 0 for a base and -1 for a limit) and getSegmentAperture in AMDGPULegalizerInfo.cpp and SIISelLowering.cpp (a 64-bit read whose high half is the aperture); the RDNA 2 ISA guide, sections 5.2, 5.8 (SH_MEM_BASES holds 16-bit bases) and 9.3; the KFD's MAKE_LDS_APP_LIMIT (limit = base | 0xffffffff); the gfx1030 and gfx1035 readouts on boykopovar#1190 and boykopovar#3803. The PS5's two high dwords stay inferred, as the shader technical debt records. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Hey everyone, I ran another Windows check of this PR, including the before-and-after controls. The final run passed all 40 selected tests on an RTX 4070 SUPER. Tested PR head Windows 11 build 26300, NVIDIA driver 617.42, WinLibs GCC 15.2 r7, Release,
One environment wrinkle: the initial sandbox run was 39/40 because The new GPU test ran guest wave32 and wave64 on host subgroup32. These results check the emulator's aperture values and routing together; they do not measure the PS5 high words or PTR32 state. I did not run a game, Linux, other GPUs, or the whole CTest suite. Thanks for the work on this. AI-assisted with Codex; the logs, controls, restored source and binary hashes were independently checked in a second review. |
c2931c1 to
dc1c12a
Compare
What
Fixes #3803. Since #1940, a shader that reads
src_shared_base,src_shared_limit,src_private_baseorsrc_private_limit(scalar source codes 235-238) as a value was refused withthe scalar aperture source ... is not modelled. These four sources now return the 64-bit apertures that the flat routing from #1190 already uses. A flat pointer built from them goes to LDS or scratch, and comparing against the limits gives the hardware's ordering.src_shared_base0x80000000_000000000x00000000src_shared_limit0x80000000_ffffffff0xffffffffsrc_private_base0x70000000_000000000x00000000src_private_limit0x70000000_ffffffff0xffffffffs_mov_b64, a 64-bit VALU source such asv_cmp_*_u64, or a lane mask in wave64) returns the whole value. A 32-bit read returns the low dword, as on gfx1030 and gfx1035. Titles take the high dword from ans_mov_b64, the same way LLVM does.SharedApertureHighandPrivateApertureHighmoved fromSpirvMemoryInstructions.cpptoRdnaInstructionDecoder.hpp.RdnaApertureSourceValuebuilds the four values from them, so the routing (SplitAperture) and the reads cannot diverge. The routing itself is unchanged.readRawU32returns the low dword.readU32Pairreturns low and high, which coversreadU64,readF64Bitsand every 64-bit scalar or VALU source.readMaskreads the 64-bit value as a lane mask. Before, a wave64 lane mask would have used the low dword for every lane.readScalarCode235-238 goes through the same values.docs/dev/debt/shader.md):Sources:
SHARED_BASE,SHARED_LIMIT,PRIVATE_BASEandPRIVATE_LIMIT, "Memory Aperture definition. Values are affected by system addressing mode: 32 or 64 bit".SH_MEM_BASES: bits [15:0] are the private base and [31:16] the shared base, so each base is a 16-bit field.064297491a6e):SIRegisterInfo.tdL245-L269: aperture registers are 64 bit, and their low 32 bits are always zero for a base and -1 for a limit.getBaseSegmentApertureinAMDGPULegalizerInfo.cppL2492-L2505 andSIISelLowering.cppL9453-L9462: LLVM copiesSRC_SHARED_BASE/SRC_PRIVATE_BASEas 64 bits and keeps the high half, because a 32-bit read "only returns zeroes".AMDGPUUsage.rstL1187-L1196: in 64-bit mode the apertures are 2^32 bytes and 2^32-aligned.24a19b953e2a):kfd_flat_memory.cL285-L306:MAKE_*_APP_LIMIT(base)is(base & 0xFFFFFFFF00000000) | 0xFFFFFFFF, and on gfx9+ the bases are set by the top 16 address bits.kfd_device_queue_manager_v10.cL51-L57: eachSH_MEM_BASESfield isbase >> 48. So with a 16-bit field of 0x8000, the high dword is 0x80000000.0ad3997b) does not constrain this. ACO never emits these operands, and it does not use FLAT loads or stores on GFX10 (src/amd/compiler/README-ISA.md). A search ofsrc/amdfinds no use of the aperture sources.Not measured on a console: the PS5's two high dwords. They are the values #1190 inferred from GTA V's traversal addresses (shared 0x8000 and private 0x7000 in the high 16 bits), and this PR reads exactly those values so that reads and routing agree. The wave is assumed to use 64-bit addressing (PTR32 clear). The debt entry records both.
Tested
Windows Server 2025, NVIDIA GeForce RTX 3060 (driver 591.86), MinGW-w64 GCC 15.2.0 (WinLibs r7), Release. The full run was on
mainc2565f0. After rebasing onto a24da90, the aperture,agc_driver_flat_apertures_*andagc_driver_flat_storetests were run again, and all 17 pass.agc_driver_flat_aperture_sources(tests/execution/FlatApertureSources.cpp). One compute dispatch per wave size (wave32, and wave64 where the device can run it). Every lane checks:s_mov_b32ands_mov_b64(low and high) result of each of the four sources;flat_store_dwordthrough a pointer whose high dword comes fromsrc_shared_base, read back withds_read_b32andflat_load_dword;src_private_base, read back withscratch_load_dwordandflat_load_dword;v_cmp_le_u64/v_cmp_ge_u64compares of those pointers against the bases and limits, including the limit itself and the first address past it;v_cndmask_b32with each source as the lane mask.aperture_sources. It asserted the refusal and now asserts the translated constants fors_mov_b32ands_mov_b64of each source.agc_driver_flat_aperture_sourcesfails withShaderRecompiler::Recompile: TranslationContext::readRawU32: the scalar aperture source src_shared_base is not modelled.aperture_sourcesaborts with the same message.SplitApertureto compare withSharedApertureHigh + 1makes the new test fail withBDA access failed: address=0x8000000000000000. The test therefore pins that the value read and the routing match.agc_driver_stencil_ref_exportand thevideo_out_flip_*tests). This includesagc_driver_flat_apertures_0-13and every other flat, global, BDA, LDS, scratch, scalar and recompiler test. The one failure islog_macros. It links onlylibc, and it fails the same way in another worktree build on this machine without this change.tools/check_conventions.py --base upstream/main: all checks passed.tools/check_test_registration.py: none new.src_shared_base;src_shared_basein local runs;src_shared_baseandsrc_private_basein local runs.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code