← 输入框|github.com|刷新
Skip to content

Maximum and minimum total resources in GPUBindGroup/Layout? #409

Closed

Description

@JusSn

Inspired by #406: we should spec the maximum and minimum number of any resources per bind group.

Metal

No verbiage about a minimum number of arguments, but attempting to create an empty MTLArgumentEncoder crashes my Metal driver.

Our Metal implementation uses MTLArgumentEncoders to back GPUBindGroupLayouts. One MTLArgumentEncoder binds the resources corresponding to one stage of the programmable pipeline, so a GPUBindGroupLayout that contains a resource visible to all three will create three MTLArgumentEncoders.

The least-capable Metal device capable of using MTLArgumentEncoder can encode:

31 buffers
31 textures
16 samplers

per shader stage. (This is equivalent to the normal resource limits per stage for this level of hardware.)

Here is my limited understanding of other frameworks.

D3D

"Each descriptor table stores descriptors of one or more types." though I am unsure what would happen if one attempted to create and set an empty one.

The minimum hardware support for DX12 Descriptor Tables is Tier 1; across all descriptor tables for a pipeline we can set:

14 constant (uniform) buffer views
128 shader resource views (textures et al)
16 samplers

per shader stage, in addition to

8 (for D3D Feature Level 11_0) or 64 (for 11_1+) unordered access (storage) views

across all shader stages.

Vulkan

"A descriptor set layout object is defined by an array of zero or more descriptor bindings."

From Table 46 in the spec, these are minimum supported numbers per descriptor set:

12 uniform buffers
4 storage buffers
16 sampled images (textures)
4 storage images
16 samplers

per shader stage.

Conclusion

It looks like Vulkan's minimum support is the most restrictive across the board other than D3D12's UAV restrictions for Feature Level 11_0, where we'd have to limit total storage-buffers to 8 per layout.

Due to D3D12's documentation and the Metal behavior I observed, it should also be illegal to create a GPUBindGroupLayout or GPUBindGroup with no bindings. WDYT?

Activity

  1. kainino0x commented on Aug 14, 2019

    @kainino0x
    Contributor

    I wonder if we could patch up the no-bindings case inside implementations. If the implementation is simple, I think it would be nice for users. Other than that, this sounds good.

  2. JusSn commented on Aug 14, 2019

    @JusSn
    ContributorAuthor

    We could totally just not create platform objects in the 0 bindings case, but unless Vulkan has a use-case other than no-op, not really a point IMO.

  3. kainino0x commented on Aug 14, 2019

    @kainino0x
    Contributor

    I think it would be a no-op, just thinking it could be slightly handy for applications that build bind groups programmatically, which would have to special-case empty bind groups. It's very tiny. Either is OK with me.

  4. kvark commented on Aug 15, 2019

    @kvark
    Contributor

    A spec that doesn't have such a restriction is making a slightly better API, given that the semantics of this is obvious.

  5. JusSn commented on Aug 15, 2019

    @JusSn
    ContributorAuthor

    I actually agree. So to clarify, creating an empty GPUBindGroupLayout creates a valid object that may or may not be backed with a backend object, likewise for GPUBindGroup, and setting such a GPUBindGroup on an encoder is a no-op?

  6. kainino0x commented on Aug 16, 2019

    @kainino0x
    Contributor

    Yeah, as long as we can make it transparent.

  7. JusSn commented on Aug 27, 2019

    @JusSn
    ContributorAuthor

    Question: In a bind group, or across multiple bind groups set on one pipeline, a single resource bound with different binding numbers is considered multiple distinct bindings, right?

  8. kvark commented on Sep 9, 2019

    @kvark
    Contributor

    Correct.

  9. austinEng commented on Jun 23, 2020

    @austinEng
    Contributor

    I have a question which seems like it was discussed in the review for #427.

    Some of these limits are per pipeline layout, and some are per shader stage. When are the limits enforced? Is it only on pipeline layout?

    If they are not enforced until pipeline layout creation, then the implementation needs to support bind group layouts and bind groups of completely unbounded size as "valid" even though it would be impossible to use a bind group that exceeds the per-pipeline-layout limits with a valid pipeline.

    Knowing this, an implementation could avoid actually creating data and storage for enormous bind groups (because it would be impossible to use in a valid call), but I would prefer to avoid this type of magic. Can per-stage limits and per-pipeline-layout limits also be enforced on the bind group layout? i.e. a BGL that exceeds the per-pipeline or per-stage limits would be a validation error.

  10. kainino0x commented on Jun 23, 2020

    @kainino0x
    Contributor

    I think we discussed this in more detail at some point (may have just been an editors call). At that time I was thinking it was better to enforce in just one place, but to avoid pointless magic in implementations I agree we should enforce it in both.

  11. austinEng commented on Jun 24, 2020

    @austinEng
    Contributor

    This was discussed in the 06/24 VF2F. We decided we would also enforce maximum per-pipeline and per-stage limits during bind group layout validation.

  12. Kangz commented on Sep 2, 2021

    @Kangz
    Contributor

    Closing this investigation now that the limits are in the spec.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions