Loko Kung | 90fdaa8 | 2024-07-24 00:59:58 +0000 | [diff] [blame] | 1 | # 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 | |
| 28 | DawnJSONGenerator( |
| 29 | TARGET "emdawnwebgpu_headers" |
| 30 | PRINT_NAME "Dawn WebGPU Emscripten headers" |
| 31 | OUTPUT_HEADERS EMDAWNWEBGPU_HEADERS_GEN_HEADERS |
| 32 | ) |
| 33 | add_custom_target(emdawnwebgpu_headers_gen |
| 34 | DEPENDS ${EMDAWNWEBGPU_HEADERS_GEN_HEADERS} |
| 35 | ) |
| 36 | |
| 37 | DawnJSONGenerator( |
| 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 | ) |
| 43 | add_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" |
| 64 | if (${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 Ninomiya | 8456387 | 2024-11-01 23:04:25 +0000 | [diff] [blame] | 194 | add_dependencies(emdawnwebgpu_config webgpu_generated_struct_info_js emdawnwebgpu_js_gen) |
Loko Kung | 90fdaa8 | 2024-07-24 00:59:58 +0000 | [diff] [blame] | 195 | target_link_options(emdawnwebgpu_config INTERFACE |
| 196 | # We are using Dawn-generated bindings, not built-in ones |
| 197 | "-sUSE_WEBGPU=0" |
Loko Kung | 90fdaa8 | 2024-07-24 00:59:58 +0000 | [diff] [blame] | 198 | # 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 Kung | 90fdaa8 | 2024-07-24 00:59:58 +0000 | [diff] [blame] | 203 | "--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 Kung | 868a467 | 2024-10-25 20:17:03 +0000 | [diff] [blame] | 222 | "${EM_BUILD_GEN_DIR}/include/dawn/webgpu_cpp_print.h" |
Loko Kung | 90fdaa8 | 2024-07-24 00:59:58 +0000 | [diff] [blame] | 223 | "${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 Kung | 868a467 | 2024-10-25 20:17:03 +0000 | [diff] [blame] | 230 | 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 Ninomiya | 8456387 | 2024-11-01 23:04:25 +0000 | [diff] [blame] | 248 | "-sJSPI=1" |
Lokbondo Kung | 868a467 | 2024-10-25 20:17:03 +0000 | [diff] [blame] | 249 | ) |
| 250 | endif() |
| 251 | |
Loko Kung | 90fdaa8 | 2024-07-24 00:59:58 +0000 | [diff] [blame] | 252 | endif() |