Skip to content

Commit

Permalink
supoprt for emscripten build
Browse files Browse the repository at this point in the history
  • Loading branch information
caiiiycuk committed Feb 3, 2022
1 parent b6bd1c9 commit f7d731e
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 34 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 13 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,26 @@ default = []
#metal-auto-capture = ["gfx-backend-metal/auto-capture"]
#vulkan-portability = ["wgc/gfx-backend-vulkan"]

[dependencies.wgc]
[target.'cfg(not(target_os = "emscripten"))'.dependencies.wgc]
package = "wgpu-core"
git = "https://github.com/gfx-rs/wgpu"
rev = "63dfd98"
git = "https://github.com/caiiiycuk/wgpu"
rev = "2544f3c"
# path = "../wgpu/wgpu-core"
#version = "0.11"
features = ["raw-window-handle", "trace"]

[target.'cfg(target_os = "emscripten")'.dependencies.wgc]
package = "wgpu-core"
git = "https://github.com/caiiiycuk/wgpu"
rev = "2544f3c"
# path = "../wgpu/wgpu-core"
#version = "0.11"
features = ["raw-window-handle", "emscripten"]

[dependencies.wgt]
package = "wgpu-types"
git = "https://github.com/gfx-rs/wgpu"
rev = "63dfd98"
git = "https://github.com/caiiiycuk/wgpu"
rev = "2544f3c"
# path = "../wgpu/wgpu-types"
#version = "0.11"

Expand Down
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ lib-native: Cargo.lock Cargo.toml Makefile $(WILDCARD_SOURCE)
lib-native-release: Cargo.lock Cargo.toml Makefile $(WILDCARD_SOURCE)
cargo build --release $(EXTRA_BUILD_ARGS)

lib-native-emscripten: Cargo.lock Cargo.toml Makefile $(WILDCARD_SOURCE)
EMCC_CFLAGS="-Oz -g -s ERROR_ON_UNDEFINED_SYMBOLS=0 --no-entry -s ASSERTIONS=0" cargo build --target wasm32-unknown-emscripten --release $(EXTRA_BUILD_ARGS)

example-compute: lib-native examples/compute/main.c
cd examples/compute && $(CREATE_BUILD_DIR) && cd build && cmake -DCMAKE_BUILD_TYPE=Debug .. $(GENERATOR_PLATFORM) && cmake --build .

Expand All @@ -113,6 +116,9 @@ example-triangle: lib-native examples/triangle/main.c
run-example-triangle: example-triangle
cd examples/triangle && "$(OUTPUT_DIR)/triangle"

example-triangle-emscripten: lib-native-emscripten examples/triangle/main.c
cd examples/triangle && $(CREATE_BUILD_DIR) && cd build && emcmake cmake -DCMAKE_BUILD_TYPE=Debug .. && cmake --build .

build-helper:
cargo build -p helper

Expand Down
32 changes: 23 additions & 9 deletions examples/triangle/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ set(TARGET_NAME triangle)

add_executable(triangle main.c ../framework.c)

if(MSVC)
if(EMSCRIPTEN)
add_definitions(-DWGPU_TARGET=WGPU_TARGET_LINUX_EMSCRIPTEN)
elseif(MSVC)
add_definitions(-DWGPU_TARGET=WGPU_TARGET_WINDOWS)
target_compile_options(${TARGET_NAME} PRIVATE /W4)
set(OS_LIBRARIES "userenv" "ws2_32" "Dwmapi" "dbghelp" "d3dcompiler" "D3D12" "D3D11" "DXGI" "setupapi" "Bcrypt")
Expand All @@ -23,15 +25,27 @@ endif(USE_WAYLAND)
target_compile_options(${TARGET_NAME} PRIVATE -Wall -Wextra -pedantic)
endif(MSVC)

find_package(glfw3 3.3 REQUIRED
HINTS "$ENV{GLFW3_INSTALL_DIR}"
)
if(EMSCRIPTEN)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} \
-Oz -g -s USE_GLFW=3")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} \
-Oz -g -s FULL_ES2=1 \
-s ERROR_ON_UNDEFINED_SYMBOLS=0 \
-s MIN_WEBGL_VERSION=2 \
--preload-file \"${CMAKE_CURRENT_SOURCE_DIR}/shader.wgsl@shader.wgsl\"")
set(WGPU_LIBRARY "wgpu_native")
set_target_properties(${TARGET_NAME} PROPERTIES SUFFIX .html)
target_link_directories(${TARGET_NAME} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../../target/wasm32-unknown-emscripten/release")
else(EMSCRIPTEN)
find_package(glfw3 3.3 REQUIRED
HINTS "$ENV{GLFW3_INSTALL_DIR}"
)
find_library(WGPU_LIBRARY wgpu_native
HINTS "${CMAKE_CURRENT_SOURCE_DIR}/../../target/debug"
)
target_include_directories(${TARGET_NAME} PUBLIC $ENV{GLFW3_INCLUDE_DIR})
endif(EMSCRIPTEN)

find_library(WGPU_LIBRARY wgpu_native
HINTS "${CMAKE_CURRENT_SOURCE_DIR}/../../target/debug"
)

target_include_directories(${TARGET_NAME} PUBLIC $ENV{GLFW3_INCLUDE_DIR})
target_include_directories(${TARGET_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../ffi)
target_include_directories(${TARGET_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../)

Expand Down
23 changes: 21 additions & 2 deletions examples/triangle/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
#elif WGPU_TARGET == WGPU_TARGET_WINDOWS
#define GLFW_EXPOSE_NATIVE_WIN32
#endif
#if WGPU_TARGET != WGPU_TARGET_LINUX_EMSCRIPTEN
#include <GLFW/glfw3native.h>
#endif

static void handle_device_lost(WGPUDeviceLostReason reason, char const * message, void * userdata)
{
Expand All @@ -45,7 +47,11 @@ int main() {
return 1;
}

#if WGPU_TARGET == WGPU_TARGET_LINUX_EMSCRIPTEN
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
#else
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
#endif
GLFWwindow *window = glfwCreateWindow(640, 480, "wgpu with glfw", NULL, NULL);

if (!window) {
Expand All @@ -54,8 +60,16 @@ int main() {
}

WGPUSurface surface;

#if WGPU_TARGET == WGPU_TARGET_MACOS
#if WGPU_TARGET == WGPU_TARGET_LINUX_EMSCRIPTEN
{
surface = wgpuInstanceCreateSurface(
NULL,
&(WGPUSurfaceDescriptor){
.label = NULL,
.nextInChain = NULL,
});
}
#elif WGPU_TARGET == WGPU_TARGET_MACOS
{
id metal_layer = NULL;
NSWindow *ns_window = glfwGetCocoaWindow(window);
Expand Down Expand Up @@ -332,6 +346,11 @@ int main() {
wgpuSwapChainPresent(swapChain);

glfwPollEvents();

#if WGPU_TARGET == WGPU_TARGET_LINUX_EMSCRIPTEN
// you must use emscripten_set_main_loop or asyncify
return 0;
#endif
}

glfwDestroyWindow(window);
Expand Down
2 changes: 1 addition & 1 deletion ffi/webgpu-headers
Submodule webgpu-headers updated 1 files
+30 −2 webgpu.h
29 changes: 15 additions & 14 deletions src/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,12 @@ pub fn map_device_descriptor<'a>(
}

pub fn map_limits(limits: native::WGPULimits) -> wgt::Limits {
#[cfg(target_os = "emscripten")]
let mut wgt_limits = wgt::Limits::downlevel_webgl2_defaults();

#[cfg(not(target_os = "emscripten"))]
let mut wgt_limits = wgt::Limits::default();

if limits.maxTextureDimension1D != 0 {
wgt_limits.max_texture_dimension_1d = limits.maxTextureDimension1D;
}
Expand Down Expand Up @@ -272,46 +277,42 @@ pub fn map_limits(limits: native::WGPULimits) -> wgt::Limits {
if limits.maxStorageBufferBindingSize != 0 {
wgt_limits.max_storage_buffer_binding_size = limits.maxStorageBufferBindingSize as u32;
}
/* not yet available in wgpu-core
if limits.minUniformBufferOffsetAlignment != 0 {
wgt_limits.yyyy = limits.minUniformBufferOffsetAlignment;
wgt_limits.min_uniform_buffer_offset_alignment = limits.minUniformBufferOffsetAlignment;
}
if limits.minStorageBufferOffsetAlignment != 0 {
wgt_limits.yyyy = limits.minStorageBufferOffsetAlignment;
wgt_limits.min_storage_buffer_offset_alignment = limits.minStorageBufferOffsetAlignment;
}
*/
if limits.maxVertexBuffers != 0 {
wgt_limits.max_vertex_buffers = limits.maxVertexBuffers;
}
if limits.maxVertexAttributes != 0 {
wgt_limits.max_vertex_attributes = limits.maxVertexAttributes;
}
/* not yet available in wgpu-core
if limits.maxVertexBufferArrayStride != 0 {
wgt_limits.yyyy = limits.maxVertexBufferArrayStride;
wgt_limits.max_vertex_buffer_array_stride = limits.maxVertexBufferArrayStride;
}
if limits.maxInterStageShaderComponents != 0 {
wgt_limits.yyyy = limits.maxInterStageShaderComponents;
wgt_limits.max_inter_stage_shader_components = limits.maxInterStageShaderComponents;
}
if limits.maxComputeWorkgroupStorageSize != 0 {
wgt_limits.yyyy = limits.maxComputeWorkgroupStorageSize;
wgt_limits.max_compute_workgroup_storage_size = limits.maxComputeWorkgroupStorageSize;
}
if limits.maxComputeInvocationsPerWorkgroup != 0 {
wgt_limits.yyyy = limits.maxComputeInvocationsPerWorkgroup;
wgt_limits.max_compute_invocations_per_workgroup = limits.maxComputeInvocationsPerWorkgroup;
}
if limits.maxComputeWorkgroupSizeX != 0 {
wgt_limits.yyyy = limits.maxComputeWorkgroupSizeX;
wgt_limits.max_compute_workgroup_size_x = limits.maxComputeWorkgroupSizeX;
}
if limits.maxComputeWorkgroupSizeY != 0 {
wgt_limits.yyyy = limits.maxComputeWorkgroupSizeY;
wgt_limits.max_compute_workgroup_size_y = limits.maxComputeWorkgroupSizeY;
}
if limits.maxComputeWorkgroupSizeZ != 0 {
wgt_limits.yyyy = limits.maxComputeWorkgroupSizeZ;
wgt_limits.max_compute_workgroup_size_z = limits.maxComputeWorkgroupSizeZ;
}
if limits.maxComputeWorkgroupsPerDimension != 0 {
wgt_limits.yyyy = limits.maxComputeWorkgroupsPerDimension;
wgt_limits.max_compute_workgroups_per_dimension = limits.maxComputeWorkgroupsPerDimension;
}
*/
return wgt_limits;
}

Expand Down
12 changes: 12 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,16 @@ pub mod native {

type Global = wgc::hub::Global<wgc::hub::IdentityManagerFactory>;

#[cfg(not(target_os = "emscripten"))]
lazy_static::lazy_static! {
static ref GLOBAL: Arc<Global> = Arc::new(Global::new("wgpu", wgc::hub::IdentityManagerFactory, wgt::Backends::PRIMARY));
}

#[cfg(target_os = "emscripten")]
lazy_static::lazy_static! {
static ref GLOBAL: Arc<Global> = Arc::new(Global::new("wgpu", wgc::hub::IdentityManagerFactory, wgt::Backends::GL));
}

pub type Label<'a> = Option<Cow<'a, str>>;

struct OwnedLabel(Option<String>);
Expand Down Expand Up @@ -276,6 +282,12 @@ unsafe fn map_surface(
return wgpu_create_surface(raw_window_handle::RawWindowHandle::AndroidNdk(handle));
}

#[cfg(target_os = "emscripten")]
return wgpu_create_surface(raw_window_handle::RawWindowHandle::Web(
raw_window_handle::WebHandle::empty(),
));

#[cfg(not(target_os = "emscripten"))]
panic!("Error: Unsupported Surface");
}

Expand Down

0 comments on commit f7d731e

Please sign in to comment.