| # Copyright 2024 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. |
| |
| import("../../scripts/dawn_overrides_with_defaults.gni") |
| |
| import("${dawn_root}/generator/dawn_generator.gni") |
| |
| dawn_json_generator("emdawnwebgpu_headers_gen") { |
| target = "emdawnwebgpu_headers" |
| outputs = [ |
| "src/emdawnwebgpu/include/dawn/webgpu_cpp_print.h", |
| "src/emdawnwebgpu/include/webgpu/webgpu.h", |
| "src/emdawnwebgpu/include/webgpu/webgpu_cpp.h", |
| "src/emdawnwebgpu/include/webgpu/webgpu_cpp_chained_struct.h", |
| ] |
| } |
| |
| source_set("emdawnwebgpu_headers") { |
| all_dependent_configs = [ "${dawn_root}/include/dawn:public" ] |
| public_deps = [ ":emdawnwebgpu_headers_gen" ] |
| |
| sources = get_target_outputs(":emdawnwebgpu_headers_gen") |
| } |
| |
| dawn_json_generator("emdawnwebgpu_js_gen") { |
| target = "emdawnwebgpu_js" |
| outputs = [ |
| "src/emdawnwebgpu/struct_info_webgpu.json", |
| "src/emdawnwebgpu/library_webgpu_enum_tables.js", |
| "src/emdawnwebgpu/library_webgpu_generated_sig_info.js", |
| ] |
| } |
| |
| # When Emscripten is available, we can use one of its helper scripts to generate |
| # the struct info needed for our bindings fork (third_party/emdawnwebgpu). |
| # Those helpers, and their tree of generated dependencies, are: |
| # |
| # - library_webgpu_generated_struct_info.js |
| # is constructed by concatenating: |
| # - Some glue "snippets" from txt files |
| # - webgpu_generated_struct_info{32,64}.json |
| # which are generated using an Emscripten tool "gen_struct_info.py", from: |
| # - webgpu.h (generated from dawn.json) |
| # - struct_info_webgpu.json (generated from dawn.json) |
| # |
| # The bindings also require the following helpers (generated above): |
| # |
| # - library_webgpu_enum_tables.js |
| # - library_webgpu_generated_sig_info.js |
| # which we generate directly instead of using "gen_sig_info.py" |
| |
| if (is_wasm) { |
| template("webgpu_gen_struct_info") { |
| action(target_name) { |
| forward_variables_from(invoker, "*") |
| |
| deps = [ |
| ":emdawnwebgpu_headers_gen", # for webgpu.h |
| ":emdawnwebgpu_js_gen", # for struct_info_webgpu.json |
| ] |
| |
| script = dawn_emscripten_dir + "/tools/gen_struct_info.py" |
| args = [ |
| "-q", # quiet |
| rebase_path(sources[0], root_build_dir), # input file |
| "-o=" + rebase_path(outputs[0], root_build_dir), # output file |
| |
| # Include dir where webgpu/webgpu.h can be found |
| "-I=" + rebase_path(target_gen_dir, root_build_dir) + "/include", |
| ] |
| if (wasm64) { |
| args += [ "--wasm64" ] |
| } |
| } |
| } |
| |
| webgpu_gen_struct_info("webgpu_generated_struct_info32") { |
| sources = [ "${target_gen_dir}/struct_info_webgpu.json" ] |
| outputs = [ "${target_gen_dir}/webgpu_generated_struct_info32.json" ] |
| wasm64 = false |
| } |
| |
| webgpu_gen_struct_info("webgpu_generated_struct_info64") { |
| sources = [ "${target_gen_dir}/struct_info_webgpu.json" ] |
| outputs = [ "${target_gen_dir}/webgpu_generated_struct_info64.json" ] |
| wasm64 = true |
| } |
| |
| action("library_webgpu_generated_struct_info") { |
| deps = [ |
| ":webgpu_generated_struct_info32", |
| ":webgpu_generated_struct_info64", |
| ] |
| |
| source_files = [ |
| # The order of these files is important. |
| "snippets/library_webgpu_struct_info_part1.txt", |
| "${target_gen_dir}/webgpu_generated_struct_info32.json", |
| "snippets/library_webgpu_struct_info_part2.txt", |
| "${target_gen_dir}/webgpu_generated_struct_info64.json", |
| "snippets/library_webgpu_struct_info_part3.txt", |
| ] |
| |
| sources = source_files |
| outputs = [ "${target_gen_dir}/library_webgpu_generated_struct_info.js" ] |
| |
| script = "concat.py" |
| args = [] |
| foreach(source, [ outputs[0] ] + sources) { |
| args += [ rebase_path(source, root_build_dir) ] |
| } |
| } |
| |
| # NOTE: Do not use this directly, because it will not add dependencies on the |
| # the included files. Use :emdawnwebgpu instead. |
| config("emdawnwebgpu_config") { |
| include_dirs = [ |
| # Include directory where webgpu/webgpu{,_cpp}.h can be found. |
| # This needs to take precedent over Emscripten's built-in include |
| # directory which also has these files (at an older revision). |
| "${target_gen_dir}/include", |
| ] |
| ldflags = [ |
| # These will be processed in order; library_webgpu.js must come after |
| # the generated files, because it depends on them. |
| # (It will assert this, and also that -sUSE_WEBGPU is not enabled.) |
| "--js-library=" + |
| rebase_path("${target_gen_dir}/library_webgpu_enum_tables.js"), |
| "--js-library=" + rebase_path( |
| "${target_gen_dir}/library_webgpu_generated_struct_info.js"), |
| "--js-library=" + |
| rebase_path("${target_gen_dir}/library_webgpu_generated_sig_info.js"), |
| "--js-library=" + rebase_path( |
| "../../third_party/emdawnwebgpu/pkg/webgpu/src/library_webgpu.js"), |
| |
| # Closure externs to avoid minifying WebGPU API symbols |
| "--closure-args=--externs=" + rebase_path( |
| "../../third_party/emdawnwebgpu/pkg/webgpu/src/webgpu-externs.js"), |
| ] |
| } |
| |
| # Dawn's WebGPU bindings for Emscripten. These don't actually use Dawn at all, |
| # but generating them in Dawn lets us keep them in sync more easily. |
| # When included in Emscripten they attempt to delete Emscripten's built-in |
| # implementation and replace it with ours. |
| # |
| # This can be built as a standalone target to generate all the files needed |
| # to feed into a separate project that is built using Emscripten. |
| # Reference emdawnwebgpu_config for how to actually do that. |
| # |
| # EXPERIMENTALLY, this should also be usable as a dependency of a gn-native |
| # Wasm build target, as an alternative to -sUSE_WEBGPU=1 which uses |
| # Emscripten's built-in WebGPU bindings. This has not been well-tested. |
| source_set("emdawnwebgpu") { |
| public_configs = [ ":emdawnwebgpu_config" ] |
| deps = [ |
| ":emdawnwebgpu_headers_gen", |
| ":emdawnwebgpu_js_gen", |
| ":library_webgpu_generated_struct_info", |
| ] |
| sources = get_target_outputs(":emdawnwebgpu_headers_gen") + |
| [ "../../third_party/emdawnwebgpu/pkg/webgpu/src/webgpu.cpp" ] |
| inputs = [ |
| # TODO(crbug.com/371024051): Changing these files doesn't seem to trigger a relink. Why? |
| "../../third_party/emdawnwebgpu/pkg/webgpu/src/library_webgpu.js", |
| ] |
| } |
| |
| # Tests |
| |
| group("tests") { |
| testonly = true |
| deps = [ |
| ":emdawnwebgpu", |
| ":emdawnwebgpu_link_test", |
| ":emdawnwebgpu_tests_asyncify", |
| ":emdawnwebgpu_tests_jspi", |
| ] |
| } |
| |
| config("emdawnwebgpu_base_test_config") { |
| cflags = [] |
| ldflags = [ "-Wno-limited-postlink-optimizations" ] |
| |
| # If possible, always build with Closure, even in debug, for its static |
| # analysis checks and to test the externs. On Mac, first check whether |
| # Closure Compiler works, as it requires either Rosetta 2 or Java to be |
| # installed. Dawn bots don't have either of those. |
| use_closure = true |
| if (host_os == "mac") { |
| use_closure = exec_script("../../third_party/gn/emsdk/can-use-closure.py", |
| [], |
| "value") |
| } |
| if (use_closure) { |
| ldflags += [ "--closure=1" ] |
| } else { |
| print("WARNING: building without Closure Compiler") |
| } |
| |
| # is_asan and is_ubsan are never true when using the Emscripten toolchain, |
| # so force enable them for all builds. (If this is fixed in sanitizers.gni, |
| # then remove this, but turn on -sSAFE_HEAP for non-ASAN debug builds.) |
| # Note this makes GN builds unsuitable for testing code size. |
| cflags += [ |
| "-fsanitize=address", |
| "-fsanitize=undefined", |
| ] |
| ldflags += [ |
| "-fsanitize=address", |
| "-fsanitize=undefined", |
| ] |
| } |
| |
| source_set("emdawnwebgpu_tests") { |
| testonly = true |
| public_configs = [ ":emdawnwebgpu_base_test_config" ] |
| public_deps = [ |
| ":emdawnwebgpu", |
| "../dawn/tests:gmock_main", |
| ] |
| sources = [ |
| "tests/FuturesTests.cpp", |
| "tests/SpotTests.cpp", |
| ] |
| } |
| |
| executable("emdawnwebgpu_tests_asyncify") { |
| testonly = true |
| deps = [ ":emdawnwebgpu_tests" ] |
| ldflags = [ |
| "-sASYNCIFY=1", |
| "-sASYNCIFY_STACK_SIZE=10000", # Needed when building with ASAN. |
| ] |
| } |
| |
| executable("emdawnwebgpu_tests_jspi") { |
| testonly = true |
| deps = [ ":emdawnwebgpu_tests" ] |
| ldflags = [ |
| "-Wno-experimental", # -sJSPI is experimental. |
| "-sJSPI", |
| ] |
| } |
| |
| # A "sample" that makes real (bogus) API calls to serve as a basic code size test. |
| dawn_json_generator("emdawnwebgpu_link_test_cpp_gen") { |
| target = "emdawnwebgpu_link_test_cpp" |
| outputs = [ "src/emdawnwebgpu/LinkTest.cpp" ] |
| } |
| executable("emdawnwebgpu_link_test") { |
| # The test is just that this links, not that it runs (it will just |
| # crash), so just build to .js. Since it has a main() function, this is |
| # the same as building to .html, but skipping the .html file. |
| output_extension = "js" |
| |
| testonly = true |
| configs += [ ":emdawnwebgpu_base_test_config" ] |
| deps = [ |
| ":emdawnwebgpu", |
| ":emdawnwebgpu_link_test_cpp_gen", |
| ] |
| sources = get_target_outputs(":emdawnwebgpu_link_test_cpp_gen") |
| } |
| } |