1+ <!DOCTYPE html>
2+ < html lang ="en ">
3+ < head >
4+ < meta charset ="UTF-8 ">
5+ < meta name ="viewport " content ="width=device-width, initial-scale=1.0 ">
6+ < title > Document</ title >
7+ </ head >
8+ < body >
9+ < script >
10+ const src = `
11+ @group(0) @binding(0) var<storage, read_write> data: array<f32>;
12+ @compute @workgroup_size(1) fn divide(@builtin(global_invocation_id) id: vec3u){
13+ let i = id.x;
14+ data[i] = data[i] / 2.0;
15+ }
16+ `
17+ async function main ( ) {
18+ const adapter = await navigator . gpu ?. requestAdapter ( ) ;
19+ const device = await adapter ?. requestDevice ( ) ;
20+ if ( ! device ) {
21+ fail ( "browser does not support WebGPU" ) ;
22+ return ;
23+ }
24+ const module = device . createShaderModule ( {
25+ label : 'i am the one who divides' ,
26+ code : src
27+ } ) ;
28+ const pipeline = device . createComputePipeline ( {
29+ label : 'i am the one who pipelines' ,
30+ layout : 'auto' ,
31+ compute :{
32+ module
33+ }
34+ } )
35+ const input = new Float32Array ( [ 1 , 3 , 5 ] ) ;
36+ const work_buffer = device . createBuffer ( {
37+ label : 'work buffer' ,
38+ size : input . byteLength ,
39+ usage : GPUBufferUsage . STORAGE | GPUBufferUsage . COPY_SRC | GPUBufferUsage . COPY_DST
40+ } ) ;
41+ device . queue . writeBuffer ( work_buffer , 0 , input ) ;
42+ const result_buffer = device . createBuffer ( {
43+ label : 'result buffer' ,
44+ size : input . byteLength ,
45+ usage : GPUBufferUsage . MAP_READ | GPUBufferUsage . COPY_DST
46+ } )
47+ const bind_group = device . createBindGroup ( {
48+ label : 'bind group for work buffer' ,
49+ layout : pipeline . getBindGroupLayout ( 0 ) ,
50+ entries : [
51+ { binding :0 , resource : work_buffer }
52+ ]
53+ } ) ;
54+ const encoder = device . createCommandEncoder ( {
55+ label : 'doubling encoder' ,
56+ } ) ;
57+ const pass = encoder . beginComputePass ( {
58+ label : 'doubling compute pass' ,
59+ } ) ;
60+ pass . setPipeline ( pipeline ) ;
61+ pass . setBindGroup ( 0 , bind_group ) ;
62+ pass . dispatchWorkgroups ( input . length ) ;
63+ pass . end ( ) ;
64+ encoder . copyBufferToBuffer ( work_buffer , 0 , result_buffer , 0 , result_buffer . size ) ;
65+ const commandBuffer = encoder . finish ( ) ;
66+ device . queue . submit ( [ commandBuffer ] ) ;
67+
68+ await result_buffer . mapAsync ( GPUMapMode . READ ) ;
69+ const result = new Float32Array ( result_buffer . getMappedRange ( ) ) ;
70+
71+ console . log ( 'input' , input ) ;
72+ console . log ( 'result' , result ) ;
73+ result_buffer . unmap ( ) ;
74+ }
75+ main ( ) ;
76+
77+
78+
79+
80+
81+
82+ </ script >
83+ </ body >
84+ </ html >
0 commit comments