i915_parser.html revision 4a4f2fe02baf385f6c24fc98c6e17bf6ac5e0724
1<!DOCTYPE html>
2<!--
3Copyright (c) 2012 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7
8<link rel="import" href="/tracing/extras/importer/linux_perf/parser.html">
9
10<script>
11'use strict';
12
13/**
14 * @fileoverview Parses i915 driver events in the Linux event trace format.
15 */
16tr.exportTo('tr.e.importer.linux_perf', function() {
17  var Parser = tr.e.importer.linux_perf.Parser;
18
19  /**
20   * Parses linux i915 trace events.
21   * @constructor
22   */
23  function I915Parser(importer) {
24    Parser.call(this, importer);
25
26    importer.registerEventHandler('i915_gem_object_create',
27        I915Parser.prototype.gemObjectCreateEvent.bind(this));
28    importer.registerEventHandler('i915_gem_object_bind',
29        I915Parser.prototype.gemObjectBindEvent.bind(this));
30    importer.registerEventHandler('i915_gem_object_unbind',
31        I915Parser.prototype.gemObjectBindEvent.bind(this));
32    importer.registerEventHandler('i915_gem_object_change_domain',
33        I915Parser.prototype.gemObjectChangeDomainEvent.bind(this));
34    importer.registerEventHandler('i915_gem_object_pread',
35        I915Parser.prototype.gemObjectPreadWriteEvent.bind(this));
36    importer.registerEventHandler('i915_gem_object_pwrite',
37        I915Parser.prototype.gemObjectPreadWriteEvent.bind(this));
38    importer.registerEventHandler('i915_gem_object_fault',
39        I915Parser.prototype.gemObjectFaultEvent.bind(this));
40    importer.registerEventHandler('i915_gem_object_clflush',
41        // NB: reuse destroy handler
42        I915Parser.prototype.gemObjectDestroyEvent.bind(this));
43    importer.registerEventHandler('i915_gem_object_destroy',
44        I915Parser.prototype.gemObjectDestroyEvent.bind(this));
45    importer.registerEventHandler('i915_gem_ring_dispatch',
46        I915Parser.prototype.gemRingDispatchEvent.bind(this));
47    importer.registerEventHandler('i915_gem_ring_flush',
48        I915Parser.prototype.gemRingFlushEvent.bind(this));
49    importer.registerEventHandler('i915_gem_request',
50        I915Parser.prototype.gemRequestEvent.bind(this));
51    importer.registerEventHandler('i915_gem_request_add',
52        I915Parser.prototype.gemRequestEvent.bind(this));
53    importer.registerEventHandler('i915_gem_request_complete',
54        I915Parser.prototype.gemRequestEvent.bind(this));
55    importer.registerEventHandler('i915_gem_request_retire',
56        I915Parser.prototype.gemRequestEvent.bind(this));
57    importer.registerEventHandler('i915_gem_request_wait_begin',
58        I915Parser.prototype.gemRequestEvent.bind(this));
59    importer.registerEventHandler('i915_gem_request_wait_end',
60        I915Parser.prototype.gemRequestEvent.bind(this));
61    importer.registerEventHandler('i915_gem_ring_wait_begin',
62        I915Parser.prototype.gemRingWaitEvent.bind(this));
63    importer.registerEventHandler('i915_gem_ring_wait_end',
64        I915Parser.prototype.gemRingWaitEvent.bind(this));
65    importer.registerEventHandler('i915_reg_rw',
66        I915Parser.prototype.regRWEvent.bind(this));
67    importer.registerEventHandler('i915_flip_request',
68        I915Parser.prototype.flipEvent.bind(this));
69    importer.registerEventHandler('i915_flip_complete',
70        I915Parser.prototype.flipEvent.bind(this));
71    importer.registerEventHandler('intel_gpu_freq_change',
72        I915Parser.prototype.gpuFrequency.bind(this));
73  }
74
75  I915Parser.prototype = {
76    __proto__: Parser.prototype,
77
78    i915FlipOpenSlice: function(ts, obj, plane) {
79      // use i915_flip_obj_plane?
80      var kthread = this.importer.getOrCreatePseudoThread('i915_flip');
81      kthread.openSliceTS = ts;
82      kthread.openSlice = 'flip:' + obj + '/' + plane;
83    },
84
85    i915FlipCloseSlice: function(ts, args) {
86      var kthread = this.importer.getOrCreatePseudoThread('i915_flip');
87      if (kthread.openSlice) {
88        var slice = new tr.model.Slice('', kthread.openSlice,
89            tr.ui.b.getColorIdForGeneralPurposeString(kthread.openSlice),
90            kthread.openSliceTS,
91            args,
92            ts - kthread.openSliceTS);
93
94        kthread.thread.sliceGroup.pushSlice(slice);
95      }
96      kthread.openSlice = undefined;
97    },
98
99    i915GemObjectSlice: function(ts, eventName, obj, args) {
100      var kthread = this.importer.getOrCreatePseudoThread('i915_gem');
101      kthread.openSlice = eventName + ':' + obj;
102      var slice = new tr.model.Slice('', kthread.openSlice,
103          tr.ui.b.getColorIdForGeneralPurposeString(kthread.openSlice),
104          ts, args, 0);
105
106      kthread.thread.sliceGroup.pushSlice(slice);
107    },
108
109    i915GemRingSlice: function(ts, eventName, dev, ring, args) {
110      var kthread = this.importer.getOrCreatePseudoThread('i915_gem_ring');
111      kthread.openSlice = eventName + ':' + dev + '.' + ring;
112      var slice = new tr.model.Slice('', kthread.openSlice,
113          tr.ui.b.getColorIdForGeneralPurposeString(kthread.openSlice),
114          ts, args, 0);
115
116      kthread.thread.sliceGroup.pushSlice(slice);
117    },
118
119    i915RegSlice: function(ts, eventName, reg, args) {
120      var kthread = this.importer.getOrCreatePseudoThread('i915_reg');
121      kthread.openSlice = eventName + ':' + reg;
122      var slice = new tr.model.Slice('', kthread.openSlice,
123          tr.ui.b.getColorIdForGeneralPurposeString(kthread.openSlice),
124          ts, args, 0);
125
126      kthread.thread.sliceGroup.pushSlice(slice);
127    },
128
129    i915FreqChangeSlice: function(ts, eventName, args) {
130      var kthread = this.importer.getOrCreatePseudoThread('i915_gpu_freq');
131      kthread.openSlice = eventName;
132      var slice = new tr.model.Slice('', kthread.openSlice,
133          tr.ui.b.getColorIdForGeneralPurposeString(kthread.openSlice),
134          ts, args, 0);
135
136      kthread.thread.sliceGroup.pushSlice(slice);
137    },
138
139    /**
140     * Parses i915 driver events and sets up state in the importer.
141     */
142    gemObjectCreateEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
143      var event = /obj=(\w+), size=(\d+)/.exec(eventBase.details);
144      if (!event)
145        return false;
146
147      var obj = event[1];
148      var size = parseInt(event[2]);
149      this.i915GemObjectSlice(ts, eventName, obj,
150          {
151            obj: obj,
152            size: size
153          });
154      return true;
155    },
156
157    gemObjectBindEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
158      // TODO(sleffler) mappable
159      var event = /obj=(\w+), offset=(\w+), size=(\d+)/.exec(eventBase.details);
160      if (!event)
161        return false;
162
163      var obj = event[1];
164      var offset = event[2];
165      var size = parseInt(event[3]);
166      this.i915ObjectGemSlice(ts, eventName + ':' + obj,
167          {
168            obj: obj,
169            offset: offset,
170            size: size
171          });
172      return true;
173    },
174
175    gemObjectChangeDomainEvent: function(eventName, cpuNumber, pid, ts,
176                                         eventBase) {
177      var event = /obj=(\w+), read=(\w+=>\w+), write=(\w+=>\w+)/
178          .exec(eventBase.details);
179      if (!event)
180        return false;
181
182      var obj = event[1];
183      var read = event[2];
184      var write = event[3];
185      this.i915GemObjectSlice(ts, eventName, obj,
186          {
187            obj: obj,
188            read: read,
189            write: write
190          });
191      return true;
192    },
193
194    gemObjectPreadWriteEvent: function(eventName, cpuNumber, pid, ts,
195                                       eventBase) {
196      var event = /obj=(\w+), offset=(\d+), len=(\d+)/.exec(eventBase.details);
197      if (!event)
198        return false;
199
200      var obj = event[1];
201      var offset = parseInt(event[2]);
202      var len = parseInt(event[3]);
203      this.i915GemObjectSlice(ts, eventName, obj,
204          {
205            obj: obj,
206            offset: offset,
207            len: len
208          });
209      return true;
210    },
211
212    gemObjectFaultEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
213      // TODO(sleffler) writable
214      var event = /obj=(\w+), (\w+) index=(\d+)/.exec(eventBase.details);
215      if (!event)
216        return false;
217
218      var obj = event[1];
219      var type = event[2];
220      var index = parseInt(event[3]);
221      this.i915GemObjectSlice(ts, eventName, obj,
222          {
223            obj: obj,
224            type: type,
225            index: index
226          });
227      return true;
228    },
229
230    gemObjectDestroyEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
231      var event = /obj=(\w+)/.exec(eventBase.details);
232      if (!event)
233        return false;
234
235      var obj = event[1];
236      this.i915GemObjectSlice(ts, eventName, obj,
237          {
238            obj: obj
239          });
240      return true;
241    },
242
243    gemRingDispatchEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
244      var event = /dev=(\d+), ring=(\d+), seqno=(\d+)/.exec(eventBase.details);
245      if (!event)
246        return false;
247
248      var dev = parseInt(event[1]);
249      var ring = parseInt(event[2]);
250      var seqno = parseInt(event[3]);
251      this.i915GemRingSlice(ts, eventName, dev, ring,
252          {
253            dev: dev,
254            ring: ring,
255            seqno: seqno
256          });
257      return true;
258    },
259
260    gemRingFlushEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
261      var event = /dev=(\d+), ring=(\w+), invalidate=(\w+), flush=(\w+)/
262          .exec(eventBase.details);
263      if (!event)
264        return false;
265
266      var dev = parseInt(event[1]);
267      var ring = parseInt(event[2]);
268      var invalidate = event[3];
269      var flush = event[4];
270      this.i915GemRingSlice(ts, eventName, dev, ring,
271          {
272            dev: dev,
273            ring: ring,
274            invalidate: invalidate,
275            flush: flush
276          });
277      return true;
278    },
279
280    gemRequestEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
281      var event = /dev=(\d+), ring=(\d+), seqno=(\d+)/.exec(eventBase.details);
282      if (!event)
283        return false;
284
285      var dev = parseInt(event[1]);
286      var ring = parseInt(event[2]);
287      var seqno = parseInt(event[3]);
288      this.i915GemRingSlice(ts, eventName, dev, ring,
289          {
290            dev: dev,
291            ring: ring,
292            seqno: seqno
293          });
294      return true;
295    },
296
297    gemRingWaitEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
298      var event = /dev=(\d+), ring=(\d+)/.exec(eventBase.details);
299      if (!event)
300        return false;
301
302      var dev = parseInt(event[1]);
303      var ring = parseInt(event[2]);
304      this.i915GemRingSlice(ts, eventName, dev, ring,
305          {
306            dev: dev,
307            ring: ring
308          });
309      return true;
310    },
311
312    regRWEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
313      var event = /(\w+) reg=(\w+), len=(\d+), val=(\(\w+, \w+\))/
314          .exec(eventBase.details);
315      if (!event)
316        return false;
317
318      var rw = event[1];
319      var reg = event[2];
320      var len = event[3];
321      var data = event[3];
322      this.i915RegSlice(ts, rw, reg,
323          {
324            rw: rw,
325            reg: reg,
326            len: len,
327            data: data
328          });
329      return true;
330    },
331
332    flipEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
333      var event = /plane=(\d+), obj=(\w+)/.exec(eventBase.details);
334      if (!event)
335        return false;
336
337      var plane = parseInt(event[1]);
338      var obj = event[2];
339      if (eventName == 'i915_flip_request')
340        this.i915FlipOpenSlice(ts, obj, plane);
341      else
342        this.i915FlipCloseSlice(ts,
343            {
344              obj: obj,
345              plane: plane
346            });
347      return true;
348    },
349
350    gpuFrequency: function(eventName, cpuNumver, pid, ts, eventBase) {
351      var event = /new_freq=(\d+)/.exec(eventBase.details);
352      if (!event)
353        return false;
354      var freq = parseInt(event[1]);
355
356      this.i915FreqChangeSlice(ts, eventName, {
357            freq: freq
358          });
359      return true;
360    }
361  };
362
363  Parser.register(I915Parser);
364
365  return {
366    I915Parser: I915Parser
367  };
368});
369</script>
370
371