[emscripten] More fixes for passing pointers and i64s - Change emwgpuWaitAny to return `double` as a workaround for https://github.com/emscripten-core/emscripten/issues/23441 - Fix a bunch more pointer/i64 values that need to be BigInt in WASM_BIGINT/MEMORY64 builds. Found these just by searching for '0' or 'stringToUTF8OnStack', probably missed some. I tested a few by triggering error conditions but most are untested. - A few random nits. Tested with 40 different build configurations: https://github.com/kainino0x/webgpu-cross-platform-demo/blob/5675031561e4134b2467cd2b7f054c32776001d3/build_all.sh#L60-L78 Bug: 389977397 No-Try: true Change-Id: I0af67a347351be7002fc25e2157e3767f1e25be3 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/222314 Commit-Queue: Kai Ninomiya <kainino@chromium.org> Reviewed-by: Loko Kung <lokokung@google.com>
diff --git a/third_party/emdawnwebgpu/library_webgpu.js b/third_party/emdawnwebgpu/library_webgpu.js index 550c062..41de0a5 100644 --- a/third_party/emdawnwebgpu/library_webgpu.js +++ b/third_party/emdawnwebgpu/library_webgpu.js
@@ -18,9 +18,11 @@ // Helper functions for code generation globalThis.gpu = { - convertSentinelToUndefined: function(name, argIsPassedAsPointerType) { - // When `CAN_ADDRESS_2GB` is true, value `-1` is normalized to `0xFFFFFFFF` for pointer. - if (CAN_ADDRESS_2GB && argIsPassedAsPointerType) { + convertSentinelToUndefined: function(name, argIsSizeT) { + // The sentinel value SIZE_MAX is passed as a "p" (pointer) arg, so it comes through as + // either `0xFFFFFFFF` or `-1` depending on whether `CAN_ADDRESS_2GB` is enabled. + if (CAN_ADDRESS_2GB && argIsSizeT) { + // Note CAN_ADDRESS_2GB is always false for MEMORY64 builds. return `if (${name} == 0xFFFFFFFF) ${name} = undefined;`; } else { return `if (${name} == -1) ${name} = undefined;`; @@ -163,11 +165,12 @@ {{{ gpu.makeImportJsObject('Texture') }}} {{{ gpu.makeImportJsObject('TextureView') }}} + // TODO(crbug.com/42241415): Remove this after verifying that it's not used and/or updating users. errorCallback__deps: ['$stackSave', '$stackRestore', '$stringToUTF8OnStack'], errorCallback: (callback, type, message, userdata) => { var sp = stackSave(); var messagePtr = stringToUTF8OnStack(message); - {{{ makeDynCall('vipp', 'callback') }}}(type, messagePtr, userdata); + {{{ makeDynCall('vipp', 'callback') }}}(type, {{{ gpu.passAsPointer('messagePtr') }}}, userdata); stackRestore(sp); }, @@ -558,7 +561,7 @@ {{{ WEBGPU_INT_TO_STRING_TABLES }}} }, - // TODO(374150686): Remove this once it has been fully deprecated in users. + // TODO(crbug.com/374150686): Remove this once it has been fully deprecated in users. emscripten_webgpu_get_device__deps: ['wgpuDeviceAddRef'], emscripten_webgpu_get_device: () => { #if ASSERTIONS @@ -617,7 +620,7 @@ const firstResolvedFuture = await Promise.race(promises); delete WebGPU.Internals.futures[firstResolvedFuture]; - return {{{ gpu.passAsI64('firstResolvedFuture') }}}; + return firstResolvedFuture; }), #else emwgpuWaitAny: () => { @@ -822,7 +825,8 @@ device.onuncapturederror = (ev) => {}; var sp = stackSave(); var messagePtr = stringToUTF8OnStack(info.message); - _emwgpuOnDeviceLostCompleted(deviceLostFutureId, WebGPU.Int_DeviceLostReason[info.reason], messagePtr); + _emwgpuOnDeviceLostCompleted(deviceLostFutureId, WebGPU.Int_DeviceLostReason[info.reason], + {{{ gpu.passAsPointer('messagePtr') }}}); stackRestore(sp); })); } @@ -840,7 +844,7 @@ else if (ev.error instanceof GPUInternalError) type = {{{ gpu.ErrorType.Internal }}}; var sp = stackSave(); var messagePtr = stringToUTF8OnStack(ev.error.message); - _emwgpuOnUncapturedError(devicePtr, type, messagePtr); + _emwgpuOnUncapturedError(devicePtr, type, {{{ gpu.passAsPointer('messagePtr') }}}); stackRestore(sp); }; @@ -850,9 +854,11 @@ {{{ runtimeKeepalivePop() }}} var sp = stackSave(); var messagePtr = stringToUTF8OnStack(ex.message); - _emwgpuOnRequestDeviceCompleted(futureId, {{{ gpu.RequestDeviceStatus.Error }}}, devicePtr, messagePtr); + _emwgpuOnRequestDeviceCompleted(futureId, {{{ gpu.RequestDeviceStatus.Error }}}, + {{{ gpu.passAsPointer('devicePtr') }}}, {{{ gpu.passAsPointer('messagePtr') }}}); if (deviceLostFutureId) { - _emwgpuOnDeviceLostCompleted(deviceLostFutureId, {{{ gpu.DeviceLostReason.FailedCreation }}}, messagePtr); + _emwgpuOnDeviceLostCompleted(deviceLostFutureId, {{{ gpu.DeviceLostReason.FailedCreation }}}, + {{{ gpu.passAsPointer('messagePtr') }}}); } stackRestore(sp); })); @@ -976,7 +982,7 @@ ex.name === 'AbortError' ? {{{ gpu.MapAsyncStatus.Aborted }}} : ex.name === 'OperationError' ? {{{ gpu.MapAsyncStatus.Error }}} : {{{ gpu.MapAsyncStatus.Unknown }}}; - _emwgpuOnMapAsyncCompleted(futureId, status, messagePtr); + _emwgpuOnMapAsyncCompleted(futureId, status, {{{ gpu.passAsPointer('messagePtr') }}}); delete WebGPU.Internals.bufferOnUnmaps[bufferPtr]; })); }, @@ -1532,7 +1538,8 @@ {{{ runtimeKeepalivePop() }}} var pipelinePtr = _emwgpuCreateComputePipeline({{{ gpu.NULLPTR }}}); WebGPU.Internals.jsObjectInsert(pipelinePtr, pipeline); - _emwgpuOnCreateComputePipelineCompleted(futureId, {{{ gpu.CreatePipelineAsyncStatus.Success }}}, pipelinePtr, 0); + _emwgpuOnCreateComputePipelineCompleted(futureId, {{{ gpu.CreatePipelineAsyncStatus.Success }}}, + {{{ gpu.passAsPointer('pipelinePtr') }}}, {{{ gpu.NULLPTR }}}); }, (pipelineError) => { {{{ runtimeKeepalivePop() }}} var sp = stackSave(); @@ -1541,7 +1548,8 @@ pipeline.reason === 'validation' ? {{{ gpu.CreatePipelineAsyncStatus.ValidationError }}} : pipeline.reason === 'internal' ? {{{ gpu.CreatePipelineAsyncStatus.InternalError }}} : {{{ gpu.CreatePipelineAsyncStatus.Unknown }}}; - _emwgpuOnCreateComputePipelineCompleted(futureId, status, 0, messagePtr); + _emwgpuOnCreateComputePipelineCompleted(futureId, status, + {{{ gpu.NULLPTR }}}, {{{ gpu.passAsPointer('messagePtr') }}}); stackRestore(sp); })); }, @@ -1649,7 +1657,8 @@ pipeline.reason === 'validation' ? {{{ gpu.CreatePipelineAsyncStatus.ValidationError }}} : pipeline.reason === 'internal' ? {{{ gpu.CreatePipelineAsyncStatus.InternalError }}} : {{{ gpu.CreatePipelineAsyncStatus.Unknown }}}; - _emwgpuOnCreateRenderPipelineCompleted(futureId, status, 0, messagePtr); + _emwgpuOnCreateRenderPipelineCompleted(futureId, status, + {{{ gpu.NULLPTR }}}, {{{ gpu.passAsPointer('messagePtr') }}}); stackRestore(sp); })); }, @@ -1838,13 +1847,17 @@ #endif var sp = stackSave(); var messagePtr = gpuError ? stringToUTF8OnStack(gpuError.message) : 0; - _emwgpuOnPopErrorScopeCompleted(futureId, {{{ gpu.PopErrorScopeStatus.Success }}}, type, messagePtr); + _emwgpuOnPopErrorScopeCompleted(futureId, + {{{ gpu.PopErrorScopeStatus.Success }}}, type, + {{{ gpu.passAsPointer('messagePtr') }}}); stackRestore(sp); }, (ex) => { {{{ runtimeKeepalivePop() }}} var sp = stackSave(); var messagePtr = stringToUTF8OnStack(ex.message); - _emwgpuOnPopErrorScopeCompleted(futureId, {{{ gpu.PopErrorScopeStatus.Success }}}, {{{ gpu.ErrorType.Unknown }}}, messagePtr); + _emwgpuOnPopErrorScopeCompleted(futureId, + {{{ gpu.PopErrorScopeStatus.Success }}}, {{{ gpu.ErrorType.Unknown }}}, + {{{ gpu.passAsPointer('messagePtr') }}}); stackRestore(sp); })); }, @@ -1854,7 +1867,7 @@ device.pushErrorScope(WebGPU.ErrorFilter[filter]); }, - // TODO(42241415) Remove this after verifying that it's not used and/or updating users. + // TODO(crbug.com/42241415): Remove this after verifying that it's not used and/or updating users. wgpuDeviceSetUncapturedErrorCallback__deps: ['$callUserCallback'], wgpuDeviceSetUncapturedErrorCallback: (devicePtr, callback, userdata) => { var device = WebGPU.getJsObject(devicePtr); @@ -1941,7 +1954,8 @@ if (!('gpu' in navigator)) { var sp = stackSave(); var messagePtr = stringToUTF8OnStack('WebGPU not available on this browser (navigator.gpu is not available)'); - _emwgpuOnRequestAdapterCompleted(futureId, {{{ gpu.RequestAdapterStatus.Unavailable }}}, 0, messagePtr); + _emwgpuOnRequestAdapterCompleted(futureId, {{{ gpu.RequestAdapterStatus.Unavailable }}}, + {{{ gpu.NULLPTR }}}, {{{ gpu.passAsPointer('messagePtr') }}}); stackRestore(sp); return; } @@ -1957,14 +1971,16 @@ } else { var sp = stackSave(); var messagePtr = stringToUTF8OnStack('WebGPU not available on this browser (requestAdapter returned null)'); - _emwgpuOnRequestAdapterCompleted(futureId, {{{ gpu.RequestAdapterStatus.Unavailable }}}, 0, messagePtr); + _emwgpuOnRequestAdapterCompleted(futureId, {{{ gpu.RequestAdapterStatus.Unavailable }}}, + {{{ gpu.NULLPTR }}}, {{{ gpu.passAsPointer('messagePtr') }}}); stackRestore(sp); } }, (ex) => { {{{ runtimeKeepalivePop() }}} var sp = stackSave(); var messagePtr = stringToUTF8OnStack(ex.message); - _emwgpuOnRequestAdapterCompleted(futureId, {{{ gpu.RequestAdapterStatus.Error }}}, 0, messagePtr); + _emwgpuOnRequestAdapterCompleted(futureId, {{{ gpu.RequestAdapterStatus.Error }}}, + {{{ gpu.NULLPTR }}}, {{{ gpu.passAsPointer('messagePtr') }}}); stackRestore(sp); })); },
diff --git a/third_party/emdawnwebgpu/webgpu.cpp b/third_party/emdawnwebgpu/webgpu.cpp index 12601e2..ca52b12 100644 --- a/third_party/emdawnwebgpu/webgpu.cpp +++ b/third_party/emdawnwebgpu/webgpu.cpp
@@ -37,9 +37,9 @@ // Note that for the JS entry points, we pass uint64_t as pointer and decode it // on the other side. -FutureID emwgpuWaitAny(FutureID const* futurePtr, - size_t futureCount, - uint64_t const* timeoutNSPtr); +double emwgpuWaitAny(FutureID const* futurePtr, + size_t futureCount, + uint64_t const* timeoutNSPtr); WGPUTextureFormat emwgpuGetPreferredFormat(); // Device functions, i.e. creation functions to create JS backing objects given @@ -479,8 +479,8 @@ } bool hasTimeout = timeoutNS != UINT64_MAX; - FutureID completedId = emwgpuWaitAny(futures.data(), count, - hasTimeout ? &timeoutNS : nullptr); + FutureID completedId = static_cast<FutureID>(emwgpuWaitAny( + futures.data(), count, hasTimeout ? &timeoutNS : nullptr)); if (completedId == kNullFutureId) { return WGPUWaitStatus_TimedOut; }