From 4124186b1d68ce72e608ec4dab73ef376242e695 Mon Sep 17 00:00:00 2001 From: Peter Harris Date: Mon, 7 Apr 2025 11:19:04 +0100 Subject: [PATCH 1/2] Timeline layer: Update AS build/update in viewer Viewer will now handle the AS update stage type sent by Perfetto. Viewer will now decode fast_build, fast_trace, and update from the Perfetto stage data and report it in the GUI as a subtype, as we cannot get this from the layer today. --- .gitignore | 1 + lglpy/timeline/data/processed_trace.py | 10 +++- lglpy/timeline/data/raw_trace.py | 80 ++++++++++++++++---------- 3 files changed, 61 insertions(+), 30 deletions(-) diff --git a/.gitignore b/.gitignore index 9b3b8f4..bf49e5c 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ build* # Data files and build outputs *.gputl *.log +*.metadata *.perfetto *.so diff --git a/lglpy/timeline/data/processed_trace.py b/lglpy/timeline/data/processed_trace.py index bb323cf..f7ac7c5 100644 --- a/lglpy/timeline/data/processed_trace.py +++ b/lglpy/timeline/data/processed_trace.py @@ -600,8 +600,16 @@ def __init__( # Populate common data super().__init__(event, metadata) + # We cannot get specific subtypes from the layer, as one API call can + # contain a mixture of subtypes and is ambiguous. Instead we infer it + # from the Perfetto stage data generated by the driver which is + # subtype-specific, with multiple workloads per Vulkan command if + # the command contains multiple subtypes. + assert metadata.subtype == 'Unknown' + assert event.stage is not None + self.build_type = GPUStageID.get_ui_name(event.stage) + # We must have metadata so no need to check - self.build_type = metadata.subtype self.primitive_count = metadata.primitive_count def get_long_label(self) -> str: diff --git a/lglpy/timeline/data/raw_trace.py b/lglpy/timeline/data/raw_trace.py index d846186..be2dc40 100644 --- a/lglpy/timeline/data/raw_trace.py +++ b/lglpy/timeline/data/raw_trace.py @@ -91,9 +91,13 @@ class GPUStageID(enum.IntEnum): FRAGMENT: Fragment shaders from a render pass. BINNING: Binning subset of vertex shaders from a render pass. MAIN: Main phase vertex and fragment shaders from a render pass. - IMAGE_TRANSFER: Transfers writing an image output. + TRACE_RAYS: Ray tracing pipeline dispatch. + AS_TRANSFER: Transfer writing to/from an acceleration structure. BUFFER_TRANSFER: Transfer writing a buffer output. - ASBUILD: Acceleration structure build. + IMAGE_TRANSFER: Transfers writing an image output. + AS_BUILD_FAST_BUILD: Acceleration structure build with fast_build. + AS_BUILD_FAST_TRACE: Acceleration structure build with fast_trace. + AS_BUILD_UPDATE: Acceleration structure build with update. ''' COMPUTE = 0 ADVANCED_GEOMETRY = 1 @@ -101,9 +105,14 @@ class GPUStageID(enum.IntEnum): FRAGMENT = 3 BINNING = 4 MAIN = 5 - IMAGE_TRANSFER = 6 - BUFFER_TRANSFER = 7 - ASBUILD = 8 + TRACE_RAYS = 6 + AS_TRANSFER = 7 + BUFFER_TRANSFER = 8 + IMAGE_TRANSFER = 9 + AS_BUILD_FAST_BUILD = 10 + AS_BUILD_FAST_TRACE = 11 + AS_BUILD_UPDATE = 12 + @classmethod def get_ui_name(cls, stage_id) -> str: @@ -123,9 +132,13 @@ def get_ui_name(cls, stage_id) -> str: cls.FRAGMENT: 'Fragment', cls.BINNING: 'Binning', cls.MAIN: 'Main', - cls.IMAGE_TRANSFER: 'Image transfer', + cls.TRACE_RAYS: 'Trace rays', + cls.AS_TRANSFER: 'AS transfer', cls.BUFFER_TRANSFER: 'Buffer transfer', - cls.ASBUILD: 'Acceleration structure build', + cls.IMAGE_TRANSFER: 'Image transfer', + cls.AS_BUILD_FAST_BUILD: 'AS build (fast build)', + cls.AS_BUILD_FAST_TRACE: 'AS build (fast trace)', + cls.AS_BUILD_UPDATE: 'AS build (update)' } return human_names[stage_id] @@ -580,30 +593,39 @@ class PerfettoConfig: ''' # Known Perfetto streams and their remapped names STREAM_REMAP = { - "compute": GPUStreamID.COMPUTE, - "non-fragment": GPUStreamID.NONFRAGMENT, - "fragment": GPUStreamID.FRAGMENT, - "binning": GPUStreamID.BINNING, - "main": GPUStreamID.MAIN, - "transfer": GPUStreamID.TRANSFER + 'compute': GPUStreamID.COMPUTE, + 'vertex': GPUStreamID.NONFRAGMENT, + 'non-fragment': GPUStreamID.NONFRAGMENT, + 'fragment': GPUStreamID.FRAGMENT, + 'binning': GPUStreamID.BINNING, + 'main': GPUStreamID.MAIN, + 'transfer': GPUStreamID.TRANSFER } # Known Perfetto render stages and their remapped names STAGE_REMAP = { - "clear image": GPUStageID.IMAGE_TRANSFER, - "copy image": GPUStageID.IMAGE_TRANSFER, - "blit image": GPUStageID.IMAGE_TRANSFER, - "generate mipmap": GPUStageID.IMAGE_TRANSFER, - "copy buffer": GPUStageID.BUFFER_TRANSFER, - "fill buffer": GPUStageID.BUFFER_TRANSFER, - "compute": GPUStageID.COMPUTE, - "advanced geometry": GPUStageID.ADVANCED_GEOMETRY, - "vertex": GPUStageID.VERTEX, - "fragment": GPUStageID.FRAGMENT, - "binning": GPUStageID.BINNING, - "main": GPUStageID.MAIN, - "acceleration structure 'fast build' build": GPUStageID.ASBUILD, - "acceleration structure 'fast trace' build": GPUStageID.ASBUILD, + 'clear image': GPUStageID.IMAGE_TRANSFER, + 'copy image': GPUStageID.IMAGE_TRANSFER, + 'blit image': GPUStageID.IMAGE_TRANSFER, + 'resolve image': GPUStageID.IMAGE_TRANSFER, + 'generate mipmap': GPUStageID.IMAGE_TRANSFER, + 'copy buffer': GPUStageID.BUFFER_TRANSFER, + 'fill buffer': GPUStageID.BUFFER_TRANSFER, + 'copy query': GPUStageID.BUFFER_TRANSFER, + 'compute': GPUStageID.COMPUTE, + 'trace_rays': GPUStageID.TRACE_RAYS, + 'advanced geometry': GPUStageID.ADVANCED_GEOMETRY, + 'vertex': GPUStageID.VERTEX, + 'fragment': GPUStageID.FRAGMENT, + 'binning': GPUStageID.BINNING, + 'main': GPUStageID.MAIN, + "acceleration structure 'fast build' build": + GPUStageID.AS_BUILD_FAST_BUILD, + "acceleration structure 'fast trace' build": + GPUStageID.AS_BUILD_FAST_TRACE, + 'acceleration structure copy to memory': GPUStageID.AS_TRANSFER, + 'acceleration structure copy from memory': GPUStageID.AS_TRANSFER, + 'acceleration structure update': GPUStageID.BUFFER_TRANSFER } def __init__(self): @@ -731,7 +753,7 @@ def replace_interned_stage(self, event: RenderstageEvent) -> None: # Interned ID does not exist else: - assert False, "Stage IID not found" + assert False, 'ERROR: Unknown stage interned data ID' class RawTrace: @@ -863,7 +885,7 @@ def load_perfetto_from_file( for event in trace_events: event.start_time -= start_time - # Also ensure that "queued time" does not show as running + # Also ensure that queued time does not show as running if event.stream not in streams: streams[event.stream] = [event] continue From d2fe6f193b140b839b84745e24fa4ea684f8bc2e Mon Sep 17 00:00:00 2001 From: Peter Harris Date: Mon, 7 Apr 2025 13:30:10 +0100 Subject: [PATCH 2/2] Fix whitespace --- lglpy/timeline/data/raw_trace.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lglpy/timeline/data/raw_trace.py b/lglpy/timeline/data/raw_trace.py index be2dc40..9ceb379 100644 --- a/lglpy/timeline/data/raw_trace.py +++ b/lglpy/timeline/data/raw_trace.py @@ -113,7 +113,6 @@ class GPUStageID(enum.IntEnum): AS_BUILD_FAST_TRACE = 11 AS_BUILD_UPDATE = 12 - @classmethod def get_ui_name(cls, stage_id) -> str: '''