/// Information about buffer bindings, which /// is validated against the shader (and pipeline) /// at draw time as opposed to initialization time. #[derive(Debug, Default)] pub(crate) struct LateSizedBufferGroup { // The order has to match `BindGroup::late_buffer_binding_sizes`. pub(crate) shader_sizes: Vec<wgt::BufferAddress>,
}
#[allow(clippy::large_enum_variant)] pubenum ShaderModuleSource<'a> { #[cfg(feature = "wgsl")]
Wgsl(Cow<'a, str>), #[cfg(feature = "glsl")]
Glsl(Cow<'a, str>, naga::front::glsl::Options), #[cfg(feature = "spirv")]
SpirV(Cow<'a, [u32]>, naga::front::spv::Options),
Naga(Cow<'static, naga::Module>), /// Dummy variant because `Naga` doesn't have a lifetime and without enough active features it /// could be the last one active. #[doc(hidden)]
Dummy(PhantomData<&'a ()>),
}
#[derive(Debug)] pubstruct ShaderModule { pub(crate) raw: ManuallyDrop<Box<dyn hal::DynShaderModule>>, pub(crate) device: Arc<Device>, pub(crate) interface: ShaderMetaData, /// The `label` from the descriptor used to create the resource. pub(crate) label: String,
}
impl Drop for ShaderModule { fn drop(&mutself) {
resource_log!("Destroy raw {}", self.error_ident()); // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mutself.raw) }; unsafe { self.device.raw().destroy_shader_module(raw);
}
}
}
/// Describes a programmable pipeline stage. #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pubstruct ProgrammableStageDescriptor<'a, SM = ShaderModuleId> { /// The compiled shader module for this stage. pub module: SM, /// The name of the entry point in the compiled shader. The name is selected using the /// following logic: /// /// * If `Some(name)` is specified, there must be a function with this name in the shader. /// * If a single entry point associated with this stage must be in the shader, then proceed as /// if `Some(…)` was specified with that entry point's name. pub entry_point: Option<Cow<'a, str>>, /// Specifies the values of pipeline-overridable constants in the shader module. /// /// If an `@id` attribute was specified on the declaration, /// the key must be the pipeline constant ID as a decimal ASCII number; if not, /// the key must be the constant's identifier name. /// /// The value may represent any of WGSL's concrete scalar types. pub constants: naga::back::PipelineConstants, /// Whether workgroup scoped memory will be initialized with zero values for this stage. /// /// This is required by the WebGPU spec, but may have overhead which can be avoided /// for cross-platform applications pub zero_initialize_workgroup_memory: bool,
}
/// Describes a compute pipeline. #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pubstruct ComputePipelineDescriptor< 'a,
PLL = PipelineLayoutId,
SM = ShaderModuleId,
PLC = PipelineCacheId,
> { pub label: Label<'a>, /// The layout of bind groups for this pipeline. pub layout: Option<PLL>, /// The compiled compute stage and its entry point. pub stage: ProgrammableStageDescriptor<'a, SM>, /// The pipeline cache to use when creating this pipeline. pub cache: Option<PLC>,
}
#[derive(Debug)] pubstruct ComputePipeline { pub(crate) raw: ManuallyDrop<Box<dyn hal::DynComputePipeline>>, pub(crate) layout: Arc<PipelineLayout>, pub(crate) device: Arc<Device>, pub(crate) _shader_module: Arc<ShaderModule>, pub(crate) late_sized_buffer_groups: ArrayVec<LateSizedBufferGroup, { hal::MAX_BIND_GROUPS }>, pub(crate) immediate_slots_required: naga::valid::ImmediateSlots, /// The `label` from the descriptor used to create the resource. pub(crate) label: String, pub(crate) tracking_data: TrackingData,
}
impl Drop for ComputePipeline { fn drop(&mutself) {
resource_log!("Destroy raw {}", self.error_ident()); // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mutself.raw) }; unsafe { self.device.raw().destroy_compute_pipeline(raw);
}
}
}
#[derive(Debug)] pubstruct PipelineCache { pub(crate) raw: ManuallyDrop<Box<dyn hal::DynPipelineCache>>, pub(crate) device: Arc<Device>, /// The `label` from the descriptor used to create the resource. pub(crate) label: String,
}
impl Drop for PipelineCache { fn drop(&mutself) {
resource_log!("Destroy raw {}", self.error_ident()); // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mutself.raw) }; unsafe { self.device.raw().destroy_pipeline_cache(raw);
}
}
}
/// Describes how the vertex buffer is interpreted. #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pubstruct VertexBufferLayout<'a> { /// The stride, in bytes, between elements of this buffer. pub array_stride: wgt::BufferAddress, /// How often this vertex buffer is "stepped" forward. pub step_mode: wgt::VertexStepMode, /// The list of attributes which comprise a single vertex. pub attributes: Cow<'a, [wgt::VertexAttribute]>,
}
/// A null vertex buffer layout that may be placed in unused slots. impl Default for VertexBufferLayout<'_> { fn default() -> Self { Self {
array_stride: Default::default(),
step_mode: Default::default(),
attributes: Cow::Borrowed(&[]),
}
}
}
/// Describes the vertex process in a render pipeline. #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pubstruct VertexState<'a, SM = ShaderModuleId> { /// The compiled vertex stage and its entry point. pub stage: ProgrammableStageDescriptor<'a, SM>, /// The format of any vertex buffers used with this pipeline. pub buffers: Cow<'a, [Option<VertexBufferLayout<'a>>]>,
}
/// Describes fragment processing in a render pipeline. #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pubstruct FragmentState<'a, SM = ShaderModuleId> { /// The compiled fragment stage and its entry point. pub stage: ProgrammableStageDescriptor<'a, SM>, /// The effect of draw calls on the color aspect of the output target. pub targets: Cow<'a, [Option<wgt::ColorTargetState>]>,
}
/// Describes a vertex processor for either a conventional or mesh shading /// pipeline architecture. /// /// This is not a public API. It is for use by `player` only. The public APIs /// are [`VertexState`], [`TaskState`], and [`MeshState`]. /// /// cbindgen:ignore #[doc(hidden)] #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pubenum RenderPipelineVertexProcessor<'a, SM = ShaderModuleId> {
Vertex(VertexState<'a, SM>),
Mesh(Option<TaskState<'a, SM>>, MeshState<'a, SM>),
}
/// Describes a render (graphics) pipeline. #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pubstruct RenderPipelineDescriptor< 'a,
PLL = PipelineLayoutId,
SM = ShaderModuleId,
PLC = PipelineCacheId,
> { pub label: Label<'a>, /// The layout of bind groups for this pipeline. pub layout: Option<PLL>, /// The vertex processing state for this pipeline. pub vertex: VertexState<'a, SM>, /// The properties of the pipeline at the primitive assembly and rasterization level. #[cfg_attr(feature = "serde", serde(default))] pub primitive: wgt::PrimitiveState, /// The effect of draw calls on the depth and stencil aspects of the output target, if any. #[cfg_attr(feature = "serde", serde(default))] pub depth_stencil: Option<wgt::DepthStencilState>, /// The multi-sampling properties of the pipeline. #[cfg_attr(feature = "serde", serde(default))] pub multisample: wgt::MultisampleState, /// The fragment processing state for this pipeline. pub fragment: Option<FragmentState<'a, SM>>, /// If the pipeline will be used with a multiview render pass, this indicates how many array /// layers the attachments will have. pub multiview_mask: Option<NonZeroU32>, /// The pipeline cache to use when creating this pipeline. pub cache: Option<PLC>,
} /// Describes a mesh shader pipeline. #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pubstruct MeshPipelineDescriptor< 'a,
PLL = PipelineLayoutId,
SM = ShaderModuleId,
PLC = PipelineCacheId,
> { pub label: Label<'a>, /// The layout of bind groups for this pipeline. pub layout: Option<PLL>, /// The task processing state for this pipeline. pub task: Option<TaskState<'a, SM>>, /// The mesh processing state for this pipeline pub mesh: MeshState<'a, SM>, /// The properties of the pipeline at the primitive assembly and rasterization level. #[cfg_attr(feature = "serde", serde(default))] pub primitive: wgt::PrimitiveState, /// The effect of draw calls on the depth and stencil aspects of the output target, if any. #[cfg_attr(feature = "serde", serde(default))] pub depth_stencil: Option<wgt::DepthStencilState>, /// The multi-sampling properties of the pipeline. #[cfg_attr(feature = "serde", serde(default))] pub multisample: wgt::MultisampleState, /// The fragment processing state for this pipeline. pub fragment: Option<FragmentState<'a, SM>>, /// If the pipeline will be used with a multiview render pass, this indicates how many array /// layers the attachments will have. pub multiview: Option<NonZeroU32>, /// The pipeline cache to use when creating this pipeline. pub cache: Option<PLC>,
}
/// Describes a render (graphics) pipeline, with either conventional or mesh /// shading architecture. /// /// This is not a public API. It is for use by `player` only. The public APIs /// are [`RenderPipelineDescriptor`] and [`MeshPipelineDescriptor`]. /// /// cbindgen:ignore #[doc(hidden)] #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pubstruct GeneralRenderPipelineDescriptor< 'a,
PLL = PipelineLayoutId,
SM = ShaderModuleId,
PLC = PipelineCacheId,
> { pub label: Label<'a>, /// The layout of bind groups for this pipeline. pub layout: Option<PLL>, /// The vertex processing state for this pipeline. pub vertex: RenderPipelineVertexProcessor<'a, SM>, /// The properties of the pipeline at the primitive assembly and rasterization level. #[cfg_attr(feature = "serde", serde(default))] pub primitive: wgt::PrimitiveState, /// The effect of draw calls on the depth and stencil aspects of the output target, if any. #[cfg_attr(feature = "serde", serde(default))] pub depth_stencil: Option<wgt::DepthStencilState>, /// The multi-sampling properties of the pipeline. #[cfg_attr(feature = "serde", serde(default))] pub multisample: wgt::MultisampleState, /// The fragment processing state for this pipeline. pub fragment: Option<FragmentState<'a, SM>>, /// If the pipeline will be used with a multiview render pass, this indicates how many array /// layers the attachments will have. pub multiview_mask: Option<NonZeroU32>, /// The pipeline cache to use when creating this pipeline. pub cache: Option<PLC>,
} impl<'a, PLL, SM, PLC> From<RenderPipelineDescriptor<'a, PLL, SM, PLC>> for GeneralRenderPipelineDescriptor<'a, PLL, SM, PLC>
{ fn from(value: RenderPipelineDescriptor<'a, PLL, SM, PLC>) -> Self { Self {
label: value.label,
layout: value.layout,
vertex: RenderPipelineVertexProcessor::Vertex(value.vertex),
primitive: value.primitive,
depth_stencil: value.depth_stencil,
multisample: value.multisample,
fragment: value.fragment,
multiview_mask: value.multiview_mask,
cache: value.cache,
}
}
} impl<'a, PLL, SM, PLC> From<MeshPipelineDescriptor<'a, PLL, SM, PLC>> for GeneralRenderPipelineDescriptor<'a, PLL, SM, PLC>
{ fn from(value: MeshPipelineDescriptor<'a, PLL, SM, PLC>) -> Self { Self {
label: value.label,
layout: value.layout,
vertex: RenderPipelineVertexProcessor::Mesh(value.task, value.mesh),
primitive: value.primitive,
depth_stencil: value.depth_stencil,
multisample: value.multisample,
fragment: value.fragment,
multiview_mask: value.multiview,
cache: value.cache,
}
}
}
/// Not a public API. For use by `player` only. /// /// cbindgen:ignore pubtype ResolvedGeneralRenderPipelineDescriptor<'a> =
GeneralRenderPipelineDescriptor<'a, Arc<PipelineLayout>, Arc<ShaderModule>, Arc<PipelineCache>>;
#[derive(Clone, Debug, Error)] #[non_exhaustive] pubenum ColorStateError { #[error("Format {0:?} is not renderable")]
FormatNotRenderable(wgt::TextureFormat), #[error("Format {0:?} is not blendable")]
FormatNotBlendable(wgt::TextureFormat), #[error("Format {0:?} does not have a color aspect")]
FormatNotColor(wgt::TextureFormat), #[error("Sample count {0} is not supported by format {1:?} on this device. The WebGPU spec guarantees {2:?} samples are supported by this format. With the TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES feature your device supports {3:?}.")]
InvalidSampleCount(u32, wgt::TextureFormat, Vec<u32>, Vec<u32>), #[error("Output format {pipeline} is incompatible with the shader {shader}")]
IncompatibleFormat {
pipeline: validation::NumericType,
shader: validation::NumericType,
}, #[error("Invalid write mask {0:?}")]
InvalidWriteMask(wgt::ColorWrites), #[error("Using the blend factor {factor:?} for render target {target} is not possible. Only the first render target may be used when dual-source blending.")]
BlendFactorOnUnsupportedTarget {
factor: wgt::BlendFactor,
target: u32,
}, #[error( "Blend factor {factor:?} for render target {target} is not valid. Blend factor must be `one` when using min/max blend operations."
)]
InvalidMinMaxBlendFactor {
factor: wgt::BlendFactor,
target: u32,
},
}
#[derive(Clone, Debug, Error)] #[non_exhaustive] pubenum DepthStencilStateError { #[error("Format {0:?} is not renderable")]
FormatNotRenderable(wgt::TextureFormat), #[error("Format {0:?} is not a depth/stencil format")]
FormatNotDepthOrStencil(wgt::TextureFormat), #[error("Format {0:?} does not have a depth aspect, but depth test/write is enabled")]
FormatNotDepth(wgt::TextureFormat), #[error("Format {0:?} does not have a stencil aspect, but stencil test/write is enabled")]
FormatNotStencil(wgt::TextureFormat), #[error("Sample count {0} is not supported by format {1:?} on this device. The WebGPU spec guarantees {2:?} samples are supported by this format. With the TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES feature your device supports {3:?}.")]
InvalidSampleCount(u32, wgt::TextureFormat, Vec<u32>, Vec<u32>), #[error("Depth bias is not compatible with non-triangle topology {0:?}")]
DepthBiasWithIncompatibleTopology(wgt::PrimitiveTopology), #[error("Depth compare function must be specified for depth format {0:?}")]
MissingDepthCompare(wgt::TextureFormat), #[error("Depth write enabled must be specified for depth format {0:?}")]
MissingDepthWriteEnabled(wgt::TextureFormat),
}
#[derive(Clone, Debug, Error)] #[non_exhaustive] pubenum CreateRenderPipelineError { #[error(transparent)]
ColorAttachment(#[from] ColorAttachmentError), #[error(transparent)]
Device(#[from] DeviceError), #[error("Unable to derive an implicit layout")]
Implicit(#[from] ImplicitLayoutError), #[error("Color state [{0}] is invalid")]
ColorState(u8, #[source] ColorStateError), #[error("Depth/stencil state is invalid")]
DepthStencilState(#[from] DepthStencilStateError), #[error("Invalid sample count {0}")]
InvalidSampleCount(u32), #[error("The number of vertex buffers {given} exceeds the limit {limit}")]
TooManyVertexBuffers { given: u32, limit: u32 }, #[error("The number of bind groups + vertex buffers {given} exceeds the limit {limit}")]
TooManyBindGroupsPlusVertexBuffers { given: u32, limit: u32 }, #[error("The total number of vertex attributes {given} exceeds the limit {limit}")]
TooManyVertexAttributes { given: u32, limit: u32 }, #[error("Vertex attribute location {given} must be less than limit {limit}")]
VertexAttributeLocationTooLarge { given: u32, limit: u32 }, #[error("Vertex buffer {index} stride {given} exceeds the limit {limit}")]
VertexStrideTooLarge { index: u32, given: u32, limit: u32 }, #[error("Vertex attribute at location {location} stride {given} exceeds the limit {limit}")]
VertexAttributeStrideTooLarge {
location: wgt::ShaderLocation,
given: u32,
limit: u32,
}, #[error("Vertex buffer {index} stride {stride} does not respect `VERTEX_ALIGNMENT`")]
UnalignedVertexStride {
index: u32,
stride: wgt::BufferAddress,
}, #[error("Vertex attribute at location {location} has invalid offset {offset}")]
InvalidVertexAttributeOffset {
location: wgt::ShaderLocation,
offset: wgt::BufferAddress,
}, #[error("Two or more vertex attributes were assigned to the same location in the shader: {0}")]
ShaderLocationClash(u32), #[error("Strip index format was not set to None but to {strip_index_format:?} while using the non-strip topology {topology:?}")]
StripIndexFormatForNonStripTopology {
strip_index_format: Option<wgt::IndexFormat>,
topology: wgt::PrimitiveTopology,
}, #[error("Conservative Rasterization is only supported for wgt::PolygonMode::Fill")]
ConservativeRasterizationNonFillPolygonMode, #[error(transparent)]
MissingFeatures(#[from] MissingFeatures), #[error(transparent)]
MissingDownlevelFlags(#[from] MissingDownlevelFlags), #[error("Error matching {stage:?} shader requirements against the pipeline")]
Stage {
stage: wgt::ShaderStages, #[source]
error: validation::StageError,
}, #[error("Internal error in {stage:?} shader: {error}")]
Internal {
stage: wgt::ShaderStages,
error: String,
}, #[error("Pipeline constant error in {stage:?} shader: {error}")]
PipelineConstants {
stage: wgt::ShaderStages,
error: String,
}, #[error("In the provided shader, the type given for group {group} binding {binding} has a size of {size}. As the device does not support `DownlevelFlags::BUFFER_BINDINGS_NOT_16_BYTE_ALIGNED`, the type must have a size that is a multiple of 16 bytes.")]
UnalignedShader { group: u32, binding: u32, size: u64 }, #[error("Dual-source blending requires exactly one color target, but {count} color targets are present")]
DualSourceBlendingWithMultipleColorTargets { count: usize }, #[error("{}", concat!( "At least one color attachment or depth-stencil attachment was expected, ", "but no render target for the pipeline was specified."
))]
NoTargetSpecified, #[error(transparent)]
InvalidResource(#[from] InvalidResourceError),
}
/// How a render pipeline will retrieve attributes from a particular vertex buffer. #[derive(Clone, Copy, Debug)] pubstruct VertexStep { /// The byte stride in the buffer between one attribute value and the next. pub stride: wgt::BufferAddress,
/// The byte size required to fit the last vertex in the stream. pub last_stride: wgt::BufferAddress,
/// Whether the buffer is indexed by vertex number or instance number. pub mode: wgt::VertexStepMode,
}
#[derive(Debug)] pubstruct RenderPipeline { pub(crate) raw: ManuallyDrop<Box<dyn hal::DynRenderPipeline>>, pub(crate) device: Arc<Device>, pub(crate) layout: Arc<PipelineLayout>, pub(crate) _shader_modules: ArrayVec<Arc<ShaderModule>, { hal::MAX_CONCURRENT_SHADER_STAGES }>, pub(crate) pass_context: RenderPassContext, pub(crate) flags: PipelineFlags, pub(crate) topology: wgt::PrimitiveTopology, pub(crate) strip_index_format: Option<wgt::IndexFormat>, pub(crate) vertex_steps: Vec<Option<VertexStep>>, pub(crate) late_sized_buffer_groups: ArrayVec<LateSizedBufferGroup, { hal::MAX_BIND_GROUPS }>, pub(crate) immediate_slots_required: naga::valid::ImmediateSlots, /// The `label` from the descriptor used to create the resource. pub(crate) label: String, pub(crate) tracking_data: TrackingData, /// Whether this is a mesh shader pipeline pub(crate) is_mesh: bool, pub(crate) has_task_shader: bool,
}
impl Drop for RenderPipeline { fn drop(&mutself) {
resource_log!("Destroy raw {}", self.error_ident()); // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mutself.raw) }; unsafe { self.device.raw().destroy_render_pipeline(raw);
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.