blob: 3fdcda567998ede748ed403182eb0026a1dc57d8 [file] [log] [blame]
José Fonseca0b217312011-06-30 14:32:57 +01001About **apitrace**
2==================
3
4**apitrace** consists of a set of tools to:
5
José Fonsecac7cc2722011-11-29 23:25:13 +00006* trace OpenGL, OpenGL ES, D3D9, D3D8, D3D7, and DDRAW APIs calls to a file;
José Fonseca0b217312011-06-30 14:32:57 +01007
José Fonsecac7cc2722011-11-29 23:25:13 +00008* retrace OpenGL and OpenGL ES calls from a file;
José Fonseca0b217312011-06-30 14:32:57 +01009
José Fonseca892cad62011-09-23 08:24:28 +010010* inspect OpenGL state at any call while retracing;
11
12* visualize and edit trace files.
José Fonseca0b217312011-06-30 14:32:57 +010013
14
José Fonseca6d617002011-09-06 01:17:48 +010015Basic usage
16===========
José Fonseca0b217312011-06-30 14:32:57 +010017
José Fonseca5104ef42012-02-29 09:15:29 +000018To obtain apitrace either [download the latest
19binaries](https://github.com/apitrace/apitrace/downloads) for your platform if
20available, or follow the (build instructions)[INSTALL.markdown] to build it
21yourself.
22
José Fonseca0b217312011-06-30 14:32:57 +010023Run the application you want to trace as
24
José Fonseca155fc782012-02-27 10:37:32 +000025 apitrace trace --api API /path/to/application [args...]
José Fonseca0b217312011-06-30 14:32:57 +010026
27and it will generate a trace named `application.trace` in the current
José Fonseca155fc782012-02-27 10:37:32 +000028directory. You can specify the written trace filename by passing the
29`--output` command line option.
José Fonseca0b217312011-06-30 14:32:57 +010030
José Fonsecac4e76a92012-02-29 09:00:05 +000031Problems while tracing (e.g, if the application uses calls/parameters
32unsupported by apitrace) will be reported via stderr output on Unices. On
33Windows you'll need to run
34[DebugView](http://technet.microsoft.com/en-us/sysinternals/bb896647) to view
35these messages.
36
José Fonseca0b217312011-06-30 14:32:57 +010037View the trace with
38
José Fonseca155fc782012-02-27 10:37:32 +000039 apitrace dump application.trace
José Fonseca0b217312011-06-30 14:32:57 +010040
José Fonsecac7cc2722011-11-29 23:25:13 +000041Replay an OpenGL trace with
José Fonseca0b217312011-06-30 14:32:57 +010042
José Fonsecac7cc2722011-11-29 23:25:13 +000043 glretrace application.trace
José Fonseca0b217312011-06-30 14:32:57 +010044
45Pass the `-sb` option to use a single buffered visual. Pass `--help` to
46glretrace for more options.
47
48Start the GUI as
49
José Fonsecac7cc2722011-11-29 23:25:13 +000050 qapitrace application.trace
José Fonseca0b217312011-06-30 14:32:57 +010051
José Fonseca0b217312011-06-30 14:32:57 +010052
José Fonseca6d617002011-09-06 01:17:48 +010053Advanced command line usage
54===========================
55
56
José Fonseca225193d2012-01-26 19:08:32 +000057Call sets
58---------
59
60Several tools take `CALLSET` arguments, e.g:
61
62 apitrace dump --calls CALLSET foo.trace
63 glretrace -S CALLSET foo.trace
64
65The call syntax is very flexible. Here are a few examples:
66
67 * `4` one call
68
69 * `1,2,4,5` set of calls
70
71 * `"1 2 4 5"` set of calls (commas are optional and can be replaced with whitespace)
72
73 * `1-100/2` calls 1, 3, 5, ..., 99
74
75 * `1-1000/draw` all draw calls between 1 and 1000
76
77 * `1-1000/fbo` all fbo changes between calls 1 and 1000
78
79 * `frame` all calls at end of frames
80
81 * `@foo.txt` read call numbers from `foo.txt`, using the same syntax as above
82
83
84
José Fonseca7edf24a2011-11-03 12:30:18 +000085Tracing manually
86----------------
87
88### Linux ###
89
90Run the application you want to trace as
91
José Fonsecadab19cd2011-11-03 14:32:45 +000092 LD_PRELOAD=/path/to/apitrace/wrappers/glxtrace.so /path/to/application
José Fonseca7edf24a2011-11-03 12:30:18 +000093
94and it will generate a trace named `application.trace` in the current
95directory. You can specify the written trace filename by setting the
96`TRACE_FILE` environment variable before running.
97
98The `LD_PRELOAD` mechanism should work with most applications. There are some
99applications, e.g., Unigine Heaven, which global function pointers with the
100same 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
102overwritten with the address to our wrapper library, and the application will
103segfault when trying to write to them. For these applications it is possible
104to trace by using `glxtrace.so` as an ordinary `libGL.so` and injecting into
105`LD_LIBRARY_PATH`:
106
José Fonsecadab19cd2011-11-03 14:32:45 +0000107 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
José Fonseca7edf24a2011-11-03 12:30:18 +0000111 export TRACE_LIBGL=/path/to/real/libGL.so.1
112 /path/to/application
113
114See the `ld.so` man page for more information about `LD_PRELOAD` and
115`LD_LIBRARY_PATH` environment flags.
116
José Fonsecac5b4a942012-01-18 16:15:30 +0000117To trace the application inside gdb, invoke gdb as:
118
119 gdb --ex 'set exec-wrapper env LD_PRELOAD=/path/to/glxtrace.so' --args /path/to/application
120
José Fonseca7edf24a2011-11-03 12:30:18 +0000121### Mac OS X ###
122
123Run the application you want to trace as
124
125 DYLD_LIBRARY_PATH=/path/to/apitrace/wrappers /path/to/application
126
127Note 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
130page for more details about these environment flags.
131
José Fonseca155fc782012-02-27 10:37:32 +0000132### Windows ###
133
134Copy `opengl32.dll`, `d3d8.dll`, or `d3d9.dll` from the wrappers directory
135to the directory with the application you want to trace. Then run the
136application.
137
138You can specify the written trace filename by setting the `TRACE_FILE`
139environment variable before running.
140
José Fonseca7edf24a2011-11-03 12:30:18 +0000141
José Fonsecaf028a8f2012-02-15 23:33:35 +0000142Emitting annotations to the trace
143---------------------------------
José Fonsecae62cabc2011-09-18 10:31:04 +0100144
José Fonsecaf028a8f2012-02-15 23:33:35 +0000145From OpenGL applications you can embed annotations in the trace file through the
José Fonsecae62cabc2011-09-18 10:31:04 +0100146[`GL_GREMEDY_string_marker`](http://www.opengl.org/registry/specs/GREMEDY/string_marker.txt)
147and
148[`GL_GREMEDY_frame_terminator`](http://www.opengl.org/registry/specs/GREMEDY/frame_terminator.txt)
149GL extensions.
150
José Fonseca892cad62011-09-23 08:24:28 +0100151**apitrace** will advertise and intercept these GL extensions independently of
José Fonsecae62cabc2011-09-18 10:31:04 +0100152the GL implementation. So all you have to do is to use these extensions when
153available.
154
155For example, if you use [GLEW](http://glew.sourceforge.net/) to dynamically
156detect and use GL extensions, you could easily accomplish this by doing:
157
158 void foo() {
159
160 if (GLEW_GREMEDY_string_marker) {
161 glStringMarkerGREMEDY(0, __FUNCTION__ ": enter");
162 }
163
164 ...
165
166 if (GLEW_GREMEDY_string_marker) {
167 glStringMarkerGREMEDY(0, __FUNCTION__ ": leave");
168 }
169
170 }
171
172This has the added advantage of working equally well with gDEBugger.
173
174
José Fonsecaf028a8f2012-02-15 23:33:35 +0000175From 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)
177extension.
178
179
180For Direct3D applications you can follow the same procedure used for
181[instrumenting an application for PIX](http://technet.microsoft.com/en-us/query/ee417250)
182
183
José Fonseca6d617002011-09-06 01:17:48 +0100184Dump GL state at a particular call
185----------------------------------
186
187You can get a dump of the bound GL state at call 12345 by doing:
188
José Fonsecac7cc2722011-11-29 23:25:13 +0000189 glretrace -D 12345 application.trace > 12345.json
José Fonseca6d617002011-09-06 01:17:48 +0100190
191This is precisely the mechanism the GUI obtains its own state.
192
José Fonsecac7cc2722011-11-29 23:25:13 +0000193You can compare two state dumps by doing:
José Fonseca6d617002011-09-06 01:17:48 +0100194
José Fonsecac7cc2722011-11-29 23:25:13 +0000195 apitrace diff-state 12345.json 67890.json
José Fonseca6d617002011-09-06 01:17:48 +0100196
197
198Comparing two traces side by side
199---------------------------------
200
José Fonseca73694fa2011-11-06 09:01:12 +0000201 apitrace diff trace1.trace trace2.trace
José Fonseca6d617002011-09-06 01:17:48 +0100202
203This works only on Unices, and it will truncate the traces due to performance
204limitations.
205
206
207Recording a video with FFmpeg
208-----------------------------
209
210You can make a video of the output by doing
211
José Fonsecac7cc2722011-11-29 23:25:13 +0000212 glretrace -s - application.trace \
José Fonseca6d617002011-09-06 01:17:48 +0100213 | ffmpeg -r 30 -f image2pipe -vcodec ppm -i pipe: -vcodec mpeg4 -y output.mp4
214
215
José Fonseca7b1b0a22012-02-15 07:18:22 +0000216Triming a trace
217---------------
218
219You can make a smaller trace by doing:
220
221 apitrace trim --callset 100-1000 -o trimed.trace applicated.trace
222
223If you need precise control over which calls to trim you can specify the
224individual call numbers a plaintext file, as described in the 'Call sets'
225section above.
226
227
José Fonseca6d617002011-09-06 01:17:48 +0100228Advanced usage for OpenGL implementors
229======================================
230
José Fonsecaff427582011-09-18 10:49:13 +0100231There are several advanced usage examples meant for OpenGL implementors.
José Fonseca6d617002011-09-06 01:17:48 +0100232
233
234Regression testing
235------------------
236
José Fonseca892cad62011-09-23 08:24:28 +0100237These are the steps to create a regression test-suite around **apitrace**:
José Fonseca6d617002011-09-06 01:17:48 +0100238
239* obtain a trace
240
José Fonsecac582fc62012-02-29 09:06:53 +0000241* obtain reference snapshots, by doing on a reference system:
José Fonseca6d617002011-09-06 01:17:48 +0100242
José Fonsecac582fc62012-02-29 09:06:53 +0000243 mkdir /path/to/reference/snapshots/
José Fonsecac7cc2722011-11-29 23:25:13 +0000244 glretrace -s /path/to/reference/snapshots/ application.trace
José Fonseca6d617002011-09-06 01:17:48 +0100245
José Fonseca6d617002011-09-06 01:17:48 +0100246* prune the snapshots which are not interesting
247
248* to do a regression test, do:
249
José Fonsecac7cc2722011-11-29 23:25:13 +0000250 glretrace -c /path/to/reference/snapshots/ application.trace
José Fonseca6d617002011-09-06 01:17:48 +0100251
José Fonsecac7cc2722011-11-29 23:25:13 +0000252 Alternatively, for a HTML summary, use `apitrace diff-images`:
José Fonseca6d617002011-09-06 01:17:48 +0100253
José Fonsecac582fc62012-02-29 09:06:53 +0000254 glretrace -s /path/to/test/snapshots/ application.trace
255 apitrace diff-images --output summary.html /path/to/reference/snapshots/ /path/to/test/snapshots/
José Fonseca6d617002011-09-06 01:17:48 +0100256
257
258Automated git-bisection
259-----------------------
260
261With tracecheck.py it is possible to automate git bisect and pinpoint the
262commit responsible for a regression.
263
264Below is an example of using tracecheck.py to bisect a regression in the
265Mesa-based Intel 965 driver. But the procedure could be applied to any GL
266driver hosted on a git repository.
267
268First, create a build script, named build-script.sh, containing:
269
270 #!/bin/sh
271 set -e
272 export PATH=/usr/lib/ccache:$PATH
273 export CFLAGS='-g'
274 export CXXFLAGS='-g'
275 ./autogen.sh --disable-egl --disable-gallium --disable-glut --disable-glu --disable-glw --with-dri-drivers=i965
276 make clean
277 make "$@"
278
279It is important that builds are both robust, and efficient. Due to broken
280dependency discovery in Mesa's makefile system, it was necessary invoke `make
281clean` in every iteration step. `ccache` should be installed to avoid
282recompiling unchanged source files.
283
284Then do:
285
286 cd /path/to/mesa
287 export LIBGL_DEBUG=verbose
288 export LD_LIBRARY_PATH=$PWD/lib
289 export LIBGL_DRIVERS_DIR=$PWD/lib
290 git bisect start \
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
300
301The trace-check.py script will skip automatically when there are build
302failures.
303
304The `--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
José Fonsecaff427582011-09-18 10:49:13 +0100306driver is unintentionally loaded due to missing symbol in the DRI driver, or
José Fonseca6d617002011-09-06 01:17:48 +0100307another runtime fault).
308
309
310Side by side retracing
311----------------------
312
313In order to determine which draw call a regression first manifests one could
José Fonseca05ba4192011-09-17 21:18:57 +0100314generate snapshots for every draw call, using the `-S` option. That is, however,
José Fonseca6d617002011-09-06 01:17:48 +0100315very inefficient for big traces with many draw calls.
316
317A faster approach is to run both the bad and a good GL driver side-by-side.
José Fonsecaff427582011-09-18 10:49:13 +0100318The latter can be either a previously known good build of the GL driver, or a
José Fonseca6d617002011-09-06 01:17:48 +0100319reference software renderer.
320
321This can be achieved with retracediff.py script, which invokes glretrace with
322different environments, allowing to choose the desired GL driver by
323manipulating variables such as `LD_LIBRARY_PATH` or `LIBGL_DRIVERS_DIR`.
324
325For example:
326
327 ./scripts/retracediff.py \
328 --ref-env LD_LIBRARY_PATH=/path/to/reference/GL/implementation \
329 -r ./glretrace \
330 --diff-prefix=/path/to/output/diffs \
331 application.trace
332
333
334
José Fonseca0b217312011-06-30 14:32:57 +0100335Links
336=====
337
338About **apitrace**:
339
Zack Rusind029d5f2011-08-22 21:50:08 -0400340* [Official mailing list](http://lists.freedesktop.org/mailman/listinfo/apitrace)
341
José Fonseca0b217312011-06-30 14:32:57 +0100342* [Zack Rusin's blog introducing the GUI](http://zrusin.blogspot.com/2011/04/apitrace.html)
343
344* [Jose's Fonseca blog introducing the tool](http://jrfonseca.blogspot.com/2008/07/tracing-d3d-applications.html)
345
346
347Direct3D
348--------
349
350Open-source:
351
352* [Proxy DLL](http://www.mikoweb.eu/index.php?node=21)
353
354 * [Intercept Calls to DirectX with a Proxy DLL](http://www.codeguru.com/cpp/g-m/directx/directx8/article.php/c11453/)
355
356* [Direct3D 9 API Interceptor](http://graphics.stanford.edu/~mdfisher/D3D9Interceptor.html)
357
358Closed-source:
359
360* [Microsoft PIX](http://msdn.microsoft.com/en-us/library/ee417062.aspx)
361
362 * [D3DSpy](http://doc.51windows.net/Directx9_SDK/?url=/directx9_sdk/graphics/programmingguide/TutorialsAndSamplesAndToolsAndTips/Tools/D3DSpy.htm): the predecessor of PIX
363
364* [AMD GPU PerfStudio](http://developer.amd.com/gpu/PerfStudio/pages/APITraceWindow.aspx)
365
366
367OpenGL
368------
369
370Open-source:
371
372* [BuGLe](http://www.opengl.org/sdk/tools/BuGLe/)
373
374* [GLIntercept](http://code.google.com/p/glintercept/)
375
376* [tracy](https://gitorious.org/tracy): OpenGL ES and OpenVG trace, retrace, and state inspection
377
378Closed-source:
379
380* [gDEBugger](http://www.gremedy.com/products.php)
381
382* [glslDevil](http://cumbia.informatik.uni-stuttgart.de/glsldevil/index.html)
383
384* [AMD GPU PerfStudio](http://developer.amd.com/gpu/PerfStudio/pages/APITraceWindow.aspx)
385