1#!/bin/bash
2
3# This script is to be run on the KVM host, inside the container
4
5set -ex
6
7export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
8export PYTHONPATH=/usr/local/lib/python3.7/site-packages
9
10benchmark_loops=0
11perfetto_loops=10
12wait_after_frame=
13
14debug=no
15trace=
16command=""
17prep_snapshot=
18while [ -n "$1" ] ; do
19    case "$1" in
20
21        --trace|-t)
22          trace="$2"
23          shift
24          ;;
25
26        --benchmark|-b)
27          command="$command benchmark=$2"
28          benchmark_loops=$2
29          shift
30          ;;
31
32        --perfetto|-p)
33          command="$command perfetto=$2"
34          perfetto_loops=$2
35          shift
36          ;;
37
38  	--wait-after-frame|-w)
39          command="$command wait-after-frame=1"
40          wait_after_frame="--wait-after-frame"
41	  ;;
42
43        --snapshot|-s)
44          command="$command record-frame=1"
45          prep_snapshot=yes
46          ;;
47
48        --debug)
49          debug=yes
50          ;;
51        *)
52          echo "Unknown option '$1' given, run with option --help to see supported options"
53          exit
54          ;;
55    esac
56    shift
57done
58
59if [ "x$trace" = "x" ]; then
60    echo "No trace given in run script, you must pass is as free parameter to the docker call"
61    exit 1
62fi
63
64pushd /mesa
65mkdir -p build
66
67if [ ! -f build/build.ninja ]; then
68   meson build/ \
69      -Dprefix=/usr/local \
70      -Ddri-drivers=i965 \
71      -Dgallium-drivers=swrast,virgl,radeonsi,iris \
72      -Dbuildtype=debugoptimized \
73      -Dllvm=true \
74      -Dglx=dri \
75      -Degl=true \
76      -Dgbm=false \
77      -Dgallium-vdpau=false \
78      -Dgallium-va=false \
79      -Dvulkan-drivers=[] \
80      -Dvalgrind=false \
81      -Dtracing=perfetto \
82      -Dlibdir=lib
83else
84   pushd build
85   meson configure \
86      -Dprefix=/usr/local \
87      -Ddri-drivers=i965 \
88      -Dgallium-drivers=swrast,virgl,radeonsi,iris \
89      -Dbuildtype=debugoptimized \
90      -Dllvm=true \
91      -Dglx=dri \
92      -Degl=true \
93      -Dgbm=false \
94      -Dgallium-vdpau=false \
95      -Dgallium-va=false \
96      -Dvulkan-drivers=[] \
97      -Dvalgrind=false \
98      -Dtracing=perfetto \
99      -Dlibdir=lib
100   popd
101fi
102ninja -C build/ install
103popd
104
105pushd /virglrenderer
106mkdir -p build
107
108if [ ! -f build/build.ninja ]; then
109   meson build/ \
110      -Dprefix=/usr/local \
111      -Dlibdir=lib \
112      -Dplatforms=egl \
113      -Dminigbm_allocation=true \
114      -Dtracing=perfetto \
115      -Dbuildtype=debugoptimized
116else
117   pushd build
118   meson configure \
119      -Dprefix=/usr/local \
120      -Dlibdir=lib \
121      -Dplatforms=egl \
122      -Dminigbm_allocation=true \
123      -Dtracing=perfetto \
124      -Dbuildtype=debugoptimized
125   popd
126fi
127ninja -C build/ install
128popd
129
130# Crosvm needs to link with minigbm, due to incompatible ABI
131export LD_PRELOAD=/usr/lib/libminigbm.so.1.0.0
132
133export PATH="/apitrace/build:$PATH"
134export PATH="/waffle/build/bin:$PATH"
135export LD_LIBRARY_PATH="/waffle/build/lib:$LD_LIBRARY_PATH"
136export LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH"
137export LD_LIBRARY_PATH="/usr/local/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH"
138
139trace_no_ext=${trace%.*}
140datadir="/traces-db/${trace_no_ext}-out"
141
142echo "Host:"
143wflinfo --platform surfaceless_egl --api gles2
144
145export EGL_PLATFORM="surfaceless"
146export WAFFLE_PLATFORM="surfaceless_egl"
147export DISPLAY=
148
149if [ "x$benchmark_loops" != "x0" ]; then
150   echo "Measuring rendering times:"
151   eglretrace --benchmark --loop=$benchmark_loops --headless "/traces-db/${trace}"
152fi
153
154# To keep Perfetto happy
155echo 0 > /sys/kernel/debug/tracing/tracing_on
156echo nop > /sys/kernel/debug/tracing/current_tracer
157
158if [  "x$perfetto_loops" != "x" ] ; then
159   echo "perfetto_loops parameter not given"
160fi
161
162if [ "x$perfetto_loops" != "x0" ]; then
163    /perfetto/out/dist/traced &
164    /perfetto/out/dist/traced_probes &
165    sleep 1
166    /gfx-pps/build/src/gpu/producer-gpu &
167    sleep 1
168    /perfetto/out/dist/perfetto --txt -c /usr/local/perfetto-host.cfg -o /tmp/perfetto-host.trace --detach=mykey
169    sleep 1
170
171    echo "Replaying for Perfetto:"
172    eglretrace --benchmark --singlethread --loop=$perfetto_loops $wait_after_frame --headless "/traces-db/${trace}"
173fi
174
175
176iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
177echo 1 > /proc/sys/net/ipv4/ip_forward
178
179
180# store name of trace to be replayed so the guest can obtain the name
181echo $trace_no_ext > /traces-db/current_trace
182echo $command > /traces-db/command
183
184trace_base=$(basename $trace_no_ext)
185guest_perf="$datadir/${trace_base}-guest.perfetto"
186host_perf="$datadir/${trace_base}-host.perfetto"
187summary_perf="$datadir/${trace_base}-summary.perfetto"
188
189mkdir -p $datadir
190
191# work around Crosvm crashing because of errors in context
192# handling, could be a problem with the kernel and/or with virglrenderer
193export MESA_EXTENSION_OVERRIDE="-GL_ARB_buffer_storage -GL_EXT_buffer_storage"
194
195if [ "x$debug" = "xyes" ]; then
196   export EGL_DEBUG=debug
197fi
198
199
200if [ -e /wd/crosvm-debug.cmd ]; then
201    gdb -x /wd/crosvm-debug.cmd
202else
203    crosvm run \
204   --gpu gles=false\
205   -m 4096 \
206   -c 4 \
207   -i /rootfs.cpio.gz \
208   --shared-dir "/usr/local:local:type=fs" \
209   --shared-dir "/waffle:waffle-tag:type=fs" \
210   --shared-dir "/apitrace:apitrace-tag:type=fs" \
211   --shared-dir "/traces-db:traces-db-tag:type=fs" \
212   --shared-dir "/perfetto:perfetto-tag:type=fs" \
213   --host_ip 192.168.200.1 --netmask 255.255.255.0 --mac AA:BB:CC:00:00:12 \
214   -p "root=/dev/ram0 rdinit=/init.sh ip=192.168.200.2::192.168.200.1:255.255.255.0:crosvm:eth0 nohz=off clocksource=kvm-clock" \
215   /vmlinux
216fi
217
218rm -f /traces-db/current_trace
219rm -f /traces-db/command
220
221if [ "x$perfetto_loops" != "x0" ]; then
222    /perfetto/out/dist/perfetto --attach=mykey --stop
223
224    mv /tmp/perfetto-host.trace "$host_perf"
225    chmod a+rw "$host_perf"
226
227    # sometimes one of these processes seems to crash or exit before, so
228    # check whether it is still
229    kill `pidof producer-gpu` || echo "producer-gpu was not running (anymore)"
230    kill `pidof traced_probes` || echo "traced_probes was not running (anymore)"
231    kill `pidof traced` || echo "traced was not running (anymore="
232
233    /usr/local/merge_traces.py "$host_perf" "$guest_perf" "$summary_perf"
234fi
235
236sleep 1
237