4 **apitrace** consists of a set of tools to:
6 * trace OpenGL, OpenGL ES, D3D9, D3D8, D3D7, and DDRAW APIs calls to a file;
8 * retrace OpenGL and OpenGL ES calls from a file;
10 * inspect OpenGL state at any call while retracing;
12 * visualize and edit trace files.
18 To obtain apitrace either [download the latest
19 binaries](https://github.com/apitrace/apitrace/downloads) for your platform if
20 available, or follow the (build instructions)[INSTALL.markdown] to build it
23 Run the application you want to trace as
25 apitrace trace --api API /path/to/application [args...]
27 and it will generate a trace named `application.trace` in the current
28 directory. You can specify the written trace filename by passing the
29 `--output` command line option.
31 Problems while tracing (e.g, if the application uses calls/parameters
32 unsupported by apitrace) will be reported via stderr output on Unices. On
33 Windows you'll need to run
34 [DebugView](http://technet.microsoft.com/en-us/sysinternals/bb896647) to view
39 apitrace dump application.trace
41 Replay an OpenGL trace with
43 glretrace application.trace
45 Pass the `-sb` option to use a single buffered visual. Pass `--help` to
46 glretrace for more options.
50 qapitrace application.trace
53 Advanced command line usage
54 ===========================
60 Several tools take `CALLSET` arguments, e.g:
62 apitrace dump --calls CALLSET foo.trace
63 glretrace -S CALLSET foo.trace
65 The call syntax is very flexible. Here are a few examples:
69 * `1,2,4,5` set of calls
71 * `"1 2 4 5"` set of calls (commas are optional and can be replaced with whitespace)
73 * `1-100/2` calls 1, 3, 5, ..., 99
75 * `1-1000/draw` all draw calls between 1 and 1000
77 * `1-1000/fbo` all fbo changes between calls 1 and 1000
79 * `frame` all calls at end of frames
81 * `@foo.txt` read call numbers from `foo.txt`, using the same syntax as above
90 Run the application you want to trace as
92 LD_PRELOAD=/path/to/apitrace/wrappers/glxtrace.so /path/to/application
94 and it will generate a trace named `application.trace` in the current
95 directory. You can specify the written trace filename by setting the
96 `TRACE_FILE` environment variable before running.
98 The `LD_PRELOAD` mechanism should work with most applications. There are some
99 applications, e.g., Unigine Heaven, which global function pointers with the
100 same name as GL entrypoints, living in a shared object that wasn't linked with
101 `-Bsymbolic` flag, so relocations to those globals function pointers get
102 overwritten with the address to our wrapper library, and the application will
103 segfault when trying to write to them. For these applications it is possible
104 to trace by using `glxtrace.so` as an ordinary `libGL.so` and injecting into
107 ln -s glxtrace.so wrappers/libGL.so
108 ln -s glxtrace.so wrappers/libGL.so.1
109 ln -s glxtrace.so wrappers/libGL.so.1.2
110 export LD_LIBRARY_PATH=/path/to/apitrace/wrappers:$LD_LIBRARY_PATH
111 export TRACE_LIBGL=/path/to/real/libGL.so.1
114 See the `ld.so` man page for more information about `LD_PRELOAD` and
115 `LD_LIBRARY_PATH` environment flags.
117 To trace the application inside gdb, invoke gdb as:
119 gdb --ex 'set exec-wrapper env LD_PRELOAD=/path/to/glxtrace.so' --args /path/to/application
123 Run the application you want to trace as
125 DYLD_LIBRARY_PATH=/path/to/apitrace/wrappers /path/to/application
127 Note that although Mac OS X has an `LD_PRELOAD` equivalent,
128 `DYLD_INSERT_LIBRARIES`, it is mostly useless because it only works with
129 `DYLD_FORCE_FLAT_NAMESPACE=1` which breaks most applications. See the `dyld` man
130 page for more details about these environment flags.
134 Copy `opengl32.dll`, `d3d8.dll`, or `d3d9.dll` from the wrappers directory
135 to the directory with the application you want to trace. Then run the
138 You can specify the written trace filename by setting the `TRACE_FILE`
139 environment variable before running.
142 Emitting annotations to the trace
143 ---------------------------------
145 From OpenGL applications you can embed annotations in the trace file through the
146 [`GL_GREMEDY_string_marker`](http://www.opengl.org/registry/specs/GREMEDY/string_marker.txt)
148 [`GL_GREMEDY_frame_terminator`](http://www.opengl.org/registry/specs/GREMEDY/frame_terminator.txt)
151 **apitrace** will advertise and intercept these GL extensions independently of
152 the GL implementation. So all you have to do is to use these extensions when
155 For example, if you use [GLEW](http://glew.sourceforge.net/) to dynamically
156 detect and use GL extensions, you could easily accomplish this by doing:
160 if (GLEW_GREMEDY_string_marker) {
161 glStringMarkerGREMEDY(0, __FUNCTION__ ": enter");
166 if (GLEW_GREMEDY_string_marker) {
167 glStringMarkerGREMEDY(0, __FUNCTION__ ": leave");
172 This has the added advantage of working equally well with gDEBugger.
175 From OpenGL ES applications you can embed annotations in the trace file through the
176 [`GL_EXT_debug_marker`](http://www.khronos.org/registry/gles/extensions/EXT/EXT_debug_marker.txt)
180 For Direct3D applications you can follow the same procedure used for
181 [instrumenting an application for PIX](http://technet.microsoft.com/en-us/query/ee417250)
184 Dump GL state at a particular call
185 ----------------------------------
187 You can get a dump of the bound GL state at call 12345 by doing:
189 glretrace -D 12345 application.trace > 12345.json
191 This is precisely the mechanism the GUI obtains its own state.
193 You can compare two state dumps by doing:
195 apitrace diff-state 12345.json 67890.json
198 Comparing two traces side by side
199 ---------------------------------
201 apitrace diff trace1.trace trace2.trace
203 This works only on Unices, and it will truncate the traces due to performance
207 Recording a video with FFmpeg
208 -----------------------------
210 You can make a video of the output by doing
212 glretrace -s - application.trace \
213 | ffmpeg -r 30 -f image2pipe -vcodec ppm -i pipe: -vcodec mpeg4 -y output.mp4
219 You can make a smaller trace by doing:
221 apitrace trim --callset 100-1000 -o trimed.trace applicated.trace
223 If you need precise control over which calls to trim you can specify the
224 individual call numbers a plaintext file, as described in the 'Call sets'
228 Advanced usage for OpenGL implementors
229 ======================================
231 There are several advanced usage examples meant for OpenGL implementors.
237 These are the steps to create a regression test-suite around **apitrace**:
241 * obtain reference snapshots, by doing on a reference system:
243 mkdir /path/to/reference/snapshots/
244 glretrace -s /path/to/reference/snapshots/ application.trace
246 * prune the snapshots which are not interesting
248 * to do a regression test, do:
250 glretrace -c /path/to/reference/snapshots/ application.trace
252 Alternatively, for a HTML summary, use `apitrace diff-images`:
254 glretrace -s /path/to/test/snapshots/ application.trace
255 apitrace diff-images --output summary.html /path/to/reference/snapshots/ /path/to/test/snapshots/
258 Automated git-bisection
259 -----------------------
261 With tracecheck.py it is possible to automate git bisect and pinpoint the
262 commit responsible for a regression.
264 Below is an example of using tracecheck.py to bisect a regression in the
265 Mesa-based Intel 965 driver. But the procedure could be applied to any GL
266 driver hosted on a git repository.
268 First, create a build script, named build-script.sh, containing:
272 export PATH=/usr/lib/ccache:$PATH
275 ./autogen.sh --disable-egl --disable-gallium --disable-glut --disable-glu --disable-glw --with-dri-drivers=i965
279 It is important that builds are both robust, and efficient. Due to broken
280 dependency discovery in Mesa's makefile system, it was necessary invoke `make
281 clean` in every iteration step. `ccache` should be installed to avoid
282 recompiling unchanged source files.
287 export LIBGL_DEBUG=verbose
288 export LD_LIBRARY_PATH=$PWD/lib
289 export LIBGL_DRIVERS_DIR=$PWD/lib
291 6491e9593d5cbc5644eb02593a2f562447efdcbb 71acbb54f49089b03d3498b6f88c1681d3f649ac \
292 -- src/mesa/drivers/dri/intel src/mesa/drivers/dri/i965/
293 git bisect run /path/to/tracecheck.py \
294 --precision-threshold 8.0 \
295 --build /path/to/build-script.sh \
296 --gl-renderer '.*Mesa.*Intel.*' \
297 --retrace=/path/to/glretrace \
298 -c /path/to/reference/snapshots/ \
299 topogun-1.06-orc-84k.trace
301 The trace-check.py script will skip automatically when there are build
304 The `--gl-renderer` option will also cause a commit to be skipped if the
305 `GL_RENDERER` is unexpected (e.g., when a software renderer or another GL
306 driver is unintentionally loaded due to missing symbol in the DRI driver, or
307 another runtime fault).
310 Side by side retracing
311 ----------------------
313 In order to determine which draw call a regression first manifests one could
314 generate snapshots for every draw call, using the `-S` option. That is, however,
315 very inefficient for big traces with many draw calls.
317 A faster approach is to run both the bad and a good GL driver side-by-side.
318 The latter can be either a previously known good build of the GL driver, or a
319 reference software renderer.
321 This can be achieved with retracediff.py script, which invokes glretrace with
322 different environments, allowing to choose the desired GL driver by
323 manipulating variables such as `LD_LIBRARY_PATH` or `LIBGL_DRIVERS_DIR`.
327 ./scripts/retracediff.py \
328 --ref-env LD_LIBRARY_PATH=/path/to/reference/GL/implementation \
330 --diff-prefix=/path/to/output/diffs \
340 * [Official mailing list](http://lists.freedesktop.org/mailman/listinfo/apitrace)
342 * [Zack Rusin's blog introducing the GUI](http://zrusin.blogspot.com/2011/04/apitrace.html)
344 * [Jose's Fonseca blog introducing the tool](http://jrfonseca.blogspot.com/2008/07/tracing-d3d-applications.html)
352 * [Proxy DLL](http://www.mikoweb.eu/index.php?node=21)
354 * [Intercept Calls to DirectX with a Proxy DLL](http://www.codeguru.com/cpp/g-m/directx/directx8/article.php/c11453/)
356 * [Direct3D 9 API Interceptor](http://graphics.stanford.edu/~mdfisher/D3D9Interceptor.html)
360 * [Microsoft PIX](http://msdn.microsoft.com/en-us/library/ee417062.aspx)
362 * [D3DSpy](http://doc.51windows.net/Directx9_SDK/?url=/directx9_sdk/graphics/programmingguide/TutorialsAndSamplesAndToolsAndTips/Tools/D3DSpy.htm): the predecessor of PIX
364 * [AMD GPU PerfStudio](http://developer.amd.com/gpu/PerfStudio/pages/APITraceWindow.aspx)
372 * [BuGLe](http://www.opengl.org/sdk/tools/BuGLe/)
374 * [GLIntercept](http://code.google.com/p/glintercept/)
376 * [tracy](https://gitorious.org/tracy): OpenGL ES and OpenVG trace, retrace, and state inspection
380 * [gDEBugger](http://www.gremedy.com/products.php)
382 * [glslDevil](http://cumbia.informatik.uni-stuttgart.de/glsldevil/index.html)
384 * [AMD GPU PerfStudio](http://developer.amd.com/gpu/PerfStudio/pages/APITraceWindow.aspx)