diff --git a/examples/example_emscripten_wgpu/CMakeLists.txt b/examples/example_emscripten_wgpu/CMakeLists.txt index 646c5b3c298b..2b7bad6b4725 100644 --- a/examples/example_emscripten_wgpu/CMakeLists.txt +++ b/examples/example_emscripten_wgpu/CMakeLists.txt @@ -1,7 +1,6 @@ # Building for desktop (WebGPU-native) with Dawn: # -# git clone https://github.com/google/dawn dawn -# cmake -B build -DIMGUI_DAWN_DIR=dawn +# cmake -B build # cmake --build build # # The resulting binary will be found at one of the following locations: @@ -33,34 +32,7 @@ if(EMSCRIPTEN) set(LIBRARIES glfw) add_compile_options(-sDISABLE_EXCEPTION_CATCHING=1 -DIMGUI_DISABLE_FILE_FUNCTIONS=1) else() - # Dawn wgpu desktop - set(DAWN_FETCH_DEPENDENCIES ON) - set(IMGUI_DAWN_DIR CACHE PATH "Path to Dawn repository") - if (NOT IMGUI_DAWN_DIR) - message(FATAL_ERROR "Please specify the Dawn repository by setting IMGUI_DAWN_DIR") - endif() - - option(DAWN_FETCH_DEPENDENCIES "Use fetch_dawn_dependencies.py as an alternative to using depot_tools" ON) - - # Dawn builds many things by default - disable things we don't need - option(DAWN_BUILD_SAMPLES "Enables building Dawn's samples" OFF) - option(TINT_BUILD_CMD_TOOLS "Build the Tint command line tools" OFF) - option(TINT_BUILD_DOCS "Build documentation" OFF) - option(TINT_BUILD_TESTS "Build tests" OFF) - if (NOT APPLE) - option(TINT_BUILD_MSL_WRITER "Build the MSL output writer" OFF) - endif() - if(WIN32) - option(TINT_BUILD_SPV_READER "Build the SPIR-V input reader" OFF) - option(TINT_BUILD_WGSL_READER "Build the WGSL input reader" ON) - option(TINT_BUILD_GLSL_WRITER "Build the GLSL output writer" OFF) - option(TINT_BUILD_GLSL_VALIDATOR "Build the GLSL output validator" OFF) - option(TINT_BUILD_SPV_WRITER "Build the SPIR-V output writer" OFF) - option(TINT_BUILD_WGSL_WRITER "Build the WGSL output writer" ON) - endif() - - add_subdirectory("${IMGUI_DAWN_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/dawn" EXCLUDE_FROM_ALL) - + include(dawn-distribution/FetchDawn.cmake) set(LIBRARIES webgpu_dawn webgpu_cpp webgpu_glfw glfw) endif() diff --git a/examples/example_emscripten_wgpu/dawn-distribution/FetchDawn.cmake b/examples/example_emscripten_wgpu/dawn-distribution/FetchDawn.cmake new file mode 100644 index 000000000000..514238b1c66c --- /dev/null +++ b/examples/example_emscripten_wgpu/dawn-distribution/FetchDawn.cmake @@ -0,0 +1,163 @@ +# Prevent multiple includes +if (TARGET dawn_native) + return() +endif() + +include(FetchContent) + +FetchContent_Declare( + dawn + #GIT_REPOSITORY https://dawn.googlesource.com/dawn + #GIT_TAG 7eeefdef6b539dadfede41295cae186ba92bb36d + #GIT_SHALLOW ON + + # Manual download mode, even shallower than GIT_SHALLOW ON + DOWNLOAD_COMMAND + cd ${FETCHCONTENT_BASE_DIR}/dawn-src && + git init && + git fetch --depth=1 https://dawn.googlesource.com/dawn 7eeefdef6b539dadfede41295cae186ba92bb36d && + git reset --hard FETCH_HEAD +) + +FetchContent_GetProperties(dawn) +if (NOT dawn_POPULATED) + FetchContent_Populate(dawn) + + # This option replaces depot_tools + set(DAWN_FETCH_DEPENDENCIES ON) + + # A more minimalistic choice of backand than Dawn's default + if (APPLE) + set(USE_VULKAN OFF) + set(USE_METAL ON) + else() + set(USE_VULKAN ON) + set(USE_METAL OFF) + endif() + set(DAWN_ENABLE_D3D11 OFF) + set(DAWN_ENABLE_D3D12 OFF) + set(DAWN_ENABLE_METAL ${USE_METAL}) + set(DAWN_ENABLE_NULL OFF) + set(DAWN_ENABLE_DESKTOP_GL OFF) + set(DAWN_ENABLE_OPENGLES OFF) + set(DAWN_ENABLE_VULKAN ${USE_VULKAN}) + set(TINT_BUILD_SPV_READER OFF) + + # Disable unneeded parts + set(DAWN_BUILD_SAMPLES OFF) + set(TINT_BUILD_TINT OFF) + set(TINT_BUILD_SAMPLES OFF) + set(TINT_BUILD_DOCS OFF) + set(TINT_BUILD_TESTS OFF) + set(TINT_BUILD_FUZZERS OFF) + set(TINT_BUILD_SPIRV_TOOLS_FUZZER OFF) + set(TINT_BUILD_AST_FUZZER OFF) + set(TINT_BUILD_REGEX_FUZZER OFF) + set(TINT_BUILD_BENCHMARKS OFF) + set(TINT_BUILD_TESTS OFF) + set(TINT_BUILD_AS_OTHER_OS OFF) + set(TINT_BUILD_REMOTE_COMPILE OFF) + + add_subdirectory(${dawn_SOURCE_DIR} ${dawn_BINARY_DIR}) +endif () + +set(AllDawnTargets + core_tables + dawn_common + dawn_glfw + dawn_headers + dawn_native + dawn_platform + dawn_proc + dawn_utils + dawn_wire + dawncpp + dawncpp_headers + emscripten_bits_gen + enum_string_mapping + extinst_tables + webgpu_dawn + webgpu_headers_gen + + tint_api + tint_api_common + tint_api_options + tint_cmd_common + tint_cmd_info_cmd + tint_cmd_loopy_cmd + tint_cmd_remote_compile_cmd + tint_cmd_tint_cmd + tint_lang_core + tint_lang_core_constant + tint_lang_core_intrinsic + tint_lang_core_ir + tint_lang_core_ir_transform + tint_lang_core_type + tint_lang_glsl_validate + tint_lang_glsl_writer_raise + tint_lang_hlsl_writer_common + tint_lang_msl_writer_raise + tint_lang_spirv + tint_lang_spirv_intrinsic + tint_lang_spirv_ir + tint_lang_spirv_reader_common + tint_lang_spirv_type + tint_lang_spirv_writer + tint_lang_spirv_writer_ast_printer + tint_lang_spirv_writer_ast_raise + tint_lang_spirv_writer_common + tint_lang_spirv_writer_helpers + tint_lang_spirv_writer_printer + tint_lang_spirv_writer_raise + tint_lang_wgsl + tint_lang_wgsl_ast + tint_lang_wgsl_ast_transform + tint_lang_wgsl_helpers + tint_lang_wgsl_inspector + tint_lang_wgsl_intrinsic + tint_lang_wgsl_ir + tint_lang_wgsl_program + tint_lang_wgsl_reader + tint_lang_wgsl_reader_lower + tint_lang_wgsl_reader_parser + tint_lang_wgsl_reader_program_to_ir + tint_lang_wgsl_resolver + tint_lang_wgsl_sem + tint_lang_wgsl_writer + tint_lang_wgsl_writer_ast_printer + tint_lang_wgsl_writer_ir_to_program + tint_lang_wgsl_writer_raise + tint_lang_wgsl_writer_syntax_tree_printer + tint_utils_cli + tint_utils_command + tint_utils_containers + tint_utils_debug + tint_utils_diagnostic + tint_utils_file + tint_utils_generator + tint_utils_ice + tint_utils_id + tint_utils_macros + tint_utils_math + tint_utils_memory + tint_utils_reflection + tint_utils_result + tint_utils_rtti + tint_utils_socket + tint_utils_strconv + tint_utils_symbol + tint_utils_text + tint_utils_traits + tint-format + tint-lint +) + +foreach (Target ${AllDawnTargets}) + if (TARGET ${Target}) + set_property(TARGET ${Target} PROPERTY FOLDER "Dawn") + endif() +endforeach() + +# This is likely needed for other targets as well +# TODO: Notify this upstream (is this still needed?) +target_include_directories(dawn_utils PUBLIC "${CMAKE_BINARY_DIR}/_deps/dawn-src/src") diff --git a/examples/example_emscripten_wgpu/dawn-distribution/LICENSE.txt b/examples/example_emscripten_wgpu/dawn-distribution/LICENSE.txt new file mode 100644 index 000000000000..01b38b2ba535 --- /dev/null +++ b/examples/example_emscripten_wgpu/dawn-distribution/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022-2023 Élie Michel + +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. diff --git a/examples/example_emscripten_wgpu/dawn-distribution/README.md b/examples/example_emscripten_wgpu/dawn-distribution/README.md new file mode 100644 index 000000000000..dce040d39280 --- /dev/null +++ b/examples/example_emscripten_wgpu/dawn-distribution/README.md @@ -0,0 +1,114 @@ +
+ + + + Learn WebGPU Logo + + + LearnWebGPU  |  WebGPU-C++  |  glfw3webgpu  |  WebGPU-distribution +
+ +WebGPU distribution +=================== + +Overview +-------- + +The standard [WebGPU](https://www.w3.org/TR/webgpu) graphics API has multiple implementations, mostly [wgpu-native](https://github.com/gfx-rs/wgpu-native) (Firefox) and [Dawn](https://dawn.googlesource.com/dawn) (Chrome). + +This repository provides **distributions** of these implementations that are: + + - **Easy to integrate.** These are standard [CMake](https://cmake.org) projects, that can be included either with a simple `add_subdirectory` (potentially using git submodules) or using [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html). No esoteric build tool is needed. + + - **Interchangeable.** Switching from one backend to another one does not require any change to the build system. Just replace your `webgpu` directory by a different distribution. A preprocessor variable `WEBGPU_BACKEND_WGPU` or `WEBGPU_BACKEND_DAWN` is defined to handle discrepancies in the source code. + + - **emscripten-ready** When calling `emcmake`, these distributions switch to emscripten's WebGPU header (which is mapped to JavaScript WebGPU API). + +As a bonus, they include a [WebGPU-C++](https://github.com/eliemichel/WebGPU-Cpp) header consistent with the backend capabilities to ease C++ development of WebGPU-based applications. + +Usage +----- + +Different options for using this repository are detailed bellow. The only difference is the `` to use when getting a distribution, either by downloading the source from: + +``` +https://github.com/eliemichel/WebGPU-distribution/archive/refs/heads/.zip +``` + +and including it with `add_subdirectory(webgpu)`, or by using fetch content: + +```CMake +FetchContent_Declare( + webgpu + GIT_REPOSITORY https://github.com/eliemichel/WebGPU-distribution + GIT_TAG +) +FetchContent_MakeAvailable(webgpu) +``` + +This creates a `webgpu` CMake target that you can link against. + +**NB** In order to ensure that dynamically linked backend are copied next to the generated application, call `target_copy_webgpu_binaries(TargetName)` at the end of your CMakeLists for each target `TargetName` that links against `webgpu`. + +### Option A: Flexibility + +**Branch:** `main` (recommended) + +The main branch enables one to chose any backend when configuring the project by setting the `WEBGPU_BACKEND` CMake cache variable. It is even possible to maintain multiple builds that use different backends: + +```bash +# Build using wgpu-native backend +cmake -B build-wgpu -DWEBGPU_BACKEND=WGPU +cmake --build build-wgpu + +# Build using Dawn backend +cmake -B build-dawn -DWEBGPU_BACKEND=DAWN +cmake --build build-dawn + +# Build using emscripten +emcmake cmake -B build-emscripten +cmake --build build-emscripten +``` + +Other branches enable only one of these solutions. Use them only if you want to target a specific backend. + +An alternate way to include this option is to copy the `webgpu.cmake` file in your project and call `include(webgpu.cmake)`. You may then adapt the `GIT_TAG` to freeze the version of each backend (by specifying an exact commit hash). + +### Option B: Speed + +**Branch:** `wgpu` + +This backend is provided as pre-compiled binaries. You need to trust these binaries, but if you do it is the fastest solution. + +This is also the solution to use for fully offline builds as it does not fetch any other content. + +### Option C: Comfort + +**Branch:** `dawn` + +**Extra dependency:** [Python](https://www.python.org) + +The Dawn-based branch compiles a WebGPU backend entirely from source, including a code generation step that requires Python. This is safer but takes some time to build the first time. + +Dawn provides much more details about errors than wgpu-native. And since it is a C++ project, it provides stack trace information that integrates nicely in IDEs. + +### Option D: Web + +**Branch:** `emscripten` + +One of the strengths of WebGPU is to be possibly built as web pages. This branch is very lightweight, since when targeting only the web, no backend is needed (the web browser provides is at runtime). + +Details +------- + +> *Why is this distribution repository needed?* + +In theory we could use WebGPU backends as packaged by their developers. However in their current state, they suffer from some limitations: + + - wgpu-native does not provide any CMake integration. + + - wgpu-native auto-built binaries have some issues: binaries for Windows and macOS were incorrectly named (defeating linking), Windows release build is sometimes missing. + + - Dawn build instructions require the installation of depot_tools, which is overkill: our distribution replaces it with a simple Python script, Python being needed anyways for code generation purposes. + + - Dawn provides a C++ interface similar in some ways to WebGPU-C++ but that cannot be used with wgpu-native because it directly communicates with the Dawn backend instead of using only the standard `webgpu.h` header.