blob: de673537d3fe580651b1bae50b6984ee58621399 [file] [log] [blame]
Loko Kung90fdaa82024-07-24 00:59:58 +00001# Copyright 2024 The Dawn & Tint Authors
2#
3# Redistribution and use in source and binary forms, with or without
4# modification, are permitted provided that the following conditions are met:
5#
6# 1. Redistributions of source code must retain the above copyright notice, this
7# list of conditions and the following disclaimer.
8#
9# 2. Redistributions in binary form must reproduce the above copyright notice,
10# this list of conditions and the following disclaimer in the documentation
11# and/or other materials provided with the distribution.
12#
13# 3. Neither the name of the copyright holder nor the names of its
14# contributors may be used to endorse or promote products derived from
15# this software without specific prior written permission.
16#
17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28DawnJSONGenerator(
29 TARGET "emdawnwebgpu_headers"
30 PRINT_NAME "Dawn WebGPU Emscripten headers"
31 OUTPUT_HEADERS EMDAWNWEBGPU_HEADERS_GEN_HEADERS
32)
33add_custom_target(emdawnwebgpu_headers_gen
34 DEPENDS ${EMDAWNWEBGPU_HEADERS_GEN_HEADERS}
35)
36
37DawnJSONGenerator(
38 TARGET "emdawnwebgpu_js"
39 PRINT_NAME "Dawn WebGPU Emscripten JS files"
40 OUTPUT_JSONS EMDAWNWEBGPU_STRUCT_INFO_JSON_GEN_SOURCES
41 OUTPUT_JS EMDAWNWEBGPU_JS_GEN_SOURCES
42)
43add_custom_target(emdawnwebgpu_js_gen
44 DEPENDS ${EMDAWNWEBGPU_STRUCT_INFO_JSON_GEN_SOURCES} ${EMDAWNWEBGPU_JS_GEN_SOURCES}
45)
46
47# When Emscripten is available, we can use one of its helper scripts to generate
48# the struct info needed for our bindings fork (third_party/emdawnwebgpu).
49# Those helpers, and their tree of generated dependencies, are:
50#
51# - library_webgpu_generated_struct_info.js
52# is constructed by concatenating:
53# - Some glue "snippets" from txt files
54# - webgpu_generated_struct_info{32,64}.json
55# which are generated using an Emscripten tool "gen_struct_info.py", from:
56# - webgpu.h (generated from dawn.json)
57# - struct_info_webgpu.json (generated from dawn.json)
58#
59# The bindings also require the following helpers (generated above):
60#
61# - library_webgpu_enum_tables.js
62# - library_webgpu_generated_sig_info.js
63# which we generate directly instead of using "gen_sig_info.py"
64if (${DAWN_ENABLE_EMSCRIPTEN})
65 set(EM_SRC_DIR "${DAWN_SRC_DIR}/emdawnwebgpu")
66 set(EM_BUILD_GEN_DIR "${DAWN_BUILD_GEN_DIR}/src/emdawnwebgpu")
67
68 function(webgpu_gen_struct_info)
69 cmake_parse_arguments(PARSE_ARGV 0 arg
70 ""
71 "OUTPUT_JSON;WASM64"
72 ""
73 )
74 if (arg_UNPARSED_ARGUMENTS)
75 message(FATAL_ERROR
76 "Unparsed arguments for webgpu_gen_struct_info: "
77 "${arg_UNPARSED_ARGUMENTS}")
78 endif()
79
80 set(ARGS
81 "${DAWN_EMSCRIPTEN_TOOLCHAIN}/tools/maint/gen_struct_info.py"
82 -q
83 "${EM_BUILD_GEN_DIR}/struct_info_webgpu.json"
84 "-I=${EM_BUILD_GEN_DIR}/include"
85 )
86
87 set(PRINT_NAME)
88 if (${arg_WASM64})
89 set(PRINT_NAME "webgpu_generated_struct_info64.json")
90 list(APPEND ARGS "--wasm64")
91 else()
92 set(PRINT_NAME "webgpu_generated_struct_info32.json")
93 endif()
94 set(OUTPUT "${EM_BUILD_GEN_DIR}/${PRINT_NAME}")
95 set(${arg_OUTPUT_JSON} "${OUTPUT}" PARENT_SCOPE)
96 list(APPEND ARGS "-o=${OUTPUT}")
97
98 add_custom_command(
99 COMMAND ${ARGS}
100 OUTPUT ${OUTPUT}
101 COMMENT "Dawn Emscripten: Generating ${PRINT_NAME}."
102 )
103
104 # Prior to CMake 3.20 the GENERATED property is local to a directory which means that putting
105 # generated headers in INTERFACE properties causes dependent targets to complain that they
106 # cannot find the file. (because they don't see it as generated and want to check is is
107 # actually on the filesystem).
108 # Work around this by generating the files once if they aren't present at configuration time.
109 if (NOT EXISTS ${OUTPUT})
110 message(STATUS "Dawn: Generating initial versions of files for ${PRINT_NAME}.")
111 execute_process(COMMAND ${ARGS} RESULT_VARIABLE RET)
112 if (NOT RET EQUAL 0)
113 message(FATAL_ERROR "Dawn: Failed to generate the initial version of files for ${PRINT_NAME}. Base args are '${ARGS}'.")
114 endif()
115 endif()
116 endfunction()
117
118 message(STATUS "Dawn: Configuring Emscripten gen_struct_info for WebGPU.")
119
120 webgpu_gen_struct_info(
121 OUTPUT_JSON WEBGPU_STRUCT_INFO_GEN32
122 WASM64 OFF
123 )
124 add_custom_target(webgpu_generated_struct_info32
125 DEPENDS emdawnwebgpu_headers_gen ${EMDAWNWEBGPU_STRUCT_INFO_JSON_GEN_SOURCES} ${WEBGPU_STRUCT_INFO_GEN32}
126 )
127 webgpu_gen_struct_info(
128 OUTPUT_JSON WEBGPU_STRUCT_INFO_GEN64
129 WASM64 ON
130 )
131 add_custom_target(webgpu_generated_struct_info64
132 DEPENDS emdawnwebgpu_headers_gen ${EMDAWNWEBGPU_STRUCT_INFO_JSON_GEN_SOURCES} ${WEBGPU_STRUCT_INFO_GEN64}
133 )
134
135 # TODO(crbug.com/346806934): Consider using CMake builtin `cat` as per https://stackoverflow.com/a/62362885,
136 # especially if we are to remove the GN build where concat.py is needed.
137 function(webgpu_gen_struct_info_js)
138 cmake_parse_arguments(PARSE_ARGV 0 arg
139 ""
140 "OUTPUT_JS"
141 ""
142 )
143 if (arg_UNPARSED_ARGUMENTS)
144 message(FATAL_ERROR
145 "Unparsed arguments for webgpu_gen_struct_info_js: "
146 "${arg_UNPARSED_ARGUMENTS}")
147 endif()
148
149 set(PRINT_NAME library_webgpu_generated_struct_info.js)
150 set(OUTPUT "${EM_BUILD_GEN_DIR}/${PRINT_NAME}")
151 set(ARGS
152 ${Python3_EXECUTABLE}
153 "${EM_SRC_DIR}/concat.py"
154 "${OUTPUT}"
155 "${EM_SRC_DIR}/snippets/library_webgpu_struct_info_part1.txt"
156 "${EM_BUILD_GEN_DIR}/webgpu_generated_struct_info32.json"
157 "${EM_SRC_DIR}/snippets/library_webgpu_struct_info_part2.txt"
158 "${EM_BUILD_GEN_DIR}/webgpu_generated_struct_info64.json"
159 "${EM_SRC_DIR}/snippets/library_webgpu_struct_info_part3.txt"
160 )
161 set(${arg_OUTPUT_JS} "${OUTPUT}" PARENT_SCOPE)
162
163 add_custom_command(
164 COMMAND ${ARGS}
165 OUTPUT ${OUTPUT}
166 COMMENT "Dawn Emscripten: Generating ${PRINT_NAME}."
167 )
168
169 # Prior to CMake 3.20 the GENERATED property is local to a directory which means that putting
170 # generated headers in INTERFACE properties causes dependent targets to complain that they
171 # cannot find the file. (because they don't see it as generated and want to check is is
172 # actually on the filesystem).
173 # Work around this by generating the files once if they aren't present at configuration time.
174 if (NOT EXISTS ${OUTPUT})
175 message(STATUS "Dawn: Generating initial versions of files for ${PRINT_NAME}.")
176 execute_process(COMMAND ${ARGS} RESULT_VARIABLE RET)
177 if (NOT RET EQUAL 0)
178 message(FATAL_ERROR "Dawn: Failed to generate the initial version of files for ${PRINT_NAME}. Base args are '${ARGS}'.")
179 endif()
180 endif()
181 endfunction()
182
183 webgpu_gen_struct_info_js(
184 OUTPUT_JS EMDAWNWEBGPU_STRUCT_INFO_JS
185 )
186 add_custom_target(webgpu_generated_struct_info_js
187 DEPENDS webgpu_generated_struct_info32 webgpu_generated_struct_info64 ${EMDAWNWEBGPU_STRUCT_INFO_JS}
188 )
189
190 add_library(emdawnwebgpu_config INTERFACE)
191 target_include_directories(emdawnwebgpu_config BEFORE INTERFACE
192 "${EM_BUILD_GEN_DIR}/include"
193 )
Kai Ninomiya84563872024-11-01 23:04:25 +0000194 add_dependencies(emdawnwebgpu_config webgpu_generated_struct_info_js emdawnwebgpu_js_gen)
Loko Kung90fdaa82024-07-24 00:59:58 +0000195 target_link_options(emdawnwebgpu_config INTERFACE
196 # We are using Dawn-generated bindings, not built-in ones
197 "-sUSE_WEBGPU=0"
Loko Kung90fdaa82024-07-24 00:59:58 +0000198 # The JS libraries needed for bindings
199 "--js-library=${EM_BUILD_GEN_DIR}/library_webgpu_enum_tables.js"
200 "--js-library=${EM_BUILD_GEN_DIR}/library_webgpu_generated_struct_info.js"
201 "--js-library=${EM_BUILD_GEN_DIR}/library_webgpu_generated_sig_info.js"
202 "--js-library=${DAWN_EMDAWNWEBGPU_DIR}/library_webgpu.js"
Loko Kung90fdaa82024-07-24 00:59:58 +0000203 "--closure-args=--externs=${DAWN_EMSCRIPTEN_TOOLCHAIN}/src/closure-externs/webgpu-externs.js"
204 )
205
206 dawn_add_library(
207 emdawnwebgpu_c
208 ENABLE_EMSCRIPTEN
209 HEADERS
210 "${EM_BUILD_GEN_DIR}/include/webgpu/webgpu.h"
211 SOURCES
212 "${DAWN_EMDAWNWEBGPU_DIR}/webgpu.cpp"
213 DEPENDS
214 emdawnwebgpu_config
215 )
216
217 dawn_add_library(
218 emdawnwebgpu_cpp
219 ENABLE_EMSCRIPTEN
220 HEADER_ONLY
221 HEADERS
Lokbondo Kung868a4672024-10-25 20:17:03 +0000222 "${EM_BUILD_GEN_DIR}/include/dawn/webgpu_cpp_print.h"
Loko Kung90fdaa82024-07-24 00:59:58 +0000223 "${EM_BUILD_GEN_DIR}/include/webgpu/webgpu_cpp.h"
224 "${EM_BUILD_GEN_DIR}/include/webgpu/webgpu_cpp_chained_struct.h"
225 "${DAWN_INCLUDE_DIR}/webgpu/webgpu_enum_class_bitmasks.h"
226 DEPENDS
227 emdawnwebgpu_c
228 )
229
Lokbondo Kung868a4672024-10-25 20:17:03 +0000230 if (${DAWN_BUILD_TESTS})
231 set(emdawnwebgpu_test_sources
232 "tests/FuturesTests.cpp"
233 )
234 add_executable(emdawnwebgpu_tests ${emdawnwebgpu_test_sources})
235 set_target_properties(emdawnwebgpu_tests PROPERTIES
236 SUFFIX ".html")
237 target_link_libraries(
238 emdawnwebgpu_tests
239 PUBLIC
240 dawn::dawn_wgpu_utils
241 emdawnwebgpu_cpp
242 gmock_main
243 )
244 target_link_options(emdawnwebgpu_tests PUBLIC
245 # We need ASYNCIFY for Future implementation. Note that for
246 # some reason, at the moment, these tests do not work with
247 # JSPI.
Kai Ninomiya84563872024-11-01 23:04:25 +0000248 "-sJSPI=1"
Lokbondo Kung868a4672024-10-25 20:17:03 +0000249 )
250 endif()
251
Loko Kung90fdaa82024-07-24 00:59:58 +0000252endif()