Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

kvark
Copy link
Contributor

@kvark kvark commented Feb 24, 2020

It's very rough, hoping to get feedback to make it better. It's supposed to cover the important missing bits about what the actual usage scopes are, and how the validation is done.


Preview | Diff

Copy link
Contributor

@Kangz Kangz left a comment

Choose a reason for hiding this comment

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

Looks good!

spec/index.bs Outdated
at the [=usage scope=] boundaries.

This specification defines the following [=usage scopes=]:
1. an individual copy command on a {{GPUCommandEncoder}}, such as {{GPUCommandEncoder/copyBufferToTexture()|GPUCommandEncoder.copyBufferToTexture}}.
Copy link
Contributor

Choose a reason for hiding this comment

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

or just "an individual command on a ..."

spec/index.bs Outdated

This specification defines the following [=usage scopes=]:
1. an individual copy command on a {{GPUCommandEncoder}}, such as {{GPUCommandEncoder/copyBufferToTexture()|GPUCommandEncoder.copyBufferToTexture}}.
2. an individual command inside a {{GPUComputePassEncoder}}, such as {{GPUProgrammablePassEncoder/setBindGroup(index, bindGroup, dynamicOffsets)|GPUProgrammablePassEncoder.setBindGroup}}.
Copy link
Contributor

Choose a reason for hiding this comment

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

Actually isn't it just dispatch and dispatch indirect that are usage scopes? The rest are just setting state for these two commands.

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 is a great question to raise. The reason I went for any command here is apposed to just the draws, is because it would be awkward to allow bad state to be bound even if it's not used.

So, first, I think we are going to be specifying the exact resources used by a dispatch as those that are covered by the bind groups attached to slots expected by the layout of the active pipeline. So there might be bindings not included/used by a dispatch, and similarly for the draws.

What happens if, for example, the user is recording a render pass, and they bind a group that uses one of the current render targets as STORAGE? It seems to me that making this an error versus non error based on the dependencies of a draw() would make up for a weaker API. It would be nice to specify that, in particular, everything you bind within a render pass becomes part of the usage scope for this pass.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for the detailed explanation. It makes a lot of sense for the render pass. For the dispatch we'd want to consider the resources used by that dispatch and only this one so the wording might get a bit more complicated.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What happens if the user does setBindGroup() with one that is self-conflicting? I.e. it has different mutable bindings for the same resource? If we spec the usage scopes for dispatch only, we'd be ignoring these bindings, potentially.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure what's best here. Both validating the setBindGroup by itself and not doing it seem weird.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Would be nice to be somewhat consistent between the compute and render passes wrt the usage scopes, even if the scopes are different. I.e. it would be good to say that the usage scope of a render pass is the union of the usage scopes of its commands, and for the compute pass it's just not a union.

So the same kind of problem can be seen in render passes: if the user calls setVertexData we have a choice (in how we define the usage scopes):

  1. Every command by itself is a usage scope, and the render pass considers the union of all usage scopes of its commands. This is what the current PR has (or at least aims to). The consequence here is that we consider the vertex buffer to be used by the pass (regardless of what the draw calls would do).
  2. Only draws, dispatches, and copies are considered to be the usage scopes (and a render pass is a union of its draw usage scopes). This means that on each draw() we would have to traverse the dependencies and consider the usage scopes. In this case, it will be up to the active render pipeline layout at the next draw() to decide whether the vertex buffer is considered to be used.

I have a slight preference towards (1) for making the validation simpler, which may allow us to have higher draw call throughput in the end.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it makes sense that calling setVertexBuffer will mark the buffer as used for that pass even if it's not actually accessed by the draw call. It's up to the developer to prevent that from happening if they want to use a vertex buffer as something else during that pass.

spec/index.bs Outdated
For example, it can check if all the bindings inside a single {{GPUBindGroup}} make a valid usage scope
that would be considered every time {{GPUProgrammablePassEncoder/setBindGroup(index, bindGroup, dynamicOffsets)}} is called.

Issue: Should a created bind group then be considered invalid?
Copy link
Contributor

Choose a reason for hiding this comment

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

TBH I don't think it's useful for implementations to do early validation like this because it only optimizes the error case, not the success case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I don't have strong feelings about this. Will remove the issue.

spec/index.bs Outdated
Comment on lines 419 to 422
Timeline could be split into a sequence of [=usage scope=]:
within each scope the usage of the [=subresource=] stays unchanged,
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
Timeline could be split into a sequence of [=usage scope=]:
within each scope the usage of the [=subresource=] stays unchanged,
The [=Queue timeline=] is split into a sequence of [=usage scope=]s.
Within each scope the usage of the [=subresource=] stays unchanged,

Copy link
Contributor

Choose a reason for hiding this comment

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

In multiqueue, there's one queue timeline per queue, right? Hard to say now, but there needs to be at least some synchronization at the device timeline.

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 think it would be up to the multi-queue proposal to specify.

{{GPUQueue/submit(commandBuffers)}} does nothing and produces an error if any of the following is true:

- Any {{GPUBuffer}} referenced in any element of `commandBuffers` isn't in the `"unmapped"` [=buffer state=].
- Any of the [=usage scopes=] contained in the command buffers fail the [=usage scope validation=].
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
- Any of the [=usage scopes=] contained in the command buffers fail the [=usage scope validation=].
- Any of the [=usage scopes=] contained in the command buffers fail [=usage scope validation=].

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 wonder why the shouldn't be here?

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree it shouldn't be there, but kind of okay either way: "if any X fail validation." vs "if any X fail the validation."

spec/index.bs Outdated
which have been validated for correct resource usage during recording on the [=Content timeline=],
results in the resource usage also being valid at the [=Queue timeline=].

The implementation does the <dfn dfn>usage scope validation</dfn> by composing
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
The implementation does the <dfn dfn>usage scope validation</dfn> by composing
The implementation performs <dfn dfn>usage scope validation</dfn> by composing

spec/index.bs Outdated

The implementation does the <dfn dfn>usage scope validation</dfn> by composing
the union of all usage flags of the [=subresources=] used by the [=usage scope=].
The {{GPUValidationError}} is generated in the current scope with appropriate error message
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
The {{GPUValidationError}} is generated in the current scope with appropriate error message
A {{GPUValidationError}} is generated in the current scope with appropriate error message

@kainino0x kainino0x changed the title Syncronization section of the spec Synchronization section of the spec Mar 9, 2020
Copy link
Contributor

@kainino0x kainino0x left a comment

Choose a reason for hiding this comment

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

Looks pretty good so far.

spec/index.bs Outdated
Comment on lines 419 to 422
Timeline could be split into a sequence of [=usage scope=]:
within each scope the usage of the [=subresource=] stays unchanged,
Copy link
Contributor

Choose a reason for hiding this comment

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

In multiqueue, there's one queue timeline per queue, right? Hard to say now, but there needs to be at least some synchronization at the device timeline.

spec/index.bs Outdated
if the union contains a [=mutating usage=] combined with any other usage.

Note: an implementation is likely to validate the usage scopes earlier
than at {{GPUQueue/submit()|GPUQueue.submit}} time, where the [=Queue timeline=] is defined.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
than at {{GPUQueue/submit()|GPUQueue.submit}} time, where the [=Queue timeline=] is defined.
than at {{GPUQueue/submit()|GPUQueue.submit}} time (which occurs on the [=Queue timeline=]).

spec/index.bs Outdated
Comment on lines 441 to 442
For example, it can check if all the bindings inside a single {{GPUBindGroup}} make a valid usage scope
that would be considered every time {{GPUProgrammablePassEncoder/setBindGroup(index, bindGroup, dynamicOffsets)}} is called.
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand what this is saying; we can talk about it on the editors call.

Copy link
Contributor

Choose a reason for hiding this comment

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

resolved: We don't need this particular bit. But we should move the validation from submit() to finish().

spec/index.bs Outdated
{{GPUBindingType/"sampled-texture"}}, |view|'s texture's {{GPUTextureDescriptor/usage}}
must include {{GPUTextureUsage/SAMPLED}}.
must include {{GPUTextureUsage/SAMPLED}}. The texture's [=subresources=] seen by the |view|
are considered to be [=used=] by the resulting bind group as {{GPUTextureUsage/SAMPLED}}.
Copy link
Contributor

Choose a reason for hiding this comment

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

We could make this more formal (put the subresource usages in a list, or something), but it can definitely be done later

kvark added 3 commits March 11, 2020 09:51
Rewrite the usage validation section to tell that it happens at finish() time.
Add "usedBuffers" and "usedTextures" internal slots to "GPUBindGroup".
@kvark
Copy link
Contributor Author

kvark commented Mar 11, 2020

I addressed the changes we discussed and rebased this. The validation is described to happen at finish() time now. I also added the usageBuffers and usageTextures internal slots to the bind group as a "pilot" thing. We will probably need to evolve it in the following ways:

  1. define an internal object with all the usages, so that we can have it as internal slot for things like bind groups, bundles, or render passes.
  2. clearly define an internal object for a texture subresource (i.e. a "(texture, mipmap level, slice)" tuple).

We can do this as a follow-up.

@kvark kvark marked this pull request as ready for review March 11, 2020 20:28
@kvark kvark merged commit 82346de into gpuweb:master Mar 13, 2020
@kvark kvark deleted the sync branch March 13, 2020 01:26
Copy link
Contributor

@kainino0x kainino0x left a comment

Choose a reason for hiding this comment

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

I'll open a PR with some small nits.


Issue: This section will need to be redacted to support multiple queues.

The [=Queue timeline=] could be split into a sequence of [=usage scopes=]:
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this supposed to be part of the Issue? If not, then "could" doesn't make sense here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no, it's not a part of the issue. I was trying to say that we can consider the queue timeline to be seen as a sequence of usage scopes.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, then I think the version I have in the "nits" should be what you intended.

JusSn pushed a commit to JusSn/gpuweb that referenced this pull request Jun 8, 2020
* Syncronization section
* Address Kang's notes
* Address Kai's comments.

Rewrite the usage validation section to tell that it happens at finish() time.
Add "usedBuffers" and "usedTextures" internal slots to "GPUBindGroup".
JusSn pushed a commit to JusSn/gpuweb that referenced this pull request Jun 8, 2020
* Syncronization section
* Address Kang's notes
* Address Kai's comments.

Rewrite the usage validation section to tell that it happens at finish() time.
Add "usedBuffers" and "usedTextures" internal slots to "GPUBindGroup".
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.

4 participants