diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 9ec3687c6..4645c48a9 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -45,6 +45,9 @@ Other Changes: - Style: border sizes are now scaled (and rounded) by ScaleAllSizes(). - Clipper: clear DisplayStart/DisplayEnd fields when Step() returns false. +- Examples: + - WGPU: fixed undefined behaviors in example code for requesting adapter + and device. (#9246, #9256) [@r-lyeh] ----------------------------------------------------------------------- diff --git a/examples/example_glfw_wgpu/main.cpp b/examples/example_glfw_wgpu/main.cpp index 1a6373c8a..f77314bd6 100644 --- a/examples/example_glfw_wgpu/main.cpp +++ b/examples/example_glfw_wgpu/main.cpp @@ -385,23 +385,29 @@ static WGPUAdapter RequestAdapter(WGPUInstance& instance) { WGPURequestAdapterOptions adapter_options = {}; - WGPUAdapter local_adapter; + WGPUAdapter local_adapter = nullptr; WGPURequestAdapterCallbackInfo adapterCallbackInfo = {}; + adapterCallbackInfo.mode = WGPUCallbackMode_WaitAnyOnly; adapterCallbackInfo.callback = handle_request_adapter; adapterCallbackInfo.userdata1 = &local_adapter; - wgpuInstanceRequestAdapter(instance, &adapter_options, adapterCallbackInfo); + WGPUFuture future = wgpuInstanceRequestAdapter(instance, &adapter_options, adapterCallbackInfo); + WGPUFutureWaitInfo waitInfo = { future, false }; + wgpuInstanceWaitAny(instance, 1, &waitInfo, ~0ull); IM_ASSERT(local_adapter && "Error on Adapter request"); return local_adapter; } -static WGPUDevice RequestDevice(WGPUAdapter& adapter) +static WGPUDevice RequestDevice(WGPUInstance& instance, WGPUAdapter& adapter) { - WGPUDevice local_device; + WGPUDevice local_device = nullptr; WGPURequestDeviceCallbackInfo deviceCallbackInfo = {}; + deviceCallbackInfo.mode = WGPUCallbackMode_WaitAnyOnly; deviceCallbackInfo.callback = handle_request_device; deviceCallbackInfo.userdata1 = &local_device; - wgpuAdapterRequestDevice(adapter, nullptr, deviceCallbackInfo); + WGPUFuture future = wgpuAdapterRequestDevice(adapter, nullptr, deviceCallbackInfo); + WGPUFutureWaitInfo waitInfo = { future, false }; + wgpuInstanceWaitAny(instance, 1, &waitInfo, ~0ull); IM_ASSERT(local_device && "Error on Device request"); return local_device; } @@ -449,7 +455,11 @@ bool InitWGPU(GLFWwindow* window) // WGPU backend: Adapter and Device acquisition, Surface creation #elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) - wgpu_instance = wgpuCreateInstance(nullptr); + WGPUInstanceDescriptor instanceDesc = {}; + WGPUInstanceFeatureName timedWaitAny = WGPUInstanceFeatureName_TimedWaitAny; + instanceDesc.requiredFeatureCount = 1; + instanceDesc.requiredFeatures = &timedWaitAny; + wgpu_instance = wgpuCreateInstance(&instanceDesc); #ifdef __EMSCRIPTEN__ getAdapterAndDeviceViaJS(); @@ -476,7 +486,7 @@ bool InitWGPU(GLFWwindow* window) WGPUAdapter adapter = RequestAdapter(wgpu_instance); ImGui_ImplWGPU_DebugPrintAdapterInfo(adapter); - wgpu_device = RequestDevice(adapter); + wgpu_device = RequestDevice(wgpu_instance, adapter); // Create the surface. wgpu_surface = CreateWGPUSurface(wgpu_instance, window); diff --git a/examples/example_sdl2_wgpu/main.cpp b/examples/example_sdl2_wgpu/main.cpp index 40a206cf1..66bd77015 100644 --- a/examples/example_sdl2_wgpu/main.cpp +++ b/examples/example_sdl2_wgpu/main.cpp @@ -369,23 +369,29 @@ static WGPUAdapter RequestAdapter(WGPUInstance& instance) { WGPURequestAdapterOptions adapter_options = {}; - WGPUAdapter local_adapter; + WGPUAdapter local_adapter = nullptr; WGPURequestAdapterCallbackInfo adapterCallbackInfo = {}; + adapterCallbackInfo.mode = WGPUCallbackMode_WaitAnyOnly; adapterCallbackInfo.callback = handle_request_adapter; adapterCallbackInfo.userdata1 = &local_adapter; - wgpuInstanceRequestAdapter(instance, &adapter_options, adapterCallbackInfo); + WGPUFuture future = wgpuInstanceRequestAdapter(instance, &adapter_options, adapterCallbackInfo); + WGPUFutureWaitInfo waitInfo = { future, false }; + wgpuInstanceWaitAny(instance, 1, &waitInfo, ~0ull); IM_ASSERT(local_adapter && "Error on Adapter request"); return local_adapter; } -static WGPUDevice RequestDevice(WGPUAdapter& adapter) +static WGPUDevice RequestDevice(WGPUInstance& instance, WGPUAdapter& adapter) { - WGPUDevice local_device; + WGPUDevice local_device = nullptr; WGPURequestDeviceCallbackInfo deviceCallbackInfo = {}; + deviceCallbackInfo.mode = WGPUCallbackMode_WaitAnyOnly; deviceCallbackInfo.callback = handle_request_device; deviceCallbackInfo.userdata1 = &local_device; - wgpuAdapterRequestDevice(adapter, nullptr, deviceCallbackInfo); + WGPUFuture future = wgpuAdapterRequestDevice(adapter, nullptr, deviceCallbackInfo); + WGPUFutureWaitInfo waitInfo = { future, false }; + wgpuInstanceWaitAny(instance, 1, &waitInfo, ~0ull); IM_ASSERT(local_device && "Error on Device request"); return local_device; } @@ -434,7 +440,11 @@ static bool InitWGPU(SDL_Window* window) // WGPU backend: Adapter and Device acquisition, Surface creation #elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) - wgpu_instance = wgpuCreateInstance(nullptr); + WGPUInstanceDescriptor instanceDesc = {}; + WGPUInstanceFeatureName timedWaitAny = WGPUInstanceFeatureName_TimedWaitAny; + instanceDesc.requiredFeatureCount = 1; + instanceDesc.requiredFeatures = &timedWaitAny; + wgpu_instance = wgpuCreateInstance(&instanceDesc); #ifdef __EMSCRIPTEN__ getAdapterAndDeviceViaJS(); @@ -461,7 +471,7 @@ static bool InitWGPU(SDL_Window* window) WGPUAdapter adapter = RequestAdapter(wgpu_instance); ImGui_ImplWGPU_DebugPrintAdapterInfo(adapter); - wgpu_device = RequestDevice(adapter); + wgpu_device = RequestDevice(wgpu_instance, adapter); // Create the surface. wgpu_surface = CreateWGPUSurface(wgpu_instance, window); diff --git a/examples/example_sdl3_wgpu/main.cpp b/examples/example_sdl3_wgpu/main.cpp index 795ffbacf..aa67d3098 100644 --- a/examples/example_sdl3_wgpu/main.cpp +++ b/examples/example_sdl3_wgpu/main.cpp @@ -380,23 +380,29 @@ static WGPUAdapter RequestAdapter(WGPUInstance& instance) { WGPURequestAdapterOptions adapter_options = {}; - WGPUAdapter local_adapter; + WGPUAdapter local_adapter = nullptr; WGPURequestAdapterCallbackInfo adapterCallbackInfo = {}; + adapterCallbackInfo.mode = WGPUCallbackMode_WaitAnyOnly; adapterCallbackInfo.callback = handle_request_adapter; adapterCallbackInfo.userdata1 = &local_adapter; - wgpuInstanceRequestAdapter(instance, &adapter_options, adapterCallbackInfo); + WGPUFuture future = wgpuInstanceRequestAdapter(instance, &adapter_options, adapterCallbackInfo); + WGPUFutureWaitInfo waitInfo = { future, false }; + wgpuInstanceWaitAny(instance, 1, &waitInfo, ~0ull); IM_ASSERT(local_adapter && "Error on Adapter request"); return local_adapter; } -static WGPUDevice RequestDevice(WGPUAdapter& adapter) +static WGPUDevice RequestDevice(WGPUInstance& instance, WGPUAdapter& adapter) { - WGPUDevice local_device; + WGPUDevice local_device = nullptr; WGPURequestDeviceCallbackInfo deviceCallbackInfo = {}; + deviceCallbackInfo.mode = WGPUCallbackMode_WaitAnyOnly; deviceCallbackInfo.callback = handle_request_device; deviceCallbackInfo.userdata1 = &local_device; - wgpuAdapterRequestDevice(adapter, nullptr, deviceCallbackInfo); + WGPUFuture future = wgpuAdapterRequestDevice(adapter, nullptr, deviceCallbackInfo); + WGPUFutureWaitInfo waitInfo = { future, false }; + wgpuInstanceWaitAny(instance, 1, &waitInfo, ~0ull); IM_ASSERT(local_device && "Error on Device request"); return local_device; } @@ -445,7 +451,11 @@ static bool InitWGPU(SDL_Window* window) // WGPU backend: Adapter and Device acquisition, Surface creation #elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) - wgpu_instance = wgpuCreateInstance(nullptr); + WGPUInstanceDescriptor instanceDesc = {}; + WGPUInstanceFeatureName timedWaitAny = WGPUInstanceFeatureName_TimedWaitAny; + instanceDesc.requiredFeatureCount = 1; + instanceDesc.requiredFeatures = &timedWaitAny; + wgpu_instance = wgpuCreateInstance(&instanceDesc); #ifdef __EMSCRIPTEN__ getAdapterAndDeviceViaJS(); @@ -472,7 +482,7 @@ static bool InitWGPU(SDL_Window* window) WGPUAdapter adapter = RequestAdapter(wgpu_instance); ImGui_ImplWGPU_DebugPrintAdapterInfo(adapter); - wgpu_device = RequestDevice(adapter); + wgpu_device = RequestDevice(wgpu_instance, adapter); // Create the surface. wgpu_surface = CreateWGPUSurface(wgpu_instance, window);