Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Download dawn automatically with CMake's FetchContent, only when it is needed #1

Open
wants to merge 1 commit into
base: webgpu_native
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 2 additions & 30 deletions examples/example_emscripten_wgpu/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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:
Expand Down Expand Up @@ -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()

Expand Down
163 changes: 163 additions & 0 deletions examples/example_emscripten_wgpu/dawn-distribution/FetchDawn.cmake
Original file line number Diff line number Diff line change
@@ -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")
21 changes: 21 additions & 0 deletions examples/example_emscripten_wgpu/dawn-distribution/LICENSE.txt
Original file line number Diff line number Diff line change
@@ -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.
114 changes: 114 additions & 0 deletions examples/example_emscripten_wgpu/dawn-distribution/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<div align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/eliemichel/LearnWebGPU/main/images/webgpu-dark.svg">
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/eliemichel/LearnWebGPU/main/images/webgpu-light.svg">
<img alt="Learn WebGPU Logo" src="images/webgpu-dark.svg" width="200">
</picture>

<a href="https://github.com/eliemichel/LearnWebGPU">LearnWebGPU</a> &nbsp;|&nbsp; <a href="https://github.com/eliemichel/WebGPU-Cpp">WebGPU-C++</a> &nbsp;|&nbsp; <a href="https://github.com/eliemichel/glfw3webgpu">glfw3webgpu</a> &nbsp;|&nbsp; <a href="https://github.com/eliemichel/WebGPU-distribution">WebGPU-distribution</a>
</div>

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 `<branch_name>` to use when getting a distribution, either by downloading the source from:

```
https://github.com/eliemichel/WebGPU-distribution/archive/refs/heads/<branch_name>.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 <branch_name>
)
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.