WebGPU API
æéå¯ç¨
æ¤ç¹æ§ä¸å±äºåºçº¿ï¼å 为å®å°æªå¨ä¸»æµæµè§å¨ä¸å¾å°æ¯æã
Want more browser support for this feature? Tell us why.
å®éªæ§: è¿æ¯ä¸é¡¹å®éªæ§ææ¯
å¨å°å
¶ç¨äºç产ä¹åï¼è¯·ä»ç»æ£æ¥æµè§å¨å
¼å®¹æ§è¡¨æ ¼ã
WebGPU API 使 web å¼å人åè½å¤ä½¿ç¨åºå±ç³»ç»ç GPUï¼å¾å½¢å¤çå¨ï¼è¿è¡é«æ§è½è®¡ç®å¹¶ç»å¶å¯å¨æµè§å¨ä¸æ¸²æç夿å¾å½¢ã
WebGPU æ¯ WebGL çç»§ä»»è ï¼ä¸ºç°ä»£ GPU æä¾æ´å¥½çå ¼å®¹ãæ¯ææ´éç¨ç GPU 计ç®ãæ´å¿«çæä½ä»¥åè½å¤è®¿é®å°æ´é«çº§ç GPU ç¹æ§ã
æ¦å¿µå使ç¨
å¾å
¬å¹³å°è¯´ï¼WebGL å¨ 2011 å¹´å·¦å³é¦æ¬¡åºç°åï¼å¨å¾å½¢åè½æ¹é¢å½»åºæ¹åäº webãWebGL æ¯ OpenGL ES 2.0 å¾å½¢åºç JavaScript 端å£ï¼å
许 web 页é¢ç´æ¥å°æ¸²æè®¡ç®ä¼ éç»è®¾å¤ç GPUï¼è¿ä¼ä»¥é常é«çé度å¤çï¼å¹¶å¨ <canvas> å
渲æç»æã
WebGL åç¨äºç¼å WebGL çè²å¨ä»£ç ç GLSL è¯è¨åå夿ï¼å æ¤å建äºå 个 WebGL åºï¼ä»¥ä¾¿æ´è½»æ¾å°ç¼å WebGL åºç¨ç¨åºï¼æµè¡ç示ä¾å æ¬ Three.jsãBabylon.js 以å PlayCanvasãå¼åè å¯ä»¥ä½¿ç¨è¿äºå·¥å ·å»æå»ºèº«ä¸´å ¶å¢çåºäº web 3D çæ¸¸æãé³ä¹è§é¢ãå¹è®åå»ºæ¨¡å·¥å ·ãVR å AR ä½éªçã
ç¶èï¼WebGL æä¸äºéè¦è§£å³çåºæ¬é®é¢ï¼
- èª WebGL åå¸ä»¥æ¥ï¼åºç°äºæ°ä¸ä»£çåç GPU APIââæå欢è¿çæ¯å¾®è½¯ç Direct3D 12ãè¹æç Metal 以åç§çº³æ¯ç»ç»ç Vulkanââå®ä»¬æä¾äºå¤§éæ°ç¹æ§ã并没æä»»ä½è®¡å对 OpenGLï¼ä»¥å WebGLï¼è¿è¡æ´å¤æ´æ°ï¼å æ¤å®å°ä¸ä¼è·å¾ä»»æè¿äºæ°çç¹æ§ãç¶èï¼WebGPU å°å¨æªæ¥æ·»å è¿äºæ°ç¹æ§ã
- WebGL å®å ¨åºäºç»å¶å¾å½¢å¹¶å°å®ä»¬æ¸²æå°ç»å¸çç¨ä¾ãå®å¹¶ä¸è½å¾å¥½å°å¤çéç¨ GPUï¼GPGPUï¼ç计ç®ãGPGPU 计ç®å¯¹äºå¾å¤ä¸åçç¨ä¾æ¾å¾è¶æ¥è¶éè¦ï¼ä¾å¦é£äºåºäºæºå¨å¦ä¹ çæ¨¡åã
- æ 论æ¯å¨åæ¶æ¸²æç对象æ¹é¢ï¼è¿æ¯æ°æ¸²æç¹æ§çä½¿ç¨æ¹é¢ï¼3D å¾å½¢åºç¨ç¨åºçéæ±é½å¨éæ¸åé«ã
WebGPU è§£å³äºè¿äºé®é¢ï¼å ¶æä¾äºä¸ç°ä»£ GPU API å ¼å®¹çæ´æ°çéç¨æ¶æï¼å®ä¼è®©ä½ æå°æ´å 䏿»ã宿¯æå¾å½¢æ¸²æï¼åæ¶å¯¹ GPGPU 计ç®ä¹æä¸æµçæ¯æãå¨ CPU 端渲æåä¸ªå¯¹è±¡çææ¬è¦ä½å¾å¤ï¼å¹¶ä¸å®æ¯æç°ä»£åç GPU 渲æç¹æ§ï¼ä¾å¦ï¼åºäºè®¡ç®çç²ååç¨äºåæå¤ççæ»¤éï¼å¦é¢è²ææãéååæ¯æ·±æ¨¡æãæ¤å¤ï¼å®ä¹å¯ä»¥ç´æ¥å¨ GPU ä¸å¤ç诸å¦åé¤å骨骼å¨ç»æ¨¡åçè费大é计ç®èµæºçä»»å¡ã
éç¨æ¨¡å
è®¾å¤ GPU åè¿è¡ WebGPU API ç web æµè§å¨ä¹é´æå¤ä¸ªæ½è±¡å±ãçè§£è¿äºï¼å¯¹ä½ å¼å§å¦ä¹ WebGPU 徿ç¨ï¼

-
ç©ç设å¤å ·æ GPUã大夿°è®¾å¤ä» æä¸ä¸ª GPUï¼ä½æäºè®¾å¤ä¸æ¢ä¸ä¸ªãå¯ä»¥ä½¿ç¨çä¸å GPU ç±»åï¼
- éæ¾ï¼Integrated GPUï¼ï¼ä¸ CPU ä½äºåä¸ä¸»æ¿ä¸ï¼å¹¶å ±äº«å ¶å åã
- ç¬æ¾ï¼Discrete GPUï¼ï¼ä½äºåç¬çæ¾å¡ä¸ï¼ä¸ CPU åå¼ã
- 软件 GPUï¼Software "GPU"ï¼ï¼å¨ CPU ä¸å®ç°ã
夿³¨ï¼ä¸å¾åè®¾ä» æä¸ä¸ª CPU 设å¤ã
-
æ¬æº GPU API æ¯æä½ç³»ç»ï¼ä¾å¦ macOS ä¸ç Metalï¼çä¸é¨åï¼æ¯ä¸ç§å è®¸æ¬æºåºç¨ç¨åºä½¿ç¨ GPU åè½çç¼ç¨æ¥å£ãAPI æä»¤éè¿é©±å¨ç¨åºåéå° GPUï¼å¹¶æ¥æ¶ååºï¼ãä¸ä¸ªç³»ç»å¯ä»¥æå¤ä¸ªæ¬æºæä½ç³»ç» API å驱å¨ç¨åºå¯ç¨äºä¸ GPU éä¿¡ï¼å°½ç®¡ä¸è¿°å¾ç¤ºä» å设ä¸ä¸ªè®¾å¤ä» æä¸ä¸ªæ¬æº API/驱å¨å¨ç¨åºã
-
æµè§å¨ç WebGPU å®ç°äºéè¿æ¬æº GPU API ä¸ GPU è¿è¡éä¿¡ãWebGPU 设é å¨å¨ä½ ç代ç ä¸å®é ä¸è¡¨ç¤ºå°æ¯ä¸ä¸ªç©ç GPU åå¯å©ç¨ç驱å¨ç¨åºã
-
é»è¾è®¾å¤æ¯ä¸ç§æ½è±¡ï¼éè¿å®ï¼å个 web åºç¨ç¨åºå¯ä»¥ä»¥ååºçæ¹å¼è®¿é® GPU åè½ãé»è¾è®¾å¤éè¦æä¾å¤ç¨çåè½ãå 为ä¸ä¸ªç©ç设å¤ç GPU å¯è½åæ¶è¢«å¤ä¸ªåºç¨ç¨åºåè¿ç¨ä½¿ç¨ï¼å æ¬è®¸å¤ web å¼ç¨ç¨åºã为äºå®å ¨åé»è¾ä¸çåå ï¼æ¯ä¸ª web åºç¨ç¨åºé½éè¦è½å¤é离å°è®¿é® WebGPUã
è·å设å¤çè®¿é®æé
é»è¾è®¾å¤ï¼éè¿ GPUDevice 对象å®ä¾è¡¨ç¤ºï¼æ¯ web åºç¨ç¨åºè®¿é®ææ WebGPU åè½çåºç¡ã访é®è®¾å¤çè¿ç¨å¦ä¸ï¼
Navigator.gpu屿§ï¼æWorkerNavigator.gpuï¼å¦æä½ å¨ worker å é¨ä½¿ç¨ WebGPU åè½ï¼ä¸ºå½åä¸ä¸æè¿åGPU对象ã- éè¿
GPU.requestAdapter()æ¹æ³è®¿é®éé å¨ãè¯¥æ¹æ³æ¥åä¸ä¸ªå¯éç设置对象ï¼å ¶å è®¸ä½ è¯·æ±ä¸ä¸ªé«æ§è½æè ä½åèçéé å¨ãå¦ææ²¡æå¯éç对象ï¼è®¾å¤å°æä¾å¯¹é»è®¤éé å¨ç访é®ï¼è¿å¯¹äºå¤§å¤æ°ç¨éæ¥è¯´è¶³å¤äºã - 设å¤å¯ä»¥éè¿
GPUAdapter.requestDevice()请æ±ãè¯¥æ¹æ³æ¥åä¸ä¸ªå¯éç对象ï¼ç§°ä¸ºæè¿°ç¬¦ï¼ï¼è¯¥è®¾å¤å¯ä»¥ç¨äºæå®ä½ æ³è¦é»è¾è®¾å¤å ·æçç¡®åç¹æ§åéå¶ãå¦ææ²¡æå¯éçå¯¹è±¡ï¼ææä¾ç设å¤å°ä½¿ç¨åççéç¨çè§åï¼è¿å¯¹äºå¤§å¤æ°ç¨éæ¥è¯´å¤äºã
å°å ¶ä¸ä¸äºç¹æ§æ£æµæ£æ¥ç»åèµ·æ¥ï¼å¯ä»¥æå¦ä¸æ¹å¼å®ç°ä¸è¿°è¿ç¨ï¼
async function init() {
if (!navigator.gpu) {
throw Error("WebGPU not supported.");
}
const adapter = await navigator.gpu.requestAdapter();
if (!adapter) {
throw Error("Couldn't request WebGPU adapter.");
}
const device = await adapter.requestDevice();
//...
}
管线åçè²å¨ï¼WebGPU åºç¨ç¨åºçææ
管线ï¼pipelineï¼æ¯ä¸ä¸ªé»è¾ç»æï¼å ¶å å«å¨ä½ 宿ç¨åºå·¥ä½çå¯ç¼ç¨é¶æ®µãWebGPU ç®åè½å¤å¤ç两ç§ç±»åç管线ï¼
-
渲æç®¡çº¿ç¨äºæ¸²æå¾å½¢ï¼é常渲æå°
<canvas>å ç´ ä¸ï¼ä½å®ä¹å¯ä»¥å¨ç»é¢ä¹å¤çå°æ¹æ¸²æå¾å½¢ãå®æä¸¤ä¸ªä¸»è¦é¶æ®µï¼-
é¡¶ç¹çè²é¶æ®µï¼å¨è¯¥é¶æ®µä¸ï¼é¡¶ç¹çè²å¨ï¼vertex shaderï¼æ¥å GPU è¾å ¥çä½ç½®æ°æ®å¹¶ä½¿ç¨åæè½¬ã平移æéè§çç¹å®çææå°é¡¶ç¹å¨ 3D 空é´ä¸å®ä½ãç¶åï¼è¿äºé¡¶ç¹ä¼è¢«ç»è£ æåºæ¬ç渲æå¾å ï¼ä¾å¦ä¸è§å½¢çï¼ç¶åéè¿ GPU è¿è¡å æ åï¼è®¡ç®åºæ¯ä¸ªé¡¶ç¹åºè¯¥è¦çå¨ canvas ä¸çåªäºåç´ ã
-
çå çè²é¶æ®µï¼å¨è¯¥é¶æ®µä¸ï¼çå çè²å¨ï¼fragment shaderï¼è®¡ç®ç±é¡¶ç¹çè²å¨çæçåºæ¬å¾å æè¦ççæ¯ä¸ªåç´ çé¢è²ãè¿äºè®¡ç®é常使ç¨è¾å ¥ï¼å¦å¾åï¼ä»¥çº¹ççæ¹å¼ï¼æä¾è¡¨é¢ç»è以åèæåå æºçä½ç½®åé¢è²ã
-
-
计ç®ç®¡çº¿ç¨äºéç¨è®¡ç®ã计ç®ç®¡çº¿å å«åç¬ç计ç®é¶æ®µï¼å¨è¯¥é¶æ®µä¸ï¼è®¡ç®çè²å¨ï¼compute shaderï¼æ¥åéç¨çæ°æ®ï¼å¨æå®æ°éçå·¥ä½ç»ä¹é´å¹¶è¡å¤çæ°æ®ï¼ç¶åå°ç»æè¿åå°ä¸ä¸ªæè å¤ä¸ªç¼å²åºãè¿äºç¼å²åºå¯ä»¥å å«ä»»æç±»åçæ°æ®ã
ä¸é¢æå°ççè²å¨æ¯éè¿ GPU å¤ççæä»¤éãWebGPU çè²å¨è¯è¨æ¯ç¨ç§°ä¸º WebGPU çè²å¨è¯è¨ï¼WGSLï¼çä½çº§çç±» Rust è¯è¨ç¼åçã
ä½ å¯ä»¥éè¿å ç§ä¸åçæ¹å¼å»æå»º WebGPU åºç¨ç¨åºï¼ä½è¯¥è¿ç¨åºå å«ä»¥ä¸æ¥éª¤ï¼
- å建çè²å¨æ¨¡åï¼å¨ WGSL åä½ ççè²å¨ä»£ç å¹¶å°å ¶æå å°ä¸ä¸ªæè å¤ä¸ªçè²å¨æ¨¡åã
- è·ååé
ç½® canvas ä¸ä¸æï¼è·å
<canvas>å ç´ çwebgpuä¸ä¸æå¹¶å°å ¶é 置为ä»ä½ ç GPU é»è¾è®¾å¤æ¥æ¶æå ³æ¸²æçå¾å½¢ä¿¡æ¯ãå¦æä½ çåºç¨ç¨åºæ²¡æå¾å½¢è¾åºï¼ä¾å¦ä» 使ç¨è®¡ç®ç®¡çº¿ï¼ï¼åæ¤æ¥éª¤æ¯ä¸éè¦çã - å建å å«ä½ æ°æ®çèµæºï¼ä½ æ³è¦éè¿ä½ ç管线å¤ççæ°æ®åå¨å¨ GPU ç¼å²åºæè 纹çä¸ï¼ä»¥ä¾åºç¨ç¨åºè®¿é®ã
- å建管线ï¼å®ä¹ç®¡çº¿æè¿°ç¬¦ï¼è¯¦ç»å°æè¿°ç®¡çº¿ï¼å 嫿éçæ°æ®ç»æãç»å®ãçè²å¨åèµæºå¸å±ï¼ç¶åä»ä¸å建管线ãæä»¬çåºæ¬æ¼ç¤ºä» å å«å个管线ï¼ä½å¤æçåºç¨ç¨åºé常ä¼å å«å¤ä¸ªç¨äºä¸åç®çç管线ã
- å
许计ç®/渲æééï¼è¿æ¶å许å¤åæ¥éª¤ï¼
- å建ä¸ä¸ªæä»¤ç¼ç å¨ï¼å®å¯ä»¥å¯¹ä¸ç»ä¼ éç» GPU çæä»¤æ§è¡ç¼ç ã
- å建ä¸ä¸ªééç¼ç å¨å¯¹è±¡ï¼è¯¥å¯¹è±¡ç¨äºååºè®¡ç®/渲ææä»¤ã
- è¿è¡æä»¤ï¼æå®ä½¿ç¨åªäºç®¡çº¿ãä»åªä¸ªç¼å²åºè·åæ°æ®ãè¿è¡å¤å°æ¬¡ç»å¶æä½çã
- 宿æä»¤å表åï¼å°å ¶å°è£ 尿令ç¼å²åºä¸ã
- éè¿é»è¾è®¾å¤çæä»¤éåæäº¤æä»¤å°ç¼å²åºã
å¨ä¸é¢çé¨åï¼æä»¬å°ç ç©¶ä¸ä¸ªåºæ¬ç渲æç®¡çº¿æ¼ç¤ºï¼è®©ä½ ç¥éæ¢ç´¢å®éè¦ä»ä¹ãç¨åï¼æä»¬ä¹å°ç ç©¶ä¸ä¸ªåºç¡ç计ç®ç®¡çº¿ç¤ºä¾ï¼ççå®ä¸æ¸²æç®¡çº¿æä»ä¹ä¸åã
åºç¡ç渲æç®¡çº¿
卿们çåºç¡ç渲æç®¡çº¿ç¤ºä¾ä¸ï¼æä»¬ç» <canvas> å
ç´ ä¸ä¸ªçº¯èè²èæ¯å¹¶ä¸å¨å
¶ä¸ç»å¶ä¸è§å½¢ã
å建çè²å¨æ¨¡å
æä»¬ä½¿ç¨ä»¥ä¸çè²å¨ä»£ç ãé¡¶ç¹çè²é¶æ®µï¼@vertex 代ç åï¼æ¥åå
å«ä½ç½®åé¢è²çæ°æ®ååï¼æ ¹æ®ç»å®çä½ç½®å®ä½é¡¶ç¹ï¼æå
¥é¢è²ï¼ç¶åå°æ°æ®ä¼ å
¥å°çå
çè²å¨é¶æ®µãçå
çè²é¶æ®µï¼@fragment 代ç åï¼æ¥åæ¥èªé¡¶ç¹çè²å¨é¶æ®µçæ°æ®ï¼å¹¶æ ¹æ®ç»å®çé¢è²ä¸ºé¡¶ç¹çè²ã
const shaders = `
struct VertexOut {
@builtin(position) position : vec4f,
@location(0) color : vec4f
}
@vertex
fn vertex_main(@location(0) position: vec4f,
@location(1) color: vec4f) -> VertexOut
{
var output : VertexOut;
output.position = position;
output.color = color;
return output;
}
@fragment
fn fragment_main(fragData: VertexOut) -> @location(0) vec4f
{
return fragData.color;
}
`;
夿³¨ï¼å¨æä»¬çæ¼ç¤ºä¸ï¼æä»¬å°æä»¬ç代ç åå¨å¨æ¨¡æ¿åé¢éä¸ï¼ä½æ¯ä½ å¯ä»¥å°å
¶åå¨å¨ä»»ä½å°æ¹ï¼ä»¥ä¾¿å¯ä»¥å¾å®¹æå°å°å
¶ä½ä¸ºææ¬ååï¼å¹¶è¾å
¥å°ä½ ç WebGPU ç¨åºä¸ãä¾å¦ï¼å¦ä¸ç§å¸¸è§ç使³æ¯å°çè²å¨åå¨å¨ <script> å
ç´ ä¸å¹¶ä¸ä½¿ç¨ Node.textContent ååå
容ãç¨äº WGSL çæ£ç¡® MIME ç±»åæ¯ text/wgslã
为äºç¡®ä¿ä½ ççè²å¨ä»£ç 坿ä¾ç» WebGPUï¼ä½ å¿
é¡»éè¿ GPUDevice.createShaderModule() è°ç¨ï¼å°å
¶æ¾å
¥ GPUShaderModule ä¸ï¼å°ä½ ççè²å¨ä»£ç ä½ä¸ºæè¿°ç¬¦å¯¹è±¡ä¸ç屿§ä¼ éãä¾å¦ï¼
const shaderModule = device.createShaderModule({
code: shaders,
});
è·ååé ç½® canvas ä¸ä¸æ
卿¸²æç®¡çº¿ä¸ï¼æä»¬éè¦æå®å¨åªä¸ªä½ç½®æ¸²æå¾å½¢ãå¨è¿ç§æ
åµä¸ï¼æä»¬è·å¾å¯¹å±å¹ä¸ <canvas> å
ç´ çå¼ç¨ï¼ç¶åä½¿ç¨ webgpu åæ°è°ç¨ HTMLCanvasElement.getContext()ï¼ä»¥è¿åå®ç GPU ä¸ä¸æï¼ä¸ä¸ª GPUCanvasContext å®ä¾ï¼ã
ä»è¿éç»§ç»ï¼æä»¬å°éè¿è°ç¨ GPUCanvasContext.configure() å»é
ç½®ä¸ä¸æï¼åå®ä¼ éå
嫿¸²æä¿¡æ¯çå¯é对象ï¼å
æ¬ GPUDeviceã纹ççæ ¼å¼ä»¥åå¨åéæçº¹çæ¶ä½¿ç¨ç alpha 模å¼ã
const canvas = document.querySelector("#gpuCanvas");
const context = canvas.getContext("webgpu");
context.configure({
device: device,
format: navigator.gpu.getPreferredCanvasFormat(),
alphaMode: "premultiplied",
});
夿³¨ï¼ç¡®å®çº¹çæ ¼å¼çæä½³åæ³æ¯ä½¿ç¨ GPU.getPreferredCanvasFormat() æ¹æ³ï¼è¿å°ä¸ºç¨æ·ç设å¤éæ©æææçæ ¼å¼ï¼bgra8unorm æ rgba8unormï¼ã
å建ç¼å²åºå¹¶å°æä»¬çä¸è§å½¢æ°æ®åå ¥
æ¥ä¸æ¥ï¼æä»¬å°ä»¥ WebGPU å¯ä»¥ä½¿ç¨çæ°æ®å½¢å¼åå®çç¨åºæä¾æä»¬çæ°æ®ãæä»¬çæ°æ®æåå¨ Float32Array 䏿ä¾ï¼æ¯ä¸ªä¸è§å½¢å
å« 8 ä¸ªæ°æ®ç¹ââXãYãZãW 代表ä½ç½®ï¼RãGãBãA 代表é¢è²ã
const vertices = new Float32Array([
0.0, 0.6, 0, 1, 1, 0, 0, 1, -0.5, -0.6, 0, 1, 0, 1, 0, 1, 0.5, -0.6, 0, 1, 0,
0, 1, 1,
]);
使¯ï¼æä»¬è¿éæä¸ä¸ªé®é¢ãæä»¬éè¦å°æä»¬çæ°æ®æ¾å
¥ GPUBufferãå¨å¹åï¼è¿ç§ç±»åçç¼å²åºä¸ GPU çæ ¸å¿é常紧å¯çéæå¨ä¸èµ·ï¼ä»¥å®ç°æéç髿§è½å¤çãç±äºå¯ä½ç¨ï¼è¯¥å
åä¸è½éè¿ä¸»æºç³»ç»ä¸è¿è¡çè¿ç¨ï¼ä¾å¦æµè§å¨ï¼è®¿é®ã
GPUBuffer éè¿è°ç¨ GPUDevice.createBuffer() å建ãæä»¬ç»å®ä¸ vertices æ°ç»é¿åº¦çåç大å°ï¼è¿æ ·å®å¯ä»¥å
å«æææ°æ®ï¼ä»¥å VERTEX å COPY_DST ä½¿ç¨æ å¿å»æç¤ºç¼å²åºå°ç¨äºé¡¶ç¹ç¼å²åºåå¤å¶æä½çç®çå°ã
const vertexBuffer = device.createBuffer({
size: vertices.byteLength, // make it big enough to store vertices in
usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
});
æä»¬å°ä½¿ç¨æ å°æä½å°æä»¬çæ°æ®æ¾å
¥ GPUBufferï¼å°±åæä»¬å¨è®¡ç®ç®¡çº¿å®ä¾ä¸ï¼å°æ°æ®ä» GPU 读åå° JavaScriptãç¶èï¼å¨è¿ç§æ
åµä¸ï¼æä»¬å°ä½¿ç¨ä¾¿å©ç GPUQueue.writeBuffer() æ¹æ³ï¼å®å°è¦åå
¥ç¼å²åºçãè¦åå
¥æ°æ®æºçãæ¯ä¸ªåç§»å¼åè¦åå
¥æ°æ®ç大å°ä½ä¸ºåæ°ï¼æä»¬å·²ç»æå®äºæ°æ®çæ´ä¸ªé¿åº¦ï¼ãç¶åæµè§å¨ä¼æ¾åºåå
¥æ°æ®çæé«æçæ¹å¼ã
device.queue.writeBuffer(vertexBuffer, 0, vertices, 0, vertices.length);
å®ä¹åå建渲æç®¡çº¿
ç°å¨æä»¬å·²ç»å°æ°æ®æ¾å ¥ç¼å²åºï¼è®¾ç½®çä¸ä¸é¨åæ¯å®é å建æä»¬ç管线ï¼ä¸ºæ¸²æåå¤å¥½ã
é¦å
ï¼æä»¬å建ä¸ä¸ªå¯¹è±¡ï¼è¯¥å¯¹è±¡æè¿°æä»¬é¡¶ç¹æ°æ®æéçå¸å±ãè¿å®ç¾å°æè¿°äºæä»¬å¨ vertices æ°ç»åé¡¶ç¹çè²é¶æ®µçå°çå
容ââæ¯ä¸ªé¡¶ç¹é½æä½ç½®åé¢è²æ°æ®ã两è
é½éç¨ float32x4 æ ¼å¼ï¼æ å°å° WGSL ç vec4<f32> ç±»åï¼ï¼é¢è²æ°æ®ä»æ¯ä¸ªé¡¶ç¹ç 16 åèåç§»éå¼å§ãarrayStride æå®äºæ¥å¹
ï¼è¡¨ç¤ºæææ¯ä¸ªé¡¶ç¹çåèæ°ï¼stepMode æå®äºåºè¯¥æé¡¶ç¹è·åæ°æ®ã
const vertexBuffers = [
{
attributes: [
{
shaderLocation: 0, // ä½ç½®
offset: 0,
format: "float32x4",
},
{
shaderLocation: 1, // é¢è²
offset: 16,
format: "float32x4",
},
],
arrayStride: 32,
stepMode: "vertex",
},
];
ä¸ä¸æ¥ï¼æä»¬å建ä¸ä¸ªæè¿°ç¬¦å¯¹è±¡ï¼è¯¥å¯¹è±¡æå®äºæä»¬æ¸²æç®¡çº¿é¶æ®µçé
ç½®ã对äºä¸¤ä¸ªçè²é¶æ®µï¼æä»¬æå®äºå¯ä»¥å¨ shaderModule 䏿¾å°ç¸å
³ä»£ç ç GPUShaderModuleï¼ä»¥åæ¾å°æ¯ä¸ªé¶æ®µå
¥å£ç¹ç彿°åç§°ã
æ¤å¤ï¼å¨é¡¶ç¹çè²é¶æ®µï¼æä»¬æä¾æä»¬ç vertexBuffers å¯¹è±¡ï¼æ¥æä¾é¡¶ç¹æ°æ®çé¢æç¶æã卿们ççå
çè²é¶æ®µï¼æä»¬æä¾äºä¸ç»é¢è²ç®æ 说æçæ°ç»ï¼å
¶æç¤ºæ¸²æçæ ¼å¼ï¼è¿ä¸æä»¬ä¹åå¨ canvas ä¸ä¸æé
ç½®ä¸æå®çæ ¼å¼ç¸å¹é
ï¼ã
æä»¬ä¹æå®äºä¸ä¸ª primitive 说æï¼å¨è¿ç§æ
åµä¸ï¼å®åªæ¯è¯´æäºæä»¬å°è¦ç»å¶çåå§ç±»åï¼ä»¥å layout 为 autoãlayout 屿§å®ä¹äºå¨ç®¡çº¿æ§è¡æé´ï¼ææ GPU èµæºï¼ç¼å²åºã纹ççï¼çå¸å±ï¼ç»æãç¨éåç±»åã卿´å¤æçåºç¨ç¨åºä¸ï¼è¿å°éç¨ GPUPipelineLayout 对象çå½¢å¼ï¼ä½¿ç¨ GPUDevice.createPipelineLayout() å建ï¼ä½ å¯ä»¥å¨æä»¬çåºç¡ç计ç®ç®¡çº¿çè§è¿ä¸ªç¤ºä¾ï¼ï¼å®å
许 GPU æå弿¸
æ¥å¦ä½æ´ææå°è¿è¡ç®¡çº¿ãç¶èï¼å¨è¿éæä»¬æå®äº auto å¼ï¼è¿å°å¯¼è´ç®¡çº¿åºäºçè²å¨ä»£ç ä¸å®ä¹çä»»ä½ç»å®çæéå¼ç»å®ç»å¸å±ã
const pipelineDescriptor = {
vertex: {
module: shaderModule,
entryPoint: "vertex_main",
buffers: vertexBuffers,
},
fragment: {
module: shaderModule,
entryPoint: "fragment_main",
targets: [
{
format: navigator.gpu.getPreferredCanvasFormat(),
},
],
},
primitive: {
topology: "triangle-list",
},
layout: "auto",
};
æç»ï¼æä»¬éè¿ä¼ é pipelineDescriptor åæ°ç» GPUDevice.createRenderPipeline() æ¹æ³è°ç¨ï¼æä»¬å建äºä¸ä¸ª GPURenderPipelineã
const renderPipeline = device.createRenderPipeline(pipelineDescriptor);
è¿è¡æ¸²æéé
ç°å¨ææè®¾ç½®é½å·²å®æï¼å®é
ä¸ï¼æä»¬å¯ä»¥è¿è¡ä¸ä¸ªæ¸²æéé并卿们ç <canvas> ä¸è¿è¡ç»å¶ã为äºå¯¹ç¨ååéç» GPU ç任使令è¿è¡ç¼ç ï¼ä½ éè¦å建ä¸ä¸ª GPUCommandEncoder å®ä¾ï¼è¿æ¯è°ç¨ GPUDevice.createCommandEncoder() 宿çã
const commandEncoder = device.createCommandEncoder();
ä¸ä¸æ¥ï¼æä»¬éè¿è°ç¨ GPUCommandEncoder.beginRenderPass() å建 GPURenderPassEncoder å®ä¾æ¥å¼å§è¿è¡æ¸²æééãè¯¥æ¹æ³éç¨ä¸ä¸ªæè¿°ç¬¦å¯¹è±¡ä½ä¸ºåæ°ï¼å¯ä¸çå¿
须屿§æ¯ colorAttachments æ°ç»ãå¨è¯¥å®ä¾ä¸ï¼æä»¬æå®äºï¼
- è¦æ¸²æå°ç纹çè§å¾ï¼æä»¬éè¿
context.getCurrentTexture().createView()ä»<canvas>å建ä¸ä¸ªæ°è§å¾ã - 纹çè§å¾ä¸æ¦å 载并ä¸å¨ä»»ä½ç»å¶åçä¹åï¼å°âæ¸ é¤âè§å¾å°ä¸ä¸ªæå®çé¢è²ãè¿å°±æ¯å¯¼è´ä¸è§å½¢åé¢åºç°èè²èæ¯çåå ã
- æä»¬è¿è¦å¨å½åçæ¸²æééä¸åå¨è¿ä¸ªé¢è²éä»¶çå¼ã
const clearColor = { r: 0.0, g: 0.5, b: 1.0, a: 1.0 };
const renderPassDescriptor = {
colorAttachments: [
{
clearValue: clearColor,
loadOp: "clear",
storeOp: "store",
view: context.getCurrentTexture().createView(),
},
],
};
const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
ç°å¨ï¼æä»¬å¯ä»¥è°ç¨æ¸²æééç¼ç å¨çæ¹æ³å»ç»å¶æä»¬çä¸è§å½¢ï¼
- 尿们ç
renderPipeline对象ä½ä¸ºGPURenderPassEncoder.setPipeline()æ¹æ³çåæ°è°ç¨ï¼ä»¥æå®ç¨äºæ¸²æç®¡çº¿çééã - 尿们ç
vertexBuffer对象ä½ä¸ºGPURenderPassEncoder.setVertexBuffer()æ¹æ³çåæ°è°ç¨ï¼ä½ä¸ºæ°æ®æºä¼ éç»ç®¡çº¿è¿è¡æ¸²æã第ä¸ä¸ªåæ°æ¯è®¾ç½®é¡¶ç¹ç¼å²åºçææ§½ï¼è¿æ¯å¯¹vertexBuffersæ°ç»ä¸æè¿°è¯¥ç¼å²åºå¸å±çå ç´ ç´¢å¼çå¼ã GPURenderPassEncoder.draw()è®¾ç½®å¨æç»å¶ã卿们çvertexBuffer䏿ä¸ä¸ªé¡¶ç¹çæ°æ®ï¼æä»¥æä»¬å°é¡¶ç¹æ°å¼è®¾ç½®ä¸º3å»ç»å¶å®ä»¬ã
passEncoder.setPipeline(renderPipeline);
passEncoder.setVertexBuffer(0, vertexBuffer);
passEncoder.draw(3);
è¦å®æå¯¹æä»¤åºåçç¼ç å¹¶å°å®ä»¬åéç» GPUï¼è¿éè¦ä¸ä¸ªæ¥éª¤ã
- æä»¬è°ç¨
GPURenderPassEncoder.end()æ¹æ³å»ç»æ¸²ææä»¤å表ååºç»æçä¿¡å·ã - æä»¬è°ç¨
GPUCommandEncoder.finish()æ¹æ³å»å®æå¯¹ååºæä»¤åºåçè®°å½ï¼å¹¶å°å ¶å°è£ å°GPUCommandBuffer对象ä¸ã - æä»¬æäº¤
GPUCommandBufferå°è®¾å¤çæä»¤éåä¸ï¼éè¿GPUQueueå®ä¾è¡¨ç¤ºï¼å·²åéç» GPUãè¿ä¸ªè®¾å¤çéåå¯ä»¥éè¿GPUDevice.queue屿§è·åï¼å¹¶å¯ä»¥éè¿GPUQueue.submit()è°ç¨å°GPUCommandBufferå®ä¾æ°ç»å¢å å°éåä¸ã
è¿ä¸ä¸ªæ¥éª¤å¯ä»¥éè¿ä»¥ä¸ä¸¤è¡æ¥å®ç°ã
passEncoder.end();
device.queue.submit([commandEncoder.finish()]);
åºç¡ç计ç®ç®¡çº¿
卿们çåºç¡è®¡ç®æ¼ç¤ºä¸ï¼æä»¬è®© GPU 计ç®ä¸äºå¼ï¼å°å®ä»¬åå¨å°è¾åºç¼åä¸ï¼å°æ°æ®å¤å¶å°æåç¼å²åºï¼ç¶åæ å°è¯¥æåç¼å²åºï¼ä»¥ä¾¿æ°æ®å¯ä»¥è¯»åºå° JavaScript å¹¶ä¸è®°å½å°æ§å¶å°ã
该åºç¨ç¨åºä¸åºç¡çæ¸²ææ¼ç¤ºæçç¸ä¼¼çç»æãæä»¬ä»¥ä¸ä¹åç¸åçæ¹å¼å建ä¸ä¸ª GPUDevice å¼ç¨ï¼å¹¶éè¿è°ç¨ GPUDevice.createShaderModule() 尿们ççè²å¨ä»£ç å°è£
å° GPUShaderModuleãè¿éçåºå«å¨äºæä»¬ççè²å¨ä»£ç ä»
æä¸ä¸ªçè²é¶æ®µï¼@compute é¶æ®µï¼
// å®ä¹å
¨å±çç¼å²åºå¤§å°
const BUFFER_SIZE = 1000;
const shader = `
@group(0) @binding(0)
var<storage, read_write> output: array<f32>;
@compute @workgroup_size(64)
fn main(
@builtin(global_invocation_id)
global_id : vec3u,
@builtin(local_invocation_id)
local_id : vec3u,
) {
// Avoid accessing the buffer out of bounds
if (global_id.x >= ${BUFFER_SIZE}) {
return;
}
output[global_id.x] =
f32(global_id.x) * 1000. + f32(local_id.x);
}
`;
å建ç¼å²åºå¤çæä»¬çæ°æ®
å¨è¯¥ç¤ºä¾ä¸ï¼æä»¬å建äºä¸¤ä¸ª GPUBuffer å®ä¾å»å¤çæä»¬çæ°æ®ï¼output ç¼å²åºé«éå°åå
¥ GPU 计ç®ç»æï¼stagingBuffer ç¼å²åºç¨äºå° output çå
容å¤å¶å°èªèº«ï¼å®å¯ä»¥è¢«æ å°ä»¥å
许 JavaScript 访é®è¿äºå¼ã
- æå®
output为ä¸ä¸ªåå¨ç¼å²åºï¼å®å°æä¸ºå¤å¶æä½çæºã - æå®
stagingBufferå¯ä»¥è¢«æ å°ä¸ºä¸ä¸ªç± JavaScript 读åçç¼å²åºï¼å¹¶å°æä¸ºå¤å¶æä½çç®æ ã
const output = device.createBuffer({
size: BUFFER_SIZE,
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC,
});
const stagingBuffer = device.createBuffer({
size: BUFFER_SIZE,
usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,
});
å建ç»å®ç»å¸å±
å½å建管线æ¶ï¼æä»¬éè¦ä¸ºç®¡çº¿æå®ä¸ä¸ªç»å®ç»ãè¿å°é¦å
å建 GPUBindGroupLayoutï¼éè¿è°ç¨ GPUDevice.createBindGroupLayout()ï¼ï¼è¯¥å¸å±å®ä¹äº GPU èµæºï¼ä¾å¦å°å¨æ¤ç®¡çº¿ä¸ä½¿ç¨çç¼å²åºï¼çç»æåç¨éãæ¤å¸å±å°ç¨ä½ç»å®ç»ç模æ¿ãå¨è¿ç§æ
åµä¸ï¼æä»¬å°ç®¡çº¿ä¸ä¸ä¸ªåä¸çå
åç¼å²åºç»å®ï¼ç»å®å°ç»å®æ§½ 0ï¼è¿ä¸æä»¬ççè²å¨ä»£ç ä¸çç¸å
³ç»å®å·å¹é
ââ@binding(0)ï¼ï¼å¯å¨ç®¡çº¿ç计ç®é¶æ®µä½¿ç¨ï¼å¹¶å°ç¼å²åºçç¨éå®ä¹ä¸º storageã
const bindGroupLayout = device.createBindGroupLayout({
entries: [
{
binding: 0,
visibility: GPUShaderStage.COMPUTE,
buffer: {
type: "storage",
},
},
],
});
ä¸ä¸æ¥ï¼æä»¬éè¿è°ç¨ GPUDevice.createBindGroup() å建 GPUBindGroupãæä»¬éè¿æ¤æ¹æ³è°ç¨ä¸ä¸ªæè¿°ç¬¦å¯¹è±¡ï¼è¯¥å¯¹è±¡æå®äºè¿ä¸ªç»å®ç»åºè¯¥åºäºçç»å®ç»å¸å±ï¼ä»¥åç»å®å°å¸å±ä¸å®ä¹çææ§½åéç详ç»ä¿¡æ¯ãå¨è¿ç§æ
åµä¸ï¼æä»¬å£°æäºç»å®ææ§½ 0ï¼å¹¶æå®äºä¹åå®ä¹ç output ç¼å²åºåºè¯¥ç»å®å°å®ã
const bindGroup = device.createBindGroup({
layout: bindGroupLayout,
entries: [
{
binding: 0,
resource: {
buffer: output,
},
},
],
});
夿³¨ï¼ä½ å¯ä»¥éè¿è°ç¨ GPUComputePipeline.getBindGroupLayout() æ¹æ³æ£ç´¢å¨å建ç»å®ç»æ¶ä½¿ç¨çéå¼å¸å±ãè¿æä¸ä¸ªå¯ä»¥ç¨äºæ¸²æç®¡çº¿ççæ¬ï¼åè§ GPURenderPipeline.getBindGroupLayout()ã
å建计ç®ç®¡çº¿
ä¸è¿°ä¸å就绪åï¼æä»¬ç°å¨å¯ä»¥éè¿è°ç¨ GPUDevice.createComputePipeline() å¹¶åå®ä¼ éä¸ä¸ªç®¡çº¿æè¿°ç¬¦å¯¹è±¡å建计ç®ç®¡çº¿ãè¿ä¸å建渲æç®¡çº¿çæ¹å¼ç±»ä¼¼ãæä»¬æè¿°è®¡ç®çè²å¨ï¼æå®å¨åªä¸ªæ¨¡å䏿¥æ¾ä»£ç 以åå
¥å£ç¹æ¯ä»ä¹ãæä»¬ä¹ä¸ºç®¡çº¿æå®äº layoutï¼å¨æ¬ä¾ä¸ï¼æä»¬éè¿è°ç¨ GPUDevice.createPipelineLayout() å建ä¸ä¸ªåºäºä¹åå®ä¹ç bindGroupLayout çå¸å±ã
const computePipeline = device.createComputePipeline({
layout: device.createPipelineLayout({
bindGroupLayouts: [bindGroupLayout],
}),
compute: {
module: shaderModule,
entryPoint: "main",
},
});
å¯ä¸çåºå«æ¯ï¼è¿éæä»¬æ²¡ææå®åå§ç±»åï¼å 为æä»¬ä¸éè¦ç»å¶ä»»ä½ä¸è¥¿ã
è¿è¡è®¡ç®éé
å¨ç»æä¸ï¼è¿è¡è®¡ç®ééä¸è¿è¡æ¸²æéé类似ãé¦å
ï¼æä»¬ä½¿ç¨ GPUCommandEncoder.beginComputePass() å建ééç¼ç å¨ã
å¨ååºæä»¤æ¶ï¼æä»¬ä½¿ç¨ç¸åçæ¹å¼æå®ç®¡çº¿ï¼ä½¿ç¨ GPUComputePassEncoder.setPipeline()ãç¶åï¼æä»¬ä½¿ç¨ GPUComputePassEncoder.setBindGroup() æå®æ³è¦ä½¿ç¨ç bindGroup æ¥æå®å¨è®¡ç®ä¸ä½¿ç¨çæ°æ®ï¼å¹¶ä½¿ç¨ GPUComputePassEncoder.dispatchWorkgroups() æå®è¦è¿è¡å¹¶è¡è®¡ç®ç GPU å·¥ä½ç»çæ°éã
æåï¼æä»¬ä½¿ç¨ GPURenderPassEncoder.end() ååºæ¸²æééæä»¤ç»æçä¿¡å·ã
passEncoder.setPipeline(computePipeline);
passEncoder.setBindGroup(0, bindGroup);
passEncoder.dispatchWorkgroups(Math.ceil(BUFFER_SIZE / 64));
passEncoder.end();
å°ç»æè¯»å JavaScript
å¨ä½¿ç¨ GPUQueue.submit() å°ç¼ç æä»¤æäº¤ç» GPU æ§è¡ä¹åï¼æä»¬ä½¿ç¨ GPUCommandEncoder.copyBufferToBuffer() å° output ç¼å²åºçå
容å¤å¶å° stagingBuffer ç¼å²åºä¸ã
// å¤å¶ output ç¼å²å»å° staging ç¼å²åº
commandEncoder.copyBufferToBuffer(
output,
0, // æ¥æºç¼å²åºåç§»é
stagingBuffer,
0, // ç®çç¼å²åºåç§»é
BUFFER_SIZE,
);
// éè¿å°å½ä»¤ç¼å²åºæ°ç»ä¼ éç»å½ä»¤éå以æ§è¡æ¥ç»æ
device.queue.submit([commandEncoder.finish()]);
䏿¦è¾åºæ°æ®å¯ç¨äº stagingBufferï¼æä»¬ä½¿ç¨ GPUBuffer.mapAsync() æ¹æ³å°æ°æ®æ å°å°ä¸é´å
åï¼å¹¶ä½¿ç¨ GPUBuffer.getMappedRange() è·åæ å°èå´çå¼ç¨ï¼å°æ°æ®å¤å¶å° JavaScripï¼å¹¶å°å
¶è®°å½å°æ§å¶å°ã宿åï¼æä»¬è¿ä¼åæ¶æ å°å° stagingBufferã
// æ å° staging ç¼å²åºï¼ä»¥ä¾¿è¯»åå° JS
await stagingBuffer.mapAsync(
GPUMapMode.READ,
0, // åç§»é
BUFFER_SIZE, // é¿åº¦
);
const copyArrayBuffer = stagingBuffer.getMappedRange(0, BUFFER_SIZE);
const data = copyArrayBuffer.slice();
stagingBuffer.unmap();
console.log(new Float32Array(data));
GPU é误å¤ç
WebGPU è°ç¨å¨ GPU è¿ç¨ä¸ä»¥å¼æ¥çæ¹å¼è¿è¡éªè¯ã妿åç°éè¯¯ï¼æé®é¢çè°ç¨ä¼å¨ GPU 端æ è®°ä¸ºæ æã妿ä¾èµäºä¸ä¸ªæ æè°ç¨è¿åå¼çå¦ä¸ä¸ªè°ç¨è¢«æ§è¡ï¼é£ä¹è¯¥å¯¹è±¡å°ä¹è¢«æ è®°ä¸ºæ æï¼ä»¥æ¤ç±»æ¨ãå æ¤ï¼WebGPU çé误被称为âä¼ ææ§é误âã
æ¯ä¸ª GPUDevice å®ä¾é½ç»´æ¤è¿èªå·±çé误ä½ç¨åæ ãè¿ä¸ªæ æåæ¯ç©ºçï¼ä½æ¯ä½ å¯ä»¥éè¿è°ç¨ GPUDevice.pushErrorScope() æ¥å¼å§æ¨å
¥é误ä½ç¨åå°æ ï¼ä»¥æè·ç¹å®ç±»åçé误ã
䏿¦å®æé误æè·ï¼ä½ å¯ä»¥éè¿è°ç¨ GPUDevice.popErrorScope() æ¥ç»ææè·ãè¿ä¼ä»æ ä¸å¼¹åºä½ç¨åå¹¶è¿åä¸ä¸ª Promiseï¼è¯¥ Promise å
ç°ä¸ºä¸ä¸ªå¯¹è±¡ï¼GPUInternalErrorãGPUOutOfMemoryError æ GPUValidationErrorï¼ï¼æè¿°å¨ä½ç¨åå
æè·ç第ä¸ä¸ªé误ï¼å¦ææ²¡æé误æè·ï¼åæ¯ nullã
å¨éå½çâéªè¯âé¨åï¼æä»¬è¯å¾å»æä¾å¸®å©ä½ ç解为ä»ä¹ä½ ç WebGPU 代ç åçé误çæç¨ä¿¡æ¯ï¼å
¶ä¸ååºäºé¿å
éè¯¯çæ¡ä»¶ãä¾å¦ï¼åè§ GPUDevice.createBindGroup() æ£éªé¨åãå
¶ä¸ä¸äºä¿¡æ¯å¾å¤æï¼æä»¬å³å®ä»
ååºä»¥ä¸é误æ åï¼è䏿¯éå¤è§èï¼
- 䏿æ¾çé误æ åï¼ä¾å¦å¯¼è´éªè¯é误çæè¿°ç¬¦å±æ§çç»åãæ²¡æå¿ è¦åè¯ä½ ç¡®ä¿ä½¿ç¨æ£ç¡®çæè¿°ç¬¦å¯¹è±¡ç»æãè¿æ¢æ¯æ¾èæè§çåæ¯æ¨¡ç³çã
- ç±å¼åè æ§å¶çé误æ åãä¸äºé误æ åä» åºäºå é¨å ç´ ï¼å¯¹äº web å¼åè å¹¶ä¸çæ£ç¸å ³ã
ä½ å¯ä»¥å¨å ³äº WebGPU é误å¤ççè§£é䏿¾å°æ´å¤æå ³ä¿¡æ¯ââåè§å¯¹è±¡çæææ§åéæ¯ç¶æä»¥åé误ãWebGPU é误å¤ççæä½³å®è·µæä¾äºå¾å¤æå ³çå®ä¸çç示ä¾å建议çæç¨ä¿¡æ¯ã
夿³¨ï¼å¨ WebGL ä¸å¤çé误çå岿¹å¼æ¯æä¾ä¸ä¸ª getError() æ¹æ³ï¼è¯¥æ¹æ³è¿åé误çä¿¡æ¯ãè¿ç§æ¹å¼åå¨é®é¢ï¼å 为å®ä¼åæ¥è¿åé误ï¼è¿å¯¹æ§è½æ¯ä¸å©çââæ¯æ¬¡è°ç¨é½éè¦å¾è¿å° GPU å¹¶ä¸éè¦ææå
åååºçæä½é½å·²ç»å®æãå®çç¶ææ¨¡å乿¯æå¹³çï¼è¿æå³çé误å¯ä»¥å¨ä¸ç¸å
³ç代ç ä¹é´æ³é²ãWebGPU çå建è
å³å®æ¹åè¿ä¸ç¹ã
æ¥å£
>API çå ¥å£ç¹
-
API çå ¥å£ç¹ââè¿åå½åä¸ä¸æç
GPU对象ã GPU-
ä½¿ç¨ WebGPU çèµ·ç¹ãå®å¯ç¨äºè¿å
GPUAdapterã GPUAdapter-
表示 GPU éé å¨ãä½ å¯ä»¥ä»è¿é请æ±
GPUDeviceãéé å¨ä¿¡æ¯ãç¹æ§åéå¶ã GPUAdapterInfo-
å å«æå ³éé å¨çæ è¯ä¿¡æ¯ã
é ç½® GPUDevice
GPUDevice-
表示é»è¾ GPU 设å¤ãè¿æ¯è®¿é®å¤§å¤æ° WebGPU åè½çä¸»è¦æ¥å£ã
GPUSupportedFeatures-
ä¸ä¸ªç±» Set 对象ï¼è¯¥å¯¹è±¡éè¿
GPUAdapteræGPUDeviceæè¿°äºé¢å¤çåè½ã GPUSupportedLimits-
æè¿°
GPUAdapteræGPUDeviceæ¯æçéå¶ã
é
置渲æ <canvas>
HTMLCanvasElement.getContext()ââcontextType为"webgpu"-
使ç¨
contextType为"webgpu"è°ç¨getContext()æ¹æ³ï¼å ¶ä¼è¿åä¸ä¸ªGPUCanvasContext对象å®ä¾ï¼ç¶åå¯ä»¥ä½¿ç¨GPUCanvasContext.configure()å¯¹å ¶è¿è¡é ç½®ã GPUCanvasContext-
表示
<canvas>å ç´ ç WebGPU 渲æä¸ä¸æã
è¡¨ç¤ºç®¡çº¿èµæº
GPUBuffer-
表示å ååï¼å ¶å¯ä»¥ç¨äºå¨ GPU æä½ä¸åå¨åå§æ°æ®ã
GPUExternalTexture-
å å«
HTMLVideoElementå¿«ç §çå è£ å¨å¯¹è±¡ï¼å¯ç¨ä½ GPU 渲ææä½ä¸ç纹çã GPUSampler-
æ§å¶çè²å¨å¦ä½è½¬æ¢åè¿æ»¤çº¹çèµæºæ°æ®ã
GPUShaderModule-
对å é¨çè²å¨æ¨¡å对象çå¼ç¨ï¼å®æ¯ WGSL çè²å¨ä»£ç ç容å¨ï¼éè¿ç®¡çº¿æäº¤ç» GPU æ§è¡ã
GPUTexture-
ç¨äºåå¨ 1Dã2D æ 3D æ°æ®æ°ç»ï¼ä¾å¦å¾åï¼ä»¥å¨ GPU 渲ææä½ä¸ä½¿ç¨ç容å¨ã
GPUTextureView-
ç±ç¹å®
GPUTextureå®ä¹ç纹çåèµæºçæä¸ªåéçè§å¾ã
表示管线
GPUBindGroup-
åºäº
GPUBindGroupLayoutï¼GPUBindGroupå®ä¹äºä¸ç»è¦ç»å®å¨ä¸èµ·çèµæºä»¥åå¦ä½å¨çè²é¶æ®µä½¿ç¨è¿äºèµæºã GPUBindGroupLayout-
å®ä¹ç¸å ³ GPU èµæºçç»æåç¨éï¼ä¾å¦å°å¨ç®¡çº¿ä¸ä½¿ç¨çç¼å²åºï¼å¹¶å¨å建
GPUBindGroupæ¶ç¨ä½æ¨¡æ¿ã GPUComputePipeline-
æ§å¶è®¡ç®çè²é¶æ®µï¼å¯ä»¥å¨
GPUComputePassEncoderä¸ä½¿ç¨ã GPUPipelineLayout-
å®ä¹ç®¡çº¿ä½¿ç¨ç
GPUBindGroupLayoutã卿令ç¼ç æé´ä¸ç®¡çº¿ä¸èµ·ä½¿ç¨çGPUBindGroupå¿ é¡»å ·æå ¼å®¹çGPUBindGroupLayoutã GPURenderPipeline-
æ§å¶é¡¶ç¹åçå çè²é¶æ®µï¼å¯ä»¥å¨
GPURenderPassEncoderæGPURenderBundleEncoder使ç¨ã
ç¼ç å¹¶å GPU æäº¤æä»¤
GPUCommandBuffer-
表示 GPU æä»¤çå½å¶å表ï¼å ¶å¯ä»¥æäº¤ç»
GPUQueueæ§è¡ã GPUCommandEncoder-
表示æä»¤ç¼ç å¨ï¼ç¨äºç¼ç æä»¤åå¸ç» GPUã
GPUComputePassEncoder-
ç¼ç 䏿§å¶è®¡ç®çè²é¶æ®µç¸å ³çæä»¤ï¼ç±
GPUComputePipelineååºãæ¯GPUCommandEncoderæ´ä½ç¼ç æ¿æ´»è¿åçä¸é¨åã GPUQueue-
æ§å¶ GPU ç¼ç æä»¤çæ§è¡ã
GPURenderBundle-
é¢å å½å¶çæä»¤ bundle ç容å¨ï¼åè§
GPURenderBundleEncoderï¼ã GPURenderBundleEncoder-
ç¨äºé¢å è®°å½æä»¤ç bundleãè¿äºå¯ä»¥éè¿
executeBundles()æ¹æ³å¨GPURenderPassEncoder䏿 ¹æ®éè¦éå¤ä½¿ç¨ã GPURenderPassEncoder-
ç¼ç 䏿§å¶é¡¶ç¹åçæ®µçè²é¶æ®µç¸å ³çæä»¤ï¼ç±
GPURenderPipelineååºãæ¯GPUCommandEncoderæ´ä½ç¼ç æ¿æ´»è¿åçä¸é¨åã
卿¸²æéé䏿§è¡æ¥è¯¢
GPUQuerySet-
ç¨äºè®°å½éé䏿¥è¯¢çç»æï¼ä¾å¦é®æ¡ææ¶é´æ³æ¥è¯¢ã
è°è¯é误
GPUCompilationInfo-
GPUCompilationMessage对象æ°ç»ï¼ç± GPU çè²å¨æ¨¡åç¼è¯å¨çæï¼ç¨äºå¸®å©è¯æçè²å¨ä»£ç é®é¢ã GPUCompilationMessage-
è¡¨ç¤ºç± GPU çè²å¨æ¨¡åç¼è¯å¨çæçå个信æ¯ãè¦åæéè¯¯æ¶æ¯ã
GPUDeviceLostInfo-
å½
GPUDevice.lostPromiseå ç°æ¶è¿åï¼æä¾æå ³è®¾å¤ä¸¢å¤±åå çä¿¡æ¯ã GPUError-
GPUDevice.popErrorScopeåuncapturederroräºä»¶æ¾ç¤ºé误çåºæ¬æ¥å£ã GPUInternalError-
GPUDevice.popErrorScopeåGPUDeviceuncapturederroräºä»¶æ¾ç¤ºçé误类åä¹ä¸ã表示æä½å ç³»ç»æç¹å®äºå®ç°çåå è失败ï¼å³ä½¿æ»¡è¶³ææéªè¯è¦æ±ä¹ä¼å¤±è´¥ã GPUOutOfMemoryError-
GPUDevice.popErrorScopeåGPUDeviceuncapturederroräºä»¶æ¾ç¤ºçé误类åä¹ä¸ã表示没æè¶³å¤çå¯ç¨å åæ¥å®æè¯·æ±çæä½ã GPUPipelineError-
æè¿°ç®¡çº¿ç失败ãå½
GPUDevice.createComputePipelineAsync()æGPUDevice.createRenderPipelineAsync()è°ç¨è¿åçPromise被æç»æ¶ï¼æ¥æ¶å°çå¼ã GPUUncapturedErrorEvent-
GPUDeviceuncapturederroräºä»¶çäºä»¶å¯¹è±¡ç±»åã GPUValidationError-
GPUDevice.popErrorScopeåGPUDeviceuncapturederroräºä»¶æ¾ç¤ºçé误类åä¹ä¸ãæè¿°ä¸ä¸ªåºç¨ç¨åºéè¯¯ï¼æç¤ºæä½æªéè¿ WebGPU API çéªè¯çº¦æã
示ä¾
è§è
| è§è |
|---|
| WebGPU > # gpu-interface > |