Try   HackMD

PSA for Chromium / Dawn WebGPU API updates 2020-04-28

Chromium's WebGPU implementation and Dawn's API try to closely follow changes to the WebGPU specification. When the WebGPU IDL changes, as best as possible Chromium and Dawn will support both the "old" and the "new" version of the IDL at the same time so prototypes can be updated. In JS, uses of the "old" path will result in a console warning, while when using Dawn directly, the "old" path will print a warning to stderr.

Note that all changes to Dawn's API make it closer to webgpu.h that we hope will allow applications to target both Dawn, and wgpu in native before being compiled in WASM. Emscripten will also be updated from the "old" to the "new" API but won't have the smooth transition since developers control which version of emscripten they use.

A couple weeks after an update like this one, the "old" version will be removed. This means that the "old" version of the items below will start being removed from Chromium/Dawn starting on 2020-05-12.

Breaking changes

GPUDevice .createQueue() -> .defaultQueue

WebGPU PR

No changes for JS: .createQueue() was already removed from Chromium so this is only a Dawn API change.

-wgpu::Queue queue = device.CreateQueue();
+wgpu::Queue queue = device.GetDefaultQueue();

BindGroup[Layout]Binding -> BindGroup[Layout]Entry

WebGPU PR

No changes for JS.

The name of structure has been updated in Dawn's API. The only change needed is replacing references to wgpu::BindGroupLayoutBinding to wgpu::BindGroupLayoutEntry and references to wgpu::BindGroupBinding to wgpu::BindGroupEntry.

BindGroup[Layout]Descriptor .bindings -> .entries

WebGPU PR

In JS the dictionary member name needs to be updated:

 const layout = device.createBindGroupLayout({
-    bindings: [ ... ],
+    entries: [ ... ],
 });
 const bindgroup = device.createBindGroup({
     layout,
-    bindings: [ ... ],
+    entries: [ ... ],
 });

Likewise when using Dawn's API changes are needed:

 wgpu::BindGroupLayoutDescriptor layoutDesc;
-layoutDesc.bindingCount = 1;
-layoutDesc.bindings = &myLayoutEntry;
+layoutDesc.entryCount = 1;
+layoutDesc.entries = &myLayoutEntry;
 wgpu::BindGroupLayout layout = device.CreateBindGroupLayout(&layoutDesc);

 wgpu::BindGroupDescriptor bgDesc;
 bgDesc.layout = layout;
-bgDesc.bindingCount = 1;
-bgDesc.bindings = &myBgEntry;
+bgDesc.entryCount = 1;
+bgDesc.entries = &myBgEntry;
 wgpu::BindGroup bg = device.CreateBindGroup(&bgDesc);

BindGroupLayoutEntry.textureDimension -> viewDimension

WebGPU PR

In JS the dictionary member name needs to be updated:

 const layout = device.createBindGroupLayout({
     entries: [{
         binding: 0,
         type: "sampled-texture",
-        textureDimension: "3d",
+        viewDimension: "3d",
     }]
 });

Likewise when using Dawn's API changes are needed:

 wgpu::BindGroupEntry entry;
 entry.binding = 0;
 entry.type = wgpu::BindingType::SampledTexture;
-entry.textureDimension = wgpu::TextureDimension::e3D;
+entry.viewDimension = wgpu::TextureDimension::e3D;

Renames of rowPitch and imageHeight

WebGPU PR

They are now called bytesPerRow and rowsPerImage respectively. In JS the member of dictionaries needs to be updated.

 commandEncoder.copyBufferToTexture({
     buffer: textureDataBuffer,
-    rowPitch: myRowPitch,
-    imageHeight: myImageHeight,
+    bytesPerRow: myBytesPerRow,
+    rowsPerImage: myRowsPerImage,
 }, ...);

Likewise in Dawn's API uses of wgpu::BufferCopyView must be updated:

 wgpu::BufferCopyView bufferView;
 bufferView.buffer = buffer;
-bufferView.rowPitch = myRowPitch;
-bufferView.imageHeight = myImageHeight;
+bufferView.bytesPerRow = myBytesPerRow;
+bufferView.rowsPerImage = myRowsPerImage;

 encoder.CopyBufferToTexture(&bufferView, ...);

Usages of sub-descriptors for wgpu::ShaderModuleDescriptor

WebGPU PR

Dawn is looking to support both SPIR-V and WGSL at the same time. This will be done by using the "chained structure" extension mechanism. Ingestion of SPIR-V will be moved to a chained structure.

-wgpu::ShaderModuleDescriptor desc;
-desc.codeSize = spirv.size();
-desc.code = spirv.data();

+wgpu::ShaderModuleSPIRVDescriptor chainedDesc;
+chainedDesc.codeSize = spirv.size();
+chainedDesc.code = spirv.data();

+wgpu::ShaderModuleDescriptor desc;
+desc.nextInChain = &chainedDesc;

 wgpu::ShaderModule module = device.CreateShaderModule(&desc);

Less breaking changes

Draw defaults

WebGPU PR

Defaults were added to the draw commands so that in JS pass.draw(3, 1, 0, 0) can be written pass.draw(3) and pass.drawIndexed(3, 1, 0, 0, 0) can be written pass.drawIndexed(3). Similar defaults are added to Dawn's C++ API.

Comparison samplers

WebGPU PR

GPUSamplerDescriptor.compare is now optional and must be set if and only if the sampler is a comparison sampler meant to be used with the new "comparison-sampler" binding type. Likewise in Dawn's C++ API where wgpu::SamplerDescriptor::compare default to wgpu::CompareFunction::Undefined which represents the member not being set.

Optional size for GPURenderEncoderBase.set[Vertex|Index]Buffer

WebGPU PR

Calls to GPURenderEncoderBase.setVertexBuffer and GPURenderEncoderBase.setIndexBuffer now take an additional and optional size argument. If left to the default value of 0, size represents the entire length of the buffer after offset. Similar defaults are added to Dawn's C++ API.

Addition of storage textures

WebGPU PR

This adds a couple new GPUBindingType and GPUBindGroupLayoutEntry.storageTextureFormat. No changes needed to update your code.

Upcoming IDL changes

GPUBuffer.setSubData removal

We're waiting for discussions around writeBuffer to finish in the group before removing GPUBuffer.setSubData in Chromium and wgpu::Buffer::SetSubData in Dawn.

GPUShaderModuleDescriptor.code being WGSL instead of SPIRV

WebGPU PR

Chromium's WGSL implementation isn't complete enough to be useful to write applications so GPUShaderModuleDescriptor.code still only allows Uint32Array containing SPIRV.

Merging GPUTextureDescriptor.arrayLayerCount in size.depth

WebGPU PR

This isn't implemented in Dawn yet. In JS texture creation needs to be updated (but there will be another PSA before the "old" path is removed).

 const texture = device.createTexture({
     format: "rgba8-unorm",
     usage: GPUTextureUsage.OUTPUT_ATTACHMENT,
-    size: {width: 16, height:16, depth: 1},
-    arrayLayerCount: 4,
+    size: {width: 16, height:16, depth: 4},
 });

Query APIs

WebGPU PR

They aren't implemented in Chromium/Dawn yet.

Object label getters and setters

They aren't implemented in Chromium/Dawn yet.