ifcviewer: move buildPipelines + selection-flags wiring into ViewportCore (#84-k)

Move the main render pipeline construction + the selection flags
buffer/bind group lifecycle. Both buildPipelines and the selection
flags methods produce/consume state ViewportCore already owns
(main_pipeline_, frame_bgl_, etc.) plus a handful of "frame
infrastructure" fields this commit also brings across.

State moved (7 fields):
  WGPUBuffer        frame_uniform_buffer_
  WGPUBindGroup     frame_bind_group_
  WGPUBuffer        selection_flags_buffer_
  uint32_t          selection_flags_capacity_
  std::vector<u32>  selection_flags_scratch_
  SelectionState    selection_
  VisibilityState   visibility_

Methods moved:
  buildPipelines              (~150 lines + 320-line MAIN_WGSL string)
  ensureSelectionFlagsBuffer  (~60 lines)
  uploadSelectionFlagsIfDirty (~10 lines)

Plus the MAIN_WGSL constant + the svFromCStr helper into
ViewportCore.cpp's anonymous namespace. ViewportWindow.cpp keeps its
own svFromCStr copy (still used by 50+ label fields in the not-yet-
moved pipeline builders + render encoders).

Shared constants extracted to ViewportCore.h:
  kMaxSectionPlanes (was OverlayRenderer::kMaxSectionPlanes — assert
                     in VW.cpp keeps them in sync)
  kViewportSampleCount (was SAMPLE_COUNT in VW; VW keeps a static
                        constexpr alias for the existing callsites)
  struct FrameUniforms (canonical layout for the per-frame UBO,
                        consumed by both core's buildPipelines and
                        VW's still-in-flight updateFrameUniforms)

Builds: desktop / bonsai / web all green. Tests 100/100.
This commit is contained in:
Dion Moult
2026-06-05 16:39:01 +10:00
parent 8cf7d4346d
commit 66a21923b8
4 changed files with 674 additions and 593 deletions
+10 -20
View File
@@ -658,25 +658,14 @@ private:
WGPURenderPipeline& main_pipeline_;
WGPURenderPipeline& main_pipeline_transparent_;
// Per-frame uniform (view-proj + lighting), bound at group 0.
WGPUBuffer frame_uniform_buffer_ = nullptr;
WGPUBindGroup frame_bind_group_ = nullptr;
// Selection flags storage buffer at group=0 binding=1. u32-per-object_id,
// bit 0 = selected, bit 1 = active. Sized to next_object_id_ rounded up;
// grows when a load pushes past the current capacity. Bound in the
// frame bind group because object_ids are globally unique across models.
WGPUBuffer selection_flags_buffer_ = nullptr;
uint32_t selection_flags_capacity_ = 0; // number of u32 entries
SelectionState selection_;
std::vector<uint32_t> selection_flags_scratch_;
// Per-element visibility. Consulted in cullModelCpuCompute to drop
// hidden instances before they're added to visible_draws — keeps
// hidden geometry out of cost on every axis (no draw, no depth, no
// pick). Mutated on the main thread between renders; cull workers
// read concurrently which is safe as long as no concurrent writes.
VisibilityState visibility_;
// Frame uniforms + selection flags aliases (storage in core_).
WGPUBuffer& frame_uniform_buffer_;
WGPUBindGroup& frame_bind_group_;
WGPUBuffer& selection_flags_buffer_;
uint32_t& selection_flags_capacity_;
std::vector<uint32_t>& selection_flags_scratch_;
SelectionState& selection_;
VisibilityState& visibility_;
// Depth attachment (4× MSAA), recreated on surface resize.
WGPUTexture depth_texture_ = nullptr;
@@ -690,7 +679,8 @@ private:
WGPUTextureView msaa_color_view_ = nullptr;
int msaa_w_ = 0;
int msaa_h_ = 0;
static constexpr uint32_t SAMPLE_COUNT = 4;
// SAMPLE_COUNT moved to ViewportCore.h as kViewportSampleCount (#84-k).
static constexpr uint32_t SAMPLE_COUNT = kViewportSampleCount;
// HiZ occlusion culling. After each frame's main render pass we
// downsample MSAA depth into a small single-sample Depth32Float texture