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

Expose and enforce a maximum buffer size. #2776

Closed
wants to merge 1 commit into from

Conversation

nical
Copy link
Contributor

@nical nical commented Jun 15, 2022

Connections

WebGPU spec discussion: gpuweb/gpuweb#1371

Description

A maximum buffer size will be exposed in the WebGPU specification. This is mostly because of metal which is officially restrictive in that area while other APIs (as far as I know), don't expose limits on the maximum buffer size and only limit the maximum binding size.

However in practice drivers have bugs. Mesa/lavapipe for example runs into trouble with sizes that don't fit into a signed 32 bit integer, and more generally my experience is that allocating gpu buffers and textures in the order of multiple gigabytes is a very good way to find driver bugs, in particular the kind that bring the OS on the mid/low end of the hardware ecosystem.

This PR exposes metal's maximum buffer size in Limits and sets the max buffer size to i32::MAX for all other backends.

I realize that the i32::MAX global limit might be controversial. It's very likely that the browser will override it with something even more conservative but on the native side, some might find it limiting.

The limit could depend on the hardware and driver with some more work.

Testing

None.

@nical
Copy link
Contributor Author

nical commented Jun 15, 2022

A test is failing, probably because of the 128MB value I naively set for dowlevel_defaults (it's the guaranteed supported SSBO size). Maybe I misunderstood what dowlevel_defaults was for but let's first discuss whether the general approach makes sense.

Copy link
Member

@jimblandy jimblandy left a comment

Choose a reason for hiding this comment

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

This looks good to me. Just some suggestions.

@@ -804,6 +808,7 @@ impl Limits {
max_compute_workgroup_size_y: 256,
max_compute_workgroup_size_z: 64,
max_compute_workgroups_per_dimension: 65535,
max_buffer_size: 134_217_728, // 128MB is the guaranteed supported SSBO size in GL
Copy link
Member

Choose a reason for hiding this comment

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

nit: I'd prefer 128 * 1024 * 1024, since that's more recognizably 128Mi.

@@ -847,6 +847,7 @@ impl super::PrivateCapabilities {
max_compute_workgroup_size_y: self.max_threads_per_group,
max_compute_workgroup_size_z: self.max_threads_per_group,
max_compute_workgroups_per_dimension: 0xFFFF,
max_buffer_size: self.max_buffer_size as u32,
Copy link
Member

Choose a reason for hiding this comment

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

Let's use a try_from(...).unwrap() here.

Comment on lines +3183 to +3190
let max_size = device.limits.max_buffer_size as BufferAddress;
if desc.size > max_size {
break resource::CreateBufferError::MaxBufferSize {
requested: desc.size,
maximum: max_size,
};
}

Copy link
Member

Choose a reason for hiding this comment

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

Would this check fit better in Device::create_buffer?

@nical
Copy link
Contributor Author

nical commented Jun 17, 2022

On second thought I think that completely forbidding large allocations is probably not the right thing to do in wgpu. Instead we should set a limit only for drivers that are known to be buggy or perhaps via a "safer" opt-in or opt-out mode, while letting programs/users that can afford to trust the graphics driver allocate huge buffers as they see fit.

@jimblandy
Copy link
Member

Oh, I thought these limits were going to reflect architectural limits of the underlying API. That's why i32::MAX was fine with me. The device can always return OOM on us anyway - and that might be due to fragmentation, not exhaustion. So there's no sense in which we're promising that an allocation of the given size or less would always succeed.

@nical
Copy link
Contributor Author

nical commented Jun 21, 2022

Dropping this in favor of #2796.

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.

2 participants