]> git.cworth.org Git - apitrace/blob - README.markdown
Tweak regression testing section.
[apitrace] / README.markdown
1 About **apitrace**
2 ==================
3
4 **apitrace** consists of a set of tools to:
5
6 * trace OpenGL, OpenGL ES, D3D9, D3D8, D3D7, and DDRAW APIs calls to a file;
7
8 * retrace OpenGL and OpenGL ES calls from a file;
9
10 * inspect OpenGL state at any call while retracing;
11
12 * visualize and edit trace files.
13
14
15 Basic usage
16 ===========
17
18 Run the application you want to trace as
19
20     apitrace trace --api API /path/to/application [args...]
21
22 and it will generate a trace named `application.trace` in the current
23 directory.  You can specify the written trace filename by passing the
24 `--output` command line option.
25
26 Problems while tracing (e.g, if the application uses calls/parameters
27 unsupported by apitrace) will be reported via stderr output on Unices.  On
28 Windows you'll need to run
29 [DebugView](http://technet.microsoft.com/en-us/sysinternals/bb896647) to view
30 these messages.
31
32 View the trace with
33
34     apitrace dump application.trace
35
36 Replay an OpenGL trace with
37
38     glretrace application.trace
39
40 Pass the `-sb` option to use a single buffered visual.  Pass `--help` to
41 glretrace for more options.
42
43 Start the GUI as
44
45     qapitrace application.trace
46
47
48 Advanced command line usage
49 ===========================
50
51
52 Call sets
53 ---------
54
55 Several tools take `CALLSET` arguments, e.g:
56
57     apitrace dump --calls CALLSET foo.trace
58     glretrace -S CALLSET foo.trace
59
60 The call syntax is very flexible. Here are a few examples:
61
62  * `4`             one call
63
64  * `1,2,4,5`       set of calls
65
66  * `"1 2 4 5"`     set of calls (commas are optional and can be replaced with whitespace)
67
68  * `1-100/2`       calls 1, 3, 5, ...,  99
69
70  * `1-1000/draw`   all draw calls between 1 and 1000
71
72  * `1-1000/fbo`    all fbo changes between calls 1 and 1000
73
74  * `frame`         all calls at end of frames
75
76  * `@foo.txt`      read call numbers from `foo.txt`, using the same syntax as above
77
78
79
80 Tracing manually
81 ----------------
82
83 ### Linux ###
84
85 Run the application you want to trace as
86
87      LD_PRELOAD=/path/to/apitrace/wrappers/glxtrace.so /path/to/application
88
89 and it will generate a trace named `application.trace` in the current
90 directory.  You can specify the written trace filename by setting the
91 `TRACE_FILE` environment variable before running.
92
93 The `LD_PRELOAD` mechanism should work with most applications.  There are some
94 applications, e.g., Unigine Heaven, which global function pointers with the
95 same name as GL entrypoints, living in a shared object that wasn't linked with
96 `-Bsymbolic` flag, so relocations to those globals function pointers get
97 overwritten with the address to our wrapper library, and the application will
98 segfault when trying to write to them.  For these applications it is possible
99 to trace by using `glxtrace.so` as an ordinary `libGL.so` and injecting into
100 `LD_LIBRARY_PATH`:
101
102     ln -s glxtrace.so wrappers/libGL.so
103     ln -s glxtrace.so wrappers/libGL.so.1
104     ln -s glxtrace.so wrappers/libGL.so.1.2
105     export LD_LIBRARY_PATH=/path/to/apitrace/wrappers:$LD_LIBRARY_PATH
106     export TRACE_LIBGL=/path/to/real/libGL.so.1
107     /path/to/application
108
109 See the `ld.so` man page for more information about `LD_PRELOAD` and
110 `LD_LIBRARY_PATH` environment flags.
111
112 To trace the application inside gdb, invoke gdb as:
113
114     gdb --ex 'set exec-wrapper env LD_PRELOAD=/path/to/glxtrace.so' --args /path/to/application
115
116 ### Mac OS X ###
117
118 Run the application you want to trace as
119
120     DYLD_LIBRARY_PATH=/path/to/apitrace/wrappers /path/to/application
121
122 Note that although Mac OS X has an `LD_PRELOAD` equivalent,
123 `DYLD_INSERT_LIBRARIES`, it is mostly useless because it only works with
124 `DYLD_FORCE_FLAT_NAMESPACE=1` which breaks most applications.  See the `dyld` man
125 page for more details about these environment flags.
126
127 ### Windows ###
128
129 Copy `opengl32.dll`, `d3d8.dll`, or `d3d9.dll` from the wrappers directory
130 to the directory with the application you want to trace.  Then run the
131 application.
132
133 You can specify the written trace filename by setting the `TRACE_FILE`
134 environment variable before running.
135
136
137 Emitting annotations to the trace
138 ---------------------------------
139
140 From OpenGL applications you can embed annotations in the trace file through the
141 [`GL_GREMEDY_string_marker`](http://www.opengl.org/registry/specs/GREMEDY/string_marker.txt)
142 and
143 [`GL_GREMEDY_frame_terminator`](http://www.opengl.org/registry/specs/GREMEDY/frame_terminator.txt)
144 GL extensions.
145
146 **apitrace** will advertise and intercept these GL extensions independently of
147 the GL implementation.  So all you have to do is to use these extensions when
148 available.
149
150 For example, if you use [GLEW](http://glew.sourceforge.net/) to dynamically
151 detect and use GL extensions, you could easily accomplish this by doing:
152
153     void foo() {
154     
155       if (GLEW_GREMEDY_string_marker) {
156         glStringMarkerGREMEDY(0, __FUNCTION__ ": enter");
157       }
158       
159       ...
160       
161       if (GLEW_GREMEDY_string_marker) {
162         glStringMarkerGREMEDY(0, __FUNCTION__ ": leave");
163       }
164       
165     }
166
167 This has the added advantage of working equally well with gDEBugger.
168
169
170 From OpenGL ES applications you can embed annotations in the trace file through the
171 [`GL_EXT_debug_marker`](http://www.khronos.org/registry/gles/extensions/EXT/EXT_debug_marker.txt)
172 extension.
173
174
175 For Direct3D applications you can follow the same procedure used for 
176 [instrumenting an application for PIX](http://technet.microsoft.com/en-us/query/ee417250)
177
178
179 Dump GL state at a particular call
180 ----------------------------------
181
182 You can get a dump of the bound GL state at call 12345 by doing:
183
184     glretrace -D 12345 application.trace > 12345.json
185
186 This is precisely the mechanism the GUI obtains its own state.
187
188 You can compare two state dumps by doing:
189
190     apitrace diff-state 12345.json 67890.json
191
192
193 Comparing two traces side by side
194 ---------------------------------
195
196     apitrace diff trace1.trace trace2.trace
197
198 This works only on Unices, and it will truncate the traces due to performance
199 limitations.
200
201
202 Recording a video with FFmpeg
203 -----------------------------
204
205 You can make a video of the output by doing
206
207     glretrace -s - application.trace \
208     | ffmpeg -r 30 -f image2pipe -vcodec ppm -i pipe: -vcodec mpeg4 -y output.mp4
209
210
211 Triming a trace
212 ---------------
213
214 You can make a smaller trace by doing:
215
216     apitrace trim --callset 100-1000 -o trimed.trace applicated.trace
217
218 If you need precise control over which calls to trim you can specify the
219 individual call numbers a plaintext file, as described in the 'Call sets'
220 section above.
221
222
223 Advanced usage for OpenGL implementors
224 ======================================
225
226 There are several advanced usage examples meant for OpenGL implementors.
227
228
229 Regression testing
230 ------------------
231
232 These are the steps to create a regression test-suite around **apitrace**:
233
234 * obtain a trace
235
236 * obtain reference snapshots, by doing on a reference system:
237
238         mkdir /path/to/reference/snapshots/
239         glretrace -s /path/to/reference/snapshots/ application.trace
240
241 * prune the snapshots which are not interesting
242
243 * to do a regression test, do:
244
245         glretrace -c /path/to/reference/snapshots/ application.trace
246
247   Alternatively, for a HTML summary, use `apitrace diff-images`:
248
249         glretrace -s /path/to/test/snapshots/ application.trace
250         apitrace diff-images --output summary.html /path/to/reference/snapshots/ /path/to/test/snapshots/
251
252
253 Automated git-bisection
254 -----------------------
255
256 With tracecheck.py it is possible to automate git bisect and pinpoint the
257 commit responsible for a regression.
258
259 Below is an example of using tracecheck.py to bisect a regression in the
260 Mesa-based Intel 965 driver.  But the procedure could be applied to any GL
261 driver hosted on a git repository.
262
263 First, create a build script, named build-script.sh, containing:
264
265     #!/bin/sh
266     set -e
267     export PATH=/usr/lib/ccache:$PATH
268     export CFLAGS='-g'
269     export CXXFLAGS='-g'
270     ./autogen.sh --disable-egl --disable-gallium --disable-glut --disable-glu --disable-glw --with-dri-drivers=i965
271     make clean
272     make "$@"
273
274 It is important that builds are both robust, and efficient.  Due to broken
275 dependency discovery in Mesa's makefile system, it was necessary invoke `make
276 clean` in every iteration step.  `ccache` should be installed to avoid
277 recompiling unchanged source files.
278
279 Then do:
280
281     cd /path/to/mesa
282     export LIBGL_DEBUG=verbose
283     export LD_LIBRARY_PATH=$PWD/lib
284     export LIBGL_DRIVERS_DIR=$PWD/lib
285     git bisect start \
286         6491e9593d5cbc5644eb02593a2f562447efdcbb 71acbb54f49089b03d3498b6f88c1681d3f649ac \
287         -- src/mesa/drivers/dri/intel src/mesa/drivers/dri/i965/
288     git bisect run /path/to/tracecheck.py \
289         --precision-threshold 8.0 \
290         --build /path/to/build-script.sh \
291         --gl-renderer '.*Mesa.*Intel.*' \
292         --retrace=/path/to/glretrace \
293         -c /path/to/reference/snapshots/ \
294         topogun-1.06-orc-84k.trace
295
296 The trace-check.py script will skip automatically when there are build
297 failures.
298
299 The `--gl-renderer` option will also cause a commit to be skipped if the
300 `GL_RENDERER` is unexpected (e.g., when a software renderer or another GL
301 driver is unintentionally loaded due to missing symbol in the DRI driver, or
302 another runtime fault).
303
304
305 Side by side retracing
306 ----------------------
307
308 In order to determine which draw call a regression first manifests one could
309 generate snapshots for every draw call, using the `-S` option.  That is, however,
310 very inefficient for big traces with many draw calls.
311
312 A faster approach is to run both the bad and a good GL driver side-by-side.
313 The latter can be either a previously known good build of the GL driver, or a
314 reference software renderer.
315
316 This can be achieved with retracediff.py script, which invokes glretrace with
317 different environments, allowing to choose the desired GL driver by
318 manipulating variables such as `LD_LIBRARY_PATH` or `LIBGL_DRIVERS_DIR`.
319
320 For example:
321
322     ./scripts/retracediff.py \
323         --ref-env LD_LIBRARY_PATH=/path/to/reference/GL/implementation \
324         -r ./glretrace \
325         --diff-prefix=/path/to/output/diffs \
326         application.trace
327
328
329
330 Links
331 =====
332
333 About **apitrace**:
334
335 * [Official mailing list](http://lists.freedesktop.org/mailman/listinfo/apitrace)
336
337 * [Zack Rusin's blog introducing the GUI](http://zrusin.blogspot.com/2011/04/apitrace.html)
338
339 * [Jose's Fonseca blog introducing the tool](http://jrfonseca.blogspot.com/2008/07/tracing-d3d-applications.html)
340
341
342 Direct3D
343 --------
344
345 Open-source:
346
347 * [Proxy DLL](http://www.mikoweb.eu/index.php?node=21)
348
349   * [Intercept Calls to DirectX with a Proxy DLL](http://www.codeguru.com/cpp/g-m/directx/directx8/article.php/c11453/)
350
351 * [Direct3D 9 API Interceptor](http://graphics.stanford.edu/~mdfisher/D3D9Interceptor.html)
352
353 Closed-source:
354
355 * [Microsoft PIX](http://msdn.microsoft.com/en-us/library/ee417062.aspx)
356
357   * [D3DSpy](http://doc.51windows.net/Directx9_SDK/?url=/directx9_sdk/graphics/programmingguide/TutorialsAndSamplesAndToolsAndTips/Tools/D3DSpy.htm): the predecessor of PIX
358
359 * [AMD GPU PerfStudio](http://developer.amd.com/gpu/PerfStudio/pages/APITraceWindow.aspx)
360
361
362 OpenGL
363 ------
364
365 Open-source:
366
367 * [BuGLe](http://www.opengl.org/sdk/tools/BuGLe/)
368
369 * [GLIntercept](http://code.google.com/p/glintercept/)
370
371 * [tracy](https://gitorious.org/tracy): OpenGL ES and OpenVG trace, retrace, and state inspection
372
373 Closed-source:
374
375 * [gDEBugger](http://www.gremedy.com/products.php)
376
377 * [glslDevil](http://cumbia.informatik.uni-stuttgart.de/glsldevil/index.html)
378
379 * [AMD GPU PerfStudio](http://developer.amd.com/gpu/PerfStudio/pages/APITraceWindow.aspx)
380