@@ -28,6 +28,10 @@ import {createTraceProcessorSliceTrack} from '../dev.perfetto.TraceProcessorTrac
2828interface GpuCounterSchema {
2929 readonly type : string ;
3030 readonly group : string | undefined ;
31+ // When set, the track is named "${gpu.displayName} ${gpuTrackName}" instead
32+ // of using the DB track name. This avoids redundant prefixes like
33+ // "GPU 0 GPU Memory" by allowing explicit control (e.g., "GPU 0 Memory").
34+ readonly gpuTrackName : string | undefined ;
3135}
3236
3337interface GpuSliceSchema {
@@ -36,13 +40,29 @@ interface GpuSliceSchema {
3640}
3741
3842const GPU_COUNTER_SCHEMAS : ReadonlyArray < GpuCounterSchema > = [
39- { type : 'gpu_counter' , group : 'Counters' } ,
40- { type : 'gpu_memory' , group : undefined } ,
41- { type : 'virtgpu_latency' , group : 'Virtgpu Latency' } ,
42- { type : 'virtgpu_num_free' , group : 'Virtgpu num_free' } ,
43- { type : 'vulkan_device_mem_allocation' , group : 'Vulkan Allocations' } ,
44- { type : 'vulkan_device_mem_bind' , group : 'Vulkan Binds' } ,
45- { type : 'vulkan_driver_mem' , group : 'Vulkan Driver Memory' } ,
43+ { type : 'gpu_counter' , group : 'Counters' , gpuTrackName : undefined } ,
44+ { type : 'gpu_memory' , group : undefined , gpuTrackName : 'Memory' } ,
45+ { type : 'virtgpu_latency' , group : 'Virtgpu Latency' , gpuTrackName : undefined } ,
46+ {
47+ type : 'virtgpu_num_free' ,
48+ group : 'Virtgpu num_free' ,
49+ gpuTrackName : undefined ,
50+ } ,
51+ {
52+ type : 'vulkan_device_mem_allocation' ,
53+ group : 'Vulkan Allocations' ,
54+ gpuTrackName : undefined ,
55+ } ,
56+ {
57+ type : 'vulkan_device_mem_bind' ,
58+ group : 'Vulkan Binds' ,
59+ gpuTrackName : undefined ,
60+ } ,
61+ {
62+ type : 'vulkan_driver_mem' ,
63+ group : 'Vulkan Driver Memory' ,
64+ gpuTrackName : undefined ,
65+ } ,
4666] ;
4767
4868const GPU_SLICE_SCHEMAS : ReadonlyArray < GpuSliceSchema > = [
@@ -231,6 +251,13 @@ export default class GpuPlugin implements PerfettoPlugin {
231251 ` ) ;
232252
233253 const schemas = new Map ( GPU_COUNTER_SCHEMAS . map ( ( x ) => [ x . type , x ] ) ) ;
254+ const counterTracks : Array < {
255+ schema : GpuCounterSchema ;
256+ gpu : Gpu | null ;
257+ trackName : string ;
258+ baseName : string ;
259+ uri : string ;
260+ } > = [ ] ;
234261 const it = result . iter ( {
235262 id : NUM ,
236263 type : STR ,
@@ -262,7 +289,10 @@ export default class GpuPlugin implements PerfettoPlugin {
262289 gpuId !== null
263290 ? new Gpu ( ugpu ?? trackId , gpuId , machineId , gpuName ?? undefined )
264291 : null ;
265- const trackName = getTrackName ( { name, kind : COUNTER_TRACK_KIND } ) ;
292+ let trackName = getTrackName ( { name, kind : COUNTER_TRACK_KIND } ) ;
293+ if ( gpu !== null && schema . gpuTrackName !== undefined ) {
294+ trackName = `${ gpu . displayName } ${ schema . gpuTrackName } ${ gpu . maybeMachineLabel ( ) } ` ;
295+ }
266296 const uri = `/counter_${ ugpu ?? trackId } _${ trackId } ` ;
267297
268298 ctx . tracks . registerTrack ( {
@@ -284,10 +314,44 @@ export default class GpuPlugin implements PerfettoPlugin {
284314 trackName ,
285315 ) ,
286316 } ) ;
317+
318+ counterTracks . push ( {
319+ schema,
320+ gpu,
321+ trackName,
322+ baseName : getTrackName ( { name, kind : COUNTER_TRACK_KIND } ) ,
323+ uri,
324+ } ) ;
325+ }
326+
327+ // Count ungrouped tracks per type to decide if a sub-group is needed,
328+ // matching the GPU Frequency pattern: only create a sub-group when
329+ // there are multiple tracks of the same type.
330+ const ungroupedCounts = new Map < string , number > ( ) ;
331+ for ( const { schema} of counterTracks ) {
332+ if ( schema . group === undefined ) {
333+ ungroupedCounts . set (
334+ schema . type ,
335+ ( ungroupedCounts . get ( schema . type ) ?? 0 ) + 1 ,
336+ ) ;
337+ }
338+ }
339+
340+ for ( const { schema, gpu, trackName, baseName, uri} of counterTracks ) {
341+ let group = schema . group ;
342+ let groupGpu = gpu ;
343+ if ( group === undefined && ( ungroupedCounts . get ( schema . type ) ?? 0 ) > 1 ) {
344+ // Multiple tracks of the same ungrouped type: create a sub-group
345+ // using the base track name (e.g., "GPU Memory") and add tracks
346+ // directly under it without per-GPU sub-groups, matching how
347+ // addGpuFreq handles GPU Frequency tracks.
348+ group = baseName ;
349+ groupGpu = null ;
350+ }
287351 this . addToGpuGroup (
288352 ctx ,
289- schema . group ,
290- gpu ,
353+ group ,
354+ groupGpu ,
291355 new TrackNode ( { uri, name : trackName , sortOrder : 0 } ) ,
292356 ) ;
293357 }
0 commit comments