Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
99a1a9e
SGL compiling with emscripten
j8asic Feb 6, 2026
f3a9e44
Slangpy emscripten cmake preset
j8asic Feb 6, 2026
53a884f
Merge branch 'main' of https://github.com/shader-slang/slangpy
j8asic Feb 6, 2026
cb11acd
Compute and render example working via WASM/WebGPU
j8asic Feb 6, 2026
9bdf3ee
fmt and imgui settings for emscripten
j8asic Feb 24, 2026
fc0b85d
feat: conditionally enable CUDA features
j8asic Feb 24, 2026
1ea8d8d
Trying to finalize cmake stuff for emscripten
j8asic Feb 24, 2026
7573001
Connecting wasm build process to wasm based slang-rhi
j8asic Feb 24, 2026
0705058
Merge branch 'main' into main
j8asic Feb 24, 2026
9b004ab
Emscripten flags to enable asyncify and enable memory growth
j8asic Feb 25, 2026
4e4d005
noentry em flag for sgl
j8asic Feb 25, 2026
e9ce692
Avoid emscripten warnings by compiling sgl as static lib
j8asic Feb 25, 2026
e125b4f
Merge branch 'main' into main
j8asic Feb 26, 2026
bae20ac
Update Emscripten slang-rhi repository to use upstream version
j8asic Apr 17, 2026
0bc8d28
Merge branch 'main' into main
j8asic Apr 17, 2026
eb0fbea
Merge branch 'main' into main
j8asic Apr 22, 2026
44b52da
Merge branch 'main' into main
j8asic Apr 28, 2026
e80296f
Merge branch 'shader-slang:main' into main
j8asic May 4, 2026
cc9b1db
Fix preprocessor conditionals for Emscripten compatibility
j8asic May 5, 2026
3d4973f
Remove Emscripten-specific slang-rhi FetchContent configuration
j8asic May 5, 2026
6aa6061
Expose function user attributes in reflection (#983)
ccummingsNV May 14, 2026
22685a4
wip plan
ccummingsNV May 14, 2026
427569f
Test format acknowledgement (#985)
ccummingsNV May 14, 2026
edf0b32
Start on native conversion
ccummingsNV May 14, 2026
a81469d
Start portin reflection types
ccummingsNV May 14, 2026
fc3b167
docs + cleanup
ccummingsNV May 14, 2026
c7d2546
Add function + field extraction
ccummingsNV May 14, 2026
61b8386
native lookup system
ccummingsNV May 14, 2026
4c5da3a
Merge branch 'main' of https://github.com/shader-slang/slangpy into d…
ccummingsNV May 14, 2026
9d16e49
Update slang-rhi (#987)
skallweitNV May 15, 2026
95deede
Update slang-rhi (#988)
skallweitNV May 15, 2026
7389235
Merge branch 'shader-slang:main' into main
j8asic May 16, 2026
3792e47
Improving Emscripten compatibility based on PR review
j8asic May 16, 2026
7e48fb9
Clang warning handling for C++20 compatibility in testing header
j8asic May 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,19 @@ jobs:
with:
python-version: "3.9"

- name: Install pre-commit
run: python -m pip install pre-commit

- name: Record pre-commit version
run: pre-commit --version | tee pre-commit-version.txt

- name: Run pre-commit
id: pre_commit
uses: pre-commit/action@v3.0.0
run: pre-commit run --all-files

- name: Upload pre-commit version
if: always()
uses: actions/upload-artifact@v4
with:
extra_args: --all-files
name: pre-commit-version
path: pre-commit-version.txt
33 changes: 33 additions & 0 deletions .github/workflows/pre-commit-comment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
types: [completed]

permissions:
actions: read
contents: read
issues: write
pull-requests: write
Expand All @@ -16,10 +17,21 @@ jobs:
runs-on: ubuntu-latest

steps:
- name: Download pre-commit version
if: github.event.workflow_run.conclusion == 'failure'
uses: actions/download-artifact@v4
continue-on-error: true
with:
name: pre-commit-version
path: pre-commit-version
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}

- name: Update pre-commit help comment
uses: actions/github-script@v8
with:
script: |
const fs = require("fs");
let pullRequests = context.payload.workflow_run.pull_requests || [];
if (pullRequests.length === 0) {
const associated = await github.rest.repos.listPullRequestsAssociatedWithCommit({
Expand Down Expand Up @@ -58,12 +70,33 @@ jobs:
return;
}

let preCommitVersion = "unavailable";
try {
preCommitVersion = fs
.readFileSync("pre-commit-version/pre-commit-version.txt", "utf8")
.trim();
} catch (error) {
core.warning(`Failed to read pre-commit version artifact: ${error.message}`);
}

const body = [
marker,
"Pre-commit failed for this PR.",
"",
`Workflow run: ${context.payload.workflow_run.html_url}`,
"",
"GitHub used:",
"",
"```text",
preCommitVersion,
"```",
"",
"You can check your local version with:",
"",
"```bash",
"pre-commit --version",
"```",
"",
"You can fix this locally by running:",
"",
"```bash",
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
build/
build.em/
external/vcpkg
external/slang/
tools/download
Expand Down
13 changes: 12 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(SGL_MACOS TRUE)
set(SGL_HAS_D3D12 OFF)
set(SGL_HAS_VULKAN ON)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Emscripten")
set(SGL_PLATFORM "Emscripten")
set(SGL_EMSCRIPTEN TRUE)
set(SGL_HAS_D3D12 OFF)
set(SGL_HAS_VULKAN OFF)
else()
message(FATAL_ERROR "Unsupported platform!")
endif()
Expand All @@ -123,7 +128,13 @@ endif()
# CUDA
# -----------------------------------------------------------------------------

if(NOT SGL_USE_DYNAMIC_CUDA)
if(SGL_EMSCRIPTEN OR SGL_MACOS)
set(SGL_HAS_CUDA OFF)
else()
set(SGL_HAS_CUDA ON)
endif()

if(SGL_HAS_CUDA AND NOT SGL_USE_DYNAMIC_CUDA)
find_package(CUDAToolkit REQUIRED)
endif()

Expand Down
25 changes: 25 additions & 0 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,19 @@
"VCPKG_TARGET_TRIPLET": "arm64-osx",
"CMAKE_APPLE_SILICON_PROCESSOR": "arm64"
}
},
{
"name": "emscripten",
"description": "Emscripten-based WebAssembly build",
"generator": "Ninja Multi-Config",
"binaryDir": "${sourceDir}/build.em",
"toolchainFile": "$env{EMSCRIPTEN_ROOT}/cmake/Modules/Platform/Emscripten.cmake",
"cacheVariables": {
"SGL_BUILD_TESTS": "OFF",
"SGL_BUILD_PYTHON": "OFF",
"CMAKE_CXX_FLAGS_INIT": "-fwasm-exceptions -Os -include cstdlib",
"CMAKE_EXE_LINKER_FLAGS": "-sASSERTIONS --export=__cpp_exception"
}
}
],
"buildPresets": [
Expand Down Expand Up @@ -325,6 +338,18 @@
"displayName": "Debug",
"configurePreset": "macos-arm64-clang",
"configuration": "Debug"
},
{
"name": "emscripten-release",
"displayName": "Release",
"configurePreset": "emscripten",
"configuration": "Release"
},
{
"name": "emscripten-debug",
"displayName": "Debug",
"configurePreset": "emscripten",
"configuration": "Debug"
}
],
"testPresets": [
Expand Down
5 changes: 5 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@ add_subdirectory(raytracing)
add_subdirectory(render_pipeline)
add_subdirectory(simple_compute)
add_subdirectory(tinybc)

# WASM example for Emscripten
if(SGL_EMSCRIPTEN)
add_subdirectory(wasm)
endif()
130 changes: 92 additions & 38 deletions examples/render_pipeline/render_pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "sgl/sgl.h"
#include "sgl/core/platform.h"
#include "sgl/core/window.h"
#include "sgl/device/device.h"
#include "sgl/device/shader.h"
#include "sgl/device/command.h"
Expand All @@ -11,50 +12,71 @@
#include "sgl/device/agility_sdk.h"
#include "sgl/device/input_layout.h"
#include "sgl/device/pipeline.h"
#include "sgl/utils/tev.h"
#include "sgl/device/surface.h"
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif

SGL_EXPORT_AGILITY_SDK

#ifdef __EMSCRIPTEN__
static const std::filesystem::path EXAMPLE_DIR(".");
#else
static const std::filesystem::path EXAMPLE_DIR(SGL_EXAMPLE_DIR);
#endif

using namespace sgl;

int main()
{
sgl::static_init();

struct App {
ref<Window> window;
ref<Device> device;
ref<Surface> surface;
ref<Buffer> vertex_buffer;
ref<Buffer> index_buffer;
ref<InputLayout> input_layout;
ref<ShaderProgram> program;
ref<RenderPipeline> pipeline;

App()
{
ref<Device> device = Device::create({
window = Window::create({
.width = 1024,
.height = 1024,
.title = "render_pipeline",
});

device = Device::create({
.enable_debug_layers = true,
.compiler_options = {.include_paths = {EXAMPLE_DIR}},
});

surface = device->create_surface(window);
surface->configure({
.format = surface->info().preferred_format,
.usage = TextureUsage::render_target,
.width = window->width(),
.height = window->height(),
.vsync = true,
});

std::vector<float2> vertices{{-1.f, -1.f}, {1.f, -1.f}, {0.f, 1.f}};
std::vector<uint32_t> indices{0, 1, 2};

ref<Buffer> vertex_buffer = device->create_buffer({
.usage = BufferUsage::shader_resource,
vertex_buffer = device->create_buffer({
.usage = BufferUsage::vertex_buffer,
.label = "vertex_buffer",
.data = vertices.data(),
.data_size = vertices.size() * sizeof(float2),
});

ref<Buffer> index_buffer = device->create_buffer({
.usage = BufferUsage::shader_resource,
index_buffer = device->create_buffer({
.usage = BufferUsage::index_buffer,
.label = "index_buffer",
.data = indices.data(),
.data_size = indices.size() * sizeof(uint32_t),
});

ref<Texture> render_texture = device->create_texture({
.format = Format::rgba32_float,
.width = 1024,
.height = 1024,
.usage = TextureUsage::render_target,
.label = "render_texture",
});

ref<InputLayout> input_layout = device->create_input_layout({
input_layout = device->create_input_layout({
.input_elements{
{
.semantic_name = "POSITION",
Expand All @@ -67,32 +89,64 @@ int main()
},
});

ref<ShaderProgram> program = device->load_program("render_pipeline.slang", {"vertex_main", "fragment_main"});
ref<RenderPipeline> pipeline = device->create_render_pipeline({
program = device->load_program("render_pipeline.slang", {"vertex_main", "fragment_main"});
pipeline = device->create_render_pipeline({
.program = program,
.input_layout = input_layout,
.targets = {{.format = Format::rgba32_float}},
.targets = {{.format = surface->info().preferred_format}},
});
}

ref<CommandEncoder> command_encoder = device->create_command_encoder();
{
auto pass_encoder = command_encoder->begin_render_pass({
.color_attachments = {{.view = render_texture->create_view({})}},
});
pass_encoder->bind_pipeline(pipeline);
pass_encoder->set_render_state({
.viewports = {{Viewport::from_size(float(render_texture->width()), float(render_texture->height()))}},
.scissor_rects = {{ScissorRect::from_size(render_texture->width(), render_texture->height())}},
.vertex_buffers = {vertex_buffer},
});
pass_encoder->draw({.vertex_count = 3});
pass_encoder->end();
void main_loop()
{
window->process_events();

if (!surface->config())
return;

ref<Texture> surface_texture = surface->acquire_next_image();
if (surface_texture) {
ref<CommandEncoder> command_encoder = device->create_command_encoder();
{
auto pass_encoder = command_encoder->begin_render_pass({
.color_attachments = {{.view = surface_texture->create_view({}), .load_op = LoadOp::clear}},
});
pass_encoder->bind_pipeline(pipeline);
pass_encoder->set_render_state({
.viewports
= {{Viewport::from_size(float(surface_texture->width()), float(surface_texture->height()))}},
.scissor_rects = {{ScissorRect::from_size(surface_texture->width(), surface_texture->height())}},
.vertex_buffers = {vertex_buffer},
});
pass_encoder->draw({.vertex_count = 3});
pass_encoder->end();
}
device->submit_command_buffer(command_encoder->finish());

surface->present();
}
device->submit_command_buffer(command_encoder->finish());
}

~App()
{
if (device)
device->close();
}
};

tev::show(render_texture, "render_pipeline");
int main()
{
sgl::static_init();

device->close();
{
App app;

while (!app.window->should_close()) {
app.main_loop();
#ifdef __EMSCRIPTEN__
emscripten_sleep(0);
#endif
}
}

sgl::static_shutdown();
Expand Down
Loading