Skip to content

debug_marker: publish object names in a SQL-visible form as well - #40

Draft
jimblacklercorp wants to merge 1 commit into
android-graphics:mainfrom
jimblacklercorp:debugmarker-names-for-memory
Draft

jimblacklercorp wants to merge 1 commit into
android-graphics:mainfrom
jimblacklercorp:debugmarker-names-for-memory

Conversation

@jimblacklercorp

Copy link
Copy Markdown

The layer already records every object name the application sets and writes it as a VulkanApiEvent.VkDebugUtilsObjectName packet. trace_processor keeps those in a private lookup that it consults only while parsing GpuRenderStageEvent, so they become render pass, render target and command buffer names on GPU queue slices and are reachable no other way. A name on a buffer or image is parsed and then never surfaced, and nothing in SQL can see any of them.

That leaves consumers outside the GPU render stage path with no way to identify the objects they are reporting on. Sherlock's Vulkan memory snapshot is the immediate case: it lists live allocations by handle, and a 64-bit handle tells a developer nothing about which texture or vertex buffer is holding the memory.

Emit each name a second time as a "VulkanObjectName" instant event. Instants land in the slice table with their arguments intact, so a consumer can join a name to any object, of any type, by handle. Neither representation subsumes the other - the packet is the only form the render stage parser reads, the slice is the only form SQL can see - so both are written. A name is a few dozen bytes and is written once per naming call, not per frame.

Both emissions go through a new Emit(), which also removes the copy of the packet-writing code that SetDebugObjectName and EmitAllDebugMarkers each carried. Session-start replay therefore publishes both representations too, which is what keeps names visible to a session that attaches after the application has already named its objects.

Set timestamp_clock_id on the raw packet. This is not cosmetic. The SDK only publishes TracePacketDefaults, which carry timestamp_clock_id = the incremental clock, once a sequence actually writes a track event. Until this change the layer wrote nothing but raw packets, so no defaults were emitted and the absolute boot-time timestamp was read as boot time. Adding the instant event makes the SDK publish those defaults, and a packet that sets a timestamp without naming a clock then inherits the incremental one - so an absolute boot-time value is read as a delta of however long the device has been up. Measured on a ten second capture: the sequence clock advanced by 1.7 hours per name, every incremental state clear briefly reset it, and 4524 of 4535 name slices landed days past the end of the trace, where a consumer filtering on ts would never see them. The other layers are unaffected; this is the only one that writes a raw packet alongside its track events.

Nothing else changes: the same names, at the same points, from the same layer. Consumers that want names in the memory snapshot must record with this layer enabled, which is deliberate - no other layer duplicates its bookkeeping.

The layer already records every object name the application sets and writes it
as a VulkanApiEvent.VkDebugUtilsObjectName packet. trace_processor keeps those
in a private lookup that it consults only while parsing GpuRenderStageEvent, so
they become render pass, render target and command buffer names on GPU queue
slices and are reachable no other way. A name on a buffer or image is parsed and
then never surfaced, and nothing in SQL can see any of them.

That leaves consumers outside the GPU render stage path with no way to identify
the objects they are reporting on. Sherlock's Vulkan memory snapshot is the
immediate case: it lists live allocations by handle, and a 64-bit handle tells a
developer nothing about which texture or vertex buffer is holding the memory.

Emit each name a second time as a "VulkanObjectName" instant event. Instants
land in the slice table with their arguments intact, so a consumer can join a
name to any object, of any type, by handle. Neither representation subsumes the
other - the packet is the only form the render stage parser reads, the slice is
the only form SQL can see - so both are written. A name is a few dozen bytes and
is written once per naming call, not per frame.

Both emissions go through a new Emit(), which also removes the copy of the
packet-writing code that SetDebugObjectName and EmitAllDebugMarkers each carried.
Session-start replay therefore publishes both representations too, which is what
keeps names visible to a session that attaches after the application has already
named its objects.

Set timestamp_clock_id on the raw packet. This is not cosmetic. The SDK only
publishes TracePacketDefaults, which carry timestamp_clock_id = the incremental
clock, once a sequence actually writes a track event. Until this change the
layer wrote nothing but raw packets, so no defaults were emitted and the
absolute boot-time timestamp was read as boot time. Adding the instant event
makes the SDK publish those defaults, and a packet that sets a timestamp without
naming a clock then inherits the incremental one - so an absolute boot-time
value is read as a delta of however long the device has been up. Measured on a
ten second capture: the sequence clock advanced by 1.7 hours per name, every
incremental state clear briefly reset it, and 4524 of 4535 name slices landed
days past the end of the trace, where a consumer filtering on ts would never see
them. The other layers are unaffected; this is the only one that writes a raw
packet alongside its track events.

Nothing else changes: the same names, at the same points, from the same layer.
Consumers that want names in the memory snapshot must record with this layer
enabled, which is deliberate - no other layer duplicates its bookkeeping.
@jimblacklercorp
jimblacklercorp marked this pull request as draft September 22, 2026 11:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant