Skip to content
This repository has been archived by the owner on Dec 16, 2023. It is now read-only.

Wasm experiment #63

Merged
merged 93 commits into from
Dec 14, 2019
Merged

Wasm experiment #63

merged 93 commits into from
Dec 14, 2019

Conversation

pthom
Copy link
Contributor

@pthom pthom commented Dec 13, 2019

Hi Sam,


Remark

  • This is the same message as the in the last PR, but inside a dedeicated PR, so that we can keep track of the history
  • Do not merge this PR now, it is not ready. However you can test it on your side, and may be help me on the problem I describe below.

If you like you can look at the current status here:
https://github.com/pthom/BabylonCpp/tree/wasm_experiment

I do not have time to detail all the changes now (there are a lot).

In this branch, you can do a build for emscripten like this:

cmake .. -DCMAKE_BUILD_TYPE=Debug -DBABYLON_WASM=ON \
-DCMAKE_TOOLCHAIN_FILE=/YOUR/PATH/TO/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake \
-GNinja -DUSE_CCACHE=ON

I added support for SDL2 instead of GLFW (since emscripten supports SDL natively and it is the recommended method by imgui for emscripten).

Status:

  • All the code compiles correctly to emscripten
  • Demos using SDL work (see target imgui_runner_demo_emscripten)
  • Demos using SDL and imgui Docking work (see target imgui_runner_babylon_demo_emscripten)
  • When running a 3D scene however there is a runtime error during shader compilation

How to test this:

  • Install emscripten's emsdk
  • Build with
cmake .. -DCMAKE_BUILD_TYPE=Debug -DBABYLON_WASM=ON \
-DCMAKE_TOOLCHAIN_FILE=/YOUR/PATH/TO/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake \
-GNinja -DUSE_CCACHE=ON
  • Run a web server:
cd src/
python3 -m http.server

(replace "cmake-build-emscripten" by your build folder name)

  • The following demos will work: imgui_runner_babylon_demo_emscripten.htmland imgui_runner_demo_emscripten.html (they do not initialize a 3D scene)
  • The following demo will not work: BabylonRunStandalone.html

How to debug:

There is a source map, so in theory you should be able to add breakpoints. However in practice, this is fragile.
Based on my experience, two adices:

  • Always test the same code on a desktop version before trying wiht emscripten
  • Debugging by "printf / std:::cout" is time-consuming, but works: you will see that I (temporarily) added lots of debug messages

Analysis of the issue

Below is an extract of the stack trace. Can you help me on this?

I suspect an issue with OpenGL and/or glsl version. Here are some possible location where some adaptations could (should ?) be made for emscripten, as far as OpenGL and Glsl are concerned:

  • src/BabylonCpp/include/babylon/shaders/shadersinclude/glsl_version_3.h
  • RunnerEmscripten::Select_Gl_Version()
  • RunnerEmscripten::GlslVersion()

Stack trace that I have when running BabylonRunStandalone.html:

exception thrown: TypeError: Argument 2 of WebGL2RenderingContext.attachShader is not an object.,_glAttachShader@http://localhost:8000/cmake-build-emscripten/build/bin/BabylonRunStandalone.js:10441:13
BABYLON::GL::GLRenderingContext::attachShader(BABYLON::GL::IGLProgram*, BABYLON::GL::IGLShader*)@http://localhost:8000/cmake-build-emscripten/build/bin/BabylonRunStandalone.wasm:wasm-function[1111]:0x3c6ed
BABYLON::Engine::_createShaderProgram(std::__2::shared_ptr<BABYLON::GL::IGLShader> const&, std::__2::shared_ptr<BABYLON::GL::IGLShader> const&, BABYLON::GL::IGLRenderingContext*, std::__2::vector<std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> >, std::__2::allocator<std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > > > const&)@http://localhost:8000/cmake-build-emscripten/build/bin/BabylonRunStandalone.wasm:wasm-function[52801]:0xb723cf
BABYLON::Engine::createShaderProgram(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&, std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&, std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&, BABYLON::GL::IGLRenderingContext*, std::__2::vector<std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> >, std::__2::allocator<std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > > > const&)@http://localhost:8000/cmake-build-emscripten/build/bin/BabylonRunStandalone.wasm:wasm-function[52814]:0xb74166
BABYLON::Effect::_prepareEffect()@http://localhost:8000/cmake-build-emscripten/build/bin/BabylonRunStandalone.wasm:wasm-function[70904]:0xe27f98
BABYLON::Effect::Effect(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&, BABYLON::EffectCreationOptions&, BABYLON::Engine*)::$_0::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const@http://localhost:8000/cmake-build-emscripten/build/bin/BabylonRunStandalone.wasm:wasm-function[71459]:0xe3f2e7
void std::__2::__invoke_void_return_wrapper<void>::__call<BABYLON::Effect::Effect(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&, BABYLON::EffectCreationOptions&, BABYLON::Engine*)::$_0::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)&, std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&>(BABYLON::Effect::Effect(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&, BABYLON::EffectCreationOptions&, BABYLON::Engine*)::$_0::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)&, std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)@http://localhost:8000/cmake-build-emscripten/build/bin/BabylonRunStandalone.wasm:wasm-function[71455]:0xe3edae
std::__2::__function::__alloc_func<BABYLON::Effect::Effect(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&, BABYLON::EffectCreationOptions&, BABYLON::Engine*)::$_0::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&), std::__2::allocator<BABYLON::Effect::Effect(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&, BABYLON::EffectCreationOptions&, BABYLON::Engine*)::$_0::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)>, void (std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)>::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)@http://localhost:8000/cmake-build-emscripten/build/bin/BabylonRunStandalone.wasm:wasm-function[71453]:0xe3ed13
void std::__2::__function::__policy_invoker<void (std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)>::__call_impl<std::__2::__function::__alloc_func<BABYLON::Effect::Effect(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&, BABYLON::EffectCreationOptions&, BABYLON::Engine*)::$_0::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&), std::__2::allocator<BABYLON::Effect::Effect(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&, BABYLON::EffectCreationOptions&, BABYLON::Engine*)::$_0::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)>, void (std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)> >(std::__2::__function::__policy_storage const*, std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)@http://localhost:8000/cmake-build-emscripten/build/bin/BabylonRunStandalone.wasm:wasm-function[71441]:0xe3e8ec
std::__2::__function::__policy_func<void (std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)>::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const@http://localhost:8000/cmake-build-emscripten/build/bin/BabylonRunStandalone.wasm:wasm-function[27336]:0x80e46e
std::__2::function<void (std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)>::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const@http://localhost:8000/cmake-build-emscripten/build/bin/BabylonRunStandalone.wasm:wasm-function[27292]:0x80bb28
BABYLON::Effect::_processShaderConversion(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&, bool, std::__2::function<void (std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)> const&)@http://localhost:8000/cmake-build-emscripten/build/bin/BabylonRunStandalone.wasm:wasm-function[70855]:0xe1f070
BABYLON::Effect::Effect(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&, BABYLON::EffectCreationOptions&, BABYLON::Engine*)::$_0::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const::'lambda'(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&)::operator()(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char> > const&) const@http://localhost:8000/cmake-build-emscripten/build/bin/BabylonRunStandalone.wasm:wasm-function[71424]:0xe3e0bb

Concerning the rest of the changes, I'll make a more complete explanation later.
In summary:

  • Simplification of the CMakeListsss (lots of simplifications but there is still room for improvement):
    • use glob_recurse
    • Test are not run during build (this was causing issue during the build: how to solve an issue that causes the build to fail?)
  • Add SDL2
  • Add new project imgui_runner and imgui_runner_babylon: they can handle glfw, sdl and emscripten

Cheers!

pthom added 30 commits December 12, 2019 15:03
(Note: did not correct code duplication in cmake files, but this should be done later)
* find_package(OpenGL REQUIRED) and ${OPENGL_LIBRARIES} cannot be used
* glfw is disabled
* BABYLON_BUILD_PLAYGROUND disabld
* libraries are static for emscripten (not shared)
…* part of the build

Otherwise you canot debug tests, because the build fails!
@samdauwe samdauwe changed the base branch from master to wasm_experiment December 14, 2019 08:39
@samdauwe samdauwe merged commit 4a42f74 into samdauwe:wasm_experiment Dec 14, 2019
@pthom pthom mentioned this pull request Dec 18, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants