use {MAX_COLOR_TARGETS, MAX_VERTEX_ATTRIBUTES, MAX_CONSTANT_BUFFERS,
MAX_RESOURCE_VIEWS, MAX_UNORDERED_VIEWS, MAX_SAMPLERS};
use {ConstantBufferSlot, ColorSlot, ResourceViewSlot,
UnorderedViewSlot, SamplerSlot,
Primitive, Resources};
use {format, state as s, texture};
use shade::Usage;
use std::error::Error;
use std::fmt;
pub const MAX_VERTEX_BUFFERS: usize = 16;
pub type BufferOffset = usize;
#[derive(Clone, Debug, PartialEq)]
pub struct CreationError;
impl fmt::Display for CreationError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.description())
}
}
impl Error for CreationError {
fn description(&self) -> &str {
"Could not create PSO on device."
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
pub struct ColorInfo {
pub mask: s::ColorMask,
pub color: Option<s::BlendChannel>,
pub alpha: Option<s::BlendChannel>,
}
impl From<s::ColorMask> for ColorInfo {
fn from(mask: s::ColorMask) -> Self {
ColorInfo {
mask: mask,
color: None,
alpha: None,
}
}
}
impl From<s::Blend> for ColorInfo {
fn from(blend: s::Blend) -> Self {
ColorInfo {
mask: s::ColorMask::all(),
color: Some(blend.color),
alpha: Some(blend.alpha),
}
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
pub struct DepthStencilInfo {
pub depth: Option<s::Depth>,
pub front: Option<s::StencilSide>,
pub back: Option<s::StencilSide>,
}
impl From<s::Depth> for DepthStencilInfo {
fn from(depth: s::Depth) -> DepthStencilInfo {
DepthStencilInfo {
depth: Some(depth),
front: None,
back: None,
}
}
}
impl From<s::Stencil> for DepthStencilInfo {
fn from(stencil: s::Stencil) -> DepthStencilInfo {
DepthStencilInfo {
depth: None,
front: Some(stencil.front),
back: Some(stencil.back),
}
}
}
impl From<(s::Depth, s::Stencil)> for DepthStencilInfo {
fn from(ds: (s::Depth, s::Stencil)) -> DepthStencilInfo {
DepthStencilInfo {
depth: Some(ds.0),
front: Some(ds.1.front),
back: Some(ds.1.back),
}
}
}
pub type BufferIndex = u8;
pub type ElemOffset = u32;
pub type ElemStride = u8;
pub type InstanceRate = u8;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
pub struct Element<F> {
pub format: F,
pub offset: ElemOffset,
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
pub struct VertexBufferDesc {
pub stride: ElemStride,
pub rate: InstanceRate,
}
pub type AttributeDesc = (BufferIndex, Element<format::Format>);
pub type ConstantBufferDesc = Usage;
pub type ResourceViewDesc = Usage;
pub type UnorderedViewDesc = Usage;
pub type SamplerDesc = Usage;
pub type ColorTargetDesc = (format::Format, ColorInfo);
pub type DepthStencilDesc = (format::Format, DepthStencilInfo);
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
pub struct Descriptor {
pub primitive: Primitive,
pub rasterizer: s::Rasterizer,
pub scissor: bool,
pub vertex_buffers: [Option<VertexBufferDesc>; MAX_VERTEX_BUFFERS],
pub attributes: [Option<AttributeDesc>; MAX_VERTEX_ATTRIBUTES],
pub constant_buffers: [Option<ConstantBufferDesc>; MAX_CONSTANT_BUFFERS],
pub resource_views: [Option<ResourceViewDesc>; MAX_RESOURCE_VIEWS],
pub unordered_views: [Option<UnorderedViewDesc>; MAX_UNORDERED_VIEWS],
pub samplers: [Option<SamplerDesc>; MAX_SAMPLERS],
pub color_targets: [Option<ColorTargetDesc>; MAX_COLOR_TARGETS],
pub depth_stencil: Option<DepthStencilDesc>,
}
impl Descriptor {
pub fn new(primitive: Primitive, rast: s::Rasterizer) -> Descriptor {
Descriptor {
primitive: primitive,
rasterizer: rast,
scissor: false,
vertex_buffers: [None; MAX_VERTEX_BUFFERS],
attributes: [None; MAX_VERTEX_ATTRIBUTES],
constant_buffers: [None; MAX_CONSTANT_BUFFERS],
resource_views: [None; MAX_RESOURCE_VIEWS],
unordered_views: [None; MAX_UNORDERED_VIEWS],
samplers: [None; MAX_SAMPLERS],
color_targets: [None; MAX_COLOR_TARGETS],
depth_stencil: None,
}
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct VertexBufferSet<R: Resources>(
pub [Option<(R::Buffer, BufferOffset)>; MAX_VERTEX_ATTRIBUTES]
);
impl<R: Resources> VertexBufferSet<R> {
pub fn new() -> VertexBufferSet<R> {
VertexBufferSet([None; MAX_VERTEX_ATTRIBUTES])
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct ConstantBufferParam<R: Resources>(pub R::Buffer, pub Usage, pub ConstantBufferSlot);
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct ResourceViewParam<R: Resources>(pub R::ShaderResourceView, pub Usage, pub ResourceViewSlot);
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct UnorderedViewParam<R: Resources>(pub R::UnorderedAccessView, pub Usage, pub UnorderedViewSlot);
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct SamplerParam<R: Resources>(pub R::Sampler, pub Usage, pub SamplerSlot);
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct PixelTargetSet<R: Resources> {
pub colors: [Option<R::RenderTargetView>; MAX_COLOR_TARGETS],
pub depth: Option<R::DepthStencilView>,
pub stencil: Option<R::DepthStencilView>,
pub dimensions: Option<texture::Dimensions>,
}
impl<R: Resources> PixelTargetSet<R> {
pub fn new() -> Self {
PixelTargetSet {
colors: [None; MAX_COLOR_TARGETS],
depth: None,
stencil: None,
dimensions: None,
}
}
pub fn add_color(&mut self,
slot: ColorSlot,
view: &R::RenderTargetView,
dim: texture::Dimensions) {
self.colors[slot as usize] = Some(view.clone());
self.set_dimensions(dim);
}
pub fn add_depth_stencil(&mut self,
view: &R::DepthStencilView,
has_depth: bool,
has_stencil: bool,
dim: texture::Dimensions) {
if has_depth {
self.depth = Some(view.clone());
}
if has_stencil {
self.stencil = Some(view.clone());
}
self.set_dimensions(dim);
}
fn set_dimensions(&mut self, dim: texture::Dimensions) {
debug_assert!(self.dimensions.map(|d| d == dim).unwrap_or(true));
self.dimensions = Some(dim);
}
pub fn get_view(&self) -> (u16, u16, u16) {
use std::cmp::max;
self.dimensions
.map(|(w, h, d, _)| (max(w, 1), max(h, 1), max(d, 1)))
.unwrap_or((1, 1, 1))
}
}