bindTexture method
- ShaderHandle shader,
- String slot,
- TextureHandle texture, {
- SamplerOptions? sampler,
Binds texture to the sampler called slot in shader. False when that
stage declares no such sampler.
False, never a throw and never a silent success, on every backend.
Until 0.8.0 this returned nothing and each backend answered a slot the
stage does not have in its own way: Impeller threw "Failed to bind
texture", WebGL and WebGPU did nothing, and the software rasteriser bound
it anyway. So a renderer that handed PolylineVertex a morph texture it
never declared drew every golden on three backends and failed on Metal
at the first frame, for three releases. bindUniformBlock has always
answered the same question with a bool, and now both do. A backend with
no reflection of its stages answers true, for the reason
bindUniformBlock gives.
Asked of the stage, not of the program. A sampler the fragment stage declares is false through the vertex stage's handle, on every backend that can tell the two apart.
A shader that declares a sampler must still have something bound to it, so "no texture" is a neutral texture rather than an absent binding.
A null sampler means SamplerOptions.linearRepeat, not the
SamplerOptions constructor's own defaults.
Stated because it was not. Both hardware backends had chosen
linearRepeat independently, so they agreed and nobody wrote the rule
down; the third backend read this interface, took the constructor
defaults — nearest and clamp — and every textured picture it drew had
hard seams where the others had soft ones. Two percent of every textured
golden, and it looked like a filtering bug in the new backend rather than
a question the contract had never answered.
Implementation
@override
bool bindTexture(
ShaderHandle shader,
String slot,
TextureHandle texture, {
SamplerOptions? sampler,
}) {
if (!shader.mayBindSampler(slot)) return false;
commands.add(RecordedTexture(slot, texture, sampler, shader: shader));
if (!_declares(shader, slot, sampler: true)) return false;
_boundSamplers.putIfAbsent(shader.name, () => <String>{}).add(slot);
return true;
}