pubusecrate::pipeline_cache::PipelineCacheValidationError; usecrate::{
binding_model::{CreateBindGroupLayoutError, CreatePipelineLayoutError, PipelineLayout},
command::ColorAttachmentError,
device::{Device, DeviceError, MissingDownlevelFlags, MissingFeatures, RenderPassContext},
id::{PipelineCacheId, PipelineLayoutId, ShaderModuleId},
resource::{InvalidResourceError, Labeled, TrackingData},
resource_log, validation, Label,
}; use arrayvec::ArrayVec; use naga::error::ShaderError; use std::{borrow::Cow, marker::PhantomData, mem::ManuallyDrop, num::NonZeroU32, sync::Arc}; use thiserror::Error;
/// Information about buffer bindings, which /// is validated against the shader (and pipeline) /// at draw time as opposed to initialization time. #[derive(Debug)] 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: Option<validation::Interface>, /// 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);
}
}
}
//Note: `Clone` would require `WithSpan: Clone`. #[derive(Clone, Debug, Error)] #[non_exhaustive] pubenum CreateShaderModuleError { #[cfg(any(feature = "wgsl", feature = "indirect-validation"))] #[error(transparent)]
Parsing(#[from] ShaderError<naga::front::wgsl::ParseError>), #[cfg(feature = "glsl")] #[error(transparent)]
ParsingGlsl(#[from] ShaderError<naga::front::glsl::ParseErrors>), #[cfg(feature = "spirv")] #[error(transparent)]
ParsingSpirV(#[from] ShaderError<naga::front::spv::Error>), #[error("Failed to generate the backend-specific code")]
Generation, #[error(transparent)]
Device(#[from] DeviceError), #[error(transparent)]
Validation(#[from] ShaderError<naga::WithSpan<naga::valid::ValidationError>>), #[error(transparent)]
MissingFeatures(#[from] MissingFeatures), #[error( "Shader global {bind:?} uses a group index {group} that exceeds the max_bind_groups limit of {limit}."
)]
InvalidGroupIndex {
bind: naga::ResourceBinding,
group: u32,
limit: u32,
},
}
/// Describes a programmable pipeline stage. #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pubstruct ProgrammableStageDescriptor<'a> { /// The compiled shader module for this stage. pub module: ShaderModuleId, /// 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: Cow<'a, 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 programmable pipeline stage. #[derive(Clone, Debug)] pubstruct ResolvedProgrammableStageDescriptor<'a> { /// The compiled shader module for this stage. pub module: Arc<ShaderModule>, /// 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: Cow<'a, 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,
}
/// Number of implicit bind groups derived at pipeline creation. pubtype ImplicitBindGroupCount = u8;
#[derive(Clone, Debug, Error)] #[non_exhaustive] pubenum ImplicitLayoutError { #[error("The implicit_pipeline_ids arg is required")]
MissingImplicitPipelineIds, #[error("Missing IDs for deriving {0} bind groups")]
MissingIds(ImplicitBindGroupCount), #[error("Unable to reflect the shader {0:?} interface")]
ReflectionError(wgt::ShaderStages), #[error(transparent)]
BindGroup(#[from] CreateBindGroupLayoutError), #[error(transparent)]
Pipeline(#[from] CreatePipelineLayoutError),
}
/// Describes a compute pipeline. #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pubstruct ComputePipelineDescriptor<'a> { pub label: Label<'a>, /// The layout of bind groups for this pipeline. pub layout: Option<PipelineLayoutId>, /// The compiled compute stage and its entry point. pub stage: ProgrammableStageDescriptor<'a>, /// The pipeline cache to use when creating this pipeline. pub cache: Option<PipelineCacheId>,
}
/// Describes a compute pipeline. #[derive(Clone, Debug)] pubstruct ResolvedComputePipelineDescriptor<'a> { pub label: Label<'a>, /// The layout of bind groups for this pipeline. pub layout: Option<Arc<PipelineLayout>>, /// The compiled compute stage and its entry point. pub stage: ResolvedProgrammableStageDescriptor<'a>, /// The pipeline cache to use when creating this pipeline. pub cache: Option<Arc<PipelineCache>>,
}
#[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 }>, /// 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]>,
}
/// Describes the vertex process in a render pipeline. #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pubstruct VertexState<'a> { /// The compiled vertex stage and its entry point. pub stage: ProgrammableStageDescriptor<'a>, /// The format of any vertex buffers used with this pipeline. pub buffers: Cow<'a, [VertexBufferLayout<'a>]>,
}
/// Describes the vertex process in a render pipeline. #[derive(Clone, Debug)] pubstruct ResolvedVertexState<'a> { /// The compiled vertex stage and its entry point. pub stage: ResolvedProgrammableStageDescriptor<'a>, /// The format of any vertex buffers used with this pipeline. pub buffers: Cow<'a, [VertexBufferLayout<'a>]>,
}
/// Describes fragment processing in a render pipeline. #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pubstruct FragmentState<'a> { /// The compiled fragment stage and its entry point. pub stage: ProgrammableStageDescriptor<'a>, /// The effect of draw calls on the color aspect of the output target. pub targets: Cow<'a, [Option<wgt::ColorTargetState>]>,
}
/// Describes fragment processing in a render pipeline. #[derive(Clone, Debug)] pubstruct ResolvedFragmentState<'a> { /// The compiled fragment stage and its entry point. pub stage: ResolvedProgrammableStageDescriptor<'a>, /// The effect of draw calls on the color aspect of the output target. pub targets: Cow<'a, [Option<wgt::ColorTargetState>]>,
}
/// Describes a render (graphics) pipeline. #[derive(Clone, Debug)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pubstruct RenderPipelineDescriptor<'a> { pub label: Label<'a>, /// The layout of bind groups for this pipeline. pub layout: Option<PipelineLayoutId>, /// The vertex processing state for this pipeline. pub vertex: VertexState<'a>, /// 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>>, /// 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<PipelineCacheId>,
}
/// Describes a render (graphics) pipeline. #[derive(Clone, Debug)] pubstruct ResolvedRenderPipelineDescriptor<'a> { pub label: Label<'a>, /// The layout of bind groups for this pipeline. pub layout: Option<Arc<PipelineLayout>>, /// The vertex processing state for this pipeline. pub vertex: ResolvedVertexState<'a>, /// The properties of the pipeline at the primitive assembly and rasterization level. pub primitive: wgt::PrimitiveState, /// The effect of draw calls on the depth and stencil aspects of the output target, if any. pub depth_stencil: Option<wgt::DepthStencilState>, /// The multi-sampling properties of the pipeline. pub multisample: wgt::MultisampleState, /// The fragment processing state for this pipeline. pub fragment: Option<ResolvedFragmentState<'a>>, /// 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<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),
}
#[derive(Clone, Debug, Error)] #[non_exhaustive] pubenum DepthStencilStateError { #[error("Format {0:?} is not renderable")]
FormatNotRenderable(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>),
}
#[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 total number of vertex attributes {given} exceeds the limit {limit}")]
TooManyVertexAttributes { 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_STRIDE_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("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("Pipeline expects the shader entry point to make use of dual-source blending.")]
PipelineExpectsShaderToUseDualSourceBlending, #[error("Shader entry point expects the pipeline to make use of dual-source blending.")]
ShaderExpectsPipelineToUseDualSourceBlending, #[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) strip_index_format: Option<wgt::IndexFormat>, pub(crate) vertex_steps: Vec<VertexStep>, pub(crate) late_sized_buffer_groups: ArrayVec<LateSizedBufferGroup, { hal::MAX_BIND_GROUPS }>, /// The `label` from the descriptor used to create the resource. pub(crate) label: String, pub(crate) tracking_data: TrackingData,
}
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.