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