Open3D (C++ API)  0.19.0
GaussianSplatVulkanInteropContext.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - Open3D: www.open3d.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.open3d.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 //
8 // Vulkan-OpenGL interop context for Gaussian splatting compute (Linux/Windows).
9 //
10 // Owns a headless Vulkan instance and logical device used solely for compute
11 // work. All resources that must be visible to both Vulkan compute and
12 // OpenGL/Filament are allocated here as exportable memory objects.
13 //
14 // Key relationships:
15 // - GaussianSplatOpenGLContext creates the GL/GLFW context and calls
16 // glewInit(). After that, call ProbeGLExtensions() to verify the
17 // GL interop extensions are present.
18 // - FilamentEngine.cpp calls Initialize() before GL context setup, and
19 // Shutdown() on engine teardown.
20 // - GaussianSplatVulkanBackend uses CreateSharedColorImage() and
21 // CreateSharedDepthImage() per view, holding the handles in OutputTargets.
22 //
23 // Uses vulkan-hpp (Vulkan-Headers) for Vulkan loading and RAII handle
24 // lifetime management, and VMA (vk_mem_alloc.h from the pinned 3rdparty
25 // download) for suballocated internal-only buffer allocations.
26 //
27 // Thread-safety: not thread-safe. All calls must be made from the render
28 // thread. Shared images must be created or destroyed while the GL context is
29 // current (for the GL import calls).
30 
31 #pragma once
32 
33 #if !defined(__APPLE__)
34 
35 #include <cstdint>
36 #include <string>
37 
38 // Suppress C function-prototype declarations in vulkan.h: all Vulkan entry
39 // points are resolved at runtime through vulkan-hpp's per-object RAII
40 // dispatchers (ContextDispatcher / InstanceDispatcher / DeviceDispatcher),
41 // not as statically-linked symbols.
42 //
43 // NOTE: BlueVK (used by Filament) also defines VK_NO_PROTOTYPES before
44 // including vulkan.h, so the two includes are mutually compatible when
45 // this header is included after Filament headers.
46 #ifndef VK_NO_PROTOTYPES
47 #define VK_NO_PROTOTYPES
48 #endif
49 #include <vulkan/vulkan_raii.hpp>
50 
51 namespace open3d {
52 namespace visualization {
53 namespace rendering {
54 
55 // ---------------------------------------------------------------------------
56 // Shared resource descriptors
57 // ---------------------------------------------------------------------------
58 
61  kRGBA16F,
62  kDepth32F,
63 };
64 
77  VkImage vk_image = VK_NULL_HANDLE;
78  VkDeviceMemory vk_memory = VK_NULL_HANDLE;
79 
84 
89 
92  VkImageLayout current_layout = VK_IMAGE_LAYOUT_UNDEFINED;
93 
94  bool IsValid() const { return vk_image != VK_NULL_HANDLE; }
95 };
96 
97 // ---------------------------------------------------------------------------
98 // GaussianSplatVulkanInteropContext — headless Vulkan compute context
99 // ---------------------------------------------------------------------------
100 
108 public:
110 
116  bool Initialize();
117 
119  void Shutdown();
120 
121  bool IsValid() const { return initialized_; }
122 
126  bool ProbeGLExtensions();
127 
128  bool AreGLExtensionsReady() const { return gl_extensions_ok_; }
129 
131  const std::string& GetLastError() const { return last_error_; }
132 
133  // --- Device accessors (used by VulkanBackend and ComputeGPUVulkan) ----
134  // vk::Handle::CType provides the underlying C type (e.g.
135  // vk::Instance::CType
136  // == VkInstance). On 64-bit platforms vk::raii handles implicitly convert
137  // to their C equivalents; static_cast is used here to be explicit and
138  // 32-bit safe.
139  VkInstance GetVkInstance() const {
140  return static_cast<vk::Instance::CType>(*instance_);
141  }
142  VkDevice GetDevice() const {
143  return static_cast<vk::Device::CType>(*device_);
144  }
145  VkPhysicalDevice GetPhysicalDevice() const {
146  return static_cast<vk::PhysicalDevice::CType>(*physical_device_);
147  }
148  VkQueue GetComputeQueue() const {
149  return static_cast<vk::Queue::CType>(*compute_queue_);
150  }
152  return compute_queue_family_;
153  }
156  bool GetDebugUtilsEnabled() const { return debug_utils_enabled_; }
159  std::uint32_t GetSubgroupSize() const { return subgroup_size_; }
161  return subgroup_supported_stages_;
162  }
164  return subgroup_supported_operations_;
165  }
166 
167  // RAII accessors used by ComputeGPUVulkan to create sub-objects.
168  const vk::raii::Instance& GetRaiiInstance() const { return instance_; }
169  const vk::raii::Device& GetRaiiDevice() const { return device_; }
170 
171  // --- Shared-image lifecycle -------------------------------------------
172 
179  const char* label = nullptr);
180 
185  const char* label = nullptr);
186 
191 
192  // --- Vulkan device memory type helpers --------------------------------
193 
198  VkMemoryPropertyFlags props) const;
199 
200 private:
203 
205  const GaussianSplatVulkanInteropContext&) = delete;
207  const GaussianSplatVulkanInteropContext&) = delete;
208 
209  // --- Internal helpers -------------------------------------------------
210 
211  bool CreateInstance();
212  bool SelectPhysicalDevice();
213  bool CreateLogicalDevice();
214 
217  bool AllocateExportableImage(std::uint32_t width,
219  VkFormat vk_format,
220  VkImageUsageFlags usage,
221  VkImage& out_image,
222  VkDeviceMemory& out_memory,
223  int& out_fd) const;
224 
227  bool ImportFDIntoGL(int fd,
230  VkDeviceSize memory_size,
232  std::uint32_t& out_gl_memory_object,
233  std::uint32_t& out_gl_texture) const;
234 
235  SharedImageDesc CreateSharedImage(std::uint32_t width,
238  const char* label);
239 
240  // --- State ------------------------------------------------------------
241  bool initialized_ = false;
242  bool gl_extensions_ok_ = false;
243  bool debug_utils_enabled_ =
244  false; // VK_EXT_debug_utils enabled in instance
245  std::uint32_t subgroup_size_ = 0; // queried after logical device creation
246  std::uint32_t subgroup_supported_stages_ = 0;
247  std::uint32_t subgroup_supported_operations_ = 0;
248  std::string last_error_;
249 
250  // RAII handles. Destruction order is reverse of declaration order:
251  // compute_queue_ → device_ → physical_device_ → instance_ → context_.
252  // vk::raii::Context loads the Vulkan loader; all others are sub-objects.
253  vk::raii::Context context_;
254  vk::raii::Instance instance_{nullptr};
255  vk::raii::PhysicalDevice physical_device_{nullptr};
256  vk::raii::Device device_{nullptr};
257  vk::raii::Queue compute_queue_{nullptr};
258  std::uint32_t compute_queue_family_ = UINT32_MAX;
259 
260  VkPhysicalDeviceMemoryProperties memory_props_{};
261 };
262 
263 } // namespace rendering
264 } // namespace visualization
265 } // namespace open3d
266 
267 #endif // !defined(__APPLE__)
filament::Texture::InternalFormat format
Definition: FilamentResourceManager.cpp:202
Definition: GaussianSplatVulkanInteropContext.h:107
const vk::raii::Instance & GetRaiiInstance() const
Definition: GaussianSplatVulkanInteropContext.h:168
const std::string & GetLastError() const
Human-readable description of the last failure (extension name, etc.).
Definition: GaussianSplatVulkanInteropContext.h:131
SharedImageDesc CreateSharedColorImage(std::uint32_t width, std::uint32_t height, const char *label=nullptr)
Definition: GaussianSplatVulkanInteropContext.cpp:763
VkQueue GetComputeQueue() const
Definition: GaussianSplatVulkanInteropContext.h:148
static GaussianSplatVulkanInteropContext & GetInstance()
Definition: GaussianSplatVulkanInteropContext.cpp:159
std::uint32_t GetSubgroupSupportedStages() const
Definition: GaussianSplatVulkanInteropContext.h:160
std::uint32_t GetSubgroupSupportedOperations() const
Definition: GaussianSplatVulkanInteropContext.h:163
SharedImageDesc CreateSharedDepthImage(std::uint32_t width, std::uint32_t height, const char *label=nullptr)
Definition: GaussianSplatVulkanInteropContext.cpp:769
VkPhysicalDevice GetPhysicalDevice() const
Definition: GaussianSplatVulkanInteropContext.h:145
bool GetDebugUtilsEnabled() const
Definition: GaussianSplatVulkanInteropContext.h:156
std::uint32_t FindMemoryType(std::uint32_t type_filter, VkMemoryPropertyFlags props) const
Definition: GaussianSplatVulkanInteropContext.cpp:455
void Shutdown()
Release all Vulkan resources and invalidate the context.
Definition: GaussianSplatVulkanInteropContext.cpp:208
std::uint32_t GetSubgroupSize() const
Definition: GaussianSplatVulkanInteropContext.h:159
const vk::raii::Device & GetRaiiDevice() const
Definition: GaussianSplatVulkanInteropContext.h:169
bool ProbeGLExtensions()
Definition: GaussianSplatVulkanInteropContext.cpp:242
void DestroySharedImage(SharedImageDesc &desc)
Definition: GaussianSplatVulkanInteropContext.cpp:775
VkInstance GetVkInstance() const
Definition: GaussianSplatVulkanInteropContext.h:139
bool IsValid() const
Definition: GaussianSplatVulkanInteropContext.h:121
std::uint32_t GetComputeQueueFamily() const
Definition: GaussianSplatVulkanInteropContext.h:151
VkDevice GetDevice() const
Definition: GaussianSplatVulkanInteropContext.h:142
bool Initialize()
Definition: GaussianSplatVulkanInteropContext.cpp:172
bool AreGLExtensionsReady() const
Definition: GaussianSplatVulkanInteropContext.h:128
int width
Definition: FilePCD.cpp:52
int height
Definition: FilePCD.cpp:53
const char const char value recording_handle imu_sample recording_handle uint8_t size_t data_size k4a_record_configuration_t config target_format k4a_capture_t capture_handle k4a_imu_sample_t imu_sample playback_handle k4a_logging_message_cb_t void min_level device_handle k4a_imu_sample_t timeout_in_ms capture_handle capture_handle capture_handle image_handle temperature_c k4a_image_t image_handle uint8_t image_handle image_handle image_handle image_handle uint32_t
Definition: K4aPlugin.cpp:548
VkInteropImageFormat
Image format selector used for interop image creation.
Definition: GaussianSplatVulkanInteropContext.h:60
@ kDepth32F
Depth-only (VK_FORMAT_D32_SFLOAT / GL DEPTH_COMPONENT32F)
@ kRGBA16F
RGBA16F colour (VK_FORMAT_R16G16B16A16_SFLOAT / GL RGBA16F)
Definition: PinholeCameraIntrinsic.cpp:16
Definition: GaussianSplatVulkanInteropContext.h:76
std::uint32_t gl_texture
GL texture name; pass to Filament.
Definition: GaussianSplatVulkanInteropContext.h:83
std::uint32_t width
Dimensions and format (stored for resize/recreate checks).
Definition: GaussianSplatVulkanInteropContext.h:86
std::uint32_t height
Definition: GaussianSplatVulkanInteropContext.h:87
VkImage vk_image
Definition: GaussianSplatVulkanInteropContext.h:77
VkDeviceMemory vk_memory
Dedicated exportable alloc.
Definition: GaussianSplatVulkanInteropContext.h:78
std::uint32_t gl_memory_object
glCreateMemoryObjectsEXT result
Definition: GaussianSplatVulkanInteropContext.h:82
bool IsValid() const
Definition: GaussianSplatVulkanInteropContext.h:94
VkInteropImageFormat format
Definition: GaussianSplatVulkanInteropContext.h:88
VkImageLayout current_layout
Definition: GaussianSplatVulkanInteropContext.h:92