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 Shaders + ExecutionMode's #195

Merged
merged 8 commits into from
Nov 10, 2020

Conversation

charles-r-earp
Copy link
Contributor

Adds a wgpu compute shader example, "wgpu-example-compute-runner" and "wgpu-example-compute-shader". At minimum to compile and execute a compute shader, ie GLCompute, the execution mode LocalSize must be set. So this PR additionally adds a mechanism to do that:

#[spirv(gl_compute(local_size_x=64, local_size_y=16, local_size_z=4))]
pub fn main_cs() {}

Emulating GLSL, dimensions not specified default to 1 (gl_compute only).

The execution modes specified within a execution model, are collected into a Vec along with their arguments, and then this is sent as a SpirvAttribute::Entry, which is now special Entry struct. In entry.rs, the stub functions submit these execution modes.

I also added the fn compute_shader_entry_stub as a duplicate of shader_entry_stub, which in the future may handle function parameters differently.

I added the complete list of execution modes. There may be some additional logic for default values that I'm not familiar with, notably you can now specify OriginLowerLeft to vertex shaders, (OriginUpperLeft is the default). There isn't any error handling about which modes are valid per execution model, or specifying multiple conflicting modes. In general they are collected and submitted left to right.

All the tests passed.

…cutionModel. Replaced SpirvAttribute::Entry ExecutionModel with an Entry struct, which includes a Vec of ExecutionMode, ExecutionModeExtra to be submitted in entry.rs. Compute example runs. Passes all tests.
@repi repi requested a review from khyperia October 30, 2020 22:00
@repi
Copy link
Contributor

repi commented Oct 30, 2020

wow thanks for the contribution!

linking to #180

Copy link
Contributor

@khyperia khyperia left a comment

Choose a reason for hiding this comment

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

Oh my goodness, I was gearing up to implement this, and then you just come along and, do it??? Thank you so so so very much, this is incredible! I'm very happy taking this as-is right now (with the -> bool rustc nightly version fixed) and addressing the other feedback in a follow-up (either me or you, either is fine by me).

todo!()
}

fn add_unreachable_region(&mut self, _instance: Instance<'tcx>, _region: CodeRegion) -> bool {
fn add_unreachable_region(&mut self, _instance: Instance<'tcx>, _region: CodeRegion) {
Copy link
Contributor

Choose a reason for hiding this comment

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

ah, these should actually return bool - make sure you're up to date with the nightly specified in rust-toolchain! (these were changed to return bool recently)

});
}

fn compute_shader_entry_stub(
Copy link
Contributor

Choose a reason for hiding this comment

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

There's a decent amount of duplication between this and shader_entry_stub (and the existing duplication with kernel too), it might be nice to refactor things into something a little better structured - but probably in a later PR (I can do so), this is fine as-is as a temp solution.

Fragment => {
//FIXME: Is this the correct default?
let origin_mode = origin_mode.unwrap_or(OriginUpperLeft);
e.execution_modes.push((origin_mode, ExecutionModeExtra::new([])));
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a little convoluted code so I might be missing something, but it might be nice to only specify this if the user didn't do so themselves. (Considering we didn't even allow users to specify it before this PR, this is fine as-is for now, mostly just making a note that we should follow up on this later!)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This isn't a breaking change. The origin_mode variable is None, and replaced with OriginUpperLeft or OriginLowerLeft if specified. Before it was hardcoded in entry.rs for fragment shaders.

}
result
Copy link
Contributor

Choose a reason for hiding this comment

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

This whole thing is super nested, it'd be really nice if we could split it into some smaller functions.


fn main() {
let spirv = include_bytes_align_as!(u32, env!("wgpu_example_compute_shader.spv"));
println!("{}\n", disassemble_spirv(bytemuck::cast_slice(spirv)));
Copy link
Contributor

Choose a reason for hiding this comment

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

prooobably shouldn't include this, as all the other examples don't? but shrug, doesn't really matter either way.

examples/wgpu-example-compute-runner/Cargo.toml Outdated Show resolved Hide resolved
…unner to be more similar to other wgpu example. Split of entry logic in symbol.rs to separate function. Fixed issue in builder/mod.rs.
@khyperia
Copy link
Contributor

I'm not sure why CI isn't running on this - perhaps the merge conflicts need to get resolved first?

@XAMPPRocky XAMPPRocky added the s: waiting on author PRs that blocked on the author implementing feedback. label Nov 2, 2020
…moved really_unsafe_ignore_bitcasts to its own Symbol match. In entry.rs, entry stubs now return the fn_id, so that entry_stub() can add the execution modes in one place. Passed all tests.
@charles-r-earp
Copy link
Contributor Author

Yes, merge conflicts are fixed.

@XAMPPRocky XAMPPRocky added s: waiting on review PRs that blocked on a team member's review. and removed s: waiting on author PRs that blocked on the author implementing feedback. labels Nov 9, 2020
Copy link
Contributor

@khyperia khyperia left a comment

Choose a reason for hiding this comment

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

thanks so much!

let custom = std::iter::once((
"really_unsafe_ignore_bitcasts",
SpirvAttribute::ReallyUnsafeIgnoreBitcasts,
));
Copy link
Contributor

Choose a reason for hiding this comment

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

why split this out into its own thing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I figured it was commonly used. And this logic matches descriptor_set, binding. But it probably should be reverted to how it was, in attributes.

.attributes
.get(&name.name)
.map(|a| match a {
SpirvAttribute::Entry(entry) => SpirvAttribute::Entry(
Copy link
Contributor

Choose a reason for hiding this comment

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

I would prefer this gets handled in the same way descriptor_set and binding is handled, but whatever, that can be cleaned up later.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So you're saying add additional if else statements for each entry / execution_model? Wouldn't putting everything in the attributes HashMap scale better?

@mergify mergify bot merged commit 32c2ea5 into EmbarkStudios:main Nov 10, 2020
@charles-r-earp charles-r-earp deleted the compute-shaders branch November 27, 2020 02:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
s: waiting on review PRs that blocked on a team member's review.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants