diff --git a/layersvt/debug_marker/debug_marker.cpp b/layersvt/debug_marker/debug_marker.cpp index 11bf435ad2..6c6942df4b 100644 --- a/layersvt/debug_marker/debug_marker.cpp +++ b/layersvt/debug_marker/debug_marker.cpp @@ -20,6 +20,26 @@ #include "perfetto/perfetto.h" #include +namespace { + +// The packet shares the track event sequence, whose defaults declare an incremental clock, so the +// absolute timestamp must carry an explicit clock id to not be read as a delta. +void EmitDebugObjectNamePacket(uint64_t device, int32_t type, uint64_t handle, const std::string& name) { + perfetto::TrackEvent::Trace([device, type, handle, &name](perfetto::TrackEvent::TraceContext ctx) { + auto packet = ctx.NewTracePacket(); + packet->set_timestamp(perfetto::TrackEvent::GetTraceTimeNs()); + packet->set_timestamp_clock_id(static_cast(perfetto::TrackEvent::GetTraceClockId())); + auto event = packet->set_vulkan_api_event()->set_vk_debug_utils_object_name(); + event->set_pid(static_cast(perfetto::base::GetProcessId())); + event->set_vk_device(device); + event->set_object_type(type); + event->set_object(handle); + event->set_object_name(name.data(), name.size()); + }); +} + +} // namespace + DebugMarker::DebugMarker() = default; const layersvt::LayerManifest* DebugMarker::GetLayerManifest() const { @@ -78,36 +98,14 @@ void DebugMarker::SetDebugObjectName(uint64_t device, int32_t type, uint64_t han std::string name_str = name ? name : "NULL"; debug_object_names_[std::make_pair(type, handle)] = DebugObjectName(device, type, handle, name_str); - - perfetto::TrackEvent::Trace([device, type, handle, name_str](perfetto::TrackEvent::TraceContext ctx) { - auto packet = ctx.NewTracePacket(); - packet->set_timestamp(perfetto::base::GetBootTimeNs().count()); - auto event = packet->set_vulkan_api_event()->set_vk_debug_utils_object_name(); - event->set_vk_device(device); - event->set_object_type(type); - event->set_object(handle); - event->set_object_name(name_str.c_str()); - }); + EmitDebugObjectNamePacket(device, type, handle, name_str); } void DebugMarker::EmitAllDebugMarkers() { std::lock_guard lock(mutex_); for (const auto& entry : debug_object_names_) { const auto& marker = entry.second; - uint64_t device = marker.vk_device; - int32_t type = marker.object_type; - uint64_t handle = marker.handle; - std::string name_str = marker.name; - - perfetto::TrackEvent::Trace([device, type, handle, name_str](perfetto::TrackEvent::TraceContext ctx) { - auto packet = ctx.NewTracePacket(); - packet->set_timestamp(perfetto::base::GetBootTimeNs().count()); - auto event = packet->set_vulkan_api_event()->set_vk_debug_utils_object_name(); - event->set_vk_device(device); - event->set_object_type(type); - event->set_object(handle); - event->set_object_name(name_str.c_str()); - }); + EmitDebugObjectNamePacket(marker.vk_device, marker.object_type, marker.handle, marker.name); } } diff --git a/layersvt/test/test_debugmarker.cpp b/layersvt/test/test_debugmarker.cpp index 544fa7fc53..825f84f605 100644 --- a/layersvt/test/test_debugmarker.cpp +++ b/layersvt/test/test_debugmarker.cpp @@ -15,6 +15,7 @@ #include "layer_test_helper.h" #include "../debug_marker/debug_marker.h" +#include "../debug_marker/debug_marker_perfetto.h" #include #include #include @@ -430,3 +431,63 @@ TEST_F(DebugMarkerTests, ForwardedDebugUtilsMessengerTest) { commands.destroy(mock_instance, messenger, nullptr); EXPECT_EQ(downstream_destroy_messenger_calls, 1u); } + +TEST_F(DebugMarkerTests, ObjectNamePacketFieldsTest) { + TEST_DESCRIPTION("Verify emitted VkDebugUtilsObjectName TracePacket has timestamp_clock_id, pid, and object name fields"); + + perfetto::TracingInitArgs args; + args.backends = perfetto::kInProcessBackend; + perfetto::Tracing::Initialize(args); + perfetto::TrackEvent::Register(); + + perfetto::TraceConfig cfg; + cfg.add_buffers()->set_size_kb(1024); + auto* ds_cfg = cfg.add_data_sources()->mutable_config(); + ds_cfg->set_name("track_event"); + + auto tracing_session = perfetto::Tracing::NewTrace(); + ASSERT_NE(tracing_session, nullptr); + tracing_session->Setup(cfg); + tracing_session->StartBlocking(); + + constexpr uint64_t kDevice = 0x1234u; + constexpr int32_t kObjectType = VK_OBJECT_TYPE_BUFFER; + constexpr uint64_t kObjectHandle = 0x5678u; + constexpr const char* kObjectName = "TestBufferName"; + + DebugMarker::Get().SetDebugObjectName(kDevice, kObjectType, kObjectHandle, kObjectName); + + perfetto::TrackEvent::Flush(); + tracing_session->StopBlocking(); + std::vector raw_trace = tracing_session->ReadTraceBlocking(); + ASSERT_FALSE(raw_trace.empty()); + + perfetto::protos::pbzero::Trace::Decoder trace(reinterpret_cast(raw_trace.data()), raw_trace.size()); + bool found = false; + for (auto it = trace.packet(); it; ++it) { + perfetto::protos::pbzero::TracePacket::Decoder packet(*it); + if (!packet.has_vulkan_api_event()) { + continue; + } + perfetto::protos::pbzero::VulkanApiEvent::Decoder vk_event(packet.vulkan_api_event()); + if (!vk_event.has_vk_debug_utils_object_name()) { + continue; + } + perfetto::protos::pbzero::VulkanApiEvent_VkDebugUtilsObjectName::Decoder event( + vk_event.vk_debug_utils_object_name()); + if (event.object() != kObjectHandle) { + continue; + } + found = true; + EXPECT_TRUE(packet.has_timestamp()); + EXPECT_TRUE(packet.has_timestamp_clock_id()); + EXPECT_EQ(packet.timestamp_clock_id(), static_cast(perfetto::TrackEvent::GetTraceClockId())); + EXPECT_TRUE(event.has_pid()); + EXPECT_EQ(event.pid(), static_cast(perfetto::base::GetProcessId())); + EXPECT_EQ(event.vk_device(), kDevice); + EXPECT_EQ(event.object_type(), kObjectType); + EXPECT_EQ(event.object(), kObjectHandle); + EXPECT_EQ(event.object_name().ToStdString(), kObjectName); + } + EXPECT_TRUE(found); +}