WebGPU
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Write
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
      • Invitee
    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Sharing URL Help
Menu
Options
Versions and GitHub Sync Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Write
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
Invitee
Publish Note

Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

Your note will be visible on your profile and discoverable by anyone.
Your note is now live.
This note is visible on your profile and discoverable online.
Everyone on the web can find and read all notes of this public team.
See published notes
Unpublish note
Please check the box to agree to the Community Guidelines.
View profile
Engagement control
Commenting
Permission
Disabled Forbidden Owners Signed-in users Everyone
Enable
Permission
  • Forbidden
  • Owners
  • Signed-in users
  • Everyone
Suggest edit
Permission
Disabled Forbidden Owners Signed-in users Everyone
Enable
Permission
  • Forbidden
  • Owners
  • Signed-in users
Emoji Reply
Enable
Import from Dropbox Google Drive Gist Clipboard
   owned this note    owned this note      
Published Linked with GitHub
Subscribed
  • Any changes
    Be notified of any changes
  • Mention me
    Be notified of mention me
  • Unsubscribe
Subscribe
# PSA for Chromium / Dawn WebGPU API updates 2021-04-07 Chromium's WebGPU implementation and Dawn's API try to closely follow changes to the WebGPU specification. When the WebGPU IDL changes, Chromium and Dawn will try to support both the deprecated and the new version of the IDL at the same time so prototypes can be updated. In JavaScript, uses of the deprecated path will result in a console warning, while when using Dawn directly, the deprecated path will print a warning to stderr. Note that all changes to Dawn's API make it closer to [`webgpu.h`](https://github.com/webgpu-native/webgpu-headers/blob/master/webgpu.h) that we hope will allow applications to target both [Dawn](https://dawn.googlesource.com/dawn), and [wgpu](https://github.com/gfx-rs/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 2021-04-21. Previous PSAs: - [PSA for Chromium / Dawn WebGPU API updates 2020-10-19](https://hackmd.io/uH1MI9cnQBG9GGOZG20COw) - [PSA for Chromium / Dawn WebGPU API updates 2020-07-28](https://hackmd.io/szV68rOVQ56GYzPJMBko8A) - [PSA for Chromium / Dawn WebGPU API updates 2020-04-28](https://hackmd.io/Et7xlhoaThmi8dEX_s-xSw) ## WGSL improvements The WGSL specification has made a lot of progress with most of the builtin functions specified and nice ergonomics improvements (with more likely coming). The implementation in Chromium is still evolving rapidly to catch up with the specification so we aren't offering a gradual deprecation like for the WebGPU API yet. Around the last PSA, WGSL code looked like this: ```rust= type MyData = [[block]] struct { [[offset 0]] modelViewProjectionMatrix : mat4x4<f32>; [[offset 64]] positionOffset : vec4<f32>; }; [[binding 0, set 0]] var<uniform> u : MyData; [[location 0]] var<in> position : vec4<f32>;] [[builtin position]] var<out> Position : vec4<f32>; [[location 0]] var<out> FragUV : vec2<f32>; fn main() -> void { const fixedPosition : vec4<f32> = position + u.positionOffset; FragUV = position.xy * 0.5; Position = u.modelViewProjectionMatrix * fixedPosition; return; } entry_point vertex as "main" = main; ``` It now looks like this: ```rust= [[block]] struct MyData { modelViewProjectionMatrix : mat4x4<f32>; positionOffset : vec4<f32>; }; [[group(0), binding(0)]] var<uniform> u : MyData; struct Outputs { [[builtin(position)]] position : vec4<f32>; [[location(0)]] fragUV: vec2<f32>; }; [[stage(vertex)]] fn main([[location(0)]] position : vec2<f32>) -> Outputs { let fixedPosition = position + u.positionOffset; var outputs : Outputs; outputs.fragUV = position.xy * 0.5; outputs.position = u.modelViewProjectionMatrix * fixedPosition; return outputs; } ``` ## Breaking changes There are a lot of breaking changes this time, and a couple of them might require large changes (`GPUBindGroupLayoutEntry` and `GPURenderPipelineDescriptor`). The changes come both from feedback of WebGPU early adopters as well as some more focus on ergonomics from the WebGPU group. The group looked at most of the API to see if changes are needed and no breaking changes are in the pipeline. That's why we are hopeful that there will be fewer breaking changed in the future. ### `OUTPUT_ATTACHMENT` -> `RENDER_ATTACHMENT` WebGPU [PR](https://github.com/gpuweb/gpuweb/pull/1168) Contrary to Vulkan, WebGPU doesn't have "input attachment" so there is not symmetry needed with `OUTPUT_ATTACHMENT`. For clarity it is renamed to `RENDER_ATTACHMENT`. In JavaScript the following changes are needed: ```diff= const texture = device.createTexture({ dimension: '2d', size: [4, 4], format: 'rgba8unorm', - usage: GPUTextureUsage.OUTPUT_ATTACHMENT, + usage: GPUTextureUsage.RENDER_ATTACHMENT, }); ``` Likewise when using Dawn’s API, changes are needed: ```diff= wgpu::TextureDescriptor desc; desc.dimension = wgpu::TextureDimension::e2D; desc.size = {4, 4}; desc.format = wgpu::TextureFormat::RGBA8Unorm; -desc.usage = wgpu::TextureUsage::OutputAttachment; +desc.usage = wgpu::TextureUsage::RenderAttachment; wgpu::Texture texture = device.CreateTexture(&desc); ``` ### `GPUBindGroupLayoutEntry` changes Main WebGPU [PR](https://github.com/gpuweb/gpuweb/pull/1223) In order to keep the complexity of `BindGroupLayoutEntry` from exploding as more capabilities are added, it was refactored to isolate the properties needed for each type of binding. An example of the change needed in JavaScript: ```diff= const bindGroupLayout = device.createBindGroupLayout({ entries: [{ binding: 0, visibility: GPUShaderStage.VERTEX, - type: 'uniform-buffer' + buffer: {} }, { binding: 1, visibility: GPUShaderStage.FRAGMENT, - type: 'sampler' + sampler: {} }, { binding: 2, visibility: GPUShaderStage.FRAGMENT, - type: 'sampled-texture' + texture: {} }, { binding: 3, visibility: GPUShaderStage.COMPUTE, - type: 'storage-buffer' + buffer: { type: 'storage' } }, { binding: 4, visibility: GPUShaderStage.FRAGMENT, - type: 'sampled-texture' - viewDimension: 'cube' + texture: { viewDimension: 'cube' } }] }); ``` An example of the changes needed when using Dawn's API (note that at least one of `buffer.type`, `sampler.type`, `texture.sampleType` or `storageTexture.access+format` must be set): ```diff= wgpu::BindGroupLayoutEntry entries[5]; entries[0].binding = 0; entries[0].visibility = wgpu::ShaderStage::Vertex; -entries[0].bindingType = wgpu::BindingType::UniformBuffer; +entries[0].buffer.type = wgpu::BufferBindingType::Uniform; entries[1].binding = 1; entries[1].visibility = wgpu::ShaderStage::Fragment; -entries[1].bindingType = wgpu::BindingType::Sampler; +entries[1].sampler.type = wgpu::SamplerBindingType::Filtering; entries[2].binding = 2; entries[2].visibility = wgpu::ShaderStage::Fragment; -entries[2].bindingType = wgpu::BindingType::SampledTexture; +entries[2].texture.sampleType = wgpu::TextureSampleType::Float; entries[3].binding = 3; entries[3].visibility = wgpu::ShaderStage::Compute; -entries[3].bindingType = wgpu::BindingType::StorageBuffer; +entries[0].buffer.type = wgpu::BufferBindingType::Storage; entries[4].binding = 4; entries[4].visibility = wgpu::ShaderStage::Compute; -entries[4].bindingType = wgpu::BindingType::StorageTexture; -entries[4].format = wgpu::TextureFormat::RGBA8Unorm; +entries[4].storageTexture.access = wgpu::StorageTextureAccess::ReadOnly; +entries[4].storageTexture.format = wgpu::TextureFormat::RGBA8Unorm; ``` ### Render pipeline changes Main WebGPU [PR](https://github.com/gpuweb/gpuweb/pull/1352) The GPURenderPipelineDescriptor format has been re-organized for clarity. See the table below for converting deprecated GPURenderPipelineDescriptors to the new format. [Dawn Tracking Bug](https://bugs.chromium.org/p/dawn/issues/detail?id=642) | Old key | New Key | |------------------------------------------|--------------------------------------| | `vertexStage.module` | `vertex.module` | | `vertexStage.entryPoint` | `vertex.entryPoint` | | `vertexState.vertexBuffers` | `vertex.buffers` | | `vertexState.indexFormat` | `primitive.stripIndexFormat` | | `primitiveTopology` | `primitive.topology` | | `rasterizationState.frontFace` | `primitive.frontFace` | | `rasterizationState.cullMode` | `primitive.cullMode` | | `rasterizationState.depthBias` | `depthStencil.depthBias` | | `rasterizationState.depthBiasSlopeScale` | `depthStencil.depthBiasSlopeScale` | | `rasterizationState.depthBiasClamp` | `depthStencil.depthBiasClamp` | | `depthStencilState.format` | `depthStencil.format` | | `depthStencilState.depthWriteEnabled` | `depthStencil.depthWriteEnabled` | | `depthStencilState.depthCompare` | `depthStencil.depthCompare` | | `depthStencilState.stencilFront` | `depthStencil.stencilFront` | | `depthStencilState.stencilBack` | `depthStencil.stencilBack` | | `depthStencilState.stencilReadMask` | `depthStencil.stencilReadMask` | | `depthStencilState.stencilWriteMask` | `depthStencil.stencilWriteMask` | | `sampleCount` | `multisample.count` | | `sampleMask` | `multisample.mask` | | `alphaToCoverageEnabled` | `multisample.alphaToCoverageEnabled` | | `fragmentStage.module` | `fragment.module` | | `fragmentStage.entryPoint` | `fragment.entryPoint` | | `colorStates[i].format` | `fragment.targets[i].format` | | `colorStates[i].writeMask` | `fragment.targets[i].writeMask` | | `colorStates[i].colorBlend` | `fragment.targets[i].blend.color` | | `colorStates[i].alphaBlend` | `fragment.targets[i].blend.alpha` | Note that Chromium/Dawn will now validate that `fragment.targets[i].blend` is `undefined` / `nullptr` if `fragment.targets[i].format` is a non-filterable format (i.e. integer or float32). Some types part of the `GPUPipelineDescriptor` have been renamed. No changes are needed in JavaScript, but the following updates are required when using Dawn's API: | Previous type | New type | |-|-| |`wgpu::BlendDescriptor`|`wgpu::BlendComponent`| |`wgpu::StencilFaceStateDescriptor`|`wgpu::StencilFaceState`| |`wgpu::VertexAttributeDescriptor`|`wgpu::VertexAttributes`| |`wgpu::VertexBufferLayoutDescriptor`|`wgpu::VertexBufferLayout`| Also when using Dawn's API the new render pipeline descriptor is called `wgpu::RenderPipelineDescriptor2` and passed to `wgpu::Device::CreateRenderPipeline2`. Of course this is only temporary and after the deprecation period, the "2" variant will be deprecated in favor of the old names (but with the new structure). ### `GPUDevice.defaultQueue` -> `GPUDevice.queue` WebGPU [PR](https://github.com/gpuweb/gpuweb/pull/1367) Since WebGPU does not yet support multiple queues, and many applications will only ever need one queue, the `GPUDevice`'s default queue has been renamed to simply `queue` to reduce the amount of typing needed. An example of the change needed in JavaScript: ```diff= -device.defaultQueue.submit([commandEncoder.finish()]); +device.queue.submit([commandEncoder.finish()]); ``` Likewise when using Dawn’s API, changes are needed: ```diff= -wgpu::Queue queue = device.GetDefaultQueue(); +wgpu::Queue queue = device.GetQueue(); ``` ### `GPUFence` -> `GPUQueue.onSubmittedWorkDone` WebGPU [PR](https://github.com/gpuweb/gpuweb/pull/1217) Since WebGPU does not yet support multiple queues, the `GPUFence` could only be used to watch the completion of work submitted to queues. Because of this extremely limited use, they are replaced with `GPUQueue.onSubmittedWorkDone` which is a `Promise` that resolves when the queue is done processing work submitted until this point. In JavaScript the following changes are needed: ```diff= -const fence = queue.createFence(); -queue.signal(fence, 1); -await fence.onCompletion(1); +await queue.onSubmittedWorkDone(); ``` Likewise when using Dawn’s API, changes are needed: ```diff= -wgpu::Fence fence = queue.CreateFence(); -queue.Signal(fence, 1); -fence.OnCompletion(CompletionCallback, userdata); +queue.OnSubmittedWorkDone(CompletionCallback, userdata); ``` ### VertexFormat rename. WebGPU [PR](https://github.com/gpuweb/gpuweb/pull/1322) WebGPU's vertex formats were using `"char"`, `"short"` and similar terminology which wasn't used anywhere else (and isn't very descriptive if you don't know C/C++). To make it more clear it has been changed to use names like `"uint8"`, `"sint16"` and `"float32"`. See the table below for correspondances in the JavaScript API and Dawn's API. | Old Javascript | New Javascript | Old Dawn | New Dawn | |-|-|-|-| | `"uchar2"` | `"uint8x2"` | `UChar2` | `Uint8x2` | | `"uchar4"` | `"uint8x4"` | `UChar4` | `Uint8x4` | | `"char2"` | `"sint8x2"` | `Char2` | `Sint8x2` | | `"char4"` | `"sint8x4"` | `Char4` | `Sint8x4` | | `"uchar2norm"` | `"unorm8x2"` | `UChar2Norm` | `Unorm8x2` | | `"uchar4norm"` | `"unorm8x4"` | `UChar4Norm` | `Unorm8x4` | | `"char2norm"` | `"snorm8x2"` | `Char2Norm` | `Snorm8x2` | | `"char4norm"` | `"snorm8x4"` | `Char4Norm` | `Snorm8x4` | | `"ushort2"` | `"uint16x2"` | `UShort2` | `Uint16x2` | | `"ushort4"` | `"uint16x4"` | `UShort4` | `Uint16x4` | | `"short2"` | `"sint16x2"` | `Short2` | `Sint16x2` | | `"short4"` | `"sint16x4"` | `Short4` | `Sint16x4` | | `"ushort2norm"` | `"unorm16x2"` | `UShort2Norm` | `Unorm16x2` | | `"ushort4norm"` | `"unorm16x4"` | `UShort4Norm` | `Unorm16x4` | | `"short2norm"` | `"snorm16x2"` | `Short2Norm` | `Snorm16x2` | | `"short4norm"` | `"snorm16x4"` | `Short4Norm` | `Snorm16x4` | | `"half2"` | `"float16x2"` | `Half2` | `Float16x2` | | `"half4"` | `"float16x4"` | `Half4` | `Float16x4` | | `"float"` | `"float32"` | `Float` | `Float32` | | `"float2"` | `"float32x2"` | `Float2` | `Float32x2` | | `"float3"` | `"float32x3"` | `Float3` | `Float32x3` | | `"float4"` | `"float32x4"` | `Float4` | `Float32x4` | | `"uint"` | `"uint32"` | `UInt` | `Uint32` | | `"uint2"` | `"uint32x2"` | `UInt2` | `Uint32x2` | | `"uint3"` | `"uint32x3"` | `UInt3` | `Uint32x3` | | `"uint4"` | `"uint32x4"` | `UInt4` | `Uint32x4` | | `"int"` | `"sint32"` | `SInt` | `Uint32` | | `"int2"` | `"sint32x2"` | `Int2` | `Sint32x2` | | `"int3"` | `"sint32x3"` | `Int3` | `Sint32x3` | | `"int4"` | `"sint32x4"` | `Int4` | `Sint32x4` | ### CopyView type renames WebGPU [PR](https://github.com/gpuweb/gpuweb/pull/1375) To avoid confusion with the concept of `TextureView`s, the types `BufferCopyView`, `TextureCopyView`, and `ImageBitmapCopyView` have been renamed to `ImageCopyBuffer`, `ImageCopyTexture`, and `ImageCopyImageBitmap` respectively. Since these types are dictionaries this rename has no effect on JavaScript code, other than to make the documentation a bit clearer. When using Dawn's API, changes are needed: ```diff= -wgpu::BufferCopyView bufferSrc; +wgpu::ImageCopyBuffer bufferSrc; bufferSrc.buffer = buffer; bufferSrc.layout.offset = 0; bufferSrc.layout.bytesPerRow = 1024; bufferSrc.layout.rowsPerImage = wgpu::kCopyStrideUndefined; -wgpu::TextureCopyView textureDst; +wgpu::ImageCopyTexture textureDst; textureDst.texture = texture; textureDst.mipLevel = 0; textureDst.origin = {0, 0, 0}; textureDst.aspect = wgpu::TextureAspect::All; wgpu::Extent3D copySize = {1024, 1024, 1}; wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); encoder.CopyBufferToTexture(&bufferSrc, &textureDst, &copySize); ``` ### Dawn API `bytesPerRow` and `rowsPerImage` changes Previously when doing 1D copies, validation ignored the value `bytesPerRow` so it was valid to set it to 0, or another value too small. This will now cause a validation error. Instead set `bytesPerRow` to `wgpu::kCopyStrideUndefined` (the default struct member value) or a value larger than the copy's size in bytes. Likewise previously when doing 2D copies, validation ignored the value `rowsPerImage`. To avoid a validation error it must now be set to `wgpu::kCopyStrideUndefined` (the default struct member value) or a value larger than the copy's height. Finally when doing 3D copies, a 0 value for `rowsPerImage` caused it to default to the copy height. This will now produce a validation error and you should use `wgpu::kCopyStrideUndefined` instead (the default struct member value These changes are made to be closer to the Javascript API where `undefined` and 0 have different behaviors, and makes it easier to implement the Javascript API using Dawn's API. ### GPUExtent3DDict depth -> depthOrArrayLayers WebGPU [PR](https://github.com/gpuweb/gpuweb/pull/1390) Depending on context, the 3rd element of a `GPUExtent3DDict` may represent either a depth, as in the case of a 3D texture, or the number of layers, as in the case of a 2D array texture. To clarify this dual purpose, the `depth` attribute has been renamed to `depthOrArrayLayers`. An example of the change needed in JavaScript: ```diff= const texture = device.createTexture({ - size: { width: 16, height: 16, depth: 16 }, + size: { width: 16, height: 16, depthOrArrayLayers: 16 }, dimension: '3d'; format: 'rgba8unorm', usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.SAMPLED }); ``` Likewise when using Dawn’s API, changes are needed: ```diff= wgpu::TextureDescriptor descriptor; descriptor.size.width = 16; descriptor.size.height = 16; -descriptor.size.depth = 16; +descriptor.size.depthOrArrayLayers = 16; descriptor.dimension = wgpu::TextureDimension::e3D; descriptor.format = wgpu::TextureFormat::RGBA8Unorm; descriptor.usage = wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::Sampled; wgpu::Texture texture = device.CreateTexture(&descriptor); ``` Note that both Javascript and Dawn's API support shorthand declarations with unspecified values defaulting to one. In Javascript: ```js [w, h] // Same as {width: w, height: h, depthOrArrayLayers: 1} ``` Using Dawn's API: ```cpp= wgpu::Extent3D extent = {w, h}; // Is the same as wgpu::Extent3D extent; extent.width = w; extent.height = h; extent.depthOrArrayLayers = 1; ``` ### getSwapChainPreferredFormat It was determined that `getSwapChainPreferredFormat` didn't need to be asynchronous, and that it was more appropriate for it to accept a `GPUAdapter` than a `GPUDevice`. An example of the change needed in JavaScript: ```diff= const context = canvas.getContext('gpupresent'); -const swapChainFormat = await context.getSwapChainPreferredFormat(device); +const swapChainFormat = context.getSwapChainPreferredFormat(adapter); const swapChain = context.configureSwapChain({ device: device, format: swapChainFormat }); ``` The Dawn API does not currently have an equivalent call, so no changes are needed. ### `SetIndexBufferWithFormat` -> `SetIndexBuffer` In Dawn's API `SetIndexBuffer` was temporarily renamed to `SetIndexBufferWithFormat` while its signature was changed. Now that the signature is changed, `SetIndexBufferWithFormat` is deprecated in favor of `SetIndexBuffer` (with the updated signature). ### extensions->features rename WebGPU [PR](https://github.com/gpuweb/gpuweb/pull/1097) The WebGPU specification has started referring to what was previously called "Extensions" as "Features". This is because they include functionality that is present in the base spec but is not universally supported, and as such needs to be enabled explicitly (such as compressed texture formats). In service of this change the `extensions` attribute on both `GPUAdapter` and `GPUDevice` has been renamed to `features`. Also, the `extensions` key of the `GPUDeviceDescriptor` dictionary has beed renamed to `nonGuaranteedFeatures`. The name `nonGuaranteedFeatures` was chosen to emphasize that the features requested in this array are not guaranteed to be supported on all platforms and devices, and as such should be verified against the `GPUAdapter.features` list prior to requesting. As was the case prior to the rename, specifying a feature in the `nonGuaranteedFeatures` that is not supported by the `GPUAdapter` will cause `requestDevice()` to fail. An example of the change needed in JavaScript: ```diff= let deviceDescriptor = {}; -const hasBCCompression = adapter.extensions.indexOf('texture-compression-bc') != -1; +const hasBCCompression = adapter.features.indexOf('texture-compression-bc') != -1; if (hasBCCompression) { - deviceDescriptor.extensions = ['texture-compression-bc']; + deviceDescriptor.nonGuaranteedFeatures = ['texture-compression-bc']; } let device = await adapter.requestDevice(deviceDescriptor); ``` This change has not yet been made in Dawn, so no changes are required yet. ## New features and improvements Most of the improvements to Dawn / Chromium for WebGPU are happening under the hood. Recently our focus has been on massively improving the security of our implementation in preparation for a future WebGPU Origin Trial. This includes reworking large parts of our cross-process remoting architecture, vastly expanded test coverage (and fixing all the tiny issues found in the spec etc), automatic fuzzing, etc. Another huge effort is expanding usage of [Tint](https://dawn.googlesource.com/tint), our WGSL compiler. Previously it directly converted WGSL to SPIR-V and we were using [SPIRV-Cross](https://github.com/KhronosGroup/SPIRV-Cross) for translation to MSL / HLSL / GLSL and reflection. SPIRV-Cross is a mature library but is not meant to handle untrusted/malicious inputs like you can find on the Web. Tint has been expanded to the point where Dawn can use it for shader reflection and WGSL -> HLSL translation. ### OffscreenCanvas support OffscreenCanvas now supports the `"gpupresent"` context type! It can currently be used to detach the content of the canvas into and ImageBitmap with `transferToImageBitmap()`. Additional features like using WebGPU on an `OffscreenCanvas` received from `transferToOffscreenCanvas()` and `OffscreenCanvas.convertToBlob()` will follow shortly. ### Create\*PipelineAsync When a `GPURenderPipeline` or `GPUComputePipeline` is created with `GPUDevice.createRenderPipeline()` or `GPUDevice.createComputePipeline()` respectively, they return immediately. On the GPU process side it means that the pipelines have to be compiled immediately and stall the execution of further commands (because they could be used for drawing immediately). This can easily cause frame hitching and at worst compiling a lot of pipelines can trigger the "GPU watchdog" that will lose the WebGPU devices. New methods for creating pipelines asynchronously, `GPUDevice.createRenderPipelineAsync()` and `GPUDevice.createComputePipelineAsync()`, have been added to address this. These methods accept the same descriptors as their synchronous counterparts but asynchronously return the pipeline once it is fully ready to be used. Using pipelines returned from the `create*PipelineAsync()` methods can help reduce hitches on first use compared to those returned from `create*Pipeline()`. This is a similar idea to WebGL's [`KHR_parallel_shader_compile`](https://www.khronos.org/registry/webgl/extensions/KHR_parallel_shader_compile/) but more Javacript-idiomatic. Note that currently these methods aren't completely asynchronous internally but work is ongoing to improve their performance. Using the feature in Javascript is done like below: ```javascript= const computePipeline = await device.createComputePipelineAsync({ compute: { module: device.createShaderModule({ code }), entryPoint: 'main' } }); const commandEncoder = device.createCommandEncoder(); const passEncoder = commandEncoder.beginComputePass(); passEncoder.setPipeline(computePipeline); passEncoder.dispatch(1024, 1024); passEncoder.endPass(); device.queue.submit([commandEncoder.finish()]); ``` Using the feature in Dawn's API is done like below: ```cpp= wgpu::ComputePipelineDescriptor desc; // Fill `desc` as usual. device->CreateComputePipeline(&desc, [](WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline pipeline, const char* message, void* userdata) { if (status == WGPUCreatePipelineAsyncStatus::WGPUCreatePipelineAsyncStatus_Success) { // pipeline can now be used as usual. } }, nullptr // userdata passed to the callback. ); ``` ### Depth clamping `"depth-clamping"` is a new optional WebGPU feature that allows controlling the behavior of fragments with a depth that fall outside of the `[0, 1]` range. By default without this extension they are discarded, instead when setting `GPUPrimitiveState.clampDepth = true` the fragments will be kept and their depth clamped to [0, 1]. This is particularly useful when rendering shadow maps so that geometry outside of the light's frustum still occludes geometry correctly (otherwise it would just "disappear" from the shadow). Using the feature in Javascript is done like below: ```javascript= // Check that our adapter has the feature available. const adapter = await navigator.gpu.requestAdapter(); if (!adapter.features.includes("depth-clamping")) { alert("Need GPUAdapter with depth clamping support!"); return; } // Create the device, requesting the feature to be enabled. const device = await adapter.requestDevice({ nonGuaranteedFeatures: ["depth-clamping"] }); // Create a pipeline that uses the feature. const pipeline = device.createRenderPipeline({ primitive: { clampDepth: true, // ... }, // ... }); ``` Using the feature in Dawn's API, when a `wgpu::Device` with the feature has been created is done like below. Extensibility of descriptors in C++ is done with "chained structures" a bit like Vulkan: ```cpp= wgpu::RenderPipelineDescriptor desc; // Fill `desc` as usual. // Chain our depth clamping state in desc.primitive. wgpu::PrimitiveDepthClampingState depthClampState; depthClampState.clampDepth = true; desc.primitive.nextInChain = &depthClampState; wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&desc); ``` ### maxAnisotropy It is now possible to specify a `GPUSampler`'s maximum anisotropy for [anisotropic filtering](https://en.wikipedia.org/wiki/Anisotropic_filtering). For historical reasons this features is not guaranteed to be everywhere so the WebGPU specification doesn't require that values higher than 1 do something, but that should be the case everywhere in practice. Using the feature is done by adding `maxAnisotropy` to the descriptor passed to `GPUDevice.createSampler`: ```js= const sampler = device.createSampler({ magFilter: "linear", minFilter: "linear", mipmapFilter: "linear", maxAnisotropy: 4, }); ``` When using Dawn's API `maxAnisotropy` can be set in a similar way: ```cpp= wgpu::SamplerDescriptor desc; desc.magFilter = wgpu::FilterMode::Linear; desc.minFilter = wgpu::FilterMode::Linear; desc.mipmapFilter = wgpu::FilterMode::Linear; desc.maxAnisotropy = 4; wgpu::Sampler sampler = device.CreateSampler(&desc); ```

Import from clipboard

Paste your markdown or webpage here...

Advanced permission required

Your current role can only read. Ask the system administrator to acquire write and comment permission.

This team is disabled

Sorry, this team is disabled. You can't edit this note.

This note is locked

Sorry, only owner can edit this note.

Reach the limit

Sorry, you've reached the max length this note can be.
Please reduce the content or divide it to more notes, thank you!

Import from Gist

Import from Snippet

or

Export to Snippet

Are you sure?

Do you really want to delete this note?
All users will lose their connection.

Create a note from template

Create a note from template

Oops...
This template has been removed or transferred.
Upgrade
All
  • All
  • Team
No template.

Create a template

Upgrade

Delete template

Do you really want to delete this template?
Turn this template into a regular note and keep its content, versions, and comments.

This page need refresh

You have an incompatible client version.
Refresh to update.
New version available!
See releases notes here
Refresh to enjoy new features.
Your user state has changed.
Refresh to load new user state.

Sign in

Forgot password

or

By clicking below, you agree to our terms of service.

Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
Wallet ( )
Connect another wallet

New to HackMD? Sign up

Help

  • English
  • 中文
  • Français
  • Deutsch
  • 日本語
  • Español
  • Català
  • Ελληνικά
  • Português
  • italiano
  • Türkçe
  • Русский
  • Nederlands
  • hrvatski jezik
  • język polski
  • Українська
  • हिन्दी
  • svenska
  • Esperanto
  • dansk

Documents

Help & Tutorial

How to use Book mode

Slide Example

API Docs

Edit in VSCode

Install browser extension

Contacts

Feedback

Discord

Send us email

Resources

Releases

Pricing

Blog

Policy

Terms

Privacy

Cheatsheet

Syntax Example Reference
# Header Header 基本排版
- Unordered List
  • Unordered List
1. Ordered List
  1. Ordered List
- [ ] Todo List
  • Todo List
> Blockquote
Blockquote
**Bold font** Bold font
*Italics font* Italics font
~~Strikethrough~~ Strikethrough
19^th^ 19th
H~2~O H2O
++Inserted text++ Inserted text
==Marked text== Marked text
[link text](https:// "title") Link
![image alt](https:// "title") Image
`Code` Code 在筆記中貼入程式碼
```javascript
var i = 0;
```
var i = 0;
:smile: :smile: Emoji list
{%youtube youtube_id %} Externals
$L^aT_eX$ LaTeX
:::info
This is a alert area.
:::

This is a alert area.

Versions and GitHub Sync
Get Full History Access

  • Edit version name
  • Delete

revision author avatar     named on  

More Less

Note content is identical to the latest version.
Compare
    Choose a version
    No search result
    Version not found
Sign in to link this note to GitHub
Learn more
This note is not linked with GitHub
 

Feedback

Submission failed, please try again

Thanks for your support.

On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

Please give us some advice and help us improve HackMD.

 

Thanks for your feedback

Remove version name

Do you want to remove this version name and description?

Transfer ownership

Transfer to
    Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

      Link with GitHub

      Please authorize HackMD on GitHub
      • Please sign in to GitHub and install the HackMD app on your GitHub repo.
      • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
      Learn more  Sign in to GitHub

      Push the note to GitHub Push to GitHub Pull a file from GitHub

        Authorize again
       

      Choose which file to push to

      Select repo
      Refresh Authorize more repos
      Select branch
      Select file
      Select branch
      Choose version(s) to push
      • Save a new version and push
      • Choose from existing versions
      Include title and tags
      Available push count

      Pull from GitHub

       
      File from GitHub
      File from HackMD

      GitHub Link Settings

      File linked

      Linked by
      File path
      Last synced branch
      Available push count

      Danger Zone

      Unlink
      You will no longer receive notification when GitHub file changes after unlink.

      Syncing

      Push failed

      Push successfully