131 {
132 if (gpu_initialized)
133 return;
134
135 wgpu::InstanceDescriptor instanceDesc = {};
136 instance = wgpu::CreateInstance(&instanceDesc);
137
138 if (!instance) {
139 std::cerr << "Fatal: WebGPU instance creation failed." << std::endl;
140 return;
141 }
142
143
144
145
146 std::cout << "Requesting Adapter..." << std::endl;
147 adapter_ready = false;
148
149 instance.RequestAdapter(
150 nullptr,
151 wgpu::CallbackMode::AllowProcessEvents,
152 [this](wgpu::RequestAdapterStatus status, wgpu::Adapter a, wgpu::StringView msg) {
153 if (status == wgpu::RequestAdapterStatus::Success) {
154 adapter = std::move(a);
155 std::cout << "Adapter Acquired" << std::endl;
156 } else {
157 std::cerr << "Adapter Failed: "
158 << std::string_view(msg.data ? msg.data : "", msg.length)
159 << std::endl;
160 }
161 adapter_ready = true;
162 }
163 );
164
165
166 while (!adapter_ready) {
167 instance.ProcessEvents();
168#if defined(__EMSCRIPTEN__)
169 emscripten_sleep(10);
170#endif
171 }
172
173 if (!adapter) {
174 std::cerr << "Fatal: Could not get WebGPU Adapter." << std::endl;
175 return;
176 }
177
178
179
180
181 std::cout << "Requesting Device..." << std::endl;
182 device_ready = false;
183
184 wgpu::DeviceDescriptor deviceDesc = {};
185 deviceDesc.SetUncapturedErrorCallback([](const wgpu::Device&, wgpu::ErrorType type,
186 wgpu::StringView msg) {
187
188 std::string err_str = (msg.data && msg.length > 0) ? std::string(msg.data, msg.length)
189 : "Unknown Error (Null message)";
190
191
192 std::cerr << "\n[WEBGPU FATAL ERROR] Type: " << static_cast<uint32_t>(type)
193 << " | Msg: " << err_str << "\n"
194 << std::endl;
195 });
196 deviceDesc.SetDeviceLostCallback(
197 wgpu::CallbackMode::AllowProcessEvents,
198 [](const wgpu::Device&, wgpu::DeviceLostReason reason, wgpu::StringView msg) {
199 std::string err_msg = (msg.data && msg.length > 0)
200 ? std::string(msg.data, msg.length)
201 : "Unknown device lost reason";
202 std::cerr << "[DEVICE LOST] Reason: " << static_cast<int>(reason)
203 << " Msg: " << err_msg << std::endl;
204 }
205 );
206
207
208 wgpu::Limits supportedLimits;
209 wgpu::Limits requiredLimits;
210 if (adapter.GetLimits(&supportedLimits)) {
211
212
213
214 requiredLimits = supportedLimits;
215
216 std::cout << "maxBufferSize: " << requiredLimits.maxBufferSize << std::endl;
217 std::cout << "maxStorageBufferBindingSize: "
218 << requiredLimits.maxStorageBufferBindingSize << std::endl;
219
220 deviceDesc.requiredLimits = &requiredLimits;
221 }
222
223 adapter.RequestDevice(
224 &deviceDesc,
225 wgpu::CallbackMode::AllowProcessEvents,
226 [this](wgpu::RequestDeviceStatus status, wgpu::Device d, wgpu::StringView msg) {
227 if (status == wgpu::RequestDeviceStatus::Success) {
228 device = std::move(d);
229 std::cout << "Device Acquired" << std::endl;
230 } else {
231 std::cerr << "Device Failed: "
232 << (msg.data && msg.length > 0 ? std::string(msg.data, msg.length)
233 : "Unknown error")
234 << std::endl;
235 }
236 device_ready = true;
237 }
238 );
239
240
241 while (!device_ready) {
242 instance.ProcessEvents();
243#if defined(__EMSCRIPTEN__)
244 emscripten_sleep(10);
245#endif
246 }
247
248 if (!device) {
249 std::cerr << "Fatal: Could not get WebGPU Device." << std::endl;
250 return;
251 }
252
253 if (!validate_device()) {
254 std::cerr << "Fatal: Could not get WebGPU Device." << std::endl;
255 return;
256 }
257
258 queue = device.GetQueue();
259 gpu_initialized = true;
260 std::cout << "GPU Fully Initialized." << std::endl;
261 };