fix(core): render repeated map viewports correctly with WebGPU - #10536
Conversation
Possible luma.gl follow-upThe underlying issue is that a single mutable uniform buffer is reused across multiple encoded draws, while A general luma.gl fix would make each draw's uniforms immutable:
That would fix repeated viewports and other same-model/multiple-uniform cases, including fill/stroke-style draws, while keeping a single render pass and a single submission. This PR is the focused deck.gl-side workaround until that upstream behavior exists. |
|
Updated the proposed architecture after discussion: repeated-view scheduling now lives above The luma.gl-level improvement would still be immutable per-draw uniform snapshots: allocate aligned slices from a frame-scoped uniform ring, bind the appropriate range/dynamic offset for every draw, and forward WebGPU dynamic offsets through |
5eea9c7 to
bb9d56b
Compare
Goal
Fix WebGPU rendering and picking of repeated Mercator world copies reported in #10534 (comment).
Root cause
Repeated viewports redraw the same model with different projection uniforms. luma.gl currently reuses one managed uniform buffer per shader module, and the implicit WebGPU
Model.draw()path updates it withGPUQueue.writeBuffer(). When those draws share one submission, every encoded draw can observe the final viewport's projection.Changes
LayersPassinto a shared helper used byDeckRendererand both synchronous/asynchronousDeckPickerpaths.LayersPassonly receives a selected physical subviewport.Possible luma.gl solution
A cleaner upstream fix would give each draw an immutable uniform snapshot.
UniformStore/Model.draw()could allocate aligned per-draw slices from a frame-scoped uniform ring buffer and bind each slice through buffer ranges or WebGPU dynamic offsets; alternatively, each draw could receive its own uniform buffer/bind group. luma.gl already has buffer-range bindings,hasDynamicOffset, andminUniformBufferOffsetAlignment, butWebGPURenderPass.setBindings()does not yet pass dynamic offsets tosetBindGroup(). Completing that support would let repeated views share one render pass/submission without deck.gl-specific scheduling.Validation
yarn linttsc --noEmit --pretty false -p modules/core/tsconfig.jsonyarn vitest run --project headless test/modules/core/passes/layers-pass.spec.ts test/modules/core/passes/pick-layers-pass.spec.ts test/modules/core/lib/deck-renderer.spec.ts test/modules/core/lib/deck-picker.spec.ts— 17 passed, including real-WebGPU rendering/picking of three world copies and shared picking-color decoding.yarn vitest run --project render test/render/test-cases/views.spec.ts -t map-repeat— 1 golden-image test passed.yarn vitest run --project node test/modules/imports.node.spec.ts test/modules/layers/core-layers.node.spec.ts— 15 passed.Refs #10534.