mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 18:13:23 +09:00
[tools, docs] (P7): device window 2 runbook and scripts
This commit is contained in:
+19
@@ -0,0 +1,19 @@
|
||||
# 设备窗口 #2(P7 收官)· 工具与 dry run
|
||||
|
||||
- 运行手册:[`tools/RUNBOOK.md`](tools/RUNBOOK.md)(一条命令 `tools/window.sh <pipe-sha>`,detached、可续跑;工作副本在 `~/w7/notes/p7/window2/`)。
|
||||
- 脚本:`tools/{lib.sh,detach.sh,window.sh,10-build.sh,21-preflight.sh,20-install.sh,30-gate3.sh,40-bsl-stats.sh,50-cts-after.sh,60-reduce.py,90-restore.sh}`;
|
||||
`tools/dry-run-p7w6.sh` 是下面 dry run 的原样命令。
|
||||
- `$BASE` 的机器可读 JSON 此前缺失,已由 `cts_multi_report.py --adopt-legacy` 从 `~/w7/logs/cts-a64/base/runs` 重生成:
|
||||
`tools/cts/baselines/base-DirectVulkan-monolith-p7w1-9be62cbc.{json,md}`(逐块数字与 `../device-window-1/CTS-base/README.md` 一致)。
|
||||
|
||||
## dry run(2026-09-23,Redmi `2f7cbe2e`,已装 p7w6 APK,只证管线)
|
||||
|
||||
| 目录 | 内容 |
|
||||
|---|---|
|
||||
| `dry-run/dry-p7w6/` | preflight(找到:supervisor 在跑 / stay-on 15 / UNPINNED)→ 身份核对(设备 `base.apk` = `45759c30…`)→ 门 3 两例(OpenRA、iris-bsl-in-world)× 四臂 × 1 → bsl inproc → CTS dsa 前 20 例 → reduce → restore;`verdict.txt` 与 `timing.tsv` |
|
||||
| `dry-run/dry-p7w6-b-bsl/` | 修 supervisor 探测与采样器预停后重跑:bsl inproc + spawn 的 maps / RSS 峰值与 `wbuf[]` |
|
||||
| `dry-run/dry-p7w6-c-cts-ssbo-dsa/` | CTS 计时样本:p7w6 inproc 全 ssbo + dsa |
|
||||
| `dry-run/build-p7w7dry-14e1c8b9/` | `10-build.sh 14e1c8b9 p7w7dry-14e1c8b9`:APK 131 s、主机制品 223 s;**未安装** |
|
||||
| `dry-run/pre-14e1c8b9-cts/` | pipe 头 lib 的 CTS 五块预读(inproc)与红例的 monolith / inproc 逐例归属(`attribution.txt`)——门 5 在该头上会红,见 RUNBOOK §6 |
|
||||
|
||||
原始归档(actual PNG、角色日志、qpa)在 `~/w7/logs/devprep/w2/<stamp>/`。
|
||||
@@ -0,0 +1 @@
|
||||
f2ca6b02c790c1be51e432aa3671d577888bc46cca7554108914dab1e38b2f3a trace-p7w7dry-14e1c8b9.apk
|
||||
@@ -0,0 +1,3 @@
|
||||
3d6a959f2fb8caa0780d339393eb3194f051130749ac264e94aee961c93acdde libMobileGL.so
|
||||
7a95cb4d276b40e4843c9d9f8c4d0f3486bfa6b5fc3e3b9a0dd842e1e9403ed6 libMobileGLServer.so
|
||||
700907be83c2c1c1c83eec8de37300a6fdab4c7f06387116fa8aaee0169b7291 mobilegl_trace_replay
|
||||
@@ -0,0 +1,2 @@
|
||||
7891670f7286d0a6522d52185a48b810004f3273e37e7c7bdf4d2d6f1bed3804 libMobileGL.so
|
||||
24c4eaf39a7c3ec3dbdc1198c269c72abde1e318fbce1c428ac92a6bbd1efc39 libMobileGLServer.so
|
||||
@@ -0,0 +1,3 @@
|
||||
build-apk 2026-09-23T09:32:36 2026-09-23T09:34:47 131
|
||||
build-host 2026-09-23T09:34:47 2026-09-23T09:38:30 223
|
||||
build 2026-09-23T09:32:32 2026-09-23T09:38:30 358 all
|
||||
|
@@ -0,0 +1,28 @@
|
||||
== BSL-ESC-MENU MOBILEGL_PIPE_STATS (maps lines / RSS peaks, wbuf[] gauges) ==
|
||||
[inproc] rc=0 seconds=14 finished=2026-09-23T09:43:28-04:00
|
||||
replay: passed=True ssim=0.999791667 sha=155dcdd13a24e0ee
|
||||
pid comm role samples maps_peak VmRSS_peak_kB VmHWM_kB span_s
|
||||
483 ugin.p7w1.trace app 38 8536 822968 822968 14.0
|
||||
3 wbuf[wbufs=28 wlivepk=1052 wdefpk=3312832 wdefsync=24]
|
||||
[spawn] rc=0 seconds=14 finished=2026-09-23T09:43:47-04:00
|
||||
replay: passed=True ssim=0.999791667 sha=155dcdd13a24e0ee
|
||||
pid comm role samples maps_peak VmRSS_peak_kB VmHWM_kB span_s
|
||||
7405 libMobileGLServ server 32 7401 342144 343392 13.1
|
||||
677 ugin.p7w1.trace app 33 4595 552672 554952 13.5
|
||||
3 wbuf[wbufs=28 wlivepk=1052 wdefpk=3312832 wdefsync=24]
|
||||
|
||||
== CTS AFTER (inproc x DirectVulkan) vs BASE (monolith x DirectVulkan, p7w1) ==
|
||||
rate = Pass/(results-NotSupported); gate: delta >= -0.5 pp and 0 new crash per block
|
||||
block cases BASE P/NS/F/X rate AFTER P/NS/F/X rate delta pp crash regr fixed verdict
|
||||
dsa 20 19/0/0/1 95.000% 19/0/0/1 95.000% +0.000 0 0 0 PASS (SUBSET)
|
||||
CTS PASS (SUBSET run: not a gate verdict)
|
||||
|
||||
== TIMING ==
|
||||
preflight 5s 2026-09-23T09:43:03 -> 2026-09-23T09:43:08 reboot=0 pin=1
|
||||
install 0s 2026-09-23T09:43:08 -> 2026-09-23T09:43:08 verify_only=1
|
||||
bsl-inproc 14s 2026-09-23T09:43:11 -> 2026-09-23T09:43:25
|
||||
bsl-spawn 14s 2026-09-23T09:43:30 -> 2026-09-23T09:43:44
|
||||
bsl 38s 2026-09-23T09:43:09 -> 2026-09-23T09:43:47
|
||||
cts-dsa 1s 2026-09-23T09:43:51 -> 2026-09-23T09:43:52 limit=20
|
||||
cts 6s 2026-09-23T09:43:47 -> 2026-09-23T09:43:53 blocks=[dsa] limit=20
|
||||
reduce rc=0
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
== CTS AFTER (inproc x DirectVulkan) vs BASE (monolith x DirectVulkan, p7w1) ==
|
||||
rate = Pass/(results-NotSupported); gate: delta >= -0.5 pp and 0 new crash per block
|
||||
block cases BASE P/NS/F/X rate AFTER P/NS/F/X rate delta pp crash regr fixed verdict
|
||||
dsa 371 368/0/2/1 99.191% 366/0/3/2 98.652% -0.539 1 2 0 FAIL
|
||||
! 1 NEW crash(es)
|
||||
! delta -0.539 pp < -0.5 pp
|
||||
NEW CRASH KHR-GL46.direct_state_access.renderbuffers_storage
|
||||
Pass->not KHR-GL46.direct_state_access.renderbuffers_storage
|
||||
Pass->not KHR-GL46.direct_state_access.renderbuffers_storage_multisample
|
||||
ssbo 124 124/0/0/0 100.000% 124/0/0/0 100.000% +0.000 0 0 0 PASS
|
||||
CTS FAIL
|
||||
|
||||
== TIMING ==
|
||||
preflight 6s 2026-09-23T09:56:51 -> 2026-09-23T09:56:57 reboot=0 pin=1
|
||||
cts-ssbo 3s 2026-09-23T09:57:00 -> 2026-09-23T09:57:03 limit=0
|
||||
cts-dsa 9s 2026-09-23T09:57:04 -> 2026-09-23T09:57:13 limit=0
|
||||
cts 16s 2026-09-23T09:56:57 -> 2026-09-23T09:57:13 blocks=[ssbo dsa] limit=0
|
||||
reduce rc=1
|
||||
@@ -0,0 +1,5 @@
|
||||
codePath=/data/app/~~4br5M_QTsaPrvHx-69f_Xg==/top.mobilegl.plugin.p7w1.trace-NDMXLIpuwnAYYsgnuI7hRA==
|
||||
primaryCpuAbi=arm64-v8a
|
||||
versionCode=26091061 minSdk=26 targetSdk=34
|
||||
versionName=26.09.0e16ca2-trace
|
||||
lastUpdateTime=2026-09-23 12:03:48
|
||||
@@ -0,0 +1 @@
|
||||
device base.apk: /data/app/~~4br5M_QTsaPrvHx-69f_Xg==/top.mobilegl.plugin.p7w1.trace-NDMXLIpuwnAYYsgnuI7hRA==/base.apk 45759c3038854c5cff558a352b27f86553ebcddad2ee218fe796d74208406cf8
|
||||
@@ -0,0 +1,8 @@
|
||||
apk : /home/swung/w7/logs/p7w6/trace-p7w6.apk
|
||||
apk sha256 : 45759c3038854c5cff558a352b27f86553ebcddad2ee218fe796d74208406cf8
|
||||
lib sha256 : 12861aa16bfce3001ead2f958bb128825336b5fba712b6dd3ae2331b03b4294c
|
||||
lib stamp hits : 0 (dry-p7w6)
|
||||
device before : 7f58aa0b140dd6501586f89bf2a352d81ac77bb3148f2bb3059e097b202b4994
|
||||
glcts sha256 : e980ea0abc6a729d413454b4c84ec87d90d0488a7b1d9e3e78671464adc7b809
|
||||
env : MOBILEGL_BACKEND_TYPE=DirectVulkan MOBILEGL_CTS_FBO_COLOR_TEXTURE=1 MOBILEGL_TRANSPORT=inproc MOBILEGL_IPC_ROLE_SPLIT_STATE=1 MOBILEGL_IPC_STRICT_ERRORS=1 MOBILEGL_IPC_RUN_AHEAD=1
|
||||
device after : 12861aa16bfce3001ead2f958bb128825336b5fba712b6dd3ae2331b03b4294c
|
||||
@@ -0,0 +1,2 @@
|
||||
mgprobe: transport-marker=1 ipc-lines=[Config: IPC ring=8MiB stage=32MiB wire-deferred=64MiB spin=50us persistent-block=64KiB adopt-tier=2 verb-barrier=1 run-ahead=1 present-credit=1 strict=1 audit=0 role-split-state=1 affinity='auto'] fatal=0 -> PROVEN
|
||||
glcts KHR-GL46.direct_state_access.buffers_clear: transport-marker=1 ipc-lines=[Config: IPC ring=8MiB stage=32MiB wire-deferred=64MiB spin=50us persistent-block=64KiB adopt-tier=2 verb-barrier=1 run-ahead=1 present-credit=1 strict=1 audit=0 role-split-state=1 affinity='auto'] fatal=0 -> PROVEN
|
||||
@@ -0,0 +1,8 @@
|
||||
monolith OpenRA 0 6 2026-09-23T09:39:50-04:00
|
||||
monolith minecraft-1.21.4-fabric-iris-bsl-in-world 0 8 2026-09-23T09:39:58-04:00
|
||||
inproc OpenRA 0 7 2026-09-23T09:40:06-04:00
|
||||
inproc minecraft-1.21.4-fabric-iris-bsl-in-world 0 8 2026-09-23T09:40:14-04:00
|
||||
spawn OpenRA 0 7 2026-09-23T09:40:22-04:00
|
||||
spawn minecraft-1.21.4-fabric-iris-bsl-in-world 0 8 2026-09-23T09:40:30-04:00
|
||||
inproc-ra0 OpenRA 1 6 2026-09-23T09:40:37-04:00
|
||||
inproc-ra0 minecraft-1.21.4-fabric-iris-bsl-in-world 1 8 2026-09-23T09:40:46-04:00
|
||||
|
@@ -0,0 +1,5 @@
|
||||
FOUND_SUPERVISOR=1
|
||||
FOUND_STAYON=15
|
||||
FOUND_PIN=UNPINNED
|
||||
FOUND_AT=2026-09-23T09:39:38-04:00
|
||||
# FOUND_SUPERVISOR corrected 0->1 by hand: the first preflight read a live supervisor (am_kill of pid 17256 :mglsrv at 21:39:47 device time, AFTER this record) as absent through the pipefail + grep -q bug since fixed in lib.sh
|
||||
@@ -0,0 +1,5 @@
|
||||
focus : mCurrentFocus=Window{3128f99 u0 com.miui.home/com.miui.home.launcher.Launcher}
|
||||
supervisor : listening (found: 1)
|
||||
pin : UNPINNED (found: UNPINNED)
|
||||
stayon : 15 (found: 15)
|
||||
doze wl : user,top.mobilegl.plugin.p7w1.trace,10318
|
||||
@@ -0,0 +1,12 @@
|
||||
preflight 2026-09-23T09:39:38 2026-09-23T09:39:43 5 reboot=0 pin=1
|
||||
install 2026-09-23T09:39:43 2026-09-23T09:39:43 0 verify_only=1
|
||||
gate3-monolith 2026-09-23T09:39:44 2026-09-23T09:39:59 15 2 cases
|
||||
gate3-inproc 2026-09-23T09:39:59 2026-09-23T09:40:15 16 2 cases
|
||||
gate3-spawn 2026-09-23T09:40:15 2026-09-23T09:40:30 15 2 cases
|
||||
gate3-inproc-ra0 2026-09-23T09:40:31 2026-09-23T09:40:46 15 2 cases
|
||||
gate3 2026-09-23T09:39:43 2026-09-23T09:40:46 63
|
||||
bsl-inproc 2026-09-23T09:40:48 2026-09-23T09:41:01 13
|
||||
bsl 2026-09-23T09:40:47 2026-09-23T09:41:05 18
|
||||
cts-dsa 2026-09-23T09:41:08 2026-09-23T09:41:09 1 limit=20
|
||||
cts 2026-09-23T09:41:05 2026-09-23T09:41:10 5 blocks=[dsa] limit=20
|
||||
restore 2026-09-23T09:41:16 2026-09-23T09:41:23 7
|
||||
|
@@ -0,0 +1,39 @@
|
||||
== GATE 3 (DirectVulkan x pbuffer; split repeat=1; tol |ssim-monolith| <= 0.0005) ==
|
||||
case verdict monolith inproc(min..max) #sha spawn(min..max) #sha ra0 i==s==m
|
||||
OpenRA PASS 1.000000 1.000000..1.000000 #1 1.000000..1.000000 #1 1.000000 yes
|
||||
minecraft-1.21.4-fabric-iris-bsl-in-world PASS 0.997010 0.997010..0.997010 #1 0.997010..0.997010 #1 0.997010 yes
|
||||
-- RUN_AHEAD=0 control (recorded, not gating): 2 case(s); proofs: run-ahead=0
|
||||
-- excluded (red on monolith, CONTRACT-P7 7.1): minecraft-1.21.1-neoforge-create-indirect-in-world, minecraft-1.21.11-main-menu, minecraft-1.21.4-fabric-iris-photon-v1.3b-in-world
|
||||
GATE3 PASS: 2/2 cases PASS (denominator is 2, not the gate's 36: a subset run is NOT a gate verdict)
|
||||
|
||||
== BSL-ESC-MENU MOBILEGL_PIPE_STATS (maps lines / RSS peaks, wbuf[] gauges) ==
|
||||
[inproc] rc=0 seconds=13 finished=2026-09-23T09:41:05-04:00
|
||||
replay: passed=True ssim=0.999791667 sha=155dcdd13a24e0ee
|
||||
pid comm samples maps_peak VmRSS_peak_kB VmHWM_kB span_s
|
||||
32599 ugin.p7w1.trace 38 8115 821992 823612 13.9
|
||||
32416 ugin.p7w1.trace 6 5191 768728 804116 1.9
|
||||
3 wbuf[wbufs=28 wlivepk=1052 wdefpk=3312832 wdefsync=24]
|
||||
|
||||
== CTS AFTER (inproc x DirectVulkan) vs BASE (monolith x DirectVulkan, p7w1) ==
|
||||
rate = Pass/(results-NotSupported); gate: delta >= -0.5 pp and 0 new crash per block
|
||||
block cases BASE P/NS/F/X rate AFTER P/NS/F/X rate delta pp crash regr fixed verdict
|
||||
dsa 20 19/0/0/1 95.000% 19/0/0/1 95.000% +0.000 0 0 0 PASS (SUBSET)
|
||||
CTS PASS (SUBSET run: not a gate verdict)
|
||||
|
||||
== TIMING ==
|
||||
preflight 5s 2026-09-23T09:39:38 -> 2026-09-23T09:39:43 reboot=0 pin=1
|
||||
install 0s 2026-09-23T09:39:43 -> 2026-09-23T09:39:43 verify_only=1
|
||||
gate3-monolith 15s 2026-09-23T09:39:44 -> 2026-09-23T09:39:59 2 cases
|
||||
gate3-inproc 16s 2026-09-23T09:39:59 -> 2026-09-23T09:40:15 2 cases
|
||||
gate3-spawn 15s 2026-09-23T09:40:15 -> 2026-09-23T09:40:30 2 cases
|
||||
gate3-inproc-ra0 15s 2026-09-23T09:40:31 -> 2026-09-23T09:40:46 2 cases
|
||||
gate3 63s 2026-09-23T09:39:43 -> 2026-09-23T09:40:46
|
||||
bsl-inproc 13s 2026-09-23T09:40:48 -> 2026-09-23T09:41:01
|
||||
bsl 18s 2026-09-23T09:40:47 -> 2026-09-23T09:41:05
|
||||
cts-dsa 1s 2026-09-23T09:41:08 -> 2026-09-23T09:41:09 limit=20
|
||||
cts 5s 2026-09-23T09:41:05 -> 2026-09-23T09:41:10 blocks=[dsa] limit=20
|
||||
gate3 monolith 2 case invocations, mean 7s, total 14s
|
||||
gate3 inproc 2 case invocations, mean 8s, total 15s
|
||||
gate3 spawn 2 case invocations, mean 8s, total 15s
|
||||
gate3 inproc-ra0 2 case invocations, mean 7s, total 14s
|
||||
reduce rc=0
|
||||
@@ -0,0 +1,8 @@
|
||||
apk : /home/swung/w7/logs/devprep/w2/p7w7dry-14e1c8b9/apk/trace-p7w7dry-14e1c8b9.apk
|
||||
apk sha256 : f2ca6b02c790c1be51e432aa3671d577888bc46cca7554108914dab1e38b2f3a
|
||||
lib sha256 : 7891670f7286d0a6522d52185a48b810004f3273e37e7c7bdf4d2d6f1bed3804
|
||||
lib stamp hits : 0 (pre-14e1c8b9)
|
||||
device before : 7f58aa0b140dd6501586f89bf2a352d81ac77bb3148f2bb3059e097b202b4994
|
||||
glcts sha256 : e980ea0abc6a729d413454b4c84ec87d90d0488a7b1d9e3e78671464adc7b809
|
||||
env : MOBILEGL_BACKEND_TYPE=DirectVulkan MOBILEGL_CTS_FBO_COLOR_TEXTURE=1 MOBILEGL_TRANSPORT=inproc MOBILEGL_IPC_ROLE_SPLIT_STATE=1 MOBILEGL_IPC_STRICT_ERRORS=1 MOBILEGL_IPC_RUN_AHEAD=1
|
||||
device after : 7891670f7286d0a6522d52185a48b810004f3273e37e7c7bdf4d2d6f1bed3804
|
||||
@@ -0,0 +1,2 @@
|
||||
mgprobe: transport-marker=1 ipc-lines=[Config: IPC ring=8MiB stage=32MiB wire-deferred=64MiB spin=50us persistent-block=64KiB adopt-tier=2 verb-barrier=1 run-ahead=1 present-credit=1 strict=1 audit=0 role-split-state=1 affinity='auto'] fatal=0 -> PROVEN
|
||||
glcts KHR-GL46.direct_state_access.buffers_clear: transport-marker=1 ipc-lines=[Config: IPC ring=8MiB stage=32MiB wire-deferred=64MiB spin=50us persistent-block=64KiB adopt-tier=2 verb-barrier=1 run-ahead=1 present-credit=1 strict=1 audit=0 role-split-state=1 affinity='auto'] fatal=0 -> PROVEN
|
||||
@@ -0,0 +1,16 @@
|
||||
direct_state_access.renderbuffers_storage monolith RC=0 StatusCode="Pass"
|
||||
direct_state_access.renderbuffers_storage inproc-gate RC=134 Fatal{ReplyTooLarge, "ReadPixels 256x512 0x1908/0x1406 2097152 > 2097136"}
|
||||
direct_state_access.renderbuffers_storage inproc-plain RC=134 Fatal{ReplyTooLarge, "ReadPixels 256x512 0x1908/0x1406 2097152 > 2097136"}
|
||||
direct_state_access.renderbuffers_storage_multisample monolith RC=0 StatusCode="Pass"
|
||||
direct_state_access.renderbuffers_storage_multisample inproc-gate RC=1 StatusCode="Fail"
|
||||
direct_state_access.renderbuffers_storage_multisample inproc-plain RC=1 StatusCode="Fail"
|
||||
shader_image_load_store.incomplete_textures monolith RC=1 StatusCode="Fail"
|
||||
shader_image_load_store.incomplete_textures inproc-gate RC=134 Fatal{UnmigratedVerb, "Magma:image-view-window"}
|
||||
shader_image_load_store.incomplete_textures inproc-plain RC=134 Fatal{UnmigratedVerb, "Magma:image-view-window"}
|
||||
shader_image_load_store.advanced-sync-vertexArray monolith RC=1 StatusCode="Fail"
|
||||
shader_image_load_store.advanced-sync-vertexArray inproc-gate RC=1 StatusCode="Fail"
|
||||
shader_image_load_store.advanced-sync-vertexArray inproc-plain RC=1 StatusCode="Fail"
|
||||
texture_border_clamp.Texture2DArrayCompressed monolith RC=0 StatusCode="Pass"
|
||||
texture_border_clamp.Texture2DArrayCompressed inproc-gate RC=0 StatusCode="Pass"
|
||||
texture_border_clamp.Texture2DArrayCompressed inproc-plain RC=0 StatusCode="Pass"
|
||||
BASE lib restored (7f58aa0b140dd6501586f89bf2a352d81ac77bb3148f2bb3059e097b202b4994)
|
||||
@@ -0,0 +1,17 @@
|
||||
=== glcts conformance summary [DirectVulkan-inproc-dsa] ===
|
||||
files parsed : 2
|
||||
cases with result : 371
|
||||
|
||||
Pass 366 98.65%
|
||||
! Fail 3 0.81%
|
||||
CompatibilityWarning 1 0.27%
|
||||
! Crash 1 0.27%
|
||||
|
||||
conformance pass rate (Pass+NotSupported+warnings) : 98.92% (367/371)
|
||||
strict pass rate (Pass only) : 98.65% (366/371)
|
||||
failures : 4
|
||||
|
||||
--- worst groups (of 1) ---
|
||||
KHR-GL46.direct_state_access 4/371 fail ( 1.1%)
|
||||
|
||||
wrote /home/swung/w7/logs/devprep/w2/pre-14e1c8b9/cts/report-dsa.json
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
=== glcts conformance summary [DirectVulkan-inproc-packed-pixels] ===
|
||||
files parsed : 1
|
||||
cases with result : 4732
|
||||
|
||||
Pass 4732 100.00%
|
||||
|
||||
conformance pass rate (Pass+NotSupported+warnings) : 100.00% (4732/4732)
|
||||
strict pass rate (Pass only) : 100.00% (4732/4732)
|
||||
failures : 0
|
||||
|
||||
wrote /home/swung/w7/logs/devprep/w2/pre-14e1c8b9/cts/report-packed-pixels.json
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
=== glcts conformance summary [DirectVulkan-inproc-shader-image] ===
|
||||
files parsed : 2
|
||||
cases with result : 125
|
||||
|
||||
Pass 65 52.00%
|
||||
NotSupported 56 44.80%
|
||||
! Fail 3 2.40%
|
||||
! Crash 1 0.80%
|
||||
|
||||
conformance pass rate (Pass+NotSupported+warnings) : 96.80% (121/125)
|
||||
strict pass rate (Pass only) : 52.00% (65/125)
|
||||
failures : 4
|
||||
|
||||
--- worst groups (of 2) ---
|
||||
KHR-GL46.shader_image_load_store 4/51 fail ( 7.8%)
|
||||
|
||||
wrote /home/swung/w7/logs/devprep/w2/pre-14e1c8b9/cts/report-shader-image.json
|
||||
@@ -0,0 +1,11 @@
|
||||
=== glcts conformance summary [DirectVulkan-inproc-ssbo] ===
|
||||
files parsed : 1
|
||||
cases with result : 124
|
||||
|
||||
Pass 124 100.00%
|
||||
|
||||
conformance pass rate (Pass+NotSupported+warnings) : 100.00% (124/124)
|
||||
strict pass rate (Pass only) : 100.00% (124/124)
|
||||
failures : 0
|
||||
|
||||
wrote /home/swung/w7/logs/devprep/w2/pre-14e1c8b9/cts/report-ssbo.json
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
=== glcts conformance summary [DirectVulkan-inproc-texture] ===
|
||||
files parsed : 1
|
||||
cases with result : 1054
|
||||
|
||||
Pass 823 78.08%
|
||||
NotSupported 221 20.97%
|
||||
! Fail 10 0.95%
|
||||
|
||||
conformance pass rate (Pass+NotSupported+warnings) : 99.05% (1044/1054)
|
||||
strict pass rate (Pass only) : 78.08% (823/1054)
|
||||
failures : 10
|
||||
|
||||
--- NOT MEASURED (excluded from the rates above) ---
|
||||
quarantined up front : 1
|
||||
The rates above cover only cases that produced a result.
|
||||
|
||||
--- worst groups (of 19) ---
|
||||
KHR-GL46.texture_cube_map_array 5/27 fail ( 18.5%)
|
||||
KHR-GL46.texture_border_clamp 3/32 fail ( 9.4%)
|
||||
KHR-GL46.texture_buffer 1/16 fail ( 6.2%)
|
||||
KHR-GL46.texture_view 1/7 fail ( 14.3%)
|
||||
|
||||
wrote /home/swung/w7/logs/devprep/w2/pre-14e1c8b9/cts/report-texture.json
|
||||
+1
@@ -0,0 +1 @@
|
||||
KHR-GL46.direct_state_access.renderbuffers_storage
|
||||
+1
@@ -0,0 +1 @@
|
||||
KHR-GL46.shader_image_load_store.incomplete_textures
|
||||
@@ -0,0 +1,42 @@
|
||||
== CTS AFTER (inproc x DirectVulkan) vs BASE (monolith x DirectVulkan, p7w1) ==
|
||||
rate = Pass/(results-NotSupported); gate: delta >= -0.5 pp and 0 new crash per block
|
||||
block cases BASE P/NS/F/X rate AFTER P/NS/F/X rate delta pp crash regr fixed verdict
|
||||
dsa 371 368/0/2/1 99.191% 366/0/3/2 98.652% -0.539 1 2 0 FAIL
|
||||
! 1 NEW crash(es)
|
||||
! delta -0.539 pp < -0.5 pp
|
||||
NEW CRASH KHR-GL46.direct_state_access.renderbuffers_storage
|
||||
Pass->not KHR-GL46.direct_state_access.renderbuffers_storage
|
||||
Pass->not KHR-GL46.direct_state_access.renderbuffers_storage_multisample
|
||||
packed-pixels 4732 4732/0/0/0 100.000% 4732/0/0/0 100.000% +0.000 0 0 0 PASS
|
||||
shader-image 125 63/56/6/0 91.304% 65/56/3/1 94.203% +2.899 1 1 3 FAIL
|
||||
! 1 NEW crash(es)
|
||||
! note: AFTER is 2.899 pp ABOVE BASE (not a regression; review the fixed list)
|
||||
NEW CRASH KHR-GL46.shader_image_load_store.incomplete_textures
|
||||
Pass->not KHR-GL46.shader_image_load_store.advanced-sync-vertexArray
|
||||
not->Pass KHR-GL46.shader_image_load_store.advanced-sync-drawIndirect
|
||||
not->Pass KHR-GL46.shader_image_load_store.advanced-sync-textureUpdate
|
||||
not->Pass KHR-GL46.shader_image_load_store.non-layered_binding
|
||||
ssbo 124 124/0/0/0 100.000% 124/0/0/0 100.000% +0.000 0 0 0 PASS
|
||||
texture 1054 815/221/18/0 97.839% 823/221/10/0 98.800% +0.960 0 1 9 PASS
|
||||
! note: AFTER is 0.960 pp ABOVE BASE (not a regression; review the fixed list)
|
||||
Pass->not KHR-GL46.texture_border_clamp.Texture2DArrayCompressed
|
||||
not->Pass KHR-GL46.texture_barrier.disjoint-texels
|
||||
not->Pass KHR-GL46.texture_barrier.overlapping-texels
|
||||
not->Pass KHR-GL46.texture_barrier.same-texel-rw
|
||||
not->Pass KHR-GL46.texture_barrier.same-texel-rw-multipass
|
||||
not->Pass KHR-GL46.texture_size_promotion.functional
|
||||
not->Pass KHR-GL46.texture_swizzle.functional_format_idx_19_target_idx_7
|
||||
not->Pass KHR-GL46.texture_swizzle.functional_format_idx_19_target_idx_8
|
||||
not->Pass KHR-GL46.texture_swizzle.functional_format_idx_8_target_idx_7
|
||||
not->Pass KHR-GL46.texture_swizzle.functional_format_idx_8_target_idx_8
|
||||
CTS FAIL
|
||||
|
||||
== TIMING ==
|
||||
preflight 5s 2026-09-23T09:59:01 -> 2026-09-23T09:59:06 reboot=0 pin=1
|
||||
cts-shader-image 9s 2026-09-23T09:59:10 -> 2026-09-23T09:59:19 limit=0
|
||||
cts-ssbo 3s 2026-09-23T09:59:20 -> 2026-09-23T09:59:23 limit=0
|
||||
cts-dsa 9s 2026-09-23T09:59:24 -> 2026-09-23T09:59:33 limit=0
|
||||
cts-texture 108s 2026-09-23T09:59:34 -> 2026-09-23T10:01:22 limit=0
|
||||
cts-packed-pixels 220s 2026-09-23T10:01:23 -> 2026-09-23T10:05:03 limit=0
|
||||
cts 358s 2026-09-23T09:59:06 -> 2026-09-23T10:05:04 blocks=[shader-image ssbo dsa texture packed-pixels] limit=0
|
||||
reduce rc=1
|
||||
@@ -0,0 +1,127 @@
|
||||
#!/usr/bin/env bash
|
||||
# 10-build.sh <pipe-sha> [<stamp>] [--apk-only|--host-only]
|
||||
#
|
||||
# Builds the window's two artefacts from ONE source commit and ONE explicit stamp:
|
||||
# <out>/apk/trace-<stamp>.apk signed, debuggable, side-by-side id top.mobilegl.plugin.p7w1.trace
|
||||
# <out>/host/{libMobileGL.so,libMobileGLServer.so,mobilegl_trace_replay} + catalog.json
|
||||
# (<out> = ~/w7/logs/p7w7/<stamp>; stamp defaults to p7w7-<sha8>). The same stamp on both ends is
|
||||
# what MOBILEGL_IPC_REQUIRE_SAME_BUILD=1 checks, and the device server must be THIS build (F changed
|
||||
# the wire fingerprint: an old server + new client only says `no Welcome (rc=6)`).
|
||||
#
|
||||
# It never builds in ~/w7/pipe (read-only for agents, and a gate needs its status clean): the source
|
||||
# is a DETACHED worktree ~/w7/p7w7-tree-<sha8> at <pipe-sha>, submodules copied from the pipe
|
||||
# checkout when their recorded commit matches, the glslang External tree copied, LFS fixtures
|
||||
# smudged by the worktree checkout. That tree is also the tools tree the device steps run from.
|
||||
# Recipe = ~/w7/logs/p7w6-apk-inner.sh + ~/w7/logs/p7w6host-build.sh, parameterised.
|
||||
set -euo pipefail
|
||||
. "$(dirname "$0")/lib.sh"
|
||||
|
||||
[ $# -ge 1 ] || die "usage: $0 <pipe-sha> [<stamp>] [--apk-only|--host-only]"
|
||||
SHA=$(git -C "$W2_PIPE" rev-parse --verify "$1^{commit}") || die "unknown commit $1 in $W2_PIPE"
|
||||
SHA8=${SHA:0:8}
|
||||
STAMP=${2:-p7w7-$SHA8}
|
||||
case "${2:-}" in --*) STAMP=p7w7-$SHA8;; esac
|
||||
MODE=all
|
||||
for a in "$@"; do case "$a" in --apk-only) MODE=apk;; --host-only) MODE=host;; esac; done
|
||||
TREE=${W2_BUILD_TREE:-$HOME/w7/p7w7-tree-$SHA8}
|
||||
OUT=$(w2_out "$STAMP")
|
||||
mkdir -p "$OUT/apk" "$OUT/host"
|
||||
t0=$(date +%s)
|
||||
log "build sha=$SHA stamp=$STAMP tree=$TREE out=$OUT mode=$MODE"
|
||||
|
||||
# ---- source tree ---------------------------------------------------------------------------
|
||||
if [ ! -e "$TREE/.git" ]; then
|
||||
log "creating detached worktree $TREE @ $SHA8"
|
||||
git -C "$W2_PIPE" worktree add --detach "$TREE" "$SHA" > "$OUT/worktree.log" 2>&1
|
||||
fi
|
||||
[ "$(git -C "$TREE" rev-parse HEAD)" = "$SHA" ] || die "$TREE is not at $SHA (refusing to move a tree someone may be using)"
|
||||
# Submodules: copy the pipe checkout's copy when it is at the recorded commit (fast, offline);
|
||||
# otherwise fall back to a real submodule update for that path.
|
||||
git -C "$TREE" submodule status | while read -r st path _; do
|
||||
want=${st#[-+U ]}
|
||||
[ -z "$(ls -A "$TREE/$path" 2>/dev/null)" ] || continue
|
||||
have=$(git -C "$W2_PIPE/$path" rev-parse HEAD 2>/dev/null || true)
|
||||
if [ "$have" = "$want" ]; then
|
||||
rm -rf "$TREE/$path"
|
||||
cp -a "$W2_PIPE/$path" "$TREE/$path"
|
||||
rm -f "$TREE/$path/.git" # the gitlink points into pipe's module store: never share it
|
||||
log "submodule $path: copied from pipe ($want)"
|
||||
else
|
||||
log "submodule $path: pipe has ${have:-nothing}, want $want - git submodule update"
|
||||
git -C "$TREE" submodule update --init --recursive -- "$path"
|
||||
fi
|
||||
done
|
||||
[ -d "$TREE/3rdparty/glslang/External/spirv-tools" ] \
|
||||
|| cp -a "$W2_PIPE/3rdparty/glslang/External" "$TREE/3rdparty/glslang/"
|
||||
if head -c 40 "$TREE/tools/trace_replay/fixtures/openra.tgz" | grep -q 'git-lfs'; then
|
||||
log "fixtures are LFS pointers - git lfs pull"
|
||||
git -C "$TREE" lfs pull
|
||||
fi
|
||||
|
||||
# ---- APK -----------------------------------------------------------------------------------
|
||||
if [ "$MODE" != host ]; then
|
||||
ta=$(date +%s)
|
||||
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk ANDROID_HOME=$HOME/android-sdk ANDROID_SDK_ROOT=$HOME/android-sdk
|
||||
export PATH=$JAVA_HOME/bin:$PATH
|
||||
BT=$(ls -d "$HOME"/android-sdk/build-tools/* | sort -V | tail -1)
|
||||
SUFFIX=${STAMP%%-*}
|
||||
export MOBILEGL_BUILD_STAMP=$STAMP
|
||||
( cd "$TREE"
|
||||
rm -rf android-plugin/app/.cxx .cxx build/intermediates/cxx android-plugin/app/build/outputs/apk/trace
|
||||
"$HOME/gradle-8.10.2/bin/gradle" --no-daemon -p android-plugin :app:assembleTraceRelease \
|
||||
-Pmobilegl.apkSuffix="$SUFFIX" -Pmobilegl.applicationIdSuffix=.p7w1 -Pmobilegl.debuggableRelease=true \
|
||||
-Pmobilegl.logLevel=MOBILEGL_LOG_LEVEL_INFO -Pmobilegl.pipePush=ON \
|
||||
-Pmobilegl.buildDisaggregated=ON -Pmobilegl.buildDisaggregatedInproc=ON \
|
||||
--parallel --max-workers 8 ) > "$OUT/apk/gradle.log" 2>&1 || { tail -40 "$OUT/apk/gradle.log"; die "gradle failed"; }
|
||||
unsigned="$TREE/android-plugin/app/build/outputs/apk/trace/release/MobileGL-plugin-trace-release-$SUFFIX.apk"
|
||||
[ -f "$unsigned" ] || die "gradle produced no $unsigned"
|
||||
APK="$OUT/apk/trace-$STAMP.apk"
|
||||
"$BT/apksigner" sign --ks "$HOME/.android/debug.keystore" --ks-pass pass:android --key-pass pass:android \
|
||||
--ks-key-alias androiddebugkey --out "$APK" "$unsigned"
|
||||
rm -rf "$TREE/android-plugin/app/.cxx"
|
||||
( cd "$OUT/apk" && sha256sum "trace-$STAMP.apk" > apk.sha256 )
|
||||
rm -rf "$OUT/apk/lib" && mkdir -p "$OUT/apk/lib"
|
||||
unzip -o -q -j "$APK" lib/arm64-v8a/libMobileGL.so lib/arm64-v8a/libMobileGLServer.so -d "$OUT/apk/lib"
|
||||
n=$(strings "$OUT/apk/lib/libMobileGL.so" | grep -c -F "$STAMP" || true)
|
||||
[ "$n" -ge 1 ] || die "stamp $STAMP not found in the APK's libMobileGL.so"
|
||||
( cd "$OUT/apk/lib" && sha256sum libMobileGL.so libMobileGLServer.so > ../lib.sha256 )
|
||||
unzip -l "$APK" | grep -E 'libMobileGL(Server)?\.so' > "$OUT/apk/lib-listing.txt"
|
||||
log "APK $(stat -c %s "$APK") bytes sha256 $(cut -c1-16 "$OUT/apk/apk.sha256"), stamp strings in lib: $n"
|
||||
w2_timing "$OUT" build-apk "$ta" "$(date +%s)"
|
||||
fi
|
||||
|
||||
# ---- host artefacts (the TCP client side; same stamp) ---------------------------------------
|
||||
if [ "$MODE" != apk ]; then
|
||||
th=$(date +%s)
|
||||
cmake -S "$TREE" -B "$TREE/build-host" -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DMOBILEGL_BUILD_DISAGGREGATED=ON -DMOBILEGL_BUILD_DISAGGREGATED_INPROC=ON \
|
||||
-DMOBILEGL_PIPE_PUSH=ON -DMOBILEGL_BUILD_TRACE_REPLAY=ON \
|
||||
-DMOBILEGL_BUILD_INTEGRATION_TEST=ON -DMOBILEGL_BUILD_TEST=ON \
|
||||
-DMOBILEGL_BUILD_STAMP="$STAMP" -DMOBILEGL_LOG_ACTIVE_LEVEL=MOBILEGL_LOG_LEVEL_INFO \
|
||||
-DMOBILEGL_ITEST_EGL_VENDOR=/usr/share/glvnd/egl_vendor.d/50_mesa.json \
|
||||
-DMOBILEGL_ITEST_VK_ICD=/usr/share/vulkan/icd.d/lvp_icd.json \
|
||||
-DMOBILEGL_ITEST_TCP_ENDPOINT=tcp://127.0.0.1:41317 \
|
||||
> "$OUT/host/configure.log" 2>&1 || { tail -30 "$OUT/host/configure.log"; die "host configure failed"; }
|
||||
cmake --build "$TREE/build-host" -j 8 --target MobileGL MobileGLServer mobilegl_trace_replay \
|
||||
> "$OUT/host/build.log" 2>&1 || { tail -30 "$OUT/host/build.log"; die "host build failed"; }
|
||||
cp "$TREE/build-host/libMobileGL.so" "$TREE/build-host/libMobileGLServer.so" \
|
||||
"$TREE/build-host/tools/trace_replay/mobilegl_trace_replay" "$OUT/host/"
|
||||
n=$(strings "$OUT/host/libMobileGL.so" | grep -c -F "$STAMP" || true)
|
||||
[ "$n" -ge 1 ] || die "stamp $STAMP not found in the host libMobileGL.so"
|
||||
( cd "$OUT/host" && sha256sum libMobileGL.so libMobileGLServer.so mobilegl_trace_replay > ../host.sha256 )
|
||||
( cd "$TREE/build-host" && ctest --show-only=json-v1 > "$OUT/host/catalog.json" )
|
||||
log "host artefacts in $OUT/host (stamp strings: $n)"
|
||||
w2_timing "$OUT" build-host "$th" "$(date +%s)"
|
||||
fi
|
||||
|
||||
cat > "$OUT/build.env" <<EOF
|
||||
BUILD_SHA=$SHA
|
||||
BUILD_SHA8=$SHA8
|
||||
BUILD_STAMP=$STAMP
|
||||
BUILD_TREE=$TREE
|
||||
BUILD_APK=$OUT/apk/trace-$STAMP.apk
|
||||
EOF
|
||||
w2_timing "$OUT" build "$t0" "$(date +%s)" "$MODE"
|
||||
log "=== BUILD DONE $STAMP ==="
|
||||
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env bash
|
||||
# 20-install.sh <stamp> [--verify-only]
|
||||
#
|
||||
# Installs <out>/apk/trace-<stamp>.apk over the side-by-side package (adb install -r keeps the
|
||||
# package's data and never uninstalls anything), waits for dex2oat, and PROVES the identity: the
|
||||
# on-device base.apk sha256 must equal the signed file's. That on-device hash - not run.json, not
|
||||
# the newest Gradle output (W6-verify README's wrong-SHA note) - is what names the binary behind
|
||||
# every picture of the window. --verify-only skips the install (the dry run proves p7w6 this way).
|
||||
# The TCP supervisor dies with the package on install; 90-restore.sh restarts it if it was up.
|
||||
set -euo pipefail
|
||||
. "$(dirname "$0")/lib.sh"
|
||||
|
||||
[ $# -ge 1 ] || die "usage: $0 <stamp> [--verify-only]"
|
||||
STAMP=$1; VERIFY_ONLY=0; [ "${2:-}" = --verify-only ] && VERIFY_ONLY=1
|
||||
w2_load_build "$STAMP"
|
||||
OUT=$(w2_out "$STAMP")/session
|
||||
mkdir -p "$OUT"
|
||||
w2_require_device
|
||||
w2_lock
|
||||
t0=$(date +%s)
|
||||
WANT=$(sha256sum "$W2_APK" | cut -d' ' -f1)
|
||||
echo "$WANT $W2_APK" > "$OUT/apk.sha256"
|
||||
if [ $VERIFY_ONLY -eq 0 ]; then
|
||||
Ash "pm list packages | grep -i mobilegl" > "$OUT/packages-before.txt" || true
|
||||
log "installing $W2_APK ($WANT)"
|
||||
A install -r "$W2_APK" 2>&1 | tr -d '\r' | tee "$OUT/install.txt"
|
||||
grep -q Success "$OUT/install.txt" || die "install failed"
|
||||
fi
|
||||
Ash "dumpsys package $W2_PKG" | grep -E 'versionName|versionCode|lastUpdateTime|codePath|primaryCpuAbi' > "$OUT/apk-install.txt"
|
||||
cat "$OUT/apk-install.txt"
|
||||
BASE=$(Ash "pm path $W2_PKG" | sed -n 's/^package://p' | grep 'base.apk' | head -1)
|
||||
GOT=$(Ash "sha256sum $BASE" | cut -d' ' -f1)
|
||||
echo "device base.apk: $BASE $GOT" | tee "$OUT/apk-on-device.sha256"
|
||||
[ "$GOT" = "$WANT" ] || die "installed APK ($GOT) is not $W2_APK ($WANT)"
|
||||
if [ -n "${BUILD_SHA:-}" ]; then
|
||||
grep -q "versionName=.*${BUILD_SHA:0:7}" "$OUT/apk-install.txt" || die "versionName does not carry ${BUILD_SHA:0:7}"
|
||||
fi
|
||||
# An am_kill "due to installPackageLI" inside an arm measures the installer (runbook 1 section 3).
|
||||
Ash 'n=0; while pgrep dex2oat >/dev/null && [ $n -lt 150 ]; do sleep 2; n=$((n+1)); done; echo "dex2oat idle after $((n*2))s"' | tee "$OUT/dex2oat.txt"
|
||||
w2_timing "$(w2_out "$STAMP")" install "$t0" "$(date +%s)" "verify_only=$VERIFY_ONLY"
|
||||
log "=== INSTALL OK $STAMP (on-device sha256 $GOT) ==="
|
||||
@@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env bash
|
||||
# 21-preflight.sh <stamp> [--reboot] [--no-pin]
|
||||
#
|
||||
# Session start (runbook 1 section 2, CONTRACT-P7 7.2 "same reboot-clean session"):
|
||||
# --reboot records boot_id, reboots, waits for boot_completed, records boot_id again; the two
|
||||
# must differ or the window is NOT reboot-clean. Gate 3 requires it; the dry run
|
||||
# does not reboot.
|
||||
# records the state 90-restore.sh puts back: TCP supervisor up or not, stay-on setting, pin
|
||||
# state, Doze whitelist line, focused activity;
|
||||
# wakes the phone and sets `svc power stayon true` (息屏 cut child TCP in window 1b, ID-P7-48);
|
||||
# pins (pin_device.sh pin) unless --no-pin, then classifies `check` (PINNED-1100 = the board's
|
||||
# documented 1100 MHz pwrlevel-0 reading, accepted);
|
||||
# checks the CTS bundle is on the device and there is room to work.
|
||||
set -uo pipefail
|
||||
. "$(dirname "$0")/lib.sh"
|
||||
|
||||
[ $# -ge 1 ] || die "usage: $0 <stamp> [--reboot] [--no-pin]"
|
||||
STAMP=$1; shift
|
||||
REBOOT=0; PIN=1
|
||||
for a in "$@"; do case "$a" in --reboot) REBOOT=1;; --no-pin) PIN=0;; *) die "unknown option $a";; esac; done
|
||||
w2_load_build "$STAMP"
|
||||
OUT=$(w2_out "$STAMP")/session
|
||||
mkdir -p "$OUT"
|
||||
w2_require_device
|
||||
w2_lock
|
||||
t0=$(date +%s)
|
||||
|
||||
# ---- what we found (only the FIRST preflight of a stamp writes these: restore reads them) ---
|
||||
if [ ! -f "$OUT/found.env" ]; then
|
||||
sup=0; w2_supervisor_running && sup=1
|
||||
stayon=$(Ash "settings get global stay_on_while_plugged_in")
|
||||
pinstate=$(w2_pin_check "$W2_TOOLS" "$OUT/pin-found.txt")
|
||||
cat > "$OUT/found.env" <<EOF
|
||||
FOUND_SUPERVISOR=$sup
|
||||
FOUND_STAYON=$stayon
|
||||
FOUND_PIN=$pinstate
|
||||
FOUND_AT=$(date -Is)
|
||||
EOF
|
||||
Ash "dumpsys deviceidle whitelist" | grep -i mobilegl > "$OUT/deviceidle-found.txt" || true
|
||||
Ash "dumpsys window" | grep -E 'mCurrentFocus' > "$OUT/focus-found.txt" || true
|
||||
Ash "ps -A -o PID,PPID,USER,NAME,ARGS" | grep -iE 'mobilegl|mglsrv' > "$OUT/processes-found.txt" || true
|
||||
log "found: supervisor=$sup stayon=$stayon pin=$pinstate"
|
||||
fi
|
||||
|
||||
if [ $REBOOT -eq 1 ]; then
|
||||
Ash "cat /proc/sys/kernel/random/boot_id" > "$OUT/boot-id-before.txt"
|
||||
log "rebooting for a reboot-clean session"
|
||||
A reboot
|
||||
sleep 20
|
||||
A wait-for-device
|
||||
for _ in $(seq 1 120); do [ "$(Ash 'getprop sys.boot_completed')" = 1 ] && break; sleep 2; done
|
||||
sleep 20
|
||||
# File-based encryption: the app's data dir (where trace-replay-ci.sh copies each fixture with
|
||||
# run-as) is readable only after the first unlock. A phone with a lock-screen credential needs
|
||||
# one manual unlock here; wait up to 10 minutes for it rather than failing every case.
|
||||
w2_wake
|
||||
for i in $(seq 1 120); do
|
||||
[ "$(Ash 'getprop sys.user.0.ce_available')" = true ] && break
|
||||
[ $i = 1 ] && log "waiting for credential-encrypted storage: UNLOCK THE PHONE BY HAND if it shows a lock screen"
|
||||
sleep 5
|
||||
done
|
||||
[ "$(Ash 'getprop sys.user.0.ce_available')" = true ] || die "user 0 storage still locked after 10 min"
|
||||
fi
|
||||
Ash "cat /proc/sys/kernel/random/boot_id" > "$OUT/boot-id.txt"
|
||||
if [ $REBOOT -eq 1 ]; then
|
||||
if cmp -s "$OUT/boot-id-before.txt" "$OUT/boot-id.txt"; then die "boot_id unchanged: the reboot did not happen"; fi
|
||||
echo "reboot-clean: $(cat "$OUT/boot-id-before.txt") -> $(cat "$OUT/boot-id.txt")" | tee "$OUT/reboot-clean.txt"
|
||||
else
|
||||
echo "NOT reboot-clean (no --reboot): boot_id $(cat "$OUT/boot-id.txt"), up $(Ash 'cat /proc/uptime' | cut -d' ' -f1)s" | tee "$OUT/reboot-clean.txt"
|
||||
fi
|
||||
|
||||
w2_wake
|
||||
Ash "svc power stayon true"
|
||||
Ash "dumpsys power" | grep -E 'mWakefulness=|mStayOn=' > "$OUT/power.txt"
|
||||
Ash "dumpsys deviceidle get deep" > "$OUT/deviceidle-deep.txt" 2>&1 || true
|
||||
{
|
||||
echo "model : $(Ash 'getprop ro.product.model') / $(Ash 'getprop ro.board.platform')"
|
||||
echo "build : $(Ash 'getprop ro.build.fingerprint')"
|
||||
echo "battery : $(Ash 'dumpsys battery' | grep -E 'level|temperature|AC powered|USB powered' | tr -s ' ' | tr '\n' ' ')"
|
||||
echo "memory : $(Ash 'grep -E "MemTotal|MemAvailable" /proc/meminfo' | tr -s ' ' | tr '\n' ' ')"
|
||||
echo "tmp free : $(Ash 'df -h /data/local/tmp' | tail -1)"
|
||||
echo "mgcts : $(Ash "ls $W2_CTS_DEV 2>&1" | tr '\n' ' ')"
|
||||
echo "apk : $(grep versionName "$(w2_out "$STAMP")/session/apk-install.txt" 2>/dev/null | tr -d ' ')"
|
||||
} | tee "$OUT/device.txt"
|
||||
|
||||
if [ $PIN -eq 1 ]; then
|
||||
bash "$W2_TOOLS/tools/device_bench/pin_device.sh" "$W2_SERIAL" pin > "$OUT/pin-session-start.txt" 2>&1
|
||||
echo 1 > "$OUT/pinned-by-window"
|
||||
fi
|
||||
pin=$(w2_pin_check "$W2_TOOLS" "$OUT/pin-check-00.txt")
|
||||
log "pin: $pin"
|
||||
if [ $PIN -eq 1 ] && [ "$pin" != PINNED ] && [ "$pin" != PINNED-1100 ]; then
|
||||
die "pin did not take ($pin, see $OUT/pin-check-00.txt)"
|
||||
fi
|
||||
w2_timing "$(w2_out "$STAMP")" preflight "$t0" "$(date +%s)" "reboot=$REBOOT pin=$PIN"
|
||||
log "=== PREFLIGHT OK $STAMP ==="
|
||||
@@ -0,0 +1,124 @@
|
||||
#!/usr/bin/env bash
|
||||
# 30-gate3.sh <stamp> [--cases a,b,...] [--repeat N] [--arms monolith,inproc,spawn,inproc-ra0]
|
||||
#
|
||||
# CONTRACT-P7 7.1/7.2 exit gate 3, one reboot-clean session, DirectVulkan x --use-pbuffer:
|
||||
# monolith x1 the same-session control every split reading is scored against
|
||||
# inproc xN (N = --repeat, default 3) must be bit-identical across passes
|
||||
# spawn xN same, server role in a second process
|
||||
# inproc-ra0 x1 MOBILEGL_IPC_RUN_AHEAD=0 lockstep control, recorded only
|
||||
# over the 36-case denominator = --matrix's DirectVulkan cases minus W2_EXCLUDED (the three that
|
||||
# are red on monolith: create-indirect, 1.21.11 main menu, photon v1.3b). iterationrp carries the
|
||||
# apk.yml:460-462 Magma knobs on every arm. Every repeat's result.json, actual PNG, both role logs,
|
||||
# transport proof and logcat are archived under <out>/gate3/archive/<arm>/<case>-DirectVulkan/.
|
||||
#
|
||||
# RESUMABLE: one runner invocation per (arm, case); a finished pair writes
|
||||
# <out>/gate3/state/<arm>/<case>.done and is skipped on the next start. An interrupted pair is
|
||||
# re-run from scratch (its partial archive is removed first). Run it detached:
|
||||
# bash detach.sh ~/w7/logs/p7w7/<stamp>/gate3.log 30-gate3.sh <stamp>
|
||||
set -uo pipefail
|
||||
. "$(dirname "$0")/lib.sh"
|
||||
|
||||
[ $# -ge 1 ] || die "usage: $0 <stamp> [--cases a,b] [--repeat N] [--arms list]"
|
||||
STAMP=$1; shift
|
||||
CASES_ARG=""; REPEAT=3; ARMS="monolith inproc spawn inproc-ra0"
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--cases) CASES_ARG=$2; shift 2;;
|
||||
--repeat) REPEAT=$2; shift 2;;
|
||||
--arms) ARMS=${2//,/ }; shift 2;;
|
||||
*) die "unknown option $1";;
|
||||
esac
|
||||
done
|
||||
w2_load_build "$STAMP"
|
||||
OUT=$(w2_out "$STAMP")/gate3
|
||||
mkdir -p "$OUT"
|
||||
w2_require_device
|
||||
w2_lock
|
||||
export MOBILEGL_TRACE_PACKAGE=$W2_PKG MOBILEGL_TRACE_SKIP_INSTALL=1 MOBILEGL_TRACE_APK=$W2_APK
|
||||
RUNNER="$W2_TOOLS/tools/trace_replay/run_android_retrace_local.py"
|
||||
|
||||
# ---- the case list is frozen on first start so a resume cannot change the denominator ----------
|
||||
if [ ! -s "$OUT/cases.txt" ]; then
|
||||
if [ -n "$CASES_ARG" ]; then
|
||||
tr ',' '\n' <<<"$CASES_ARG" | sed '/^$/d' > "$OUT/cases.txt"
|
||||
else
|
||||
W2_EXCLUDED="$W2_EXCLUDED" python3 - "$W2_TOOLS/tools/trace_replay" > "$OUT/cases.txt" <<'PY'
|
||||
import os, sys
|
||||
sys.path.insert(0, sys.argv[1])
|
||||
from trace_cases import ci_backends, ci_trace_cases, load_trace_cases, split_trace_cases
|
||||
excluded = set(os.environ["W2_EXCLUDED"].split())
|
||||
for case in split_trace_cases(ci_trace_cases(load_trace_cases())):
|
||||
if "DirectVulkan" in ci_backends(case) and case["name"] not in excluded:
|
||||
print(case["name"])
|
||||
PY
|
||||
fi
|
||||
printf '%s\n' $W2_EXCLUDED > "$OUT/excluded.txt"
|
||||
fi
|
||||
mapfile -t CASES < "$OUT/cases.txt"
|
||||
[ ${#CASES[@]} -gt 0 ] || die "empty case list"
|
||||
[ -f "$OUT/arms.txt" ] || printf 'arms=%s\nrepeat=%s\napk=%s\ntools=%s\n' "$ARMS" "$REPEAT" "$W2_APK" "$W2_TOOLS" > "$OUT/arms.txt"
|
||||
log "gate3 stamp=$STAMP cases=${#CASES[@]} arms=[$ARMS] repeat=$REPEAT apk=$W2_APK tools=$W2_TOOLS"
|
||||
|
||||
arm_args() { # <arm> -> runner arguments
|
||||
case "$1" in
|
||||
monolith) echo "--transport monolith --repeat 1";;
|
||||
inproc) echo "--transport inproc --repeat $REPEAT";;
|
||||
spawn) echo "--transport spawn --repeat $REPEAT";;
|
||||
inproc-ra0) echo "--transport inproc --repeat 1 --env MOBILEGL_IPC_RUN_AHEAD=0";;
|
||||
*) die "unknown arm $1";;
|
||||
esac
|
||||
}
|
||||
|
||||
t_all=$(date +%s)
|
||||
for arm in $ARMS; do
|
||||
mkdir -p "$OUT/state/$arm" "$OUT/logs/$arm" "$OUT/archive/$arm"
|
||||
pending=0
|
||||
for c in "${CASES[@]}"; do [ -f "$OUT/state/$arm/$c.done" ] || pending=$((pending + 1)); done
|
||||
if [ $pending -eq 0 ]; then log "arm $arm: all ${#CASES[@]} done, skipping"; continue; fi
|
||||
log "=== arm $arm start ($pending pending) ==="
|
||||
pin=$(w2_pin_check "$W2_TOOLS" "$OUT/pin-before-$arm.txt"); log "pin before $arm: $pin"
|
||||
t_arm=$(date +%s)
|
||||
for c in "${CASES[@]}"; do
|
||||
[ -f "$OUT/state/$arm/$c.done" ] && continue
|
||||
rm -rf "$OUT/archive/$arm/$c-DirectVulkan"
|
||||
if [ "$c" = "$W2_ITERATIONRP" ]; then
|
||||
# apk.yml:460-462, verbatim; trace-replay-ci.sh reads them from the environment.
|
||||
export MOBILEGL_MAGMA_FIX_ITERATIONRP_SUBGROUP_SCRATCH=1 MOBILEGL_MAGMA_DERIVE_NUM_SUBGROUPS=1 \
|
||||
MOBILEGL_MAGMA_ITERATIONRP_FIX_BARRIER=1
|
||||
else
|
||||
unset MOBILEGL_MAGMA_FIX_ITERATIONRP_SUBGROUP_SCRATCH MOBILEGL_MAGMA_DERIVE_NUM_SUBGROUPS \
|
||||
MOBILEGL_MAGMA_ITERATIONRP_FIX_BARRIER
|
||||
fi
|
||||
attempt=1
|
||||
while :; do
|
||||
w2_require_device
|
||||
w2_wake
|
||||
t0=$(date +%s)
|
||||
# shellcheck disable=SC2046
|
||||
python3 "$RUNNER" --case "$c" --backend DirectVulkan --use-pbuffer $(arm_args "$arm") \
|
||||
--archive-dir "$OUT/archive/$arm" > "$OUT/logs/$arm/$c.attempt$attempt.log" 2>&1
|
||||
rc=$?
|
||||
t1=$(date +%s)
|
||||
# trace-replay-ci.sh's "infrastructure" verdict (adb/system_server gone, not the case):
|
||||
# the CI lane retries once, so does this driver - and says so in the done marker.
|
||||
if [ $attempt -eq 1 ] && grep -q 'requesting one infrastructure retry' "$OUT/logs/$arm/$c.attempt1.log"; then
|
||||
log " $arm $c: infrastructure failure, one retry"
|
||||
attempt=2; rm -rf "$OUT/archive/$arm/$c-DirectVulkan"; sleep 20; continue
|
||||
fi
|
||||
break
|
||||
done
|
||||
cp "$OUT/logs/$arm/$c.attempt$attempt.log" "$OUT/logs/$arm/$c.log"
|
||||
# The runner rewrites <archive>/run.json per invocation; keep each case's copy beside it.
|
||||
[ -f "$OUT/archive/$arm/run.json" ] && mv "$OUT/archive/$arm/run.json" "$OUT/archive/$arm/$c-DirectVulkan/run.json" 2>/dev/null
|
||||
passes=$(grep -c '"passed": true' "$OUT/logs/$arm/$c.log" || true)
|
||||
printf 'rc=%s seconds=%s attempts=%s passed_lines=%s finished=%s\n' "$rc" "$((t1 - t0))" "$attempt" "$passes" "$(date -Is)" \
|
||||
> "$OUT/state/$arm/$c.done"
|
||||
printf '%s\t%s\t%s\t%s\t%s\n' "$arm" "$c" "$rc" "$((t1 - t0))" "$(date -Is)" >> "$OUT/progress.tsv"
|
||||
log " $arm $c rc=$rc $((t1 - t0))s"
|
||||
done
|
||||
pin=$(w2_pin_check "$W2_TOOLS" "$OUT/pin-after-$arm.txt"); log "pin after $arm: $pin"
|
||||
w2_timing "$(w2_out "$STAMP")" "gate3-$arm" "$t_arm" "$(date +%s)" "${#CASES[@]} cases"
|
||||
log "=== arm $arm done in $(( $(date +%s) - t_arm ))s ==="
|
||||
done
|
||||
w2_timing "$(w2_out "$STAMP")" gate3 "$t_all" "$(date +%s)"
|
||||
log "=== GATE3 DONE $STAMP ==="
|
||||
@@ -0,0 +1,125 @@
|
||||
#!/usr/bin/env bash
|
||||
# 40-bsl-stats.sh <stamp> [--arms inproc,spawn] [--interval 0.25]
|
||||
#
|
||||
# The M2 device reading the W6 window did not take (W6-verify/README.md: "峰值与 wbuf[] 仍待开
|
||||
# stats 的专门一遍采集"): minecraft-1.21.4-fabric-iris-bsl-esc-menu-854, DirectVulkan x pbuffer,
|
||||
# one replay per arm with MOBILEGL_PIPE_STATS=1 (PERIOD=1), while an on-device root sampler
|
||||
# records every 0.25 s, for the replay's process(es):
|
||||
# /proc/<pid>/maps line count (the vm.max_map_count question CONTRACT-P7 12 left open)
|
||||
# VmRSS / VmHWM
|
||||
# inproc samples the app process (both roles live there); spawn samples the app (client) and the
|
||||
# libMobileGLServer.so child it launched. The TCP supervisor's own libMobileGLServer.so (argv has
|
||||
# tcp://...) is excluded by name. The wbuf[] gauges are read from the archived role logs.
|
||||
# Output: <out>/bsl/<arm>/{samples.txt,peaks.txt,wbuf.txt} + the archived repeat.
|
||||
set -uo pipefail
|
||||
. "$(dirname "$0")/lib.sh"
|
||||
|
||||
[ $# -ge 1 ] || die "usage: $0 <stamp> [--arms inproc,spawn] [--interval S]"
|
||||
STAMP=$1; shift
|
||||
ARMS="inproc spawn"; INTERVAL=0.25
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--arms) ARMS=${2//,/ }; shift 2;;
|
||||
--interval) INTERVAL=$2; shift 2;;
|
||||
*) die "unknown option $1";;
|
||||
esac
|
||||
done
|
||||
w2_load_build "$STAMP"
|
||||
OUT=$(w2_out "$STAMP")/bsl
|
||||
mkdir -p "$OUT"
|
||||
w2_require_device
|
||||
w2_lock
|
||||
[ "$(Ash "su -c 'id -u'")" = 0 ] || die "no root on $W2_SERIAL: /proc/<pid>/maps of an app process needs it"
|
||||
export MOBILEGL_TRACE_PACKAGE=$W2_PKG MOBILEGL_TRACE_SKIP_INSTALL=1 MOBILEGL_TRACE_APK=$W2_APK
|
||||
unset MOBILEGL_MAGMA_FIX_ITERATIONRP_SUBGROUP_SCRATCH MOBILEGL_MAGMA_DERIVE_NUM_SUBGROUPS MOBILEGL_MAGMA_ITERATIONRP_FIX_BARRIER
|
||||
RUNNER="$W2_TOOLS/tools/trace_replay/run_android_retrace_local.py"
|
||||
DEV_SAMPLER=/data/local/tmp/p7w7-sampler.sh
|
||||
|
||||
cat > "$OUT/sampler.sh" <<'SH'
|
||||
#!/system/bin/sh
|
||||
# p7w7 window-2 sampler: <out> <package> <stopfile> <interval>
|
||||
out=$1; pkg=$2; stop=$3; interval=$4
|
||||
: > "$out"
|
||||
while [ ! -f "$stop" ]; do
|
||||
ts=$(date +%s.%N)
|
||||
for p in $(pidof "$pkg") $(pgrep -f libMobileGLServer); do
|
||||
[ -r /proc/$p/maps ] || continue
|
||||
args=$(tr '\0' ' ' < /proc/$p/cmdline 2>/dev/null)
|
||||
case "$args" in *tcp://*|*p7w7-sampler*) continue;; esac
|
||||
n=$(wc -l < /proc/$p/maps)
|
||||
st=$(grep -E '^(VmRSS|VmHWM):' /proc/$p/status | tr -s ' \t' ' ' | tr '\n' ' ')
|
||||
echo "$ts pid=$p comm=$(cat /proc/$p/comm) maps=$n $st"
|
||||
done >> "$out"
|
||||
sleep "$interval"
|
||||
done
|
||||
SH
|
||||
A push "$OUT/sampler.sh" "$DEV_SAMPLER" >/dev/null || die "push sampler failed"
|
||||
Ash "chmod 755 $DEV_SAMPLER"
|
||||
|
||||
t_all=$(date +%s)
|
||||
for arm in $ARMS; do
|
||||
[ -f "$OUT/$arm/.done" ] && { log "bsl $arm already done"; continue; }
|
||||
rm -rf "$OUT/$arm"; mkdir -p "$OUT/$arm"
|
||||
dev_out=/data/local/tmp/p7w7-samples-$arm.txt; dev_stop=/data/local/tmp/p7w7-sampler.stop
|
||||
Ash "su -c 'rm -f $dev_stop $dev_out'"
|
||||
# The previous replay's app process outlives its Activity; stop it BEFORE the sampler starts,
|
||||
# or its 800 MB and its maps count land in this arm's peaks (seen in the dry run: a 2 s pid
|
||||
# that was gate 3's last case, not this replay).
|
||||
Ash "am force-stop $W2_PKG"
|
||||
sleep 1
|
||||
w2_wake
|
||||
# The sampler runs as root on the device, in the background of one adb shell.
|
||||
adb -s "$W2_SERIAL" shell "su -c 'sh $DEV_SAMPLER $dev_out $W2_PKG $dev_stop $INTERVAL'" > "$OUT/$arm/sampler-adb.log" 2>&1 &
|
||||
sampler=$!
|
||||
sleep 1
|
||||
t0=$(date +%s)
|
||||
python3 "$RUNNER" --case "$W2_BSL" --backend DirectVulkan --use-pbuffer --transport "$arm" --repeat 1 \
|
||||
--archive-dir "$OUT/$arm/archive" --env MOBILEGL_PIPE_STATS=1 --env MOBILEGL_PIPE_STATS_PERIOD=1 \
|
||||
> "$OUT/$arm/replay.log" 2>&1
|
||||
rc=$?
|
||||
t1=$(date +%s)
|
||||
sleep 2
|
||||
Ash "su -c 'touch $dev_stop'"
|
||||
for _ in $(seq 1 20); do kill -0 $sampler 2>/dev/null || break; sleep 1; done
|
||||
kill $sampler 2>/dev/null || true
|
||||
A pull "$dev_out" "$OUT/$arm/samples.txt" >/dev/null 2>&1 || log " WARN: no samples pulled for $arm"
|
||||
Ash "su -c 'rm -f $dev_stop $dev_out'"
|
||||
# peaks per (pid, comm)
|
||||
python3 - "$OUT/$arm/samples.txt" > "$OUT/$arm/peaks.txt" <<'PY'
|
||||
import re, sys
|
||||
peaks = {}
|
||||
try:
|
||||
lines = open(sys.argv[1], encoding="utf-8", errors="replace").read().splitlines()
|
||||
except OSError:
|
||||
lines = []
|
||||
for line in lines:
|
||||
m = re.match(r"(\S+) pid=(\d+) comm=(\S+) maps=(\d+)(.*)", line)
|
||||
if not m:
|
||||
continue
|
||||
key = (m.group(2), m.group(3))
|
||||
rss = re.search(r"VmRSS: (\d+) kB", m.group(5)); hwm = re.search(r"VmHWM: (\d+) kB", m.group(5))
|
||||
p = peaks.setdefault(key, {"samples": 0, "maps": 0, "rss": 0, "hwm": 0, "first": m.group(1), "last": m.group(1)})
|
||||
p["samples"] += 1; p["last"] = m.group(1)
|
||||
p["maps"] = max(p["maps"], int(m.group(4)))
|
||||
if rss: p["rss"] = max(p["rss"], int(rss.group(1)))
|
||||
if hwm: p["hwm"] = max(p["hwm"], int(hwm.group(1)))
|
||||
print("%-8s %-18s %-6s %7s %10s %12s %12s %8s" % ("pid", "comm", "role", "samples", "maps_peak", "VmRSS_peak_kB", "VmHWM_kB", "span_s"))
|
||||
for (pid, comm), p in sorted(peaks.items(), key=lambda kv: -kv[1]["maps"]):
|
||||
# comm is 15 chars: the app reads "ugin.p7w1.trace", the spawned server "libMobileGLServ".
|
||||
role = "server" if comm.startswith("libMobileGL") else "app"
|
||||
print("%-8s %-18s %-6s %7d %10d %12d %12d %8.1f" % (pid, comm, role, p["samples"], p["maps"], p["rss"], p["hwm"],
|
||||
float(p["last"]) - float(p["first"])))
|
||||
if not peaks:
|
||||
print("NO SAMPLES")
|
||||
PY
|
||||
grep -rh 'wbuf\[' "$OUT/$arm/archive" 2>/dev/null | sed 's/^.*MGPipe stats: //' > "$OUT/$arm/wbuf.txt" || true
|
||||
grep -rhoE 'wbuf\[[^]]*\]' "$OUT/$arm/archive" 2>/dev/null | sort | uniq -c > "$OUT/$arm/wbuf-gauges.txt" || true
|
||||
printf 'rc=%s seconds=%s finished=%s\n' "$rc" "$((t1 - t0))" "$(date -Is)" > "$OUT/$arm/.done"
|
||||
log "bsl $arm rc=$rc $((t1 - t0))s"
|
||||
sed 's/^/ /' "$OUT/$arm/peaks.txt"
|
||||
sed 's/^/ /' "$OUT/$arm/wbuf-gauges.txt"
|
||||
w2_timing "$(w2_out "$STAMP")" "bsl-$arm" "$t0" "$t1"
|
||||
done
|
||||
Ash "rm -f $DEV_SAMPLER"
|
||||
w2_timing "$(w2_out "$STAMP")" bsl "$t_all" "$(date +%s)"
|
||||
log "=== BSL STATS DONE $STAMP ==="
|
||||
@@ -0,0 +1,146 @@
|
||||
#!/usr/bin/env bash
|
||||
# 50-cts-after.sh <stamp> [--blocks shader-image,ssbo,dsa,texture,packed-pixels] [--limit N]
|
||||
# [--restore-base-lib]
|
||||
#
|
||||
# CONTRACT-P7 7.3 exit gate 5, AFTER reading: the five KHR-GL46 blocks, inproc x DirectVulkan,
|
||||
# against device-window-1/CTS-base ($BASE = monolith x DirectVulkan, p7w1). Same glcts bundle,
|
||||
# same caselists, same skip file and the same run_cts.py flags as $BASE (CTS-base/README.md,
|
||||
# ~/w7/logs/cts-a64/base/run-base-inner.sh); the ONLY differences are the library and the arm:
|
||||
# MOBILEGL_TRANSPORT=inproc + the split acceptance knobs the retrace split lane uses
|
||||
# (MOBILEGL_IPC_ROLE_SPLIT_STATE=1 MOBILEGL_IPC_STRICT_ERRORS=1 MOBILEGL_IPC_RUN_AHEAD=1).
|
||||
# The library is this build's APK arm64 libMobileGL.so, pushed to /data/local/tmp/mgcts exactly as
|
||||
# ~/w7/logs/cts-a64/deploy/deploy.sh pushed the $BASE one, and verified by sha256 on the device.
|
||||
#
|
||||
# Arm proof before any block: mgprobe (the SKILL step-5 preflight) and one glcts case, each under
|
||||
# the AFTER environment, must log ConfigLoader's "Config: MOBILEGL_TRANSPORT=inproc - the MGPipe
|
||||
# record stream" and a "Config: IPC" line with strict=1 role-split-state=1 run-ahead=1.
|
||||
# RESUMABLE per block (<out>/cts/runs/<block>/.done). --limit N runs the first N cases of each
|
||||
# block (the dry run). --restore-base-lib re-pushes the $BASE library afterwards (dry run only).
|
||||
set -uo pipefail
|
||||
. "$(dirname "$0")/lib.sh"
|
||||
|
||||
[ $# -ge 1 ] || die "usage: $0 <stamp> [--blocks list] [--limit N] [--restore-base-lib]"
|
||||
STAMP=$1; shift
|
||||
BLOCKS="shader-image ssbo dsa texture packed-pixels"; LIMIT=0; RESTORE_BASE=0
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--blocks) BLOCKS=${2//,/ }; shift 2;;
|
||||
--limit) LIMIT=$2; shift 2;;
|
||||
--restore-base-lib) RESTORE_BASE=1; shift;;
|
||||
*) die "unknown option $1";;
|
||||
esac
|
||||
done
|
||||
w2_load_build "$STAMP"
|
||||
OUT=$(w2_out "$STAMP")/cts
|
||||
mkdir -p "$OUT/deploy" "$OUT/runs" "$OUT/caselists"
|
||||
w2_require_device
|
||||
w2_lock
|
||||
CTS_ENV=(MOBILEGL_CTS_FBO_COLOR_TEXTURE=1 MOBILEGL_TRANSPORT=inproc $W2_SPLIT_KNOBS)
|
||||
ENV_ARGS=(); for kv in "${CTS_ENV[@]}"; do ENV_ARGS+=(--env "$kv"); done
|
||||
DEV_ENV="MOBILEGL_BACKEND_TYPE=DirectVulkan ${CTS_ENV[*]}"
|
||||
t_all=$(date +%s)
|
||||
|
||||
# ---- deploy ---------------------------------------------------------------------------------
|
||||
for f in glcts mgprobe; do
|
||||
[ "$(Ash "test -x $W2_CTS_DEV/$f && echo ok")" = ok ] || die "$W2_CTS_DEV/$f missing: deploy the bundle first ($W2_CTS_BUNDLE/deploy.sh $W2_SERIAL)"
|
||||
done
|
||||
[ "$(Ash "test -d $W2_CTS_DEV/gl_cts && echo ok")" = ok ] || die "$W2_CTS_DEV/gl_cts missing"
|
||||
unzip -o -q -j "$W2_APK" lib/arm64-v8a/libMobileGL.so -d "$OUT/deploy" || die "no arm64 libMobileGL.so in $W2_APK"
|
||||
WANT=$(sha256sum "$OUT/deploy/libMobileGL.so" | cut -d' ' -f1)
|
||||
BEFORE=$(Ash "sha256sum $W2_CTS_DEV/libMobileGL.so" | cut -d' ' -f1)
|
||||
{
|
||||
echo "apk : $W2_APK"
|
||||
echo "apk sha256 : $(sha256sum "$W2_APK" | cut -d' ' -f1)"
|
||||
echo "lib sha256 : $WANT"
|
||||
echo "lib stamp hits : $(strings "$OUT/deploy/libMobileGL.so" | grep -c -F "${BUILD_STAMP:-$STAMP}" || true) (${BUILD_STAMP:-$STAMP})"
|
||||
echo "device before : $BEFORE"
|
||||
echo "glcts sha256 : $(Ash "sha256sum $W2_CTS_DEV/glcts" | cut -d' ' -f1)"
|
||||
echo "env : $DEV_ENV"
|
||||
} > "$OUT/deploy/IDENTITY.txt"
|
||||
if [ "$BEFORE" != "$WANT" ]; then
|
||||
A push "$OUT/deploy/libMobileGL.so" "$W2_CTS_DEV/libMobileGL.so" > "$OUT/deploy/push.log" 2>&1 || die "push failed"
|
||||
fi
|
||||
GOT=$(Ash "sha256sum $W2_CTS_DEV/libMobileGL.so" | cut -d' ' -f1)
|
||||
echo "device after : $GOT" >> "$OUT/deploy/IDENTITY.txt"
|
||||
[ "$GOT" = "$WANT" ] || die "the device does not carry the AFTER library ($GOT != $WANT)"
|
||||
log "deployed AFTER lib $WANT to $W2_CTS_DEV"
|
||||
|
||||
# ---- preflight + arm proof ---------------------------------------------------------------------
|
||||
arm_proof() { # <label> <logcat file> -> 0 when inproc really resolved with the gate's knobs
|
||||
local f=$2 ok=1 marker ipc good fatal
|
||||
marker=$(grep -c 'Config: MOBILEGL_TRANSPORT=inproc - the MGPipe record stream' "$f")
|
||||
ipc=$(grep -oE 'Config: IPC.*' "$f")
|
||||
good=$(printf '%s\n' "$ipc" | grep -E '\bstrict=1\b' | grep -E '\brole-split-state=1\b' | grep -cE '\brun-ahead=1\b')
|
||||
fatal=$(grep -c 'Fatal{' "$f")
|
||||
[ "$marker" -ge 1 ] && [ "$good" -ge 1 ] && [ "$fatal" -eq 0 ] || ok=0
|
||||
echo "$1: transport-marker=$marker ipc-lines=[$(printf '%s\n' "$ipc" | head -1)] fatal=$fatal -> $([ $ok = 1 ] && echo PROVEN || echo NOT-PROVEN)"
|
||||
[ $ok = 1 ]
|
||||
}
|
||||
if [ ! -f "$OUT/preflight.done" ]; then
|
||||
w2_wake
|
||||
A logcat -c
|
||||
Ash "cd $W2_CTS_DEV && LD_LIBRARY_PATH=. $DEV_ENV ./mgprobe --backend DirectVulkan --surface imagereader --lib ./libMobileGL.so" > "$OUT/preflight.txt" 2>&1
|
||||
A logcat -d > "$OUT/preflight-logcat.txt" 2>&1
|
||||
grep -q '^PASS' "$OUT/preflight.txt" || { cat "$OUT/preflight.txt"; die "mgprobe preflight did not PASS under the AFTER environment"; }
|
||||
arm_proof mgprobe "$OUT/preflight-logcat.txt" | tee "$OUT/arm-proof.txt" || die "mgprobe did not prove the inproc arm (see $OUT/preflight-logcat.txt)"
|
||||
first=$(grep -v '^#' "$W2_TOOLS/tools/cts/caselists/p7-dsa-gl46.txt" | sed '/^$/d' | head -1)
|
||||
A logcat -c
|
||||
Ash "cd $W2_CTS_DEV && echo $first > p7w7-proof.txt && $DEV_ENV LD_LIBRARY_PATH=. ./glcts --deqp-caselist-file=p7w7-proof.txt --deqp-surface-type=fbo --deqp-surface-width=256 --deqp-surface-height=256 --deqp-gl-config-name=rgba8888d24s8 --deqp-terminate-on-device-lost=disable --deqp-log-images=disable --deqp-log-shader-sources=disable --deqp-log-filename=p7w7-proof.qpa > /dev/null 2>&1; echo RC=\$?; grep -o 'StatusCode=\"[A-Za-z]*\"' p7w7-proof.qpa; rm -f p7w7-proof.txt p7w7-proof.qpa" > "$OUT/proof-glcts.txt" 2>&1
|
||||
A logcat -d > "$OUT/proof-glcts-logcat.txt" 2>&1
|
||||
arm_proof "glcts $first" "$OUT/proof-glcts-logcat.txt" | tee -a "$OUT/arm-proof.txt" || die "glcts did not prove the inproc arm (see $OUT/proof-glcts-logcat.txt)"
|
||||
touch "$OUT/preflight.done"
|
||||
fi
|
||||
|
||||
# ---- blocks -------------------------------------------------------------------------------------
|
||||
for b in $BLOCKS; do
|
||||
run="$OUT/runs/$b"
|
||||
[ -f "$run/.done" ] && { log "block $b already done"; continue; }
|
||||
rm -rf "$run"; mkdir -p "$run"
|
||||
caselist="$W2_TOOLS/tools/cts/caselists/p7-$b-gl46.txt"
|
||||
[ -f "$caselist" ] || die "no caselist $caselist"
|
||||
if [ "$LIMIT" -gt 0 ]; then
|
||||
grep -v '^#' "$caselist" | sed '/^$/d' | head -n "$LIMIT" > "$OUT/caselists/p7-$b-gl46.first$LIMIT.txt"
|
||||
caselist="$OUT/caselists/p7-$b-gl46.first$LIMIT.txt"
|
||||
fi
|
||||
echo "$caselist" > "$run/caselist.path"
|
||||
pin=$(w2_pin_check "$W2_TOOLS" "$OUT/pin-before-$b.txt")
|
||||
w2_wake
|
||||
log "block $b start ($(grep -vc '^#' "$caselist") cases, pin $pin)"
|
||||
t0=$(date +%s)
|
||||
python3 "$W2_TOOLS/tools/cts/scripts/run_cts.py" --serial "$W2_SERIAL" --backend DirectVulkan \
|
||||
--caselist "$caselist" --outdir "$run" "${ENV_ARGS[@]}" \
|
||||
--surface fbo --gl-config-name rgba8888d24s8 --cpu-mask fast \
|
||||
--chunk-timeout 900 --skip-file "$W2_TOOLS/tools/cts/caselists/p7-skip.txt" > "$OUT/run-$b.log" 2>&1
|
||||
rc=$?
|
||||
t1=$(date +%s)
|
||||
python3 "$W2_TOOLS/tools/cts/scripts/qpa_report.py" "$run" --label "DirectVulkan-inproc-$b" \
|
||||
--json "$OUT/report-$b.json" > "$OUT/report-$b.txt" 2>&1
|
||||
pin=$(w2_pin_check "$W2_TOOLS" "$OUT/pin-after-$b.txt")
|
||||
for f in unrun hung crashed; do [ -s "$run/$f.txt" ] && log " [$b] $f.txt: $(wc -l < "$run/$f.txt") lines"; done
|
||||
grep -E 'Pass|Fail|NotSupported|Crash|rate' "$OUT/report-$b.txt" | head -8 | sed "s/^/ [$b] /"
|
||||
printf 'rc=%s seconds=%s pin_after=%s finished=%s\n' "$rc" "$((t1 - t0))" "$pin" "$(date -Is)" > "$run/.done"
|
||||
w2_timing "$(w2_out "$STAMP")" "cts-$b" "$t0" "$t1" "limit=$LIMIT"
|
||||
log "block $b rc=$rc $((t1 - t0))s"
|
||||
done
|
||||
|
||||
# The same machine-readable shape as $BASE (tools/cts/baselines/base-DirectVulkan-monolith-p7w1-
|
||||
# 9be62cbc.json, cts_multi_report.py over the $BASE runs): one suite per finished block.
|
||||
suites=()
|
||||
for b in $BLOCKS; do
|
||||
[ -f "$OUT/runs/$b/.done" ] && suites+=(--suite DirectVulkan "$b" "$(cat "$OUT/runs/$b/caselist.path")" "$OUT/runs/$b")
|
||||
done
|
||||
if [ ${#suites[@]} -gt 0 ]; then
|
||||
python3 "$W2_TOOLS/tools/cts/scripts/cts_multi_report.py" "${suites[@]}" --adopt-legacy --allow-incomplete \
|
||||
--markdown "$OUT/after-DirectVulkan-inproc-$STAMP.md" --json "$OUT/after-DirectVulkan-inproc-$STAMP.json" \
|
||||
> "$OUT/multi-report.log" 2>&1 || log "WARN: cts_multi_report failed (see $OUT/multi-report.log)"
|
||||
fi
|
||||
|
||||
if [ $RESTORE_BASE -eq 1 ]; then
|
||||
BASE_LIB="$W2_CTS_BUNDLE/libMobileGL.so"
|
||||
BASE_SHA=$(awk '/^libMobileGL.so *sha256:/ {print $3}' "$W2_CTS_BUNDLE/IDENTITY.txt")
|
||||
A push "$BASE_LIB" "$W2_CTS_DEV/libMobileGL.so" >/dev/null 2>&1
|
||||
GOT=$(Ash "sha256sum $W2_CTS_DEV/libMobileGL.so" | cut -d' ' -f1)
|
||||
[ "$GOT" = "$BASE_SHA" ] && log "restored the \$BASE library ($BASE_SHA)" || log "WARN: restore mismatch $GOT != $BASE_SHA"
|
||||
fi
|
||||
w2_timing "$(w2_out "$STAMP")" cts "$t_all" "$(date +%s)" "blocks=[$BLOCKS] limit=$LIMIT"
|
||||
log "=== CTS AFTER DONE $STAMP ==="
|
||||
@@ -0,0 +1,383 @@
|
||||
#!/usr/bin/env python3
|
||||
"""60-reduce.py <stamp> [--logroot DIR] [--tools TREE] [--json OUT]
|
||||
|
||||
Device window 2 verdicts, read from the window's own output directory (<logroot>/<stamp>):
|
||||
|
||||
GATE 3 (CONTRACT-P7 7.2), per case of gate3/cases.txt:
|
||||
* monolith x1 is the same-session control; it must itself pass;
|
||||
* inproc and spawn: every expected repeat present and error-free, each repeat's arm proof
|
||||
(transport-proof.json passed), the device's own pass verdict (ssim >= case threshold),
|
||||
ALL repeats bit-identical (actual PNG SHA-256), and |ssim - monolith ssim| <= 0.0005 on every
|
||||
repeat; a repeat whose logcat is byte-identical to the previous repeat's is flagged STALE;
|
||||
* OpenRA: 1.000000 and mismatch 0 on every repeat of both split arms AND on monolith;
|
||||
* inproc-ra0 (RUN_AHEAD=0): recorded (ssim, sha, run-ahead=0 proof), never gating.
|
||||
BSL STATS: per arm, maps-line / VmRSS / VmHWM peaks and the wbuf[] gauges.
|
||||
CTS AFTER (CONTRACT-P7 7.3), per block vs device-window-1/CTS-base/report-<block>.json, over the
|
||||
cases the AFTER run was asked to run (so a --limit subset is compared like for like):
|
||||
rate = Pass / (results - NotSupported) [every non-NS outcome - Fail, Crash, warnings - is in the
|
||||
denominator; NS excluded], delta in percentage points, PASS iff delta >= -0.5 pp, no new crash
|
||||
(Crash/Timeout/InternalError/ResourceError/DeviceHang/Incomplete not already so in BASE) and the
|
||||
block is complete (unrun.txt empty).
|
||||
Exit status: 0 when every section that has data is PASS, 1 otherwise, 2 on bad input.
|
||||
"""
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
TOL = 0.0005
|
||||
CTS_TOL_PP = 0.5
|
||||
HARD = {"Crash", "Timeout", "InternalError", "ResourceError", "DeviceHang", "Incomplete"}
|
||||
SPLIT_ARMS = ("inproc", "spawn")
|
||||
OPENRA = "OpenRA"
|
||||
|
||||
|
||||
def sha(path):
|
||||
h = hashlib.sha256()
|
||||
with open(path, "rb") as f:
|
||||
for block in iter(lambda: f.read(1 << 20), b""):
|
||||
h.update(block)
|
||||
return h.hexdigest()
|
||||
|
||||
|
||||
def read_kv(path):
|
||||
out = {}
|
||||
if path.is_file():
|
||||
for line in path.read_text(encoding="utf-8", errors="replace").splitlines():
|
||||
if "=" in line:
|
||||
k, v = line.split("=", 1)
|
||||
out[k.strip()] = v.strip()
|
||||
return out
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------------------------
|
||||
# gate 3
|
||||
# ------------------------------------------------------------------------------------------------
|
||||
def gate3(out, ca):
|
||||
g = out / "gate3"
|
||||
cases_file = g / "cases.txt"
|
||||
if not cases_file.is_file():
|
||||
return None
|
||||
cases = [c for c in cases_file.read_text().split() if c]
|
||||
excluded = (g / "excluded.txt").read_text().split() if (g / "excluded.txt").is_file() else []
|
||||
meta = read_kv(g / "arms.txt")
|
||||
repeat = int(meta.get("repeat", "3"))
|
||||
arms_present = [a for a in ("monolith", "inproc", "spawn", "inproc-ra0") if (g / "archive" / a).is_dir()]
|
||||
summaries = {a: ca.summarize(g / "archive" / a) for a in arms_present}
|
||||
|
||||
def rows(arm, case):
|
||||
s = summaries.get(arm)
|
||||
if not s:
|
||||
return []
|
||||
return [r for r in s["rows"] if r["arm"] == case + "-DirectVulkan"]
|
||||
|
||||
def proof(row):
|
||||
p = Path(row["dir"]) / "transport-proof.json"
|
||||
try:
|
||||
return json.loads(p.read_text(encoding="utf-8"))
|
||||
except (OSError, ValueError):
|
||||
return None
|
||||
|
||||
def logcat_sha(row):
|
||||
p = Path(row["dir"]) / "logcat.txt"
|
||||
return sha(p) if p.is_file() else None
|
||||
|
||||
def ra0_proof(row):
|
||||
p = Path(row["dir"]) / "mobilegl.log"
|
||||
if not p.is_file():
|
||||
return "no-log"
|
||||
lines = re.findall(r"Config: IPC[^\r\n]*", p.read_text(encoding="utf-8", errors="replace"))
|
||||
if lines and all(re.search(r"\brun-ahead=0\b", line) for line in lines):
|
||||
return "run-ahead=0"
|
||||
return "NOT-PROVEN(" + ";".join(lines)[:120] + ")"
|
||||
|
||||
results = []
|
||||
for case in cases:
|
||||
reasons, incomplete = [], []
|
||||
entry = {"case": case, "arms": {}}
|
||||
mono = rows("monolith", case)
|
||||
mono_ssim = None
|
||||
if len(mono) != 1 or mono[0].get("error"):
|
||||
incomplete.append("monolith: %s" % (mono[0].get("error") if mono else "not run"))
|
||||
else:
|
||||
m = mono[0]
|
||||
mono_ssim = m.get("ssim_vs_golden")
|
||||
entry["arms"]["monolith"] = {"ssim": mono_ssim, "sha": m.get("actual_sha256"),
|
||||
"mismatch": m.get("mismatch_pixels_vs_golden"), "passed": m.get("passed")}
|
||||
if m.get("passed") is not True:
|
||||
reasons.append("monolith control did not pass (ssim %s)" % mono_ssim)
|
||||
if case == OPENRA and not (m.get("mismatch_pixels_vs_golden") == 0 and (mono_ssim or 0) >= 0.9999995):
|
||||
reasons.append("OpenRA monolith not 1.000000/0 (%s/%s)" % (mono_ssim, m.get("mismatch_pixels_vs_golden")))
|
||||
for arm in SPLIT_ARMS:
|
||||
rs = rows(arm, case)
|
||||
a = {"repeats": len(rs), "ssim": [r.get("ssim_vs_golden") for r in rs],
|
||||
"sha": sorted({r.get("actual_sha256") for r in rs if r.get("actual_sha256")})}
|
||||
entry["arms"][arm] = a
|
||||
if arm not in summaries:
|
||||
incomplete.append(arm + ": not run")
|
||||
continue
|
||||
if len(rs) != repeat:
|
||||
incomplete.append("%s: %d/%d repeats" % (arm, len(rs), repeat))
|
||||
for r in rs:
|
||||
if r.get("error"):
|
||||
incomplete.append("%s rep%d: %s" % (arm, r["repeat"], r["error"]))
|
||||
continue
|
||||
if r.get("passed") is not True:
|
||||
reasons.append("%s rep%d below threshold (ssim %s)" % (arm, r["repeat"], r.get("ssim_vs_golden")))
|
||||
p = proof(r)
|
||||
if not p or p.get("passed") is not True:
|
||||
reasons.append("%s rep%d arm proof not passed" % (arm, r["repeat"]))
|
||||
if mono_ssim is not None and r.get("ssim_vs_golden") is not None:
|
||||
d = abs(r["ssim_vs_golden"] - mono_ssim)
|
||||
if d > TOL:
|
||||
reasons.append("%s rep%d |ssim-monolith|=%.6f > %.4f" % (arm, r["repeat"], d, TOL))
|
||||
if case == OPENRA and not (r.get("mismatch_pixels_vs_golden") == 0 and (r.get("ssim_vs_golden") or 0) >= 0.9999995):
|
||||
reasons.append("OpenRA %s rep%d not 1.000000/0 (%s/%s)" % (arm, r["repeat"], r.get("ssim_vs_golden"), r.get("mismatch_pixels_vs_golden")))
|
||||
shas = [r.get("actual_sha256") for r in rs if r.get("actual_sha256")]
|
||||
if len(set(shas)) > 1:
|
||||
reasons.append("%s repeats NOT bit-identical (%d distinct pictures)" % (arm, len(set(shas))))
|
||||
lc = [logcat_sha(r) for r in rs]
|
||||
for i in range(1, len(lc)):
|
||||
if lc[i] and lc[i] == lc[i - 1]:
|
||||
reasons.append("%s rep%d STALE (logcat identical to rep%d)" % (arm, rs[i]["repeat"], rs[i - 1]["repeat"]))
|
||||
ra0 = rows("inproc-ra0", case)
|
||||
if ra0:
|
||||
r = ra0[0]
|
||||
entry["arms"]["inproc-ra0"] = {"ssim": r.get("ssim_vs_golden"), "sha": r.get("actual_sha256"),
|
||||
"passed": r.get("passed"), "proof": ra0_proof(r), "error": r.get("error")}
|
||||
ip = set(entry["arms"].get("inproc", {}).get("sha", []))
|
||||
sp = set(entry["arms"].get("spawn", {}).get("sha", []))
|
||||
entry["inproc_eq_spawn"] = bool(ip) and ip == sp
|
||||
entry["split_eq_monolith"] = bool(ip) and ip == sp == {entry["arms"].get("monolith", {}).get("sha")}
|
||||
entry["verdict"] = "INCOMPLETE" if incomplete else ("FAIL" if reasons else "PASS")
|
||||
entry["reasons"] = incomplete + reasons
|
||||
results.append(entry)
|
||||
verdicts = [e["verdict"] for e in results]
|
||||
overall = "PASS" if verdicts and all(v == "PASS" for v in verdicts) else (
|
||||
"INCOMPLETE" if "INCOMPLETE" in verdicts and "FAIL" not in verdicts else "FAIL")
|
||||
return {"cases": results, "excluded": excluded, "repeat": repeat, "denominator": len(cases),
|
||||
"overall": overall, "arms_present": arms_present}
|
||||
|
||||
|
||||
def print_gate3(g3):
|
||||
print("== GATE 3 (DirectVulkan x pbuffer; split repeat=%d; tol |ssim-monolith| <= %.4f) ==" % (g3["repeat"], TOL))
|
||||
w = max([len(e["case"]) for e in g3["cases"]] + [4])
|
||||
print("%-*s %-10s %-11s %-24s %-24s %-11s %s" % (w, "case", "verdict", "monolith", "inproc(min..max) #sha", "spawn(min..max) #sha", "ra0", "i==s==m"))
|
||||
for e in g3["cases"]:
|
||||
def cell(arm):
|
||||
a = e["arms"].get(arm)
|
||||
if not a or not a.get("ssim"):
|
||||
return "-"
|
||||
vals = [v for v in a["ssim"] if isinstance(v, (int, float))]
|
||||
if not vals:
|
||||
return "err"
|
||||
return "%.6f..%.6f #%d" % (min(vals), max(vals), len(a["sha"]))
|
||||
mono = e["arms"].get("monolith", {}).get("ssim")
|
||||
ra0 = e["arms"].get("inproc-ra0", {}).get("ssim")
|
||||
print("%-*s %-10s %-11s %-24s %-24s %-11s %s" % (
|
||||
w, e["case"], e["verdict"], "%.6f" % mono if isinstance(mono, (int, float)) else "-",
|
||||
cell("inproc"), cell("spawn"), "%.6f" % ra0 if isinstance(ra0, (int, float)) else "-",
|
||||
"yes" if e["split_eq_monolith"] else ("i==s" if e["inproc_eq_spawn"] else "no")))
|
||||
for reason in e["reasons"]:
|
||||
print("%-*s ! %s" % (w, "", reason))
|
||||
ra0s = [(e["case"], e["arms"]["inproc-ra0"]) for e in g3["cases"] if "inproc-ra0" in e["arms"]]
|
||||
if ra0s:
|
||||
print("-- RUN_AHEAD=0 control (recorded, not gating): %d case(s); proofs: %s" % (
|
||||
len(ra0s), ", ".join(sorted({r["proof"] for _, r in ra0s}))))
|
||||
print("-- excluded (red on monolith, CONTRACT-P7 7.1): " + (", ".join(g3["excluded"]) or "none"))
|
||||
n = len(g3["cases"])
|
||||
npass = sum(e["verdict"] == "PASS" for e in g3["cases"])
|
||||
note = "" if n == 36 else " (denominator is %d, not the gate's 36: a subset run is NOT a gate verdict)" % n
|
||||
print("GATE3 %s: %d/%d cases PASS%s" % (g3["overall"], npass, n, note))
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------------------------
|
||||
# bsl stats
|
||||
# ------------------------------------------------------------------------------------------------
|
||||
def bsl(out, ca):
|
||||
b = out / "bsl"
|
||||
if not b.is_dir():
|
||||
return None
|
||||
arms = {}
|
||||
for arm_dir in sorted(p for p in b.iterdir() if p.is_dir()):
|
||||
a = {"done": read_kv(arm_dir / ".done")}
|
||||
a["peaks"] = (arm_dir / "peaks.txt").read_text() if (arm_dir / "peaks.txt").is_file() else ""
|
||||
a["wbuf"] = (arm_dir / "wbuf-gauges.txt").read_text() if (arm_dir / "wbuf-gauges.txt").is_file() else ""
|
||||
if (arm_dir / "archive").is_dir():
|
||||
s = ca.summarize(arm_dir / "archive")
|
||||
a["replay"] = [{k: r.get(k) for k in ("passed", "ssim_vs_golden", "actual_sha256", "error")} for r in s["rows"]]
|
||||
arms[arm_dir.name] = a
|
||||
return arms
|
||||
|
||||
|
||||
def print_bsl(arms):
|
||||
print("== BSL-ESC-MENU MOBILEGL_PIPE_STATS (maps lines / RSS peaks, wbuf[] gauges) ==")
|
||||
for arm, a in arms.items():
|
||||
print("[%s] %s" % (arm, " ".join("%s=%s" % kv for kv in a["done"].items())))
|
||||
for r in a.get("replay", []):
|
||||
print(" replay: passed=%s ssim=%s sha=%s %s" % (r["passed"], r["ssim_vs_golden"],
|
||||
(r["actual_sha256"] or "-")[:16], r.get("error") or ""))
|
||||
for line in a["peaks"].splitlines():
|
||||
print(" " + line)
|
||||
for line in a["wbuf"].splitlines() or ["(no wbuf[] line in the archived logs)"]:
|
||||
print(" " + line.strip())
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------------------------
|
||||
# CTS AFTER vs BASE
|
||||
# ------------------------------------------------------------------------------------------------
|
||||
def read_list(path):
|
||||
if not path.is_file():
|
||||
return []
|
||||
return [l.strip() for l in path.read_text(encoding="utf-8").splitlines() if l.strip() and not l.startswith("#")]
|
||||
|
||||
|
||||
def rate(statuses):
|
||||
p = sum(1 for s in statuses if s == "Pass")
|
||||
ns = sum(1 for s in statuses if s == "NotSupported")
|
||||
f = sum(1 for s in statuses if s == "Fail")
|
||||
d = len(statuses) - ns
|
||||
return {"pass": p, "ns": ns, "fail": f, "other": d - p - f, "denominator": d,
|
||||
"rate": (p / d) if d else None, "literal_p_over_p_plus_f": (p / (p + f)) if (p + f) else None}
|
||||
|
||||
|
||||
def cts(out, base_dir):
|
||||
c = out / "cts"
|
||||
if not c.is_dir():
|
||||
return None
|
||||
blocks = []
|
||||
for report in sorted(c.glob("report-*.json")):
|
||||
b = report.stem[len("report-"):]
|
||||
run = c / "runs" / b
|
||||
after = json.loads(report.read_text(encoding="utf-8"))["results"]
|
||||
base_path = base_dir / ("report-%s.json" % b)
|
||||
if not base_path.is_file():
|
||||
blocks.append({"block": b, "verdict": "NO-BASE", "reasons": ["no " + str(base_path)]})
|
||||
continue
|
||||
base = json.loads(base_path.read_text(encoding="utf-8"))["results"]
|
||||
caselist = Path((run / "caselist.path").read_text().strip()) if (run / "caselist.path").is_file() else None
|
||||
universe = read_list(caselist) if caselist else sorted(after)
|
||||
skipped = set(read_list(run / "skipped.txt"))
|
||||
universe = [x for x in universe if x not in skipped]
|
||||
unrun = read_list(run / "unrun.txt")
|
||||
hung = read_list(run / "hung.txt")
|
||||
a_st = [after[x] for x in universe if x in after]
|
||||
b_st = [base[x] for x in universe if x in base]
|
||||
ra, rb = rate(a_st), rate(b_st)
|
||||
delta = None if ra["rate"] is None or rb["rate"] is None else (ra["rate"] - rb["rate"]) * 100.0
|
||||
new_crash = sorted(x for x in universe if after.get(x) in HARD and base.get(x) not in HARD)
|
||||
new_crash += sorted(x for x in hung if x not in new_crash)
|
||||
regress = sorted(x for x in universe if base.get(x) == "Pass" and after.get(x) not in (None, "Pass"))
|
||||
fixed = sorted(x for x in universe if base.get(x) not in (None, "Pass") and after.get(x) == "Pass")
|
||||
missing_base = sorted(x for x in universe if x not in base)
|
||||
reasons = []
|
||||
verdict = "PASS"
|
||||
if unrun or len(a_st) < len(universe):
|
||||
verdict = "INCOMPLETE"
|
||||
reasons.append("%d case(s) without an AFTER result (unrun.txt %d)" % (len(universe) - len(a_st), len(unrun)))
|
||||
if new_crash:
|
||||
verdict = "FAIL"
|
||||
reasons.append("%d NEW crash(es)" % len(new_crash))
|
||||
if delta is not None and delta < -CTS_TOL_PP:
|
||||
verdict = "FAIL"
|
||||
reasons.append("delta %.3f pp < -%.1f pp" % (delta, CTS_TOL_PP))
|
||||
if delta is not None and delta > CTS_TOL_PP:
|
||||
reasons.append("note: AFTER is %.3f pp ABOVE BASE (not a regression; review the fixed list)" % delta)
|
||||
blocks.append({"block": b, "cases": len(universe), "after": ra, "base": rb, "delta_pp": delta,
|
||||
"new_crash": new_crash, "regressed": regress, "fixed": fixed, "missing_in_base": missing_base,
|
||||
"unrun": len(unrun), "hung": hung, "verdict": verdict, "reasons": reasons,
|
||||
"subset": bool(caselist and "first" in caselist.name)})
|
||||
verdicts = [b["verdict"] for b in blocks]
|
||||
overall = "PASS" if blocks and all(v == "PASS" for v in verdicts) else ("FAIL" if "FAIL" in verdicts else "INCOMPLETE")
|
||||
return {"blocks": blocks, "overall": overall}
|
||||
|
||||
|
||||
def print_cts(c):
|
||||
print("== CTS AFTER (inproc x DirectVulkan) vs BASE (monolith x DirectVulkan, p7w1) ==")
|
||||
print("rate = Pass/(results-NotSupported); gate: delta >= -%.1f pp and 0 new crash per block" % CTS_TOL_PP)
|
||||
print("%-14s %6s %-26s %-26s %9s %5s %5s %5s %s" % ("block", "cases", "BASE P/NS/F/X rate", "AFTER P/NS/F/X rate", "delta pp", "crash", "regr", "fixed", "verdict"))
|
||||
for b in c["blocks"]:
|
||||
if "after" not in b:
|
||||
print("%-14s %s %s" % (b["block"], b["verdict"], "; ".join(b["reasons"])))
|
||||
continue
|
||||
def cell(r):
|
||||
return "%d/%d/%d/%d %s" % (r["pass"], r["ns"], r["fail"], r["other"],
|
||||
"%.3f%%" % (100 * r["rate"]) if r["rate"] is not None else "n/a")
|
||||
print("%-14s %6d %-26s %-26s %9s %5d %5d %5d %s%s" % (
|
||||
b["block"], b["cases"], cell(b["base"]), cell(b["after"]),
|
||||
"%+.3f" % b["delta_pp"] if b["delta_pp"] is not None else "n/a",
|
||||
len(b["new_crash"]), len(b["regressed"]), len(b["fixed"]), b["verdict"],
|
||||
" (SUBSET)" if b["subset"] else ""))
|
||||
for reason in b["reasons"]:
|
||||
print(" ! " + reason)
|
||||
for x in b["new_crash"]:
|
||||
print(" NEW CRASH " + x)
|
||||
for x in b["regressed"][:40]:
|
||||
print(" Pass->not " + x)
|
||||
if len(b["regressed"]) > 40:
|
||||
print(" ... %d more regressions in the JSON" % (len(b["regressed"]) - 40))
|
||||
for x in b["fixed"][:20]:
|
||||
print(" not->Pass " + x)
|
||||
print("CTS %s" % c["overall"] + (" (SUBSET run: not a gate verdict)" if any(b.get("subset") for b in c["blocks"]) else ""))
|
||||
|
||||
|
||||
def print_timing(out):
|
||||
t = out / "timing.tsv"
|
||||
if not t.is_file():
|
||||
return
|
||||
print("== TIMING ==")
|
||||
for line in t.read_text().splitlines():
|
||||
step, start, end, secs, note = (line.split("\t") + [""] * 5)[:5]
|
||||
print(" %-18s %6ss %s -> %s %s" % (step, secs, start, end, note))
|
||||
prog = out / "gate3" / "progress.tsv"
|
||||
if prog.is_file():
|
||||
per = {}
|
||||
for line in prog.read_text().splitlines():
|
||||
arm, case, rc, secs, _ = (line.split("\t") + [""] * 5)[:5]
|
||||
per.setdefault(arm, []).append(int(secs))
|
||||
for arm, v in per.items():
|
||||
print(" gate3 %-11s %2d case invocations, mean %.0fs, total %ds" % (arm, len(v), sum(v) / len(v), sum(v)))
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||
ap.add_argument("stamp")
|
||||
ap.add_argument("--logroot", default=os.environ.get("W2_LOGROOT", str(Path.home() / "w7/logs/p7w7")))
|
||||
ap.add_argument("--tools", help="MobileGL tree holding compare_actuals.py and CTS-base (default: build.env)")
|
||||
ap.add_argument("--json", help="write every section as JSON here (default <out>/verdict.json)")
|
||||
args = ap.parse_args()
|
||||
out = Path(args.logroot) / args.stamp
|
||||
if not out.is_dir():
|
||||
print("no such window output: %s" % out, file=sys.stderr)
|
||||
return 2
|
||||
tools = args.tools or os.environ.get("W2_TOOLS_OVERRIDE") or read_kv(out / "build.env").get("BUILD_TREE")
|
||||
if not tools:
|
||||
print("no tools tree (--tools)", file=sys.stderr)
|
||||
return 2
|
||||
sys.path.insert(0, str(Path(tools) / "tools" / "trace_replay"))
|
||||
import compare_actuals as ca
|
||||
base_dir = Path(tools) / "docs/Disaggregated/notes/p7/device-window-1/CTS-base"
|
||||
report = {"stamp": args.stamp, "out": str(out)}
|
||||
ok = True
|
||||
g3 = gate3(out, ca)
|
||||
if g3:
|
||||
print_gate3(g3); print()
|
||||
report["gate3"] = g3; ok &= g3["overall"] == "PASS"
|
||||
b = bsl(out, ca)
|
||||
if b:
|
||||
print_bsl(b); print()
|
||||
report["bsl"] = b
|
||||
c = cts(out, base_dir)
|
||||
if c:
|
||||
print_cts(c); print()
|
||||
report["cts"] = c; ok &= c["overall"] == "PASS"
|
||||
print_timing(out)
|
||||
Path(args.json or out / "verdict.json").write_text(json.dumps(report, indent=1) + "\n", encoding="utf-8")
|
||||
return 0 if ok else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env bash
|
||||
# 90-restore.sh <stamp>
|
||||
#
|
||||
# Puts the phone back the way 21-preflight.sh found it (<out>/session/found.env): Home screen,
|
||||
# the TCP supervisor restarted on the INSTALLED package if it was running (every replay's
|
||||
# `am force-stop` kills it; tcp_device_server.py start with the same listen/token and the saved
|
||||
# Doze state file, which it never overwrites), the pin released if this window set it, and the
|
||||
# stay-on setting as found. Prints the final state; never uninstalls anything.
|
||||
set -uo pipefail
|
||||
. "$(dirname "$0")/lib.sh"
|
||||
|
||||
[ $# -ge 1 ] || die "usage: $0 <stamp>"
|
||||
STAMP=$1
|
||||
w2_load_build "$STAMP"
|
||||
OUT=$(w2_out "$STAMP")/session
|
||||
[ -f "$OUT/found.env" ] || die "no $OUT/found.env: nothing recorded to restore to"
|
||||
. "$OUT/found.env"
|
||||
w2_require_device
|
||||
w2_lock
|
||||
t0=$(date +%s)
|
||||
|
||||
Ash "input keyevent KEYCODE_HOME"
|
||||
if [ "${FOUND_SUPERVISOR:-0}" = 1 ]; then
|
||||
if w2_supervisor_running; then
|
||||
log "supervisor already listening on $W2_LISTEN"
|
||||
else
|
||||
python3 "$W2_TOOLS/tools/trace_replay/tcp_device_server.py" start --serial "$W2_SERIAL" \
|
||||
--package "$W2_PKG" --listen "$W2_LISTEN" --token "$W2_TOKEN" --allow-idle \
|
||||
--state-file "$W2_IDLE_STATE" > "$OUT/supervisor-restart.txt" 2>&1
|
||||
for _ in $(seq 1 20); do w2_supervisor_running && break; sleep 1; done
|
||||
w2_supervisor_running && log "supervisor restarted on $W2_LISTEN" || log "WARN: supervisor NOT listening (see $OUT/supervisor-restart.txt)"
|
||||
fi
|
||||
Ash "input keyevent KEYCODE_HOME"
|
||||
fi
|
||||
if [ -f "$OUT/pinned-by-window" ]; then
|
||||
bash "$W2_TOOLS/tools/device_bench/pin_device.sh" "$W2_SERIAL" unpin > "$OUT/pin-session-end.txt" 2>&1
|
||||
rm -f "$OUT/pinned-by-window"
|
||||
fi
|
||||
pin=$(w2_pin_check "$W2_TOOLS" "$OUT/pin-check-final.txt")
|
||||
if [ -n "${FOUND_STAYON:-}" ] && [ "$(Ash 'settings get global stay_on_while_plugged_in')" != "$FOUND_STAYON" ]; then
|
||||
Ash "settings put global stay_on_while_plugged_in $FOUND_STAYON"
|
||||
fi
|
||||
sleep 2
|
||||
{
|
||||
echo "focus : $(Ash 'dumpsys window' | grep -m1 mCurrentFocus | tr -s ' ')"
|
||||
echo "supervisor : $(w2_supervisor_running && echo listening || echo not-running) (found: ${FOUND_SUPERVISOR:-?})"
|
||||
echo "pin : $pin (found: ${FOUND_PIN:-?})"
|
||||
echo "stayon : $(Ash 'settings get global stay_on_while_plugged_in') (found: ${FOUND_STAYON:-?})"
|
||||
echo "doze wl : $(Ash 'dumpsys deviceidle whitelist' | grep -i mobilegl | tr '\n' ' ')"
|
||||
} | tee "$OUT/restored.txt"
|
||||
w2_timing "$(w2_out "$STAMP")" restore "$t0" "$(date +%s)"
|
||||
log "=== RESTORE DONE $STAMP ==="
|
||||
@@ -0,0 +1,111 @@
|
||||
# 设备窗口 #2 运行手册(P7 收官:门 3 终局 + bsl stats + CTS AFTER)
|
||||
|
||||
一条命令产出三样东西:CONTRACT-P7 §7.2 的门 3 读数(36 例 × DirectVulkan × `--use-pbuffer`,
|
||||
monolith ×1 + inproc ×3 + spawn ×3 + inproc `RUN_AHEAD=0` ×1,同一 reboot-clean 会话)、
|
||||
M2/M3 的 bsl-esc-menu 设备读数(`MOBILEGL_PIPE_STATS` 下的 `/proc/<pid>/maps` 行数峰值与 `wbuf[]`),
|
||||
以及 §7.3 门 5 的 CTS AFTER(五块 KHR-GL46,inproc × DirectVulkan,对 `device-window-1/CTS-base`)。
|
||||
脚本在 `~/w7/notes/p7/window2/`(仓库副本 `docs/Disaggregated/notes/p7/device-window-2/tools/`)。
|
||||
|
||||
**参数**:`<pipe-sha>` = 最终功能包全部落地后的集成树提交;`<stamp>` 缺省 `p7w7-<sha8>`。
|
||||
输出根 `~/w7/logs/p7w7/<stamp>/`。设备 Redmi `2f7cbe2e`,包 `top.mobilegl.plugin.p7w1.trace`(原地 `install -r`,不卸载任何东西)。
|
||||
|
||||
## 0. 前置(不占设备,开窗前核对)
|
||||
|
||||
1. `<pipe-sha>` 必须含 `p7/devprep` 的跑器修复(`fe4c8745`:`run_android_retrace_local.py` 能从 POSIX 主机起跑、
|
||||
每遍之前清掉上一遍的产物)。没拣就会在第一步被 `lib.sh` 以名字拒绝;应急可 `export W2_TOOLS_OVERRIDE=~/w7/p7-devprep`
|
||||
(只借工具,APK 仍按 `<pipe-sha>` 构建)。
|
||||
2. Windows 侧 adb server 在跑并看得见 `2f7cbe2e`。WSL 的 `/usr/sbin/adb` 经 mirrored networking 连的就是它;
|
||||
server 没了在 **Windows** 上 `adb start-server`,不要在 WSL 里起(会抢 5037 而看不见 USB)。
|
||||
3. 手机 `/data/local/tmp/mgcts` 有 `glcts`、`gl_cts/`、`mgprobe`(窗口 1 部署,现仍在;缺则 `sh ~/w7/logs/cts-a64/deploy/deploy.sh 2f7cbe2e`)。
|
||||
4. 窗口期间没有别的 agent 用手机、主机不并行跑 gate(超时是墙钟)。手机若有锁屏密码,reboot 后要手动解锁一次
|
||||
(preflight 等 `sys.user.0.ce_available=true` 最多 10 min)。
|
||||
|
||||
## 1. 一条命令
|
||||
|
||||
```bash
|
||||
bash ~/w7/notes/p7/window2/detach.sh ~/w7/logs/p7w7/window-<sha8>.log ~/w7/notes/p7/window2/window.sh <pipe-sha>
|
||||
tail -f ~/w7/logs/p7w7/window-<sha8>.log # 结束行 "=== WINDOW 2 DONE <stamp>",其后打印 verdict
|
||||
```
|
||||
|
||||
`detach.sh` = `setsid nohup … < /dev/null &`,与终端 / 工具 10 min 上限脱钩。**中断后原命令重跑即续**:
|
||||
每步完成写 `<out>/steps/<step>.done`;门 3 逐 (arm, case) 写 `gate3/state/<arm>/<case>.done`(未完成的那一对整对重跑);
|
||||
CTS 逐块写 `cts/runs/<block>/.done`。只重跑一例:删它的 `.done` 再跑 `30-gate3.sh <stamp>`。
|
||||
不重启:`window.sh <pipe-sha> --no-reboot`(门 3 要 reboot-clean,只在复跑时用)。
|
||||
|
||||
## 2. 步骤(等价的逐条命令)与耗时
|
||||
|
||||
| # | 命令 | 做什么 | 估时 |
|
||||
|---|---|---|---|
|
||||
| 1 | `10-build.sh <sha> [<stamp>]` | `~/w7/p7w7-tree-<sha8>`(pipe 的 detached worktree,子模块从 pipe 拷,LFS fixture 随 checkout)里构建 APK(`assembleTraceRelease`,`.p7w1` 并排 id,debuggable,显式 stamp,debug keystore 签名)与主机制品(`build-host`:`libMobileGL.so`/`libMobileGLServer.so`/`mobilegl_trace_replay` + catalog),两端 stamp 字符串各 ≥1 | 6 min(dry:APK 131 s、host 223 s) |
|
||||
| 2 | `21-preflight.sh <stamp> --reboot` | 记录「找到时」的状态(supervisor、stay-on、钉频、Doze 白名单)→ reboot,前后 boot_id 必须不同 → 唤醒、`svc power stayon true` → `pin_device.sh pin`,`check` 为 `PINNED` 或 `PINNED-1100`(本板 pwrlevel 0 实跑 1100 MHz,窗口 1 已记,脚本期望值过期) | 2–3 min |
|
||||
| 3 | `20-install.sh <stamp>` | `adb install -r`;**设备上 `base.apk` 的 sha256 必须等于签名 APK**,versionName 带 `<sha7>`;等 dex2oat 空闲 | ~1 min |
|
||||
| 4 | `30-gate3.sh <stamp>` | 36 例(`--matrix` 的 DirectVulkan 集减 `create-indirect` / `1.21.11-main-menu` / `photon-v1.3b`,冻结在 `gate3/cases.txt`)× 四臂;iterationrp 带 `apk.yml:460-462` 三个 Magma 旋钮;每遍 result.json / actual PNG / 双角色日志 / transport-proof / logcat 归档;每臂前后 pin check | 55–65 min |
|
||||
| 5 | `40-bsl-stats.sh <stamp>` | bsl-esc-menu × {inproc, spawn} 各 1 遍,`MOBILEGL_PIPE_STATS=1 PERIOD=1`;先 force-stop 再起设备端 root 采样器(0.25 s:maps 行数、VmRSS、VmHWM;排除 argv 带 `tcp://` 的 supervisor server);`wbuf[]` 从归档日志取 | ~1 min |
|
||||
| 6 | `50-cts-after.sh <stamp>` | APK 的 arm64 `libMobileGL.so` 推到 `mgcts` 并在设备上核 sha256;AFTER 环境 = `$BASE` 的 flag + `MOBILEGL_TRANSPORT=inproc` + `ROLE_SPLIT_STATE=1 STRICT_ERRORS=1 RUN_AHEAD=1`;臂证明(mgprobe PASS 且 logcat 有 inproc 解析句与 `Config: IPC … strict=1 role-split-state=1 run-ahead=1`、0 Fatal;再用一个 glcts 用例证一次);五块依次跑(顺序同 `$BASE`),每块 `qpa_report --json`,最后 `cts_multi_report` 出与 `$BASE` 同形的 JSON | 6–7 min(pipe 头 lib inproc 实测 358 s;`$BASE` monolith 372 s) |
|
||||
| 7 | `60-reduce.py <stamp>` | 写 `verdict.txt` / `verdict.json`(见 §3) | <10 s |
|
||||
| 8 | `90-restore.sh <stamp>` | Home;supervisor 若开窗时在跑则以 `tcp_device_server.py start --allow-idle`(同 listen / token / Doze 状态文件)在**新 APK**上重启并核实在听;解钉频;stay-on 复原 | ~10 s |
|
||||
|
||||
合计:构建 ~6 min + 设备 ~65–80 min ≈ **1.3–1.5 h**。外推依据见 §5。
|
||||
|
||||
## 3. 判读 `verdict.txt`
|
||||
|
||||
- **门 3**,逐例 `PASS / FAIL / INCOMPLETE` + 原因:monolith 本身通过;inproc 与 spawn 各 3 遍齐全、每遍臂证明通过、
|
||||
每遍 ssim ≥ 阈值、**三遍 actual PNG SHA-256 相同**、每遍 `|ssim − monolith| ≤ 0.0005`;OpenRA 在 monolith / inproc / spawn
|
||||
每遍都 `1.000000` 且 mismatch 0;一遍的 logcat 与上一遍逐字节相同记 `STALE`。`RUN_AHEAD=0` 臂只记录
|
||||
(ssim、SHA、`Config: IPC` 全是 `run-ahead=0` 的证明);它的 runner rc=1 是 `--require-inproc` 要求 `run-ahead=1` 的已知副作用(E1)。
|
||||
末行 `GATE3 PASS: 36/36` 才是门 3;列 `i==s==m` 表示三臂同图(信息,不设门)。
|
||||
- **BSL**:每臂每进程(app / server)的 maps 行数峰值、VmRSS / VmHWM 峰值、`wbuf[wbufs wlivepk wdefpk wdefsync]`。
|
||||
- **CTS**:每块 BASE 与 AFTER 的 `P/NS/F/X` 与 rate = Pass / (结果数 − NotSupported)(Fail、Crash、warning 全在分母里),
|
||||
delta pp;块判据 delta ≥ −0.5 pp、**新增 crash = 0**(AFTER 为 Crash/Timeout/InternalError/ResourceError/DeviceHang/Incomplete 而 BASE 不是,另加 hung.txt)、
|
||||
`unrun.txt` 为空。另列 Pass→非 Pass 与非 Pass→Pass 的逐例名单;AFTER 高出 0.5 pp 以上只标注不判红。
|
||||
- `reduce` 的退出码只作记录:红的门也要走完 restore。
|
||||
|
||||
## 4. 入库清单 → `docs/Disaggregated/notes/p7/device-window-2/`
|
||||
|
||||
`verdict.txt`、`verdict.json`、`timing.tsv`;`session/`(`found.env`、`reboot-clean.txt`、`boot-id*.txt`、`apk.sha256`、`apk-on-device.sha256`、
|
||||
`apk-install.txt`、`pin-*.txt`、`device.txt`、`restored.txt`);`gate3/{cases.txt,excluded.txt,arms.txt,progress.tsv,pin-*.txt}`;
|
||||
`bsl/<arm>/{peaks.txt,wbuf.txt,wbuf-gauges.txt}`;`cts/{IDENTITY 即 deploy/IDENTITY.txt,arm-proof.txt,preflight.txt,report-*.txt,report-*.json,after-*.json,after-*.md,pin-*.txt}`、
|
||||
`cts/runs/*/{crashed,hung,unrun,skipped}.txt`。归档图像与日志(`gate3/archive/`、`bsl/*/archive/`、qpa)留在 `~/w7/logs/p7w7/<stamp>/`,
|
||||
在 README 里记绝对路径(>2 MiB 不入库)。主机制品 `<out>/host/` 与 `host.sha256` 供之后的 TCP 对照(`run_tcp_matrix.py --library/--runner`,同 stamp)。
|
||||
|
||||
## 5. Dry run(2026-09-23,已装 p7w6 APK `45759c30…`,只证管线,不是判据)
|
||||
|
||||
命令:`dry-run-p7w6.sh`(`W2_APK_OVERRIDE=~/w7/logs/p7w6/trace-p7w6.apk`,`W2_TOOLS_OVERRIDE=~/w7/p7-devprep`,不重启,钉频)。
|
||||
|
||||
| 步 | 结果 | 墙钟 |
|
||||
|---|---|---|
|
||||
| preflight(无 reboot) | found:supervisor 在跑、stay-on 15、UNPINNED;pin → PINNED | 5 s |
|
||||
| install `--verify-only` | 设备 `base.apk` sha256 = `45759c30…`,versionName `26.09.0e16ca2-trace` | <1 s |
|
||||
| 门 3:OpenRA + iris-bsl-in-world × 四臂 × 1 | 8 次回放全部归档;OpenRA 四臂 1.000000 / 0;bsl-in-world 四臂 0.997010 同 SHA;spawn 证明 `server role in pid …`;ra0 两例 `run-ahead=0`,rc=1(预期) | 63 s(7–8 s/例/臂) |
|
||||
| bsl stats inproc(+ 第二轮 spawn) | 两臂 0.999791667、SHA `155dcdd1…`(= W6/E0a);p7w6 读数:inproc app maps 峰 8536 行 / VmHWM 823 MB;spawn server 7401 行 / 343 MB,client 4595 行 / 555 MB;`wbuf[wbufs=28 wlivepk=1052 wdefpk=3312832 wdefsync=24]` | 14 s/臂 |
|
||||
| CTS AFTER dsa 前 20 例 | 部署 p7w6 lib `12861aa1…` 并核 sha;mgprobe PASS;mgprobe 与 glcts 的臂证明 PROVEN;BASE 19/0/0/1 vs AFTER 19/0/0/1,+0.000 pp,0 新 crash;之后 `$BASE` lib `7f58aa0b…` 推回 | 1–2 s/块 |
|
||||
| restore | Home、supervisor 在新起的 `tcp://0.0.0.0:40613` 在听、UNPINNED、stay-on 15、Doze 白名单同开窗 | 5 s |
|
||||
| 构建脚本 @ `14e1c8b9`,stamp `p7w7dry-14e1c8b9`(**未安装**) | APK `f2ca6b02…`(id `.p7w1`、versionName `26.09.14e1c8b-trace`、同 debug 证书),lib stamp 串 1;主机制品 stamp 串 1 | 358 s |
|
||||
| CTS 计时样本:p7w6 inproc 全 ssbo + dsa | ssbo 124/124;dsa 366/0/3/2,−0.539 pp,1 新 crash(见 §6) | 3 s + 9 s |
|
||||
| CTS 预读:pipe 头 `14e1c8b9` 的 arm64 lib(取自上行未安装的 APK,只推到 `mgcts`)五块全跑 | 见 §6:dsa 与 shader-image 各 1 个新 crash;之后 `$BASE` lib 推回并核 sha | 358 s |
|
||||
|
||||
**外推**:窗口 1 同机同口径的逐例间隔(E0a monolith 39 例 360 s、E0a inproc 342 s、W4 inproc 412 s;最慢 derivative 30 s、
|
||||
bsl-esc-menu 15–30 s)与本次 dry run 的 7–8 s/例一致,36 例一遍 ≈ 5.5–7 min;8 遍 ≈ 45–55 min,另加 144 次 runner 调用的
|
||||
启动 / 汇总页与每臂 pin check ≈ 5 min → 门 3 55–65 min。CTS 五块 inproc 实测 358 s(shader-image 9 / ssbo 3 / dsa 9 / texture 108 / packed-pixels 220 s)。
|
||||
|
||||
## 6. 已知事实与限制
|
||||
|
||||
- **门 5 在 pipe 头 `14e1c8b9` 上会红(预读,非判据,逐例归属在 `docs/Disaggregated/notes/p7/device-window-2/dry-run/pre-14e1c8b9-cts/attribution.txt`)**:同一 lib 的 monolith 与
|
||||
inproc 逐例对照(inproc 带或不带三个 split 旋钮结果相同):
|
||||
- `KHR-GL46.direct_state_access.renderbuffers_storage`:monolith Pass,inproc **SIGABRT** `Fatal{ReplyTooLarge, "ReadPixels 256x512 0x1908/0x1406 2097152 > 2097136"}`
|
||||
——RGBA/FLOAT 回读恰 2 MiB,比一个 reply 槽的载荷上限(槽 − 16 B 头,`MG_Remote/Transport/ReplySlot.h:166-169`)多 16 B;客户端在发射前具名拒绝
|
||||
(`MG_Remote/Client/ClientSession.cpp:2319`,ID-47:「chunked readback 是 P6 债」)。
|
||||
- `…renderbuffers_storage_multisample`:monolith Pass,inproc Fail。两例合计 dsa −0.539 pp(门限 0.5)+ 1 新 crash。
|
||||
- `KHR-GL46.shader_image_load_store.incomplete_textures`:monolith Fail(`$BASE` 亦非 Pass),inproc **SIGABRT** `Fatal{UnmigratedVerb, "Magma:image-view-window"}`
|
||||
(`MG_Backend/DirectVulkan/Renderer/UniformManager.cpp:151`)——Fail 变 Crash,按门 5 是新 crash。
|
||||
- `…shader_image_load_store.advanced-sync-vertexArray`:`$BASE` Pass,pipe 头 monolith 与 inproc 都 Fail——不是分离缺陷,是 p7w1 之后两臂共有的漂移。
|
||||
- `KHR-GL46.texture_border_clamp.Texture2DArrayCompressed`:整块里 Fail 一次,单跑三臂都 Pass——抖动。
|
||||
- 其余:ssbo、packed-pixels 与 `$BASE` 相同;texture +0.96 pp;shader-image 整体 +2.9 pp(3 例修好)。
|
||||
终局窗口之前要么修(ReadPixels 分块或放大 reply 槽;`image-view-window` 的 incomplete-texture 形状 decline 成 GL 语义而不是 Fatal),要么由集成者裁定。
|
||||
- dry run 暴露并已修的两处:`run_android_retrace_local.py` 只会用 Git Bash 起跑(WSL 下每例 FileNotFoundError),且一遍没产出时会归档上一遍的图(假「逐位相同」)——`fe4c8745`,带 red-once 单测;
|
||||
脚本自身的 `pipefail` + `grep -q` 把在跑的 supervisor 读成「不在」——已改为先取输出再匹配。
|
||||
- `$BASE` 的机器可读 JSON(CTS-base/README 所称 `base-DirectVulkan-monolith-p7w1-9be62cbc.json`)此前不在任何树里;已按 `cts_multi_report.py --adopt-legacy` 从
|
||||
`~/w7/logs/cts-a64/base/runs` 重生成入 `tools/cts/baselines/`(数字与 README 表逐块一致;texture 因 skip 表 1 例记 INCOMPLETE 是该工具的口径)。
|
||||
判据本身用的是入库的 `CTS-base/report-*.json` 逐例结果。
|
||||
- `$BASE` 库的 IDENTITY 写 stamp `p7w1-d260f110`,README / JSON 名写 `9be62cbc`:两者是同一补丁(`d260f110` 与 `9be62cbc` 同题提交),只是命名差。
|
||||
- 每次回放的 `am force-stop` 会杀 TCP supervisor;restore 负责按开窗状态复原。
|
||||
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env bash
|
||||
# detach.sh <logfile> <script> [args...]
|
||||
#
|
||||
# Starts one window-2 step so that it survives the terminal / the agent's 10-minute tool limit:
|
||||
# a new session (setsid), immune to hangup (nohup), stdin from /dev/null, all output to <logfile>.
|
||||
# Prints the pid and the log path, and returns at once. Poll with: tail -f <logfile>
|
||||
# Every step is resumable (per-case / per-block done markers), so re-running the same command
|
||||
# after an interruption continues where it stopped.
|
||||
set -euo pipefail
|
||||
[ $# -ge 2 ] || { echo "usage: $0 <logfile> <script> [args...]" >&2; exit 64; }
|
||||
logfile=$1; shift
|
||||
mkdir -p "$(dirname "$logfile")"
|
||||
setsid nohup bash "$@" > "$logfile" 2>&1 < /dev/null &
|
||||
pid=$!
|
||||
disown "$pid" 2>/dev/null || true
|
||||
# Linger briefly: when the caller is `wsl.exe ... bash launcher.sh`, returning at once can tear the
|
||||
# WSL session down before the child has left the caller's session (observed: a step that never
|
||||
# wrote its first line). Two seconds, then say whether it is really running.
|
||||
sleep 2
|
||||
if kill -0 "$pid" 2>/dev/null; then
|
||||
echo "detached pid=$pid log=$logfile"
|
||||
else
|
||||
echo "WARNING: pid $pid already exited; see $logfile" >&2
|
||||
fi
|
||||
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
# dry-run-p7w6.sh - the plumbing proof recorded in RUNBOOK.md section 5, against the p7w6 APK that
|
||||
# is ALREADY installed (nothing is installed or uninstalled): 2 gate-3 cases x all four arms x1,
|
||||
# bsl stats on inproc once, CTS AFTER on the first 20 dsa cases (then the $BASE lib goes back),
|
||||
# reduce, restore. Not a verdict run.
|
||||
set -uo pipefail
|
||||
HERE=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
export W2_LOGROOT=${W2_LOGROOT:-$HOME/w7/logs/devprep/w2}
|
||||
export W2_APK_OVERRIDE=${W2_APK_OVERRIDE:-$HOME/w7/logs/p7w6/trace-p7w6.apk}
|
||||
export W2_TOOLS_OVERRIDE=${W2_TOOLS_OVERRIDE:-$HOME/w7/p7-devprep}
|
||||
STAMP=${1:-dry-p7w6}
|
||||
CASES=${DRY_CASES:-OpenRA,minecraft-1.21.4-fabric-iris-bsl-in-world}
|
||||
echo "=== DRY RUN START $(date -Is) stamp=$STAMP apk=$W2_APK_OVERRIDE tools=$W2_TOOLS_OVERRIDE ==="
|
||||
bash "$HERE/21-preflight.sh" "$STAMP" || exit 1
|
||||
bash "$HERE/20-install.sh" "$STAMP" --verify-only || exit 1
|
||||
bash "$HERE/30-gate3.sh" "$STAMP" --cases "$CASES" --repeat 1
|
||||
bash "$HERE/40-bsl-stats.sh" "$STAMP" --arms inproc
|
||||
bash "$HERE/50-cts-after.sh" "$STAMP" --blocks dsa --limit 20 --restore-base-lib
|
||||
python3 "$HERE/60-reduce.py" "$STAMP" > "$W2_LOGROOT/$STAMP/verdict.txt" 2>&1; echo "reduce rc=$?" >> "$W2_LOGROOT/$STAMP/verdict.txt"
|
||||
bash "$HERE/90-restore.sh" "$STAMP"
|
||||
cat "$W2_LOGROOT/$STAMP/verdict.txt"
|
||||
echo "=== DRY RUN DONE $(date -Is) ==="
|
||||
@@ -0,0 +1,98 @@
|
||||
# Device window 2 (P7 closeout) - shared settings and helpers. Sourced, never run.
|
||||
#
|
||||
# Every setting is an overridable W2_* environment variable; the defaults are the Redmi
|
||||
# 2f7cbe2e / p7w1-side-by-side-package facts recorded in docs/Disaggregated/notes/p7/
|
||||
# device-window-1/00-session/README.md and HANDOFF-2026-09-22.md.
|
||||
|
||||
W2_HERE=$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
|
||||
W2_SERIAL=${W2_SERIAL:-2f7cbe2e}
|
||||
W2_PKG=${W2_PKG:-top.mobilegl.plugin.p7w1.trace}
|
||||
W2_TOKEN=${W2_TOKEN:-p7w1b-lan-token-20260922} # >= 16 bytes (ServerMain token rule)
|
||||
W2_LISTEN=${W2_LISTEN:-tcp://0.0.0.0:40613}
|
||||
W2_PIPE=${W2_PIPE:-$HOME/w7/pipe} # integration tree: READ-ONLY here
|
||||
export W2_LOGROOT=${W2_LOGROOT:-$HOME/w7/logs/p7w7} # one directory per <stamp> below this
|
||||
W2_CTS_BUNDLE=${W2_CTS_BUNDLE:-$HOME/w7/logs/cts-a64/deploy} # glcts + mgprobe + BASE lib
|
||||
W2_CTS_DEV=${W2_CTS_DEV:-/data/local/tmp/mgcts}
|
||||
W2_IDLE_STATE=${W2_IDLE_STATE:-$HOME/.cache/mobilegl/tcp-server/${W2_SERIAL}-${W2_PKG}.json}
|
||||
W2_LOCK=${W2_LOCK:-$HOME/w7/logs/p7w7-device-${W2_SERIAL}.lock}
|
||||
export MOBILEGL_FLATC_EXECUTABLE=${MOBILEGL_FLATC_EXECUTABLE:-/home/swung/w7/flatc-build/flatc}
|
||||
|
||||
# The three gate-3 exclusions (CONTRACT-P7 7.1, E0-attribution/exclusions.md). They are red on
|
||||
# the MONOLITH arm too, so they are not split defects; they are listed, never silently dropped.
|
||||
W2_EXCLUDED="minecraft-1.21.1-neoforge-create-indirect-in-world minecraft-1.21.11-main-menu minecraft-1.21.4-fabric-iris-photon-v1.3b-in-world"
|
||||
W2_ITERATIONRP=minecraft-1.21.4-fabric-iris-iterationrp-in-world
|
||||
W2_BSL=minecraft-1.21.4-fabric-iris-bsl-esc-menu-854
|
||||
# The split acceptance knobs run_android_retrace_local.py hands every split arm
|
||||
# (SPLIT_ACCEPTANCE_KNOBS); CTS AFTER uses the same arm.
|
||||
W2_SPLIT_KNOBS="MOBILEGL_IPC_ROLE_SPLIT_STATE=1 MOBILEGL_IPC_STRICT_ERRORS=1 MOBILEGL_IPC_RUN_AHEAD=1"
|
||||
|
||||
A() { adb -s "$W2_SERIAL" "$@"; }
|
||||
Ash() { adb -s "$W2_SERIAL" shell "$@" | tr -d '\r'; }
|
||||
log() { printf '[%s] %s\n' "$(date +%H:%M:%S)" "$*"; }
|
||||
die() { printf '[%s] FATAL: %s\n' "$(date +%H:%M:%S)" "$*" >&2; exit 1; }
|
||||
|
||||
# <stamp> -> the window's output directory, and the per-stamp facts 10-build.sh wrote.
|
||||
w2_out() { printf '%s/%s\n' "$W2_LOGROOT" "$1"; }
|
||||
w2_load_build() {
|
||||
local out; out=$(w2_out "$1")
|
||||
[ -f "$out/build.env" ] && . "$out/build.env"
|
||||
# Overrides for a run against an APK this window did not build (the dry run: p7w6).
|
||||
W2_APK=${W2_APK_OVERRIDE:-${BUILD_APK:-$out/apk/trace-$1.apk}}
|
||||
W2_TOOLS=${W2_TOOLS_OVERRIDE:-${BUILD_TREE:-}}
|
||||
[ -n "$W2_TOOLS" ] || die "no tools tree: run 10-build.sh first or set W2_TOOLS_OVERRIDE"
|
||||
[ -f "$W2_TOOLS/tools/trace_replay/run_android_retrace_local.py" ] || die "not a MobileGL tree: $W2_TOOLS"
|
||||
# The runner must be able to start from this (POSIX) host: the fix is p7/devprep fe4c8745.
|
||||
grep -q 'def bash_executable' "$W2_TOOLS/tools/trace_replay/run_android_retrace_local.py" \
|
||||
|| die "$W2_TOOLS lacks the POSIX-host runner fix (cherry-pick p7/devprep fe4c8745)"
|
||||
grep -q 'def clear_repeat_outputs' "$W2_TOOLS/tools/trace_replay/run_android_retrace_local.py" \
|
||||
|| die "$W2_TOOLS lacks the per-repeat output clear (cherry-pick p7/devprep fe4c8745)"
|
||||
[ -f "$W2_APK" ] || die "APK not found: $W2_APK"
|
||||
}
|
||||
|
||||
w2_require_device() {
|
||||
local state; state=$(timeout 20 adb -s "$W2_SERIAL" get-state 2>/dev/null | tr -d '\r')
|
||||
[ "$state" = device ] || die "adb does not see $W2_SERIAL (state '$state'). WSL's adb is a client of the WINDOWS adb server (mirrored networking); if it is gone, run 'adb start-server' on Windows - never start one from WSL"
|
||||
}
|
||||
|
||||
# One device user at a time: the runner's result root and the device are both single-tenant.
|
||||
w2_lock() {
|
||||
mkdir -p "$(dirname "$W2_LOCK")"
|
||||
exec 9>"$W2_LOCK"
|
||||
flock -n 9 || die "another window-2 step holds $W2_LOCK"
|
||||
}
|
||||
|
||||
w2_wake() {
|
||||
timeout 15 adb -s "$W2_SERIAL" shell input keyevent KEYCODE_WAKEUP >/dev/null 2>&1 || true
|
||||
timeout 15 adb -s "$W2_SERIAL" shell wm dismiss-keyguard >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
# pin_device.sh check, classified. PINNED = exit 0. The one tolerated DRIFT is the documented
|
||||
# board fact (00-session/README.md): this unit's GPU really runs pwrlevel 0 at 1100 MHz, while
|
||||
# pin_device.sh still expects 1050 - that is PINNED-1100, not a slipped pin. Anything else is
|
||||
# recorded as-is and the arm's pin status is UNPROVEN.
|
||||
w2_pin_check() { # <tools-tree> <outfile>
|
||||
local out=$2 rc
|
||||
bash "$1/tools/device_bench/pin_device.sh" "$W2_SERIAL" check > "$out" 2>&1; rc=$?
|
||||
if [ $rc -eq 0 ]; then echo PINNED; return 0; fi
|
||||
if grep -q 'VERDICT: DRIFT' "$out" \
|
||||
&& [ "$(grep -c '^ - ' "$out")" = 1 ] \
|
||||
&& grep -q '^ - gpu pinned to pwrlevel 0 but gpuclk=1100000000 (expected 1050000000)' "$out"; then
|
||||
echo PINNED-1100; return 0
|
||||
fi
|
||||
grep -q 'VERDICT: UNPINNED' "$out" && { echo UNPINNED; return 1; }
|
||||
echo DRIFT; return 1
|
||||
}
|
||||
|
||||
# No `| grep -q` anywhere under `set -o pipefail`: grep -q exits on the first match, the writer
|
||||
# takes SIGPIPE and the pipeline reports 141 - a MATCH read as "not running" (the dry run's first
|
||||
# preflight recorded a live supervisor as absent exactly this way).
|
||||
w2_supervisor_running() {
|
||||
local ps; ps=$(Ash "ps -A -o ARGS" 2>/dev/null)
|
||||
case "$ps" in *"libMobileGLServer.so ${W2_LISTEN} --serve"*) return 0;; esac
|
||||
return 1
|
||||
}
|
||||
|
||||
w2_timing() { # <out> <step> <start-epoch> <end-epoch> [note]
|
||||
printf '%s\t%s\t%s\t%s\t%s\n' "$2" "$(date -d @"$3" +%FT%T)" "$(date -d @"$4" +%FT%T)" \
|
||||
"$(( $4 - $3 ))" "${5:-}" >> "$1/timing.tsv"
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env bash
|
||||
# window.sh <pipe-sha> [<stamp>] [--no-reboot] [--skip build,preflight,install,gate3,bsl,cts,reduce,restore]
|
||||
#
|
||||
# The whole device window 2 as one resumable sequence (run it detached: see RUNBOOK.md):
|
||||
# 10-build.sh APK + host artefacts, stamp <stamp> (default p7w7-<sha8>) host only
|
||||
# 21-preflight.sh record found state, reboot-clean (unless --no-reboot), stay-on, pin
|
||||
# 20-install.sh adb install -r, on-device base.apk sha256 == built APK, dex2oat idle
|
||||
# 30-gate3.sh 36 cases x {monolith x1, inproc x3, spawn x3, inproc RUN_AHEAD=0 x1}
|
||||
# 40-bsl-stats.sh bsl-esc-menu x {inproc, spawn} with MOBILEGL_PIPE_STATS + maps sampler
|
||||
# 50-cts-after.sh five KHR-GL46 blocks, inproc x DirectVulkan, AFTER lib deployed to mgcts
|
||||
# 60-reduce.py gate-3 verdict per case, bsl peaks, CTS delta table + new-crash list
|
||||
# 90-restore.sh Home, supervisor as found, unpin, stay-on as found
|
||||
# Each finished step leaves <out>/steps/<step>.done; a re-run skips it (gate3 / cts also resume
|
||||
# inside a step). A step that fails stops the sequence; fix the cause and run the same command.
|
||||
set -euo pipefail
|
||||
HERE=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
. "$HERE/lib.sh"
|
||||
|
||||
[ $# -ge 1 ] || die "usage: $0 <pipe-sha> [<stamp>] [--no-reboot] [--skip a,b]"
|
||||
PIPE_SHA=$1; shift
|
||||
STAMP=""; REBOOT=--reboot; SKIP=""
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--no-reboot) REBOOT=""; shift;;
|
||||
--skip) SKIP=",$2,"; shift 2;;
|
||||
--*) die "unknown option $1";;
|
||||
*) STAMP=$1; shift;;
|
||||
esac
|
||||
done
|
||||
SHA=$(git -C "$W2_PIPE" rev-parse --verify "$PIPE_SHA^{commit}")
|
||||
STAMP=${STAMP:-p7w7-${SHA:0:8}}
|
||||
OUT=$(w2_out "$STAMP")
|
||||
mkdir -p "$OUT/steps"
|
||||
log "=== WINDOW 2 START sha=$SHA stamp=$STAMP out=$OUT ==="
|
||||
|
||||
step() { # <name> <command...>
|
||||
local name=$1; shift
|
||||
if [ -f "$OUT/steps/$name.done" ]; then log "--- $name: done earlier, skipping"; return 0; fi
|
||||
case "$SKIP" in *",$name,"*) log "--- $name: skipped by --skip"; return 0;; esac
|
||||
log "--- $name: $*"
|
||||
local t0; t0=$(date +%s)
|
||||
"$@"
|
||||
date -Is > "$OUT/steps/$name.done"
|
||||
log "--- $name: OK in $(( $(date +%s) - t0 ))s"
|
||||
}
|
||||
|
||||
step build bash "$HERE/10-build.sh" "$SHA" "$STAMP"
|
||||
step preflight bash "$HERE/21-preflight.sh" "$STAMP" $REBOOT
|
||||
step install bash "$HERE/20-install.sh" "$STAMP"
|
||||
step gate3 bash "$HERE/30-gate3.sh" "$STAMP"
|
||||
step bsl bash "$HERE/40-bsl-stats.sh" "$STAMP"
|
||||
step cts bash "$HERE/50-cts-after.sh" "$STAMP"
|
||||
# The verdict is data, not a stop condition: a red gate still has to restore the phone.
|
||||
step reduce bash -c "python3 '$HERE/60-reduce.py' '$STAMP' > '$OUT/verdict.txt' 2>&1; echo reduce-rc=\$? >> '$OUT/verdict.txt'"
|
||||
step restore bash "$HERE/90-restore.sh" "$STAMP"
|
||||
log "=== WINDOW 2 DONE $STAMP: verdict in $OUT/verdict.txt ==="
|
||||
cat "$OUT/verdict.txt"
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,23 @@
|
||||
# GL CTS multi-suite conformance report
|
||||
|
||||
| Backend | Suite | Expected | Result | Pass | Accepted | Crash | Hang | Unrun | Duplicate | Coverage | Strict Pass-only | Conformance-accepted | Validation |
|
||||
|---|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|:---:|
|
||||
| DirectVulkan | shader-image | 125 | 125 | 63 | 119 | 0 | 0 | 0 | 0 | 100.00% (125/125) | 50.40% (63/125) | 95.20% (119/125) | OK |
|
||||
| DirectVulkan | ssbo | 124 | 124 | 124 | 124 | 0 | 0 | 0 | 0 | 100.00% (124/124) | 100.00% (124/124) | 100.00% (124/124) | OK |
|
||||
| DirectVulkan | dsa | 371 | 371 | 368 | 369 | 0 | 0 | 0 | 0 | 100.00% (371/371) | 99.19% (368/371) | 99.46% (369/371) | OK |
|
||||
| DirectVulkan | texture | 1055 | 1054 | 815 | 1036 | 0 | 0 | 1 | 0 | 99.91% (1054/1055) | 77.25% (815/1055) | 98.20% (1036/1055) | INCOMPLETE |
|
||||
| DirectVulkan | packed-pixels | 4732 | 4732 | 4732 | 4732 | 0 | 0 | 0 | 0 | 100.00% (4732/4732) | 100.00% (4732/4732) | 100.00% (4732/4732) | OK |
|
||||
| **DirectVulkan** | **DirectVulkan weighted subtotal** | **6407** | **6406** | **6102** | **6380** | **0** | **0** | **1** | **0** | **99.98% (6406/6407)** | **95.24% (6102/6407)** | **99.58% (6380/6407)** | **INCOMPLETE** |
|
||||
| **All backends** | **Overall weighted** | **6407** | **6406** | **6102** | **6380** | **0** | **0** | **1** | **0** | **99.98% (6406/6407)** | **95.24% (6102/6407)** | **99.58% (6380/6407)** | **INCOMPLETE** |
|
||||
|
||||
Rates use unique **Expected** caselist cases as the denominator. Unrun cases remain in the denominator and are not accepted.
|
||||
Accepted statuses: `Pass`, `NotSupported`, `QualityWarning`, `CompatibilityWarning`, `Waiver`.
|
||||
Duplicate is the number of extra QPA observations; the final observation wins.
|
||||
|
||||
## Validation details
|
||||
|
||||
- **DirectVulkan/shader-image OK**: result directory has no run_state.json; backend provenance is unverified
|
||||
- **DirectVulkan/ssbo OK**: result directory has no run_state.json; backend provenance is unverified
|
||||
- **DirectVulkan/dsa OK**: result directory has no run_state.json; backend provenance is unverified
|
||||
- **DirectVulkan/texture INCOMPLETE**: result directory has no run_state.json; backend provenance is unverified
|
||||
- **DirectVulkan/packed-pixels OK**: result directory has no run_state.json; backend provenance is unverified
|
||||
Reference in New Issue
Block a user