From 4b2c3dd8ef0417fab7c224c1622bd436ac47cee2 Mon Sep 17 00:00:00 2001 From: Xu Xing Date: Tue, 25 Aug 2020 16:29:18 +0800 Subject: [PATCH] Add case to reproduce writeTexture and rowsPerImage issue --- demo/common.js | 3 ++ demo/index_add.js | 6 ++- src/texture.ts | 125 +++++++++++++++++++++++----------------------- 3 files changed, 70 insertions(+), 64 deletions(-) diff --git a/demo/common.js b/demo/common.js index 31f5f89..47c9172 100644 --- a/demo/common.js +++ b/demo/common.js @@ -167,6 +167,9 @@ export async function runTestAdd(device, glslang, size_x = 4096, size_y = 256, t device, glslang, firstMatrix, secondMatrix, size_x, size_y, shape); if (error) return; } + if (trials == 0) { + return; + } { const addOp = new compute.AddBufferOp( diff --git a/demo/index_add.js b/demo/index_add.js index 9c51d04..3322dee 100644 --- a/demo/index_add.js +++ b/demo/index_add.js @@ -14,6 +14,8 @@ import * as common from './common.js'; const enableTimeStamp = false; const device = await adapter.requestDevice(); const glslang = await glslangInit(); - await common.runTestAdd(device, glslang, 4096, 256, 50,50); - await common.runTestAdd(device, glslang, 4096, 1024, 50,50); + await common.runTestAdd(device, glslang, 4096, 128, 0,0); + await common.runTestAdd(device, glslang, 4096, 256, 0,0); + await common.runTestAdd(device, glslang, 4096, 512, 0,0); + await common.runTestAdd(device, glslang, 4096, 1024, 0,0); })(); \ No newline at end of file diff --git a/src/texture.ts b/src/texture.ts index e55e2b9..831c967 100644 --- a/src/texture.ts +++ b/src/texture.ts @@ -28,8 +28,58 @@ export class TextureOp { this.bufferID = 0; } - private copyFromHostBufferToDeviceTexture( - src: GPUBuffer, width: number, height: number) { + // From: Dawn:ComputeTextureCopyBufferSize + // TODO: Make this works with different input size + getBufferSize() { + const blockHeight = 1; + const blockWidth = 1; + + const [widthTex, heightTex] = + tex_util.getPackedMatrixTextureShapeWidthHeight( + this.shape[0], this.shape[1], this.format); + + const bytesPerRow = tex_util.getBytesPerRow(widthTex, this.kBytesPerTexel); + + const sliceSize = bytesPerRow * (heightTex / blockHeight - 1) + + (widthTex / blockWidth) * this.kBytesPerTexel; + return sliceSize; + } + + /* + private writeTexture( + data: Float32Array|Uint32Array, width: number, height: number) { + const [widthTex, heightTex] = + tex_util.getPackedMatrixTextureShapeWidthHeight( + width, height, this.format); + + const texture = this.device.createTexture({ + size: {width: widthTex, height: heightTex, depth: 1}, + format: this.format, + usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC | + GPUTextureUsage.STORAGE + }); + + const bytesPerRow = tex_util.getBytesPerRow(widthTex, this.kBytesPerTexel); + console.log(heightTex); + this.queue.writeTexture( + {texture: texture}, data as ArrayBuffer, + {bytesPerRow: bytesPerRow}, // heightTex + {width: widthTex, height: heightTex, depth: 1}); + return texture; + } + */ + + private writeTextureWithCopy( + matrixData: Float32Array|Uint32Array, width: number, height: number) { + const src = this.device.createBuffer({ + mappedAtCreation: true, + size: this.getBufferSize(), + usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | + GPUBufferUsage.COPY_DST + }); + // TODO: turn this into type of secondMatrix. + new Float32Array(src.getMappedRange()).set(matrixData); + src.unmap(); const [widthTex, heightTex] = tex_util.getPackedMatrixTextureShapeWidthHeight( width, height, this.format); @@ -53,77 +103,26 @@ export class TextureOp { return texture; } - // From: Dawn:ComputeTextureCopyBufferSize - // TODO: Make this works with different input size - getBufferSize() { - const blockHeight = 1; - const blockWidth = 1; - - const [widthTex, heightTex] = - tex_util.getPackedMatrixTextureShapeWidthHeight( - this.shape[0], this.shape[1], this.format); - - const bytesPerRow = tex_util.getBytesPerRow(widthTex, this.kBytesPerTexel); - - const sliceSize = bytesPerRow * (heightTex / blockHeight - 1) + - (widthTex / blockWidth) * this.kBytesPerTexel; - return sliceSize; - } - compile( firstMatrix: Float32Array|Uint32Array, secondMatrix: Float32Array|Uint32Array, shape: Uint32Array, computeShaderCode: any) { this.shape = shape; - // console.log('B2T this.getBufferSize()=' + this.getBufferSize()); + + const gpuTextureFirstMatrix = + this.writeTextureWithCopy(firstMatrix, this.shape[0], this.shape[1]); /* - const [gpuBufferFirstMatrix, arrayBufferFirstMatrix] = - this.device.createBufferMapped({ - size: this.getBufferSize(), // (firstMatrix as - // Float32Array).byteLength, - usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | - GPUBufferUsage.COPY_DST - }); - new Float32Array(arrayBufferFirstMatrix).set(firstMatrix); - gpuBufferFirstMatrix.unmap(); + const gpuTextureFirstMatrix = + this.writeTexture(firstMatrix, this.shape[2], this.shape[3]); */ - const gpuBufferFirstMatrix = this.device.createBuffer({ - mappedAtCreation: true, - size: this.getBufferSize(), - usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | - GPUBufferUsage.COPY_DST - }); - // TODO: turn this into type of secondMatrix. - new Float32Array(gpuBufferFirstMatrix.getMappedRange()).set(firstMatrix); - gpuBufferFirstMatrix.unmap(); - - const gpuTextureFirstMatrix = this.copyFromHostBufferToDeviceTexture( - gpuBufferFirstMatrix, this.shape[0], this.shape[1]); + const gpuTextureSecondMatrix = + this.writeTextureWithCopy(secondMatrix, this.shape[2], this.shape[3]); /* - const [gpuBufferSecondMatrix, arrayBufferSecondMatrix] = - this.device.createBufferMapped({ - size: this.getBufferSize(), //(secondMatrix as - // Float32Array).byteLength, - usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | - GPUBufferUsage.COPY_DST - }); - new Float32Array(arrayBufferSecondMatrix).set(secondMatrix); - gpuBufferSecondMatrix.unmap(); + const gpuTextureSecondMatrix = + this.writeTexture(secondMatrix, this.shape[2], this.shape[3]); */ - const gpuBufferSecondMatrix = this.device.createBuffer({ - mappedAtCreation: true, - size: this.getBufferSize(), - usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | - GPUBufferUsage.COPY_DST - }); - // TODO: turn this into type of secondMatrix. - new Float32Array(gpuBufferSecondMatrix.getMappedRange()).set(secondMatrix); - gpuBufferSecondMatrix.unmap(); - - const gpuTextureSecondMatrix = this.copyFromHostBufferToDeviceTexture( - gpuBufferSecondMatrix, this.shape[2], this.shape[3]); // Result Matrix. this.resultMatrixTextureSize = @@ -147,6 +146,8 @@ export class TextureOp { new Uint32Array(shapeMapping).set(shape); shapeBuffer.unmap(); */ + + // TODO: make this buffer.destroy automatically! const shapeBuffer = this.device.createBuffer({ mappedAtCreation: true, size: shape.byteLength,