debug_marker: publish object names in a SQL-visible form as well - #40
Draft
jimblacklercorp wants to merge 1 commit into
Draft
jimblacklercorp wants to merge 1 commit into
jimblacklercorp wants to merge 1 commit into
Conversation
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
marked this pull request as draft
September 22, 2026 11:58
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.