16 wgpu::Instance instance;
17#if defined(__EMSCRIPTEN__)
18 instance = wgpu::CreateInstance();
22 const WGPUInstanceFeatureName requiredFeatures[] = {WGPUInstanceFeatureName_TimedWaitAny};
23 WGPUInstanceDescriptor instanceDesc{};
24 instanceDesc.requiredFeatureCount = 1;
25 instanceDesc.requiredFeatures = requiredFeatures;
26 instance = wgpu::CreateInstance(
reinterpret_cast<const wgpu::InstanceDescriptor*
>(&instanceDesc));
28 if (!instance)
throw Exception(
"WebGPU: wgpuCreateInstance failed");
33 wgpu::Instance& instance = prev.
instance;
38 std::atomic<bool> received{
false};
41 WGPURequestAdapterOptions opts{};
42 opts.compatibleSurface = compatibleSurface.Get();
43 opts.powerPreference = WGPUPowerPreference_HighPerformance;
45 WGPURequestAdapterCallbackInfo cbInfo{};
46 cbInfo.nextInChain =
nullptr;
47 cbInfo.mode = WGPUCallbackMode_AllowProcessEvents;
48 cbInfo.callback = [](WGPURequestAdapterStatus
status, WGPUAdapter
a, WGPUStringView msg,
void* userdata1,
50 auto*
r =
static_cast<Result*
>(userdata1);
51 if (
status == WGPURequestAdapterStatus_Success &&
a) {
52 r->adapter = wgpu::Adapter(
a);
54 r->error = msg.data ? std::string(msg.data, msg.length) :
"unknown adapter error";
56 r->received.store(
true);
58 cbInfo.userdata1 = &result;
59 cbInfo.userdata2 =
nullptr;
61 wgpuInstanceRequestAdapter(instance.Get(), &opts, cbInfo);
62 while (!result.received.load()) {
63#if defined(__EMSCRIPTEN__)
68 wgpuInstanceProcessEvents(instance.Get());
70 if (!result.adapter) {
71 throw Exception(
"WebGPU: no adapter found (%s)", result.error.c_str());
73 return AdapterDone{std::move(instance), std::move(result.adapter)};
77 wgpu::Instance& instance = prev.
instance;
78 wgpu::Adapter&
adapter = prev.adapter;
83 std::atomic<bool> received{
false};
86 WGPUDeviceDescriptor devDesc{};
87 devDesc.label =
sv(
"eve_device");
89 constexpr std::uint32_t requiredSampledTextures = 17;
93 constexpr std::uint32_t requiredColorAttachmentBytes = 40;
94 wgpu::Limits adapterLimits{};
95 if (
adapter.GetLimits(&adapterLimits) != wgpu::Status::Success ||
96 adapterLimits.maxSampledTexturesPerShaderStage < requiredSampledTextures)
97 throw Exception(
"WebGPU: adapter exposes fewer than %u sampled textures per shader stage",
98 requiredSampledTextures);
99 if (adapterLimits.maxColorAttachmentBytesPerSample < requiredColorAttachmentBytes)
101 "WebGPU: adapter maxColorAttachmentBytesPerSample (%u) is below the "
102 "GBuffer requirement (%u)",
103 adapterLimits.maxColorAttachmentBytesPerSample, requiredColorAttachmentBytes);
104 WGPULimits requiredLimits = WGPU_LIMITS_INIT;
105 requiredLimits.maxSampledTexturesPerShaderStage = requiredSampledTextures;
106 requiredLimits.maxColorAttachmentBytesPerSample = requiredColorAttachmentBytes;
108 devDesc.requiredLimits = &requiredLimits;
109 devDesc.uncapturedErrorCallbackInfo.callback = [](WGPUDevice
const*, WGPUErrorType
type, WGPUStringView
message,
111 std::fprintf(stderr,
"[webgpu] uncaptured error type=%d: %.*s\n",
int(
type),
int(
message.length),
115 WGPURequestDeviceCallbackInfo cbInfo{};
116 cbInfo.nextInChain =
nullptr;
117 cbInfo.mode = WGPUCallbackMode_AllowProcessEvents;
118 cbInfo.callback = [](WGPURequestDeviceStatus
status, WGPUDevice
d, WGPUStringView msg,
void* userdata1,
120 auto*
r =
static_cast<Result*
>(userdata1);
121 if (
status == WGPURequestDeviceStatus_Success &&
d) {
122 r->device = wgpu::Device(
d);
124 r->error = msg.data ? std::string(msg.data, msg.length) :
"unknown device error";
126 r->received.store(
true);
128 cbInfo.userdata1 = &result;
129 cbInfo.userdata2 =
nullptr;
131 wgpuAdapterRequestDevice(
adapter.Get(), &devDesc, cbInfo);
132 while (!result.received.load()) {
133#if defined(__EMSCRIPTEN__)
136 wgpuInstanceProcessEvents(instance.Get());
138 if (!result.device) {
139 throw Exception(
"WebGPU: device request failed (%s)", result.error.c_str());
142 wgpu::Queue queue = result.device.GetQueue();
145 return DeviceDone{std::move(instance), std::move(
adapter), std::move(result.device), std::move(queue),
wgpu::PopErrorScopeStatus status