blob: 287d73c239f133bbca8276fde86563d4e3949fff [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é Fonsecaf9c5da22012-04-30 22:59:40 +01006* trace OpenGL, OpenGL ES, Direct3D, and DirectDraw 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
José Fonsecaab8b9df2012-10-21 11:08:36 +010014See the [apitrace homepage](http://apitrace.github.com/) for more details.
15
José Fonseca0b217312011-06-30 14:32:57 +010016
José Fonseca45afa262012-03-09 18:22:28 +000017Obtaining **apitrace**
18======================
José Fonseca0b217312011-06-30 14:32:57 +010019
José Fonseca5104ef42012-02-29 09:15:29 +000020To obtain apitrace either [download the latest
21binaries](https://github.com/apitrace/apitrace/downloads) for your platform if
José Fonseca9cc74f62012-03-10 09:41:46 +000022available, or follow the instructions in INSTALL.markdown to build it yourself.
23On 64bits Linux and Windows platforms you'll need apitrace binaries that match
24the architecture (32bits or 64bits) of the application being traced.
José Fonseca5104ef42012-02-29 09:15:29 +000025
José Fonseca45afa262012-03-09 18:22:28 +000026
27Basic usage
28===========
29
José Fonseca0b217312011-06-30 14:32:57 +010030Run the application you want to trace as
31
José Fonseca155fc782012-02-27 10:37:32 +000032 apitrace trace --api API /path/to/application [args...]
José Fonseca0b217312011-06-30 14:32:57 +010033
34and it will generate a trace named `application.trace` in the current
José Fonseca155fc782012-02-27 10:37:32 +000035directory. You can specify the written trace filename by passing the
36`--output` command line option.
José Fonseca0b217312011-06-30 14:32:57 +010037
José Fonsecac4e76a92012-02-29 09:00:05 +000038Problems while tracing (e.g, if the application uses calls/parameters
39unsupported by apitrace) will be reported via stderr output on Unices. On
40Windows you'll need to run
41[DebugView](http://technet.microsoft.com/en-us/sysinternals/bb896647) to view
42these messages.
43
José Fonsecaa4f17e72012-02-29 09:37:40 +000044Follow the "Tracing manually" instructions below if you cannot obtain a trace.
45
José Fonseca0b217312011-06-30 14:32:57 +010046View the trace with
47
José Fonseca155fc782012-02-27 10:37:32 +000048 apitrace dump application.trace
José Fonseca0b217312011-06-30 14:32:57 +010049
José Fonsecac7cc2722011-11-29 23:25:13 +000050Replay an OpenGL trace with
José Fonseca0b217312011-06-30 14:32:57 +010051
José Fonsecac7cc2722011-11-29 23:25:13 +000052 glretrace application.trace
José Fonseca0b217312011-06-30 14:32:57 +010053
54Pass the `-sb` option to use a single buffered visual. Pass `--help` to
55glretrace for more options.
56
José Fonseca45afa262012-03-09 18:22:28 +000057
58Basic GUI usage
59===============
60
José Fonseca0b217312011-06-30 14:32:57 +010061Start the GUI as
62
José Fonsecac7cc2722011-11-29 23:25:13 +000063 qapitrace application.trace
José Fonseca0b217312011-06-30 14:32:57 +010064
José Fonseca45afa262012-03-09 18:22:28 +000065You can also tell the GUI to go directly to a specific call
66
67 qapitrace application.trace 12345
68
José Fonseca0b217312011-06-30 14:32:57 +010069
José Fonseca6d617002011-09-06 01:17:48 +010070Advanced command line usage
71===========================
72
73
José Fonseca225193d2012-01-26 19:08:32 +000074Call sets
75---------
76
77Several tools take `CALLSET` arguments, e.g:
78
79 apitrace dump --calls CALLSET foo.trace
80 glretrace -S CALLSET foo.trace
81
82The call syntax is very flexible. Here are a few examples:
83
84 * `4` one call
85
86 * `1,2,4,5` set of calls
87
88 * `"1 2 4 5"` set of calls (commas are optional and can be replaced with whitespace)
89
90 * `1-100/2` calls 1, 3, 5, ..., 99
91
92 * `1-1000/draw` all draw calls between 1 and 1000
93
94 * `1-1000/fbo` all fbo changes between calls 1 and 1000
95
96 * `frame` all calls at end of frames
97
98 * `@foo.txt` read call numbers from `foo.txt`, using the same syntax as above
99
100
101
José Fonseca7edf24a2011-11-03 12:30:18 +0000102Tracing manually
103----------------
104
105### Linux ###
106
José Fonsecaa4f17e72012-02-29 09:37:40 +0000107On 64 bits systems, you'll need to determine ether the application is 64 bits
108or 32 bits. This can be done by doing
109
110 file /path/to/application
111
112But beware of wrapper shell scripts -- what matters is the architecture of the
113main process.
114
José Fonseca7edf24a2011-11-03 12:30:18 +0000115Run the application you want to trace as
116
José Fonsecadab19cd2011-11-03 14:32:45 +0000117 LD_PRELOAD=/path/to/apitrace/wrappers/glxtrace.so /path/to/application
José Fonseca7edf24a2011-11-03 12:30:18 +0000118
119and it will generate a trace named `application.trace` in the current
120directory. You can specify the written trace filename by setting the
121`TRACE_FILE` environment variable before running.
122
José Fonseca4b9e58e2012-10-18 13:25:45 +0100123The `LD_PRELOAD` mechanism should work with the majority applications. There
124are some applications (e.g., Unigine Heaven, Android GPU emulator, etc.), that
125have global function pointers with the same name as GL entrypoints, living in a
126shared object that wasn't linked with `-Bsymbolic` flag, so relocations to
127those globals function pointers get overwritten with the address to our wrapper
128library, and the application will segfault when trying to write to them. For
129these applications it is possible to trace by using `glxtrace.so` as an
130ordinary `libGL.so` and injecting it via `LD_LIBRARY_PATH`:
José Fonseca7edf24a2011-11-03 12:30:18 +0000131
José Fonsecadab19cd2011-11-03 14:32:45 +0000132 ln -s glxtrace.so wrappers/libGL.so
133 ln -s glxtrace.so wrappers/libGL.so.1
134 ln -s glxtrace.so wrappers/libGL.so.1.2
135 export LD_LIBRARY_PATH=/path/to/apitrace/wrappers:$LD_LIBRARY_PATH
José Fonseca7edf24a2011-11-03 12:30:18 +0000136 export TRACE_LIBGL=/path/to/real/libGL.so.1
137 /path/to/application
138
José Fonseca4b9e58e2012-10-18 13:25:45 +0100139If you are an application developer, you can avoid this either by linking with
140`-Bsymbolic` flag, or by using some unique prefix for your function pointers.
141
José Fonseca7edf24a2011-11-03 12:30:18 +0000142See the `ld.so` man page for more information about `LD_PRELOAD` and
143`LD_LIBRARY_PATH` environment flags.
144
José Fonsecac5b4a942012-01-18 16:15:30 +0000145To trace the application inside gdb, invoke gdb as:
146
147 gdb --ex 'set exec-wrapper env LD_PRELOAD=/path/to/glxtrace.so' --args /path/to/application
148
Imre Deakb4c584d2012-03-30 15:44:39 +0300149### Android ###
150
151The following instructions should work at least for Android Ice Scream
152Sandwitch:
153
154For standalone applications the instructions above for Linux should
155work. To trace applications started from within the Android VM process
José Fonseca0a64dc22012-08-13 13:36:31 +0100156(`app_process` aka zygote) you'll have to wrap this process and enable
Imre Deakb4c584d2012-03-30 15:44:39 +0300157tracing dynamically for the application to be traced.
158
159- Wrapping the android main VM process:
160
José Fonseca0a64dc22012-08-13 13:36:31 +0100161 In the Android root /init.rc add the `LD_PRELOAD` setting to zygote's
Imre Deakb4c584d2012-03-30 15:44:39 +0300162 environment in the 'service zygote' section:
163
José Fonseca0a64dc22012-08-13 13:36:31 +0100164 service zygote ...
165 setenv LD_PRELOAD /data/egltrace.so
166 ...
Imre Deakb4c584d2012-03-30 15:44:39 +0300167
168 Note that ICS will overwrite the /init.rc during each boot with the
169 version in the recovery image. So you'll have to change the file in
170 your ICS source tree, rebuild and reflash the device.
171 Rebuilding/reflashing only the recovery image should be sufficient.
172
Imre Deakb4c584d2012-03-30 15:44:39 +0300173- Copy egltrace.so to /data
174
175 On the host:
Imre Deakb4c584d2012-03-30 15:44:39 +0300176
José Fonseca0a64dc22012-08-13 13:36:31 +0100177 adb push /path/to/apitrace/build/wrappers/egltrace.so /data
Imre Deakb4c584d2012-03-30 15:44:39 +0300178
179- Adjust file permissions to store the trace file:
180
181 By default egltrace.so will store the trace in
José Fonseca0a64dc22012-08-13 13:36:31 +0100182 `/data/app_process.trace`. For this to work for applications running
183 with a uid other than 0, you have to allow writes to the `/data`
Imre Deakb4c584d2012-03-30 15:44:39 +0300184 directory on the device:
185
José Fonseca0a64dc22012-08-13 13:36:31 +0100186 chmod 0777 /data
Imre Deakb4c584d2012-03-30 15:44:39 +0300187
188- Enable tracing for a specific process name:
189
190 To trace for example the Settings application:
Imre Deakb4c584d2012-03-30 15:44:39 +0300191
José Fonseca0a64dc22012-08-13 13:36:31 +0100192 setprop debug.apitrace.procname com.android.settings
Imre Deakb4c584d2012-03-30 15:44:39 +0300193
José Fonseca0a64dc22012-08-13 13:36:31 +0100194 In general this name will match what `ps` reports.
Imre Deakb4c584d2012-03-30 15:44:39 +0300195
196- Start the application:
197
198 If the application was already running, for example due to ICS's way
199 of pre-starting the apps, you might have to kill the application
200 first:
201
José Fonseca0a64dc22012-08-13 13:36:31 +0100202 kill <pid of app>
Imre Deakb4c584d2012-03-30 15:44:39 +0300203
204 Launch the application for example from the application menu.
205
José Fonseca7edf24a2011-11-03 12:30:18 +0000206### Mac OS X ###
207
208Run the application you want to trace as
209
210 DYLD_LIBRARY_PATH=/path/to/apitrace/wrappers /path/to/application
211
212Note that although Mac OS X has an `LD_PRELOAD` equivalent,
213`DYLD_INSERT_LIBRARIES`, it is mostly useless because it only works with
214`DYLD_FORCE_FLAT_NAMESPACE=1` which breaks most applications. See the `dyld` man
215page for more details about these environment flags.
216
José Fonseca155fc782012-02-27 10:37:32 +0000217### Windows ###
218
José Fonsecaa4f17e72012-02-29 09:37:40 +0000219When tracing third-party applications, you can identify the target
220application's main executable, either by:
221
222* right clicking on the application's icon in the _Start Menu_, choose
223 _Properties_, and see the _Target_ field;
224
225* or by starting the application, run Windows Task Manager (taskmgr.exe), right
226 click on the application name in the _Applications_ tab, choose _Go To Process_,
227 note the highlighted _Image Name_, and search it on `C:\Program Files` or
228 `C:\Program Files (x86)`.
229
230On 64 bits Windows, you'll need to determine ether the application is a 64 bits
231or 32 bits. 32 bits applications will have a `*32` suffix in the _Image Name_
232column of the _Processes_ tab of _Windows Task Manager_ window.
233
234Copy the appropriate `opengl32.dll`, `d3d8.dll`, or `d3d9.dll` from the
235wrappers directory to the directory with the application you want to trace.
236Then run the application as usual.
José Fonseca155fc782012-02-27 10:37:32 +0000237
238You can specify the written trace filename by setting the `TRACE_FILE`
239environment variable before running.
240
José Fonseca7edf24a2011-11-03 12:30:18 +0000241
José Fonsecaf028a8f2012-02-15 23:33:35 +0000242Emitting annotations to the trace
243---------------------------------
José Fonsecae62cabc2011-09-18 10:31:04 +0100244
José Fonsecaf028a8f2012-02-15 23:33:35 +0000245From OpenGL applications you can embed annotations in the trace file through the
José Fonsecae62cabc2011-09-18 10:31:04 +0100246[`GL_GREMEDY_string_marker`](http://www.opengl.org/registry/specs/GREMEDY/string_marker.txt)
247and
248[`GL_GREMEDY_frame_terminator`](http://www.opengl.org/registry/specs/GREMEDY/frame_terminator.txt)
249GL extensions.
250
José Fonseca892cad62011-09-23 08:24:28 +0100251**apitrace** will advertise and intercept these GL extensions independently of
José Fonsecae62cabc2011-09-18 10:31:04 +0100252the GL implementation. So all you have to do is to use these extensions when
253available.
254
255For example, if you use [GLEW](http://glew.sourceforge.net/) to dynamically
256detect and use GL extensions, you could easily accomplish this by doing:
257
258 void foo() {
259
260 if (GLEW_GREMEDY_string_marker) {
261 glStringMarkerGREMEDY(0, __FUNCTION__ ": enter");
262 }
263
264 ...
265
266 if (GLEW_GREMEDY_string_marker) {
267 glStringMarkerGREMEDY(0, __FUNCTION__ ": leave");
268 }
269
270 }
271
272This has the added advantage of working equally well with gDEBugger.
273
274
José Fonsecaf028a8f2012-02-15 23:33:35 +0000275From OpenGL ES applications you can embed annotations in the trace file through the
276[`GL_EXT_debug_marker`](http://www.khronos.org/registry/gles/extensions/EXT/EXT_debug_marker.txt)
277extension.
278
279
280For Direct3D applications you can follow the same procedure used for
281[instrumenting an application for PIX](http://technet.microsoft.com/en-us/query/ee417250)
282
283
José Fonseca6d617002011-09-06 01:17:48 +0100284Dump GL state at a particular call
285----------------------------------
286
287You can get a dump of the bound GL state at call 12345 by doing:
288
José Fonsecac7cc2722011-11-29 23:25:13 +0000289 glretrace -D 12345 application.trace > 12345.json
José Fonseca6d617002011-09-06 01:17:48 +0100290
291This is precisely the mechanism the GUI obtains its own state.
292
José Fonsecac7cc2722011-11-29 23:25:13 +0000293You can compare two state dumps by doing:
José Fonseca6d617002011-09-06 01:17:48 +0100294
José Fonsecac7cc2722011-11-29 23:25:13 +0000295 apitrace diff-state 12345.json 67890.json
José Fonseca6d617002011-09-06 01:17:48 +0100296
297
298Comparing two traces side by side
299---------------------------------
300
José Fonseca73694fa2011-11-06 09:01:12 +0000301 apitrace diff trace1.trace trace2.trace
José Fonseca6d617002011-09-06 01:17:48 +0100302
303This works only on Unices, and it will truncate the traces due to performance
304limitations.
305
306
307Recording a video with FFmpeg
308-----------------------------
309
310You can make a video of the output by doing
311
José Fonsecac7cc2722011-11-29 23:25:13 +0000312 glretrace -s - application.trace \
José Fonseca6d617002011-09-06 01:17:48 +0100313 | ffmpeg -r 30 -f image2pipe -vcodec ppm -i pipe: -vcodec mpeg4 -y output.mp4
314
315
James Benton5b670de2012-08-06 18:04:56 +0100316Trimming a trace
317----------------
José Fonseca7b1b0a22012-02-15 07:18:22 +0000318
319You can make a smaller trace by doing:
320
321 apitrace trim --callset 100-1000 -o trimed.trace applicated.trace
322
323If you need precise control over which calls to trim you can specify the
324individual call numbers a plaintext file, as described in the 'Call sets'
325section above.
326
327
James Benton5b670de2012-08-06 18:04:56 +0100328Profiling a trace
329-----------------
330
331You can perform gpu and cpu profiling with the command line options:
332
333 * `-pgpu` record gpu times for frames and draw calls.
334
335 * `-pcpu` record cpu times for frames and draw calls.
336
337 * `-ppd` record pixels drawn for each draw call.
338
339The results from this can then be read by hand or analysed with a script.
340
James Bentonfdeaa542012-08-09 16:46:43 +0100341`scripts/profileshader.py` will read the profile results and format them into a
James Benton5b670de2012-08-06 18:04:56 +0100342table which displays profiling results per shader.
343
344For example, to record all profiling data and utilise the per shader script:
James Bentonfdeaa542012-08-09 16:46:43 +0100345
James Benton5b670de2012-08-06 18:04:56 +0100346 ./glretrace -pgpu -pcpu -ppd foo.trace | ./scripts/profileshader.py
347
348
José Fonseca6d617002011-09-06 01:17:48 +0100349Advanced usage for OpenGL implementors
350======================================
351
José Fonsecaff427582011-09-18 10:49:13 +0100352There are several advanced usage examples meant for OpenGL implementors.
José Fonseca6d617002011-09-06 01:17:48 +0100353
354
355Regression testing
356------------------
357
José Fonseca892cad62011-09-23 08:24:28 +0100358These are the steps to create a regression test-suite around **apitrace**:
José Fonseca6d617002011-09-06 01:17:48 +0100359
360* obtain a trace
361
José Fonsecac582fc62012-02-29 09:06:53 +0000362* obtain reference snapshots, by doing on a reference system:
José Fonseca6d617002011-09-06 01:17:48 +0100363
José Fonsecac582fc62012-02-29 09:06:53 +0000364 mkdir /path/to/reference/snapshots/
José Fonsecac7cc2722011-11-29 23:25:13 +0000365 glretrace -s /path/to/reference/snapshots/ application.trace
José Fonseca6d617002011-09-06 01:17:48 +0100366
José Fonseca6d617002011-09-06 01:17:48 +0100367* prune the snapshots which are not interesting
368
369* to do a regression test, do:
370
José Fonsecac7cc2722011-11-29 23:25:13 +0000371 glretrace -c /path/to/reference/snapshots/ application.trace
José Fonseca6d617002011-09-06 01:17:48 +0100372
José Fonsecac7cc2722011-11-29 23:25:13 +0000373 Alternatively, for a HTML summary, use `apitrace diff-images`:
José Fonseca6d617002011-09-06 01:17:48 +0100374
José Fonsecac582fc62012-02-29 09:06:53 +0000375 glretrace -s /path/to/test/snapshots/ application.trace
376 apitrace diff-images --output summary.html /path/to/reference/snapshots/ /path/to/test/snapshots/
José Fonseca6d617002011-09-06 01:17:48 +0100377
378
379Automated git-bisection
380-----------------------
381
382With tracecheck.py it is possible to automate git bisect and pinpoint the
383commit responsible for a regression.
384
385Below is an example of using tracecheck.py to bisect a regression in the
386Mesa-based Intel 965 driver. But the procedure could be applied to any GL
387driver hosted on a git repository.
388
389First, create a build script, named build-script.sh, containing:
390
391 #!/bin/sh
392 set -e
393 export PATH=/usr/lib/ccache:$PATH
394 export CFLAGS='-g'
395 export CXXFLAGS='-g'
396 ./autogen.sh --disable-egl --disable-gallium --disable-glut --disable-glu --disable-glw --with-dri-drivers=i965
397 make clean
398 make "$@"
399
400It is important that builds are both robust, and efficient. Due to broken
401dependency discovery in Mesa's makefile system, it was necessary invoke `make
402clean` in every iteration step. `ccache` should be installed to avoid
403recompiling unchanged source files.
404
405Then do:
406
407 cd /path/to/mesa
408 export LIBGL_DEBUG=verbose
409 export LD_LIBRARY_PATH=$PWD/lib
410 export LIBGL_DRIVERS_DIR=$PWD/lib
411 git bisect start \
412 6491e9593d5cbc5644eb02593a2f562447efdcbb 71acbb54f49089b03d3498b6f88c1681d3f649ac \
413 -- src/mesa/drivers/dri/intel src/mesa/drivers/dri/i965/
414 git bisect run /path/to/tracecheck.py \
415 --precision-threshold 8.0 \
416 --build /path/to/build-script.sh \
417 --gl-renderer '.*Mesa.*Intel.*' \
418 --retrace=/path/to/glretrace \
419 -c /path/to/reference/snapshots/ \
420 topogun-1.06-orc-84k.trace
421
422The trace-check.py script will skip automatically when there are build
423failures.
424
425The `--gl-renderer` option will also cause a commit to be skipped if the
426`GL_RENDERER` is unexpected (e.g., when a software renderer or another GL
José Fonsecaff427582011-09-18 10:49:13 +0100427driver is unintentionally loaded due to missing symbol in the DRI driver, or
José Fonseca6d617002011-09-06 01:17:48 +0100428another runtime fault).
429
430
431Side by side retracing
432----------------------
433
434In order to determine which draw call a regression first manifests one could
José Fonseca05ba4192011-09-17 21:18:57 +0100435generate snapshots for every draw call, using the `-S` option. That is, however,
José Fonseca6d617002011-09-06 01:17:48 +0100436very inefficient for big traces with many draw calls.
437
438A faster approach is to run both the bad and a good GL driver side-by-side.
José Fonsecaff427582011-09-18 10:49:13 +0100439The latter can be either a previously known good build of the GL driver, or a
José Fonseca6d617002011-09-06 01:17:48 +0100440reference software renderer.
441
442This can be achieved with retracediff.py script, which invokes glretrace with
443different environments, allowing to choose the desired GL driver by
José Fonsecae4a4f152012-03-21 18:58:19 +0000444manipulating variables such as `LD_LIBRARY_PATH`, `LIBGL_DRIVERS_DIR`, or
445`TRACE_LIBGL`.
José Fonseca6d617002011-09-06 01:17:48 +0100446
José Fonsecae4a4f152012-03-21 18:58:19 +0000447For example, on Linux:
José Fonseca6d617002011-09-06 01:17:48 +0100448
449 ./scripts/retracediff.py \
450 --ref-env LD_LIBRARY_PATH=/path/to/reference/GL/implementation \
José Fonsecae4a4f152012-03-21 18:58:19 +0000451 --retrace /path/to/glretrace \
José Fonseca6d617002011-09-06 01:17:48 +0100452 --diff-prefix=/path/to/output/diffs \
453 application.trace
454
José Fonsecae4a4f152012-03-21 18:58:19 +0000455Or on Windows:
456
457 python scripts\retracediff.py --retrace \path\to\glretrace.exe --ref-env TRACE_LIBGL=\path\to\reference\opengl32.dll application.trace
José Fonseca6d617002011-09-06 01:17:48 +0100458
459
José Fonseca0b217312011-06-30 14:32:57 +0100460Links
461=====
462
463About **apitrace**:
464
Zack Rusind029d5f2011-08-22 21:50:08 -0400465* [Official mailing list](http://lists.freedesktop.org/mailman/listinfo/apitrace)
466
José Fonseca0b217312011-06-30 14:32:57 +0100467* [Zack Rusin's blog introducing the GUI](http://zrusin.blogspot.com/2011/04/apitrace.html)
468
469* [Jose's Fonseca blog introducing the tool](http://jrfonseca.blogspot.com/2008/07/tracing-d3d-applications.html)
470
471
472Direct3D
473--------
474
475Open-source:
476
477* [Proxy DLL](http://www.mikoweb.eu/index.php?node=21)
478
479 * [Intercept Calls to DirectX with a Proxy DLL](http://www.codeguru.com/cpp/g-m/directx/directx8/article.php/c11453/)
480
481* [Direct3D 9 API Interceptor](http://graphics.stanford.edu/~mdfisher/D3D9Interceptor.html)
482
483Closed-source:
484
485* [Microsoft PIX](http://msdn.microsoft.com/en-us/library/ee417062.aspx)
486
487 * [D3DSpy](http://doc.51windows.net/Directx9_SDK/?url=/directx9_sdk/graphics/programmingguide/TutorialsAndSamplesAndToolsAndTips/Tools/D3DSpy.htm): the predecessor of PIX
488
José Fonseca8ab0d9e2012-03-10 09:07:26 +0000489* [NVIDIA PerfKit](http://developer.nvidia.com/nvidia-perfkit)
490
José Fonseca0b217312011-06-30 14:32:57 +0100491* [AMD GPU PerfStudio](http://developer.amd.com/gpu/PerfStudio/pages/APITraceWindow.aspx)
492
José Fonseca8ab0d9e2012-03-10 09:07:26 +0000493* [Intel Graphics Performance Analyzers](http://www.intel.com/software/gpa/)
494
José Fonseca0b217312011-06-30 14:32:57 +0100495
496OpenGL
497------
498
499Open-source:
500
501* [BuGLe](http://www.opengl.org/sdk/tools/BuGLe/)
502
503* [GLIntercept](http://code.google.com/p/glintercept/)
504
505* [tracy](https://gitorious.org/tracy): OpenGL ES and OpenVG trace, retrace, and state inspection
506
José Fonseca8aba5c32012-03-05 22:50:09 +0100507* [WebGL-Inspector](http://benvanik.github.com/WebGL-Inspector/)
508
José Fonseca0b217312011-06-30 14:32:57 +0100509Closed-source:
510
José Fonsecaa23e4492012-10-13 09:48:37 +0100511* [AMD CodeXL](http://developer.amd.com/tools/hc/CodeXL/Pages/default.aspx)
512
513* [AMD GPU PerfStudio](http://developer.amd.com/gpu/PerfStudio/pages/APITraceWindow.aspx)
514
José Fonseca8ab0d9e2012-03-10 09:07:26 +0000515* [gDEBugger](http://www.gremedy.com/products.php) and [AMD gDEBugger](http://developer.amd.com/tools/gDEBugger/Pages/default.aspx)
José Fonseca0b217312011-06-30 14:32:57 +0100516
517* [glslDevil](http://cumbia.informatik.uni-stuttgart.de/glsldevil/index.html)
518