Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compute shader example #6009

Closed

Conversation

erikdubbelboer
Copy link
Contributor

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 #5760

Kinda implements #2974 for WebGPU.

I confirm I have read the contributing guidelines and signed the Contributor License Agreement.

@willeastcott willeastcott changed the title Computer shader example Compute shader example Jan 28, 2024
@slimbuck slimbuck requested a review from a team January 29, 2024 09:13
@slimbuck slimbuck added the area: graphics Graphics related issue label Jan 29, 2024
@erikdubbelboer erikdubbelboer force-pushed the computer-shader-example branch from 0709cfa to 4396555 Compare February 11, 2024 05:31
@erikdubbelboer erikdubbelboer marked this pull request as ready for review February 11, 2024 05:31
@erikdubbelboer erikdubbelboer force-pushed the computer-shader-example branch 2 times, most recently from 3a8c25a to fe17fa0 Compare February 11, 2024 05:39
@erikdubbelboer
Copy link
Contributor Author

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.

@erikdubbelboer erikdubbelboer force-pushed the computer-shader-example branch from fe17fa0 to b0926e2 Compare February 24, 2024 04:28
const bytesPerPixel = formatInfo.size;

// Calculate bytes per row, ensuring it's a multiple of 256
const bytesPerRow = Math.ceil((texture.width * bytesPerPixel) / 256) * 256;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use math.roundUp

@mvaligursky
Copy link
Contributor

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: #6183

@mvaligursky
Copy link
Contributor

And another update / building block: #6186

@mvaligursky
Copy link
Contributor

Another related change: #6187

@mvaligursky
Copy link
Contributor

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 #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 mvaligursky marked this pull request as draft March 25, 2024 16:34
@erikdubbelboer
Copy link
Contributor Author

@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: erikdubbelboer@19963f1
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?

@mvaligursky
Copy link
Contributor

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.

@erikdubbelboer
Copy link
Contributor Author

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.

@mvaligursky
Copy link
Contributor

closing as all is now in the engine, thanks again @erikdubbelboer

Final PR: #6233

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: graphics Graphics related issue
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants