From 9cb0b5c93d6b6b0dd7b56e5ce8d6037bfef8d27c Mon Sep 17 00:00:00 2001 From: Yunchao He Date: Mon, 3 Aug 2020 17:45:17 -0700 Subject: [PATCH 1/5] Add some restrictions about resource usage tracking/validation The revisions include: - add aspect (in addition to array layer and mip level) for subresource - add definition of atom resource, and use atom resource to replace subresource - race condition of writable storage buffer/texture in render pass is allowed - resource usages validation is done within "usage scope" - invisible usages and overwritten usages should be tracked --- spec/index.bs | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/spec/index.bs b/spec/index.bs index 87b476d335..7f56afae16 100644 --- a/spec/index.bs +++ b/spec/index.bs @@ -596,24 +596,35 @@ Issue(gpuweb/gpuweb#296): Consider merging all read-only usages. Textures may consist of separate [=mipmap levels=] and [=array layers=], which can be used differently at any given time. Each such subresource is uniquely identified by a -[=texture=], [=mipmap level=], and -(for {{GPUTextureDimension/2d}} textures only) [=array layer=]. +[=texture=], [=mipmap level=], +(for {{GPUTextureDimension/2d}} textures only) [=array layer=], +and [=aspect=]. -The **main usage rule** is that any [=subresource=] -at any given time can only be in either: +atom resource means a whole buffer or a single subresource of a texture. + +The **main usage rule** is that any [=atom resource=] +at any given time within [=usage scope=] can only be in either: - a combination of [=read-only usage=]s - a single [=mutating usage=] +The only exception is that a combination of writeonly-storage-texture usages, or a combination +of storage-buffer usages upon the same [#atom resource#] in render pass is allowed. + +Note that all invisible usages and overwritten usages should be counted, for example: + - a resource binding attached to a shader stage with visiblity none + - a resource binding attached to compute shader stage in render pass, or vice versa + - a collection of bindings are set by a bind group but being overwritten within current [=usage scope=] + Enforcing this rule allows the API to limit when data races can occur when working with memory. That property makes applications written against WebGPU more likely to run without modification on different platforms. -Generally, when an implementation processes an operation that uses a [=subresource=] +Generally, when an implementation processes an operation that uses a [=atom resource=] in a different way than its current usage allows, it schedules a transition of the resource into the new state. In some cases, like within an open {{GPURenderPassEncoder}}, such a transition is impossible due to the hardware limitations. We define these places as usage scopes: -each [=subresource=] must not change usage within the [=usage scope=]. +each [=atom resource=] must not change usage within the [=usage scope=]. For example, binding the same buffer for {{GPUBufferUsage/STORAGE|GPUBufferUsage.STORAGE}} as well as for {{GPUBufferUsage/VERTEX|GPUBufferUsage.VERTEX}} within the same {{GPURenderPassEncoder}} would put the encoder @@ -648,18 +659,18 @@ Issue(gpuweb/gpuweb#514): Document read-only states for depth views. ### Synchronization ### {#programming-model-synchronization} -For each [=subresource=] of a [=physical resource=], its set of +For each [=atom resource=] of a [=physical resource=], its set of [=usage flags=] is tracked on the [=Queue timeline=]. Usage flags are {{GPUBufferUsage}} or {{GPUTextureUsage}} flags, -according to the type of the subresource. +according to the type of the [=atom resource=]. Issue: This section will need to be revised to support multiple queues. On the [=Queue timeline=], there is an ordered sequence of [=usage scopes=]. Each item on the timeline is contained within exactly one scope. For the duration of each scope, the set of [=usage flags=] of any given -[=subresource=] is constant. -A [=subresource=] may transition to new usages +[=atom resource=] is constant. +A [=atom resource=] may transition to new usages at the boundaries between [=usage scope=]s. This specification defines the following [=usage scopes=]: @@ -676,7 +687,7 @@ regardless of whether the indexed draw calls are used afterwards. The [=usage scopes=] are validated at {{GPUCommandEncoder/finish()|GPUCommandEncoder.finish}} time. The implementation performs the usage scope validation by composing -the set of all [=usage flags=] of each [=subresource=] used in the [=usage scope=]. +the set of all [=usage flags=] of each [=atom resource=] used in the [=usage scope=]. A {{GPUValidationError}} is generated in the current scope with an appropriate error message if that union contains a [=mutating usage=] combined with any other usage. @@ -1682,7 +1693,7 @@ interface GPUMapMode { Issue: define texture (internal object) -Issue: define mipmap level, array layer, slice (concepts) +Issue: define mipmap level, array layer, aspect, slice (concepts) ## GPUTexture ## {#texture-interface} From 3e26f524aae1616acb199018caa8da9ab27fed3b Mon Sep 17 00:00:00 2001 From: Yunchao He Date: Mon, 3 Aug 2020 22:09:54 -0700 Subject: [PATCH 2/5] Add one more example about overwritten resource usage --- spec/index.bs | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/index.bs b/spec/index.bs index 7f56afae16..c6eba8d96d 100644 --- a/spec/index.bs +++ b/spec/index.bs @@ -614,6 +614,7 @@ Note that all invisible usages and overwritten usages should be counted, for exa - a resource binding attached to a shader stage with visiblity none - a resource binding attached to compute shader stage in render pass, or vice versa - a collection of bindings are set by a bind group but being overwritten within current [=usage scope=] + - index or vertex buffer being overwritten within current [=usage scope=] Enforcing this rule allows the API to limit when data races can occur when working with memory. That property makes applications written against From de47e7aa66ed9da82be1279290f805830a644511 Mon Sep 17 00:00:00 2001 From: Yunchao He Date: Tue, 4 Aug 2020 10:48:13 -0700 Subject: [PATCH 3/5] Addressed feedback from Dzmitry --- spec/index.bs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/spec/index.bs b/spec/index.bs index c6eba8d96d..51e5abddaf 100644 --- a/spec/index.bs +++ b/spec/index.bs @@ -610,11 +610,14 @@ at any given time within [=usage scope=] can only be in either: The only exception is that a combination of writeonly-storage-texture usages, or a combination of storage-buffer usages upon the same [#atom resource#] in render pass is allowed. -Note that all invisible usages and overwritten usages should be counted, for example: - - a resource binding attached to a shader stage with visiblity none - - a resource binding attached to compute shader stage in render pass, or vice versa - - a collection of bindings are set by a bind group but being overwritten within current [=usage scope=] - - index or vertex buffer being overwritten within current [=usage scope=] +Note: +All invisible usages and replaced usages should be tracked, for example: + 1) a resource binding attached to a shader stage with visiblity none, + 2) a resource binding attached to compute shader stage in render pass, or vice versa, + 3) resource usages bound in a group that is replaced by a different bind group within current [=usage scope=], + 4) index or vertex buffer usage bound but replaced by a different + {{GPURenderEncoderBase/setIndexBuffer()|GPURenderEncoderBase.setIndexBuffer}} or + {{GPURenderEncoderBase/setVertexBuffer()|GPURenderEncoderBase.setVertexBuffer}} within current [=usage scope=]. Enforcing this rule allows the API to limit when data races can occur when working with memory. That property makes applications written against From 62df6fe77f36438d2e210101eba7bbd55c573c37 Mon Sep 17 00:00:00 2001 From: Yunchao He Date: Fri, 21 Aug 2020 11:43:45 -0700 Subject: [PATCH 4/5] Combine two subresource usages into one, with some changes for better wording/style --- spec/index.bs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/spec/index.bs b/spec/index.bs index 2ccc395448..aa3bdd06ee 100644 --- a/spec/index.bs +++ b/spec/index.bs @@ -639,10 +639,9 @@ We define subresource to be either a whole buffer, or a [=texture Some [=internal usage=]s are compatible with others. A [=subresource=] can be in a state that combines multiple usages together. We consider a list |U| to be a compatible usage list if (and only if) it satisfies any of the following rules: - - Each usage in |U| is [=internal usage/input=], [=internal usage/constant=], or [=internal usage/storage-read=]. + - Each usage in |U| is [=internal usage/input=], [=internal usage/constant=], [=internal usage/storage-read=], or [=internal usage/attachment-read=]. - Each usage in |U| is [=internal usage/storage=] or [=internal usage/storage-read=]. - Each usage in |U| is [=internal usage/storage-write=]. - - Each usage in |U| is [=internal usage/attachment-read=], [=internal usage/storage-read=], or [=internal usage/constant=]. - |U| contains exactly one element: [=internal usage/attachment=]. @@ -665,14 +664,18 @@ For example, binding the same buffer for [=internal usage/storage=] as well as f as well as the owning {{GPUCommandEncoder}} into the error state. This combination of usages does not make a [=compatible usage list=]. -Note: -All invisible usages and replaced usages should be tracked, for example: - 1) a resource binding attached to a shader stage with visiblity none, - 2) a resource binding attached to compute shader stage in render pass, or vice versa, - 3) resource usages bound in a group that is replaced by a different bind group within current [=usage scope=], - 4) index or vertex buffer usage bound but replaced by a different - {{GPURenderEncoderBase/setIndexBuffer()|GPURenderEncoderBase.setIndexBuffer}} or - {{GPURenderEncoderBase/setVertexBuffer()|GPURenderEncoderBase.setVertexBuffer}} within current [=usage scope=]. +Note: race condition of multiple writable storage buffer/texture usages in a single [=usage scope=] is allowed. + +
+ This means usages are tracked at state-setting time, not draw/dispatch time, + and they ignore binding {{GPUBindGroupLayoutEntry/visibility}}. + This means the following example usages **are** tracked: + + - Bind group entries with visibility 0, or visible only to the the compute stage used in a render pass or vice versa. + - Bind groups and vertex buffers not used by a pipeline. + - Index or vertex buffers not used by any draw call. + - Bind groups, index buffers, or vertex buffers which are `set`, then shadowed by another `set` call. +
The [=subresources=] of textures included in the views provided to {{GPURenderPassColorAttachmentDescriptor/attachment|GPURenderPassColorAttachmentDescriptor.attachment}} and From 78475c87631dda7278e8ea0aca7bbf9a02d2e601 Mon Sep 17 00:00:00 2001 From: Yunchao He Date: Tue, 25 Aug 2020 11:21:50 -0700 Subject: [PATCH 5/5] Address feedback from CG meeting and spec editors' meeting --- spec/index.bs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/spec/index.bs b/spec/index.bs index aa3bdd06ee..db2323163e 100644 --- a/spec/index.bs +++ b/spec/index.bs @@ -666,17 +666,6 @@ This combination of usages does not make a [=compatible usage list=]. Note: race condition of multiple writable storage buffer/texture usages in a single [=usage scope=] is allowed. -
- This means usages are tracked at state-setting time, not draw/dispatch time, - and they ignore binding {{GPUBindGroupLayoutEntry/visibility}}. - This means the following example usages **are** tracked: - - - Bind group entries with visibility 0, or visible only to the the compute stage used in a render pass or vice versa. - - Bind groups and vertex buffers not used by a pipeline. - - Index or vertex buffers not used by any draw call. - - Bind groups, index buffers, or vertex buffers which are `set`, then shadowed by another `set` call. -
- The [=subresources=] of textures included in the views provided to {{GPURenderPassColorAttachmentDescriptor/attachment|GPURenderPassColorAttachmentDescriptor.attachment}} and {{GPURenderPassColorAttachmentDescriptor/resolveTarget|GPURenderPassColorAttachmentDescriptor.resolveTarget}}