• Home
Name Date Size #Lines LOC

..--

.gitignoreD04-Jul-20253

BUILD.gnD04-Jul-20251.6 KiB5751

OWNERSD04-Jul-202521 21

README.mdD04-Jul-202532 KiB858662

check_trace_diffs.pyD04-Jul-20251.3 KiB4430

compare_trace_screenshots.pyD04-Jul-20258.8 KiB219149

gen_restricted_traces.pyD04-Jul-20253.9 KiB13490

gpumem.shD04-Jul-2025842 3222

power_denoising.shD04-Jul-20252.8 KiB6440

restricted_trace_gold_tests.pyD04-Jul-202521.9 KiB562421

restricted_trace_perf.pyD04-Jul-202549.6 KiB1,301933

restricted_traces.jsonD04-Jul-20257.5 KiB305304

retrace_restricted_traces.pyD04-Jul-202525.3 KiB683510

sync_restricted_traces_to_cipd.pyD04-Jul-20255.9 KiB161120

README.md

1# ANGLE Restricted Traces
2
3The files in this directory are traces of real applications. We host them
4internally because they may contain third party IP which we don't want
5to share publicly.
6
7## Accessing the traces
8
9In order to compile and run with these, you must be granted access by Google,
10then authenticate with [CIPD](https://chromium.googlesource.com/infra/luci/luci-go/+/main/cipd/README.md). Googlers, use your @google account.
11```
12cipd auth-login
13```
14Add the following to ANGLE's .gclient file:
15```
16    "custom_vars": {
17      "checkout_angle_restricted_traces": True
18    },
19```
20
21Note: alternatively, you can checkout only a few specific traces using the following format (`angle_restricted_traces` in gn args below should be a matching list or a subset):
22```
23    "custom_vars": {
24      "checkout_angle_restricted_trace_{trace_name_1}": True,
25      "checkout_angle_restricted_trace_{trace_name_2}": True,
26      ...
27    },
28```
29
30Then use gclient to pull down binary files from CIPD.
31```
32gclient sync -D
33```
34This should result in a number of directories created in `src/tests/restricted_traces` that contain
35the trace files listed in [restricted_traces.json](restricted_traces.json):
36```
37$ ls -d src/tests/restricted_traces/*/
38src/tests/restricted_traces/aliexpress/
39src/tests/restricted_traces/angry_birds_2_1500/
40src/tests/restricted_traces/arena_of_valor/
41src/tests/restricted_traces/asphalt_8/
42src/tests/restricted_traces/brawl_stars/
43src/tests/restricted_traces/bus_simulator_indonesia/
44src/tests/restricted_traces/candy_crush_500/
45src/tests/restricted_traces/clash_of_clans/
46src/tests/restricted_traces/clash_royale/
47src/tests/restricted_traces/cod_mobile/
48...
49```
50
51## Building the trace tests
52
53To build for Android, follow the steps in [DevSetupAndroid.md](../../../doc/DevSetupAndroid.md)
54(Recommend using the [`Performance`](../../../doc/DevSetupAndroid.md#performance-config) arguments
55for best performance)
56
57To build for Desktop, follow the steps in [DevSetup.md](../../../doc/DevSetup.md)
58
59When that is working, add the following GN arg to your setup:
60```
61build_angle_trace_perf_tests = true
62```
63### Selecting which traces to build
64
65Since the traces are numerous, you should limit compilation to a subset with the following GN arg:
66```
67angle_restricted_traces = ["among_us 5", "street_fighter_duel 1"]
68```
69If you choose not to pick any traces and build them all, you must follow different steps for Android. Skip ahead to [Building and running all traces for Android](#building-and-running-all-traces-for-android)
70
71To build the trace tests:
72```
73autoninja -C out/<config> angle_trace_tests
74```
75## Running the trace tests
76The trace tests can be run with default options like so:
77```
78out/<config>/angle_trace_tests
79```
80To select a specific trace to run, provide it with a filter:
81```
82out/<config>/angle_trace_tests --gtest_filter=TraceTest.<trace_name>
83```
84The specific options available with traces can be found in the PerfTests [`README`](../perf_tests/README.md#trace-tests)
85
86Common options used are:
87```
88# Use ANGLE as the driver with the system's Vulkan driver as backend
89--use-angle=vulkan
90
91# Use the system's native GLES driver
92--use-gl=native
93```
94
95### Building and running all traces for Android
96Our trace library has gotten large enough that they no longer fit in a single APK.  To support building and running the entire library, we can compile the libraries by themselves, outside of the APK, and push them to locations accessible by the test harness.
97
98To do so, remove `angle_restricted_traces` from your GN args, then compile with:
99```
100autoninja -C out/<config> angle_trace_perf_tests
101```
102and run with (including recommended options):
103```
104out/<config>/angle_trace_tests --filter='*among_us*' --verbose --fixed-test-time-with-warmup 10
105```
106
107If more than one device is connected, the target device serial should be provided as well:
108```
109ANDROID_SERIAL=<device_serial> out/<config>/angle_trace_tests ...
110```
111
112# Capturing and adding new Android traces
113
114Generally we want to use a Debug setup for recording new traces. That allows us to see asserts and
115errors if the tracer needs to be improved.
116Add the following GN arg to your Debug setup:
117```
118angle_with_capture_by_default = true
119```
120
121After [building](../../../doc/DevSetupAndroid.md#building-angle-for-android) and
122[installing](../../../doc/DevSetupAndroid.md#install-the-angle-apk) the APK with the above arg,
123we're ready to start capturing.
124
125If capturing a new trace using OpenCL, also add the following to your Debug setup:
126```
127angle_enable_cl = true
128```
129
130<details>
131  <summary>Example of full OpenCL GN arg Debug setup for Capture</summary>
132  <br>
133
134    # Target information
135    is_clang = true
136    target_cpu = "arm64"
137    target_os = "android"
138
139    # Enable CL + backends
140    angle_enable_cl = true
141    angle_enable_vulkan = true
142
143    # Debug mode flags
144    is_debug = true
145    symbol_level = 2
146    strip_debug_info = false
147    android_full_debug = true
148    ignore_elf32_limitations = true
149
150    # Other flag settings
151    is_official_build = false
152    is_component_build = false
153    angle_extract_native_libs = true
154</details>
155
156## Determine the target app
157
158We first need to identify which application we want to trace.  That can generally be done by
159looking at the web-based Play Store entry for your app.  For instance, Angry Birds 2 is listed
160here: https://play.google.com/store/apps/details?id=com.rovio.baba
161
162If there is no Play Store entry for your app, there are a couple of ways you can determine the
163app's name.
164
165If you have a userdebug build of Android, you can check logcat when you launch the application.
166You should see an entry like this:
167```
168GraphicsEnvironment: ANGLE Developer option for 'com.rovio.baba' set to: 'default'
169```
170If you just have an APK, you can use the following command to find the package name:
171```
172$ aapt dump badging angry_birds_2.apk | grep package
173package: name='com.rovio.baba' versionCode='24900001' versionName='2.49.1' platformBuildVersionName=''
174```
175You can also just guess at the package name, then check your device to see if it is installed. Keep
176trying combinations until you find it:
177```
178$ adb shell pm list packages | grep rovio
179package:com.rovio.baba
180```
181Track the package name for use in later steps:
182```
183export PACKAGE_NAME=com.rovio.baba
184```
185
186## Choose a trace name
187
188Next, we need to chose a name for the trace. Choose something simple that identifies the app, then use snake
189case. This will be the name of the trace files, including the trace directory. Changing this value later is possible,
190but not recommended.
191```
192export LABEL=angry_birds_2
193```
194
195## Opt the application into ANGLE
196
197Note: If running an executable, not an application/APK, these settings don't apply.
198
199Next, opt the application into using your ANGLE with capture enabled by default:
200```
201adb shell settings put global angle_debug_package org.chromium.angle
202adb shell settings put global angle_gl_driver_selection_pkgs $PACKAGE_NAME
203adb shell settings put global angle_gl_driver_selection_values angle
204```
205
206## Set up some Capture/Replay properties
207
208We also need to set some debug properties used by the tracer.
209
210Ensure frame capture is enabled. This might be redundant, but ensure the property isn't set to
211zero, which disables frame capture.
212```
213adb shell setprop debug.angle.capture.enabled 1
214```
215Empty the start and end frames. Again, this might be redundant, but it is less confusing.
216```
217adb shell setprop debug.angle.capture.frame_start '""'
218adb shell setprop debug.angle.capture.frame_end '""'
219```
220Set the label to be used in the trace files
221```
222adb shell setprop debug.angle.capture.label $LABEL
223```
224Set a trigger value to be used by the tracer. This should be set to the *number of frames* you want
225to capture. We typically use 10 to get an idea of how a scene is running, but some workloads
226require more. Use your discretion here:
227```
228adb shell setprop debug.angle.capture.trigger 10
229```
230
231For OpenCL capture, a trigger most likely won't be wanted. So, set the frame_start and frame_end values accordingly. Each ```clEnqueueNDRangeKernel``` is considered the end of a frame.
232```
233adb shell setprop debug.angle.capture.frame_start 1
234adb shell setprop debug.angle.capture.frame_end 100.
235```
236
237## Create output location
238
239We need to write out the trace file in a location accessible by the app. We use the app's data
240storage on sdcard, but create a subfolder to isolate ANGLE's files:
241```
242adb shell mkdir -p /sdcard/Android/data/$PACKAGE_NAME/angle_capture
243```
244
245## Start the target app
246
247From here, you can start the application. You should see logcat entries like the following,
248indicating that we've succesfully turned on capturing:
249```
250ANGLE   : INFO: Capture trigger detected, disabling capture start/end frame.
251ANGLE   : INFO: Limiting binary format support count to zero while FrameCapture enabled
252ANGLE   : INFO: Limiting image unit count to 8 while FrameCapture enabled
253ANGLE   : INFO: Setting uniform buffer offset alignment to 256 while FrameCapture enabled
254ANGLE   : INFO: Disabling GL_EXT_map_buffer_range and GL_OES_mapbuffer during capture, which are not supported on some native drivers
255ANGLE   : INFO: Disabling GL_CHROMIUM_bind_uniform_location during capture, which is not supported on native drivers
256ANGLE   : INFO: Disabling GL_NV_shader_noperspective_interpolation during capture, which is not supported on some native drivers
257ANGLE   : INFO: Limiting draw buffer count to 4 while FrameCapture enabled
258```
259## Trigger the capture
260
261Note: If you have set the start and end frame, this step does not apply.
262
263When you have reached the content in your application that you want to record, set the trigger
264value to zero:
265```
266adb shell setprop debug.angle.capture.trigger 0
267```
268In logcat we'll see another entry corresponding to this:
269```
270ANGLE   : INFO: Capture triggered after frame 30440 for 10 frames
271```
272The app may pause briefly when the capture is completing. You can check its progress by looking at
273the file system:
274```
275adb shell ls -la /sdcard/Android/data/$PACKAGE_NAME/angle_capture
276```
277Allow the app to run until the logcat entry indicating the end of the API
278capture. The app should continue rendering after that:
279```
280ANGLE   : INFO: Finished recording graphics API capture
281```
282
283## Optionally trigger additional captures
284
285It is possible to capture an arbitrary number of traces.
286
287After each trace completes, set the trigger value to the desired number of frames to capture
288for the next trace, optionally create and specify a different out_dir for the new trace data,
289and then start the new trace by again resetting the trigger value to zero.
290
291Example workflow for multiple captures:
292
293```
294adb shell mkdir -p /data/data/$PACKAGE_NAME/angle_capture_1
295adb shell mkdir -p /data/data/$PACKAGE_NAME/angle_capture_2
296adb shell mkdir -p /data/data/$PACKAGE_NAME/angle_capture_3
297
298# Set initial output dir and frame count
299adb shell setprop debug.angle.capture.out_dir /data/data/$PACKAGE_NAME/angle_capture_1
300adb shell setprop debug.angle.capture.trigger 100
301
302# Trigger capture
303adb shell setprop debug.angle.capture.trigger 0
304
305# Set the next output dir and frame count
306adb shell setprop debug.angle.capture.out_dir /data/data/$PACKAGE_NAME/angle_capture_2
307adb shell setprop debug.angle.capture.trigger 30
308
309# Trigger capture
310adb shell setprop debug.angle.capture.trigger 0
311
312# Set the next output dir and frame count
313adb shell setprop debug.angle.capture.out_dir /data/data/$PACKAGE_NAME/angle_capture_3
314adb shell setprop debug.angle.capture.trigger 60
315
316# Trigger capture
317adb shell setprop debug.angle.capture.trigger 0
318
319# Pull the traces
320adb pull /data/data/$PACKAGE_NAME/angle_capture_1
321adb pull /data/data/$PACKAGE_NAME/angle_capture_2
322adb pull /data/data/$PACKAGE_NAME/angle_capture_3
323```
324
325Note that multiple captures are incompatible with applications using persistent coherent memory.
326If more than one capture is attempted in this situation the tracer will exit immediately.
327The initial capture will remain valid.
328
329## Pull the trace files
330
331Next, we want to pull those files over to the host and run some scripts.
332```
333cd $CHROMIUM_SRC/third_party/angle/src/tests/restricted_traces
334mkdir -p $LABEL
335adb pull /sdcard/Android/data/$PACKAGE_NAME/angle_capture/. $LABEL/
336```
337
338## Add the new trace to the JSON list
339
340The list of traces is tracked in [restricted_traces.json](restricted_traces.json). Manually add your
341new trace to this list. Use version "1" for the trace version.
342
343On Linux, you can also use a tool called `jq` to update the list. This ensures we get them in
344alphabetical order with no duplicates. It can also be done by hand if you are unable to install it,
345for some reason.
346```
347sudo apt-get install jq
348```
349Then run the following command:
350```
351export VERSION=1
352jq ".traces = (.traces + [\"$LABEL $VERSION\"] | unique)" restricted_traces.json | sponge restricted_traces.json
353```
354
355## Run code auto-generation
356
357The [`gen_restricted_traces`](gen_restricted_traces.py) script auto-generates entries
358in our checkout dependencies to sync restricted trace data on checkout. To trigger
359code generation run the following from the angle root folder:
360```
361python ./scripts/run_code_generation.py
362```
363After this you should be able to `git diff` and see changes in the following files:
364
365 * `DEPS`
366 * `scripts/code_generation_hashes/restricted_traces.json`
367 * `src/tests/restricted_traces/restricted_traces.json` (this is the file you originally modified)
368
369Note the absence of the traces themselves listed above. They are automatically
370ignored by [`.gitignore`](.gitignore) since they won't be checked in directly
371to the repo.
372
373## Upload your trace to CIPD
374
375Once you feel good about your trace, you can upload it to our collection of traces.  This can only
376be done by Googlers with write access to the trace CIPD prefix. If you need write access contact
377someone listed in the `OWNERS` file.
378
379Please kindly go over the trace content with ANGLE code owners before running
380below commands. You can share your trace through Google Drive for content
381iterations. We cannot delete trace files once they are up on the CIPD.
382Doing additional rounds of content check can help us save CIPD resources.
383
384```
385src/tests/restricted_traces/sync_restricted_traces_to_cipd.py
386```
387
388## Upload your CL
389
390Ensure your current working directory is up-to-date, and upload:
391
392```
393git cl upload
394```
395
396You're now ready to run your new trace on CI!
397
398# Comparing screenshots against the native driver
399
400To compare trace screenshots from ANGLE vs the native driver, you can
401use the `compare_trace_screenshots.py` script.
402
403The following steps will work on Android, but are transferrable to
404any operating system.
405
406First, make a spot for the results:
407```
408adb shell rm -r /sdcard/angle/screenshots
409adb shell mkdir -p /sdcard/angle/screenshots
410```
411
412Then run the traces using ANGLE:
413```
414out/AndroidPerformance/angle_trace_tests --verbose --run-to-key-frame --screenshot-dir /sdcard/angle/screenshots --shard-timeout 1000000
415```
416
417And again with the native driver:
418```
419out/AndroidPerformance/angle_trace_tests --verbose --run-to-key-frame --screenshot-dir /sdcard/angle/screenshots --shard-timeout 1000000 --use-gl=native
420```
421
422It may take a few tries as some drivers will crash.  In that case, run the ones at the end that were stragglers, i.e.:
423```
424out/AndroidPerformance/angle_trace_tests --verbose --run-to-key-frame --screenshot-dir /sdcard/angle/screenshots --shard-timeout 1000000 --use-gl=native --gtest_filter="*words*:*world*:*worms*:*zenonia*:*zillow*:*zombie*"
425```
426
427Pull the screenshots:
428```
429adb pull /sdcard/angle/screenshots
430cd screenshots
431```
432
433And run the compare script:
434```
435python3 ../src/tests/restricted_traces/compare_trace_screenshots.py versus_native --trace-list-path ../src/tests/restricted_traces/
436```
437
438The script will print out results comparing ANGLE vs. native screenshots at different fuzz factors.
439It may also print out NA for missing screenshots:
440```
441...
442arknights angle_vulkan_arknights.png MISSING_EXT.png NA NA NA NA NA NA
443asphalt_8 angle_vulkan_asphalt_8.png angle_native_asphalt_8.png 641849 222157 116426 1701 82 22
444asphalt_9 angle_vulkan_asphalt_9.png angle_native_asphalt_9.png 17919 420 305 293 232 3
445...
446```
447# Upgrading existing traces
448
449With tracer updates sometimes we want to re-run tracing to upgrade the trace file format or to
450take advantage of new tracer improvements. The [`retrace_restricted_traces`](retrace_restricted_traces.py)
451script allows us to re-run tracing using [SwiftShader](https://swiftshader.googlesource.com/SwiftShader)
452on a desktop machine. As of writing we require re-tracing on a Windows machine because of size
453limitations with a Linux app window.
454
455## Part 1: Retrace it
456
457Upgrade your trace into a new directory called `retrace-wip`
458
459In this instance, we'll upgrade `octopath_traveler`
460```
461export TRACE_GN_PATH=out/Debug
462export TRACE_NAME=octopath_traveler
463src/tests/restricted_traces/retrace_restricted_traces.py upgrade $TRACE_GN_PATH retrace-wip -f $TRACE_NAME
464```
465
466## Part 2: Verify it
467
468Before we check in an upgraded trace, we want to put it through enough paces to
469ensure behaves the same or better.
470
471### Screenshots
472
473For screenshots, we want to verify all frames render correctly before and after Reset.
474
475So make two spots to gather the screenshots, and one to gather results:
476```
477mkdir retrace-wip/${TRACE_NAME}_before
478mkdir retrace-wip/${TRACE_NAME}_after
479mkdir retrace-wip/${TRACE_NAME}_compare
480```
481
482We need two loops to verify Reset, so you'll need to inspect how many frames
483are in the trace. In this case, `octopath_traveler` has 500 frames, so we need
4841000 screenshots. We use -1 as the screenshot frame so we get all images:
485```
486out/Debug/angle_trace_tests --gtest_filter=TraceTest.${TRACE_NAME} --use-angle=swiftshader --max-steps-performed 1000 --screenshot-dir retrace-wip/${TRACE_NAME}_before --screenshot-frame -1
487```
488
489Then move the new trace in and run it again:
490```
491mv src/tests/restricted_traces/${TRACE_NAME} retrace-wip/${TRACE_NAME}_orig
492cp -r retrace-wip/${TRACE_NAME} src/tests/restricted_traces
493autoninja -C out/Debug angle_trace_tests
494out/Debug/angle_trace_tests --gtest_filter=TraceTest.${TRACE_NAME} --use-angle=swiftshader --max-steps-performed 1000 --screenshot-dir retrace-wip/${TRACE_NAME}_after --screenshot-frame -1
495```
496
497After that, we have a script that will compare the before and after screenshots,
498saving the results:
499```
500src/tests/restricted_traces/compare_trace_screenshots.py versus_upgrade --before retrace-wip/${TRACE_NAME}_before --after retrace-wip/${TRACE_NAME}_after --outdir retrace-wip/${TRACE_NAME}_compare
501```
502
503If you have any diffs, they will pop out like this, and you need to investigate:
504```
505angle_vulkan_swiftshader_octopath_traveler_frame1.png 0
506angle_vulkan_swiftshader_octopath_traveler_frame10.png 0
507angle_vulkan_swiftshader_octopath_traveler_frame100.png 1.12185e+06
508Pixel diff detected!
509```
510
511### Performance
512
513We need to ensure we're getting the same frame times and memory usage.
514
515The easiest way to do that is on Android, which can show us GPU and CPU memory.
516
517First, restore the original trace, then build and install the most optimized build:
518```
519rm -r src/tests/restricted_traces/${TRACE_NAME}
520cp -r retrace-wip/${TRACE_NAME}_orig src/tests/restricted_traces/${TRACE_NAME}
521autoninja -C out/AndroidPerformance angle_trace_tests
522out/AndroidPerformance/angle_trace_tests --gtest_filter=TraceTest.${TRACE_NAME} --run-to-key-frame --no-warmup
523```
524
525Then run the `restricted_trace_perf.py` script to gather frame times and memory:
526```
527out/AndroidPerformance/restricted_trace_perf --fixedtime 10 --sleep 10 --power --output-tag ${TRACE_NAME}.before --loop-count 5 --renderer vulkan --filter ${TRACE_NAME}
528```
529
530You should get output like this:
531```
532trace                                    wall_time       gpu_time        cpu_time        gpu_power  cpu_power  gpu_mem_sustained    gpu_mem_peak    proc_mem_median      proc_mem_peak
533
534Starting run 1 with vulkan at 2023-08-17 16:26:29
535
536vulkan_octopath_traveler                 2.9650          0               3.8901000000    5183       5659       186837550            206241792       586976000            591528000
537
538Starting run 2 with vulkan at 2023-08-17 16:26:54
539
540vulkan_octopath_traveler                 3.0038          0               3.9452525714    5295       5128       186467084            205910016       584568000            589196000
541
542Starting run 3 with vulkan at 2023-08-17 16:27:18
543
544vulkan_octopath_traveler                 3.0061          0               3.9361028571    5203       5182       187197952            205262848       586596000            590324000
545
546Starting run 4 with vulkan at 2023-08-17 16:27:42
547
548vulkan_octopath_traveler                 2.9901          0               3.9330551429    5461       5165       194881803            197480448       585268000            588384000
549
550Starting run 5 with vulkan at 2023-08-17 16:28:05
551
552vulkan_octopath_traveler                 3.0749          0               3.9652568571    5197       5096       193443742            203177984       583636000            586380000
553```
554
555Bring in the upgraded trace, build and install the trace again:
556```
557rm -rf src/tests/restricted_traces/${TRACE_NAME}
558cp -r retrace-wip/${TRACE_NAME} src/tests/restricted_traces/${TRACE_NAME}
559autoninja -C out/AndroidPerformance angle_trace_tests
560out/AndroidPerformance/angle_trace_tests --gtest_filter=TraceTest.${TRACE_NAME} --run-to-key-frame --no-warmup
561```
562
563And collect performance data:
564```
565out/AndroidPerformance/restricted_trace_perf --fixedtime 10 --sleep 10 --power --output-tag ${TRACE_NAME}.after --loop-count 5 --renderer vulkan --filter ${TRACE_NAME}
566```
567
568Verify using a spreadsheet that the values are relatively the same.
569If you notice a marked difference, spend some time understanding it.
570For instance, you may see memory decrease due to fixed in the upgrade.
571
572## Part 3: Test the upgraded traces under an experimental prefix
573
574To test the trace on all platforms, we first upload them to a temporary CIPD
575path for testing. After a successful run on the CQ, we will then upload them
576to the main ANGLE prefix.
577
578To enable the experimental prefix, edit
579[`restricted_traces.json`](restricted_traces.json) to use a version
580number beginning with 'x'. For example:
581
582```
583  "traces": [
584    ...
585    "octopath_traveler x1",
586    ...
587```
588
589Then run:
590
591```
592src/tests/restricted_traces/sync_restricted_traces_to_cipd.py --filter ${TRACE_NAME}
593scripts/run_code_generation.py
594```
595
596After these commands complete succesfully, create and upload a CL as normal.
597
598Before running tests, you need to grant the bots access to your experimental
599CIPD files (substituting your account name):
600```
601cipd acl-edit experimental/google.com/$USERNAME -reader user:angle-try-builder@chops-service-accounts.iam.gserviceaccount.com
602cipd acl-edit experimental/google.com/$USERNAME -reader user:chromium-try-gpu-builder@chops-service-accounts.iam.gserviceaccount.com
603```
604
605You can verify it worked by running this command and seeing the bot added to readers:
606```
607cipd acl-list experimental/google.com/$USERNAME/angle/traces
608...
609Readers:
610  via "experimental/google.com/$USERNAME":
611    user:angle-try-builder@chops-service-accounts.iam.gserviceaccount.com
612    user:chromium-try-gpu-builder@chops-service-accounts.iam.gserviceaccount.com
613```
614
615Run CQ +1 Dry-Run. If you find a test regression, see the section below on
616diagnosing tracer errors. Otherwise proceed with the steps below.
617
618## Part 5: Upload the verified traces to CIPD under the stable prefix
619
620Now that you've validated the traces on the CQ, update
621[`restricted_traces.json`](restricted_traces.json) to remove the 'x' prefix
622and incrementing the version of the traces (skipping versions if you prefer)
623and then run:
624
625```
626src/tests/restricted_traces/sync_restricted_traces_to_cipd.py --filter ${TRACE_NAME}
627scripts/run_code_generation.py
628```
629
630Then create and upload a CL as normal. Congratulations, you've finished the
631trace upgrade!
632
633## Finding a trace's minimum requirements
634
635`retrace_restricted_traces.py` can be used to determine a trace's minimum
636extensions and GLES version. Run the command:
637
638```
639src/tests/restricted_traces/retrace_restricted_traces.py get_min_reqs $TRACE_GN_PATH [--traces "*"]
640```
641
642The script will run each listed trace multiple times so it can find the minimum
643required GLES version and each required extension. Finally it records that
644information to the trace's json file.
645
646By default it will run with SwiftShader. To make the script use your machine's
647native vulkan drivers, use the `--no-swiftshader` argument before the script's
648command:
649
650```
651src/tests/restricted_traces/retrace_restricted_traces.py --no-swiftshader get_min_reqs $TRACE_GN_PATH [--traces "*"]
652```
653
654If retracing an existing trace, any associated `addExtensionPrerequisite()` calls must be removed from `TracePerfTest.cpp` and
655the tracename.json file must be made writable.
656
657Traces are run with all extensions enabled by default. It may be useful to test with only a subset of extensions.
658This can be done by adding the `--request-extensions` argument to `angle_trace_tests`. Multiple extensions must be contained by quotation
659marks and only a single space can be used as a separator. To run with no extensions enabled, specify a null list -- `""`:
660
661```
662./out/Debug/angle_trace_tests --gtest_filter=*tracename --request-extensions "EXT_color_buffer_float GL_EXT_texture_filter_anisotropic"
663```
664  or
665```
666./out/Debug/angle_trace_tests --gtest_filter=*tracename --request-extensions ""
667```
668
669## Extended testing and full trace upgrades
670
671If you want to really drill down on trace differences, you might want to use the
672built in validation support, which serailizes the internal state of ANGLE.
673
674## Prep work: Back up existing traces
675
676This will save the original traces in a temporary folder if you need to revert to the prior trace format:
677
678```
679src/tests/restricted_traces/retrace_restricted_traces.py backup "*"
680```
681
682*Note: on Linux, remove the command `py` prefix to the Python scripts.*
683
684This will save the traces to `./retrace-backups`. At any time you can revert the trace files by running:
685
686```
687src/tests/restricted_traces/retrace_restricted_traces.py restore "*"
688```
689
690## Part 1: Upgrading Sanity Check with T-Rex
691
692First we'll retrace a single app to verify the workflow is intact. Please
693ensure you replace the specified variables with paths that work on your
694configuration and checkout:
695
696### Step 1/3: Capture T-Rex with Validation
697
698```
699export TRACE_GN_PATH=out/Debug
700export TRACE_NAME=trex_200
701src/tests/restricted_traces/retrace_restricted_traces.py upgrade $TRACE_GN_PATH retrace-wip -f $TRACE_NAME --validation --limit 3
702```
703
704The `--validation` flag will turn on additional validation checks in the
705trace. The `--limit 3` flag forces a maximum of 3 frames of tracing so the
706test will run more quickly. The trace will end up in the `retrace-wip`
707folder.
708
709### Step 2/3: Validate T-Rex
710
711The command below will update your copy of the trace, rebuild, the run the
712test suite with validation enabled:
713
714```
715src/tests/restricted_traces/retrace_restricted_traces.py validate $TRACE_GN_PATH retrace-wip $TRACE_NAME
716```
717
718If the trace failed validation, see the section below on diagnosing tracer
719errors. Otherwise proceed with the steps below.
720
721### Step 3/3: Restore the Canonical T-Rex Trace
722
723```
724src/tests/restricted_traces/retrace_restricted_traces.py restore $TRACE_NAME
725```
726
727## Part 2: Do a limited trace upgrade with validation enabled
728
729### Step 1/3: Upgrade all traces with a limit of 3 frames
730
731```
732src/tests/restricted_traces/retrace_restricted_traces.py upgrade $TRACE_GN_PATH retrace-wip --validation --limit 3  --no-overwrite
733```
734
735If this process gets interrupted, re-run the upgrade command. The
736`--no-overwrite` argument will ensure it will complete eventually.
737
738If any traces failed to upgrade, see the section below on diagnosing tracer
739errors. Otherwise proceed with the steps below.
740
741### Step 2/3: Validate all upgraded traces
742
743```
744src/tests/restricted_traces/retrace_restricted_traces.py validate $TRACE_GN_PATH retrace-wip "*"
745```
746
747If any traces failed validation, see the section below on diagnosing tracer
748errors.
749
750### Step 3/3: Restore all traces
751
752```
753src/tests/restricted_traces/retrace_restricted_traces.py restore "*"
754```
755
756## Part 3: Do the full trace upgrade
757
758```
759rm -rf retrace-wip
760src/tests/restricted_traces/retrace_restricted_traces.py upgrade $TRACE_GN_PATH retrace-wip --no-overwrite
761```
762
763If this process gets interrupted, re-run the upgrade command. The
764`--no-overwrite` argument will ensure it will complete eventually.
765
766If any traces failed to upgrade, see the section below on diagnosing tracer
767errors.
768
769Otherwise, use the steps above to [verify and upgrade your traces](#part-3-test-the-upgraded-traces-under-an-experimental-prefix).
770
771
772# Diagnosing and fixing tracer errors
773
774## Debugging a crash or GLES error
775
776Ensure you're building ANGLE in Debug. Then look in the retrace script output
777to find the exact command line and environment variables the script uses to
778produce the failure. For example:
779
780```
781INFO:root:ANGLE_CAPTURE_LABEL=trex_200 ANGLE_CAPTURE_OUT_DIR=C:\src\angle\retrace-wip\trex_200 ANGLE_CAPTURE_FRAME_START=2 ANGLE_CAPTURE_FRAME_END=4 ANGLE_CAPTURE_VALIDATION=1 ANGLE_FEATURE_OVERRIDES_ENABLED=allocateNonZeroMemory:forceInitShaderVariables out\Debug\angle_trace_tests.exe --gtest_filter=TraceTest.trex_200 --use-angle=swiftshader --max-steps-performed 3 --retrace-mode
782```
783
784Once you can reproduce the issue you can use a debugger or other standard
785debugging processes to find the root cause and a fix.
786
787## Debugging a serialization difference
788
789If you encouter a serialization mismatch in the retrace, you can find the
790complete serialization output by looking in the retrace script output. ANGLE
791saves the complete serialization file contents on any mismatch. You can
792inspect and diff these files in a text editor to help diagnose what objects
793are faulty.
794
795If the mismatch is with a Buffer or Texture object content, you can manually
796edit the `frame_capture_utils.cpp` file to force some or all of the objects
797to serialize their entire contents. This can help show what kind of pixel or
798data differences might be causing the issue. For example, change this line:
799
800```
801json->addBlob("data", dataPtr->data(), dataPtr->size());
802```
803
804to
805
806```
807json->addBlobWithMax("data", dataPtr->data(), dataPtr->size(), 1000000);
808```
809
810Note: in the future, we might make this option exposed via an envioronment
811variable, or even allow serialization of entire data blocks in text-encoded
812form that could be decoded to separate files.
813
814If you still can't determine what code might be causing the state difference,
815we can insert finer-grained serialization checkpoints to "bisect" where the
816coding mismatch is happening. It is not possible to force checkpoints after
817every GLES call, because serialization and validation is so prohibitively
818expensive. ANGLE instead has feature in the tracer that allows us to
819precisely control where the tracer inserts and validates the checkpoints, by
820using a boolean expression language.
821
822The retrace script command `--validation-expr` allows us to specify a C-like
823expression that determines when to add serialization checkpoints. For
824example, we can specify this validation expression:
825
826```
827((frame == 2) && (call < 1189) && (call > 1100) && ((call % 5) == 0))
828```
829
830Using this expression will insert a serialization checkpoint in the second
831frame, on every 5th captured call, and when the captured call count is
832between 1101 and 1188. Here the `call` keyword denotes the call counter,
833which resets to 1 every frame, and increments by 1 with every captured GLES
834API call. The `frame` keyword denotes the frame counter, which starts at 1
835and increments by 1 every captured frame. The expression syntax supports all
836common C boolean operators.
837
838By finding a starting and ending frame range, and narrowing this range through
839experimentation, you can pinpoint the exact call that triggers the
840serialization mismatch, and then diagnose and fix the root cause. In some
841cases you can use RenderDoc or other frame debugging tools to inspect
842resource states before/after the bad call once you have found it.
843
844See also: [`http://crrev.com/c/3136094`](http://crrev.com/c/3136094)
845
846## Debugging a pixel test failure without a serialization mismatch
847
848Sometimes you manage to complete validation and upload, just to find a golden
849image pixel difference that manifests in some trace configurations. These
850problems can be harder to root cause. For instance, some configurations may
851render undefined pixels that are in practice well-defined on most GLES
852implementations.
853
854The pixel differences can also be a product of mismatched state even if the
855trace validation says all states are matched. Because ANGLE's GLES state
856serialization is incomplete, it can help to check the state serialization
857logic and add missing features as necessary.
858