Browse Source

Fix readPixels when bytesPerRow not multiple of 256

Popov72 4 năm trước cách đây
mục cha
commit
5d6d066a80

+ 16 - 1
src/Engines/WebGPU/webgpuBufferManager.ts

@@ -110,7 +110,7 @@ export class WebGPUBufferManager {
         return destArray;
     }
 
-    public readDataFromBuffer(gpuBuffer: GPUBuffer, size: number, width: number, height: number, floatFormat = 0, offset = 0, buffer: Nullable<ArrayBufferView> = null, destroyBuffer = true): Promise<ArrayBufferView> {
+    public readDataFromBuffer(gpuBuffer: GPUBuffer, size: number, width: number, height: number, bytesPerRow: number, bytesPerRowAlignedAligned: number, floatFormat = 0, offset = 0, buffer: Nullable<ArrayBufferView> = null, destroyBuffer = true): Promise<ArrayBufferView> {
         return new Promise((resolve, reject) => {
             gpuBuffer.mapAsync(GPUMapMode.READ, offset, size).then(() => {
                 const copyArrayBuffer = gpuBuffer.getMappedRange(offset, size);
@@ -144,6 +144,21 @@ export class WebGPUBufferManager {
                             break;
                     }
                 }
+                if (bytesPerRow !== bytesPerRowAlignedAligned) {
+                    const data2: Uint8Array = data as Uint8Array;
+                    let offset = bytesPerRow, offset2 = 0;
+                    for (let y = 1; y < height; ++y) {
+                        offset2 = y * bytesPerRowAlignedAligned;
+                        for (let x = 0; x < bytesPerRow; ++x) {
+                            data2[offset++] = data2[offset2++];
+                        }
+                    }
+                    if (floatFormat !== 0) {
+                        data = new Float32Array(data2.buffer, 0, offset / 4);
+                    } else {
+                        data = new Uint8Array(data2.buffer, 0, offset);
+                    }
+                }
                 gpuBuffer.unmap();
                 if (destroyBuffer) {
                     this.releaseBuffer(gpuBuffer);

+ 6 - 3
src/Engines/WebGPU/webgpuTextureHelper.ts

@@ -525,7 +525,10 @@ export class WebGPUTextureHelper {
         const blockInformation = this._getBlockInformationFromFormat(format);
 
         const bytesPerRow = Math.ceil(width / blockInformation.width) * blockInformation.length;
-        const size = bytesPerRow * height;
+
+        const bytesPerRowAligned = Math.ceil(bytesPerRow / 256) * 256;
+
+        const size = bytesPerRowAligned * height;
 
         const gpuBuffer = this._bufferManager.createRawBuffer(size, GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST);
 
@@ -542,7 +545,7 @@ export class WebGPUTextureHelper {
         }, {
             buffer: gpuBuffer,
             offset: 0,
-            bytesPerRow
+            bytesPerRow: bytesPerRowAligned
         }, {
             width,
             height,
@@ -554,6 +557,6 @@ export class WebGPUTextureHelper {
         const type = this._getTextureTypeFromFormat(format);
         const floatFormat = type === Constants.TEXTURETYPE_FLOAT ? 2 : type === Constants.TEXTURETYPE_HALF_FLOAT ? 1 : 0;
 
-        return this._bufferManager.readDataFromBuffer(gpuBuffer, size, width, height, floatFormat, 0, buffer);
+        return this._bufferManager.readDataFromBuffer(gpuBuffer, size, width, height, bytesPerRow, bytesPerRowAligned, floatFormat, 0, buffer);
     }
 }