ソースを参照

Added some texture testing code

Popov72 4 年 前
コミット
b96f14a3f0
2 ファイル変更108 行追加64 行削除
  1. 83 57
      src/Engines/WebGPU/webgpuTextureHelper.ts
  2. 25 7
      src/Engines/webgpuEngine.ts

+ 83 - 57
src/Engines/WebGPU/webgpuTextureHelper.ts

@@ -331,68 +331,94 @@ export class WebGPUTextureHelper {
 
         return new Promise((resolve) => {
             promise.then((imageBitmap) => {
-                // TODO WEBGPU For debugging only, we will need to clean this
-                if (width !== 25600) {
-                    this._device.defaultQueue.copyImageBitmapToTexture({ imageBitmap }, textureView, textureExtent);
-                } else {
-                    const useOwnCommandEncoder = commandEncoder === undefined;
+                this._device.defaultQueue.copyImageBitmapToTexture({ imageBitmap }, textureView, textureExtent);
+                resolve();
+            });
+        });
+    }
 
-                    if (useOwnCommandEncoder) {
-                        commandEncoder = this._device.createCommandEncoder({});
-                    }
+    public updateTextureTest(imageBitmap: ImageBitmap | HTMLCanvasElement, gpuTexture: GPUTexture, width: number, height: number, faceIndex: number = 0, mipLevel: number = 0, invertY = false, premultiplyAlpha = false, offsetX = 0, offsetY = 0,
+        commandEncoder?: GPUCommandEncoder): void
+    {
+        let promise: Promise<ImageBitmap | HTMLCanvasElement>;
 
-                    const bytesPerRow = Math.ceil(width * 4 / 256) * 256;
-
-                    let dataBuffer: DataBuffer;
-                    if (bytesPerRow === width * 4) {
-                        if (!(this as any)._data) {
-                            console.log("here", width, height);
-                            const canvas = new OffscreenCanvas(width, height);
-                            const ctx = canvas.getContext('2d')!;
-                            ctx.drawImage(imageBitmap, 0, 0, width, height);
-                            (this as any)._data = ctx.getImageData(0, 0, width, height).data;
-                            (this as any).dataBuffer = this._bufferManager.createBuffer((this as any)._data, WebGPUConstants.BufferUsage.CopySrc | WebGPUConstants.BufferUsage.CopyDst);
-                        }
-                        //dataBuffer = this._bufferManager.createBuffer((this as any)._data, WebGPUConstants.BufferUsage.CopySrc | WebGPUConstants.BufferUsage.CopyDst);
-                        const bufferView: GPUBufferCopyView = {
-                            buffer: (this as any).dataBuffer.underlyingResource,
-                            bytesPerRow: bytesPerRow,
-                            rowsPerImage: height,
-                            offset: 0,
-                        };
-                        commandEncoder!.copyBufferToTexture(bufferView, textureView, textureExtent);
-                        //dataBuffer.underlyingResource.destroy();
-                    } else {
-                        /*const alignedPixels = new Uint8Array(bytesPerRow * height);
-                        let pixelsIndex = 0;
-                        for (let y = 0; y < height; ++y) {
-                            for (let x = 0; x < width; ++x) {
-                                let i = x * 4 + y * bytesPerRow;
-
-                                alignedPixels[i] = (pixels as any)[pixelsIndex];
-                                alignedPixels[i + 1] = (pixels as any)[pixelsIndex + 1];
-                                alignedPixels[i + 2] = (pixels as any)[pixelsIndex + 2];
-                                alignedPixels[i + 3] = (pixels as any)[pixelsIndex + 3];
-                                pixelsIndex += 4;
-                            }
-                        }
-                        dataBuffer = this._bufferManager.createBuffer(alignedPixels, WebGPUConstants.BufferUsage.CopySrc | WebGPUConstants.BufferUsage.CopyDst);
-                        const bufferView: GPUBufferCopyView = {
-                            buffer: dataBuffer.underlyingResource,
-                            bytesPerRow: bytesPerRow,
-                            rowsPerImage: height,
-                            offset: 0,
-                        };
-                        commandEncoder!.copyBufferToTexture(bufferView, textureView, textureExtent);*/
-                    }
+        if ((invertY || premultiplyAlpha) && imageBitmap instanceof ImageBitmap) {
+            promise = createImageBitmap(imageBitmap, { imageOrientation: invertY ? "flipY" : "none", premultiplyAlpha: premultiplyAlpha ? "premultiply" : "none" });
+        } else {
+            promise = Promise.resolve(imageBitmap);
+        }
+
+        promise.then((imageBitmap) => {
+            const useOwnCommandEncoder = commandEncoder === undefined;
+
+            if (useOwnCommandEncoder) {
+                commandEncoder = this._device.createCommandEncoder({});
+            }
 
-                    if (useOwnCommandEncoder) {
-                        this._device.defaultQueue.submit([commandEncoder!.finish()]);
-                        commandEncoder = null as any;
+            const bytesPerRow = Math.ceil(width * 4 / 256) * 256;
+
+            if (bytesPerRow === width * 4) {
+                if (!(this as any).textureView || !(this as any).textureView[offsetX]) {
+                    console.log("updateTextureTest create texture view and extent", width, height);
+                    const textureView = {
+                        texture: gpuTexture,
+                        origin: {
+                            x: 0/*offsetX*/,
+                            y: offsetY,
+                            z: Math.max(faceIndex, 0)
+                        },
+                        mipLevel: mipLevel
+                    };
+                    const textureExtent = {
+                        width,
+                        height,
+                        depth: 1
+                    };
+                    if (!(this as any).textureView) {
+                        (this as any).textureView = [];
+                        (this as any).textureExtent = [];
                     }
+                    (this as any).textureView[offsetX] = textureView;
+                    (this as any).textureExtent[offsetX] = textureExtent;
                 }
-                resolve();
-            });
+                if (imageBitmap instanceof HTMLCanvasElement && (!(this as any).bufferView || !(this as any).bufferView[offsetX])) {
+                    console.log("updateTextureTest create data", width, height, offsetX);
+                    const canvas = imageBitmap as unknown as HTMLCanvasElement;
+                    const ctx = canvas.getContext('2d')!;
+                    const data = ctx.getImageData(0, 0, width, height).data;
+                    const dataBuffer = this._bufferManager.createBuffer(data, WebGPUConstants.BufferUsage.CopySrc | WebGPUConstants.BufferUsage.CopyDst);
+                    const bufferView: GPUBufferCopyView = {
+                        buffer: dataBuffer.underlyingResource,
+                        bytesPerRow: bytesPerRow,
+                        rowsPerImage: height,
+                        offset: 0,
+                    };
+                    if (!(this as any).bufferView) {
+                        (this as any).bufferView = [];
+                        (this as any).dataBuffer = [];
+                        (this as any).data = [];
+                    }
+                    (this as any).bufferView[offsetX] = bufferView;
+                    (this as any).dataBuffer[offsetX] = dataBuffer;
+                    (this as any).data[offsetX] = data;
+                }
+                if ((this as any).bufferView) {
+                    /*const canvas = imageBitmap as unknown as HTMLCanvasElement;
+                    const ctx = canvas.getContext('2d')!;
+                    const data = ctx.getImageData(0, 0, width, height).data;
+                    (this as any).data[offsetX] = data;*/
+                    //this._device.defaultQueue.writeTexture({ texture: gpuTexture }, (this as any).data[offsetX], { bytesPerRow }, (this as any).textureExtent[offsetX]);
+                    this._bufferManager.setSubData((this as any).dataBuffer[offsetX], 0, (this as any).data[offsetX]);
+                    commandEncoder!.copyBufferToTexture((this as any).bufferView[offsetX], (this as any).textureView[offsetX], (this as any).textureExtent[offsetX]);
+                } else {
+                    this._device.defaultQueue.copyImageBitmapToTexture({ imageBitmap: imageBitmap as ImageBitmap }, (this as any).textureView[offsetX], (this as any).textureExtent[offsetX]);
+                }
+            }
+
+            if (useOwnCommandEncoder) {
+                this._device.defaultQueue.submit([commandEncoder!.finish()]);
+                commandEncoder = null as any;
+            }
         });
     }
 }

+ 25 - 7
src/Engines/webgpuEngine.ts

@@ -1418,17 +1418,35 @@ export class WebGPUEngine extends Engine {
             gpuTexture = this._createGPUTextureForInternalTexture(texture, width, height);
         }
 
-        // TODO WEBGPU clean this, for testing purpose only
-        /*if (!(this as any)._bitmap) {
-            (this as any)._bitmap = createImageBitmap(canvas);
-        }*/
-
         // TODO WEBGPU: handle format if <> 0
         // let internalFormat = format ? this._getInternalFormat(format) : this._gl.RGBA;
 
+        // TODO WEBGPU remove test code
+        if (canvas.width === 2560) {
+            if ((this as any)._swap === undefined) { (this as any)._swap = 0; }
+            (this as any)._swap ^= 1;
+
+            const swap = (this as any)._swap;
+
+            if (!(this as any)._bitmap) {
+                createImageBitmap(canvas).then((imageBitmap) => {
+                    (this as any)._bitmap = imageBitmap;
+                });
+            }
+            if ((this as any)._bitmap) {
+                createImageBitmap(canvas).then((bitmap: ImageBitmap) => {
+                    this._textureHelper.updateTextureTest(bitmap, gpuTexture, width, height, 0, 0, invertY, premulAlpha, swap, 0, this._uploadEncoder);
+                    texture.isReady = true;
+                });
+            }
+            //this._textureHelper.updateTextureTest(canvas as HTMLCanvasElement, gpuTexture, width, height, 0, 0, invertY, premulAlpha, swap, 0, this._uploadEncoder);
+            //texture.isReady = true;
+            return;
+        }
+
         if (makeDynamicTextureUpdateSynchronous) {
             this._promisesFrame.push(new Promise((resolve) => {
-                /*(this as any)._bitmap*/createImageBitmap(canvas).then((bitmap) => {
+                createImageBitmap(canvas).then((bitmap) => {
                     this._textureHelper.updateTexture(bitmap, gpuTexture, width, height, 0, 0, invertY, premulAlpha, 0, 0, this._uploadEncoder).then(() => {
                         if (texture.generateMipMaps) {
                             this._generateMipmaps(texture, gpuTexture);
@@ -1441,7 +1459,7 @@ export class WebGPUEngine extends Engine {
             }));
         } else {
             createImageBitmap(canvas).then((bitmap) => {
-                /*(this as any)._bitmap*/this._textureHelper.updateTexture(bitmap, gpuTexture, width, height, 0, 0, invertY, premulAlpha, 0, 0, this._uploadEncoder);
+                this._textureHelper.updateTexture(bitmap, gpuTexture, width, height, 0, 0, invertY, premulAlpha, 0, 0, this._uploadEncoder);
                 if (texture.generateMipMaps) {
                     this._generateMipmaps(texture, gpuTexture);
                 }