Skip to content

Add WebGPU backend for web platform#1458

Open
edwardxfshen wants to merge 52 commits into
mainfrom
feature/partyhuang_webgpu_backend
Open

Add WebGPU backend for web platform#1458
edwardxfshen wants to merge 52 commits into
mainfrom
feature/partyhuang_webgpu_backend

Conversation

@edwardxfshen
Copy link
Copy Markdown
Collaborator

为 Web 平台新增 WebGPU 渲染后端,与现有 WebGL 后端并行支持。

主要改动

WebGPU 后端核心实现

  • 完整的 WebGPU 渲染管线:纹理创建/上传、缓冲区管理、渲染 Pass、混合模式
  • 通过 Tint 实现 SPIR-V → WGSL 着色器转换
  • Mipmap 生成(render pass 下采样 + WGSL 着色器)
  • 视频帧上传(copyExternalImageToTexture)
  • GPU 错误回调报告

像素回读(readPixels)

  • Asyncify 方案:挂起 WASM 执行等待 buffer mapAsync 完成
  • JS 异步方案:暴露 GPUBuffer handle 供 JS 侧 mapAsync

测试基础设施

  • Web 测试支持 WebGL/WebGPU 双后端切换(CMake + npm scripts)
  • Baseline 缓存路径统一为 .cache/{backend}/,各后端 MD5 完全隔离
  • 顶层 update_baseline.sh 作为唯一入口,支持 USE_WEBGL/USE_WEBGPU
  • accept_baseline.sh 自动同步 version.json 到 Web 端缓存

工具链

  • setup_emsdk.sh 自动检测和版本校验(需要 emsdk 4.0.15)
  • Emscripten 版本兼容性检查(4.0.18 移除了 -sUSE_WEBGPU)

测试结果

WebGPU 后端通过全部测试(仅排除 FlushSemaphore,WebGPU 无信号量语义)。

Hparty and others added 25 commits May 29, 2026 17:09
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…on with 101 passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…reated textures have RENDER_ATTACHMENT usage in their descriptor, allowing them to be used as render pass color attachments.
…e copy rect dimensions do not exceed either source or destination texture bounds.
…t dimensions do not exceed render target dimensions.
…ual method to GPUBuffer base class and integrate async buffer mapping in SurfaceReadback::lockPixels() with polling.
Move emitChild(colorizerIndex) outside the if-else conditional to satisfy WGSL uniformity
requirements. When the colorizer contains texture sampling (e.g., TextureGradientColorizer),
textureSample must be in uniform control flow, not inside conditional branches.
Removed printf/console.log debug statements from SurfaceReadback, WebGPUBuffer, and WebTestRunner. Added Tint-based SPIR-V to WGSL shader conversion to replace Emscripten SPIR-V extension (which Chrome WebGPU doesn't support). Modified shader compilation pipeline to convert shaderc-generated SPIR-V to WGSL text before passing to WebGPU. Fixed test filter to properly exclude BackgroundBlurTest. Currently investigating Tint SPIR-V reader compatibility issues.
Investigated SPIR-V generation from GLSL shaders using shaderc. Identified root cause: GLSL sampler2D compiles to combined image-sampler in Vulkan SPIR-V, which WGSL/WebGPU doesn't support. Tried SPIRV-Tools optimizer split pass (failed in Emscripten) and shaderc auto-bind options (ineffective).

Current blocker: Need to separate combined image-samplers into distinct texture and sampler resources. Solutions require either: (1) modifying GLSL generation to use separate samplers, (2) finding Tint's internal transform pass, or (3) post-processing SPIR-V with tools compatible with Emscripten.

Asyncify buffer mapping and partial rendering pipeline confirmed working. Full test suite blocked by shader compilation failure.
Use global sequential counter for shader locations instead of per-buffer index.
This aligns WebGPU pipeline descriptor with WGSL shader expectations where
location indices increment globally across all vertex inputs, matching Metal
and OpenGL backends.

Result: Fixes 265 out of 292 failing tests (from 292 → 27 failures).

Commit: $(git rev-parse --short HEAD)
Pipeline layout now derives texture/sampler binding indices from
TEXTURE_BINDING_POINT_START to match WGSL shader expectations, instead of
using layoutEntries.size() which fails when UBO count != 2.

Also adds validation error capture for pipeline creation and WGSL binding
debug logging.
1. Set depthSlice = WGPU_DEPTH_SLICE_UNDEFINED for mipmap generation render
   pass color attachments (was 0, which is invalid for non-3D textures).

2. Create separate single-mip-level render views for textures with mipmaps.
   WebGPU requires render target views to have exactly 1 mip level, while
   sampling views need all levels. Added webgpuRenderView() accessor.

3. Use webgpuRenderView() for render pass color attachments and resolve
   targets instead of the default full-mipchain textureView.

Fixes 16 blank renders (from 25 down to 9) and reduces Invalid CommandBuffer
errors from 11 to 1.
WebGPU requires primitive topology at pipeline creation time, but TGFX
specifies it at draw time. Created dual pipeline variants (TriangleList and
TriangleStrip) for each render pipeline, selecting the correct one based on
the PrimitiveType parameter in draw/drawIndexed calls.

Previously all draws used TriangleList, causing TriangleStrip(4 vertices)
draws to only render half of each quad (1 triangle instead of 2).

Result: Fixes 46 additional tests (from 291 down to 245 failures).
…ersion to onMakeTexture and using copy composite in readImagePixels.
…ses synchronous getBufferSubData for readback.
@edwardxfshen edwardxfshen force-pushed the feature/partyhuang_webgpu_backend branch from 9a9b89c to 9569a7d Compare May 29, 2026 09:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants