engine
engine copied to clipboard
Compute shader example
Initial work on further implementing WebGPU Compute shaders and adding an example for it. This slightly changes the API to allow for more work to submitted in a simple pass and to allow for reading the storage texture for the result.
@mvaligursky could you have a look and let me know what you think?
Building on the work of https://github.com/playcanvas/engine/pull/5760
Kinda implements https://github.com/playcanvas/engine/issues/2974 for WebGPU.
I confirm I have read the contributing guidelines and signed the Contributor License Agreement.
I have rewritten the example to show how it can do some actual work with in and output. I have also added support for buffers as in and output, instead of just textures, as buffers allow for more useful work to be done using atomics.
Hi @erikdubbelboer - thanks for this PR, it's very much appreciated. I had a look at it multiple times, but never finished to progress too far as it introduces multiple new APIs / behaviours, and I don't have a clear idea of how I'd like all this to work, and even don't have any experience with compute shaders in WebGPU.
I've decided to take it bit by bit to progress the implementation, and guide our collaboration as well. I like that you added support for multiple compute dispatches inside a single compute pass (instead of the TODO I added). Based on this, I added this PR: https://github.com/playcanvas/engine/pull/6183
And another update / building block: https://github.com/playcanvas/engine/pull/6186
Another related change: #6187
One more change, with different API to what you proposed here, but I believe it's simpler and more obvious. I'd appreciate your feedback @erikdubbelboer https://github.com/playcanvas/engine/pull/6201
I'll leave this PR opened as it still supports few additional buts I have not integrated yet. Your effort here is much appreciated.
@mvaligursky great that you have been working on this. All your changes look good and are in line with what I wrote as well.
One thing I'm wondering is, if compute shaders should be submitted with the normal render pass or if we should submit them right away. Like this: https://github.com/erikdubbelboer/engine/commit/19963f1f2643578bd9906fc5d21eadff6ddba531
I feel like this shouldn't work with the texture-gen example as that uses uniform buffers, which uses dynamic buffers, which are only submitted on WebgpuGraphicsDevice.submit(). Which then doesn't happen before we submit the compute shader. But I tested it and it does work, even when I only submit compute work before any call to WebgpuGraphicsDevice.submit(). Do you understand what is happening here?
UniformBuffers support both using dynamic buffers, but also it's own persistent buffer. I opted to use persistent buffers in this case, and so it works.
I thought about not submitting computes at the same time, but the most common use case we'd probably need is to integrate compute with render passes. For example the scene renders using render passes, then compute uses those textures to generates some buffers for postprocessing, and then render pass consumes it. In those cases it'd need to be submitted in order. So that's what I focused for now. Same for indirect drawing.
At some point we can relax this if there's no render pass dependency, but I have not solve this yet - what the simple API would be here.
At least that's my thinking currently, with not a large level of experience with all this.
But if you submit them right away they also get executed before the render commands are submitted. I tried various variations of calling computeDispatch in the texture-gen example and it all works. It will just finish earlier and make the render pass wait less.
The only way it doesn't work is if you call computeDispatch after the render pass, but that's always going to go wrong.
closing as all is now in the engine, thanks again @erikdubbelboer
Final PR: https://github.com/playcanvas/engine/pull/6233