소스 검색

Merge pull request #8648 from ottoville/WebGPU

Remove deprecated createBufferMapped
sebavan 5 년 전
부모
커밋
a31577a7bb
3개의 변경된 파일39개의 추가작업 그리고 39개의 파일을 삭제
  1. 3 0
      src/Engines/WebGPU/webgpuConstants.ts
  2. 34 38
      src/Engines/webgpuEngine.ts
  3. 2 1
      src/LibDeclarations/webgpu.d.ts

+ 3 - 0
src/Engines/WebGPU/webgpuConstants.ts

@@ -123,6 +123,9 @@ export class WebGPUConstants {
     public static readonly GPUBufferUsage_STORAGE = 128;
     public static readonly GPUBufferUsage_INDIRECT = 256;
 
+    public static readonly GPUMapMode_READ = 1;
+    public static readonly GPUMapMode_WRITE = 2;
+
     public static readonly GPUColorWriteBits_NONE = 0;
     public static readonly GPUColorWriteBits_RED = 1;
     public static readonly GPUColorWriteBits_GREEN = 2;

+ 34 - 38
src/Engines/webgpuEngine.ts

@@ -519,27 +519,19 @@ export class WebGPUEngine extends Engine {
             throw new Error("Unable to create WebGPU buffer: cannot create zero-sized buffer"); // Zero size buffer would kill the tab in chrome
         }
         const padding = view.byteLength % 4;
-
+        const mappedAtCreation: boolean = padding == 0 && view.byteLength < this._maxBufferChunk;
         const verticesBufferDescriptor = {
-            size: view.byteLength + padding,
-            usage: flags
-        };
-        let buffer: GPUBuffer;
-        let arrBuffer: Nullable<ArrayBuffer> = null;
-        if (padding == 0 && view.byteLength < this._maxBufferChunk) {
-            [buffer, arrBuffer] = this._device.createBufferMapped(verticesBufferDescriptor);
-        }
-        else {
-            buffer = this._device.createBuffer(verticesBufferDescriptor);
-        }
-
+                size: view.byteLength + padding,
+                usage: flags,
+                mappedAtCreation
+            };
+       const buffer = this._device.createBuffer(verticesBufferDescriptor);
         const dataBuffer = new WebGPUDataBuffer(buffer);
         dataBuffer.references = 1;
         dataBuffer.capacity = view.byteLength;
-        if (arrBuffer) {
-            const outputView = new Uint8Array(arrBuffer);
-            const inputView = new Uint8Array(view.buffer, view.byteOffset, view.byteLength);
-            outputView.set(inputView);
+        if (mappedAtCreation) {
+            const range = buffer.getMappedRange();
+            new Uint8Array(range).set(new Uint8Array(view.buffer, view.byteOffset, view.byteLength));
             buffer.unmap();
         } else {
             this._setSubData(dataBuffer, 0, view);
@@ -574,31 +566,35 @@ export class WebGPUEngine extends Engine {
 
         // Chunk
         const commandEncoder = this._device.createCommandEncoder();
-        const tempBuffers: GPUBuffer[] = [];
-        try {
-            for (let offset = 0; offset < src.byteLength; offset += this._maxBufferChunk) {
-                const uploadCount = Math.min(src.byteLength - offset, this._maxBufferChunk);
-                if (uploadCount == 0) {
-                    throw new Error("Cannot create zero-sized buffer"); // Zero size buffer would kill the tab in chrome
+        if (byteLength - srcByteOffset < 1) {
+            throw new Error("Cannot create zero-sized buffer"); // 0 size buffer would kill the tab in chrome
+        }
+        const uploadBuffer = this._device.createBuffer({
+            usage: WebGPUConstants.GPUBufferUsage_TRANSFER_SRC | WebGPUConstants.GPUBufferUsage_MAP_WRITE,
+            size: byteLength - srcByteOffset
+        });
+
+        (async() => {
+            try {
+                for (let offset = 0; offset < byteLength; offset += this._maxBufferChunk) {
+                    const uploadCount = Math.min(byteLength - offset, this._maxBufferChunk);
+                    await uploadBuffer.mapAsync(WebGPUConstants.GPUMapMode_WRITE, offset, uploadCount);
+                    const uploadMapping = uploadBuffer.getMappedRange();
+
+                    new Uint8Array(uploadMapping).set(new Uint8Array(src.buffer, srcByteOffset + offset, uploadCount));
+                    uploadBuffer.unmap();
                 }
-                const [uploadBuffer, uploadMapping] = this._device.createBufferMapped({
-                    usage: WebGPUConstants.GPUBufferUsage_TRANSFER_SRC,
-                    size: uploadCount,
-                });
-                tempBuffers.push(uploadBuffer);
-                new Uint8Array(uploadMapping).set(new Uint8Array(src.buffer, srcByteOffset + offset, uploadCount));
-                uploadBuffer.unmap();
                 commandEncoder.copyBufferToBuffer(
                     uploadBuffer, 0,
-                    buffer, dstByteOffset + offset,
-                    uploadCount);
+                    buffer, dstByteOffset,
+                    byteLength);
+                this._device.defaultQueue.submit([commandEncoder.finish()]);
+            } catch (e) {
+                Logger.Error(e);
+            } finally {
+                uploadBuffer.destroy();
             }
-            this._device.defaultQueue.submit([commandEncoder.finish()]);
-        } catch (e) {
-            Logger.Error('Unable to update WebGPU buffer: ' + e);
-        } finally {
-            tempBuffers.forEach((buff) => buff.destroy());
-        }
+        })();
     }
 
     //------------------------------------------------------------------------------

+ 2 - 1
src/LibDeclarations/webgpu.d.ts

@@ -497,7 +497,8 @@ declare class GPUBuffer implements GPUObjectBase {
   //readonly mapping: ArrayBuffer | null;
   destroy(): void;
   unmap(): void;
-
+  mapAsync(mode:number, offset?:number, size?: number): Promise<void>;
+  getMappedRange(offset?:number, size?:number): ArrayBuffer;
   mapWriteAsync(): Promise<ArrayBuffer>;
   mapReadAsync(): Promise<ArrayBuffer>;
   // TODO: Remove setSubData (#280)