godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.13k stars 83 forks source link

Add WebGPU support #6646

Open kelteseth opened 1 year ago

kelteseth commented 1 year ago

Describe the project you are working on

Looks like this will ship with Chromium 113 and Firefox 113 (yes, both will have the same version). See https://developer.chrome.com/blog/webgpu-release/ and https://bugzilla.mozilla.org/show_bug.cgi?id=1746245

CanIUse has not been updated yet: https://caniuse.com/webgpu

Also, we have a nice site that makes surveys about device support: https://web3dsurvey.com/webgpu

Describe the problem or limitation you are having in your project

This is essentially Vulkan for web.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

See https://www.w3.org/TR/webgpu/

If this enhancement will not be used often, can it be worked around with a few lines of script?

No.

Is there a reason why this should be core and not an add-on in the asset library?

Yes.

niklaskorz commented 1 year ago

Is this something a first-time contributor without prior knowledge about Godot internals but with WebGPU experience could reallistically implement? I have taken a glimpse at the D3D12 pull request and besides the huge amount of dependencies it adds I feel like it looks manageable.

Calinou commented 1 year ago

Is this something a first-time contributor without prior knowledge about Godot internals but with WebGPU experience could reallistically implement? I have taken a glimpse at the D3D12 pull request and besides the huge amount of dependencies it adds I feel like it looks manageable.

@sakrel is already working on a WebGPU renderer for Godot. I suggest you get in touch with them on the Godot Contributors Chat's #rendering channel if you want to help :slightly_smiling_face:

Geequlim commented 1 year ago

WebGPU seems to be able to unify the graphics api like gles2.

If Godot's renderer is also implemented with WebGPU, it can reduce a lot of maintenance costs, and there is no need for a rendering backend like dx12.

Calinou commented 1 year ago

WebGPU seems to be able to unify the graphics api like gles2.

If Godot's renderer is also implemented with WebGPU, it can reduce a lot of maintenance costs, and there is no need for a rendering backend like dx12.

There's likely significant overhead involved in this, on top of not being able to make use of advanced features (such as raytracing extensions). Not to mention build-time complexity would go way up, as WebGPU-related tools are usually written in Rust. I wouldn't go for that route for the same reasons we don't use something like bgfx.

chrisgliddon commented 1 year ago

+1 for this!

Calinou commented 1 year ago

@chrisgliddon Please don't bump issues without contributing significant new information. Use the :+1: reaction button on the first post instead.

Starkium commented 1 year ago

WebGPU seems to be able to unify the graphics api like gles2. If Godot's renderer is also implemented with WebGPU, it can reduce a lot of maintenance costs, and there is no need for a rendering backend like dx12.

There's likely significant overhead involved in this, on top of not being able to make use of advanced features (such as raytracing extensions). Not to mention build-time complexity would go way up, as WebGPU-related tools are usually written in Rust. I wouldn't go for that route for the same reasons we don't use something like bgfx.

Don't we need it for webXR development though?

dsnopek commented 1 year ago

Don't we need it for webXR development though?

Yes, for the near future we need WebGL for WebXR. There is a proposal for supporting WebGPU in WebXR, but as far as I know, no browsers have implemented it yet. Once there's an implementation or two, it'll take a bit before it can be become a draft standard.

But even aside from that, I think we'll need to keep OpenGL/WebGL around for low-end devices for a while anyway.

Starkium commented 1 year ago

Don't we need it for webXR development though?

Yes, for the near future we need WebGL for WebXR. There is a proposal for supporting WebGPU in WebXR, but as far as I know, no browsers have implemented it yet. Once there's an implementation or two, it'll take a bit before it can be become a draft standard.

But even aside from that, I think we'll need to keep OpenGL/WebGL around for low-end devices for a while anyway.

Chrome has. I know that playcanvas is supporting it already too. https://developer.chrome.com/blog/webgpu-release/

dsnopek commented 1 year ago

Chrome has. I know that playcanvas is supporting it already too. https://developer.chrome.com/blog/webgpu-release/

Are you saying Chrome supports WebXR on WebGPU? Do you have any references about that? The link above is just about WebGPU. Anyway, if true, I'd love to try demos of WebXR on WebGPU with Chrome. :-)

Starkium commented 1 year ago

Chrome has. I know that playcanvas is supporting it already too. https://developer.chrome.com/blog/webgpu-release/

Are you saying Chrome supports WebXR on WebGPU? Do you have any references about that? The link above is just about WebGPU. Anyway, if true, I'd love to try demos of WebXR on WebGPU with Chrome. :-)

Maybe I'm wrong, but I don't see how it would be up to Google to do that implementation and not on the app dev.

Klaim commented 1 year ago

Note that this doesnt concern only rendering on the web, WebGPU have implementations in C (so C++ too), Rust etc. Therefore this also concern Desktop scenario where one would want to use WebGPU for all devices and platforms. Apparently it's better supported (from day one???) than Vulkan because of no conflicts with Apple's decisions.

Starkium commented 1 year ago

Note that this doesnt concern only rendering on the web, WebGPU have implementations in C (so C++ too), Rust etc. Therefore this also concern Desktop scenario where one would want to use WebGPU for all devices and platforms. Apparently it's better supported (from day one???) than Vulkan because of no conflicts with Apple's decisions.

Well well damn I was not aware of that. That's really cool and probably something we should focus on?

Calinou commented 1 year ago

Therefore this also concern Desktop scenario where one would want to use WebGPU for all devices and platforms. Apparently it's better supported (from day one???) than Vulkan because of no conflicts with Apple's decisions.

Feature limitations and performance issues are something I'm concerned about with this approach. I think our WebGPU usage should be scoped to the web, avoiding extra abstraction layers where feasible.

Klaim commented 1 year ago

Feature limitations and performance issues are something I'm concerned about with this approach. I think our WebGPU usage should be scoped to the web, avoiding extra abstraction layers where feasible.

Understandable. NOte that I'm not a specialist on the subject, but so far my (probalby partially wrong) understanding is that whatever the WebGPU implementation, it have the same feature-set and limitations as Vulkan?

Anyway I'm not a specialist in that domain and I'm still gathering information. I trust that yall will get it right and at worse in limited scope and growing as necessary👍🏽

hugo-sna commented 1 year ago

The advantage of WebGPU is that it's fully crossplatform, and can even run natively using wgpu or Dawn and even support compute shader.

creikey commented 1 year ago

Therefore this also concern Desktop scenario where one would want to use WebGPU for all devices and platforms. Apparently it's better supported (from day one???) than Vulkan because of no conflicts with Apple's decisions.

Feature limitations and performance issues are something I'm concerned about with this approach. I think our WebGPU usage should be scoped to the web, avoiding extra abstraction layers where feasible.

Would using webgpu even prevent diving into lower level graphics apis when you need to? If at the moment all of godot can be run on webgpu on all platforms, and raytracing that requires non-webgpu is a far off thing, why wouldn't webgpu just be the gpu interface for now and then "oh to support ultra graphics you need vulkan or xyz thing" and it calls vulkan despite being majority webgpu, not the other way around?

If the above is true and you can "fall back" to a native gfx api, using webgpu doesn't prevent you from adding any features/performance when you need to and doesn't have any drawbacks at all in current godot.

pjoe commented 1 year ago

FWIW: there have been interest in the WebGPU working group to handle Ray Tracing, there are even some draft specs. Realistically it will be awhile though before it is released, however see: https://github.com/codedhead/webrtx

fawdlstty commented 1 year ago

@creikey My understanding is that webgpu provides more advanced functionality and hides underlying details. If you want to call the underlying interface, perhaps angle is a better idea, as it not only supports multiple backends but also provides access to the underlying interface

Zireael07 commented 1 year ago

@fawdlstty Godot recently gained an ANGLE backend!

ywmaa commented 1 year ago

@Zireael07

Godot recently gained an ANGLE backend!

Which PR ?

Calinou commented 1 year ago

Which PR ?

fire commented 11 months ago

What are the presently active threads concerning WebGPU? To my knowledge, there hasn't been any public progress.

If there's anyone actively working on WebGPU, kindly make your efforts known.

sebastienwood commented 10 months ago

A master thesis was written on the subject of getting WebGPU in Godot with interesting performance gains: https://www.diva-portal.org/smash/get/diva2:1762429/FULLTEXT01.pdf

dkaste commented 9 months ago

Will we want a "forward+" renderer, a "mobile" renderer, or both?

Unfortunately, I think the answer is "both". This will put Godot in the very uncomfortable position of having to maintain 4-5 separate renderers (Vulkan/D3D12 mobile/forward+, WebGPU mobile/forward+, GLES3?).

If it were up to me, I would lean toward totally replacing Vulkan/D3D12 with WebGPU for Godot 5. The performance loss should be minimal, since the existing renderers are far from hyper-optimized anyway.

Any missing features such as raytracing could be worked around with custom "extensions" (see dawn-ray-tracing) for native platforms, or polyfills for the web (see WebRTX).

Using WebGPU as the main rendering API would probably also help attract contributors, since it is much easier to understand.

I am aware that a ton of effort has gone into the Vulkan renderers, and now Google is helping improve the mobile one, so I do understand that this decision would be quite painful.

Roosader commented 9 months ago

It seems like the latest technical preview for Safari has added WebGPU support.
https://webkit.org/blog/14879/webgpu-now-available-for-testing-in-safari-technology-preview/

This would allow for a theoretical WebGPU enabled version of the editor to run on iPads/iPhones right?

theBSH commented 9 months ago

Will we want a "forward+" renderer, a "mobile" renderer, or both?

Unfortunately, I think the answer is "both". This will put Godot in the very uncomfortable position of having to maintain 4-5 separate renderers (Vulkan/D3D12 mobile/forward+, WebGPU mobile/forward+, GLES3?).

If it were up to me, I would lean toward totally replacing Vulkan/D3D12 with WebGPU for Godot 5. The performance loss should be minimal, since the existing renderers are far from hyper-optimized anyway.

Any missing features such as raytracing could be worked around with custom "extensions" (see dawn-ray-tracing) for native platforms, or polyfills for the web (see WebRTX).

Using WebGPU as the main rendering API would probably also help attract contributors, since it is much easier to understand.

I am aware that a ton of effort has gone into the Vulkan renderers, and now Google is helping improve the mobile one, so I do understand that this decision would be quite painful.

i dont think we should get rid of vulkan or d3d12 as each have there own pros and cons , personally i dont have an issue with a long drop list if we can have more futures.

fawdlstty commented 9 months ago

i dont think we should get rid of vulkan or d3d12 as each have there own pros and cons , personally i dont have an issue with a long drop list if we can have more futures.

vulkan can be supported indirectly through angle, and d3d12 can wait a while for angle to be supported :rofl: (bushi

lucidium4 commented 9 months ago

i dont think we should get rid of vulkan or d3d12 as each have there own pros and cons , personally i dont have an issue with a long drop list if we can have more futures.

vulkan can be supported indirectly through angle, and d3d12 can wait a while for angle to be supported 🤣 (bushi

Angle is only realy for OpenGL ES 2 and 3 (and by extension WebGL 1 & 2)

fawdlstty commented 9 months ago

Angle is only realy for OpenGL ES 2 and 3 (and by extension WebGL 1 & 2)

I'm sorry, I should have made it clearer that it was a joke. I'm not opposed to adding more backends to suit the needs of more scenarios

ps. In our area, (bushi means joke

dkaste commented 9 months ago

i dont think we should get rid of vulkan or d3d12 as each have there own pros and cons , personally i dont have an issue with a long drop list if we can have more futures.

It's not about a long drop-down list, but rather the amount of effort that will have to be spent maintaining all those renderers instead of improving the engine. Also, any time a new rendering feature is added, there will be pressure to add a version of it for each renderer.

To reiterate what has been said above, WebGPU is a thin(-ish) abstraction layer on top of modern rendering APIs. By targeting the WebGPU API, you can automatically and natively run on top of Vulkan, D3D12, Metal, and WebGPU itself in web browsers (technically also OpenGL and D3D11, but those are iffy). You could, for instance, use the D3D12 backend through it and be able to run on Xbox.

Conceptually, the only thing we would be losing by replacing the raw Vulkan/D3D12 renderers with WebGPU is a certain amount of low-level control and performance. But WebGPU is still a modern API, so any lost performance may be negligible.

I'm not aware of any rendering features that would be fundamentally impossible to support with WebGPU. If there are any, please do mention them.

Starkium commented 9 months ago

Will we want a "forward+" renderer, a "mobile" renderer, or both?

Unfortunately, I think the answer is "both". This will put Godot in the very uncomfortable position of having to maintain 4-5 separate renderers (Vulkan/D3D12 mobile/forward+, WebGPU mobile/forward+, GLES3?).

If it were up to me, I would lean toward totally replacing Vulkan/D3D12 with WebGPU for Godot 5. The performance loss should be minimal, since the existing renderers are far from hyper-optimized anyway.

Any missing features such as raytracing could be worked around with custom "extensions" (see dawn-ray-tracing) for native platforms, or polyfills for the web (see WebRTX).

Using WebGPU as the main rendering API would probably also help attract contributors, since it is much easier to understand.

I am aware that a ton of effort has gone into the Vulkan renderers, and now Google is helping improve the mobile one, so I do understand that this decision would be quite painful.

Why is there a distinction between forward+ renderer and mobile? In unreal engine it is the same with flags for unsupported features sets.

dkaste commented 9 months ago

Why is there a distinction between forward+ renderer and mobile? In unreal engine it is the same with flags for unsupported features sets.

According to this video, it sounds like Unreal also has many different renderers (mobile/desktop, deferred/forward+).

Starkium commented 9 months ago

Why is there a distinction between forward+ renderer and mobile? In unreal engine it is the same with flags for unsupported features sets.

According to this video, it sounds like Unreal also has many different renderers (mobile/desktop, deferred/forward+).

Last I heard the work to unify them is already done or almost done. Maybe there's a distinction between mobile HDR flag being on or off. That thing needs to disappear though.

ElectroidDes commented 8 months ago

Why not implement something ready-made into Godot, for example: Orillusion - Web3D Rendering Engine based on WebGPU

https://www.youtube.com/watch?v=brNav4rDPHU&t=2s

https://github.com/Orillusion/orillusion https://orillusion.github.io/orillusion-webgpu-samples/#gpuParticles https://www.orillusion.com/en/example/animation/Skeleton3.html

fire commented 8 months ago

@ElectroidDes I don't understand how we can implement a typescript engine like v8 for orillusion?

hafezoa commented 6 months ago

Any estimate on when this might be added to a future Godot release?

Calinou commented 6 months ago

Any estimate on when this might be added to a future Godot release?

We can't give an ETA for WebGPU support, as the specification is still in flux and browser support is still low as of writing. There was a volunteer working on implementing WebGPU support but they're currently not available to continue working on it.

davnotdev commented 6 months ago

Hi, I've been looking at this issue for the past few months and have decided to begin working on webgpu support here using wgpu over dawn for the time being. Godot's new rendering device driver system pairs great with vulkan, but it seem too low level to fit webgpu well. I'm hoping that diving straight into development will aid the discussion about how webgpu can fit into Godot. To my understanding no one has started working on this yet? I'm not exactly sure, so I just want to make myself known.

Right now, I have implemented some basic groundwork -- webgpu compile flag, initializing the surface for X11, the equivalent of rendering_context_driver_vulkan.cpp, and creating a device / queue. I've been chipping away at this for a couple days and intend furthering the implementation when my spring break starts (I'm a student).

clayjohn commented 6 months ago

@davnotdev That would be great! Another contributor was actually working on WebGPU support for a while but they stopped due to lack of time. I have asked them to share their progress here so you can take a look.

There are a lot of discussions on the rendering channel at chat.godotengine.org. If you search through the history their for webgpu, you should find some relevant discussions about what areas were causing the biggest challenges.

seabassjh commented 5 months ago

@davnotdev How's your progress going? Need any help! I am willing to assist, I've worked with wgpu in rust, with bevy

davnotdev commented 5 months ago

@seabassjh Help would be very much appreciated! Progress is moving along steadily. Right now, I'm trying to implement the minimum required to render an empty scene. From what I can tell, the only major functions left to achieve this are shader_compile_binary_from_spirv, shader_create_from_bytecode, render_pipeline_create, compute_pipeline_create, uniform_set_create, and the command_* functions. We're getting there, but there is still quite a bit to go!

Here are some tasks that would be nice to have done:

  1. Implementing WebGpu for more platforms. Right now, only X11 is implemented. See platform/linuxbsd/x11/rendering_context_driver_webgpu_x11.cpp
  2. Implementing the command_* functions in drivers/webgpu/rendering_device_driver_webgpu.cpp
  3. Implementing a proper way to vendor wgpu-native. Currently, I manually copy a libwgpu-native.a file into thirdparty/wgpu/
  4. Implementing any features I skipped -- anything marked with // TODO or // NOTE

Thanks for offering your help. Any contribution is appreciated. Let me know if you would like write access to the branch.

seabassjh commented 5 months ago

@davnotdev do you have a discord we could collaborate on?

davnotdev commented 5 months ago

@seabassjh Sure, here's a server where we can collaborate -- https://discord.gg/vQFwDhpERz

davnotdev commented 5 months ago

A Little Update:

Blockers

  1. WGPU Spirv barrier support -- This the currently the main blocker.
  2. WGPU missing features -- This is simple fix and is currently worked around.
  3. WGPU specialization support is not available in trunk yet. -- This will require patience.
  4. Excessive dependence on extensions means that we may not be able to support web for quite a while. Currently, we use:
WGPUNativeFeature_PushConstants,
WGPUNativeFeature_TextureFormat16BitNorm,
WGPUNativeFeature_TextureAdapterSpecificFormatFeatures,
WGPUNativeFeature_TextureBindingArray,

WGPU is missing features, so I'm considering switching to Dawn.

Discussion Questions

  1. Is the purpose of the initial WebGPU implementation to provide another desktop rendering API or to support web? I'd imagine that the former is the ultimate goal, but that would require either emulating missing features or waiting for them to become apart of the spec.

  2. Is it reasonable for Godot cut out certain features to support the WebGPU implementation? For example, the use of 16bit texture appears easy to cut out, but may hurt performance and/or backwards compatibility.

  3. Should the WebGPU implementation include both WGPU and Dawn or one clean Dawn implementation? In theory, the two will be equivalent, but Dawn (C++) is more likely to be accepted over WGPU (Rust) anyway.

  4. Assuming that we have solved the web support problem, should the WebGPU implementation use Tint, or support both Tint and Naga? The two are functionally equivalent, but Tint (C++) is more likely to be accepted over Naga (Rust) anyway.

When I say C++ is more likely to be accepted than Rust, I mean that adding Rust to the codebase will complicate the build step significantly.

I'd love to see what everyone has to say about this.

clayjohn commented 5 months ago

@davnotdev the rendering team is meeting in 30 minutes for our weekly meeting. If you are available, it would be great to discuss your questions in the meeting, otherwise I will write up some answers tomorrow. You can find the link to the meeting in the rendering channel at chat.godotengine.org

clayjohn commented 5 months ago

Answers reproduced from the discussion yesterday:

  1. Is the purpose of the initial WebGPU implementation to provide another desktop rendering API or to support web? I'd imagine that the former is the ultimate goal, but that would require either emulating missing features or waiting for them to become apart of the spec.

No. The goal is only to ship WebGPU as an API for the web. For desktop we prefer to continue using the existing native backends (Vulkan, D3D12, Metal)

  1. Is it reasonable for Godot cut out certain features to support the WebGPU implementation? For example, the use of 16bit texture appears easy to cut out, but may hurt performance and/or backwards compatibility.

Yes. Support for features should be detected at the renderer level and then fallbacks should be provided.

For example, we can fallback to a 32 bit texture here: https://github.com/godotengine/godot/blob/780e1a50408360cf0cf93c0b55b59e9d7b4ad0b1/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp#L175

and here: https://github.com/godotengine/godot/blob/780e1a50408360cf0cf93c0b55b59e9d7b4ad0b1/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp#L448

and here: https://github.com/godotengine/godot/blob/780e1a50408360cf0cf93c0b55b59e9d7b4ad0b1/servers/rendering/renderer_rd/storage_rd/light_storage.cpp#L2391

and here:

https://github.com/godotengine/godot/blob/780e1a50408360cf0cf93c0b55b59e9d7b4ad0b1/servers/rendering/renderer_rd/storage_rd/light_storage.cpp#L1998

By checking for supported formats, like we do here: https://github.com/godotengine/godot/blob/780e1a50408360cf0cf93c0b55b59e9d7b4ad0b1/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp#L196

  1. Should the WebGPU implementation include both WGPU and Dawn or one clean Dawn implementation? In theory, the two will be equivalent, but Dawn (C++) is more likely to be accepted over WGPU (Rust) anyway.

Since we aren't planning on supporting desktop exports with WebGPU, then whichever library is easiest to develop in should be used.

  1. Assuming that we have solved the web support problem, should the WebGPU implementation use Tint, or support both Tint and Naga? The two are functionally equivalent, but Tint (C++) is more likely to be accepted over Naga (Rust) anyway.

This question needs a bit more exploration. Its going to depend on which supports our feature set more efficiently. Both can be used. Tint could be nice as we could include it as a thirdparty dependency if it is small enough. Naga could still be used if we host it in a separate repo and provide pre-compiled library files.

Realistically, if both libraries are truly functionally equivalent, and offer similar size/performance tradeoffs, then we would prefer tint for being C++.

Dragonashes commented 5 months ago

On question 1. I highly question the reasoning of providing for only 1 platform, a correctly implemented webgpu ought to be a simple <canvas> or <custom-element> that would be embedded on a webview and consumed on all platforms native or otherwise, hence WebGPU.

dkaste commented 5 months ago

@Dragonashes That should work fine regardless, assuming whatever web view you use fully supports WebGPU.

The question is concerned with running the WebGPU backend natively (compiling to x86 instead of WebAssembly). No web view or browser involved.

Jaeba commented 5 months ago

Hello, I was just reading through this thread to see if it's something I could possibly contribute to. I'll start with this honorable mention...

I'm not aware of any rendering features that would be fundamentally impossible to support with WebGPU. If there are any, please do mention them.

Transform feedback is a feature of other graphics api's that doesn't look like it is going to be included in WebGPU. I don't have an official source to confirm that, only the fact that it isn't there now, and random forum discussions say that it's not going to be included.

Here is a great explanation of why you don't want it in your graphics api (and motivation for it not being in WebGPU): Transform feedback is terrible, so why are we doing it?

I bring this up in case it matters to anyone here, that may not have been aware. I don't know if it's a feature that Godot users depend on at all, but my understanding is that with WebGPU you'll be forced to upgrade from transform feedback to compute shaders. This is a positive thing, but it may mean that "translating" your old pipeline to WebGPU will require more redesign work if it used TF.

For those who aren't familiar, transform feedback refers to the ability to have the vertex shader write directly to a buffer on the gpu, independently of what it does or doesn't pass on to the rasterizer and fragment shader. This feature is sort of a precursor to compute shaders, allowing you to do calculations that don't need to result in writing a color to a framebuffer, e.g. particle interactions, pretending like you're mining cryptocurrency, etc.