Open3D (C++ API)  0.20.0
Loading...
Searching...
No Matches
ComputeGPU.h
Go to the documentation of this file.
1// ----------------------------------------------------------------------------
2// - Open3D: www.open3d.org -
3// ----------------------------------------------------------------------------
4// Copyright (c) 2018-2026 www.open3d.org
5// SPDX-License-Identifier: MIT
6// ----------------------------------------------------------------------------
7//
8// Generic GPU compute abstraction used by the Gaussian splatting pipeline.
9// One header covers both Vulkan and Metal.
10// Runtime shader resources are loaded from resources/gaussian_splat/.
11//
12// Typical usage:
13//
14// // One GpuComputeFrame per geometry or composite stage (RAII).
15// GpuComputeFrame frame(ctx, GpuComputeFrame::kGeometry);
16//
17// // Each dispatch: one temporary GpuComputePass expression.
18// GpuComputePass(ctx, ComputeProgramId::kGsProject, "gs_project")
19// .UBO(0, view_params_buf)
20// .SSBO(1, positions_buf)
21// .Dispatch(groups_x, 1, 1);
22// ctx.FullBarrier();
23
24#pragma once
25
26#include <cstddef>
27#include <cstdint>
28#include <vector>
29
30namespace open3d {
31namespace visualization {
32namespace rendering {
33
34// ---------------------------------------------------------------------------
35// Enums
36// ---------------------------------------------------------------------------
37
40enum class ComputeProgramId : int {
41 kGsProject = 0,
42 kGsComposite = 1,
48 kGsDepthMerge = 5,
49 kCount = 6,
50};
51
54
57constexpr const char* kGsShaderNames[] = {
58 "gaussian_project",
59 "gaussian_composite",
60 "gaussian_radix_sort_histograms",
61 "gaussian_radix_sort_scatter",
62 "gaussian_compute_dispatch_args",
63 "gaussian_depth_merge",
64};
65static_assert(std::size(kGsShaderNames) ==
66 static_cast<std::size_t>(ComputeProgramId::kCount),
67 "kGsShaderNames must match ComputeProgramId::kCount");
68
69// ---------------------------------------------------------------------------
70// GPU data layout structs
71// ---------------------------------------------------------------------------
72
78 std::uint32_t g_num_elements = 0;
79 std::uint32_t g_shift = 0;
80 std::uint32_t g_num_workgroups = 0;
81 std::uint32_t g_num_blocks_per_workgroup = 0;
82};
83static_assert(sizeof(RadixSortParams) == 16,
84 "RadixSortParams must be 16 bytes to match GLSL layout");
85
88 std::uintptr_t view_params_buf = 0;
89 std::uintptr_t positions_buf = 0;
90 std::uintptr_t scales_buf = 0;
91 std::uintptr_t rotations_buf = 0;
92 std::uintptr_t dc_opacity_buf = 0;
93 std::uintptr_t sh_buf = 0;
96 std::uintptr_t projected_composite_buf = 0;
99 std::uintptr_t tile_counts_buf = 0;
101 std::uintptr_t counters_buf = 0;
102 std::uintptr_t dispatch_args_buf = 0;
105 std::uintptr_t sort_keys_buf[2] = {0, 0};
106 std::uintptr_t sort_values_buf[2] = {0, 0};
107 std::uintptr_t histogram_buf = 0;
108 std::uintptr_t radix_params_buf = 0;
110 std::uintptr_t mask_buf = 0;
112 std::uintptr_t composite_depth_tex = 0;
115 std::uintptr_t merged_depth_u16_tex = 0;
119 std::uint64_t cached_scene_id = 0;
120 std::uint32_t cached_splat_count = 0;
123 std::uint32_t warned_gpu_error_flags = 0;
124};
125
126// ---------------------------------------------------------------------------
127// GaussianSplatGpuContext — abstract GPU backend interface
128// ---------------------------------------------------------------------------
129
133public:
134 virtual ~GaussianSplatGpuContext() = default;
135
137 virtual bool EnsureProgramsLoaded() = 0;
138
139 // --- Buffer management ------------------------------------------------
140 virtual std::uintptr_t CreateBuffer(std::size_t size,
141 const char* label = nullptr) = 0;
142 virtual void DestroyBuffer(std::uintptr_t buf) = 0;
144 virtual std::uintptr_t ResizeBuffer(std::uintptr_t buf,
145 std::size_t new_size,
146 const char* label = nullptr) = 0;
147
150 virtual std::uintptr_t CreatePrivateBuffer(std::size_t size,
151 const char* label = nullptr) {
152 return CreateBuffer(size, label);
153 }
154 virtual std::uintptr_t ResizePrivateBuffer(std::uintptr_t buf,
155 std::size_t new_size,
156 const char* label = nullptr) {
157 return ResizeBuffer(buf, new_size, label);
158 }
159 virtual void UploadBuffer(std::uintptr_t buf,
160 const void* data,
161 std::size_t size,
162 std::size_t offset) = 0;
163 virtual bool DownloadBuffer(std::uintptr_t buf,
164 void* dst,
165 std::size_t size,
166 std::size_t offset) {
167 (void)buf;
168 (void)dst;
169 (void)size;
170 (void)offset;
171 return false;
172 }
173 virtual void ClearBufferUInt32Zero(std::uintptr_t buf) = 0;
174
175 // --- Bindings ---------------------------------------------------------
176 virtual void BindSSBO(std::uint32_t binding, std::uintptr_t buf) = 0;
177 virtual void BindUBO(std::uint32_t binding, std::uintptr_t buf) = 0;
178 virtual void BindUBORange(std::uint32_t binding,
179 std::uintptr_t buf,
180 std::size_t offset,
181 std::size_t range_size) = 0;
182
183 // --- Dispatch ---------------------------------------------------------
184 virtual void UseProgram(ComputeProgramId id) = 0;
185 virtual void Dispatch(std::uint32_t groups_x,
186 std::uint32_t groups_y,
187 std::uint32_t groups_z) = 0;
188 virtual void DispatchIndirect(std::uintptr_t indirect_buf,
189 std::size_t byte_offset) = 0;
190 virtual void FullBarrier() = 0;
191
196 virtual std::uint32_t GetMaxComputeWorkGroupCount() const { return 65535u; }
197
198 // --- Textures / images ------------------------------------------------
199 virtual std::uintptr_t CreateTexture2DR32F(std::uint32_t width,
200 std::uint32_t height,
201 const char* label = nullptr) = 0;
202 virtual void DestroyTexture(std::uintptr_t tex) = 0;
203 virtual std::uintptr_t ResizeTexture2DR32F(std::uintptr_t tex,
204 std::uint32_t width,
205 std::uint32_t height,
206 const char* label = nullptr) = 0;
208 virtual std::uintptr_t ResizeTexture2DR16UI(
209 std::uintptr_t tex,
210 std::uint32_t width,
211 std::uint32_t height,
212 const char* label = nullptr) = 0;
213
217 virtual bool DownloadTextureR32F(std::uintptr_t tex,
218 std::uint32_t width,
219 std::uint32_t height,
220 std::vector<float>& out) {
221 (void)tex;
222 (void)width;
223 (void)height;
224 (void)out;
225 return false;
226 }
227
231 virtual bool DownloadTextureR16UI(std::uintptr_t tex,
232 std::uint32_t width,
233 std::uint32_t height,
234 std::vector<std::uint16_t>& out) {
235 (void)tex;
236 (void)width;
237 (void)height;
238 (void)out;
239 return false;
240 }
241
244 virtual bool DownloadTextureRGBA16F(std::uintptr_t tex,
245 std::uint32_t width,
246 std::uint32_t height,
247 std::vector<std::uint16_t>& out) {
248 (void)tex;
249 (void)width;
250 (void)height;
251 (void)out;
252 return false;
253 }
254
256 virtual void BindImage(std::uint32_t binding,
257 std::uintptr_t tex,
258 std::uint32_t width,
259 std::uint32_t height,
260 ImageFormat fmt) = 0;
261
262 virtual void BindSamplerTexture(std::uint32_t unit,
263 std::uintptr_t tex,
264 std::uint32_t width,
265 std::uint32_t height) = 0;
266
267 // --- Frame sync -------------------------------------------------------
269 virtual bool WasLastSubmitSuccessful() const { return true; }
270
273 virtual void BeginGeometryPass() {}
274 virtual void EndGeometryPass() {}
275 virtual void BeginCompositePass() {}
276 virtual void EndCompositePass() {}
277
286 virtual void WaitForGeometryPass() {}
287
290 virtual void PushDebugGroup(const char* /*label*/) {}
291 virtual void PopDebugGroup() {}
292};
293
294// ---------------------------------------------------------------------------
295// GpuComputeFrame — RAII for Begin/EndGeometryPass or Begin/EndCompositePass
296// ---------------------------------------------------------------------------
297
301public:
303
305 : ctx_(ctx), kind_(kind) {
306 if (kind_ == kGeometry) {
307 ctx_.BeginGeometryPass();
308 ctx_.PushDebugGroup("gs_geometry_frame");
309 } else {
310 ctx_.BeginCompositePass();
311 ctx_.PushDebugGroup("gs_composite_frame");
312 }
313 }
315
318
320 void End() {
321 if (!ended_) {
322 ended_ = true;
323 ctx_.PopDebugGroup();
324 if (kind_ == kGeometry) {
325 ctx_.EndGeometryPass();
326 } else {
327 ctx_.EndCompositePass();
328 }
329 }
330 }
331
332private:
334 Kind kind_;
335 bool ended_ = false;
336};
337
338// ---------------------------------------------------------------------------
339// GpuComputePass — RAII + builder for a single compute dispatch
340// ---------------------------------------------------------------------------
341
351public:
354 const char* label = nullptr)
355 : ctx_(ctx), label_(label) {
356 ok_ = ctx_.EnsureProgramsLoaded();
357 if (ok_) {
358 ctx_.UseProgram(pid);
359 if (label_) ctx_.PushDebugGroup(label_);
360 }
361 }
362
364 if (ok_ && label_) ctx_.PopDebugGroup();
365 }
366
369
371 [[nodiscard]] bool ok() const { return ok_; }
372
373 // --- Resource binding (fluent builder) --------------------------------
374
375 GpuComputePass& UBO(std::uint32_t binding, std::uintptr_t buf) {
376 if (ok_) ctx_.BindUBO(binding, buf);
377 return *this;
378 }
379
380 GpuComputePass& UBORange(std::uint32_t binding,
381 std::uintptr_t buf,
382 std::size_t offset,
383 std::size_t size) {
384 if (ok_) ctx_.BindUBORange(binding, buf, offset, size);
385 return *this;
386 }
387
388 GpuComputePass& SSBO(std::uint32_t binding, std::uintptr_t buf) {
389 if (ok_) ctx_.BindSSBO(binding, buf);
390 return *this;
391 }
392
393 GpuComputePass& Image(std::uint32_t binding,
394 std::uintptr_t tex,
395 std::uint32_t w,
396 std::uint32_t h,
398 if (ok_) ctx_.BindImage(binding, tex, w, h, fmt);
399 return *this;
400 }
401
402 GpuComputePass& Sampler(std::uint32_t unit,
403 std::uintptr_t tex,
404 std::uint32_t w,
405 std::uint32_t h) {
406 if (ok_) ctx_.BindSamplerTexture(unit, tex, w, h);
407 return *this;
408 }
409
410 // --- Dispatch ---------------------------------------------------------
411
412 void Dispatch(std::uint32_t gx, std::uint32_t gy, std::uint32_t gz) {
413 if (ok_) ctx_.Dispatch(gx, gy, gz);
414 }
415
416 void DispatchIndirect(std::uintptr_t buf, std::size_t byte_offset) {
417 if (ok_) ctx_.DispatchIndirect(buf, byte_offset);
418 }
419
420private:
422 const char* label_;
423 bool ok_;
424};
425
426// ---------------------------------------------------------------------------
427// Factory functions
428// ---------------------------------------------------------------------------
429
430#if defined(__APPLE__)
431[[nodiscard]] std::unique_ptr<GaussianSplatGpuContext>
432CreateComputeGpuContextMetal(std::uintptr_t device_handle,
433 std::uintptr_t command_queue_handle);
434#endif
435
436} // namespace rendering
437} // namespace visualization
438} // namespace open3d
virtual void DestroyBuffer(std::uintptr_t buf)=0
virtual void EndCompositePass()
Definition ComputeGPU.h:276
virtual std::uintptr_t ResizeBuffer(std::uintptr_t buf, std::size_t new_size, const char *label=nullptr)=0
Returns a valid handle (may replace buf when the API reallocates).
virtual void DestroyTexture(std::uintptr_t tex)=0
virtual void BeginCompositePass()
Definition ComputeGPU.h:275
virtual void BindUBORange(std::uint32_t binding, std::uintptr_t buf, std::size_t offset, std::size_t range_size)=0
virtual std::uintptr_t ResizeTexture2DR32F(std::uintptr_t tex, std::uint32_t width, std::uint32_t height, const char *label=nullptr)=0
virtual void PopDebugGroup()
Definition ComputeGPU.h:291
virtual bool DownloadBuffer(std::uintptr_t buf, void *dst, std::size_t size, std::size_t offset)
Definition ComputeGPU.h:163
virtual void BindSamplerTexture(std::uint32_t unit, std::uintptr_t tex, std::uint32_t width, std::uint32_t height)=0
virtual void UploadBuffer(std::uintptr_t buf, const void *data, std::size_t size, std::size_t offset)=0
virtual void BindSSBO(std::uint32_t binding, std::uintptr_t buf)=0
virtual void Dispatch(std::uint32_t groups_x, std::uint32_t groups_y, std::uint32_t groups_z)=0
virtual std::uintptr_t ResizePrivateBuffer(std::uintptr_t buf, std::size_t new_size, const char *label=nullptr)
Definition ComputeGPU.h:154
virtual void ClearBufferUInt32Zero(std::uintptr_t buf)=0
virtual bool DownloadTextureR32F(std::uintptr_t tex, std::uint32_t width, std::uint32_t height, std::vector< float > &out)
Definition ComputeGPU.h:217
virtual std::uintptr_t CreateTexture2DR32F(std::uint32_t width, std::uint32_t height, const char *label=nullptr)=0
virtual void BindUBO(std::uint32_t binding, std::uintptr_t buf)=0
virtual void WaitForGeometryPass()
Definition ComputeGPU.h:286
virtual bool EnsureProgramsLoaded()=0
Load all compute programs (lazy, idempotent).
virtual void DispatchIndirect(std::uintptr_t indirect_buf, std::size_t byte_offset)=0
virtual std::uintptr_t CreateBuffer(std::size_t size, const char *label=nullptr)=0
virtual std::uint32_t GetMaxComputeWorkGroupCount() const
Definition ComputeGPU.h:196
virtual void BindImage(std::uint32_t binding, std::uintptr_t tex, std::uint32_t width, std::uint32_t height, ImageFormat fmt)=0
Bind a write image at the given unit with the specified format.
virtual void BeginGeometryPass()
Definition ComputeGPU.h:273
virtual void EndGeometryPass()
Definition ComputeGPU.h:274
virtual std::uintptr_t ResizeTexture2DR16UI(std::uintptr_t tex, std::uint32_t width, std::uint32_t height, const char *label=nullptr)=0
Create or resize an R16UI texture for merged-depth CPU readback.
virtual bool DownloadTextureR16UI(std::uintptr_t tex, std::uint32_t width, std::uint32_t height, std::vector< std::uint16_t > &out)
Definition ComputeGPU.h:231
virtual void UseProgram(ComputeProgramId id)=0
virtual std::uintptr_t CreatePrivateBuffer(std::size_t size, const char *label=nullptr)
Definition ComputeGPU.h:150
virtual void PushDebugGroup(const char *)
Definition ComputeGPU.h:290
virtual bool DownloadTextureRGBA16F(std::uintptr_t tex, std::uint32_t width, std::uint32_t height, std::vector< std::uint16_t > &out)
Definition ComputeGPU.h:244
virtual bool WasLastSubmitSuccessful() const
Returns whether the most recently submitted GPU work succeeded.
Definition ComputeGPU.h:269
GpuComputeFrame(const GpuComputeFrame &)=delete
~GpuComputeFrame()
Definition ComputeGPU.h:314
GpuComputeFrame(GaussianSplatGpuContext &ctx, Kind kind)
Definition ComputeGPU.h:304
GpuComputeFrame & operator=(const GpuComputeFrame &)=delete
void End()
Explicitly end the frame early (dtor becomes a no-op).
Definition ComputeGPU.h:320
GpuComputePass(const GpuComputePass &)=delete
GpuComputePass & UBORange(std::uint32_t binding, std::uintptr_t buf, std::size_t offset, std::size_t size)
Definition ComputeGPU.h:380
void DispatchIndirect(std::uintptr_t buf, std::size_t byte_offset)
Definition ComputeGPU.h:416
~GpuComputePass()
Definition ComputeGPU.h:363
GpuComputePass & operator=(const GpuComputePass &)=delete
GpuComputePass & UBO(std::uint32_t binding, std::uintptr_t buf)
Definition ComputeGPU.h:375
GpuComputePass & SSBO(std::uint32_t binding, std::uintptr_t buf)
Definition ComputeGPU.h:388
GpuComputePass(GaussianSplatGpuContext &ctx, ComputeProgramId pid, const char *label=nullptr)
Definition ComputeGPU.h:352
void Dispatch(std::uint32_t gx, std::uint32_t gy, std::uint32_t gz)
Definition ComputeGPU.h:412
GpuComputePass & Sampler(std::uint32_t unit, std::uintptr_t tex, std::uint32_t w, std::uint32_t h)
Definition ComputeGPU.h:402
bool ok() const
Returns false only when EnsureProgramsLoaded() failed (device error).
Definition ComputeGPU.h:371
GpuComputePass & Image(std::uint32_t binding, std::uintptr_t tex, std::uint32_t w, std::uint32_t h, ImageFormat fmt)
Definition ComputeGPU.h:393
int width
Definition FilePCD.cpp:53
int size
Definition FilePCD.cpp:41
int height
Definition FilePCD.cpp:54
int offset
Definition FilePCD.cpp:46
Definition DLPack.h:680
ImageFormat
Format selector for GaussianSplatGpuContext::BindImage().
Definition ComputeGPU.h:53
ComputeProgramId
Definition ComputeGPU.h:40
constexpr const char * kGsShaderNames[]
Definition ComputeGPU.h:57
Definition PinholeCameraIntrinsic.cpp:16
Per-view opaque GPU buffer and texture handles.
Definition ComputeGPU.h:87
std::uintptr_t projected_composite_buf
Definition ComputeGPU.h:96
std::uint32_t cached_splat_count
Definition ComputeGPU.h:120
std::uintptr_t scales_buf
Definition ComputeGPU.h:90
std::uintptr_t dc_opacity_buf
Definition ComputeGPU.h:92
std::uintptr_t dispatch_args_buf
Definition ComputeGPU.h:102
std::uintptr_t sort_keys_buf[2]
Definition ComputeGPU.h:105
std::uintptr_t composite_depth_tex
GS composite depth output (image binding 1); not the shared scene depth.
Definition ComputeGPU.h:112
std::uintptr_t tile_counts_buf
Definition ComputeGPU.h:99
std::uintptr_t mask_buf
Bit-packed per-splat visibility mask. Bound at binding 15.
Definition ComputeGPU.h:110
std::uintptr_t rotations_buf
Definition ComputeGPU.h:91
std::uint64_t cached_scene_id
Definition ComputeGPU.h:119
std::uintptr_t positions_buf
Definition ComputeGPU.h:89
std::uintptr_t radix_params_buf
Definition ComputeGPU.h:108
std::uint32_t warned_gpu_error_flags
Definition ComputeGPU.h:123
std::uintptr_t merged_depth_u16_tex
Definition ComputeGPU.h:115
std::uintptr_t sort_values_buf[2]
Definition ComputeGPU.h:106
std::uintptr_t view_params_buf
Definition ComputeGPU.h:88
std::uintptr_t counters_buf
GPU error/diagnostic counters (total_entries, error_flags, ...).
Definition ComputeGPU.h:101
std::uintptr_t histogram_buf
Definition ComputeGPU.h:107
std::uint32_t g_num_elements
Definition ComputeGPU.h:78
std::uint32_t g_shift
Definition ComputeGPU.h:79
std::uint32_t g_num_workgroups
Definition ComputeGPU.h:80
std::uint32_t g_num_blocks_per_workgroup
Definition ComputeGPU.h:81