From cc963789afa48c051af18c82e53e271762a62e3a Mon Sep 17 00:00:00 2001 From: Peter Harris Date: Tue, 14 Oct 2025 21:55:54 +0100 Subject: [PATCH 1/2] Timeline layer: Add VK_ARM_data_graph support --- layer_gpu_timeline/source/CMakeLists.txt | 1 + .../source/layer_device_functions.hpp | 8 +++ ...r_device_functions_dispatch_data_graph.cpp | 55 +++++++++++++++++++ .../source/timeline_protobuf_encoder.cpp | 33 ++++++++++- .../source/timeline_protobuf_encoder.hpp | 1 + layer_gpu_timeline/timeline.proto | 9 +++ source_common/trackers/command_buffer.cpp | 15 +++++ source_common/trackers/command_buffer.hpp | 7 +++ .../trackers/layer_command_stream.cpp | 6 ++ .../trackers/layer_command_stream.hpp | 18 +++++- source_common/trackers/queue.cpp | 7 ++- source_common/trackers/queue.hpp | 8 +++ source_common/trackers/stats.hpp | 36 ++++++++---- 13 files changed, 189 insertions(+), 15 deletions(-) create mode 100644 layer_gpu_timeline/source/layer_device_functions_dispatch_data_graph.cpp diff --git a/layer_gpu_timeline/source/CMakeLists.txt b/layer_gpu_timeline/source/CMakeLists.txt index a8b575f..efe08d7 100644 --- a/layer_gpu_timeline/source/CMakeLists.txt +++ b/layer_gpu_timeline/source/CMakeLists.txt @@ -47,6 +47,7 @@ add_library( layer_device_functions_command_buffer.cpp layer_device_functions_command_pool.cpp layer_device_functions_debug.cpp + layer_device_functions_dispatch_data_graph.cpp layer_device_functions_dispatch.cpp layer_device_functions_draw_call.cpp layer_device_functions_queue.cpp diff --git a/layer_gpu_timeline/source/layer_device_functions.hpp b/layer_gpu_timeline/source/layer_device_functions.hpp index 9eaf553..1030b35 100644 --- a/layer_gpu_timeline/source/layer_device_functions.hpp +++ b/layer_gpu_timeline/source/layer_device_functions.hpp @@ -279,6 +279,14 @@ VKAPI_ATTR void VKAPI_CALL layer_vkCmdDispatchIndirect(VkCommandBuffer VkBuffer buffer, VkDeviceSize offset); +// Commands for data graph + +/* See Vulkan API for documentation. */ +template<> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdDispatchDataGraphARM(VkCommandBuffer commandBuffer, + VkDataGraphPipelineSessionARM session, + const VkDataGraphPipelineDispatchInfoARM* pInfo); + // Commands for trace rays /* See Vulkan API for documentation. */ diff --git a/layer_gpu_timeline/source/layer_device_functions_dispatch_data_graph.cpp b/layer_gpu_timeline/source/layer_device_functions_dispatch_data_graph.cpp new file mode 100644 index 0000000..f28bcc3 --- /dev/null +++ b/layer_gpu_timeline/source/layer_device_functions_dispatch_data_graph.cpp @@ -0,0 +1,55 @@ +/* + * SPDX-License-Identifier: MIT + * ---------------------------------------------------------------------------- + * Copyright (c) 2025 Arm Limited + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * ---------------------------------------------------------------------------- + */ + +#include "device.hpp" +#include "device_utils.hpp" +#include "framework/device_dispatch_table.hpp" + +#include + +extern std::mutex g_vulkanLock; + +/* See Vulkan API for documentation. */ +template<> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdDispatchDataGraphARM(VkCommandBuffer commandBuffer, + VkDataGraphPipelineSessionARM session, + const VkDataGraphPipelineDispatchInfoARM* pInfo) +{ + LAYER_TRACE(__func__); + + // Hold the lock to access layer-wide global store + std::unique_lock lock {g_vulkanLock}; + auto* layer = Device::retrieve(commandBuffer); + + auto& tracker = layer->getStateTracker(); + auto& cb = tracker.getCommandBuffer(commandBuffer); + uint64_t tagID = cb.dispatchDataGraph(); + + // Release the lock to call into the driver + lock.unlock(); + emitStartTag(layer, commandBuffer, tagID); + layer->driver.vkCmdDispatchDataGraphARM(commandBuffer, session, pInfo); + emitEndTag(layer, commandBuffer); +} diff --git a/layer_gpu_timeline/source/timeline_protobuf_encoder.cpp b/layer_gpu_timeline/source/timeline_protobuf_encoder.cpp index bd8bf76..21f0c77 100644 --- a/layer_gpu_timeline/source/timeline_protobuf_encoder.cpp +++ b/layer_gpu_timeline/source/timeline_protobuf_encoder.cpp @@ -148,6 +148,13 @@ using Dispatch = pp::message< /* Any user defined debug labels associated with the dispatch */ pp::string_field<"debug_label", 5, pp::repeated>>; +/* A dispatch data graph object submission */ +using DispatchDataGraph = pp::message< + /* The unique identifier for this operation */ + pp::uint64_field<"tag_id", 1>, + /* Any user defined debug labels associated with the dispatch */ + pp::string_field<"debug_label", 2, pp::repeated>>; + /* A trace rays object submission */ using TraceRays = pp::message< /* The unique identifier for this operation */ @@ -251,7 +258,8 @@ using TimelineRecord = pp::message_field<"image_transfer", 9, ImageTransfer>, pp::message_field<"buffer_transfer", 10, BufferTransfer>, pp::message_field<"acceleration_structure_build", 11, AccelerationStructureBuild>, - pp::message_field<"acceleration_structure_transfer", 12, AccelerationStructureTransfer>>; + pp::message_field<"acceleration_structure_transfer", 12, AccelerationStructureTransfer>, + pp::message_field<"dispatch_data_graph", 13, DispatchDataGraph>>; namespace { @@ -527,6 +535,23 @@ Comms::MessageData serialize(const Tracker::LCSDispatch& dispatch, const std::ve }); } +/** + * @brief Get the metadata for this workload + * + * @param dispatch The dispatch data graph to serialize + * @param debugLabel The debug label stack for the VkQueue at submit time. + */ +Comms::MessageData serialize(const Tracker::LCSDispatchDataGraph& dispatch, const std::vector& debugLabel) +{ + using namespace pp; + + return packBuffer("dispatch_data_graph"_f, + DispatchDataGraph { + dispatch.getTagID(), + debugLabel, + }); +} + /** * @brief Get the metadata for this workload * @@ -702,6 +727,12 @@ void TimelineProtobufEncoder::operator()(const Tracker::LCSDispatch& dispatch, device.txMessage(serialize(dispatch, debugStack)); } +void TimelineProtobufEncoder::operator()(const Tracker::LCSDispatchDataGraph& dispatch, + const std::vector& debugStack) +{ + device.txMessage(serialize(dispatch, debugStack)); +} + void TimelineProtobufEncoder::operator()(const Tracker::LCSTraceRays& traceRays, const std::vector& debugStack) { diff --git a/layer_gpu_timeline/source/timeline_protobuf_encoder.hpp b/layer_gpu_timeline/source/timeline_protobuf_encoder.hpp index 75f0883..368c0da 100644 --- a/layer_gpu_timeline/source/timeline_protobuf_encoder.hpp +++ b/layer_gpu_timeline/source/timeline_protobuf_encoder.hpp @@ -112,6 +112,7 @@ class TimelineProtobufEncoder : public Tracker::SubmitCommandWorkloadVisitor const std::vector& debugStack, uint64_t renderPassTagID) override; void operator()(const Tracker::LCSDispatch& dispatch, const std::vector& debugStack) override; + void operator()(const Tracker::LCSDispatchDataGraph& dispatch, const std::vector& debugStack) override; void operator()(const Tracker::LCSTraceRays& traceRays, const std::vector& debugStack) override; void operator()(const Tracker::LCSImageTransfer& imageTransfer, const std::vector& debugStack) override; diff --git a/layer_gpu_timeline/timeline.proto b/layer_gpu_timeline/timeline.proto index 5cfb0b0..fa22823 100644 --- a/layer_gpu_timeline/timeline.proto +++ b/layer_gpu_timeline/timeline.proto @@ -209,6 +209,14 @@ message Dispatch { repeated string debug_label = 5; } +/* A dispatch data graph object submission */ +message DispatchDataGraph { + /* The unique identifier for this operation */ + uint64 tag_id = 1; + /* Any user defined debug labels associated with the dispatch */ + repeated string debug_label = 2; +} + /* A trace rays object submission */ message TraceRays { /* The unique identifier for this operation */ @@ -317,4 +325,5 @@ message TimelineRecord { BufferTransfer buffer_transfer = 10; AccelerationStructureBuild acceleration_structure_build = 11; AccelerationStructureTransfer acceleration_structure_transfer = 12; + DispatchDataGraph dispatch_data_graph = 13; } diff --git a/source_common/trackers/command_buffer.cpp b/source_common/trackers/command_buffer.cpp index f2f544c..bc8c363 100644 --- a/source_common/trackers/command_buffer.cpp +++ b/source_common/trackers/command_buffer.cpp @@ -144,6 +144,21 @@ uint64_t CommandBuffer::dispatch(int64_t xGroups, int64_t yGroups, int64_t zGrou return tagID; } +/* See header for documentation. */ +uint64_t CommandBuffer::dispatchDataGraph() +{ + uint64_t tagID = Tracker::LCSWorkload::assignTagID(); + stats.incDispatchDataGraphCount(); + + // Add a workload to the command stream + auto workload = std::make_shared(tagID); + + // Add a command to the layer-side command stream + workloadCommandStream.emplace_back(LCSInstructionWorkload(workload)); + + return tagID; +} + /* See header for documentation. */ uint64_t CommandBuffer::traceRays(int64_t xItems, int64_t yItems, int64_t zItems) { diff --git a/source_common/trackers/command_buffer.hpp b/source_common/trackers/command_buffer.hpp index 312fac7..69ba601 100644 --- a/source_common/trackers/command_buffer.hpp +++ b/source_common/trackers/command_buffer.hpp @@ -116,6 +116,13 @@ class CommandBuffer */ uint64_t dispatch(int64_t xGroups, int64_t yGroups, int64_t zGroups); + /** + * @brief Capture a data graph dispatch. + * + * @return Returns the tagID assigned to this workload. + */ + uint64_t dispatchDataGraph(); + /** * @brief Capture a trace rays dispatch. * diff --git a/source_common/trackers/layer_command_stream.cpp b/source_common/trackers/layer_command_stream.cpp index c6b2e45..350572a 100644 --- a/source_common/trackers/layer_command_stream.cpp +++ b/source_common/trackers/layer_command_stream.cpp @@ -71,6 +71,12 @@ LCSDispatch::LCSDispatch(uint64_t _tagID, int64_t _xGroups, int64_t _yGroups, in { } +/* See header for details. */ +LCSDispatchDataGraph::LCSDispatchDataGraph(uint64_t _tagID) + : LCSWorkload(_tagID) +{ +} + /* See header for details. */ LCSTraceRays::LCSTraceRays(uint64_t _tagID, int64_t _xItems, int64_t _yItems, int64_t _zItems) : LCSWorkload(_tagID), diff --git a/source_common/trackers/layer_command_stream.hpp b/source_common/trackers/layer_command_stream.hpp index 6d8a240..ec2b47a 100644 --- a/source_common/trackers/layer_command_stream.hpp +++ b/source_common/trackers/layer_command_stream.hpp @@ -272,6 +272,20 @@ class LCSDispatch : public LCSWorkload int64_t zGroups; }; +/** + * @brief Class representing a data graph dispatch workload in the command stream. + */ +class LCSDispatchDataGraph : public LCSWorkload +{ +public: + /** + * @brief Create a new data graph dispatch workload. + * + * @param tagID The assigned tagID. + */ + LCSDispatchDataGraph(uint64_t tagID); +}; + /** * @brief Class representing a trace rays workload in the command stream. */ @@ -586,8 +600,10 @@ using LCSInstruction = std::variant< LCSInstructionWorkload, // The instruction represents a continuation of a render pass workload operation LCSInstructionWorkload, - // The instruction represents a dispatch workload operation + // The instruction represents a dispatch compute workload operation LCSInstructionWorkload, + // The instruction represents a dispatch data graph workload operation + LCSInstructionWorkload, // The instruction represents a trace rays workload operation LCSInstructionWorkload, // The instruction represents an image transfer workload operation diff --git a/source_common/trackers/queue.cpp b/source_common/trackers/queue.cpp index 763dded..368ad24 100644 --- a/source_common/trackers/queue.cpp +++ b/source_common/trackers/queue.cpp @@ -127,8 +127,11 @@ namespace * @param instruction The workload instruction */ template - requires(std::is_same_v || std::is_same_v - || std::is_same_v || std::is_same_v + requires(std::is_same_v + || std::is_same_v + || std::is_same_v + || std::is_same_v + || std::is_same_v || std::is_same_v || std::is_same_v) void operator()(const LCSInstructionWorkload& instruction) diff --git a/source_common/trackers/queue.hpp b/source_common/trackers/queue.hpp index c9a0131..9a080e0 100644 --- a/source_common/trackers/queue.hpp +++ b/source_common/trackers/queue.hpp @@ -88,6 +88,14 @@ class SubmitCommandWorkloadVisitor */ virtual void operator()(const LCSDispatch& dispatch, const std::vector& debugStack) = 0; + /** + * @brief Visit a dispatch data graph workload object + * + * @param dispatch The dispatch data graph + * @param debugStack The stack of debug labels that are associated with this dispatch data graph + */ + virtual void operator()(const LCSDispatchDataGraph& dispatch, const std::vector& debugStack) = 0; + /** * @brief Visit a trace rays workload object * diff --git a/source_common/trackers/stats.hpp b/source_common/trackers/stats.hpp index e805f1a..83e0f98 100644 --- a/source_common/trackers/stats.hpp +++ b/source_common/trackers/stats.hpp @@ -68,6 +68,12 @@ class Stats */ void incDispatchCount() { dispatchCount += 1; } + /** + * @brief Increment the data graph dispatch counter. + */ + void incDispatchDataGraphCount() { dispatchDataGraphCount += 1; } + + /** * @brief Increment the trace rays counter. */ @@ -92,6 +98,7 @@ class Stats renderPassCount += other.renderPassCount; drawCallCount += other.drawCallCount; dispatchCount = other.dispatchCount; + dispatchDataGraphCount = other.dispatchDataGraphCount; traceRaysCount = other.traceRaysCount; bufferTransferCount = other.bufferTransferCount; imageTransferCount = other.imageTransferCount; @@ -106,6 +113,7 @@ class Stats renderPassCount = 0; drawCallCount = 0; dispatchCount = 0; + dispatchDataGraphCount = 0; traceRaysCount = 0; bufferTransferCount = 0; imageTransferCount = 0; @@ -117,38 +125,39 @@ class Stats uint64_t getFrameCount() const { return frameCount; } /** - * @brief Increment the render pass counter. + * @brief Get the render pass counter. */ uint64_t getRenderPassCount() const { return renderPassCount; } /** - * @brief Increment the draw counter. + * @brief Get the draw counter. */ uint64_t getDrawCallCount() const { return drawCallCount; } /** - * @brief Increment the compute dispatch counter. + * @brief Get the compute dispatch counter. */ uint64_t getDispatchCount() const { return dispatchCount; } /** - * @brief Increment the trace rays counter. + * @brief Get the compute dispatch counter. + */ + uint64_t getDispatchDataGraphCount() const { return dispatchDataGraphCount; } + + /** + * @brief Get the trace rays counter. */ uint64_t getTraceRaysCount() const { return traceRaysCount; }; /** - * @brief Increment the buffer transfer counter. + * @brief Get the buffer transfer counter. */ uint64_t getBufferTransferCount() const { return bufferTransferCount; } /** - * @brief Increment the image transfer counter. + * @brief Get the image transfer counter. */ - uint64_t getImageTransferCount() const - { - return imageTransferCount; - ; - } + uint64_t getImageTransferCount() const { return imageTransferCount; } private: /** @@ -171,6 +180,11 @@ class Stats */ uint64_t dispatchCount {0}; + /** + * @brief The number of data graph dispatches tracked. + */ + uint64_t dispatchDataGraphCount {0}; + /** * @brief The number of trace rays calls tracked. */ From efd7d2128522194dd6bf2a1f6e541f484cdff4fa Mon Sep 17 00:00:00 2001 From: Peter Harris Date: Tue, 14 Oct 2025 22:18:39 +0100 Subject: [PATCH 2/2] Add profiling layer support --- layer_gpu_profile/source/CMakeLists.txt | 1 + .../source/layer_device_functions.hpp | 8 +++ ...r_device_functions_dispatch_data_graph.cpp | 71 +++++++++++++++++++ layer_gpu_profile/source/submit_visitor.cpp | 14 +++- layer_gpu_profile/source/submit_visitor.hpp | 4 ++ 5 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 layer_gpu_profile/source/layer_device_functions_dispatch_data_graph.cpp diff --git a/layer_gpu_profile/source/CMakeLists.txt b/layer_gpu_profile/source/CMakeLists.txt index c0cb5f8..0b1bea8 100644 --- a/layer_gpu_profile/source/CMakeLists.txt +++ b/layer_gpu_profile/source/CMakeLists.txt @@ -49,6 +49,7 @@ add_library( layer_device_functions_command_buffer.cpp layer_device_functions_command_pool.cpp layer_device_functions_debug.cpp + layer_device_functions_dispatch_data_graph.cpp layer_device_functions_dispatch.cpp layer_device_functions_queue.cpp layer_device_functions_render_pass.cpp diff --git a/layer_gpu_profile/source/layer_device_functions.hpp b/layer_gpu_profile/source/layer_device_functions.hpp index ff9781d..e0e6b10 100644 --- a/layer_gpu_profile/source/layer_device_functions.hpp +++ b/layer_gpu_profile/source/layer_device_functions.hpp @@ -194,6 +194,14 @@ VKAPI_ATTR void VKAPI_CALL layer_vkCmdDispatchIndirect(VkCommandBuffer VkBuffer buffer, VkDeviceSize offset); +// Commands for data graph + +/* See Vulkan API for documentation. */ +template<> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdDispatchDataGraphARM(VkCommandBuffer commandBuffer, + VkDataGraphPipelineSessionARM session, + const VkDataGraphPipelineDispatchInfoARM* pInfo); + // Commands for trace rays /* See Vulkan API for documentation. */ diff --git a/layer_gpu_profile/source/layer_device_functions_dispatch_data_graph.cpp b/layer_gpu_profile/source/layer_device_functions_dispatch_data_graph.cpp new file mode 100644 index 0000000..39e47f4 --- /dev/null +++ b/layer_gpu_profile/source/layer_device_functions_dispatch_data_graph.cpp @@ -0,0 +1,71 @@ +/* + * SPDX-License-Identifier: MIT + * ---------------------------------------------------------------------------- + * Copyright (c) 2024-2025 Arm Limited + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * ---------------------------------------------------------------------------- + */ + +#include "device.hpp" +#include "device_utils.hpp" +#include "framework/device_dispatch_table.hpp" + +#include + +extern std::mutex g_vulkanLock; + +/** + * @brief Register a compute dispatch with the tracker. + * + * @param layer The layer context for the device. + * @param commandBuffer The command buffer we are recording. + */ +static void registerDispatchDataGraph(Device* layer, + VkCommandBuffer commandBuffer) +{ + if (!layer->isFrameOfInterest) + { + return; + } + + auto& tracker = layer->getStateTracker(); + auto& cb = tracker.getCommandBuffer(commandBuffer); + cb.dispatchDataGraph(); +} + +/* See Vulkan API for documentation. */ +template<> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdDispatchDataGraphARM(VkCommandBuffer commandBuffer, + VkDataGraphPipelineSessionARM session, + const VkDataGraphPipelineDispatchInfoARM* pInfo) +{ + LAYER_TRACE(__func__); + + // Hold the lock to access layer-wide global store + std::unique_lock lock {g_vulkanLock}; + auto* layer = Device::retrieve(commandBuffer); + + registerDispatchDataGraph(layer, commandBuffer); + + // Release the lock to call into the driver + lock.unlock(); + layer->driver.vkCmdDispatchDataGraphARM(commandBuffer, session, pInfo); + emitCPUTrap(*layer, commandBuffer); +} diff --git a/layer_gpu_profile/source/submit_visitor.cpp b/layer_gpu_profile/source/submit_visitor.cpp index 56d7b9c..3ade081 100644 --- a/layer_gpu_profile/source/submit_visitor.cpp +++ b/layer_gpu_profile/source/submit_visitor.cpp @@ -97,7 +97,7 @@ void ProfileSubmitVisitor::operator()( ) { UNUSED(renderPass); - handleCPUTrap("renderpass", debugStack); + handleCPUTrap("render_pass", debugStack); } /* See header for documentation */ @@ -123,6 +123,16 @@ void ProfileSubmitVisitor::operator()( handleCPUTrap("compute", debugStack); } +/* See header for documentation */ +void ProfileSubmitVisitor::operator()( + const Tracker::LCSDispatchDataGraph& dispatch, + const std::vector& debugStack +) { + UNUSED(dispatch); + + handleCPUTrap("data_graph", debugStack); +} + /* See header for documentation */ void ProfileSubmitVisitor::operator()( const Tracker::LCSTraceRays& traceRays, @@ -130,7 +140,7 @@ void ProfileSubmitVisitor::operator()( ) { UNUSED(traceRays); - handleCPUTrap("tracerays", debugStack); + handleCPUTrap("trace_rays", debugStack); } /* See header for documentation */ diff --git a/layer_gpu_profile/source/submit_visitor.hpp b/layer_gpu_profile/source/submit_visitor.hpp index 90ac752..8617b37 100644 --- a/layer_gpu_profile/source/submit_visitor.hpp +++ b/layer_gpu_profile/source/submit_visitor.hpp @@ -68,6 +68,10 @@ class ProfileSubmitVisitor : public Tracker::SubmitCommandWorkloadVisitor const Tracker::LCSDispatch& dispatch, const std::vector& debugStack) override; + void operator()( + const Tracker::LCSDispatchDataGraph& dispatch, + const std::vector& debugStack) override; + void operator()( const Tracker::LCSTraceRays& traceRays, const std::vector& debugStack) override;