1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
8 * @fileoverview Parses i915 driver events in the Linux event trace format.
10 tvcm.require('tracing.importer.linux_perf.parser');
11 tvcm.exportTo('tracing.importer.linux_perf', function() {
13 var Parser = tracing.importer.linux_perf.Parser;
16 * Parses linux i915 trace events.
19 function I915Parser(importer) {
20 Parser.call(this, importer);
22 importer.registerEventHandler('i915_gem_object_create',
23 I915Parser.prototype.gemObjectCreateEvent.bind(this));
24 importer.registerEventHandler('i915_gem_object_bind',
25 I915Parser.prototype.gemObjectBindEvent.bind(this));
26 importer.registerEventHandler('i915_gem_object_unbind',
27 I915Parser.prototype.gemObjectBindEvent.bind(this));
28 importer.registerEventHandler('i915_gem_object_change_domain',
29 I915Parser.prototype.gemObjectChangeDomainEvent.bind(this));
30 importer.registerEventHandler('i915_gem_object_pread',
31 I915Parser.prototype.gemObjectPreadWriteEvent.bind(this));
32 importer.registerEventHandler('i915_gem_object_pwrite',
33 I915Parser.prototype.gemObjectPreadWriteEvent.bind(this));
34 importer.registerEventHandler('i915_gem_object_fault',
35 I915Parser.prototype.gemObjectFaultEvent.bind(this));
36 importer.registerEventHandler('i915_gem_object_clflush',
37 // NB: reuse destroy handler
38 I915Parser.prototype.gemObjectDestroyEvent.bind(this));
39 importer.registerEventHandler('i915_gem_object_destroy',
40 I915Parser.prototype.gemObjectDestroyEvent.bind(this));
41 importer.registerEventHandler('i915_gem_ring_dispatch',
42 I915Parser.prototype.gemRingDispatchEvent.bind(this));
43 importer.registerEventHandler('i915_gem_ring_flush',
44 I915Parser.prototype.gemRingFlushEvent.bind(this));
45 importer.registerEventHandler('i915_gem_request',
46 I915Parser.prototype.gemRequestEvent.bind(this));
47 importer.registerEventHandler('i915_gem_request_add',
48 I915Parser.prototype.gemRequestEvent.bind(this));
49 importer.registerEventHandler('i915_gem_request_complete',
50 I915Parser.prototype.gemRequestEvent.bind(this));
51 importer.registerEventHandler('i915_gem_request_retire',
52 I915Parser.prototype.gemRequestEvent.bind(this));
53 importer.registerEventHandler('i915_gem_request_wait_begin',
54 I915Parser.prototype.gemRequestEvent.bind(this));
55 importer.registerEventHandler('i915_gem_request_wait_end',
56 I915Parser.prototype.gemRequestEvent.bind(this));
57 importer.registerEventHandler('i915_gem_ring_wait_begin',
58 I915Parser.prototype.gemRingWaitEvent.bind(this));
59 importer.registerEventHandler('i915_gem_ring_wait_end',
60 I915Parser.prototype.gemRingWaitEvent.bind(this));
61 importer.registerEventHandler('i915_reg_rw',
62 I915Parser.prototype.regRWEvent.bind(this));
63 importer.registerEventHandler('i915_flip_request',
64 I915Parser.prototype.flipEvent.bind(this));
65 importer.registerEventHandler('i915_flip_complete',
66 I915Parser.prototype.flipEvent.bind(this));
69 I915Parser.prototype = {
70 __proto__: Parser.prototype,
72 i915FlipOpenSlice: function(ts, obj, plane) {
73 // use i915_flip_obj_plane?
74 var kthread = this.importer.getOrCreatePseudoThread('i915_flip');
75 kthread.openSliceTS = ts;
76 kthread.openSlice = 'flip:' + obj + '/' + plane;
79 i915FlipCloseSlice: function(ts, args) {
80 var kthread = this.importer.getOrCreatePseudoThread('i915_flip');
81 if (kthread.openSlice) {
82 var slice = new tracing.trace_model.Slice('', kthread.openSlice,
83 tvcm.ui.getStringColorId(kthread.openSlice),
86 ts - kthread.openSliceTS);
88 kthread.thread.sliceGroup.pushSlice(slice);
90 kthread.openSlice = undefined;
93 i915GemObjectSlice: function(ts, eventName, obj, args) {
94 var kthread = this.importer.getOrCreatePseudoThread('i915_gem');
95 kthread.openSlice = eventName + ':' + obj;
96 var slice = new tracing.trace_model.Slice('', kthread.openSlice,
97 tvcm.ui.getStringColorId(kthread.openSlice), ts, args, 0);
99 kthread.thread.sliceGroup.pushSlice(slice);
102 i915GemRingSlice: function(ts, eventName, dev, ring, args) {
103 var kthread = this.importer.getOrCreatePseudoThread('i915_gem_ring');
104 kthread.openSlice = eventName + ':' + dev + '.' + ring;
105 var slice = new tracing.trace_model.Slice('', kthread.openSlice,
106 tvcm.ui.getStringColorId(kthread.openSlice), ts, args, 0);
108 kthread.thread.sliceGroup.pushSlice(slice);
111 i915RegSlice: function(ts, eventName, reg, args) {
112 var kthread = this.importer.getOrCreatePseudoThread('i915_reg');
113 kthread.openSlice = eventName + ':' + reg;
114 var slice = new tracing.trace_model.Slice('', kthread.openSlice,
115 tvcm.ui.getStringColorId(kthread.openSlice), ts, args, 0);
117 kthread.thread.sliceGroup.pushSlice(slice);
121 * Parses i915 driver events and sets up state in the importer.
123 gemObjectCreateEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
124 var event = /obj=(\w+), size=(\d+)/.exec(eventBase.details);
129 var size = parseInt(event[2]);
130 this.i915GemObjectSlice(ts, eventName, obj,
138 gemObjectBindEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
139 // TODO(sleffler) mappable
140 var event = /obj=(\w+), offset=(\w+), size=(\d+)/.exec(eventBase.details);
145 var offset = event[2];
146 var size = parseInt(event[3]);
147 this.i915ObjectGemSlice(ts, eventName + ':' + obj,
156 gemObjectChangeDomainEvent: function(eventName, cpuNumber, pid, ts,
158 var event = /obj=(\w+), read=(\w+=>\w+), write=(\w+=>\w+)/
159 .exec(eventBase.details);
165 var write = event[3];
166 this.i915GemObjectSlice(ts, eventName, obj,
175 gemObjectPreadWriteEvent: function(eventName, cpuNumber, pid, ts,
177 var event = /obj=(\w+), offset=(\d+), len=(\d+)/.exec(eventBase.details);
182 var offset = parseInt(event[2]);
183 var len = parseInt(event[3]);
184 this.i915GemObjectSlice(ts, eventName, obj,
193 gemObjectFaultEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
194 // TODO(sleffler) writable
195 var event = /obj=(\w+), (\w+) index=(\d+)/.exec(eventBase.details);
201 var index = parseInt(event[3]);
202 this.i915GemObjectSlice(ts, eventName, obj,
211 gemObjectDestroyEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
212 var event = /obj=(\w+)/.exec(eventBase.details);
217 this.i915GemObjectSlice(ts, eventName, obj,
224 gemRingDispatchEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
225 var event = /dev=(\d+), ring=(\d+), seqno=(\d+)/.exec(eventBase.details);
229 var dev = parseInt(event[1]);
230 var ring = parseInt(event[2]);
231 var seqno = parseInt(event[3]);
232 this.i915GemRingSlice(ts, eventName, dev, ring,
241 gemRingFlushEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
242 var event = /dev=(\d+), ring=(\w+), invalidate=(\w+), flush=(\w+)/
243 .exec(eventBase.details);
247 var dev = parseInt(event[1]);
248 var ring = parseInt(event[2]);
249 var invalidate = event[3];
250 var flush = event[4];
251 this.i915GemRingSlice(ts, eventName, dev, ring,
255 invalidate: invalidate,
261 gemRequestEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
262 var event = /dev=(\d+), ring=(\d+), seqno=(\d+)/.exec(eventBase.details);
266 var dev = parseInt(event[1]);
267 var ring = parseInt(event[2]);
268 var seqno = parseInt(event[3]);
269 this.i915GemRingSlice(ts, eventName, dev, ring,
278 gemRingWaitEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
279 var event = /dev=(\d+), ring=(\d+)/.exec(eventBase.details);
283 var dev = parseInt(event[1]);
284 var ring = parseInt(event[2]);
285 this.i915GemRingSlice(ts, eventName, dev, ring,
293 regRWEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
294 var event = /(\w+) reg=(\w+), len=(\d+), val=(\(\w+, \w+\))/
295 .exec(eventBase.details);
303 this.i915RegSlice(ts, rw, reg,
313 flipEvent: function(eventName, cpuNumber, pid, ts, eventBase) {
314 var event = /plane=(\d+), obj=(\w+)/.exec(eventBase.details);
318 var plane = parseInt(event[1]);
320 if (eventName == 'i915_flip_request')
321 this.i915FlipOpenSlice(ts, obj, plane);
323 this.i915FlipCloseSlice(ts,
332 Parser.registerSubtype(I915Parser);
335 I915Parser: I915Parser