-
Notifications
You must be signed in to change notification settings - Fork 0
/
gpu_profile.go
119 lines (108 loc) · 3.44 KB
/
gpu_profile.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Copyright (C) 2019 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package replay
import (
"context"
"github.com/golang/protobuf/proto"
"github.com/google/gapid/core/log"
"github.com/google/gapid/gapis/capture"
"github.com/google/gapid/gapis/service"
"github.com/google/gapid/gapis/service/path"
"github.com/google/gapid/gapis/trace"
perfetto_pb "protos/perfetto/config"
)
// Eyeball some generous trace config parameters
const (
counterPeriodNs = uint64(1000000)
bufferSizeKb = uint32(256 * 1024)
durationMs = 30000
gpuCountersDataSourceDescriptorName = "gpu.counters"
gpuRenderStagesDataSourceDescriptorName = "gpu.renderstages"
)
func getPerfettoConfig(ctx context.Context, device *path.Device) (*perfetto_pb.TraceConfig, error) {
t, err := trace.GetTracer(ctx, device)
if err != nil {
err = log.Errf(ctx, err, "Failed to find tracer for %v", device)
return nil, err
}
d := t.GetDevice()
specs := d.Instance().GetConfiguration().GetPerfettoCapability().GetGpuProfiling().GetGpuCounterDescriptor().GetSpecs()
ids := make([]uint32, len(specs))
for i, s := range specs {
ids[i] = s.GetCounterId()
}
conf := &perfetto_pb.TraceConfig{
Buffers: []*perfetto_pb.TraceConfig_BufferConfig{
{SizeKb: proto.Uint32(bufferSizeKb)},
},
DurationMs: proto.Uint32(durationMs),
DataSources: []*perfetto_pb.TraceConfig_DataSource{
{
Config: &perfetto_pb.DataSourceConfig{
Name: proto.String(gpuRenderStagesDataSourceDescriptorName),
},
},
{
Config: &perfetto_pb.DataSourceConfig{
Name: proto.String(gpuCountersDataSourceDescriptorName),
GpuCounterConfig: &perfetto_pb.GpuCounterConfig{
CounterPeriodNs: proto.Uint64(counterPeriodNs),
CounterIds: ids,
},
},
},
},
}
return conf, nil
}
// GpuProfile replays the trace and writes a Perfetto trace of the replay
func GpuProfile(ctx context.Context, capturePath *path.Capture, device *path.Device) (*service.ProfilingData, error) {
c, err := capture.ResolveGraphicsFromPath(ctx, capturePath)
if err != nil {
return nil, err
}
if device != nil {
intent := Intent{
Capture: capturePath,
Device: device,
}
conf, err := getPerfettoConfig(ctx, device)
if err != nil {
return nil, err
}
opts := &service.TraceOptions{
Device: device,
Type: service.TraceType_Perfetto,
PerfettoConfig: conf,
}
mgr := GetManager(ctx)
hints := &service.UsageHints{Background: true}
for _, a := range c.APIs {
if pf, ok := a.(Profiler); ok {
data, err := pf.Profile(ctx, intent, mgr, hints, opts)
if err != nil {
log.E(ctx, "Replay profiling failed.")
continue
}
log.I(ctx, "Replay profiling finished.")
return data, nil
}
}
} else {
err = log.Err(ctx, nil, "Failed to find replay device.")
return nil, err
}
err = log.Err(ctx, nil, "Failed to profile replay")
return nil, err
}