Reland: Add proto for recording VkDebugMarkerSetObjectNameEXT

Reland of aosp/1154195
Bug: 140590067

Change-Id: I4e43f1d7a0a28caf12617fde3037f0900300840a
diff --git a/Android.bp b/Android.bp
index bf2d0bb..f3c60ad 100644
--- a/Android.bp
+++ b/Android.bp
@@ -3081,6 +3081,7 @@
     "protos/perfetto/trace/gpu/gpu_counter_event.proto",
     "protos/perfetto/trace/gpu/gpu_log.proto",
     "protos/perfetto/trace/gpu/gpu_render_stage_event.proto",
+    "protos/perfetto/trace/gpu/vulkan_api_event.proto",
     "protos/perfetto/trace/gpu/vulkan_memory_event.proto",
   ],
   tools: [
@@ -3091,6 +3092,7 @@
     "external/perfetto/protos/perfetto/trace/gpu/gpu_counter_event.pb.cc",
     "external/perfetto/protos/perfetto/trace/gpu/gpu_log.pb.cc",
     "external/perfetto/protos/perfetto/trace/gpu/gpu_render_stage_event.pb.cc",
+    "external/perfetto/protos/perfetto/trace/gpu/vulkan_api_event.pb.cc",
     "external/perfetto/protos/perfetto/trace/gpu/vulkan_memory_event.pb.cc",
   ],
 }
@@ -3102,6 +3104,7 @@
     "protos/perfetto/trace/gpu/gpu_counter_event.proto",
     "protos/perfetto/trace/gpu/gpu_log.proto",
     "protos/perfetto/trace/gpu/gpu_render_stage_event.proto",
+    "protos/perfetto/trace/gpu/vulkan_api_event.proto",
     "protos/perfetto/trace/gpu/vulkan_memory_event.proto",
   ],
   tools: [
@@ -3112,6 +3115,7 @@
     "external/perfetto/protos/perfetto/trace/gpu/gpu_counter_event.pb.h",
     "external/perfetto/protos/perfetto/trace/gpu/gpu_log.pb.h",
     "external/perfetto/protos/perfetto/trace/gpu/gpu_render_stage_event.pb.h",
+    "external/perfetto/protos/perfetto/trace/gpu/vulkan_api_event.pb.h",
     "external/perfetto/protos/perfetto/trace/gpu/vulkan_memory_event.pb.h",
   ],
   export_include_dirs: [
@@ -3127,6 +3131,7 @@
     "protos/perfetto/trace/gpu/gpu_counter_event.proto",
     "protos/perfetto/trace/gpu/gpu_log.proto",
     "protos/perfetto/trace/gpu/gpu_render_stage_event.proto",
+    "protos/perfetto/trace/gpu/vulkan_api_event.proto",
     "protos/perfetto/trace/gpu/vulkan_memory_event.proto",
   ],
   tools: [
@@ -3138,6 +3143,7 @@
     "external/perfetto/protos/perfetto/trace/gpu/gpu_counter_event.pbzero.cc",
     "external/perfetto/protos/perfetto/trace/gpu/gpu_log.pbzero.cc",
     "external/perfetto/protos/perfetto/trace/gpu/gpu_render_stage_event.pbzero.cc",
+    "external/perfetto/protos/perfetto/trace/gpu/vulkan_api_event.pbzero.cc",
     "external/perfetto/protos/perfetto/trace/gpu/vulkan_memory_event.pbzero.cc",
   ],
 }
@@ -3149,6 +3155,7 @@
     "protos/perfetto/trace/gpu/gpu_counter_event.proto",
     "protos/perfetto/trace/gpu/gpu_log.proto",
     "protos/perfetto/trace/gpu/gpu_render_stage_event.proto",
+    "protos/perfetto/trace/gpu/vulkan_api_event.proto",
     "protos/perfetto/trace/gpu/vulkan_memory_event.proto",
   ],
   tools: [
@@ -3160,6 +3167,7 @@
     "external/perfetto/protos/perfetto/trace/gpu/gpu_counter_event.pbzero.h",
     "external/perfetto/protos/perfetto/trace/gpu/gpu_log.pbzero.h",
     "external/perfetto/protos/perfetto/trace/gpu/gpu_render_stage_event.pbzero.h",
+    "external/perfetto/protos/perfetto/trace/gpu/vulkan_api_event.pbzero.h",
     "external/perfetto/protos/perfetto/trace/gpu/vulkan_memory_event.pbzero.h",
   ],
   export_include_dirs: [
diff --git a/BUILD b/BUILD
index ed835ea..7f7e153 100644
--- a/BUILD
+++ b/BUILD
@@ -1929,6 +1929,7 @@
         "protos/perfetto/trace/gpu/gpu_counter_event.proto",
         "protos/perfetto/trace/gpu/gpu_log.proto",
         "protos/perfetto/trace/gpu/gpu_render_stage_event.proto",
+        "protos/perfetto/trace/gpu/vulkan_api_event.proto",
         "protos/perfetto/trace/gpu/vulkan_memory_event.proto",
     ],
     visibility = [
diff --git a/protos/perfetto/trace/gpu/BUILD.gn b/protos/perfetto/trace/gpu/BUILD.gn
index 64b913a..fd1ba9f 100644
--- a/protos/perfetto/trace/gpu/BUILD.gn
+++ b/protos/perfetto/trace/gpu/BUILD.gn
@@ -22,6 +22,7 @@
     "gpu_counter_event.proto",
     "gpu_log.proto",
     "gpu_render_stage_event.proto",
+    "vulkan_api_event.proto",
     "vulkan_memory_event.proto",
   ]
 }
diff --git a/protos/perfetto/trace/gpu/vulkan_api_event.proto b/protos/perfetto/trace/gpu/vulkan_api_event.proto
new file mode 100644
index 0000000..b9a2a9d
--- /dev/null
+++ b/protos/perfetto/trace/gpu/vulkan_api_event.proto
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * 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.
+ */
+
+syntax = "proto2";
+option optimize_for = LITE_RUNTIME;
+
+package perfetto.protos;
+
+// Message for recording the Vulkan call.
+message VulkanApiEvent {
+  oneof event { VkDebugUtilsObjectName vk_debug_utils_object_name = 1; }
+
+  // For recording vkSetDebugUtilsObjectNameEXT and
+  // vkDebugMarkerSetObjectNameEXT
+  message VkDebugUtilsObjectName {
+    optional int32 pid = 1;
+    optional uint64 vk_device = 2;
+    optional uint64 object = 3;
+    optional string object_name = 4;
+  }
+}
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index 4f51daa..eeef7ac 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -3556,7 +3556,7 @@
 // TracePacket(s).
 //
 // Next reserved id: 13 (up to 15).
-// Next id: 64.
+// Next id: 66.
 message TracePacket {
   // The timestamp of the TracePacket.
   // By default this timestamps refers to the trace clock (CLOCK_BOOTTIME on
@@ -3606,6 +3606,7 @@
     GraphicsFrameEvent graphics_frame_event = 57;
     // removed field with id 62
     GpuLog gpu_log = 63;
+    VulkanApiEvent vulkan_api_event = 65;
 
     // Only used in profile packets.
     ProfiledFrameSymbols profiled_frame_symbols = 55;
@@ -4718,6 +4719,24 @@
 
 // End of protos/perfetto/trace/gpu/gpu_render_stage_event.proto
 
+// Begin of protos/perfetto/trace/gpu/vulkan_api_event.proto
+
+// Message for recording the Vulkan call.
+message VulkanApiEvent {
+  oneof event { VkDebugUtilsObjectName vk_debug_utils_object_name = 1; }
+
+  // For recording vkSetDebugUtilsObjectNameEXT and
+  // vkDebugMarkerSetObjectNameEXT
+  message VkDebugUtilsObjectName {
+    optional int32 pid = 1;
+    optional uint64 vk_device = 2;
+    optional uint64 object = 3;
+    optional string object_name = 4;
+  }
+}
+
+// End of protos/perfetto/trace/gpu/vulkan_api_event.proto
+
 // Begin of protos/perfetto/config/android/android_log_config.proto
 
 message AndroidLogConfig {
diff --git a/protos/perfetto/trace/trace_packet.proto b/protos/perfetto/trace/trace_packet.proto
index 9603776..da3b6af 100644
--- a/protos/perfetto/trace/trace_packet.proto
+++ b/protos/perfetto/trace/trace_packet.proto
@@ -33,6 +33,7 @@
 import "protos/perfetto/trace/gpu/gpu_log.proto";
 import "protos/perfetto/trace/gpu/gpu_render_stage_event.proto";
 import "protos/perfetto/trace/gpu/vulkan_memory_event.proto";
+import "protos/perfetto/trace/gpu/vulkan_api_event.proto";
 import "protos/perfetto/trace/interned_data/interned_data.proto";
 import "protos/perfetto/trace/perfetto/perfetto_metatrace.proto";
 import "protos/perfetto/trace/power/battery_counters.proto";
@@ -58,7 +59,7 @@
 // TracePacket(s).
 //
 // Next reserved id: 13 (up to 15).
-// Next id: 64.
+// Next id: 66.
 message TracePacket {
   // The timestamp of the TracePacket.
   // By default this timestamps refers to the trace clock (CLOCK_BOOTTIME on
@@ -108,6 +109,7 @@
     GraphicsFrameEvent graphics_frame_event = 57;
     VulkanMemoryEvent vulkan_memory_event = 62;
     GpuLog gpu_log = 63;
+    VulkanApiEvent vulkan_api_event = 65;
 
     // Only used in profile packets.
     ProfiledFrameSymbols profiled_frame_symbols = 55;
diff --git a/src/trace_processor/importers/proto/graphics_event_module.cc b/src/trace_processor/importers/proto/graphics_event_module.cc
index 7a75a99..4c9bfc2 100644
--- a/src/trace_processor/importers/proto/graphics_event_module.cc
+++ b/src/trace_processor/importers/proto/graphics_event_module.cc
@@ -28,6 +28,7 @@
   RegisterForField(TracePacket::kGpuLogFieldNumber, context);
   RegisterForField(TracePacket::kGraphicsFrameEventFieldNumber, context);
   RegisterForField(TracePacket::kVulkanMemoryEventFieldNumber, context);
+  RegisterForField(TracePacket::kVulkanApiEventFieldNumber, context);
 }
 
 GraphicsEventModule::~GraphicsEventModule() = default;
@@ -55,6 +56,9 @@
                                      ttp.packet_sequence_state_generation,
                                      decoder.vulkan_memory_event());
       return;
+    case TracePacket::kVulkanApiEventFieldNumber:
+      parser_.ParseVulkanApiEvent(decoder.vulkan_api_event());
+      return;
   }
 }
 
diff --git a/src/trace_processor/importers/proto/graphics_event_parser.cc b/src/trace_processor/importers/proto/graphics_event_parser.cc
index 3deef91..7008386 100644
--- a/src/trace_processor/importers/proto/graphics_event_parser.cc
+++ b/src/trace_processor/importers/proto/graphics_event_parser.cc
@@ -29,6 +29,8 @@
 #include "protos/perfetto/trace/gpu/gpu_counter_event.pbzero.h"
 #include "protos/perfetto/trace/gpu/gpu_log.pbzero.h"
 #include "protos/perfetto/trace/gpu/gpu_render_stage_event.pbzero.h"
+#include "protos/perfetto/trace/gpu/vulkan_api_event.pbzero.h"
+#include "protos/perfetto/trace/gpu/vulkan_memory_event.pbzero.h"
 #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
 
 namespace perfetto {
@@ -168,6 +170,40 @@
   }
 }
 
+const StringId GraphicsEventParser::GetFullStageName(
+    const protos::pbzero::GpuRenderStageEvent_Decoder& event) {
+  size_t stage_id = static_cast<size_t>(event.stage_id());
+  StringId stage_name;
+
+  if (stage_id < gpu_render_stage_ids_.size()) {
+    stage_name = gpu_render_stage_ids_[stage_id];
+  } else {
+    char buffer[64];
+    snprintf(buffer, sizeof(buffer), "render stage(%zu)", stage_id);
+    stage_name = context_->storage->InternString(buffer);
+  }
+  // If the slice has a render target handle, we append the hex value of the
+  // handle to the name.  If a debug marker is available, we append the name
+  // of the render target.
+  if (event.has_render_target_handle()) {
+    char buffer[256];
+    base::StringWriter str_writer(buffer, sizeof(buffer));
+    str_writer.AppendString(context_->storage->GetString(stage_name));
+    auto debug_marker_name =
+        debug_marker_names_.find(event.render_target_handle());
+    str_writer.AppendChar('[');
+    if (debug_marker_name == debug_marker_names_.end()) {
+      str_writer.AppendLiteral("0x");
+      str_writer.AppendHexInt(event.render_target_handle());
+    } else {
+      str_writer.AppendString(debug_marker_name->second);
+    }
+    str_writer.AppendChar(']');
+    stage_name = context_->storage->InternString(str_writer.GetStringView());
+  }
+  return stage_name;
+}
+
 void GraphicsEventParser::ParseGpuRenderStageEvent(int64_t ts,
                                                    ConstBytes blob) {
   protos::pbzero::GpuRenderStageEvent::Decoder event(blob.data, blob.size);
@@ -207,15 +243,8 @@
   };
 
   if (event.has_event_id()) {
-    size_t stage_id = static_cast<size_t>(event.stage_id());
-    StringId stage_name;
-    if (stage_id < gpu_render_stage_ids_.size()) {
-      stage_name = gpu_render_stage_ids_[stage_id];
-    } else {
-      char buffer[64];
-      snprintf(buffer, 64, "render stage(%zu)", stage_id);
-      stage_name = context_->storage->InternString(buffer);
-    }
+    StringId stage_name = GetFullStageName(event);
+
     TrackId track_id =
         gpu_hw_queue_ids_[static_cast<size_t>(event.hw_queue_id())];
     const auto slice_id = context_->slice_tracker->Scoped(
@@ -602,5 +631,14 @@
   context_->storage->mutable_gpu_slice_table()->Insert(row);
 }
 
+void GraphicsEventParser::ParseVulkanApiEvent(ConstBytes blob) {
+  protos::pbzero::VulkanApiEvent::Decoder vk_event(blob.data, blob.size);
+  if (vk_event.has_vk_debug_utils_object_name()) {
+    protos::pbzero::VulkanApiEvent_VkDebugUtilsObjectName::Decoder event(
+        vk_event.vk_debug_utils_object_name());
+    debug_marker_names_[event.object()] = event.object_name();
+  }
+}
+
 }  // namespace trace_processor
 }  // namespace perfetto
diff --git a/src/trace_processor/importers/proto/graphics_event_parser.h b/src/trace_processor/importers/proto/graphics_event_parser.h
index 38a0a8d..28c06ef 100644
--- a/src/trace_processor/importers/proto/graphics_event_parser.h
+++ b/src/trace_processor/importers/proto/graphics_event_parser.h
@@ -27,6 +27,15 @@
 #include "protos/perfetto/trace/gpu/vulkan_memory_event.pbzero.h"
 
 namespace perfetto {
+
+namespace protos {
+namespace pbzero {
+
+class GpuRenderStageEvent_Decoder;
+
+}  // namespace pbzero
+}  // namespace protos
+
 namespace trace_processor {
 
 class TraceProcessorContext;
@@ -57,7 +66,12 @@
   void UpdateVulkanMemoryAllocationCounters(UniquePid,
                                             const VulkanMemoryEvent::Decoder&);
 
+  void ParseVulkanApiEvent(ConstBytes);
+
  private:
+  const StringId GetFullStageName(
+      const protos::pbzero::GpuRenderStageEvent_Decoder& event);
+
   TraceProcessorContext* const context_;
   // For GpuCounterEvent
   std::unordered_map<uint32_t, TrackId> gpu_counter_track_ids_;
@@ -93,6 +107,8 @@
   const StringId tag_id_;
   const StringId log_message_id_;
   std::array<StringId, 7> log_severity_ids_;
+  // For Vulkan events.
+  std::unordered_map<uint64_t, ::protozero::ConstChars> debug_marker_names_;
 };
 }  // namespace trace_processor
 }  // namespace perfetto
diff --git a/test/synth_common.py b/test/synth_common.py
index 984105b..bf054fb 100644
--- a/test/synth_common.py
+++ b/test/synth_common.py
@@ -275,6 +275,65 @@
     gpu_counter.counter_id = counter_id
     gpu_counter.int_value = value
 
+  def add_gpu_render_stages_hw_queue_spec(self, specs=[]):
+    packet = self.add_packet()
+    spec = self.packet.gpu_render_stage_event.specifications
+    for s in specs:
+      hw_queue = spec.hw_queue.add()
+      hw_queue.name = s.get('name', '')
+      hw_queue.description = s.get('description', '')
+
+  def add_gpu_render_stages_stage_spec(self, specs=[]):
+    packet = self.add_packet()
+    spec = self.packet.gpu_render_stage_event.specifications
+    for s in specs:
+      stage = spec.stage.add()
+      stage.name = s.get('name', '')
+      stage.description = s.get('description', '')
+
+  def add_gpu_render_stages(self,
+                            ts,
+                            event_id,
+                            duration,
+                            hw_queue_id,
+                            stage_id,
+                            context,
+                            render_target_handle=None,
+                            render_pass_handle=None,
+                            command_buffer_handle=None,
+                            submission_id=None,
+                            extra_data={}):
+    packet = self.add_packet()
+    packet.timestamp = ts
+    render_stage = self.packet.gpu_render_stage_event
+    render_stage.event_id = event_id
+    render_stage.duration = duration
+    render_stage.hw_queue_id = hw_queue_id
+    render_stage.stage_id = stage_id
+    render_stage.context = context
+    if render_target_handle is not None:
+      render_stage.render_target_handle = render_target_handle
+    if render_pass_handle is not None:
+      render_stage.render_pass_handle = render_pass_handle
+    if command_buffer_handle is not None:
+      render_stage.command_buffer_handle = command_buffer_handle
+    if submission_id is not None:
+      render_stage.submission_id = submission_id
+    for key, value in extra_data.items():
+      data = render_stage.extra_data.add()
+      data.name = key
+      if value is not None:
+        data.value = value
+
+  def add_vk_debug_marker(self, ts, pid, vk_device, obj, obj_name):
+    packet = self.add_packet()
+    packet.timestamp = ts
+    debug_marker = (self.packet.vulkan_api_event.vk_debug_utils_object_name)
+    debug_marker.pid = pid
+    debug_marker.vk_device = vk_device
+    debug_marker.object = obj
+    debug_marker.object_name = obj_name
+
   def add_gpu_log(self, ts, severity, tag, message):
     packet = self.add_packet()
     packet.timestamp = ts
diff --git a/test/trace_processor/gpu_render_stages.out b/test/trace_processor/gpu_render_stages.out
index 4eaa783..058cff7 100644
--- a/test/trace_processor/gpu_render_stages.out
+++ b/test/trace_processor/gpu_render_stages.out
@@ -1,19 +1,22 @@
 "track_name","ts","dur","slice_name","depth","arg_set_id","flat_key","string_value","context_id","render_target","submission_id","hw_queue_id"
 "queue 1",10,5,"stage 1",0,1,"keyOnlyTest","[NULL]",42,0,0,1
 "queue 1",10,5,"stage 1",0,1,"stencilBPP","1",42,0,0,1
-"queue 1",10,5,"stage 1",0,1,"height","1.000000",42,0,0,1
+"queue 1",10,5,"stage 1",0,1,"height","1",42,0,0,1
 "queue 0",20,5,"stage 2",0,2,"keyOnlyTest","[NULL]",42,0,0,0
-"queue 0",20,5,"stage 2",0,2,"height","4.000000",42,0,0,0
+"queue 0",20,5,"stage 2",0,2,"height","4",42,0,0,0
 "queue 1",30,5,"stage 0",0,3,"keyOnlyTest","[NULL]",42,0,0,1
 "queue 1",30,5,"stage 0",0,3,"stencilBPP","1",42,0,0,1
-"queue 1",30,5,"stage 0",0,3,"height","9.000000",42,0,0,1
+"queue 1",30,5,"stage 0",0,3,"height","9",42,0,0,1
 "queue 0",40,5,"stage 1",0,0,"[NULL]","[NULL]",42,0,0,0
 "queue 1",50,5,"stage 2",0,4,"keyOnlyTest","[NULL]",42,0,0,1
 "queue 1",50,5,"stage 2",0,4,"stencilBPP","1",42,0,0,1
-"queue 1",50,5,"stage 2",0,4,"height","25.000000",42,0,0,1
+"queue 1",50,5,"stage 2",0,4,"height","25",42,0,0,1
 "queue 0",60,5,"stage 0",0,5,"keyOnlyTest","[NULL]",42,0,0,0
-"queue 0",60,5,"stage 0",0,5,"height","36.000000",42,0,0,0
+"queue 0",60,5,"stage 0",0,5,"height","36",42,0,0,0
 "queue 1",70,5,"stage 1",0,6,"keyOnlyTest","[NULL]",42,0,0,1
 "queue 1",70,5,"stage 1",0,6,"stencilBPP","1",42,0,0,1
-"queue 1",70,5,"stage 1",0,6,"height","49.000000",42,0,0,1
+"queue 1",70,5,"stage 1",0,6,"height","49",42,0,0,1
 "queue 0",80,5,"stage 2",0,0,"[NULL]","[NULL]",42,0,0,0
+"queue 0",90,5,"stage 0[0x10]",0,0,"[NULL]","[NULL]",42,16,0,0
+"queue 0",100,5,"stage 0[frame_buffer]",0,0,"[NULL]","[NULL]",42,16,0,0
+"queue 0",110,5,"stage 0[renamed_buffer]",0,0,"[NULL]","[NULL]",42,16,0,0
diff --git a/test/trace_processor/gpu_render_stages.py b/test/trace_processor/gpu_render_stages.py
new file mode 100644
index 0000000..ee1cc33
--- /dev/null
+++ b/test/trace_processor/gpu_render_stages.py
@@ -0,0 +1,91 @@
+#!/usr/bin/python
+# Copyright (C) 2019 The Android Open Source Project
+#
+# 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.
+
+from os import sys, path
+sys.path.append(path.dirname(path.dirname(path.abspath(__file__))))
+import synth_common
+
+trace = synth_common.create_trace()
+
+trace.add_gpu_render_stages_stage_spec([{
+    'name': 'stage 0'
+}, {
+    'name': 'stage 1'
+}, {
+    'name': 'stage 2'
+}])
+
+trace.add_gpu_render_stages_hw_queue_spec([{
+    'name': 'queue 0'
+}, {
+    'name': 'queue 1'
+}])
+
+for i in range(1, 8):
+  extra_data = {}
+  render_target_handle = None
+  if i % 4 != 0:
+    extra_data['keyOnlyTest'] = None
+    if i % 2 != 0:
+      extra_data['stencilBPP'] = '1'
+    extra_data['height'] = str(pow(i, 2))
+
+  trace.add_gpu_render_stages(
+      ts=i * 10,
+      event_id=i,
+      duration=5,
+      hw_queue_id=i % 2,
+      stage_id=i % 3,
+      context=42,
+      extra_data=extra_data)
+
+# Test stage naming with render target handle.
+trace.add_gpu_render_stages(
+    ts=80, event_id=8, duration=5, hw_queue_id=0, stage_id=2, context=42)
+
+trace.add_gpu_render_stages(
+    ts=90,
+    event_id=9,
+    duration=5,
+    hw_queue_id=0,
+    stage_id=0,
+    context=42,
+    render_target_handle=0x10)
+
+trace.add_vk_debug_marker(
+    ts=91, pid=100, vk_device=1, obj=0x10, obj_name="frame_buffer")
+
+trace.add_gpu_render_stages(
+    ts=100,
+    event_id=10,
+    duration=5,
+    hw_queue_id=0,
+    stage_id=0,
+    context=42,
+    render_target_handle=0x10)
+
+trace.add_vk_debug_marker(
+    ts=101, pid=100, vk_device=1, obj=0x10, obj_name="renamed_buffer")
+
+trace.add_gpu_render_stages(
+    ts=110,
+    event_id=11,
+    duration=5,
+    hw_queue_id=0,
+    stage_id=0,
+    context=42,
+    render_target_handle=0x10)
+
+print(trace.trace.SerializeToString())
diff --git a/test/trace_processor/index b/test/trace_processor/index
index fc2ba72..6a67620 100644
--- a/test/trace_processor/index
+++ b/test/trace_processor/index
@@ -122,7 +122,7 @@
 
 # GPU trace tests.
 gpu_counters.py gpu_counters.sql gpu_counters.out
-../data/gpu_trace.pb gpu_render_stages.sql gpu_render_stages.out
+gpu_render_stages.py gpu_render_stages.sql gpu_render_stages.out
 gpu_log.py gpu_log.sql gpu_log.out
 
 # Clock sync
diff --git a/tools/gen_merged_protos b/tools/gen_merged_protos
index 1289e37..1dee4a7 100755
--- a/tools/gen_merged_protos
+++ b/tools/gen_merged_protos
@@ -112,6 +112,7 @@
     'protos/perfetto/trace/gpu/gpu_counter_event.proto',
     'protos/perfetto/trace/gpu/gpu_log.proto',
     'protos/perfetto/trace/gpu/gpu_render_stage_event.proto',
+    'protos/perfetto/trace/gpu/vulkan_api_event.proto',
 )
 
 MERGED_TRACE_PROTO = 'protos/perfetto/trace/perfetto_trace.proto'