render/sensor_pipelines.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // SPDX-License-Identifier: BSD-3-Clause | ||
| 2 | #include "chrono_batch_render/render/sensor_pipelines.h" | ||
| 3 | |||
| 4 | #include <algorithm> | ||
| 5 | #include <map> | ||
| 6 | #include <string> | ||
| 7 | #include <utility> | ||
| 8 | #include <vector> | ||
| 9 | |||
| 10 | #include "chrono_batch_render/render/kernels.h" | ||
| 11 | #include "chrono_batch_render/util/error.h" | ||
| 12 | #include "chrono_batch_render/util/text.h" | ||
| 13 | |||
| 14 | namespace chrono::batch_render { | ||
| 15 | |||
| 16 | std::shared_ptr<const CompiledSensorPipeline> | ||
| 17 | 34 | CompileSensorPipeline(device::Device& device, | |
| 18 | std::shared_ptr<const sensor_pipeline::SensorPipelineDefinition> definition, | ||
| 19 | const sensor_pipeline::NodeRegistry& registry) { | ||
| 20 | 34 | auto compiled = std::make_shared<CompiledSensorPipeline>(); | |
| 21 | 34 | compiled->generated = sensor_pipeline::GenerateSensorPipeline(*definition, registry); | |
| 22 | 34 | std::map<std::string, std::string, std::less<>> sources = { | |
| 23 | 68 | {compiled->generated.path, compiled->generated.source}}; | |
| 24 | 34 | std::vector<std::pair<std::string, std::string>> files; | |
| 25 | 172 | for (const sensor_pipeline::ResolvedNode& node : definition->pipeline.nodes) { | |
| 26 | 138 | const sensor_pipeline::NodeDef& def = registry[node.def]; | |
| 27 | 138 | if (def.code.source.empty()) { | |
| 28 | 130 | continue; | |
| 29 | } | ||
| 30 | 8 | const std::string path = ModulePath(def.code.module); | |
| 31 | 8 | if (std::ranges::find(files, path, &std::pair<std::string, std::string>::first) == | |
| 32 | 8 | files.end()) { | |
| 33 | 5 | sources.emplace(path, def.code.source); | |
| 34 | 5 | files.emplace_back(path, def.code.file); | |
| 35 | } | ||
| 36 | 8 | } | |
| 37 | 34 | try { | |
| 38 | 136 | compiled->program = device.CreateProgram({.modules = {compiled->generated.module}, | |
| 39 | .library = &kRenderKernels, | ||
| 40 | .sources = sources, | ||
| 41 | 34 | .entries = compiled->generated.Entries(), | |
| 42 | 34 | .label = "sensor pipeline"}); | |
| 43 | ✗ | } catch (const Error& error) { | |
| 44 | ✗ | throw Error("{}", MapOrigins(error.what(), files)); | |
| 45 | ✗ | } | |
| 46 | 68 | compiled->definition = std::move(definition); | |
| 47 | 34 | return compiled; | |
| 48 | 136 | } | |
| 49 | |||
| 50 | 81 | void RecordSensorPipeline(device::CommandEncoder& encoder, const CompiledSensorPipeline& compiled, | |
| 51 | const SensorPipelineParams& params, uint32_t captures, | ||
| 52 | uint64_t elements) { | ||
| 53 | 230 | for (const sensor_pipeline::GeneratedKernel& step : compiled.generated.kernels) { | |
| 54 | 149 | device::Kernel& kernel = compiled.program->Entry(step.entry); | |
| 55 | 149 | const sensor_pipeline::DispatchShape shape = step.shape; | |
| 56 | 149 | const uint64_t threads = shape == sensor_pipeline::DispatchShape::Elements ? elements | |
| 57 | : shape == sensor_pipeline::DispatchShape::ReduceGroups | ||
| 58 | 38 | ? uint64_t(captures) * kReduceGroups * kPipelineGroup | |
| 59 | : captures; | ||
| 60 | 149 | encoder.Dispatch(kernel, params, | |
| 61 | device::FoldGroups(device::GroupCount(threads, kPipelineGroup))); | ||
| 62 | 149 | encoder.Barrier(); | |
| 63 | } | ||
| 64 | 81 | } | |
| 65 | |||
| 66 | } | ||
| 67 |