pub struct LitVariant {
pub options: Hashed<LitOptions>,
pub surface: SurfaceKey,
pub channels: LitVertexChannels,
pub base_color_texture: bool,
pub morph: bool,
pub strip_index_format: Option<IndexFormat>,
}Expand description
The complete identity of a built-in lit pipeline, and its blueprint.
A family resolves one from an entity’s LitOptions and the facts its
draw carries: the mesh’s vertex channels, whether the draw binds a material,
whether the mesh morphs, the mesh’s index format and the render target. Two
draws that agree on all of it share one compiled pipeline; because the
variant is the complete description of the blueprint, the cache key is
canonical by construction.
Fields§
§options: Hashed<LitOptions>The caller’s policy, with its hash computed once. The variant is the
cache key, so the stored word is what every per-frame lookup hashes;
rewrite the policy through Hashed::update rather than the value
itself, so the word follows the change.
surface: SurfaceKeyThe render target the pipeline is built for.
channels: LitVertexChannelsThe per-vertex channels the mesh’s layout carries.
base_color_texture: boolWhether the draw binds a material group and so samples a base-color texture.
morph: boolWhether the mesh carries morph displacements.
strip_index_format: Option<IndexFormat>The strip index format the mesh’s index buffer requires, if any.
Implementations§
Source§impl LitVariant
impl LitVariant
Sourcefn features(&self, texel_arrays: bool) -> [(&'static str, bool); 17]
fn features(&self, texel_arrays: bool) -> [(&'static str, bool); 17]
The WESL @if features the variant asks for, paired with their state.
Every name appears, so the composed variant never sees a name it does
not know. The per-vertex names come from Self::channels, the material
one from Self::base_color_texture and the policy ones from
Self::options. The per-instance record is not conditional at all, so
it contributes no names here: the built-in vertex stream always
declares and binds an instance buffer.
texel_arrays is the device’s answer rather than the variant’s, so it
is passed in from the caller that read the device.
Sourcepub fn needs_joints(&self) -> bool
pub fn needs_joints(&self) -> bool
Whether the variant deforms its vertices by joint matrices and so reads the global group’s array of them.
Sourcepub fn needs_morphs(&self) -> bool
pub fn needs_morphs(&self) -> bool
Whether the variant reads the global group’s morph arrays: the per-instance weights and the per-mesh displacements.
Sourcepub fn needs_metadata(&self) -> bool
pub fn needs_metadata(&self) -> bool
Whether the variant reads the global group’s mesh-metadata array: the per-mesh decode parameters and the addressing a morph reads.
Mirrors the shader’s metadata condition, so the layout and the composed variant agree on whether the binding exists. A morph needs the array even when every channel is uncompressed, because the struct also carries the vertex offset and morph count its displacements are addressed by.
Sourcepub fn secondary_stream(&self) -> SecondaryStreamWriter
pub fn secondary_stream(&self) -> SecondaryStreamWriter
The secondary vertex stream this variant expects.
The stream is described in crate::mesh’s own terms: this variant’s
channels are translated into the ones that make up a vertex stream, so
packing meshes for this pipeline needs nothing specific to it.
Sourcepub fn position_stream(&self) -> PositionStreamWriter
pub fn position_stream(&self) -> PositionStreamWriter
The position vertex stream this variant expects.
The joint indices and weights the variant deforms with belong to this stream rather than one of their own, so a skinned variant’s stream is wider by the joint pair and nothing else changes.
Sourcefn assert_device_supports_arrays(&self, device: &Device, texel_arrays: bool)
fn assert_device_supports_arrays(&self, device: &Device, texel_arrays: bool)
Reject a variant whose array path the device cannot serve.
The texel path works on every device — a texture read is universal — so forcing it on a device that also has storage buffers is allowed. The reverse is not: a bind-group layout naming a storage buffer is rejected outright by a device without them, so the failure is caught here with the reason rather than left to wgpu’s validation.
A variant that declares no array binding at all — the UI’s, which reads only full-precision vertex attributes — has nothing to serve either way, so it is not asked to pick a path.
§Panics
If the variant reads storage buffers on a device that has none.
Source§impl LitVariant
impl LitVariant
Sourcepub fn bind_group_layouts(&self, device: &Device) -> LitBindGroupLayouts
pub fn bind_group_layouts(&self, device: &Device) -> LitBindGroupLayouts
Build the bind-group layouts this variant declares, without compiling the pipeline.
The layouts come from the same variant a pipeline is built from, so the
two agree: the global group always exists, and the material group only
for a variant that samples a base-color texture. The mesh group is
always None — the built-in variants bind nothing there.
The array path is the device’s answer rather than the variant’s, so it is read here: a cache is built for one device, which is why the path never enters the variant key.
Sourcepub fn vertex_buffer_layouts(&self) -> [Option<VertexBufferLayoutDesc>; 3]
pub fn vertex_buffer_layouts(&self) -> [Option<VertexBufferLayoutDesc>; 3]
The vertex-buffer declarations the built-in shader expects, in slot order.
The first two slots follow the variant’s channels; the third is always
the instance stream, which every built-in variant binds. A slot whose
variant declares no attributes is reported as None, so a variant never
binds a buffer the shader does not declare.
Sourcefn instance_layout(&self) -> VertexBufferLayoutDesc
fn instance_layout(&self) -> VertexBufferLayoutDesc
The instance stream every built-in variant expects.
One record layout serves every variant of a frame — the source uploads a
single &[MeshInstance] buffer and binds it at INSTANCE_SLOT for
every draw — so the stride is always the whole MeshInstance. The
declared attributes mirror the shader’s own input declarations: the
model matrix, the base color, the pose bases and the metadata index
unconditionally, the alpha cutoff and the hull width under the features
that declare them.
A pipeline never declares an attribute the shader does not, which the
validation layers would otherwise flag on every draw.
Trait Implementations§
Source§impl Clone for LitVariant
impl Clone for LitVariant
Source§impl Debug for LitVariant
impl Debug for LitVariant
impl Eq for LitVariant
Source§impl Hash for LitVariant
impl Hash for LitVariant
Source§impl PartialEq for LitVariant
impl PartialEq for LitVariant
Source§impl PipelineDescriptor<RenderPipeline> for LitVariant
impl PipelineDescriptor<RenderPipeline> for LitVariant
Source§fn create(&self, device: &Device) -> RenderPipeline
fn create(&self, device: &Device) -> RenderPipeline
Compose this variant’s entry shader and build the pipeline, so a variant compiles through the same PipelineDescriptor mechanism a caller’s own descriptor does.
The entry shader is the built-in lit.wesl, with the options’ own
snippets (LitOptions::shader) spliced into it at its marks.
Source§impl PipelineVariant<RenderPipeline> for LitVariant
impl PipelineVariant<RenderPipeline> for LitVariant
Source§type Descriptor = LitVariant
type Descriptor = LitVariant
Source§fn descriptor(&self, _device: &Device) -> Self
fn descriptor(&self, _device: &Device) -> Self
impl StructuralPartialEq for LitVariant
Auto Trait Implementations§
impl Forget for LitVariant
impl Freeze for LitVariant
impl RefUnwindSafe for LitVariant
impl Send for LitVariant
impl Sync for LitVariant
impl Unpin for LitVariant
impl UnsafeUnpin for LitVariant
impl UnwindSafe for LitVariant
Blanket Implementations§
impl<T> AsId for T
impl<T> AsIdSalt for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more