diff --git a/docs/RUNNING.md b/docs/RUNNING.md index a1cc2a3..630c41c 100644 --- a/docs/RUNNING.md +++ b/docs/RUNNING.md @@ -147,7 +147,7 @@ The flags fall into these groups: | --- | --- | | Console and early stop | `--console`, `--single-user`, `--early-stop-delay`, `--let-panic`, `--panic-serve` | | Input | `--input`, `--input-touchpad`, `--input-ptp`, `--input-active-us`, `--input-fnkeys` | -| Present path | `--present-dartpool`, `--present-resident`, `--present-beam`, `--present-va-reclaim`, `--present-maint`, `--present-latch`, `--present-pipeline` | +| Present path | `--present-dartpool`, `--present-resident`, `--present-beam`, `--present-va-reclaim`, `--present-maint`, `--present-latch`, `--present-pipeline`, `--present-early-done` | | GPU | `--ib-async`, `--gpu-recover`, `--gpu-va-wide`, `--gpu-coherent`, `--resident-mib`, `--adreno-fill-br`, `--adreno-fence-br`, `--adreno-cs-samplers`, `--gpu-x290-survey` | | Panel brightness | `--edp-backlight`, `--edp-backlight-mode` | | Clocks and bandwidth | `--thermal-guard`, `--gpu-dvfs`, `--gpu-dvfs-ceiling`, `--cpu-dvfs`, `--ddr-vote`, `--llcc`, `--bw-probe` | @@ -214,12 +214,31 @@ nits); either boot-arg moves the curve without rebuilding the monitor. The collection is built with `KEXT_PROFILE=desktop-next I2C_PROFILE=desktop-fnkeys tools/build-auxkc-desktop.sh NAME` for a monitor without `--gpu-coherent` (`desktop-next` is -`desktop-nocoherent` plus the service); a `--gpu-coherent` run needs a -`KEXT_PROFILE=desktop-backlight` collection pinned there instead. `--edp-backlight-mode` lets the first change switch a panel left in +`desktop-nocoherent` plus the service). With `--gpu-coherent` or +`--present-early-done` the run takes the collection pinned as +`INPUT_AUXKC_DESKTOP_EARLY_DONE` instead (`KEXT_PROFILE=desktop-early-done +I2C_PROFILE=desktop-fnkeys tools/build-auxkc-desktop.sh NAME`; `desktop-early-done` is +`desktop-backlight`, the coherent `desktop` plus the service, with early +completion), and is refused until that collection is pinned. `--edp-backlight-mode` lets the first change switch a panel left in PWM-pin mode to DPCD control. `tools/survey-edp-aux.py` checks, read-only from q1n1, that the clocks and the AUX controller the call needs are on. `tools/test-edp-backlight.py` is the offline test. +`--present-early-done MODE` (needs `--edp-backlight` and its chain) adds the +guest boot-arg `adreno_present_early_done=MODE` for the `desktop-early-done` +AdrenoX2 (`src/AdrenoDisplayEarlyDone.h` in the kext). AdrenoDisplay then +completes a layer-0 swap right after its scanout copy instead of at the next +frame tick. WindowServer keeps at most two swaps outstanding, so completing at +the copy frees one of its entries a refresh earlier and a frame that runs past +one refresh can still make the next latch; WindowServer may then run up to one +frame further ahead. `1` completes at every copy, `2` only while WindowServer +is late (for `--present-early-hold-ms`, default 2000, after each late frame), +`0` only measures. Every mode adds one `AdrenoDisplay: perf done` line per perf +window: completions at the copy, late frames, engagements, and histograms of +WindowServer's arrivals after each tick and of each late frame's lateness. It +excludes `--present-hold on`. `tools/test-present-early-done.py` is the offline +test (with the presentation replay's early-done scenarios). + `--view-reclaim` gives the monitor `SNAP_VIEW_RECLAIM`. The kernel's per-CPU private page-table copies (`shadow/sprr-view.h`) hold 256 tables instead of 128, and when a protecting RETYPE (read-only zone, TXM) finds them full, the diff --git a/tools/cycle.py b/tools/cycle.py index d51f629..6ec247f 100755 --- a/tools/cycle.py +++ b/tools/cycle.py @@ -295,6 +295,16 @@ def parse(argv=None): help='with --present-latch: guest boot-arg adreno_hold (default off since b12v11: on completes the swap ' 'on screen just before the next latch and copies the pending one early; b12v11 showed early ' 'copies of frames whose IB had not finished)') + p.add_argument('--present-early-done', type=int, choices=(0, 1, 2), default=None, + help='with --edp-backlight and its chain: the AuxKC INPUT_AUXKC_DESKTOP_EARLY_DONE and guest ' + 'boot-arg adreno_present_early_done: AdrenoDisplay completes a layer-0 swap right after its ' + 'scanout copy instead of at the next tick, so WindowServer\'s two swap entries free a refresh ' + 'earlier (1 always; 2 only while WindowServer is late, for --present-early-hold-ms after each late ' + 'frame; 0 measures only). Every mode adds the perf done line (WindowServer\'s arrivals against ' + 'the ticks). Not with --present-hold on; give it to every mode of the attempt') + p.add_argument('--present-early-hold-ms', type=int, default=None, + help='with --present-early-done 2: guest boot-arg adreno_present_early_hold_ms, how long a late frame ' + 'keeps early completion on (default 2000; 100..10000)') p.add_argument('--present-gate-us', type=int, default=None, help='with --present-latch: guest boot-arg adreno_gate_us, the age under which a layer-0 swap is not ' 'copied while a GPU submission is in the kext (default 4000; 0 = no gate)') diff --git a/tools/cycle_lib/installed_fresh.py b/tools/cycle_lib/installed_fresh.py index a8ebff8..06adb70 100644 --- a/tools/cycle_lib/installed_fresh.py +++ b/tools/cycle_lib/installed_fresh.py @@ -244,6 +244,17 @@ INPUT_AUXKC_PTP_DARTPOOL_RESIDENT_BEAM_VA_WIDE_LATCH_SHA = 'ccf0c8f4da4f63fbe25c # (57965a84); without --edp-backlight the latch collection above (org-desktop-nocoherent-20261023, ccf0c8f4) is used. INPUT_AUXKC_DESKTOP_BACKLIGHT = 'build/current-assets/swap-path-20261024/adreno-input.kc' INPUT_AUXKC_DESKTOP_BACKLIGHT_SHA = '9e916a4185bc609178fe80a3110e020d9f3167625da7a76a9bc9ff22412743d5' +# --edp-backlight with --gpu-coherent or --present-early-done: the --edp-backlight collection rebuilt from +# SnapAdreno's desktop-early-done profile, i.e. desktop-backlight (desktop's IO-coherent maintenance skipping plus +# AdrenoBacklight) plus -DADRENO_PRESENT_EARLY_DONE=1 in AdrenoDisplay.o (src/AdrenoDisplayEarlyDone.h: a layer-0 swap +# completed right after its scanout copy, boot-arg adreno_present_early_done 1 always / 2 while WindowServer is behind, +# 0 measures only; the perf done line), and SnapI2CHID desktop-fnkeys. Link it with +# KEXT_PROFILE=desktop-early-done I2C_PROFILE=desktop-fnkeys tools/build-auxkc-desktop.sh NAME (sudo for kmutil's staging) +# and put the two lines it prints here. Every addition is inert without its switch (the monitor's coherent ON with +# adreno_coherent=1; adreno_backlight=1; adreno_present_early_done), so the collection also serves --edp-backlight runs +# without them. None until linked and pinned: those flag sets are refused rather than run on the nocoherent kext. +INPUT_AUXKC_DESKTOP_EARLY_DONE = None +INPUT_AUXKC_DESKTOP_EARLY_DONE_SHA = None # --guest-net: INPUT_AUXKC's objects with SnapintoshVirtualEthernet's datapath (docs/GUEST-NETWORK-20261019.md). # None until that collection is built and pinned; --guest-net refuses meanwhile. INPUT_AUXKC_NET = None @@ -787,6 +798,9 @@ def route_selected(args): edp_backlight = getattr(args, 'edp_backlight', False) need(not edp_backlight or latch, '--edp-backlight needs --present-latch and its chain (its AdrenoX2 is that collection\'s with ADRENO_BACKLIGHT)') + early = getattr(args, 'present_early_done', None) + need(early is None or edp_backlight, + '--present-early-done needs --edp-backlight and its chain (its AdrenoX2 is the early-done collection)') need(not (vsync60 and (damage or cached or gpumap)), '--present-vsync60 already includes --present-gpumap\'s (and so --present-cached-read\'s) kext: give one of them') need(not (damage and cached), '--present-cached-read already includes --present-damage\'s present: give one of them') @@ -812,6 +826,14 @@ def route_selected(args): if vsync60: return ((INPUT_TOUCHPAD_PROFILE if touchpad else INPUT_PROFILE), INPUT_AUXKC_VSYNC60, INPUT_AUXKC_VSYNC60_SHA, INPUT_BUNDLES) + if dartpool and ptp and resident and beam and va_reclaim and va_wide and latch and edp_backlight and ( + getattr(args, 'gpu_coherent', False) or early is not None): + need(INPUT_AUXKC_DESKTOP_EARLY_DONE is not None and INPUT_AUXKC_DESKTOP_EARLY_DONE_SHA is not None, + '--edp-backlight with --gpu-coherent or --present-early-done: its AuxKC is not pinned yet ' + '(INPUT_AUXKC_DESKTOP_EARLY_DONE_SHA; KEXT_PROFILE=desktop-early-done I2C_PROFILE=desktop-fnkeys ' + 'tools/build-auxkc-desktop.sh NAME links it)') + return (INPUT_TOUCHPAD_PROFILE, INPUT_AUXKC_DESKTOP_EARLY_DONE, INPUT_AUXKC_DESKTOP_EARLY_DONE_SHA, + INPUT_BUNDLES) if dartpool and ptp and resident and beam and va_reclaim and va_wide and latch and edp_backlight: need(INPUT_AUXKC_DESKTOP_BACKLIGHT is not None and INPUT_AUXKC_DESKTOP_BACKLIGHT_SHA is not None, '--edp-backlight: its AuxKC is not pinned yet (INPUT_AUXKC_DESKTOP_BACKLIGHT_SHA; ' @@ -1244,6 +1266,20 @@ def boot_addition(args): if active_us is not None: need(active_us == 0 or 2000 <= active_us <= 100000, '--input-active-us must be 0 or 2000..100000') extra.append(f'snap_i2c_active_us={active_us}') + # --present-early-done: AdrenoDisplay's early completion (src/AdrenoDisplayEarlyDone.h), read only by the + # desktop-early-done AdrenoX2 that --edp-backlight then selects; the kext turns it off with the release hold. + early, early_hold = getattr(args, 'present_early_done', None), getattr(args, 'present_early_hold_ms', None) + need(early is None or getattr(args, 'edp_backlight', False), + '--present-early-done needs --edp-backlight (the early-done collection is that chain\'s)') + need(early is None or early in (0, 1, 2), '--present-early-done is 0 (measure only), 1 (always) or 2 (while behind)') + need(early_hold is None or early == 2, '--present-early-hold-ms needs --present-early-done 2') + need(not early or hold != 'on', '--present-early-done 1/2 and --present-hold on exclude each other (the hold ' + 'keeps the swap current until its release)') + if early is not None: + extra.append(f'adreno_present_early_done={early}') + if early_hold is not None: + need(100 <= early_hold <= 10000, '--present-early-hold-ms must be 100..10000') + extra.append(f'adreno_present_early_hold_ms={early_hold}') # --input-fnkeys: the keyboard's Fn-key layer (drivers/snap-i2c-hid/src/hid-keyboard.h HID_FNKEYS_*), read by a # SnapI2CHID built with SNAP_I2C_HID_FNKEYS; the same sets the kext refuses are refused here. fnkeys = getattr(args, 'input_fnkeys', None)