diff --git a/gapic/src/main/com/google/gapid/perfetto/models/SliceTrack.java b/gapic/src/main/com/google/gapid/perfetto/models/SliceTrack.java index 4832782798..944428beb0 100644 --- a/gapic/src/main/com/google/gapid/perfetto/models/SliceTrack.java +++ b/gapic/src/main/com/google/gapid/perfetto/models/SliceTrack.java @@ -67,14 +67,51 @@ protected Slice buildSlice(Row row, ArgSet args) { public static SliceTrack forGpuQueue(QueryEngine qe, GpuInfo.Queue queue) { return new WithQueryEngine(qe, "gpu_slice", queue.trackId) { + // TODO(b/148540258): Remove the copy pasted SliceTrack code and clean up + private final String GPU_COLUMNS = "render_target, render_target_name, render_pass, render_pass_name, command_buffer, command_buffer_name"; + + @Override + protected String baseColumns() { + return BASE_COLUMNS + ", " + GPU_COLUMNS; + } + + @Override + protected ListenableFuture computeData(DataRequest req) { + Window window = Window.compute(req, 5); + return transformAsync(window.update(qe, tableName("window")), $ -> + window.quantized ? computeQuantSlices(req) : computeSlices(req)); + } + + private ListenableFuture computeSlices(DataRequest req) { + return transformAsync(qe.query(slicesSql(req)), res -> + transform(qe.getAllArgs(res.stream().mapToLong(r -> r.getLong(8))), args -> { + int rows = res.getNumRows(); + Data data = new Data(req, new long[rows], new long[rows], new long[rows], new int[rows], + new String[rows], new String[rows], new ArgSet[rows]); + res.forEachRow((i, row) -> { + long start = row.getLong(1); + data.ids[i] = row.getLong(0); + data.starts[i] = start; + data.ends[i] = start + row.getLong(2); + data.categories[i] = row.getString(3); + data.titles[i] = row.getString(4); + data.depths[i] = row.getInt(5); + // Add debug marker to title if it exists + if (data.depths[i] == 0) { + String debugMarker = row.getString(10); + if (!debugMarker.isEmpty()) { + data.titles[i] += "[" + debugMarker + "]"; + } + } + data.args[i] = args.getOrDefault(row.getLong(8), ArgSet.EMPTY); + }); + return data; + })); + } + @Override protected Slice buildSlice(Row row, ArgSet args) { - return new Slice(row, args) { - @Override - public String getTitle() { - return "GPU Render Stages"; - } - }; + return new Slice.GpuSlice(row, args); } }; } @@ -159,6 +196,10 @@ public ThreadInfo getThread() { return null; } + public RenderStageInfo getRenderStageInfo() { + return null; + } + @Override public boolean contains(Slice.Key key) { return key.matches(this); @@ -242,6 +283,45 @@ public ThreadInfo getThread() { return thread; } } + + public static class GpuSlice extends Slice { + private final RenderStageInfo renderStageInfo; + + public GpuSlice(Row row, ArgSet args) { + super(row, args); + renderStageInfo = new RenderStageInfo(row.getLong(9), row.getString(10), row.getLong(11), + row.getString(12), row.getLong(13), row.getString(14)); + } + + @Override + public String getTitle() { + return "GPU Queue Events"; + } + + @Override + public RenderStageInfo getRenderStageInfo() { + return renderStageInfo; + } + } + } + + public static class RenderStageInfo { + public final long frameBufferHandle; + public final String frameBufferName; + public final long renderPassHandle; + public final String renderPassName; + public final long commandBufferHandle; + public final String commandBufferName; + + public RenderStageInfo(long frameBufferHandle, String frameBufferName, long renderPassHandle, + String renderPassName, long commandBufferHandle, String commandBufferName) { + this.frameBufferHandle = frameBufferHandle; + this.frameBufferName = frameBufferName; + this.commandBufferHandle = commandBufferHandle; + this.commandBufferName = commandBufferName; + this.renderPassHandle = renderPassHandle; + this.renderPassName = renderPassName; + } } public static class Slices implements Selection { @@ -397,12 +477,15 @@ public Node build(Map> byParent) { } private abstract static class WithQueryEngine extends SliceTrack { - private static final String BASE_COLUMNS = + protected static final String BASE_COLUMNS = "id, ts, dur, category, name, depth, stack_id, parent_stack_id, arg_set_id"; - private static final String SLICES_VIEW = - "select " + BASE_COLUMNS + " from %s where track_id = %d"; - private static final String SLICES_SQL = - "select " + BASE_COLUMNS + " from %s " + + protected final String table; + protected final long trackId; + + private final String SLICES_VIEW = + "select " + baseColumns() + " from %s where track_id = %d"; + private final String SLICES_SQL = + "select " + baseColumns() + " from %s " + "where ts >= %d - dur and ts <= %d order by ts"; private static final String SLICES_QUANT_SQL = "select min(start_ts), max(end_ts), depth, label, max(cnt) from (" + @@ -416,15 +499,16 @@ private abstract static class WithQueryEngine extends SliceTrack { " group by quantum_ts, depth) " + "group by depth, label, i"; - private static final String SLICE_SQL = - "select " + BASE_COLUMNS + " from %s where id = %d"; - private static final String SLICE_RANGE_SQL = - "select " + BASE_COLUMNS + " from %s " + + private final String SLICE_SQL = + "select " + baseColumns() + " from %s where id = %d"; + private final String SLICE_RANGE_SQL = + "select " + baseColumns() + " from %s " + "where ts < %d and ts + dur >= %d and depth >= %d and depth <= %d"; - private final QueryEngine qe; - private final String table; - private final long trackId; + + protected String baseColumns() { + return BASE_COLUMNS; + } protected WithQueryEngine(QueryEngine qe, String table, long trackId) { super(trackId); @@ -454,7 +538,7 @@ protected ListenableFuture computeData(DataRequest req) { window.quantized ? computeQuantSlices(req) : computeSlices(req)); } - private ListenableFuture computeQuantSlices(DataRequest req) { + protected ListenableFuture computeQuantSlices(DataRequest req) { return transform(qe.query(slicesQuantSql()), res -> { int rows = res.getNumRows(); Data data = new Data(req, new long[rows], new long[rows], new long[rows], new int[rows], @@ -499,7 +583,7 @@ private ListenableFuture computeSlices(DataRequest req) { })); } - private String slicesSql(DataRequest req) { + protected String slicesSql(DataRequest req) { return format(SLICES_SQL, tableName("slices"), req.range.start, req.range.end); } diff --git a/gapic/src/main/com/google/gapid/perfetto/views/SliceSelectionView.java b/gapic/src/main/com/google/gapid/perfetto/views/SliceSelectionView.java index eb5fb0c189..b1f2499a71 100644 --- a/gapic/src/main/com/google/gapid/perfetto/views/SliceSelectionView.java +++ b/gapic/src/main/com/google/gapid/perfetto/views/SliceSelectionView.java @@ -24,9 +24,11 @@ import static com.google.gapid.widgets.Widgets.withMargin; import static com.google.gapid.widgets.Widgets.withSpans; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; import com.google.gapid.perfetto.models.ProcessInfo; import com.google.gapid.perfetto.models.SliceTrack; +import com.google.gapid.perfetto.models.SliceTrack.RenderStageInfo; import com.google.gapid.perfetto.models.ThreadInfo; import org.eclipse.swt.SWT; @@ -77,6 +79,42 @@ public SliceSelectionView(Composite parent, State state, SliceTrack.Slice slice) createLabel(main, slice.name); } + RenderStageInfo renderStageInfo = slice.getRenderStageInfo(); + if (renderStageInfo != null) { + ImmutableMap.Builder propsBuilder = ImmutableMap.builder(); + if (renderStageInfo.frameBufferHandle != 0) { + if (renderStageInfo.frameBufferName.isEmpty()) { + propsBuilder.put("VkFrameBuffer:", String.format("0x%08X", renderStageInfo.frameBufferHandle)); + } else { + propsBuilder.put("VkFrameBuffer:", renderStageInfo.frameBufferName + " <" + String.format("0x%08X", renderStageInfo.frameBufferHandle) + ">"); + } + } + if (renderStageInfo.renderPassHandle != 0) { + if (renderStageInfo.renderPassName.isEmpty()) { + propsBuilder.put("VkRenderPass:", String.format("0x%08X", renderStageInfo.renderPassHandle)); + } else { + propsBuilder.put("VkRenderPass:", renderStageInfo.renderPassName + " <" + String.format("0x%08X", renderStageInfo.renderPassHandle) + ">"); + } + } + if (renderStageInfo.commandBufferHandle != 0) { + if (renderStageInfo.commandBufferName.isEmpty()) { + propsBuilder.put("VkCommandBuffer:", String.format("0x%08X", renderStageInfo.commandBufferHandle)); + } else { + propsBuilder.put("VkCommandBuffer:", renderStageInfo.commandBufferName + " <" + String.format("0x%08X", renderStageInfo.commandBufferHandle) + ">"); + } + } + + ImmutableMap props = propsBuilder.build(); + if (!props.isEmpty()) { + withLayoutData(createBoldLabel(main, "Vulkan Info"), + withSpans(new GridData(), 2, 1)); + props.forEach((key, value) -> { + createLabel(main, key); + createLabel(main, value); + }); + } + } + if (!slice.args.isEmpty()) { String[] keys = Iterables.toArray(slice.args.keys(), String.class); int panels = (keys.length + PROPERTIES_PER_PANEL - 1) / PROPERTIES_PER_PANEL; diff --git a/tools/build/third_party/perfetto/perfetto_build_flags.h b/tools/build/third_party/perfetto/perfetto_build_flags.h index 08b2079e4c..90092eddcf 100644 --- a/tools/build/third_party/perfetto/perfetto_build_flags.h +++ b/tools/build/third_party/perfetto/perfetto_build_flags.h @@ -37,5 +37,6 @@ #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_LINENOISE() (0) #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_PERCENTILE() (1) #define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_LOCAL_SYMBOLIZER() (1) +#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ZLIB() (1) #endif // GEN_BUILD_CONFIG_PERFETTO_BUILD_FLAGS_H_ diff --git a/tools/build/third_party/perfetto/perfetto_cfg.bzl b/tools/build/third_party/perfetto/perfetto_cfg.bzl index 4c17aa2c07..81400fe33a 100644 --- a/tools/build/third_party/perfetto/perfetto_cfg.bzl +++ b/tools/build/third_party/perfetto/perfetto_cfg.bzl @@ -52,6 +52,9 @@ PERFETTO_CONFIG = struct( sqlite_ext_percentile = ["@sqlite_src//:percentile_ext"], zlib = ["@net_zlib//:zlib"], ), + public_visibility = [ + "//visibility:public", + ], proto_library_visibility = "//visibility:public", deps_copts = struct( zlib = [], diff --git a/tools/build/workspace.bzl b/tools/build/workspace.bzl index 8e06e3a73e..1050af0634 100644 --- a/tools/build/workspace.bzl +++ b/tools/build/workspace.bzl @@ -163,7 +163,7 @@ def gapid_dependencies(android = True, mingw = True, locals = {}): name = "perfetto", locals = locals, remote = "https://android.googlesource.com/platform/external/perfetto", - commit = "975bbd74e6b1d7da8dbdaaeec9191fb28471ed2c", + commit = "15c8c3e5af6e843dfcaf036333b7ccdfbb1b725f", shallow_since = "1576864224 +0000", )