Skip to content

Commit ac30ce0

Browse files
authored
WebGPU: Audio Processing using ShaderNode (mrdoob#24918)
* WebGPURenderer: add .getArrayFromBuffer() * Added webgpu_audio_processing example * test if unmap() is really necessary * improve example * example update * fix .isViewportNode * added visual feedback * optimize a bit
1 parent 46ba772 commit ac30ce0

File tree

8 files changed

+321
-6
lines changed

8 files changed

+321
-6
lines changed

examples/files.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@
324324
"webgl2_volume_perlin"
325325
],
326326
"webgpu": [
327+
"webgpu_audio_processing",
327328
"webgpu_compute",
328329
"webgpu_cubemap_adjustments",
329330
"webgpu_cubemap_mix",

examples/jsm/nodes/display/ViewportNode.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class ViewportNode extends Node {
2020

2121
this.scope = scope;
2222

23-
this.isScreenNode = true;
23+
this.isViewportNode = true;
2424

2525
}
2626

examples/jsm/renderers/webgpu/WebGPUAttributes.js

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class WebGPUAttributes {
2323

2424
if ( data ) {
2525

26-
data.buffer.destroy();
26+
this._destroyBuffers( data );
2727

2828
this.buffers.delete( attribute );
2929

@@ -51,7 +51,7 @@ class WebGPUAttributes {
5151

5252
} else if ( usage && usage !== data.usage ) {
5353

54-
data.buffer.destroy();
54+
this._destroyBuffers( data );
5555

5656
data = this._createBuffer( attribute, usage );
5757

@@ -67,14 +67,61 @@ class WebGPUAttributes {
6767

6868
}
6969

70+
async getArrayBuffer( attribute ) {
71+
72+
const data = this.get( attribute );
73+
const device = this.device;
74+
75+
const gpuBuffer = data.buffer;
76+
const size = gpuBuffer.size;
77+
78+
let gpuReadBuffer = data.readBuffer;
79+
let needsUnmap = true;
80+
81+
if ( gpuReadBuffer === null ) {
82+
83+
gpuReadBuffer = device.createBuffer( {
84+
size,
85+
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
86+
} );
87+
88+
needsUnmap = false;
89+
90+
data.readBuffer = gpuReadBuffer;
91+
92+
}
93+
94+
const cmdEncoder = device.createCommandEncoder( {} );
95+
96+
cmdEncoder.copyBufferToBuffer(
97+
gpuBuffer,
98+
0,
99+
gpuReadBuffer,
100+
0,
101+
size
102+
);
103+
104+
if ( needsUnmap ) gpuReadBuffer.unmap();
105+
106+
const gpuCommands = cmdEncoder.finish();
107+
device.queue.submit( [ gpuCommands ] );
108+
109+
await gpuReadBuffer.mapAsync( GPUMapMode.READ );
110+
111+
const arrayBuffer = gpuReadBuffer.getMappedRange();
112+
113+
return new Float32Array( arrayBuffer );
114+
115+
}
116+
70117
_createBuffer( attribute, usage ) {
71118

72119
const array = attribute.array;
73120
const size = array.byteLength + ( ( 4 - ( array.byteLength % 4 ) ) % 4 ); // ensure 4 byte alignment, see #20441
74121

75122
const buffer = this.device.createBuffer( {
76123
size,
77-
usage: usage | GPUBufferUsage.COPY_DST,
124+
usage: usage | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,
78125
mappedAtCreation: true
79126
} );
80127

@@ -87,21 +134,24 @@ class WebGPUAttributes {
87134
return {
88135
version: attribute.version,
89136
buffer,
137+
readBuffer: null,
90138
usage
91139
};
92140

93141
}
94142

95143
_writeBuffer( buffer, attribute ) {
96144

145+
const device = this.device;
146+
97147
const array = attribute.array;
98148
const updateRange = attribute.updateRange;
99149

100150
if ( updateRange.count === - 1 ) {
101151

102152
// Not using update ranges
103153

104-
this.device.queue.writeBuffer(
154+
device.queue.writeBuffer(
105155
buffer,
106156
0,
107157
array,
@@ -110,7 +160,7 @@ class WebGPUAttributes {
110160

111161
} else {
112162

113-
this.device.queue.writeBuffer(
163+
device.queue.writeBuffer(
114164
buffer,
115165
0,
116166
array,
@@ -124,6 +174,14 @@ class WebGPUAttributes {
124174

125175
}
126176

177+
_destroyBuffers( { buffer, readBuffer } ) {
178+
179+
buffer.destroy();
180+
181+
if ( readBuffer !== null ) readBuffer.destroy();
182+
183+
}
184+
127185
}
128186

129187
export default WebGPUAttributes;

examples/jsm/renderers/webgpu/WebGPURenderer.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,12 @@ class WebGPURenderer {
384384

385385
}
386386

387+
async getArrayFromBuffer( attribute ) {
388+
389+
return await this._attributes.getArrayBuffer( attribute );
390+
391+
}
392+
387393
getContext() {
388394

389395
return this._context;
3.33 KB
Loading
26.6 KB
Binary file not shown.

0 commit comments

Comments
 (0)