From e55f7da6ecb54e326fa5de09b058dd691c3ac166 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 23 Jul 2026 18:41:15 +0000 Subject: [PATCH 1/2] webgpu: avoid mappedAtCreation staging upload --- .../lib/wasm/jsep/webgpu/gpu-data-manager.ts | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/js/web/lib/wasm/jsep/webgpu/gpu-data-manager.ts b/js/web/lib/wasm/jsep/webgpu/gpu-data-manager.ts index 1c6016500e7d3..5faa3a1213f39 100644 --- a/js/web/lib/wasm/jsep/webgpu/gpu-data-manager.ts +++ b/js/web/lib/wasm/jsep/webgpu/gpu-data-manager.ts @@ -237,22 +237,9 @@ class GpuDataManagerImpl implements GpuDataManager { throw new Error(`inconsistent data size. gpu data size=${gpuDataCache.originalSize}, data size=${srcLength}`); } - // create gpu buffer - const gpuBufferForUploading = this.backend.device.createBuffer( - // eslint-disable-next-line no-bitwise - { mappedAtCreation: true, size, usage: GPUBufferUsage.MAP_WRITE | GPUBufferUsage.COPY_SRC }, - ); - - // copy (upload) data - const arrayBuffer = gpuBufferForUploading.getMappedRange(); - new Uint8Array(arrayBuffer).set(new Uint8Array(srcArrayBuffer, srcOffset, srcLength)); - gpuBufferForUploading.unmap(); - - // GPU copy - const commandEncoder = this.backend.device.createCommandEncoder(); - commandEncoder.copyBufferToBuffer(gpuBufferForUploading, 0, gpuDataCache.gpuData.buffer, 0, size); - this.backend.device.queue.submit([commandEncoder.finish()]); - gpuBufferForUploading.destroy(); + const uploadData = new Uint8Array(size); + uploadData.set(new Uint8Array(srcArrayBuffer, srcOffset, srcLength)); + this.backend.device.queue.writeBuffer(gpuDataCache.gpuData.buffer, 0, uploadData, 0, size); LOG_DEBUG('verbose', () => `[WebGPU] GpuDataManager.upload(id=${id})`); } From df704997ad326f5170d94c3527ebaf83ca46c3d8 Mon Sep 17 00:00:00 2001 From: Tianlei Wu Date: Thu, 23 Jul 2026 15:08:37 -0700 Subject: [PATCH 2/2] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- js/web/lib/wasm/jsep/webgpu/gpu-data-manager.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/js/web/lib/wasm/jsep/webgpu/gpu-data-manager.ts b/js/web/lib/wasm/jsep/webgpu/gpu-data-manager.ts index 5faa3a1213f39..ecdcb8cae11c6 100644 --- a/js/web/lib/wasm/jsep/webgpu/gpu-data-manager.ts +++ b/js/web/lib/wasm/jsep/webgpu/gpu-data-manager.ts @@ -237,9 +237,14 @@ class GpuDataManagerImpl implements GpuDataManager { throw new Error(`inconsistent data size. gpu data size=${gpuDataCache.originalSize}, data size=${srcLength}`); } - const uploadData = new Uint8Array(size); - uploadData.set(new Uint8Array(srcArrayBuffer, srcOffset, srcLength)); - this.backend.device.queue.writeBuffer(gpuDataCache.gpuData.buffer, 0, uploadData, 0, size); + if (size === srcLength && srcOffset % 4 === 0) { + // Fast path: already aligned; avoid allocating/copying a padded buffer. + this.backend.device.queue.writeBuffer(gpuDataCache.gpuData.buffer, 0, srcArrayBuffer, srcOffset, srcLength); + } else { + const uploadData = new Uint8Array(size); + uploadData.set(data); + this.backend.device.queue.writeBuffer(gpuDataCache.gpuData.buffer, 0, uploadData, 0, size); + } LOG_DEBUG('verbose', () => `[WebGPU] GpuDataManager.upload(id=${id})`); }