-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
[Merged by Bors] - Documenting UniformBuffer
, DynamicUniformBuffer
, StorageBuffer
and DynamicStorageBuffer
.
#5223
Conversation
Co-authored-by: Robert Swain <robert.swain@gmail.com>
…w being merged. Co-authored-by: Robert Swain <robert.swain@gmail.com>
…ce memory" Co-authored-by: Robert Swain <robert.swain@gmail.com>
Co-authored-by: Robert Swain <robert.swain@gmail.com>
I can't comment on the accuracy of these particular docs but the writing is excellent! |
Ping @superdump for review. |
…documentation for StorageBuffer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO you should remove the "helper structure" terminology from the start of these docs :) It doesn't clarify things, and takes up space in the most important part of the description.
UniformBuffer
and DynamicUniformBuffer
.UniformBuffer
, DynamicUniformBuffer
, StorageBuffer
and DynamicStorageBuffer
.
…mic storage buffer docs
/// can store much larger data than uniform buffers, which are best suited to relatively small data. | ||
/// | ||
/// Storage buffers can store runtime-sized arrays, but only if they are the last field in a structure. To store a | ||
/// runtime-sized array of data, use [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer) instead. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this needs to be improved. It’s complicated though so I’ll have to have a go at a suggestion another time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's something like: if you want a runtime-sized array that you will index into from within your shaders, you can have one at the end of the inner type of a storage buffer. If you want multiple storage buffers of the same inner type and you will bind them in separate draw commands, you can use the dynamic storage buffer and pass the dynamic offsets when binding the buffer.
Dynamic storage buffers aren't really for runtime-sized arrays specifically. More for separating bindings due to some constraint or other or it just being more convenient for some reason. I kind of expect in practice it to be more desirable to use one storage buffer binding with a trailing runtime-sized array than to use dynamic offsets. This is because you can't batch draw calls together if you have to pass different dynamic offsets for the bindings.
/// can store much larger data than uniform buffers, which are best suited to relatively small data. Dynamic storage buffers | ||
/// are particularly well-suited to storing like a Rust-vector (wgpu's "runtime-sized arrays") and have a | ||
/// [`push`](crate::render_resource::DynamicStorageBuffer::push) method, unlike | ||
/// [`StorageBuffer`](crate::render_resource::StorageBuffer). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don’t agree with this. I’ll try to make a suggestion soon.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd probably rather say that StorageBuffer is well-suited to storing a single runtime-sized array like a Rust Vec, unlike UniformBuffer which are limited size (minimum guaranteed size is 16kB) and can only contain fixed-size arrays.
/// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::DynamicStorageBuffer::write_buffer) | ||
/// queues copying of the data from system RAM to VRAM. Dynamic storage buffers must conform to | ||
/// [std430 alignment/padding requirements], which is automatically enforced by this structure. If data does not need to | ||
/// be automatically padded or aligned, consider using [`BufferVec`](crate::render_resource::BufferVec). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additionally, each item pushed gets aligned to the required dynamic offset alignment for the wgpu backend and GPU vendor so that the byte offset provided in the binding call is valid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@superdump To address this, I wrote down now:
Dynamic storage buffers must conform to
[std430 alignment/padding requirements]
; whenever data ispush
ed into this structure, it is automatically aligned to these requirements.
Is that okay?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think dynamic offsets are part of std430. std430 is about the alignment of data within the binding. Dynamic offsets are about the alignment of the binding itself.
/// Uniform buffers are available to shaders on a read-only basis. Uniform buffers are commonly used to make available to shaders | ||
/// parameters that are constant during shader execution, and are best used for data that is relatively small in size. For | ||
/// larger data, or data that must be made accessible to shaders on a read-write basis, consider | ||
/// [`StorageBuffer`](crate::render_resource::StorageBuffer). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that WebGL2 does not support storage buffers. Alternatives for large amounts of data there are vertex/instance buffers, or data textures, depending on what is the most appropriate for the use case.
/// The contained data is stored in system RAM. [`write_buffer`](crate::render_resource::UniformBuffer::write_buffer) queues | ||
/// copying of the data from system RAM to VRAM. Data in uniform buffers must follow [std140 alignment/padding requirements], | ||
/// which is automatically enforced by this structure. Per the WGPU spec, uniform buffers cannot store runtime-sized array (vectors), or structures with fields that are vectors. | ||
/// If this is required, consider [`DynamicUniformBuffer`](crate::render_resource::DynamicUniformBuffer). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a bit of a hack one can do to fake runtime sized arrays but I suppose it should be documented in an advanced section of the book rather than here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, so I will leave this section as is. I know you have described this hack to me on the Discord, and it makes sense! I will leave a link here: https://discord.com/channels/691052431525675048/866787577687310356/991373107065532538
And I will also leave a link in the rendering documentation thread on Discord. (see: https://discord.com/channels/691052431525675048/968333504838524958)
I'm starting to feel like this is the wrong place for all the additional information about the other choices. Maybe it would be better to just write what each is specifically suitable for, and then just list the other possibilities without justification. Then we should have a more informative section in the bevy book that helps deciding which to use. It feels complicated in the scope of documentation here. What do you think @alice-i-cecile ? |
I'm in agreement with @superdump here; I think we can strip this down a bit (but keep basic cross-links) and then do a better overview at the module or book level. |
Co-authored-by: Robert Swain <robert.swain@gmail.com>
Co-authored-by: Robert Swain <robert.swain@gmail.com>
Co-authored-by: Robert Swain <robert.swain@gmail.com>
Co-authored-by: Robert Swain <robert.swain@gmail.com>
Co-authored-by: Robert Swain <robert.swain@gmail.com>
Co-authored-by: Robert Swain <robert.swain@gmail.com>
…t of links to other data storage options at end of docstring fro each particular data storage option
@superdump @alice-i-cecile sorry, this is a bit late, but I incorporated rob's suggestions and I also stripped down the docs to avoid discussing what the use cases of the other options are. Instead, I've stuck to discussing only the pros/cons of the specific option in question, and provided a set of links at the end to the other options. For example, for at the end of the docs for storage buffer: /// Other options for storing GPU-accessible data are:
/// * [`DynamicStorageBuffer`](crate::render_resource::DynamicStorageBuffer)
/// * [`UniformBuffer`](crate::render_resource::UniformBuffer)
/// * [`DynamicUniformBuffer`](crate::render_resource::DynamicUniformBuffer)
/// * [`BufferVec`](crate::render_resource::BufferVec)
/// * [`Texture`](crate::render_resource::Texture) Also, CI is failing because clippy is detecting |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. @alice-i-cecile ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bors r+
…and `DynamicStorageBuffer`. (#5223) # Objective Documents the `UniformBuffer`, `DynamicUniformBuffer`, `StorageBuffer` and `DynamicStorageBuffer` render resources. ## Solution I looked through Discord discussion on these structures, and found [a comment](https://discord.com/channels/691052431525675048/953222550568173580/956596218857918464) to be particularly helpful, in the general discussion around encase. Other resources I have used are documented here: https://discord.com/channels/691052431525675048/968333504838524958/991195474029715520 Co-authored-by: Brian Merchant <bhmerchant@gmail.com>
@bzm3r get CI passing with either an ignore or backticks (mild preference for ignore) and I'll merge this. |
Build failed: |
bors retry |
…and `DynamicStorageBuffer`. (#5223) # Objective Documents the `UniformBuffer`, `DynamicUniformBuffer`, `StorageBuffer` and `DynamicStorageBuffer` render resources. ## Solution I looked through Discord discussion on these structures, and found [a comment](https://discord.com/channels/691052431525675048/953222550568173580/956596218857918464) to be particularly helpful, in the general discussion around encase. Other resources I have used are documented here: https://discord.com/channels/691052431525675048/968333504838524958/991195474029715520 Co-authored-by: Brian Merchant <bhmerchant@gmail.com>
Pull request successfully merged into main. Build succeeded: |
UniformBuffer
, DynamicUniformBuffer
, StorageBuffer
and DynamicStorageBuffer
.UniformBuffer
, DynamicUniformBuffer
, StorageBuffer
and DynamicStorageBuffer
.
…and `DynamicStorageBuffer`. (bevyengine#5223) # Objective Documents the `UniformBuffer`, `DynamicUniformBuffer`, `StorageBuffer` and `DynamicStorageBuffer` render resources. ## Solution I looked through Discord discussion on these structures, and found [a comment](https://discord.com/channels/691052431525675048/953222550568173580/956596218857918464) to be particularly helpful, in the general discussion around encase. Other resources I have used are documented here: https://discord.com/channels/691052431525675048/968333504838524958/991195474029715520 Co-authored-by: Brian Merchant <bhmerchant@gmail.com>
…and `DynamicStorageBuffer`. (bevyengine#5223) # Objective Documents the `UniformBuffer`, `DynamicUniformBuffer`, `StorageBuffer` and `DynamicStorageBuffer` render resources. ## Solution I looked through Discord discussion on these structures, and found [a comment](https://discord.com/channels/691052431525675048/953222550568173580/956596218857918464) to be particularly helpful, in the general discussion around encase. Other resources I have used are documented here: https://discord.com/channels/691052431525675048/968333504838524958/991195474029715520 Co-authored-by: Brian Merchant <bhmerchant@gmail.com>
…and `DynamicStorageBuffer`. (bevyengine#5223) # Objective Documents the `UniformBuffer`, `DynamicUniformBuffer`, `StorageBuffer` and `DynamicStorageBuffer` render resources. ## Solution I looked through Discord discussion on these structures, and found [a comment](https://discord.com/channels/691052431525675048/953222550568173580/956596218857918464) to be particularly helpful, in the general discussion around encase. Other resources I have used are documented here: https://discord.com/channels/691052431525675048/968333504838524958/991195474029715520 Co-authored-by: Brian Merchant <bhmerchant@gmail.com>
Objective
Documents the
UniformBuffer
,DynamicUniformBuffer
,StorageBuffer
andDynamicStorageBuffer
render resources.Solution
I looked through Discord discussion on these structures, and found a comment to be particularly helpful, in the general discussion around encase. Other resources I have used are documented here: https://discord.com/channels/691052431525675048/968333504838524958/991195474029715520