bindTexture method
bool
bindTexture(
- ShaderHandle shader,
- String slot,
- TextureHandle texture, {
- SamplerOptions? sampler,
Binds texture to the sampler called slot in shader.
One name becomes two bindings, which is the shape of the whole
problem this package's GLSL is edited to solve: sampler2D is one object
in GLSL and two in WGSL, as it is in Vulkan and Metal, so the reflection
carries the pair and this splits the bind across them.
False for a slot this stage does not declare, as the contract says, and never a throw: a stage that optimised a sampler away is not a caller mistake, and the caller that did make one is told by the return value.
A null sampler is SamplerOptions.linearRepeat — the contract's
default, not the constructor's, which is nearest and clamp and which cost
a third backend two percent of every textured golden before the rule was
written down.
Implementation
@override
bool bindTexture(
ShaderHandle shader,
String slot,
TextureHandle texture, {
SamplerOptions? sampler,
}) {
if (!shader.mayBindSampler(slot)) return false;
final stage = shader.backend as WebGpuShader;
final declared = stage.samplerNamed(slot);
if (declared == null) return false;
final backend = texture.backend as WebGpuTexture;
assert(
backend.sampleable,
'the "$slot" slot was handed a texture that is multisampled or '
'deviceTransient, which on this backend is allocated without '
'TEXTURE_BINDING and can only ever be an attachment',
);
_views.putIfAbsent(
declared.group,
() => <int, GPUTextureView>{},
)[declared.textureBinding] = backend.sampledView;
_samplers.putIfAbsent(
declared.group,
() => <int, GPUSampler>{},
)[declared.samplerBinding] = _device.samplerFor(
sampler ?? SamplerOptions.linearRepeat,
);
return true;
}