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