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