From 984f03937be6b3d8d1789472021123034b48fdca Mon Sep 17 00:00:00 2001 From: Acelogic <7362641+Acelogic@users.noreply.github.com> Date: Fri, 23 Oct 2026 02:08:26 -0400 Subject: [PATCH] tools: read AdrenoDrawCommands.m with its split parts SnapMetal moves AdrenoDrawCommands.m's code into ordered parts under AdrenoMetal/AdrenoDrawCommands/, #included by the main file. Tools that read that file as text or hash the plug-in's sources must see the whole unit: - test-adreno-staging-arenas.py: the A4 lock check reads the unit with read_source(). On the main file alone it would find no lock at all and fail; its line numbers now refer to the expanded unit. - qualify-gen57-windowserver-cause.py: binds every file of the unit (source_files) and searches read_source(). An unsplit tree binds and reads exactly what it did before. - check-adreno-resource-encoding.py: hashes AdrenoMetal/ recursively, so the qualification record covers the parts. Evidence: py_compile of the three tools; the A4 check finds the same 6 locked regions in the unsplit file and in read_source() of the split unit (none in the main file alone), and flags a release inserted inside one of them. --- tools/check-adreno-resource-encoding.py | 2 +- tools/qualify-gen57-windowserver-cause.py | 10 ++++++++-- tools/test-adreno-staging-arenas.py | 9 ++++++--- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/tools/check-adreno-resource-encoding.py b/tools/check-adreno-resource-encoding.py index 28ce29d..a1e288c 100755 --- a/tools/check-adreno-resource-encoding.py +++ b/tools/check-adreno-resource-encoding.py @@ -61,7 +61,7 @@ def main(): ROOT/'compat/adreno-resource-list.c',ROOT/'compat/adreno-resource-list.h', ROOT/'compat/adreno-submit.h',PLUGIN/'build.sh', PLUGIN/'harness/resource-encoding.m',PLUGIN/'harness/regtest.m',PLUGIN/'harness/ws_selectors.h'] - sources+=list((PLUGIN/'AdrenoMetal').glob('*')) + sources+=list((PLUGIN/'AdrenoMetal').rglob('*')) # split sources keep their parts in subdirectories sources+=list((PLUGIN.parent/'include').glob('*.h')) source_hashes={str(p.relative_to(ROOT)):sha(p) for p in sorted(sources) if p.is_file()} commands=[] diff --git a/tools/qualify-gen57-windowserver-cause.py b/tools/qualify-gen57-windowserver-cause.py index 92415e1..cd7b21d 100755 --- a/tools/qualify-gen57-windowserver-cause.py +++ b/tools/qualify-gen57-windowserver-cause.py @@ -13,6 +13,10 @@ import argparse import hashlib import json import subprocess +import sys + +sys.path.insert(0, str(Path(__file__).resolve().parent)) +from source_text import read_source, source_files ROOT = Path(__file__).resolve().parents[1] PIPE = ROOT.parent / 'Snapintosh-adreno-pipeline' @@ -74,8 +78,10 @@ proof_path = bind(PIPE / 'build/ca-vpc-a16-verified-gen58-20260928-v1/verificati '8d95a910aedce77fb31710799e0882e0a1c8b0d32b1eacfbf709e0c5d0995c2e') proof = json.loads(proof_path.read_text()) assert proof['status'] == 'A16_CA_FRAME_EXACT' and not proof['desktop_verified'] -source = bind(PIPE / 'gpu/adreno-kext/plugin/AdrenoMetal/AdrenoDrawCommands.m') -assert '![var[@"interp"] isEqual:@"no_perspective"]' in source.read_text() +source = PIPE / 'gpu/adreno-kext/plugin/AdrenoMetal/AdrenoDrawCommands.m' +for part in source_files(source): + bind(part) +assert '![var[@"interp"] isEqual:@"no_perspective"]' in read_source(source) bind(__file__) output = args.output.resolve() assert not output.exists() diff --git a/tools/test-adreno-staging-arenas.py b/tools/test-adreno-staging-arenas.py index 49839e7..98164ec 100755 --- a/tools/test-adreno-staging-arenas.py +++ b/tools/test-adreno-staging-arenas.py @@ -18,7 +18,7 @@ harness gauge puts a dealloc sentinel on every staging arena the plug-in allocat faults run B: an injected IOGPU allocation failure drains a non-empty pool and is retried once (buffer and texture); with an empty pool it is not retried (A8, A16) gauge the plug-in's live counts equal the harness's; its peak equals the harness's (A13) - source no release between gAdrenoStagingLock's lock and unlock in AdrenoDrawCommands.m (A4) + source no release between gAdrenoStagingLock's lock and unlock in AdrenoDrawCommands.m and its parts (A4) stats the plug-in's diagnostics stats line carries the arenas(...) fields and stays under 1 KB (A19) --expect-before: the unchanged plug-in must fail at least one check. @@ -34,6 +34,9 @@ import struct import subprocess import sys +sys.path.insert(0, str(Path(__file__).resolve().parent)) +from source_text import read_source + ROOT = Path(__file__).resolve().parents[1] HARNESS = ROOT / 'gpu/adreno-kext/plugin/harness' REGS = ROOT / 'gpu/adreno-kext/include/AdrenoA8xxRegs.h' @@ -256,13 +259,13 @@ def main(): check(line is not None and ' arenas(live/live_kib/peak/peak_kib/pooled_kib/aged/capped/drains/failures/retries_ok/continued)=' in line and len(line) <= 1024, f'stats: the diagnostics stats line lacks the arenas fields: {line and line[-200:]}') # ---- source check (A4) - src = DRAW.read_text() + src = read_source(DRAW) bad = [] for m in re.finditer(r'os_unfair_lock_lock\(&gAdrenoStagingLock\);(.*?)os_unfair_lock_unlock\(&gAdrenoStagingLock\);', src, re.S): if re.search(r'CFBridgingRelease|__bridge_transfer|CFRelease|AdrenoStagingReleaseVictims', m.group(1)): bad.append(src[:m.start()].count('\n') + 1) check(bool(re.search(r'os_unfair_lock_lock\(&gAdrenoStagingLock\)', src)) and not bad, - f'source: a release inside gAdrenoStagingLock at lines {bad}') + f'source: a release inside gAdrenoStagingLock at lines {bad} of the expanded unit') result = dict(checks=checks, failures=failures, summary=summary, bundle=bundle, expect_before=args.expect_before) (out / 'result.json').write_text(json.dumps(result, indent=2, default=str) + '\n') if args.expect_before: