scene/tables/surfaces.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // SPDX-License-Identifier: BSD-3-Clause | ||
| 2 | #include "chrono_batch_render/scene/tables/surfaces.h" | ||
| 3 | |||
| 4 | #include <algorithm> | ||
| 5 | #include <set> | ||
| 6 | |||
| 7 | #include "chrono_batch_render/device/commands.h" | ||
| 8 | #include "chrono_batch_render/device/queue.h" | ||
| 9 | #include "chrono_batch_render/scene/kernels.h" | ||
| 10 | #include "chrono_batch_render/scene/records/render_tables.h" | ||
| 11 | #include "chrono_batch_render/scene/schema/columns.h" | ||
| 12 | #include "chrono_batch_render/scene/tables/kernels/surfaces.h" | ||
| 13 | #include "chrono_batch_render/stage/publish/change_set.h" | ||
| 14 | #include "chrono_batch_render/util/profiler.h" | ||
| 15 | |||
| 16 | namespace chrono::batch_render { | ||
| 17 | |||
| 18 | namespace { | ||
| 19 | |||
| 20 | constexpr ColumnRef kInputs[] = {kGprimPrimvars, | ||
| 21 | kGprimDisplayColor, | ||
| 22 | kGprimDisplayOpacity, | ||
| 23 | kPointBasedNormals, | ||
| 24 | kPointBasedNormalsInterpolation, | ||
| 25 | kMeshSubdivisionScheme, | ||
| 26 | kPointInstancerPrimvars, | ||
| 27 | kPointInstancerIds}; | ||
| 28 | |||
| 29 | } | ||
| 30 | |||
| 31 | 2573 | std::span<const ColumnRef> SurfaceTable::Inputs() const { | |
| 32 | 2573 | return kInputs; | |
| 33 | } | ||
| 34 | |||
| 35 | 649 | void SurfaceTable::Describe(RenderTables& tables) const { | |
| 36 | 649 | tables.surfaces.address = m_surfaces.Address(); | |
| 37 | 649 | } | |
| 38 | |||
| 39 | 649 | void SurfaceTable::Run(const ChangeSet& changes, TableVersions&) { | |
| 40 | 649 | CHRONO_BATCH_RENDER_ZONE("Surfaces/Run"); | |
| 41 | 649 | m_written = 0; | |
| 42 | 649 | ColumnStore& store = m_structure.GetColumnStore(); | |
| 43 | 649 | const std::span<const uint32_t> starts = m_instances.FirstInstances(); | |
| 44 | 649 | const std::span<const uint32_t> counts = m_instances.InstanceCounts(); | |
| 45 | 649 | if (m_tables.instances.address == 0 || counts.empty()) { | |
| 46 | return; | ||
| 47 | } | ||
| 48 | 649 | device::Device& device = store.GetDevice(); | |
| 49 | 649 | const bool grown = m_surfaces.Reserve(device, starts.back()); | |
| 50 | 649 | std::set<uint32_t> dirty; | |
| 51 | 649 | for (const uint32_t world : | |
| 52 | 1307 | changes.resync || grown ? std::vector<uint32_t>{kGlobalWorld} : changes.worlds) { | |
| 53 | 1316 | dirty.merge(m_instances.Tlases(world)); | |
| 54 | 649 | } | |
| 55 | 649 | std::vector<uint32_t> tlases(dirty.begin(), dirty.end()); | |
| 56 | 649 | uint32_t widest = 0; | |
| 57 | 1396 | for (const uint32_t tlas : tlases) { | |
| 58 | 747 | widest = std::max(widest, starts[tlas + 1] - starts[tlas]); | |
| 59 | 747 | m_written += counts[tlas]; | |
| 60 | } | ||
| 61 | 649 | if (widest == 0) { | |
| 62 | ✗ | return; | |
| 63 | } | ||
| 64 | 649 | const Ref<device::Buffer> list = device.CreateBuffer({.label = "surface TLASes"}, tlases); | |
| 65 | 649 | SurfaceParams params{}; | |
| 66 | 1298 | params.scene.address = store.DeviceData(); | |
| 67 | 649 | params.layout = m_tables.instances; | |
| 68 | 649 | params.meshes = m_tables.meshes; | |
| 69 | 649 | params.surfaces.address = m_surfaces.Address(); | |
| 70 | 649 | params.tlases.address = list->Address(); | |
| 71 | 649 | params.normalsName = m_structure.GetTokens().Intern("normals").id; | |
| 72 | 649 | params.displayOpacityName = m_structure.GetTokens().Intern("displayOpacity").id; | |
| 73 | 649 | device::Queue& queue = device.GetQueue(); | |
| 74 | 649 | static const profiler::ZoneId zone = profiler::ZoneId::Named("Surfaces/Write"); | |
| 75 | 649 | device::CommandEncoder encoder = queue.CreateEncoder(); | |
| 76 | 649 | { | |
| 77 | 649 | const device::ZoneScope scope(encoder, zone); | |
| 78 | 649 | encoder.Dispatch( | |
| 79 | 649 | Kernels().Entry("WriteSurfaces"), params, | |
| 80 | 649 | {.x = device::GroupCount(widest, kSurfaceGroup), .y = uint32_t(tlases.size())}); | |
| 81 | 649 | } | |
| 82 | 649 | queue.Submit(encoder.Finish()); | |
| 83 | 2596 | } | |
| 84 | |||
| 85 | 353 | void SurfaceTable::Prepare() { | |
| 86 | 353 | Kernels(); | |
| 87 | 353 | } | |
| 88 | |||
| 89 | 1002 | device::Program& SurfaceTable::Kernels() { | |
| 90 | 1002 | if (!m_program) { | |
| 91 | 1113 | m_program = m_structure.GetColumnStore().GetDevice().CreateProgram( | |
| 92 | {.modules = {"chrono_batch_render.scene.tables.kernels.surfaces"}, | ||
| 93 | .library = &kSceneKernels, | ||
| 94 | .entries = {"WriteSurfaces"}, | ||
| 95 | 742 | .label = "surfaces"}); | |
| 96 | } | ||
| 97 | 1002 | return *m_program; | |
| 98 | 742 | } | |
| 99 | |||
| 100 | } | ||
| 101 |