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

[wgsl] Elaborate storage classes section #1093

Merged
merged 21 commits into from
Oct 26, 2020
Merged

Conversation

dneto0
Copy link
Contributor

@dneto0 dneto0 commented Sep 21, 2020

Also:

  • Define IO-shareable
  • Define read-only texture
  • Define write-only texture
  • Add more cross-links.
  • Restrict where runtime-sized arrays may be used
  • Store type of uniform and storage_buffer variables must be
    block-decorated

Fixes #1004

@dneto0 dneto0 added the wgsl WebGPU Shading Language Issues label Sep 21, 2020
@dneto0 dneto0 added this to the MVP milestone Sep 21, 2020
@dneto0 dneto0 requested review from dj2 and litherum September 21, 2020 22:32
Copy link
Contributor

@kvark kvark left a comment

Choose a reason for hiding this comment

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

Thank you for describing this!

wgsl/index.bs Outdated
@@ -395,21 +411,103 @@ The following types are <dfn dfn noexport>host-shareable</dfn>:
* [[#array-types]] if the array type has a stride attribute and its element type is host-shareable
* [[#struct-types]] if all its members are host-shareable

The contents of uniform buffers and storage buffers must be of host-shareable type.

TODO: *This is a stub*: Collectively, the *stride* and *offset* attributes are called *layout attributes*.

### Storage Classes TODO ### {#storage-class}
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 still TODO?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The description of layout is for a future MR. So the TODO is still warranted.

wgsl/index.bs Outdated Show resolved Hide resolved
wgsl/index.bs Outdated
<td>[=Module scope=]
<td>[=Host-shareable=]
<td>See [[#memory-layout]].
<tr><td>image
Copy link
Contributor

Choose a reason for hiding this comment

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

Are we using "texture" and "image" interchangeably here? I understand that the term came from SPIR-V, where the relevant Vulkan API objects are images. In WGSL, it would be great to be consistent with WebGPU.

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'll change to "texture"

wgsl/index.bs Outdated
<td>Invocations in the same [=shader stage=]
<td>[=Module scope=]
<td>[=Host-shareable=]
<td>See [[#memory-layout]].
Copy link
Contributor

Choose a reason for hiding this comment

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

I find it confusing that we have 3 different uniform-ish storage classes. Was hoping to navigate to that [[#memory-layout] to understand more, but it's empty :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, the memory-layout section is empty right now. That is yet another big change I would like to do separately.

There are 3 uniform-ish things:

  • storage_buffer. For OpenGL's SSBOs. Read-write buffers with explicit layout. Contents shareable with the host. Pretty flexible layout rules
    - What's confusing is that originally Vulkan/SPIR-V had this in "Uniform" storage class with "BufferBlock" decorated struct. But now the style is "StorageBuffer" with Block-decorated struct
  • uniform. For OpenGL's UBOs. Read-only buffer with explicit layout. Strict and annoying array layouts. Limit max size. Contents shareable with host.
  • uniform_constant. For opaque things that happen to be handles, each with their own binding. The handles are immutable, but the underlying data might not be. "UniformConstant" is not my favourite name in the world but I suggest we bikeshed that separately.

Copy link
Contributor

Choose a reason for hiding this comment

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

This separation is rather confusing. First of all, it doesn't include storage images. I tried to check which storage class does glslang assign to them, and apparently I'm getting "UniformConstant" for a write-only storage image... It makes so little sense to me.

I guess the bigger question to ask is - why does WGSL need storage classes at all?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For one thing, you need to separate workgroup storage from private, for one thing.

Also, you have different rules for different storage classes. Layout rules differ.

Fundamentally, storage classes are a way of organizing the many rules about how memory treatedl

wgsl/index.bs Outdated
<td>Same invocation only
<td>[=Module scope=]
<td>[=IO-shareable=]
<td>Contains values written by an upstream pipeline stage, or by the implementation.
Copy link
Member

Choose a reason for hiding this comment

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

Maybe

Input from an upstream pipeline stage, or the implementation

Trying to remove the word written as it's confusing when read with the output line below.

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 didn't want it to read as circular. But your wording looks good.

wgsl/index.bs Outdated
<td>Same invocation only
<td>[=Module scope=]
<td>[=IO-shareable=]
<td>Shader writes values for downstream pipeline processing.
Copy link
Member

Choose a reason for hiding this comment

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

Maybe

Output for a downstream pipeline stage. Zero initialized if required.

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'll take the first part.

The zero-initialized aspect is already described in "Variable and const" https://gpuweb.github.io/gpuweb/wgsl.html#variable-declaration

wgsl/index.bs Show resolved Hide resolved
wgsl/index.bs Show resolved Hide resolved
wgsl/index.bs Show resolved Hide resolved
wgsl/index.bs Outdated Show resolved Hide resolved
wgsl/index.bs Outdated Show resolved Hide resolved
wgsl/index.bs Outdated Show resolved Hide resolved
wgsl/index.bs Outdated Show resolved Hide resolved
wgsl/index.bs Outdated Show resolved Hide resolved
@dneto0
Copy link
Contributor Author

dneto0 commented Sep 22, 2020

I think I've addressed all feedback.
I created a gist preview https://gistpreview.github.io/?2ab0184ed17ad6e4caea0a4f64af5794#storage-class

wgsl/index.bs Outdated

<pre class='def'>
storage_class
: INPUT
| OUTPUT
| FUNCTION
| PRIVATE
| UNIFORM
| WORKGROUP
| UNIFORM_CONSTANT
| STORAGE_BUFFER
| IMAGE
Copy link
Member

Choose a reason for hiding this comment

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

You renamed this to texture in the table below, should this also change to match?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It turns out we would only need this to express a pointer-to-image.
But that's only needed if we do image atomics.

However, we've learned that WGSL won't support image atomics. (see #728 (comment) ).

So the best thing is to remove "image" storage class altogether.

<td>Read-only
<td>Invocations in the same shader stage
<td>[=Module scope=]
<td>Opaque representation of handle to a sampler or texture
Copy link
Member

Choose a reason for hiding this comment

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

What about if we dropped uniform_constant and we just used constant. Then, on the SPIR-V side if the variable is sampler or texture type we make a UniformConstant buffer?

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 put an alternate proposal in: #1105 (comment)

@grorg grorg added this to For Next Meeting in WGSL Sep 29, 2020
@dneto0
Copy link
Contributor Author

dneto0 commented Oct 2, 2020

I've removed the "image" (texture) storage class, and updated the gist: https://gistpreview.github.io/?2ab0184ed17ad6e4caea0a4f64af5794#storage-class

I think the main thing to focus on is what storage classes we need for textures, samplers, and buffers. #1105

wgsl/index.bs Outdated
@@ -2943,26 +3111,22 @@ Issue: (dneto) Default rounding mode is an implementation choice. Is that what
<tr><td>`FOR`<td>for
<tr><td>`FRAGMENT`<td>fragment
<tr><td>`FUNCTION`<td>function
<tr><td>`HANDLE`<td>handle
Copy link
Member

Choose a reason for hiding this comment

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

Is this needed?

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 moved it to reserved words.

If we use the full planned generality, then you can always get the base pointer of a variable and stuff it into a const. But we could make a special rule for that. I added a TODO for that in the PR.

@dneto0
Copy link
Contributor Author

dneto0 commented Oct 7, 2020

I've rebased, and incorporated the feedback from this week's meeting.
I've updated the gist, and added more explanatory text in various places.

One choice that we can bikeshed about, is the name of the storage classes for UBO and SSBO.
I went with uniform and buffer because:

  • that matches GLSL and is short
  • when I tried "constant" I saw a lot of potential for confusion because "constant" is used all over the place, especially because const is a first class concept.

Note that the WebGPU spec has uniform-buffer and storage-bufferwhich are explicit but longer than I'd like.

@dneto0
Copy link
Contributor Author

dneto0 commented Oct 7, 2020

@dneto0
Copy link
Contributor Author

dneto0 commented Oct 9, 2020

Rebased and resolved a conflict.

@dneto0 dneto0 moved this from For Next Meeting to Open PRs (temp) in WGSL Oct 9, 2020
@kvark
Copy link
Contributor

kvark commented Oct 13, 2020

For consistency, let's use "Uniform" and "Storage" class names instead of "Uniform" and "Buffer".

@litherum
Copy link
Contributor

Also:
- Define IO-shareable
- Define read-only texture
- Define write-only texture
- Add more cross-links.
- Restrict where runtime-sized arrays may be used
- Store type of uniform and storage_buffer variables must be
block-decorated

Fixes gpuweb#1004
Highlight the difference between IO-shareable and host-shareable.

Move a TODO down to the memory layout section.  That whole section is
still TODO.
Reword the introduction to the storage classes table, and on the
"Variable scop" heading.
- Move restriction runtime arrays up to the section on array types.
  Add a TODO for tricky wording about not having intermediate values
  be of array type.
- Add various cross-references
- Move "block-decorated" restriction into the storage classes table
  so it's harder to miss.
- Wording improvements for inputs and outputs
Rexture storage class would only be used if WGSL supports image atomics.
But WebGPU won't have that because it's not available on all platform APIs.

Also reorder the grammar list of storage classes to match the table.
- Rename:
  - storage_buffer -> buffer
  - uniform_constant -> handle

- de-capitalize Private and Function storage class names in main text.
Also fill in details:

Module-scope vars:
- Describe restrictions based on storage class
Function-scope vars
- Describe restrictions on store type
The intent is to never have to write 'handle' in a WGSL program.

Add TODO to prevent function paramater or const to be of
pointer-to-handle type.
@dneto0
Copy link
Contributor Author

dneto0 commented Oct 22, 2020

I've rebased against main, and updated the storage class name "buffer"->"storage".

I've updated the gist as well: https://gistpreview.github.io/?2ab0184ed17ad6e4caea0a4f64af5794#storage-class

@dj2 dj2 merged commit 7a3f41b into gpuweb:main Oct 26, 2020
WGSL automation moved this from Open PRs to Done Oct 26, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wgsl WebGPU Shading Language Issues
Projects
WGSL
Done
Development

Successfully merging this pull request may close these issues.

WGSL should require uniform storage class variables to be [[block]] decorated.
4 participants