这是indexloc提供的服务,不要输入任何密码
Skip to content

Static Samplers Proposal #4687

@Sirtsu55

Description

@Sirtsu55

Overview

Static samplers are immutable sampler objects that can not be modified after they are defined. They exist in all three backends: Vulkan, D3D12, and Metal. They are called immutable samplers in Vulkan, static samplers in D3D12, and for Metal they are constexpr samplers in Metal Shading Language (MSL). This proposal for static samplers in WebGPU would allow for samplers to be defined in WGSL, thus simplifying the workflow since sampler objects are rarely changed after initializing them once. The proposal also allows defining them through the WebGPU API in bind group layouts (BGL).

Vulkan

Vulkan allows defining immutable samplers in VkDescriptorSetLayoutBinding with a binding. It asks for VkSamplers in VkDescriptorSetLayoutBinding::pImmutableSamplers. Immutable samplers are tied toVkDescriptorSetLayout and can be used across with different pipeline layouts. This means that WebGPU needs the binding slot and the sampler at BGL creation.

If static samplers are defined in WGSL, the implementation can automatically generate the BGL using shader reflection. If they are defined in the WebGPU API, a sampler object has to be passed. The WebGPU API is discussed later.

Direct3D 12

Static samplers in Direct3D 12 are similar to Vulkan. Static samplers are defined when creating the root signature: D3D12_ROOT_SIGNATURE_DESC::pStaticSamplers. Similar to Vulkan, they also need a binding slot for the sampler and can be used across pipelines with the same root signature. D3D12 requires a sampler description rather than a sampler object.

Unfortunately, D3D12 defines a hard upper limit on static samplers in the specification: “The total number of unique static samplers that can be declared across all root signatures live on a D3D device at a time is limited to 2032.” Note the usage of “unique static samplers”. This implies that if there are duplicate static samplers then the drivers should deduplicate it. There are a total of 1728 unique combinations of samplers that can be created in WebGPU, disregarding LOD and anisotropy fields. The upper limit can be hit, but is unlikely.

Metal

Static samplers in metal are defined in MSL as a constexpr sampler.

constexpr sampler textureSampler (mag_filter::linear, min_filter::linear);

Metal has the most straightforward static sampler implementation, which does not require any API calls. A WGSL static sampler can be translated into the Metal equivalent when parsing WGSL.

This simplicity poses a limitation for the static samplers when defining them through the WebGPU API. Consider a situation where a sampler is only declared in WGSL but the sampler description is defined via the API.

@group(X) @binding(Y) const mySampler;

If the description is provided at runtime, the implementation has to modify the Metal source or Metal-IR in order to complete the sampler definition. However, we can not require implementations to modify Metal source or Metal-IR because precompiling shaders would not be possible and Metal-IR is not documented. As a consequence, we must require the full sampler description in WGSL and in the API.

WGSL Syntax

This is an open topic and feedback is appreciated. There are many options for the syntax, but here is the most sensible.

There could be a sampler struct that corresponds to GPUSamplerDescriptor with the same defaults:

@group(X) @binding(Y) const mySampler = sampler {
addressModeU: mirror_repeat, // enumerant
magFilter: linear,
lodMinClamp: 1, // abstract float
...
};

However, this design needs struct literal syntax which does not exist in WebGPU.

WebGPU API

The static samplers are bound to the BGL, so they need to be defined in the BGL before using them in pipeline layouts. There needs to be a way to declare them in the BGL. There has been discussion on this topic: webgpu-native/webgpu-headers#284.
A new structure is introduced that will be chained to WGPUBindGroupLayoutEntry:

struct WGPUStaticSamplerBindingLayout {
	WGPUChainedStruct chain;
	WGPUSampler sampler; 
};

This structure expects a sampler object with the same description as the static sampler in WGSL shader. The sampler object can be converted into a D3D12 static sampler description and a VkSampler object in Vulkan.

Auto Layouts

The user can request to create a pipeline with an auto pipeline layout and this would take care of the static sampler definitions in the BGL for the user. This approach allow the user to only specify the static samplers in WGSL and forget about them in the API.

Improvements

Partial Auto Layouts

Currently if the user wants to override the auto layout for just one binding point (let’s say a static sampler), you have to explicitly write out every BGL for the entry point. This is cumbersome and can be avoided by introducing partial auto layouts. Issue: #2637. That proposal only allows mixing explicit and auto BGLs but this partial auto layout proposed here would allow specifying the binding slots to override.

This will allow the user to use auto pipeline generation and only override certain binding slots. The overrides act as an input for the auto pipeline layout algorithm. If the auto pipeline layout is incorrect in some circumstances, partial auto layouts avoid writing every BGL by hand. To achieve partial auto layouts, pipeline creation would take an array of (group index, binding index, bind group layout entry) and replace the bind group layout entry at the specified slot. These layouts would still be non-shareable.

Shader Reflection

Instead of redundant typing of the same sampler description in the BGL and WGSL, we can leverage shader reflection. New method for retrieving the sampler description from the shader module can simplify the use of static samplers.

WGPUSamplerDescriptor wgpuGetStaticSamplerDescriptor(WGPUShaderModule module, uint32_t group, uint32_t binding); 

The method can be used to create a new sampler and fill in WGPUStaticSamplerBindingLayout.

Validation

Static sampler validation would happen when creating the BGL. The validation layer should check if the sampler descriptor defined in the BGL is equal to the one in the shader and report it. If this happens for Vulkan or D3D12 the implementation can continue to use the static samplers as defined in the BGL and for Metal, it can continue to use the static sampler in the shader and ignore the BGL definition. This is not valid usage, but a method of keeping the program running.

D3D12 Limit

Limit of 2032 samplers in D3D12 is abundant for every application. As previously mentioned, the maximum number of combinations achievable in WebGPU is 1728 without considering LOD and anisotropy. However, if the limit is reached, implementations can lose the WebGPU device because the application is probably allocating static samplers unintendedly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    apiWebGPU APIproposalwgslWebGPU Shading Language Issues

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions