diff --git a/src/main.c b/src/main.c index e95b65c..c270fa4 100644 --- a/src/main.c +++ b/src/main.c @@ -3,48 +3,35 @@ #include #include -WGPUAdapter requestAdapterSync(WGPUInstance instance, - WGPURequestAdapterOptions const *options) { - typedef struct { - WGPUAdapter adapter; - bool requestEnded; - } UserData; - - UserData userData = {.adapter = NULL, .requestEnded = false}; - - // Callback called by wgpuInstanceRequestAdapter when the request returns - // This is a C++ lambda function, but could be any function defined in the - // global scope. It must be non-capturing (the brackets [] are empty) so - // that it behaves like a regular C function pointer, which is what - // wgpuInstanceRequestAdapter expects (WebGPU being a C API). The workaround - // is to convey what we want to capture through the pUserData pointer, - // provided as the last argument of wgpuInstanceRequestAdapter and received - // by the callback as its last argument. - auto onAdapterRequestEnded = [](WGPURequestAdapterStatus status, - WGPUAdapter adapter, char const *message, - void *pUserData) { - UserData &userData = *reinterpret_cast(pUserData); - if (status == WGPURequestAdapterStatus_Success) { - userData.adapter = adapter; - } else { - std::cout << "Could not get WebGPU adapter: " << message << std::endl; - } - userData.requestEnded = true; - }; - - // Call to the WebGPU request adapter procedure - wgpuInstanceRequestAdapter(instance /* equivalent of navigator.gpu */, - options, onAdapterRequestEnded, (void *)&userData); - - // We wait until userData.requestEnded gets true - { - {Wait for request to end - } +static void OnRequestAdapter(WGPURequestAdapterStatus status, + WGPUAdapter adapter, WGPUStringView message, + void *userdata1, void *userdata2) { + // TODO handle messages and errors better + if (status != WGPURequestAdapterStatus_Success) { + printf("%s", message.data); } + assert(status == WGPURequestAdapterStatus_Success); - assert(userData.requestEnded); + WGPUAdapter *result = userdata1; + if (*result == NULL) { + *result = adapter; + } +} - return userData.adapter; +void requestAdapterSync(WGPUInstance instance, + WGPURequestAdapterOptions const *options, + WGPUAdapter *adapter) { + + WGPURequestAdapterCallbackInfo info = {.mode = WGPUCallbackMode_WaitAnyOnly, + .callback = &OnRequestAdapter, + .userdata1 = adapter}; + WGPUFuture future = wgpuInstanceRequestAdapter(instance, options, info); + WGPUFutureWaitInfo wait = { + .future = future, + }; + WGPUWaitStatus status = wgpuInstanceWaitAny(instance, 1, &wait, 0); + assert(status == WGPUWaitStatus_Success); + assert(adapter); } int main() { @@ -65,6 +52,14 @@ int main() { // copied around without worrying about its size). printf("WGPU instance: %p\n", instance); + printf("Requesting Adapter.\n"); + WGPUAdapter adapter = NULL; + WGPURequestAdapterOptions adapterOpts = {0}; + requestAdapterSync(instance, &adapterOpts, &adapter); + printf("Got Adapter: %p\n", &adapter); + + // Cleanup + wgpuAdapterRelease(adapter); wgpuInstanceRelease(instance); return 0; }