Architecture

WebGPU 架构 - 图源自MDN

WebGPU 架构 - 图源自MDN

一个 Adapter,多个 Devices

GPUAdapter:一个特定的GPU,显然一个计算机可以有多个GPU,如独显与核显。甚至可以不是物理意义上的显卡:它只是显卡行为的抽象。

GPUDevice:逻辑设备,有独自的上下文,相互之间是隔离的,天然可并行。承担了一部分获取GPU资源的职责,在这点上是类似于 OpenGL Context 的。不过 gl.xxx 系函数是实时的,指令一经给出会立刻改变 GPU 的状态,但是 device.xxx 系操作是预先录制到命令缓冲区中的,只有在缓冲区被提交之后才会被执行。

graph TD
    A[浏览器页面 WebGPU API] --> B[navigator.gpu]

    B -->|requestAdapter()| C[GPUAdapter]
    C -->|requestDevice()| D[GPUDevice]

    %% Adapter 描述
    C --> C1[特性信息 features, limits]
    C --> C2[适配器描述 名称, 类型]

    %% Device 描述
    D --> D1[队列 GPUQueue device.queue]
    D --> D2[资源创建 GPUBuffer, GPUTexture, GPUSampler...]
    D --> D3[管线创建 GPUShaderModule, GPURenderPipeline...]
    D --> D4[绑定组 GPUBindGroup]

    style A fill:#f6f8fa,stroke:#666,stroke-width:1px
    style B fill:#e3f2fd,stroke:#1e88e5,stroke-width:1px
    style C fill:#e8f5e9,stroke:#43a047,stroke-width:1px
    style D fill:#fff3e0,stroke:#fb8c00,stroke-width:1px

大部分 GPU 资源都是从 GPUDevice 这里获取的,例如:

GPU Buffer

一个 GPUBuffer 对象表示一块连续的显存,它用来在 CPU 与 GPU 之间 共享和存储数据,其用途多样,不过需要在声明的时候指明,例如:

const buffer = device.createBuffer({
  size: 1024, // 字节数,必须是 4 的倍数
  usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
  mappedAtCreation: false
});

GPUBufferUsage 的语义不像 OpenGL 里那样直接表示绑定点,例如 GL_COPY_READ_BUFFERGL_COPY_WRITE_BUFFER 在 GL 中它们就专门用作拷贝行为的源和目标了。在 WebGPU 中它本质上是一个权限声明,只是会在对它进行相应行为的时候检查使用具有对应权限,类似于 VK 的 VkBufferUsageFlags

例如 GPUBufferUsage.COPY_DST 的意思是:允许别的资源(Buffer/Texture/CPU)往这个 Buffer 写数据。相当于在 writeBuffercopyBufferToBuffer 时相关缓冲区要具有的读写权限资格。


关于GPUBuffer 的读写操作是这样的: