====== WebGPU with EMSCRIPTEN ====== ===== References ===== ==== Key references ==== * Gitlab issue: https://gitlab.nervtech.org/nerv/nervland/-/issues/19 * https://emscripten.org/docs/api_reference/html5.h.html * https://developer.chrome.com/blog/webgpu-cross-platform?hl=fr * https://webgpufundamentals.org/webgpu/lessons/webgpu-resizing-the-canvas.html * [[https://tomassetti.me/wasi-how-to-run-webassembly-code-outside-of-your-browser/|How to run WASM outside of your browser]] * https://lyceum-allotments.github.io/2016/06/emscripten-and-sdl-2-tutorial-part-1/ ===== Usage notes ===== * To run the SDL test app we use the command: nvp nvl_serve_sdl_wasm * To run the native version of the WebGPU test app we use: nvp nvl_wgpu_wasm * To run the webgpu test app: nvp nvl_serve_wgpu_wasm ===== Building initial app with WebGPU and Emscripten ===== Created a script to run a simple SDL app in wasm: nvp nvl_serve_sdl_wasm Created another script to run a minimal Native SDL app: nvp nvl_sdl_minimal Created a script to run a simple wgpu native app: nvp nvl_wgpu_wasm I seem to have an issue when creating the WebGPU instance with native code as this is failing: // Create the webgpu instance: DEBUG_MSG("Creating WebGPU instance..."); instance = wgpu::CreateInstance(); DEBUG_MSG("WebGPU instance created.");/*//*/ **OK**, so I found this page https://groups.google.com/g/dawn-graphics/c/KdJERoKG4No, and then refactored a bit the way I link to the dawn libraries introducing the **DAWN_BASE_LIBS** variable and building **DAWN_LIBS** or **WGPU_LIBS** on top of it. => For this demo I can now use **WGPU_LIBS** and this doesn't need to link to the **dawn_proc** library, but will use **webgpu_dawn** instead. And now creating the instance works 👍! Before I could manage to build the native version correctly I had to fix the RenderPipeline creation process, since we also need to provide the entrypoints for the shader: void CreateRenderPipeline() { wgpu::ShaderModuleWGSLDescriptor wgslDesc{}; wgslDesc.code = shaderCode; wgpu::ShaderModuleDescriptor shaderModuleDescriptor{.nextInChain = &wgslDesc}; DEBUG_MSG("Creating shader module."); wgpu::ShaderModule shaderModule = device.CreateShaderModule(&shaderModuleDescriptor); DEBUG_MSG("Done creating shader module."); if (shaderModule == nullptr) { DEBUG_MSG("ERROR: Invalid shader module!"); exit(0); } shaderModule.GetCompilationInfo(wgpu_compilation_info_callback, nullptr); instance.ProcessEvents(); wgpu::ColorTargetState colorTargetState{ .format = wgpu::TextureFormat::BGRA8Unorm}; wgpu::FragmentState fragmentState{.module = shaderModule, .entryPoint = "fragmentMain", .targetCount = 1, .targets = &colorTargetState}; wgpu::RenderPipelineDescriptor descriptor{ .vertex = {.module = shaderModule, .entryPoint = "vertexMain"}, .fragment = &fragmentState}; DEBUG_MSG("Creating pipeline"); pipeline = device.CreateRenderPipeline(&descriptor); DEBUG_MSG("Done creating pipeline"); } And I also added support to retrieve some debug outputs from the device in the process: GetDevice([](wgpu::Device dev) { device = dev; device.SetUncapturedErrorCallback(printDeviceError, nullptr); device.SetDeviceLostCallback(deviceLostCallback, nullptr); device.SetLoggingCallback(deviceLogCallback, nullptr); run(); }); When first trying to build with emscripten I got the following errors: :\Projects\NervProj\tools\windows\emsdk-git\upstream\emscripten\em++.bat -DBOOST_ALL_STATIC_LINK -DNV_LIB_STATIC -DNV_USE_UNSAFE_WGPU_APIS=1 -D_CRT_SECURE_NO_WARNINGS -ID:/Projects/NervProj/libraries/windows_emcc/boost-1.79.0/include -ID:/Projects/NervProj/libraries/windows_emcc/fmt-9.1.1/include -ID:/Projects/NervLand/sources/nvCore/src -ID:/Projects/NervProj/libraries/windows_emcc/SDL2-2.26.5/include -std=c++20 -fpch-instantiate-templates -pthread -g -O0 -MD -MT tests/test_webgpu_wasm/CMakeFiles/test_webgpu_wasm.dir/main.cpp.o -MF tests\test_webgpu_wasm\CMakeFiles\test_webgpu_wasm.dir\main.cpp.o.d -o tests/test_webgpu_wasm/CMakeFiles/test_webgpu_wasm.dir/main.cpp.o -c D:/Projects/NervLand/tests/test_webgpu_wasm/main.cpp D:/Projects/NervLand/tests/test_webgpu_wasm/main.cpp:70:24: error: unknown type name 'WGPULoggingType' void deviceLogCallback(WGPULoggingType type, const char* message, ^ D:/Projects/NervLand/tests/test_webgpu_wasm/main.cpp:73:10: error: use of undeclared identifier 'WGPULoggingType_Verbose' case WGPULoggingType_Verbose: ^ D:/Projects/NervLand/tests/test_webgpu_wasm/main.cpp:76:10: error: use of undeclared identifier 'WGPULoggingType_Info' case WGPULoggingType_Info: ^ D:/Projects/NervLand/tests/test_webgpu_wasm/main.cpp:79:10: error: use of undeclared identifier 'WGPULoggingType_Warning' case WGPULoggingType_Warning: ^ D:/Projects/NervLand/tests/test_webgpu_wasm/main.cpp:82:10: error: use of undeclared identifier 'WGPULoggingType_Error' case WGPULoggingType_Error: ^ D:/Projects/NervLand/tests/test_webgpu_wasm/main.cpp:145:14: error: no member named 'code' in 'wgpu::ShaderModuleWGSLDescriptor' wgslDesc.code = shaderCode; ~~~~~~~~ ^ D:/Projects/NervLand/tests/test_webgpu_wasm/main.cpp:346:16: error: no member named 'SetLoggingCallback' in 'wgpu::Device' device.SetLoggingCallback(deviceLogCallback, nullptr); ~~~~~~ ^ 7 errors generated. => Checking the file **D:/Projects/NervProj/tools/windows/emsdk-git/upstream/emscripten/system/include/webgpu/webgpu.h** against **D:/Projects/NervProj/libraries/windows_clang/dawn-git-20231004/include/dawn/webgpu.h** we can see that the emscripten version is **really out of date**. => So this means I need to upgrade emscripten. For this let's try the following command first: nvp emsdk install Or actually, maybe we need to call the update method here 🤔? So adding the corresponding script so we can run: nvp emsdk update 2024/04/05 09:45:59 [nvp.nvp_compiler] INFO: MSVC root dir is: D:\Softs\VisualStudio\VS2022 2024/04/05 09:45:59 [nvp.core.build_manager] INFO: Selecting compiler msvc-14.34.31933 (in D:\Softs\VisualStudio\VS2022) 2024/04/05 09:45:59 [nvp.nvp_compiler] INFO: MSVC root dir is: D:\Softs\VisualStudio\VS2022 2024/04/05 09:45:59 [nvp.core.build_manager] INFO: Selecting compiler msvc-14.34.31933 (in D:\Softs\VisualStudio\VS2022) 2024/04/05 09:45:59 [__main__] INFO: emsdk command: ['D:\\Projects\\NervProj\\tools\\windows\\python-3.10.1\\python.exe', 'D:\\Projects\\NervProj\\tools\\windows\\emsdk-git\\emsdk.py', 'update'] You seem to have bootstrapped Emscripten SDK by cloning from GitHub. In this case, use "git pull" instead of "emsdk update" to update emsdk. (Not doing that automatically in case you have local changes) 2024/04/05 09:45:59 [nvp.nvp_object] ERROR: Subprocess terminated with error code 1 (cmd=['D:\\Projects\\NervProj\\tools\\windows\\python-3.10.1\\python.exe', 'D:\\Projects\\NervProj\\tools\\windows\\emsdk-git\\emsdk.py', 'update']) Traceback (most recent call last): File "D:\Projects\NervProj\nvp\core\emsdk_manager.py", line 168, in comp.run() 2024/04/05 09:45:59 [__main__] ERROR: emsdk command ['D:\\Projects\\NervProj\\tools\\windows\\python-3.10.1\\python.exe', 'D:\\Projects\\NervProj\\tools\\windows\\emsdk-git\\emsdk.py', 'update'] (in D:\Projects\NervProj) failed with return code 1: File "D:\Projects\NervProj\nvp\nvp_component.py", line 93, in run res = self.process_command(cmd) File "D:\Projects\NervProj\nvp\nvp_component.py", line 83, in process_command return self.process_cmd_path(self.ctx.get_command_path()) File "D:\Projects\NervProj\nvp\core\emsdk_manager.py", line 35, in process_cmd_path self.execute_emsdk(["update"]) File "D:\Projects\NervProj\nvp\core\emsdk_manager.py", line 70, in execute_emsdk self.throw("Detected emsdk command failure.") File "D:\Projects\NervProj\nvp\nvp_object.py", line 82, in throw raise NVPCheckError(fmt % args) nvp.nvp_object.NVPCheckError: Detected emsdk command failure. deque(['You seem to have bootstrapped Emscripten SDK by cloning from GitHub. In this case, use "git pull" instead of "emsdk update" to update emsdk. (Not doing that automatically in case you have local changes)', '\r\n'], maxlen=20) 2024/04/05 09:45:59 [nvp.nvp_object] ERROR: Subprocess terminated with error code 1 (cmd=['D:\\Projects\\NervProj\\.pyenvs\\default_env\\python.exe', 'D:\\Projects\\NervProj/nvp/core/emsdk_manager.py', 'update']) 2024/04/05 09:45:59 [nvp.components.runner] ERROR: Error occured in script command: cmd=['D:\\Projects\\NervProj\\.pyenvs\\default_env\\python.exe', 'D:\\Projects\\NervProj/nvp/core/emsdk_manager.py', 'update'] cwd=D:\Projects\NervProj return code=1 lastest outputs: return self.process_cmd_path(self.ctx.get_command_path()) File "D:\Projects\NervProj\nvp\core\emsdk_manager.py", line 35, in process_cmd_path self.execute_emsdk(["update"]) File "D:\Projects\NervProj\nvp\core\emsdk_manager.py", line 70, in execute_emsdk self.throw("Detected emsdk command failure.") File "D:\Projects\NervProj\nvp\nvp_object.py", line 82, in throw raise NVPCheckError(fmt % args) nvp.nvp_object.NVPCheckError: Detected emsdk command failure. deque(['You seem to have bootstrapped Emscripten SDK by cloning from GitHub. In this case, use "git pull" instead of "emsdk update" to update emsdk. (Not doing that automatically in case you have local changes)', '\r\n'], maxlen=20) => So let's try **git pull** instead But first it seems we need to ignore the filemode changes for this repo: git config core.filemode false Then we can pull: git pull And now let's try to install the latest version: nvp emsdk install 2024/04/05 09:56:10 [nvp.nvp_compiler] INFO: MSVC root dir is: D:\Softs\VisualStudio\VS2022 2024/04/05 09:56:10 [nvp.core.build_manager] INFO: Selecting compiler msvc-14.34.31933 (in D:\Softs\VisualStudio\VS2022) 2024/04/05 09:56:11 [nvp.nvp_compiler] INFO: MSVC root dir is: D:\Softs\VisualStudio\VS2022 2024/04/05 09:56:11 [nvp.core.build_manager] INFO: Selecting compiler msvc-14.34.31933 (in D:\Softs\VisualStudio\VS2022) 2024/04/05 09:56:11 [__main__] INFO: emsdk command: ['D:\\Projects\\NervProj\\tools\\windows\\python-3.10.1\\python.exe', 'D:\\Projects\\NervProj\\tools\\windows\\emsdk-git\\emsdk.py', 'install', 'latest'] Resolving SDK alias 'latest' to '3.1.56' Resolving SDK version '3.1.56' to 'sdk-releases-9d106be887796484c4aaffc9dc45f48a8810f336-64bit' Installing SDK 'sdk-releases-9d106be887796484c4aaffc9dc45f48a8810f336-64bit'.. Installing tool 'node-16.20.0-64bit'.. Downloading: D:/Projects/NervProj/tools/windows/emsdk-git/downloads/node-v16.20.0-win-x64.zip from https://storage.googleapis.com/webassembly/emscripten-releases-builds/deps/node-v16.20.0-win-x64.zip, 28623474 Bytes [----------------------------------------------------------------------------] Unpacking 'D:/Projects/NervProj/tools/windows/emsdk-git/downloads/node-v16.20.0-win-x64.zip' to 'D:/Projects/NervProj/tools/windows/emsdk-git/node/16.20.0_64bit' Done installing tool 'node-16.20.0-64bit'. Skipped installing python-3.9.2-nuget-64bit, already installed. Skipped installing java-8.152-64bit, already installed. Installing tool 'releases-9d106be887796484c4aaffc9dc45f48a8810f336-64bit'.. Downloading: D:/Projects/NervProj/tools/windows/emsdk-git/downloads/9d106be887796484c4aaffc9dc45f48a8810f336-wasm-binaries.zip from https://storage.googleapis.com/webassembly/emscripten-releases-builds/win/9d106be887796484c4aaffc9dc45f48a8810f336/wasm-binaries.zip, 461476312 Bytes [----------------------------------------------------------------------------] Unpacking 'D:/Projects/NervProj/tools/windows/emsdk-git/downloads/9d106be887796484c4aaffc9dc45f48a8810f336-wasm-binaries.zip' to 'D:/Projects/NervProj/tools/windows/emsdk-git/upstream' Done installing tool 'releases-9d106be887796484c4aaffc9dc45f48a8810f336-64bit'. Done installing SDK 'sdk-releases-9d106be887796484c4aaffc9dc45f48a8810f336-64bit'. Alright! that sounds interesting: so now we should have emscripten version **3.1.56** installed. And if we run this command again, we get: nvp emsdk install 2024/04/05 10:01:40 [nvp.nvp_compiler] INFO: MSVC root dir is: D:\Softs\VisualStudio\VS2022 2024/04/05 10:01:40 [nvp.core.build_manager] INFO: Selecting compiler msvc-14.34.31933 (in D:\Softs\VisualStudio\VS2022) 2024/04/05 10:01:40 [nvp.nvp_compiler] INFO: MSVC root dir is: D:\Softs\VisualStudio\VS2022 2024/04/05 10:01:40 [nvp.core.build_manager] INFO: Selecting compiler msvc-14.34.31933 (in D:\Softs\VisualStudio\VS2022) 2024/04/05 10:01:40 [__main__] INFO: emsdk command: ['D:\\Projects\\NervProj\\tools\\windows\\python-3.10.1\\python.exe', 'D:\\Projects\\NervProj\\tools\\windows\\emsdk-git\\emsdk.py', 'install', 'latest'] Resolving SDK alias 'latest' to '3.1.56' Resolving SDK version '3.1.56' to 'sdk-releases-9d106be887796484c4aaffc9dc45f48a8810f336-64bit' Installing SDK 'sdk-releases-9d106be887796484c4aaffc9dc45f48a8810f336-64bit'.. Skipped installing node-16.20.0-64bit, already installed. Skipped installing python-3.9.2-nuget-64bit, already installed. Skipped installing java-8.152-64bit, already installed. Skipped installing releases-9d106be887796484c4aaffc9dc45f48a8810f336-64bit, already installed. All SDK components already installed: 'sdk-releases-9d106be887796484c4aaffc9dc45f48a8810f336-64bit'. Now trying to rebuild again: nvp nvl_build -c emcc Arrggh, still getting some errors: D:/Projects/NervLand/tests/test_webgpu_wasm/main.cpp:70:24: error: unknown type name 'WGPULoggingType' 70 | void deviceLogCallback(WGPULoggingType type, const char* message, | ^ D:/Projects/NervLand/tests/test_webgpu_wasm/main.cpp:73:10: error: use of undeclared identifier 'WGPULoggingType_Verbose' 73 | case WGPULoggingType_Verbose: | ^ D:/Projects/NervLand/tests/test_webgpu_wasm/main.cpp:76:10: error: use of undeclared identifier 'WGPULoggingType_Info' 76 | case WGPULoggingType_Info: | ^ D:/Projects/NervLand/tests/test_webgpu_wasm/main.cpp:79:10: error: use of undeclared identifier 'WGPULoggingType_Warning' 79 | case WGPULoggingType_Warning: | ^ D:/Projects/NervLand/tests/test_webgpu_wasm/main.cpp:82:10: error: use of undeclared identifier 'WGPULoggingType_Error' 82 | case WGPULoggingType_Error: | ^ D:/Projects/NervLand/tests/test_webgpu_wasm/main.cpp:345:16: error: no member named 'SetDeviceLostCallback' in 'wgpu::Device' 345 | device.SetDeviceLostCallback(deviceLostCallback, nullptr); | ~~~~~~ ^ D:/Projects/NervLand/tests/test_webgpu_wasm/main.cpp:346:16: error: no member named 'SetLoggingCallback' in 'wgpu::Device' 346 | device.SetLoggingCallback(deviceLogCallback, nullptr); | ~~~~~~ ^ 7 errors generated. Checking the Webgpu headers again. **OK** The file was somewhat updated, but it still doesn't contain all the features from the Dawn version. And for instance the **WGPULoggingType** enum is not available. => Removing usage of **SetDeviceLostCallback** and **SetLoggingCallback** when building with emscripten. **Crap...** The next error we get now are on the QT wasm applications: wasm-ld: error: D:/Projects/NervProj/libraries/windows_emcc/QT6-6.4.2/plugins/platforms\libqwasm.a(qwasmclipboard.cpp.o): undefined symbol: _emval_new wasm-ld: error: D:/Projects/NervProj/libraries/windows_emcc/QT6-6.4.2/plugins/platforms\libqwasm.a(qwasmclipboard.cpp.o): undefined symbol: _emval_new wasm-ld: error: D:/Projects/NervProj/libraries/windows_emcc/QT6-6.4.2/plugins/platforms\libqwasm.a(qwasmcompositor.cpp.o): undefined symbol: _emval_call_void_method wasm-ld: error: D:/Projects/NervProj/libraries/windows_emcc/QT6-6.4.2/plugins/platforms\libqwasm.a(qwasmcompositor.cpp.o): undefined symbol: _emval_call_void_method wasm-ld: error: D:/Projects/NervProj/libraries/windows_emcc/QT6-6.4.2/plugins/platforms\libqwasm.a(qwasmclipboard.cpp.o): undefined symbol: _emval_new wasm-ld: error: D:/Projects/NervProj/libraries/windows_emcc/QT6-6.4.2/plugins/platforms\libqwasm.a(qwasmclipboard.cpp.o): undefined symbol: _emval_new wasm-ld: error: D:/Projects/NervProj/libraries/windows_emcc/QT6-6.4.2/plugins/platforms\libqwasm.a(qwasmcompositor.cpp.o): undefined symbol: _emval_call_void_method ===== Upgrading QT emscripten build ===== So... I guess I should first try to rebuild QT 4.6.2 with the latest version of emscripten ? Disabled access to old package ''QT6-6.4.2-windows-emcc.v0.7z'', and now trying: nvp build libs QT6 -c emcc/sxh> **OK**: it seems that rebuild qt 6.4.2 with emscripten went just fine, and the build process ended with those outputs: -- Up-to-date: D:/Projects/NervProj/libraries/windows_emcc/QT6-6.4.2/lib/libQt6WebViewQuick.prl -- Up-to-date: D:/Projects/NervProj/libraries/windows_emcc/QT6-6.4.2/lib/libQt6Widgets.prl -- Up-to-date: D:/Projects/NervProj/libraries/windows_emcc/QT6-6.4.2/lib/libQt6Xml.prl -- Up-to-date: D:/Projects/NervProj/libraries/windows_emcc/QT6-6.4.2/./qml/QtWebView -- Installing: D:/Projects/NervProj/libraries/windows_emcc/QT6-6.4.2/./qml/QtWebView/libqtwebviewquickplugin.prl 2024/04/08 11:05:56 [nvp.builders.qt6] INFO: Done building QT6 with emcc. 2024/04/08 11:05:56 [nvp.core.build_manager] INFO: Creating package QT6-6.4.2-windows-emcc.7z... 2024/04/08 11:06:44 [nvp.core.build_manager] INFO: Removing build folder D:\Projects\NervProj\build\libraries\QT6-6.4.2 2024/04/08 11:07:16 [nvp.core.build_manager] INFO: Done building QT6-6.4.2 (build time: 970.95 seconds) **Yeepee** 🥳! Now the build is successfull with the emcc compiler (ie. ''nvp nvl_build -c emcc'')$ ===== Trying to run test_webgpu_wasm app in browser ===== Added the main html file:
Preparing the script to run the wasm app: nvl_serve_wgpu_wasm: notify: false custom_python_env: brotli_env cmd: ${PYTHON} ${NVP_ROOT_DIR}/nvp/core/https_server.py serve --dir ${PROJECT_ROOT_DIR}/dist/webapps/test_webgpu_wasm python_path: ["${NVP_ROOT_DIR}"] windows_env_vars: FIREFOX_PATH: D:/LiberKey/Apps/Firefox/App/Firefox/firefox.exe Arrfff, we get an error message and no display: {{ public:projects:nervland:0019_wasm_cannot_create_webgpu_adapter.png }} => It seems we cannot retrieve the webgpu adapter 😭. Checking this page: https://toji.github.io/webgpu-test/ and error an error from firefox (no **navigator.gpu** object): so I don't have support for webgpu yet in that browser. So now trying to use Chrome instead: the test webpage is working there at least! I need to extend my **https_server.py** module to also accept chrome as host browser. Damn it. I will not run in Chrome as I get a "Connection refused" error. I think that's related to the SSL protocol setup somehow. So let's see... I seem to remember that maybe I could use "localhost" here 🤔? => In fact I had this note in the code: # **Note**: will also work without SSL if we serve on localhost: # url = f"http://localhost:{port}/{index_file}" So trying just that. hmmm... or... well... it seems that my process is closing instantly in fact ? ie. the command **['C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', 'http://localhost:444/test_webgpu_wasm.html']** is not correct ? **Note**: Found a full list of chrome command line options on this page: https://peter.sh/experiments/chromium-command-line-switches/ => Cannot figure out yet how to keep the chrome process running. But I just discovered that webgpu is workign in **edge** so maybe that could be a solution ? Anyway, for now, just not stopping the server automatically when testing with chrome. And this get me a bit further, but I now get another error: {{ public:projects:nervland:0020_wgpuinstanceprocessevents_not_supported.png }} Current workaround to be able to use Chrome as test browser is to close all other pages of chrome first! **Update:** Finally realized that to start a new chrome process all what we really need is the specify a custom user data dir, like: "--user-data-dir=D:/Temp/test" ===== Fixing issue with the call to wgpuInstanceProcessEvents ===== The error message we got above is: Aborted(wgpuInstanceProcessEvents is unsupported (use requestAnimationFrame via html5.h instead)) => checked this page to get an example of what to do: https://github.com/juj/wasm_webgpu/blob/main/samples/clear_screen/clear_screen.c So I need to call **emscripten_request_animation_frame_loop()** And in the end, I don't even need that: I can stick to calling **emscripten_set_main_loop()** And now I get the following display: {{ public:projects:nervland:0021_first_webgpu_wasm_rendering.png }} ===== Changing the background color dynamically ===== To ensure que are actually rendering something, let's try to dynamically change some color here. I just changed the following section in **Render()**, and with that I get a nice changing background color, yeepeee 🥳: static double curTime = 0.0; curTime += 0.1; wgpu::RenderPassColorAttachment attachment{ .view = swapChain.GetCurrentTextureView(), .loadOp = wgpu::LoadOp::Clear, .storeOp = wgpu::StoreOp::Store, .clearValue = {(std::cos(curTime) + 1.0) * 0.5, (std::sin(3.0 * curTime) + 1.0) * 0.5, (std::cos(2.0 * curTime + 3.14) + 1.0) * 0.5}}; ===== Adding support to resize the canvas ===== Using inputs from: https://webgpufundamentals.org/webgpu/lessons/webgpu-resizing-the-canvas.html I first changed the canvas display size with this html code: Next with the following kind of code we can retrieve the actual display size of our canvas: #ifdef __EMSCRIPTEN__ // CHeck the current canvas size: double cwidth = 0; double cheight = 0; const char* tgt = "canvas"; // element_size returns the **framebuffer** size (and args are ints) // emscripten_get_canvas_element_size(tgt, &cwidth, &cheight); // We need to call css_size to get the display size: emscripten_get_element_css_size(tgt, &cwidth, &cheight); int curWidth = (int)cwidth; int curHeight = (int)cheight; if (curWidth != kWidth || curHeight != kHeight) { DEBUG_MSG("Canvas resized to " << curWidth << "x" << curHeight); kWidth = curWidth; kHeight = curHeight; } #endif /* Video recording: Step 1: "Preparing minimal SDL2 test app" * run: nvp nvl_sdl_minimal Step 2: SDL2 WASM app: * run nvp nvl_serve_sdl_wasm Step 3: SDL2 Webgpu native app: * run nvp nvl_sdl_webgpu * ref: https://developer.chrome.com/docs/web-platform/webgpu/build-app Step 4: SDL2 Webgpu native+wasm app: * run nvp nvl_wgpu_wasm * run nvp nvl_serve_wgpu_wasm * ref: https://webgpufundamentals.org/webgpu/lessons/webgpu-resizing-the-canvas.html Hi everyone! And welcome in this new tutorial episode on WebGPU! Today, I will like to talk about the short journey I had myself lately trying to build a WebGPU application with emscripten. Now I'm pretty sure the first question you will ask yourself here is: "why on earth would you want to build a WebGPU app with emscripten when you can access webgpu directly from javascript ?" And well, from my perspective this can sti There were 4 major sub part on this path, so this is what we will be discussing here: */