Sitelet https://github.com/gpuweb/gpuweb/pull/205
Skip to content

Remove GPUPipelineLayout and inline it in GPUPipelineDescriptorBase - #205

Closed
Kangz wants to merge 1 commit into
gpuweb:masterfrom
Kangz:pipelinelayout
Closed

Kangz wants to merge 1 commit into
gpuweb:masterfrom
Kangz:pipelinelayout

Conversation

@Kangz

@Kangz Kangz commented Feb 7, 2019

Copy link
Copy Markdown
Contributor

The pipeline layouts only contained the list of bind group layouts and
didn't add any value by being a separate object. Removing them reduces
the API complexity.

Comment thread design/sketch.webidl

interface GPUPipelineLayout {
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

You should remove createPipelineLayout too. However, having a separate object can be helpful for signifying pipeline compatibility to the user.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed createPipelineLayout too, thanks for the catch.

Pipeline layout wouldn't have been used for compatibility except for "bind group inheritance" if we choose to have that. The same inheritance can exist with pipelines so I'm not too worried.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sounds good to me

The pipeline layouts only contained the list of bind group layouts and
didn't add any value by being a separate object. Removing them reduces
the API complexity.

@kainino0x kainino0x left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Seems ok, I'd only be concerned because Vulkan seems to think it's necessary. In particular, "pipeline layouts are used as part of pipeline creation (see Pipelines), as part of binding descriptor sets (see Descriptor Set Binding), and as part of setting push constants (see Push Constant Updates)."

  • pipeline creation: we still have the layout in pipeline creation
  • binding descriptor sets: why don't we need it? we're not currently passing the pipeline layout into setBindGroups. Are we (in the implementation) doing it lazily (i.e. once we know what the actual pipeline, and thereore pipeline layout, is)?
  • push constants: same as ^, probably, if we add them

@kvark

kvark commented Feb 7, 2019

Copy link
Copy Markdown
Contributor

The pipeline layouts only contained the list of bind group layouts and
didn't add any value by being a separate object.

This reminds me of #92

Following the same logic, GPUShaderModule is just a list of bytes, so having it doesn't "add any value by being a separate object". Is that the route you want to go - eliminate all the things from the API that could be cached by the backend?

There are two kind of API complexities:

  1. the perceived complexity, i.e. how many interfaces and entry points it exposes. Reducing this complexity saves the users a few lines of code.
  2. the conceptual complexity, i.e. how straightforward the mapping is from API concepts to the underlying primitives it abstracts over. Reducing this complexity makes it easy to reason about the API behavior for users who understand the native APIs.

This PR doesn't strictly reduce the complexities, it just trades (1) for (2). I believe this change makes the API harder to reason about. For example, consider the user who only creates 2 rendering pipelines and draws a bunch of objects mixed between them. The user realizes that the first bind group is actually only containing a single uniform buffer that isn't used by the second pipeline, and they consider "optimizing" it by removing the unused bind group layout. Depending on the background of the user, one of the two scenarios could happen:

  • If they know about vulkan layouts or D3D12 root signatures, they will be careful to use the same list of bind group layouts, keeping in mind that they actually want the same native API layout to be used for both. This adds mental overhead for thinking beyond the API concepts, trying to not accidentally trip a wire.
  • If they only know WebGPU API, they'll happily remove the first bind group layout from the list they pass for the creation of the second pipeline object. Our implementation will end up creating two different native pipeline layouts that are totally incompatible (since the first bind group layout is different). This ends up in our implementation re-binding all the resources (behind user's back) on each pipeline change... not the "optimization" the user wanted to get.

You can see how this is related to "pit of success" and "spooky action at a distance" concepts that's been voiced before in the group.

@Kangz

Kangz commented Feb 11, 2019

Copy link
Copy Markdown
Contributor Author

@kainino0x like you said, all of these issues should be workable if we apply things lazily. It is a bit more work for implementations for sure.

@kvark

Following the same logic, GPUShaderModule is just a list of bytes, so having it doesn't "add any value by being a separate object". Is that the route you want to go - eliminate all the things from the API that could be cached by the backend?

Like you said, it is a tradeoff. I don't think GPUShaderModule would go that route because I think we'll eventually add more capabilities to it, for example linking.

I hadn't thought about this proposal making it easier to produce pipeline layout / root signature layout incompatibilities but it is a good point. My hope is that with proper bind group inheritance rules we show developers that it is good for pipelines to be compatible. Basically this would be trading a lot of 1) for less of 2).

I'm not 100% sure about it, and it is something that is easy to change post-snapshot if developers tell us they feel the pipeline layout is redundant.

@RafaelCintron

Copy link
Copy Markdown
Contributor

I ran this proposal by a contact on the D3D team. He is in agreement with @kvark.

From a D3D12 perspective, separating the RootSignature from the PipelineState allows developers to make informed decisions about optimizing around shared root signatures. Drivers can also take advantage of caching (pre-fetching) some of the input data ahead without the need to specify the full PipelineState in a CommandList (which could kick off a shader compile operation). However, there is nothing that prevents this. As @kvark implies, this trades API convenience for execution efficiency.

@Kangz

Kangz commented Feb 12, 2019

Copy link
Copy Markdown
Contributor Author

Thanks @RafaelCintron for the feedback. It seems like keeping the pipeline layout object makes sense as removing it could be hiding too much from implementations. Closing this as won't fix.

@Kangz Kangz closed this Feb 12, 2019
@Kangz
Kangz deleted the pipelinelayout branch February 12, 2019 11:45
ben-clayton pushed a commit to ben-clayton/gpuweb that referenced this pull request Sep 6, 2022
* Expect GPUOutOfMemoryError in map_oom tests

Fixes gpuweb#199. Also adds a helper to asynchronously expect errors.

* OperationError for mapping after out-of-memory; expectGPUError
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants