Early access to the new WebGPU backend in Unity 2023.3

Hey,

I compared my settings with yours and we have the same ones except compression. The bug report to Chrome was fixed in version 128 smth and since then I can run more than 2 GB so it was fixed for me. I’ve also updated Chrome to an even later version (129.0.6668.59) and it still works - so may be something else on your side that’s crashing it?

1 Like

Great to know! thanks for the update.
Ya it’s super weird. When the heap goes beyond 2GB after loading in addressable assets, it starts causing errors with network calls of Mirror. And when a little more addressable assets are loaded, it crashes.
I’ll investigate further, and report back.

Hello @brendanduncan_u3d! I’ve run into a couple of crashes in WebGPU builds that would be interesting to get some insight on. The traces are attached below.

Uncaught TypeError: Failed to execute 'writeBuffer' on 'GPUQueue': Value is outside the 'unsigned long long' value range.
    at _wgpu_queue_write_buffer (https://localhost:8141/Build/[REMOVED]_BUILDS.framework.js:14800:28)
    at BufferWebGPU::EndWrite(unsigned long) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[9128]:0x3a4064)
    at GfxDeviceWebGPU::EndBufferWrite(GfxBuffer*, unsigned long) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[8967]:0x395d3c)
    at GeometryJobTasks::ScheduleSharedGeometryJobs(GfxDevice&, GeometryJobFence, void (*)(SharedGeometryJobData*, unsigned int), void (*)(SharedGeometryJobData*), void (*)(JobFence const&), SharedGeometryJobData*, unsigned int, DynamicVBOBuffer const*, DynamicVBOBuffer const*, bool) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[44478]:0x1265eae)
    at GfxDevice::ScheduleSharedGeometryJobsInternal(GeometryJobFence, void (*)(SharedGeometryJobData*, unsigned int), void (*)(SharedGeometryJobData*), void (*)(JobFence const&), SharedGeometryJobData*, unsigned int, DynamicVBOBuffer const*, DynamicVBOBuffer const*) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[44538]:0x1267fc2)
    at LineRenderer::RendererCullingOutputReady(BaseRenderer**, unsigned long, RendererCullingCallbackProperties const&) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[10380]:0x4294ae)
    at CallbackArray3<BaseRenderer**, unsigned long, RendererCullingCallbackProperties const&>::Invoke(BaseRenderer**, unsigned long, RendererCullingCallbackProperties const&) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[5894]:0x2426e6)
    at SendShadowCullingCallbacks(CullingOutput const&, ShadowCullData const&, SharedLightData const&, bool&) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[6058]:0x259305)
    at PrepareDrawShadowsCommandStep1(ShadowDrawingSettings const**, unsigned int, JobBatchDispatcher&, bool&) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[6343]:0x27ebea)
    at ScriptableRenderContext::ExecuteScriptableRenderLoop() (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[6391]:0x28450f)
    at ScriptableRenderContext::Submit() (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[6401]:0x28611f)
    at ScriptableRenderContext_CUSTOM_Submit_Internal(ScriptableRenderContextManaged*) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[51862]:0x1395e55)
    at ScriptableRenderContext_Submit_Internal_mAE1E99BDF4C4E5A0FD9A0147E460E25ABB84BF14 (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[61244]:0x14ed026)
    at ScriptableRenderContext_Submit_mF417223097ECEB2768EE736BE00A7F94DA3BDD26 (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[61297]:0x14ef9ea)
    at UniversalRenderPipeline_RenderSingleCamera_m2BED2535B52183757555545A51CE20C9330FC5C6 (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[125967]:0x26bba95)
    at UniversalRenderPipeline_RenderCameraStack_m47BBC0B4111D83BB6EE3275C9572BFBF2F5451B9 (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[125948]:0x26b6b9d)
    at UniversalRenderPipeline_Render_m15A42AB44C14AB4DCA7EF0B915964D46B643D50E (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[125940]:0x26b480f)
    at RenderPipeline_InternalRender_mCB77395158F4572F348D8227BA9127ABF1C9C5BE (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[61082]:0x14e2e5f)
    at RenderPipelineManager_DoRenderLoop_Internal_mB646C8738F4A9859101F3BE94809E2E10BBDB1FB (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[61145]:0x14e7150)
    at RuntimeInvoker_FalseVoid_t4861ACF8F4594C3437BB48B6E56783494B843915_RuntimeObject_IntPtr_t_RuntimeObject(void (*)(), MethodInfo const*, void*, void**, void*) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[229410]:0x4bfdfab)
    at il2cpp::vm::Runtime::InvokeWithThrow(MethodInfo const*, void*, void**) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[233197]:0x4c4e057)
    at il2cpp::vm::Runtime::Invoke(MethodInfo const*, void*, void**, Il2CppException**) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[233166]:0x4c4ba32)
    at il2cpp_runtime_invoke (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[233352]:0x4c4ff5c)
    at scripting_method_invoke(ScriptingMethodPtr, ScriptingObjectPtr, ScriptingArguments&, ScriptingExceptionPtr*, bool) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[56813]:0x13dcef9)
    at ScriptingInvocation::Invoke(ScriptingExceptionPtr*, bool) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[48047]:0x134b06d)
    at void ScriptingInvocation::Invoke<void>(ScriptingExceptionPtr*, bool) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[48051]:0x134b1a1)
    at Scripting::UnityEngine::Rendering::RenderPipelineManagerProxy::DoRenderLoop_Internal(ScriptingObjectPtr, void*, Scripting::UnityEngine::ObjectProxy, ScriptingExceptionPtr*) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[48147]:0x134e468)
    at ScriptableRenderContext::ExtractAndExecuteRenderPipeline(core::vector<Camera*, core::allocator<Camera*, 0ul>> const&, void (*)(SceneNode const*, AABB const*, IndexList&, SceneCullingParameters const*), void*, ScriptingObjectPtr) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[6408]:0x2867b4)
    at RenderManager::RenderCamerasWithScriptableRenderLoop(int) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[7782]:0x3255eb)
    at RenderManager::RenderCameras(int, void (*)(), void (*)()) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[7787]:0x325dd9)
    at PlayerRender(bool) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[11534]:0x47ef9f)
    at InitPlayerLoopCallbacks()::PostLateUpdateFinishFrameRenderingRegistrator::Forward() (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[11565]:0x480372)
    at ExecutePlayerLoop(NativePlayerLoopSystem*) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[10774]:0x44ccb9)
    at ExecutePlayerLoop(NativePlayerLoopSystem*) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[10774]:0x44cd84)
    at PlayerLoop() (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[10775]:0x44d0c6)
    at MainLoop() (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[47668]:0x132fe72)
    at _JS_CallAsLongAsNoExceptionsSeen (https://localhost:8141/Build/[REMOVED]_BUILDS.framework.js:1668:25)
    at UpdateUnityFrame() (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[47667]:0x132fc8b)
    at callUserCallback (https://localhost:8141/Build/[REMOVED]_BUILDS.framework.js:5091:3)
    at Object.runIter (https://localhost:8141/Build/[REMOVED]_BUILDS.framework.js:5154:4)
    at Browser_mainLoop_runner (https://localhost:8141/Build/[REMOVED]_BUILDS.framework.js:5706:20)

And

Uncaught TypeError: Failed to execute 'writeTexture' on 'GPUQueue': Failed to read the 'offset' property from 'GPUImageDataLayout': Value is outside the 'unsigned long long' value range.
    at _wgpu_queue_write_texture (https://localhost:8141/Build/[REMOVED]_BUILDS.framework.js:14808:29)
    at TextureWebGPU::UploadTexture(int, unsigned char const*) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[8997]:0x3999db)
    at GfxDeviceWebGPU::UploadTexture2D(TextureID, TextureDimension, unsigned char const*, unsigned long, int, int, GraphicsFormat, int, TextureUploadFlags) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[8996]:0x3997bd)
    at GraphicsTexture::Upload(TextureRawData const&, TexturePlatformMetaData const*) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[40194]:0x105002c)
    at UploadTexture2DGraphicsTexture(UploadTextureDataParams const&, core::SharedObjectPtr<GraphicsTexture>) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[43737]:0x11b9f49)
    at Texture2D::UploadTexture(int, bool) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[10290]:0x41de2c)
    at Texture2D::AwakeFromLoad(AwakeFromLoadMode) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[10271]:0x41bcb6)
    at AwakeFromLoadQueue::PersistentManagerAwakeSingleObject(Object&, AwakeFromLoadMode) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[46792]:0x12f0e9e)
    at PersistentManager::IntegrateObjectAndUnlockIntegrationMutexInternal(int) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[46936]:0x12ffdcf)
    at TimeSliceAwakeFromLoadQueue::IntegrateTimeSliced(int) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[45392]:0x128d607)
    at LoadOperation::IntegrateTimeSliced(int) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[6971]:0x2e96b1)
    at PreloadManager::UpdatePreloadingSingleStep(PreloadManager::UpdatePreloadingFlags, int) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[7016]:0x2ecd9c)
    at PreloadManager::UpdatePreloading() (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[7018]:0x2ed1b9)
    at InitPlayerLoopCallbacks()::EarlyUpdateUpdatePreloadingRegistrator::Forward() (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[11553]:0x47fd96)
    at ExecutePlayerLoop(NativePlayerLoopSystem*) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[10774]:0x44ccb9)
    at ExecutePlayerLoop(NativePlayerLoopSystem*) (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[10774]:0x44cd84)
    at PlayerLoop() (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[10775]:0x44d0c6)
    at MainLoop() (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[47668]:0x132fe72)
    at _JS_CallAsLongAsNoExceptionsSeen (https://localhost:8141/Build/[REMOVED]_BUILDS.framework.js:1668:25)
    at UpdateUnityFrame() (https://localhost:8141/Build/[REMOVED]_BUILDS.wasm:wasm-function[47667]:0x132fc8b)
    at callUserCallback (https://localhost:8141/Build/[REMOVED]_BUILDS.framework.js:5091:3)
    at Object.runIter (https://localhost:8141/Build/[REMOVED]_BUILDS.framework.js:5154:4)
    at Browser_mainLoop_runner (https://localhost:8141/Build/[REMOVED]_BUILDS.framework.js:5706:20)

Ive also seen some traces that reference text rendering but didn’t attach those as I seem to have misplaced them.

I’ve also tried in vain to gather more information using the WebGPU Inspector, this gave me no information, no validation errors or anything showing there. :worried: But let me know if I can supply any additional information to help crack this one!

And I also wanted to extend my thanks and appreciations for all the hard work put into making WebGPU a reality in Unity. Really great work with everything you do! :slight_smile:

@PiktivJB Thanks for the stack traces.

Looking at the trace for writeTexture, ‘offset’ is the pointer to the texture memory allocation. My suspicion is that the allocation is happening above 2GB, and unless >2GB pointer values are properly handled in JS, they become negative numbers, hence outside the range of ‘unsigned long long’.

I think we might still have an issue in the webgpu wrapper that isn’t handling >2GB properly. I remember seeing the issue earlier and planning on fixing it, but got distracted by Unite. I’ll make sure to get it checked out / fixed right away.

5 Likes

Ahhh that does checkout with my observations on memory. :smiley: That it seemed to happen consistently when exceeding a certain memory threshold but I didn’t know what to make of it since it was not anywhere close 4GB yet.

Haha it’s very understandable that Unite stole your attention :smile: Hard question but do you have an estimate for when a fix patch might be released? Or could you maybe shoot a message here when a fix has been done on your end so we can keep an eye on the coming patch notes?

1 Like

@PiktivJB I have a PR for the fix going out today, I’ll let you know what version it lands in.

5 Likes

The fix for >2GB memory usage with WebGPU is in 6000.0.23f1.

3 Likes

Here is the video for the Unite 2024 session we did on web platform and WebGPU, https://www.youtube.com/watch?v=3bu4WZUCGYc.

7 Likes

Really interesting presentation! Glad to see the various progress on the WebGPU implementation :slight_smile:

One part that caught my attention is multithreaded rendering which seems to be an improvement for the future! :slight_smile: This is the kind of topic I would love to learn more about!

Do you have any idea of ​​the different Unity features that are not yet implemented for WebGPU? I’m thinking in particular of APV or GPU Resident Drawer, but I’m probably forgetting others. Are these things we can hope for Unity 6.1? (crosses fingers)

@Zarbuz Multithreaded rendering is where multiple threads can create gpu command buffers, something native graphics APIs like D3D12, Vulkan, and Metal can do, but WebGPU spec still needs to expose. It can optimize certain situations, but also comes with its own set of complications. As soon as the spec enables this, we’ll start looking at it for Unity WebGPU, but there’s no timeline at all.

I don’t have an exhaustive list of missing features for WebGPU currently, but APV and GRD (GPU Resident Drawer) are on the top of the list. I’m pretty confident we can get those features working for WebGPU. But with GRD, it’s not guaranteed to be a performance benefit because it also depends on features like multi-threading, which may be problematic for the web player. STP is another feature that’s still missing, but I can’t say how likely that will be to work yet, it still needs more investigation. Chrome also just shipped HDR canvas support for WebGPU (Хром 129  |  Release notes  |  Chrome for Developers, currently only available on a couple browsers, like macOS), and I’m excited to start looking at supporting that with Unity WebGPU.

For 6.1, we are removing the need to set that project setting, and WebGPU will be available by default (not active by default, but selectable in the editor).

6 Likes

Thank you for your detailed answer!

Yes, that was a great talk and very excited for the direction Unity are going with the Web.

Do APV’s already work in WebGL? Do you have any idea of time frame for them being supported in WebGPU as this is a feature we are very keen to take advantage of, especially for the web, to reduce our project size by offloading as many lightmaps as possible.

Also is GPU Occlusion culling working in WebGPU?

@HiddenLtd APV does not work with WebGL yet, but there is a plan to add it to WebGL, the APV team did some work that would make that possible (minus any other unforeseen obstacles). We just got APV working with WebGPU locally and hope to get that released soon. I don’t have a timeframe yet, but soon. I’m excited to get APV out there on the web!

GPU Occlusion Culling technically “works” with WebGPU, but doesn’t have very much testing, so I don’t feel comfortable saying it’s fully supported yet. One of the obstacles I need to figure out for GPU Resident Drawer + GPU Occlusion Culling, is that it does make use of multithreading to gain performance (despite the emphasis of GPU in the name) and it’s not clear yet that GRD will provide performance benefit to the web with its lack of C# multithreading. This is where the remaining testing will happen.

4 Likes

Thank you for the quick response.

Quick question about WebGL backwards compatibility. We use assetbundles to load the different scenes in our project. Is it necessary to build the assetbundles twice to have WebGPU and WebGL compatibility (at the shader compilation level) or is it not necessary in order to have a WebGPU project that is WebGL backwards compatible?

@Zarbuz WebGPU and WebGL have different runtime shaders, so you’ll need both WebGL (GLSL) and WebGPU (WGSL) shaders in the asset bundle, or have different bundles for WebGL and WebGPU.

1 Like

That’s what I thought but thanks for the confirmation! I think we’re going to put a system where we’re going to compile the bundles specific to each version.

It would have been nice if they had used GLSL for WebGPU, but I understand why they couldn’t.