* Reads data from a storage buffer back into JavaScript. * * Copies data from the GPU to the CPU using a temporary buffer, * so it must be awaited. Returns a `Float32Array` for number * buffers, or an array of plain objects for struct buffers. * * Note: This is a GPU -
()
| 219 | * @returns {Promise<Float32Array|Object[]>} |
| 220 | */ |
| 221 | async read() { |
| 222 | const device = this._renderer.device; |
| 223 | this._renderer.flushDraw(); |
| 224 | |
| 225 | const stagingBuffer = device.createBuffer({ |
| 226 | size: this.size, |
| 227 | usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ, |
| 228 | }); |
| 229 | |
| 230 | const commandEncoder = device.createCommandEncoder(); |
| 231 | commandEncoder.copyBufferToBuffer(this.buffer, 0, stagingBuffer, 0, this.size); |
| 232 | device.queue.submit([commandEncoder.finish()]); |
| 233 | |
| 234 | await stagingBuffer.mapAsync(GPUMapMode.READ, 0, this.size); |
| 235 | const mappedRange = stagingBuffer.getMappedRange(0, this.size); |
| 236 | |
| 237 | // Copy before unmapping because mapped memory becomes invalid after unmap |
| 238 | const rawCopy = new Float32Array(mappedRange.byteLength / 4); |
| 239 | rawCopy.set(new Float32Array(mappedRange)); |
| 240 | |
| 241 | stagingBuffer.unmap(); |
| 242 | stagingBuffer.destroy(); |
| 243 | |
| 244 | if (this._schema !== null) { |
| 245 | return this._renderer._unpackStructArray(rawCopy, this._schema); |
| 246 | } |
| 247 | return rawCopy; |
| 248 | } |
| 249 | |
| 250 | /** |
| 251 | * Updates a single element in the buffer at a given index. Use this |
no test coverage detected