use crate::{device, pass, Backend};
mod compute;
mod descriptor;
mod graphics;
mod input_assembler;
mod output_merger;
mod specialization;
pub use self::{
compute::*, descriptor::*, graphics::*, input_assembler::*, output_merger::*, specialization::*,
};
#[derive(Clone, Debug, PartialEq, thiserror::Error)]
pub enum CreationError {
#[error("Implementation specific error occurred")]
Other,
#[error("{0:?} shader creation failed: {1:}")]
ShaderCreationError(ShaderStageFlags, String),
#[error("Pipeline kind is not supported")]
UnsupportedPipeline,
#[error("Invalid subpass: {0:?}")]
InvalidSubpass(pass::SubpassId),
#[error("Invalid entry point: {0:}")]
MissingEntryPoint(String),
#[error("Specialization failed: {0:}")]
InvalidSpecialization(String),
#[error(transparent)]
OutOfMemory(#[from] device::OutOfMemory),
}
bitflags!(
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct PipelineStage: u32 {
const TOP_OF_PIPE = 0x1;
const DRAW_INDIRECT = 0x2;
const VERTEX_INPUT = 0x4;
const VERTEX_SHADER = 0x8;
const HULL_SHADER = 0x10;
const DOMAIN_SHADER = 0x20;
const GEOMETRY_SHADER = 0x40;
const FRAGMENT_SHADER = 0x80;
const EARLY_FRAGMENT_TESTS = 0x100;
const LATE_FRAGMENT_TESTS = 0x200;
const COLOR_ATTACHMENT_OUTPUT = 0x400;
const COMPUTE_SHADER = 0x800;
const TRANSFER = 0x1000;
const BOTTOM_OF_PIPE = 0x2000;
const HOST = 0x4000;
const TASK_SHADER = 0x80000;
const MESH_SHADER = 0x100000;
}
);
bitflags!(
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Default)]
pub struct ShaderStageFlags: u32 {
const VERTEX = 0x1;
const HULL = 0x2;
const DOMAIN = 0x4;
const GEOMETRY = 0x8;
const FRAGMENT = 0x10;
const COMPUTE = 0x20;
const TASK = 0x40;
const MESH = 0x80;
const GRAPHICS = Self::VERTEX.bits | Self::HULL.bits |
Self::DOMAIN.bits | Self::GEOMETRY.bits | Self::FRAGMENT.bits;
const ALL = 0x7FFFFFFF;
}
);
impl From<naga::ShaderStage> for ShaderStageFlags {
fn from(stage: naga::ShaderStage) -> Self {
use naga::ShaderStage as Ss;
match stage {
Ss::Vertex => Self::VERTEX,
Ss::Fragment => Self::FRAGMENT,
Ss::Compute => Self::COMPUTE,
}
}
}
#[derive(Debug)]
pub struct EntryPoint<'a, B: Backend> {
pub entry: &'a str,
pub module: &'a B::ShaderModule,
pub specialization: Specialization<'a>,
}
impl<'a, B: Backend> Clone for EntryPoint<'a, B> {
fn clone(&self) -> Self {
EntryPoint {
entry: self.entry,
module: self.module,
specialization: self.specialization.clone(),
}
}
}
bitflags!(
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct PipelineCreationFlags: u32 {
const DISABLE_OPTIMIZATION = 0x1;
const ALLOW_DERIVATIVES = 0x2;
}
);
#[derive(Debug)]
pub enum BasePipeline<'a, P: 'a> {
Pipeline(&'a P),
Index(usize),
None,
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum State<T> {
Static(T),
Dynamic,
}
impl<T> State<T> {
pub fn static_or(self, default: T) -> T {
match self {
State::Static(v) => v,
State::Dynamic => default,
}
}
pub fn is_static(self) -> bool {
match self {
State::Static(_) => true,
State::Dynamic => false,
}
}
pub fn is_dynamic(self) -> bool {
!self.is_static()
}
}