Open xiaoiver opened 4 years ago
目前各大浏览器的预览版本对于 WebGPU API 的支持度都不错,但是在 Shader 语言的选择上存在分歧: https://github.com/gpuweb/gpuweb/wiki/Implementation-Status
因此目前 WebGPU 的 DEMO 都会注明是 Safari only 或者 Chrome/Edge only: https://github.com/gpuweb/gpuweb/wiki/Implementation-Status#samples
对于我们的 DSL -> GLSL #17 方案来说,也可以支持 WHLSL,也算是“一套代码,多处运行”。
Chrome/Edge 和 Safari 绝大部分 API 都是相同的,目前发现的不同点如下:
创建 ShaderModule 的 WebGPU API 略有不同:
const shaderModule = device.createShaderModule({ code: '...', // Shader 代码 isWHLSL: true // 表明使用的是 WHLSL }); device.createComputePipeline({ layout: pipelineLayout, computeStage: { module: shaderModule, entryPoint: "horizontal" // 可以指定 entryPoint } });
https://gpuweb.github.io/gpuweb/#gpuqueue
// safari this.device.getQueue().submit(this.commandBuffers); // chrome this.device.defaultQueue.submit(this.commandBuffers);
const context = (canvas.getContext( isSafari ? 'gpu' : 'gpupresent', ) as unknown) as GPUCanvasContext;
// safari mainTexture.createDefaultView(); // chrome mainTexture.createView();
format: isSafari ? 'depth32float-stencil8' : WebGPUConstants.TextureFormat.Depth24PlusStencil8,
isSafari ? { bindings: bindGroupLayoutEntries } : { entries: bindGroupLayoutEntries },
Safari 使用了 WHLSL: https://webkit.org/blog/8482/web-high-level-shading-language/ 中文版翻译:https://zhuanlan.zhihu.com/p/50344162
下面来看 Shader 语法层面 WHLSL 与 GLSL 的差异。
声明线程组语法和 GLSL 4.5 差不多,另外 Compute Shader 中 main 函数前需要加 compute 修饰符:
compute
[numthreads(100, 1, 1)] compute void horizontal() {}
GLSL 中线程组变量都是全局的,而在 WHLSL 中需要使用 Semantics 声明:
float3 dispatchThreadID : SV_DispatchThreadID
WSL 并不支持隐式类型转换。
考虑到与 GLSL 1.0 统一,标量也不支持 uint: https://gpuweb.github.io/WSL/#built-in-scalars
向量: vec3 -> float3
vec3
float3
GLSL 中可以通过 define 定义常量,但 WHLSL 中似乎不支持:
define
GPUDevice.createComputePipeline(): WHLSL compile error: Parse error at line 4: Unexpected token (expected ( got =)
本质上是不支持在全局作用域声明常量导致的:
https://gpuweb.github.io/WSL/#top-level-declarations
topLevelDecl ::= ";" | typedef | structDef | enumDef | funcDef
因此只能采取向每个函数中添加的方式来模拟。
问题背景
目前各大浏览器的预览版本对于 WebGPU API 的支持度都不错,但是在 Shader 语言的选择上存在分歧: https://github.com/gpuweb/gpuweb/wiki/Implementation-Status
因此目前 WebGPU 的 DEMO 都会注明是 Safari only 或者 Chrome/Edge only: https://github.com/gpuweb/gpuweb/wiki/Implementation-Status#samples
对于我们的 DSL -> GLSL #17 方案来说,也可以支持 WHLSL,也算是“一套代码,多处运行”。
WebGPU API 差异
Chrome/Edge 和 Safari 绝大部分 API 都是相同的,目前发现的不同点如下:
创建 ShaderModule
创建 ShaderModule 的 WebGPU API 略有不同:
获取队列
https://gpuweb.github.io/gpuweb/#gpuqueue
context
获取纹理视图
depthTextureDescriptor
GPUBindGroupDescriptor 键名
WHLSL 转译
Safari 使用了 WHLSL: https://webkit.org/blog/8482/web-high-level-shading-language/ 中文版翻译:https://zhuanlan.zhihu.com/p/50344162
下面来看 Shader 语法层面 WHLSL 与 GLSL 的差异。
声明线程组
声明线程组语法和 GLSL 4.5 差不多,另外 Compute Shader 中 main 函数前需要加
compute
修饰符:线程组变量
GLSL 中线程组变量都是全局的,而在 WHLSL 中需要使用 Semantics 声明:
数据类型
WSL 并不支持隐式类型转换。
考虑到与 GLSL 1.0 统一,标量也不支持 uint: https://gpuweb.github.io/WSL/#built-in-scalars
向量:
vec3
->float3
定义常量
GLSL 中可以通过
define
定义常量,但 WHLSL 中似乎不支持:本质上是不支持在全局作用域声明常量导致的:
https://gpuweb.github.io/WSL/#top-level-declarations
因此只能采取向每个函数中添加的方式来模拟。