Fundamental Objects
WebGPU is relatively more complex compared to WebGL. To develop with WebGPU, you need to create and configure many JavaScript objects. The ultimate goal of these objects can be summarized as sending commands to the GPU.
More precisely, it’s about submitting command buffers to the queue bound to the client GPU. This requires at least 6 steps:
- Get the browser’s
Navigator
, where you can check if the browser supports WebGPU; - If the browser supports WebGPU, you can obtain a
GPUAdapter
from theNavigator
; - Use the
GPUAdapter
to get aGPUDevice
; - Use the
GPUDevice
to create aGPUCommandEncoder
; - Configure the encoder to record commands to the buffer;
- Submit the command buffer to the
GPUQueue
bound to theGPUDevice
.
If you want to render graphics, additional steps are needed to bind the GPUDevice
to a Canvas
. This requires three additional steps:
- Get the
Canvas
element in HTML; - Get the
GPUCanvasContext
from theCanvas
element; - Configure the
GPUCanvasContext
using theGPUDevice
and canvas format.
Once the GPUDevice
is bound to the Canvas
, you can render graphics to the Canvas
by calling methods on the GPUDevice
.
Navigator
Section titled “Navigator”Modern browsers all have a Navigator
object that contains the features supported by the current browser. For example, clipboard
represents the ability to read the system clipboard.
if (!navigator.gpu) { throw new Error("WebGPU not supported.");}
The gpu
provides two important methods:
requestAdapter()
: Returns aPromise
object for aGPUAdapter
;getPreferredCanvasFormat()
: Returns a string representing the best canvas format for the browser, e.g.,bgra8unorm
GPUAdapter
Section titled “GPUAdapter”Browser support for WebGPU doesn’t mean the user’s hardware supports WebGPU rendering and computation. Therefore, you need to use requestAdapter
to obtain a GPUAdapter
.
Note that requestAdapter
returns a Promise
placeholder object. Each Promise
has three states:
pending
: The operation hasn’t completed yetfulfillment
: The operation is completerejection
: An error occurred
Typically, you would use await
to wait for the operation to complete:
const adapter = await navigator.gpu.requestAdapter();if (!adapter) { throw new Error("No appropriate GPUAdapter found.");}
After obtaining the GPUAdapter
, you can get information about the user’s rendering and computing capabilities through info
.
const info = adapter.info;
if (info) { console.log("Vendor: " + info.vendor); console.log("Architecture: " + info.architecture); console.log("Device: " + info.device); console.log("Description: " + info.description);}
For complete supported properties, refer to: GPUAdapterInfo
There are also two useful parameters, features
and limits
.
features
: Get the features supported by the GPU;limits
: Get the maximum/minimum operation parameters that the GPU can handle;
The most important function of GPUAdapter
is to provide GPUDevice
, which also returns a Promise
object:
const device = await adapter.requestDevice();
GPUDevice
Section titled “GPUDevice”GPUDevice
serves as a logical connection to the client GPU and plays a central role in WebGPU development.
GPUCommandEncoder
Section titled “GPUCommandEncoder”The most important method of GPUDevice
is createCommandEncoder
. This object is used to create and store commands to be sent to the GPU.
const encoder = device.createCommandEncoder();
The following three methods are the most important:
beginRenderPass
: Encode a render pass for graphics renderingbeginComputePass
: Encode a compute pass for computational tasksfinish
: Return a command buffer containing the encoder’s commands
GPUQueue
Section titled “GPUQueue”GPUDevice
has an important property called queue
, which provides a GPUQueue
. To execute GPU operations, you need to call methods on the GPUQueue
.
writeBuffer
: Update data in buffer objectswriteTexture
: Update data in texture objectssubmit
: Notify the GPU to execute one or more commands
The submit
method is particularly important because it tells the GPU what tasks to execute (graphics rendering or general computation). After calling the submit
method, you can monitor the queue through onSubmittedWorkDone
.
Canvas
Section titled “Canvas”To display rendered graphics on a web page, you need to use a <canvas>
element. This requires three steps:
- Create a canvas element in HTML;
- Get the canvas element through JavaScript, for example: using selectors;
- Configure through the canvas context.
<!-- Create canvas element in HTML --><canvas id="mycanvas" width="400" height="200"></canvas>
Getting HTML elements can generally be done through selectors or ID:
// Tag selectorconst canvas = document.querySelector("canvas");// ID selectorconst canvas = document.getElementById("mycanvas");
Then you can give this canvas
a webgpu
context:
const context = canvas.getContext("webgpu");
The final step is to complete the configuration:
const canvasFormat = navigator.gpu.getPreferredCanvasFormat();
context.configure({ device: device, format: canvasFormat,});
Fundamental Objects
Core Code
Section titled “Core Code”if (!navigator.gpu) { throw new Error("WebGPU not supported.");}
const adapter = await navigator.gpu.requestAdapter();if (!adapter) { throw new Error("No appropriate GPUAdapter found.");}
const info = adapter.info;
if (info) { console.log("Vendor: " + info.vendor); console.log("Architecture: " + info.architecture); console.log("Device: " + info.device); console.log("Description: " + info.description);}
const device = await adapter.requestDevice();// const encoder = device.createCommandEncoder();
const canvas = document.getElementById(id);if (!canvas) { throw new Error(`No canvas element found: ${id}`);}
const context = canvas.getContext("webgpu");if (!context) { throw new Error("Failed to get WebGPU context.");}
const canvasFormat = navigator.gpu.getPreferredCanvasFormat();context.configure({ device: device, format: canvasFormat,});