From 15fcee54dc923680afdbcae7354a2caeb74a2269 Mon Sep 17 00:00:00 2001 From: Sargun Vohra Date: Fri, 24 Jul 2026 00:57:28 -0700 Subject: [PATCH] core: emdawnwebgpu build support (#4370) --- CMakeLists.txt | 2 +- cmake/webgpu.cmake | 14 ++- include/mbgl/webgpu/renderer_backend.hpp | 2 + .../include/mbgl/gfx/headless_backend.hpp | 7 ++ src/mbgl/webgpu/offscreen_texture.cpp | 2 +- vendor/dawn.cmake | 32 +++++++ vendor/emdawnwebgpu.LICENSE | 92 +++++++++++++++++++ vendor/webgpu.cmake | 24 ++++- 8 files changed, 166 insertions(+), 9 deletions(-) create mode 100644 vendor/emdawnwebgpu.LICENSE diff --git a/CMakeLists.txt b/CMakeLists.txt index a940a55d8..913c1f7cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1211,7 +1211,7 @@ endif() # The Xcode generator with Dawn component targets (no monolithic library) breaks export() # because dawn_native/dawn_proc aren't in an export set. Skip export in that case. set(_can_export TRUE) -if(TARGET mbgl-vendor-dawn AND NOT TARGET dawn::webgpu_dawn) +if(TARGET mbgl-vendor-dawn AND NOT TARGET dawn::webgpu_dawn AND NOT MLN_WEBGPU_EMDAWN) set(_can_export FALSE) endif() if(_can_export) diff --git a/cmake/webgpu.cmake b/cmake/webgpu.cmake index 3338a8749..8b0ab5e59 100644 --- a/cmake/webgpu.cmake +++ b/cmake/webgpu.cmake @@ -20,7 +20,6 @@ list(APPEND ${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/buffer_resource.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/context.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/command_encoder.cpp - ${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/headless_backend.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/renderer_backend.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/drawable.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/drawable_builder.cpp @@ -119,7 +118,13 @@ include(${PROJECT_SOURCE_DIR}/vendor/webgpu.cmake) if(MLN_WEBGPU_IMPL_DAWN) include(${PROJECT_SOURCE_DIR}/vendor/dawn.cmake) if(TARGET mbgl-vendor-dawn) - target_link_libraries(mbgl-core PRIVATE mbgl-vendor-dawn) + if(MLN_WEBGPU_EMDAWN) + # Emdawn is a compiler/linker port rather than a conventional + # library. Consumers must inherit its final-link options. + target_link_libraries(mbgl-core PUBLIC mbgl-vendor-dawn) + else() + target_link_libraries(mbgl-core PRIVATE mbgl-vendor-dawn) + endif() endif() elseif(MLN_WEBGPU_IMPL_WGPU OR MLN_WEBGPU_IMPL_FFI) # Include wgpu-native integration @@ -130,3 +135,8 @@ elseif(MLN_WEBGPU_IMPL_WGPU OR MLN_WEBGPU_IMPL_FFI) list(APPEND SRC_FILES ${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/webgpu_cpp_impl.cpp) endif() endif() + +# Headless backend uses Dawn native / wgpu-native bootstrap; skip for emdawnwebgpu. +if(NOT MLN_WEBGPU_EMDAWN) + list(APPEND SRC_FILES ${PROJECT_SOURCE_DIR}/src/mbgl/webgpu/headless_backend.cpp) +endif() diff --git a/include/mbgl/webgpu/renderer_backend.hpp b/include/mbgl/webgpu/renderer_backend.hpp index 8dc5989c1..7c8cfa76d 100644 --- a/include/mbgl/webgpu/renderer_backend.hpp +++ b/include/mbgl/webgpu/renderer_backend.hpp @@ -37,6 +37,8 @@ public: void setSurface(void* nativeWindow); // WebGPU-specific methods + // Emdawn hosts that use synchronous readback must create the instance with + // WGPUInstanceFeatureName_TimedWaitAny enabled. void setInstance(void* instance); void setDevice(WGPUDevice device); void setQueue(WGPUQueue queue); diff --git a/platform/default/include/mbgl/gfx/headless_backend.hpp b/platform/default/include/mbgl/gfx/headless_backend.hpp index e6a3c9e53..e60e7f697 100644 --- a/platform/default/include/mbgl/gfx/headless_backend.hpp +++ b/platform/default/include/mbgl/gfx/headless_backend.hpp @@ -16,11 +16,18 @@ namespace gfx { class HeadlessBackend : public gfx::Renderable { public: // Factory. +#if MLN_WEBGPU_EMDAWN + static std::unique_ptr Create(const Size size = {256, 256}, + SwapBehaviour swapBehavior = SwapBehaviour::NoFlush, + const gfx::ContextMode contextMode = gfx::ContextMode::Unique) = + delete; +#else static std::unique_ptr Create(const Size size = {256, 256}, SwapBehaviour swapBehavior = SwapBehaviour::NoFlush, const gfx::ContextMode contextMode = gfx::ContextMode::Unique) { return Backend::Create(size, swapBehavior, contextMode); } +#endif virtual PremultipliedImage readStillImage() = 0; virtual RendererBackend* getRendererBackend() = 0; diff --git a/src/mbgl/webgpu/offscreen_texture.cpp b/src/mbgl/webgpu/offscreen_texture.cpp index 294fa11cf..395247a49 100644 --- a/src/mbgl/webgpu/offscreen_texture.cpp +++ b/src/mbgl/webgpu/offscreen_texture.cpp @@ -140,7 +140,7 @@ public: } // Process all pending device operations to ensure rendering is complete -#if MLN_WEBGPU_IMPL_DAWN +#if MLN_WEBGPU_IMPL_DAWN && !MLN_WEBGPU_EMDAWN wgpuDeviceTick(device); #endif diff --git a/vendor/dawn.cmake b/vendor/dawn.cmake index 48c05e122..86f47ccdc 100644 --- a/vendor/dawn.cmake +++ b/vendor/dawn.cmake @@ -8,6 +8,38 @@ if(NOT MLN_WITH_WEBGPU) return() endif() +if(MLN_WEBGPU_EMDAWN) + set(MLN_WEBGPU_EMDAWN_PORT "emdawnwebgpu" + CACHE STRING "Emscripten port name or path used for emdawnwebgpu") + + message(STATUS "Configuring emdawnwebgpu port: ${MLN_WEBGPU_EMDAWN_PORT}") + add_library(mbgl-vendor-dawn INTERFACE) + + # The port provides the WebGPU headers during compilation and its C++/JS + # implementation during linking. Asyncify lets synchronous APIs such as + # readStillImage() wait for browser WebGPU promises to resolve. + target_compile_options( + mbgl-vendor-dawn + INTERFACE "--use-port=${MLN_WEBGPU_EMDAWN_PORT}" + ) + target_link_options( + mbgl-vendor-dawn + INTERFACE + "--use-port=${MLN_WEBGPU_EMDAWN_PORT}" + "-sASYNCIFY=1" + ) + + set_target_properties( + mbgl-vendor-dawn + PROPERTIES + INTERFACE_MAPLIBRE_NAME "emdawnwebgpu" + INTERFACE_MAPLIBRE_URL "https://dawn.googlesource.com/dawn" + INTERFACE_MAPLIBRE_AUTHOR "Chromium Dawn Team" + INTERFACE_MAPLIBRE_LICENSE "${PROJECT_SOURCE_DIR}/vendor/emdawnwebgpu.LICENSE" + ) + return() +endif() + if(POLICY CMP0169) cmake_policy(SET CMP0169 OLD) endif() diff --git a/vendor/emdawnwebgpu.LICENSE b/vendor/emdawnwebgpu.LICENSE new file mode 100644 index 000000000..c7ef9c899 --- /dev/null +++ b/vendor/emdawnwebgpu.LICENSE @@ -0,0 +1,92 @@ +Emdawnwebgpu contains code under the BSD 3-Clause License and code derived +from Emscripten under either the MIT License or the University of +Illinois/NCSA Open Source License. + +============================================================================== + +BSD 3-Clause License + +Copyright 2017-2026 The Dawn & Tint Authors + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +============================================================================== + +MIT License + +Copyright (c) 2010-2014 Emscripten authors, see AUTHORS file. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +============================================================================== + +University of Illinois/NCSA Open Source License + +Copyright (c) 2010-2014 Emscripten authors, see AUTHORS file. +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +with the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimers. + +Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimers in the documentation +and/or other materials provided with the distribution. + +Neither the names of Mozilla, nor the names of its contributors may be used +to endorse or promote products derived from this Software without specific +prior written permission. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/webgpu.cmake b/vendor/webgpu.cmake index cf7d26e82..640972e13 100644 --- a/vendor/webgpu.cmake +++ b/vendor/webgpu.cmake @@ -3,22 +3,36 @@ set(MLN_WEBGPU_IMPL_DAWN OFF CACHE STRING "WebGPU with Dawn implementation") set(MLN_WEBGPU_IMPL_WGPU OFF CACHE STRING "WebGPU with wgpu implementation") +set(MLN_WEBGPU_EMDAWN OFF + CACHE BOOL "Use Emscripten emdawnwebgpu with Dawn headers (requires MLN_WEBGPU_IMPL_DAWN)") set(MLN_WEBGPU_IMPL_FFI OFF CACHE STRING "WebGPU with ffi interface") set(MLN_WEBGPU_IMPL_WEBGPU_HEADER_DIR "" CACHE STRING "If not empty use this path to the webgpu.h file") if(MLN_WITH_WEBGPU) + if(MLN_WEBGPU_EMDAWN AND NOT EMSCRIPTEN) + message(FATAL_ERROR "MLN_WEBGPU_EMDAWN requires Emscripten") + endif() + + if(MLN_WEBGPU_EMDAWN AND NOT MLN_WEBGPU_IMPL_DAWN) + message(FATAL_ERROR "MLN_WEBGPU_EMDAWN requires MLN_WEBGPU_IMPL_DAWN") + endif() + if(MLN_WEBGPU_IMPL_DAWN) message(STATUS "Using Dawn as WebGPU backend") - add_compile_definitions(MLN_WEBGPU_IMPL_DAWN) + target_compile_definitions(mbgl-core PUBLIC MLN_WEBGPU_IMPL_DAWN) + if(MLN_WEBGPU_EMDAWN) + message(STATUS "Using emdawnwebgpu port for browser WebGPU") + target_compile_definitions(mbgl-core PUBLIC MLN_WEBGPU_EMDAWN) + endif() elseif(MLN_WEBGPU_IMPL_WGPU) message(STATUS "Using wgpu as WebGPU backend") - add_compile_definitions(MLN_WEBGPU_IMPL_WGPU) + target_compile_definitions(mbgl-core PUBLIC MLN_WEBGPU_IMPL_WGPU) else() message(FATAL_ERROR "MLN_WEBGPU_IMPL_DAWN or MLN_WEBGPU_IMPL_WGPU must be set") endif() - if (MLN_WEBGPU_IMPL_FFI) - add_compile_definitions(MLN_WEBGPU_IMPL_FFI) - endif() + if(MLN_WEBGPU_IMPL_FFI) + target_compile_definitions(mbgl-core PUBLIC MLN_WEBGPU_IMPL_FFI) + endif() endif()