José Fonseca | 0b21731 | 2011-06-30 14:32:57 +0100 | [diff] [blame] | 1 | About **apitrace** |
| 2 | ================== |
| 3 | |
| 4 | **apitrace** consists of a set of tools to: |
| 5 | |
José Fonseca | f9c5da2 | 2012-04-30 22:59:40 +0100 | [diff] [blame] | 6 | * trace OpenGL, OpenGL ES, Direct3D, and DirectDraw APIs calls to a file; |
José Fonseca | 0b21731 | 2011-06-30 14:32:57 +0100 | [diff] [blame] | 7 | |
José Fonseca | c7cc272 | 2011-11-29 23:25:13 +0000 | [diff] [blame] | 8 | * retrace OpenGL and OpenGL ES calls from a file; |
José Fonseca | 0b21731 | 2011-06-30 14:32:57 +0100 | [diff] [blame] | 9 | |
José Fonseca | 892cad6 | 2011-09-23 08:24:28 +0100 | [diff] [blame] | 10 | * inspect OpenGL state at any call while retracing; |
| 11 | |
| 12 | * visualize and edit trace files. |
José Fonseca | 0b21731 | 2011-06-30 14:32:57 +0100 | [diff] [blame] | 13 | |
José Fonseca | ab8b9df | 2012-10-21 11:08:36 +0100 | [diff] [blame^] | 14 | See the [apitrace homepage](http://apitrace.github.com/) for more details. |
| 15 | |
José Fonseca | 0b21731 | 2011-06-30 14:32:57 +0100 | [diff] [blame] | 16 | |
José Fonseca | 45afa26 | 2012-03-09 18:22:28 +0000 | [diff] [blame] | 17 | Obtaining **apitrace** |
| 18 | ====================== |
José Fonseca | 0b21731 | 2011-06-30 14:32:57 +0100 | [diff] [blame] | 19 | |
José Fonseca | 5104ef4 | 2012-02-29 09:15:29 +0000 | [diff] [blame] | 20 | To obtain apitrace either [download the latest |
| 21 | binaries](https://github.com/apitrace/apitrace/downloads) for your platform if |
José Fonseca | 9cc74f6 | 2012-03-10 09:41:46 +0000 | [diff] [blame] | 22 | available, or follow the instructions in INSTALL.markdown to build it yourself. |
| 23 | On 64bits Linux and Windows platforms you'll need apitrace binaries that match |
| 24 | the architecture (32bits or 64bits) of the application being traced. |
José Fonseca | 5104ef4 | 2012-02-29 09:15:29 +0000 | [diff] [blame] | 25 | |
José Fonseca | 45afa26 | 2012-03-09 18:22:28 +0000 | [diff] [blame] | 26 | |
| 27 | Basic usage |
| 28 | =========== |
| 29 | |
José Fonseca | 0b21731 | 2011-06-30 14:32:57 +0100 | [diff] [blame] | 30 | Run the application you want to trace as |
| 31 | |
José Fonseca | 155fc78 | 2012-02-27 10:37:32 +0000 | [diff] [blame] | 32 | apitrace trace --api API /path/to/application [args...] |
José Fonseca | 0b21731 | 2011-06-30 14:32:57 +0100 | [diff] [blame] | 33 | |
| 34 | and it will generate a trace named `application.trace` in the current |
José Fonseca | 155fc78 | 2012-02-27 10:37:32 +0000 | [diff] [blame] | 35 | directory. You can specify the written trace filename by passing the |
| 36 | `--output` command line option. |
José Fonseca | 0b21731 | 2011-06-30 14:32:57 +0100 | [diff] [blame] | 37 | |
José Fonseca | c4e76a9 | 2012-02-29 09:00:05 +0000 | [diff] [blame] | 38 | Problems while tracing (e.g, if the application uses calls/parameters |
| 39 | unsupported by apitrace) will be reported via stderr output on Unices. On |
| 40 | Windows you'll need to run |
| 41 | [DebugView](http://technet.microsoft.com/en-us/sysinternals/bb896647) to view |
| 42 | these messages. |
| 43 | |
José Fonseca | a4f17e7 | 2012-02-29 09:37:40 +0000 | [diff] [blame] | 44 | Follow the "Tracing manually" instructions below if you cannot obtain a trace. |
| 45 | |
José Fonseca | 0b21731 | 2011-06-30 14:32:57 +0100 | [diff] [blame] | 46 | View the trace with |
| 47 | |
José Fonseca | 155fc78 | 2012-02-27 10:37:32 +0000 | [diff] [blame] | 48 | apitrace dump application.trace |
José Fonseca | 0b21731 | 2011-06-30 14:32:57 +0100 | [diff] [blame] | 49 | |
José Fonseca | c7cc272 | 2011-11-29 23:25:13 +0000 | [diff] [blame] | 50 | Replay an OpenGL trace with |
José Fonseca | 0b21731 | 2011-06-30 14:32:57 +0100 | [diff] [blame] | 51 | |
José Fonseca | c7cc272 | 2011-11-29 23:25:13 +0000 | [diff] [blame] | 52 | glretrace application.trace |
José Fonseca | 0b21731 | 2011-06-30 14:32:57 +0100 | [diff] [blame] | 53 | |
| 54 | Pass the `-sb` option to use a single buffered visual. Pass `--help` to |
| 55 | glretrace for more options. |
| 56 | |
José Fonseca | 45afa26 | 2012-03-09 18:22:28 +0000 | [diff] [blame] | 57 | |
| 58 | Basic GUI usage |
| 59 | =============== |
| 60 | |
José Fonseca | 0b21731 | 2011-06-30 14:32:57 +0100 | [diff] [blame] | 61 | Start the GUI as |
| 62 | |
José Fonseca | c7cc272 | 2011-11-29 23:25:13 +0000 | [diff] [blame] | 63 | qapitrace application.trace |
José Fonseca | 0b21731 | 2011-06-30 14:32:57 +0100 | [diff] [blame] | 64 | |
José Fonseca | 45afa26 | 2012-03-09 18:22:28 +0000 | [diff] [blame] | 65 | You can also tell the GUI to go directly to a specific call |
| 66 | |
| 67 | qapitrace application.trace 12345 |
| 68 | |
José Fonseca | 0b21731 | 2011-06-30 14:32:57 +0100 | [diff] [blame] | 69 | |
José Fonseca | 6d61700 | 2011-09-06 01:17:48 +0100 | [diff] [blame] | 70 | Advanced command line usage |
| 71 | =========================== |
| 72 | |
| 73 | |
José Fonseca | 225193d | 2012-01-26 19:08:32 +0000 | [diff] [blame] | 74 | Call sets |
| 75 | --------- |
| 76 | |
| 77 | Several tools take `CALLSET` arguments, e.g: |
| 78 | |
| 79 | apitrace dump --calls CALLSET foo.trace |
| 80 | glretrace -S CALLSET foo.trace |
| 81 | |
| 82 | The 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é Fonseca | 7edf24a | 2011-11-03 12:30:18 +0000 | [diff] [blame] | 102 | Tracing manually |
| 103 | ---------------- |
| 104 | |
| 105 | ### Linux ### |
| 106 | |
José Fonseca | a4f17e7 | 2012-02-29 09:37:40 +0000 | [diff] [blame] | 107 | On 64 bits systems, you'll need to determine ether the application is 64 bits |
| 108 | or 32 bits. This can be done by doing |
| 109 | |
| 110 | file /path/to/application |
| 111 | |
| 112 | But beware of wrapper shell scripts -- what matters is the architecture of the |
| 113 | main process. |
| 114 | |
José Fonseca | 7edf24a | 2011-11-03 12:30:18 +0000 | [diff] [blame] | 115 | Run the application you want to trace as |
| 116 | |
José Fonseca | dab19cd | 2011-11-03 14:32:45 +0000 | [diff] [blame] | 117 | LD_PRELOAD=/path/to/apitrace/wrappers/glxtrace.so /path/to/application |
José Fonseca | 7edf24a | 2011-11-03 12:30:18 +0000 | [diff] [blame] | 118 | |
| 119 | and it will generate a trace named `application.trace` in the current |
| 120 | directory. You can specify the written trace filename by setting the |
| 121 | `TRACE_FILE` environment variable before running. |
| 122 | |
José Fonseca | 4b9e58e | 2012-10-18 13:25:45 +0100 | [diff] [blame] | 123 | The `LD_PRELOAD` mechanism should work with the majority applications. There |
| 124 | are some applications (e.g., Unigine Heaven, Android GPU emulator, etc.), that |
| 125 | have global function pointers with the same name as GL entrypoints, living in a |
| 126 | shared object that wasn't linked with `-Bsymbolic` flag, so relocations to |
| 127 | those globals function pointers get overwritten with the address to our wrapper |
| 128 | library, and the application will segfault when trying to write to them. For |
| 129 | these applications it is possible to trace by using `glxtrace.so` as an |
| 130 | ordinary `libGL.so` and injecting it via `LD_LIBRARY_PATH`: |
José Fonseca | 7edf24a | 2011-11-03 12:30:18 +0000 | [diff] [blame] | 131 | |
José Fonseca | dab19cd | 2011-11-03 14:32:45 +0000 | [diff] [blame] | 132 | 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é Fonseca | 7edf24a | 2011-11-03 12:30:18 +0000 | [diff] [blame] | 136 | export TRACE_LIBGL=/path/to/real/libGL.so.1 |
| 137 | /path/to/application |
| 138 | |
José Fonseca | 4b9e58e | 2012-10-18 13:25:45 +0100 | [diff] [blame] | 139 | If 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é Fonseca | 7edf24a | 2011-11-03 12:30:18 +0000 | [diff] [blame] | 142 | See the `ld.so` man page for more information about `LD_PRELOAD` and |
| 143 | `LD_LIBRARY_PATH` environment flags. |
| 144 | |
José Fonseca | c5b4a94 | 2012-01-18 16:15:30 +0000 | [diff] [blame] | 145 | To 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 Deak | b4c584d | 2012-03-30 15:44:39 +0300 | [diff] [blame] | 149 | ### Android ### |
| 150 | |
| 151 | The following instructions should work at least for Android Ice Scream |
| 152 | Sandwitch: |
| 153 | |
| 154 | For standalone applications the instructions above for Linux should |
| 155 | work. To trace applications started from within the Android VM process |
José Fonseca | 0a64dc2 | 2012-08-13 13:36:31 +0100 | [diff] [blame] | 156 | (`app_process` aka zygote) you'll have to wrap this process and enable |
Imre Deak | b4c584d | 2012-03-30 15:44:39 +0300 | [diff] [blame] | 157 | tracing dynamically for the application to be traced. |
| 158 | |
| 159 | - Wrapping the android main VM process: |
| 160 | |
José Fonseca | 0a64dc2 | 2012-08-13 13:36:31 +0100 | [diff] [blame] | 161 | In the Android root /init.rc add the `LD_PRELOAD` setting to zygote's |
Imre Deak | b4c584d | 2012-03-30 15:44:39 +0300 | [diff] [blame] | 162 | environment in the 'service zygote' section: |
| 163 | |
José Fonseca | 0a64dc2 | 2012-08-13 13:36:31 +0100 | [diff] [blame] | 164 | service zygote ... |
| 165 | setenv LD_PRELOAD /data/egltrace.so |
| 166 | ... |
Imre Deak | b4c584d | 2012-03-30 15:44:39 +0300 | [diff] [blame] | 167 | |
| 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 Deak | b4c584d | 2012-03-30 15:44:39 +0300 | [diff] [blame] | 173 | - Copy egltrace.so to /data |
| 174 | |
| 175 | On the host: |
Imre Deak | b4c584d | 2012-03-30 15:44:39 +0300 | [diff] [blame] | 176 | |
José Fonseca | 0a64dc2 | 2012-08-13 13:36:31 +0100 | [diff] [blame] | 177 | adb push /path/to/apitrace/build/wrappers/egltrace.so /data |
Imre Deak | b4c584d | 2012-03-30 15:44:39 +0300 | [diff] [blame] | 178 | |
| 179 | - Adjust file permissions to store the trace file: |
| 180 | |
| 181 | By default egltrace.so will store the trace in |
José Fonseca | 0a64dc2 | 2012-08-13 13:36:31 +0100 | [diff] [blame] | 182 | `/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 Deak | b4c584d | 2012-03-30 15:44:39 +0300 | [diff] [blame] | 184 | directory on the device: |
| 185 | |
José Fonseca | 0a64dc2 | 2012-08-13 13:36:31 +0100 | [diff] [blame] | 186 | chmod 0777 /data |
Imre Deak | b4c584d | 2012-03-30 15:44:39 +0300 | [diff] [blame] | 187 | |
| 188 | - Enable tracing for a specific process name: |
| 189 | |
| 190 | To trace for example the Settings application: |
Imre Deak | b4c584d | 2012-03-30 15:44:39 +0300 | [diff] [blame] | 191 | |
José Fonseca | 0a64dc2 | 2012-08-13 13:36:31 +0100 | [diff] [blame] | 192 | setprop debug.apitrace.procname com.android.settings |
Imre Deak | b4c584d | 2012-03-30 15:44:39 +0300 | [diff] [blame] | 193 | |
José Fonseca | 0a64dc2 | 2012-08-13 13:36:31 +0100 | [diff] [blame] | 194 | In general this name will match what `ps` reports. |
Imre Deak | b4c584d | 2012-03-30 15:44:39 +0300 | [diff] [blame] | 195 | |
| 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é Fonseca | 0a64dc2 | 2012-08-13 13:36:31 +0100 | [diff] [blame] | 202 | kill <pid of app> |
Imre Deak | b4c584d | 2012-03-30 15:44:39 +0300 | [diff] [blame] | 203 | |
| 204 | Launch the application for example from the application menu. |
| 205 | |
José Fonseca | 7edf24a | 2011-11-03 12:30:18 +0000 | [diff] [blame] | 206 | ### Mac OS X ### |
| 207 | |
| 208 | Run the application you want to trace as |
| 209 | |
| 210 | DYLD_LIBRARY_PATH=/path/to/apitrace/wrappers /path/to/application |
| 211 | |
| 212 | Note 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 |
| 215 | page for more details about these environment flags. |
| 216 | |
José Fonseca | 155fc78 | 2012-02-27 10:37:32 +0000 | [diff] [blame] | 217 | ### Windows ### |
| 218 | |
José Fonseca | a4f17e7 | 2012-02-29 09:37:40 +0000 | [diff] [blame] | 219 | When tracing third-party applications, you can identify the target |
| 220 | application'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 | |
| 230 | On 64 bits Windows, you'll need to determine ether the application is a 64 bits |
| 231 | or 32 bits. 32 bits applications will have a `*32` suffix in the _Image Name_ |
| 232 | column of the _Processes_ tab of _Windows Task Manager_ window. |
| 233 | |
| 234 | Copy the appropriate `opengl32.dll`, `d3d8.dll`, or `d3d9.dll` from the |
| 235 | wrappers directory to the directory with the application you want to trace. |
| 236 | Then run the application as usual. |
José Fonseca | 155fc78 | 2012-02-27 10:37:32 +0000 | [diff] [blame] | 237 | |
| 238 | You can specify the written trace filename by setting the `TRACE_FILE` |
| 239 | environment variable before running. |
| 240 | |
José Fonseca | 7edf24a | 2011-11-03 12:30:18 +0000 | [diff] [blame] | 241 | |
José Fonseca | f028a8f | 2012-02-15 23:33:35 +0000 | [diff] [blame] | 242 | Emitting annotations to the trace |
| 243 | --------------------------------- |
José Fonseca | e62cabc | 2011-09-18 10:31:04 +0100 | [diff] [blame] | 244 | |
José Fonseca | f028a8f | 2012-02-15 23:33:35 +0000 | [diff] [blame] | 245 | From OpenGL applications you can embed annotations in the trace file through the |
José Fonseca | e62cabc | 2011-09-18 10:31:04 +0100 | [diff] [blame] | 246 | [`GL_GREMEDY_string_marker`](http://www.opengl.org/registry/specs/GREMEDY/string_marker.txt) |
| 247 | and |
| 248 | [`GL_GREMEDY_frame_terminator`](http://www.opengl.org/registry/specs/GREMEDY/frame_terminator.txt) |
| 249 | GL extensions. |
| 250 | |
José Fonseca | 892cad6 | 2011-09-23 08:24:28 +0100 | [diff] [blame] | 251 | **apitrace** will advertise and intercept these GL extensions independently of |
José Fonseca | e62cabc | 2011-09-18 10:31:04 +0100 | [diff] [blame] | 252 | the GL implementation. So all you have to do is to use these extensions when |
| 253 | available. |
| 254 | |
| 255 | For example, if you use [GLEW](http://glew.sourceforge.net/) to dynamically |
| 256 | detect 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 | |
| 272 | This has the added advantage of working equally well with gDEBugger. |
| 273 | |
| 274 | |
José Fonseca | f028a8f | 2012-02-15 23:33:35 +0000 | [diff] [blame] | 275 | From 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) |
| 277 | extension. |
| 278 | |
| 279 | |
| 280 | For 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é Fonseca | 6d61700 | 2011-09-06 01:17:48 +0100 | [diff] [blame] | 284 | Dump GL state at a particular call |
| 285 | ---------------------------------- |
| 286 | |
| 287 | You can get a dump of the bound GL state at call 12345 by doing: |
| 288 | |
José Fonseca | c7cc272 | 2011-11-29 23:25:13 +0000 | [diff] [blame] | 289 | glretrace -D 12345 application.trace > 12345.json |
José Fonseca | 6d61700 | 2011-09-06 01:17:48 +0100 | [diff] [blame] | 290 | |
| 291 | This is precisely the mechanism the GUI obtains its own state. |
| 292 | |
José Fonseca | c7cc272 | 2011-11-29 23:25:13 +0000 | [diff] [blame] | 293 | You can compare two state dumps by doing: |
José Fonseca | 6d61700 | 2011-09-06 01:17:48 +0100 | [diff] [blame] | 294 | |
José Fonseca | c7cc272 | 2011-11-29 23:25:13 +0000 | [diff] [blame] | 295 | apitrace diff-state 12345.json 67890.json |
José Fonseca | 6d61700 | 2011-09-06 01:17:48 +0100 | [diff] [blame] | 296 | |
| 297 | |
| 298 | Comparing two traces side by side |
| 299 | --------------------------------- |
| 300 | |
José Fonseca | 73694fa | 2011-11-06 09:01:12 +0000 | [diff] [blame] | 301 | apitrace diff trace1.trace trace2.trace |
José Fonseca | 6d61700 | 2011-09-06 01:17:48 +0100 | [diff] [blame] | 302 | |
| 303 | This works only on Unices, and it will truncate the traces due to performance |
| 304 | limitations. |
| 305 | |
| 306 | |
| 307 | Recording a video with FFmpeg |
| 308 | ----------------------------- |
| 309 | |
| 310 | You can make a video of the output by doing |
| 311 | |
José Fonseca | c7cc272 | 2011-11-29 23:25:13 +0000 | [diff] [blame] | 312 | glretrace -s - application.trace \ |
José Fonseca | 6d61700 | 2011-09-06 01:17:48 +0100 | [diff] [blame] | 313 | | ffmpeg -r 30 -f image2pipe -vcodec ppm -i pipe: -vcodec mpeg4 -y output.mp4 |
| 314 | |
| 315 | |
James Benton | 5b670de | 2012-08-06 18:04:56 +0100 | [diff] [blame] | 316 | Trimming a trace |
| 317 | ---------------- |
José Fonseca | 7b1b0a2 | 2012-02-15 07:18:22 +0000 | [diff] [blame] | 318 | |
| 319 | You can make a smaller trace by doing: |
| 320 | |
| 321 | apitrace trim --callset 100-1000 -o trimed.trace applicated.trace |
| 322 | |
| 323 | If you need precise control over which calls to trim you can specify the |
| 324 | individual call numbers a plaintext file, as described in the 'Call sets' |
| 325 | section above. |
| 326 | |
| 327 | |
James Benton | 5b670de | 2012-08-06 18:04:56 +0100 | [diff] [blame] | 328 | Profiling a trace |
| 329 | ----------------- |
| 330 | |
| 331 | You 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 | |
| 339 | The results from this can then be read by hand or analysed with a script. |
| 340 | |
James Benton | fdeaa54 | 2012-08-09 16:46:43 +0100 | [diff] [blame] | 341 | `scripts/profileshader.py` will read the profile results and format them into a |
James Benton | 5b670de | 2012-08-06 18:04:56 +0100 | [diff] [blame] | 342 | table which displays profiling results per shader. |
| 343 | |
| 344 | For example, to record all profiling data and utilise the per shader script: |
James Benton | fdeaa54 | 2012-08-09 16:46:43 +0100 | [diff] [blame] | 345 | |
James Benton | 5b670de | 2012-08-06 18:04:56 +0100 | [diff] [blame] | 346 | ./glretrace -pgpu -pcpu -ppd foo.trace | ./scripts/profileshader.py |
| 347 | |
| 348 | |
José Fonseca | 6d61700 | 2011-09-06 01:17:48 +0100 | [diff] [blame] | 349 | Advanced usage for OpenGL implementors |
| 350 | ====================================== |
| 351 | |
José Fonseca | ff42758 | 2011-09-18 10:49:13 +0100 | [diff] [blame] | 352 | There are several advanced usage examples meant for OpenGL implementors. |
José Fonseca | 6d61700 | 2011-09-06 01:17:48 +0100 | [diff] [blame] | 353 | |
| 354 | |
| 355 | Regression testing |
| 356 | ------------------ |
| 357 | |
José Fonseca | 892cad6 | 2011-09-23 08:24:28 +0100 | [diff] [blame] | 358 | These are the steps to create a regression test-suite around **apitrace**: |
José Fonseca | 6d61700 | 2011-09-06 01:17:48 +0100 | [diff] [blame] | 359 | |
| 360 | * obtain a trace |
| 361 | |
José Fonseca | c582fc6 | 2012-02-29 09:06:53 +0000 | [diff] [blame] | 362 | * obtain reference snapshots, by doing on a reference system: |
José Fonseca | 6d61700 | 2011-09-06 01:17:48 +0100 | [diff] [blame] | 363 | |
José Fonseca | c582fc6 | 2012-02-29 09:06:53 +0000 | [diff] [blame] | 364 | mkdir /path/to/reference/snapshots/ |
José Fonseca | c7cc272 | 2011-11-29 23:25:13 +0000 | [diff] [blame] | 365 | glretrace -s /path/to/reference/snapshots/ application.trace |
José Fonseca | 6d61700 | 2011-09-06 01:17:48 +0100 | [diff] [blame] | 366 | |
José Fonseca | 6d61700 | 2011-09-06 01:17:48 +0100 | [diff] [blame] | 367 | * prune the snapshots which are not interesting |
| 368 | |
| 369 | * to do a regression test, do: |
| 370 | |
José Fonseca | c7cc272 | 2011-11-29 23:25:13 +0000 | [diff] [blame] | 371 | glretrace -c /path/to/reference/snapshots/ application.trace |
José Fonseca | 6d61700 | 2011-09-06 01:17:48 +0100 | [diff] [blame] | 372 | |
José Fonseca | c7cc272 | 2011-11-29 23:25:13 +0000 | [diff] [blame] | 373 | Alternatively, for a HTML summary, use `apitrace diff-images`: |
José Fonseca | 6d61700 | 2011-09-06 01:17:48 +0100 | [diff] [blame] | 374 | |
José Fonseca | c582fc6 | 2012-02-29 09:06:53 +0000 | [diff] [blame] | 375 | glretrace -s /path/to/test/snapshots/ application.trace |
| 376 | apitrace diff-images --output summary.html /path/to/reference/snapshots/ /path/to/test/snapshots/ |
José Fonseca | 6d61700 | 2011-09-06 01:17:48 +0100 | [diff] [blame] | 377 | |
| 378 | |
| 379 | Automated git-bisection |
| 380 | ----------------------- |
| 381 | |
| 382 | With tracecheck.py it is possible to automate git bisect and pinpoint the |
| 383 | commit responsible for a regression. |
| 384 | |
| 385 | Below is an example of using tracecheck.py to bisect a regression in the |
| 386 | Mesa-based Intel 965 driver. But the procedure could be applied to any GL |
| 387 | driver hosted on a git repository. |
| 388 | |
| 389 | First, 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 | |
| 400 | It is important that builds are both robust, and efficient. Due to broken |
| 401 | dependency discovery in Mesa's makefile system, it was necessary invoke `make |
| 402 | clean` in every iteration step. `ccache` should be installed to avoid |
| 403 | recompiling unchanged source files. |
| 404 | |
| 405 | Then 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 | |
| 422 | The trace-check.py script will skip automatically when there are build |
| 423 | failures. |
| 424 | |
| 425 | The `--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é Fonseca | ff42758 | 2011-09-18 10:49:13 +0100 | [diff] [blame] | 427 | driver is unintentionally loaded due to missing symbol in the DRI driver, or |
José Fonseca | 6d61700 | 2011-09-06 01:17:48 +0100 | [diff] [blame] | 428 | another runtime fault). |
| 429 | |
| 430 | |
| 431 | Side by side retracing |
| 432 | ---------------------- |
| 433 | |
| 434 | In order to determine which draw call a regression first manifests one could |
José Fonseca | 05ba419 | 2011-09-17 21:18:57 +0100 | [diff] [blame] | 435 | generate snapshots for every draw call, using the `-S` option. That is, however, |
José Fonseca | 6d61700 | 2011-09-06 01:17:48 +0100 | [diff] [blame] | 436 | very inefficient for big traces with many draw calls. |
| 437 | |
| 438 | A faster approach is to run both the bad and a good GL driver side-by-side. |
José Fonseca | ff42758 | 2011-09-18 10:49:13 +0100 | [diff] [blame] | 439 | The latter can be either a previously known good build of the GL driver, or a |
José Fonseca | 6d61700 | 2011-09-06 01:17:48 +0100 | [diff] [blame] | 440 | reference software renderer. |
| 441 | |
| 442 | This can be achieved with retracediff.py script, which invokes glretrace with |
| 443 | different environments, allowing to choose the desired GL driver by |
José Fonseca | e4a4f15 | 2012-03-21 18:58:19 +0000 | [diff] [blame] | 444 | manipulating variables such as `LD_LIBRARY_PATH`, `LIBGL_DRIVERS_DIR`, or |
| 445 | `TRACE_LIBGL`. |
José Fonseca | 6d61700 | 2011-09-06 01:17:48 +0100 | [diff] [blame] | 446 | |
José Fonseca | e4a4f15 | 2012-03-21 18:58:19 +0000 | [diff] [blame] | 447 | For example, on Linux: |
José Fonseca | 6d61700 | 2011-09-06 01:17:48 +0100 | [diff] [blame] | 448 | |
| 449 | ./scripts/retracediff.py \ |
| 450 | --ref-env LD_LIBRARY_PATH=/path/to/reference/GL/implementation \ |
José Fonseca | e4a4f15 | 2012-03-21 18:58:19 +0000 | [diff] [blame] | 451 | --retrace /path/to/glretrace \ |
José Fonseca | 6d61700 | 2011-09-06 01:17:48 +0100 | [diff] [blame] | 452 | --diff-prefix=/path/to/output/diffs \ |
| 453 | application.trace |
| 454 | |
José Fonseca | e4a4f15 | 2012-03-21 18:58:19 +0000 | [diff] [blame] | 455 | Or 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é Fonseca | 6d61700 | 2011-09-06 01:17:48 +0100 | [diff] [blame] | 458 | |
| 459 | |
José Fonseca | 0b21731 | 2011-06-30 14:32:57 +0100 | [diff] [blame] | 460 | Links |
| 461 | ===== |
| 462 | |
| 463 | About **apitrace**: |
| 464 | |
Zack Rusin | d029d5f | 2011-08-22 21:50:08 -0400 | [diff] [blame] | 465 | * [Official mailing list](http://lists.freedesktop.org/mailman/listinfo/apitrace) |
| 466 | |
José Fonseca | 0b21731 | 2011-06-30 14:32:57 +0100 | [diff] [blame] | 467 | * [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 | |
| 472 | Direct3D |
| 473 | -------- |
| 474 | |
| 475 | Open-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 | |
| 483 | Closed-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é Fonseca | 8ab0d9e | 2012-03-10 09:07:26 +0000 | [diff] [blame] | 489 | * [NVIDIA PerfKit](http://developer.nvidia.com/nvidia-perfkit) |
| 490 | |
José Fonseca | 0b21731 | 2011-06-30 14:32:57 +0100 | [diff] [blame] | 491 | * [AMD GPU PerfStudio](http://developer.amd.com/gpu/PerfStudio/pages/APITraceWindow.aspx) |
| 492 | |
José Fonseca | 8ab0d9e | 2012-03-10 09:07:26 +0000 | [diff] [blame] | 493 | * [Intel Graphics Performance Analyzers](http://www.intel.com/software/gpa/) |
| 494 | |
José Fonseca | 0b21731 | 2011-06-30 14:32:57 +0100 | [diff] [blame] | 495 | |
| 496 | OpenGL |
| 497 | ------ |
| 498 | |
| 499 | Open-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é Fonseca | 8aba5c3 | 2012-03-05 22:50:09 +0100 | [diff] [blame] | 507 | * [WebGL-Inspector](http://benvanik.github.com/WebGL-Inspector/) |
| 508 | |
José Fonseca | 0b21731 | 2011-06-30 14:32:57 +0100 | [diff] [blame] | 509 | Closed-source: |
| 510 | |
José Fonseca | a23e449 | 2012-10-13 09:48:37 +0100 | [diff] [blame] | 511 | * [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é Fonseca | 8ab0d9e | 2012-03-10 09:07:26 +0000 | [diff] [blame] | 515 | * [gDEBugger](http://www.gremedy.com/products.php) and [AMD gDEBugger](http://developer.amd.com/tools/gDEBugger/Pages/default.aspx) |
José Fonseca | 0b21731 | 2011-06-30 14:32:57 +0100 | [diff] [blame] | 516 | |
| 517 | * [glslDevil](http://cumbia.informatik.uni-stuttgart.de/glsldevil/index.html) |
| 518 | |