-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Add UploadStream API and optimize GSplat order data uploads with non-blocking transfers #8053
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…blocking transfers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Introduces a new UploadStream
API for efficient, non-blocking GPU data uploads and refactors GSplat unified rendering to use storage buffers on WebGPU with optimized upload strategies for both WebGL and WebGPU.
- Added new
UploadStream
API with platform-specific implementations for WebGL (PBO-based) and WebGPU (staging buffer-based) non-blocking data uploads - Extended
StorageBuffer
with optional storage usage parameter and buffer copy functionality - Refactored GSplat unified rendering to use storage buffers on WebGPU and texture-based approach on WebGL with conditional shader compilation
Reviewed Changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated no comments.
Show a summary per file
File | Description |
---|---|
src/scene/shader-lib/wgsl/chunks/gsplat/vert/gsplatSource.js | Added conditional compilation for storage buffer vs texture-based splat order access in WGSL shader |
src/scene/shader-lib/glsl/chunks/gsplat/vert/gsplatSource.js | Updated GLSL shader to use uniform texture size parameter instead of computing from texture dimensions |
src/scene/gsplat/gsplat-instance.js | Refactored material order texture setup into reusable method that sets both texture and size parameters |
src/scene/gsplat-unified/gsplat-work-buffer.js | Added UploadStream integration and dual texture/storage buffer support based on graphics device type |
src/scene/gsplat-unified/gsplat-renderer.js | Updated renderer to handle both WebGL texture and WebGPU storage buffer order data with frame-based updates |
src/scene/gsplat-unified/gsplat-manager.js | Integrated new renderer update and frame update methods for optimized order data handling |
src/platform/graphics/webgpu/webgpu-upload-stream.js | Implemented WebGPU-specific UploadStream using staging buffers with recycling for non-blocking uploads |
src/platform/graphics/webgpu/webgpu-graphics-device.js | Added WebGPU UploadStream implementation factory method |
src/platform/graphics/webgpu/webgpu-dynamic-buffer.js | Fixed JSDoc type annotation formatting |
src/platform/graphics/webgl/webgl-upload-stream.js | Implemented WebGL-specific UploadStream using PBO orphaning pattern for optimized texture uploads |
src/platform/graphics/webgl/webgl-graphics-device.js | Added WebGL UploadStream implementation factory method |
src/platform/graphics/upload-stream.js | Created platform-agnostic UploadStream API for efficient GPU resource uploads |
src/platform/graphics/storage-buffer.js | Extended StorageBuffer with optional storage usage flag and buffer copy functionality |
src/platform/graphics/shader-chunks/frag/shared-wgsl.js | Added WEBGPU preprocessor define |
src/platform/graphics/null/null-graphics-device.js | Added null implementation for UploadStream factory method |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
What's the reason not to use this for the non-managed path as well? |
No reason, can be done in a separate PR. I tried doing it but it was looking to be a larger change with the way sorter is handling data, so I didn't do it as part of this PR. |
Ok awesome. This is such a significant improvement that we need it everywhere all at once right now :) |
Overview
Introduces a new
UploadStream
API for efficient, non-blocking GPU data uploads and refactors GSplat unified rendering to use storage buffers on WebGPU with optimized upload strategies for both WebGL and WebGPU.New API: UploadStream
A platform-agnostic private API for uploading data to GPU resources (texture on WebGL / storage buffer on WebGPU) with two modes:
useSingleBuffer: true
): Direct uploads for low-frequency updates. Blocking if the resource is still in use by the GPU.useSingleBuffer: false
): Non-blocking uploads using PBOs (WebGL) or staging buffers (WebGPU)Signature:
upload(data, target, offset = 0, size = data.length)
StorageBuffer API Extensions
addStorageUsage
parameter to theStorageBuffer
constructor (defaults totrue
) to support creating staging bufferscopy(srcOffset, dstBuffer, dstOffset, size)
method that wrapscopyBufferToBuffer
for efficient GPU-side buffer copies, enabling the staging buffer pattern used byUploadStream
.Key Changes
WebGL Optimizations (
WebglUploadStream
)clientWaitSync(..., 0, 0)
WebGPU Optimizations (
WebgpuUploadStream
)copyBufferToBuffer
StorageBuffer.write()
for simple modeGSplat Unified Rendering
orderBuffer
(StorageBuffer) for WebGPU alongsideorderTexture
for WebGLUploadStream
insetOrderData()
for non-blocking uploadsShader Updates
gsplatSource.js
(WGSL): Added conditional compilation via#ifdef STORAGE_ORDER
var<storage, read> splatOrder: array<u32>
splatTextureSize
uniformProfiling on Apple M4 Max
WebGPU
The impact is huge. The CPU thread is no longer blocked on the upload, and runs 60fps instead of 20 or so. We're still GPU limited, and so the frames are still skipped - but that can be addressed by GPU optimization.
before

now

WebGL
A lot lower impact, as there is no completely non-blocking way to upload, and performance depends on the driver implementation. In theory, this should deliver the same performance as WebGPU though.
before

now
