hostBlock()
Function in Layout
Declare a host-owned uniform block: a whole struct of values the host supplies, from one declaration that works on both targets.
import { hostBlock } from 'typeshade'
The signature, the description and the examples come from the compiler's own source at commit 26de7be8.
Syntax
function hostBlock<F extends Record<string, UniformFieldSpec>>( typeName: string, at: { group: number; binding: number; as: string }, fields: F, opts?: { glsl?: 'std140-block' | 'loose'; precision?: 'highp' | 'mediump' | 'lowp' },): UniformStruct<F>Parameters
typeNamestringthe struct’s type name, as the host spells it.
at{ group: number; binding: number; as: string }the WGSL
groupandbindingslot, andas, the block variable’s name.fieldsF extends Record<string, UniformFieldSpec>the members, in the host’s declaration order.
optsoptional{ glsl?: 'std140-block' | 'loose'; precision?: 'highp' | 'mediump' | 'lowp' }glslpicks the GLSL spelling;precisionis a GLSL-only qualifier applied to each member of a'loose'block (a std140 block takes the stage default).
Return value
the UniformStruct handle; camera.field.u_matrix is typed against the
declared shape.
Exceptions
SD0016SD0016 when
glsl: 'loose'is asked for a member the default block cannot spell.UnsupportedFeatureErrorTheir names must also be unique across every loose block in the module, since flattening puts them all in one namespace; a collision throws UnsupportedFeatureError at GLSL emit.
Description
On WGSL a host-owned bind group is one unit: the host hands the module @group(0) and its
layout is the authority. That is why a block is its own declaration and cannot be written
as several hostUniform calls, which would describe a different program.
On WGSL it is an ordinary @group(N) @binding(M) var<uniform> block, which the shader
still declares in order to read it, and reflect marks every entry owner: 'host'
so a consumer knows not to build a layout for it.
On GLSL ES 3.00 the spelling is the caller’s choice, because a GLSL host prelude provides one or the other and only the matching one links:
glsl: 'std140-block'(the default) emitslayout(std140) uniform CameraUniforms { ... } u_camera;.glsl: 'loose'emits oneuniform mat4 u_matrix;per member and rewrites everyu_camera.u_matrixread to the bareu_matrix. The rewrite happens on the module’s node graph before emit, so it cannot touch an unrelated substring, it survivesminify(), andreflectstill describes what was emitted.
A loose block’s members must be scalars, vectors or matrices, because the default block
has no spelling for a nested struct; this call checks it and throws SD0016. Their names
must also be unique across every loose block in the module, since flattening puts them all
in one namespace; a collision throws UnsupportedFeatureError at GLSL emit.
Examples
Example
import { hostBlock, mat4x4fT, vec2fT } from 'typeshade'
const camera = hostBlock('CameraUniforms', { group: 0, binding: 0, as: 'u_camera' }, { u_matrix: mat4x4fT, u_viewport_px: vec2fT,}, { glsl: 'loose' })
camera.field.u_matrix // typed against the declared shapeIn the guide
See also
Source
src/core/sot.ts, line 972, at commit 26de7be8