---
# System prepended metadata

title: WebGPU
tags: [WebGPU]

---

# WebGPU

{%hackmd @RintarouTW/About %}

<iframe width="560" height="315" src="https://www.youtube.com/embed/EhWvqaRDz5s?start=1" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

https://medium.com/@AlainGalvan/raw-webgpu-58522e638b17

- Spec: https://gpuweb.github.io/gpuweb/
- WGSL: https://gpuweb.github.io/gpuweb/wgsl.html (Rust based)
- SPIR: https://www.khronos.org/spir/ (Satndard Portable Intermediate Representation)
- Samples: https://austineng.github.io/webgpu-samples/
- [Chrome: Get Started with GPU Compute on the Web](https://developers.google.com/web/updates/2019/08/get-started-with-gpu-compute-on-the-web)
    - `chrome://flags/#enable-unsafe-webgpu`
    - `Safari > Develop > Experimental Features > WebGPU`
    
## Model

```graphviz
digraph {
graph [bgcolor=transparent];
node[fontcolor="#888888";color="#888888"];
edge [color="#888800"];
    rankdir=LR
    "Adapter" -> "Device"
    subgraph {
    rank=same
    "Swap Chain", "Command Queue", "Command Encoder", "Pipelines", "GPUBuffer", "Bind Group", "Render Bundle Encoder", "GPUSampler", "GPUTexture", "Shader Module", "Query Set"
    }
    "Device" -> "Swap Chain", "Command Queue", "Command Encoder", "Pipelines", "GPUBuffer", "Bind Group", "Render Bundle Encoder", "GPUSampler", "GPUTexture", "Shader Module", "Query Set"
    "GPUTexture" -> "Texture View"
    "GPUBuffer" -> "Vertex Buffer", "Index Buffer","Uniform Buffer" -> "Render Pass"
    "GPUBuffer" -> "Storage Buffer" -> "Compute Pass"
    "Pipelines" -> "Render Pipeline", "Compute Pipeline"
    "Swap Chain" -> "Surface", "Texture(View)"
    "Compute Pipeline" -> "Compute Pass"
    "Render Pipeline" -> "Render Pass"
    "Command Encoder" -> "Render Pass","Compute Pass" -> "Command Buffer" -> "Command Queue"
    "Command Queue" -> "Submit Command Buffer", "Write Texture Buffer", "Copy ImageBitmap to Texture"
}
```
## GPU

- requestAdapter()

request different adapter for different preference(ex: low-power)

## Adapter

- requestDevice()


## Swap Chain

https://en.wikipedia.org/wiki/Swap_chain

A swap chain is a series of `virtual framebuffers` utilized by the graphics card and graphics API for frame rate stabilization and several other functions. 
- screen buffer
- back buffer(s)

The swap chain usually exists in graphics memory, but it can exist in system memory as well. The non-utilization of a swap chain may result in stuttering rendering, but its existence and utilization are required by many graphics APIs. 

A swap chain with two buffers is a double buffer.

- Different `present modes` to prevent tearing on different devices.
- frame buffer pixel formats
- frame buffer size may change if window resizing.

## Buffers

### Create GPU Buffer
- device.`createBuffer()`
- `buffer.getMappedRange()` : get array buffer for CPU(js) from GPU.
- `buffer.unmap()` : return the control back to GPU.
```javascript!
// Get a GPU buffer in a mapped state and an arrayBuffer for writing.
const gpuBuffer = device.createBuffer({
  mappedAtCreation: true,
  size: 4,
  usage: GPUBufferUsage.MAP_WRITE
});
const arrayBuffer = gpuBuffer.getMappedRange();

// Write bytes to buffer.
new Uint8Array(arrayBuffer).set([0, 1, 2, 3]);

// unmap the buffer from CPU, so GPU can use it now.
gpuBuffer.unmap();
```

### Buffer Mapping

Get the mapping of the exist GPU buffer via `buffer.mapAsyc(mode, offset, size)`.

An application can request to map a GPUBuffer so that they can access its content via ArrayBuffers that represent part of the GPUBuffer's allocations. Mapping a GPUBuffer is requested asynchronously with mapAsync() so that the user agent can ensure the GPU finished using the GPUBuffer before the application can access its content. Once the GPUBuffer is mapped the application can synchronously ask for access to ranges of its content with getMappedRange. A mapped GPUBuffer cannot be used by the GPU and must be unmapped using unmap before work using it can be submitted to the Queue timeline.

## Babylon.js

[babylon.js WebGPU](https://doc.babylonjs.com/advanced_topics/webGPU)

<iframe width="560" height="315" src="https://www.youtube.com/embed/A2FxeEl4nWw?start=1" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

###### tags: `WebGPU`