-
Notifications
You must be signed in to change notification settings - Fork 345
Description
Hi. For the past six months or so, I've been helping people learn the WebGPU APIs from people of all skill levels, and one of the big stumbling blocks has been implicit pipeline layouts. This feature has caused a lot of confusion and might be the biggest cause of support that I've seen.
To me, that suggests that even if we decide the feature is helpful and keep it, we should at least rework some details of its design. A non-exhaustive list of issues I've seen:
- Beginners are confused by code samples and tutorials. Some code samples provide bind group layouts, and others rely on implicit pipeline layouts. Two ways to do something is really confusing, and tutorials do not motivate why both options exist.
- The algorithm feels magical, and I've experienced users become scared or afraid to modify their shaders once they get things working. Using implicit pipeline layouts correctly means understanding what the algorithm will do in all scenarios, which does not feel like it significantly helps lighten cognitive load. Some users I've helped feel more comfortable with their code after adding explicit pipeline layouts, since they now know all the relevant places to adjust, rather than having to "reverse engineer" what the algorithm is doing to build a bind group that matches.
- The error messages are not great, and it's unclear how what should be changed to get something the user will want. While I expect implementation error messages to improve, I suspect the magic-ness of the algorithm to remain an impediment to users.
- A silent loss of performance. On many devices, changing the BGL will incur a full device flush. Implicit pipeline layouts are easy to reach for, and it's not always obvious that the user is trading performance when relying on implicit pipeline layouts between different devices, and not just precision or specificity.
For these reasons, I don't believe that implicit pipeline layouts are providing a huge benefit over explicit ones, and I feel, given my experience, beginner users become a lot more comfortable not using them, instead using explicit pipeline layouts.
I have been told in the past that intended use case for them was for "simple" shaders like post-processing shaders. If we decide to keep implicit pipeline layouts, I still think we should rework their implementation to help limit the concerns given above. Here are a few non-exclusive options:
- Reduce their scope, and make it so that only very simple shaders work (the "postprocessing" case). Perhaps, once the user is using uint/int textures, or storage buffers, we throw an error and tell the user that implicit pipeline layouts are not supported if the shader uses an advanced feature; this should cut down on the amount of accidental resource mismatches. Bikeshedding might be required for what features are "advanced".
- Make implicit pipeline layouts harder to reach for. Rather than automatically kicking in if the user does not provide a layout, maybe we should make the user provide something like:
layout: 'implicit'in the pipeline. This would require the user to look at the documentation and possibly read about the pros and cons; if the left was instead left missing, the user might never think to look. As an example, TypeScript does not warn on a missing field, so a user filling out their pipeline field by field until TypeScript stops erroring out might not ever notice the "layout" field, nor read its documentation. - Make pipeline layouts easier to specify. If explicit pipeline layouts are too annoying to specify, we might want to look into why, and see if there are approaches or helpers we can specify to make this easier. See for one example, Why are bind group layout fields spelled differently from their WGSL counterparts? #2469.