diff --git a/engine/gfx/webgpu/src/gfx_webgpu.cpp b/engine/gfx/webgpu/src/gfx_webgpu.cpp index bc861f2..0cf5d17 100755 --- a/engine/gfx/webgpu/src/gfx_webgpu.cpp +++ b/engine/gfx/webgpu/src/gfx_webgpu.cpp @@ -1,6 +1,12 @@ #include "gfx_webgpu.hpp" +#include + bool GFXWebGPU::initialize(const GFXCreateInfo& createInfo) { + auto device = emscripten_webgpu_get_device(); + + prism::log("Initialized WebGPU!"); + return true; } diff --git a/platforms/web/CMakeLists.txt b/platforms/web/CMakeLists.txt index 3568971..d8e713d 100644 --- a/platforms/web/CMakeLists.txt +++ b/platforms/web/CMakeLists.txt @@ -1,6 +1,7 @@ include(../../cmake/AddPlatformExecutable.cmake) add_platform( + SRC ${CMAKE_CURRENT_SOURCE_DIR}/glue.cpp MAIN_FILE main.cpp.in LINK_LIBRARIES @@ -15,6 +16,9 @@ function(add_platform_commands target) PROPERTIES SUFFIX ".html" ) + target_link_options(${target} + PRIVATE "SHELL:-s USE_WEBGPU=1" + ) set(DUMMY_NAME ${target}-CopyShaders) diff --git a/platforms/web/glue.cpp b/platforms/web/glue.cpp new file mode 100644 index 0000000..4d67fc1 --- /dev/null +++ b/platforms/web/glue.cpp @@ -0,0 +1,80 @@ +// taken from https://github.com/kainino0x/webgpu-cross-platform-demo :-) thank you! +#include +#include + +/** + * \def KEEP_IN_MODULE + * Marks a function to be kept in the \c Module and exposed to script. An + * alternative to Emscripten's \c bind or \c cwrap. + * \code + * // C++ + * KEEP_IN_MODULE int getValue() { + * return 42; + * } + * // JavaScript + * console.log(Module._getValue()); + * \endcode + */ +#ifndef KEEP_IN_MODULE +#define KEEP_IN_MODULE extern "C" __attribute__((used, visibility("default"))) +#endif + +/** + * Entry point for the 'real' application. + * + * \param[in] argc count of program arguments in argv + * \param[in] argv program arguments (excluding the application) + */ +extern "C" int __main__(int /*argc*/, char* /*argv*/[]); + +//****************************************************************************/ + +namespace impl { +/** + * JavaScript async calls that need to finish before calling \c main(). + */ + EM_JS(void, glue_preint, (), { + var entry = __glue_main_; + if (entry) { + /* + * None of the WebGPU properties appear to survive Closure, including + * Emscripten's own `preinitializedWebGPUDevice` (which from looking at + *`library_html5` is probably designed to be inited in script before + * loading the Wasm). + */ + if (navigator["gpu"]) { + navigator["gpu"]["requestAdapter"]().then(function (adapter) { + adapter["requestDevice"]().then( function (device) { + Module["preinitializedWebGPUDevice"] = device; + entry(); + }); + }, function () { + console.error("No WebGPU adapter; not starting"); + }); + } else { + console.error("No support for WebGPU; not starting"); + } + } else { + console.error("Entry point not found; unable to start"); + } + }); +} + +//****************************************************************************/ + +/** + * Redirector to call \c __main__() (exposed to Emscripten's \c Module). + * + * \todo pass URL query string for args + */ +KEEP_IN_MODULE void _glue_main_() { + __main__(0, nullptr); +} + +/** + * Entry point. Workaround for Emscripten needing an \c async start. + */ +int main(int /*argc*/, char* /*argv*/[]) { + impl::glue_preint(); + return 0; +} \ No newline at end of file diff --git a/platforms/web/main.cpp.in b/platforms/web/main.cpp.in index 25bf403..e478027 100644 --- a/platforms/web/main.cpp.in +++ b/platforms/web/main.cpp.in @@ -23,7 +23,7 @@ EM_BOOL draw(double time, void *userData) { return true; } -int main(int argc, char* argv[]) { +extern "C" int __main__(int argc, char* argv[]) { engine = new prism::engine(argc, argv); app = new @APP_CLASS@(); @@ -39,7 +39,7 @@ int main(int argc, char* argv[]) { app_main(engine); - engine->add_window(nullptr, (void*)1, {100, 100}}); + engine->add_window((void*)1, (void*)1, {100, 100}); app->initialize_render(); emscripten_request_animation_frame_loop(draw, nullptr);