#![deny(missing_docs)]
#[macro_use]
extern crate bitflags;
extern crate draw_state;
extern crate log;
#[cfg(feature = "mint")]
extern crate mint;
#[cfg(feature = "serialize")]
#[macro_use]
extern crate serde;
use std::fmt::{self, Debug};
use std::error::Error;
use std::hash::Hash;
use std::any::Any;
pub use draw_state::{state, target};
pub use self::factory::Factory;
pub mod buffer;
pub mod command;
pub mod dummy;
pub mod factory;
pub mod format;
pub mod handle;
pub mod mapping;
pub mod memory;
pub mod pso;
pub mod shade;
pub mod texture;
pub const MAX_VERTEX_ATTRIBUTES: usize = 16;
pub const MAX_COLOR_TARGETS: usize = 4;
pub const MAX_CONSTANT_BUFFERS: usize = 14;
pub const MAX_RESOURCE_VIEWS: usize = 32;
pub const MAX_UNORDERED_VIEWS: usize = 4;
pub const MAX_SAMPLERS: usize = 16;
pub type VertexCount = u32;
pub type InstanceCount = u32;
pub type PatchSize = u8;
pub type AttributeSlot = u8;
pub type ConstantBufferSlot = u8;
pub type ResourceViewSlot = u8;
pub type UnorderedViewSlot = u8;
pub type ColorSlot = u8;
pub type SamplerSlot = u8;
macro_rules! define_shaders {
( $($name:ident),+ ) => {
$(
#[allow(missing_docs)]
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct $name<R: Resources>(handle::Shader<R>);
impl<R: Resources> $name<R> {
#[allow(missing_docs)]
pub fn reference(&self, man: &mut handle::Manager<R>) -> &R::Shader {
man.ref_shader(&self.0)
}
#[doc(hidden)]
pub fn new(shader: handle::Shader<R>) -> Self {
$name(shader)
}
}
)+
}
}
define_shaders!(VertexShader, HullShader, DomainShader, GeometryShader, PixelShader);
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum ShaderSet<R: Resources> {
Simple(VertexShader<R>, PixelShader<R>),
Geometry(VertexShader<R>, GeometryShader<R>, PixelShader<R>),
Tessellated(VertexShader<R>, HullShader<R>, DomainShader<R>, PixelShader<R>),
TessellatedGeometry(VertexShader<R>, HullShader<R>, DomainShader<R>, GeometryShader<R>, PixelShader<R>),
}
impl<R: Resources> ShaderSet<R> {
pub fn get_usage(&self) -> shade::Usage {
use shade::Usage;
match *self {
ShaderSet::Simple(..) => Usage::VERTEX | Usage::PIXEL,
ShaderSet::Geometry(..) => Usage::VERTEX | Usage::GEOMETRY | Usage::PIXEL,
ShaderSet::Tessellated(..) => Usage::VERTEX | Usage::HULL | Usage::DOMAIN | Usage::PIXEL,
ShaderSet::TessellatedGeometry(..) => Usage::VERTEX | Usage::HULL | Usage::DOMAIN | Usage::GEOMETRY | Usage::PIXEL,
}
}
}
#[allow(missing_docs)] #[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
pub struct Capabilities {
pub max_vertex_count: usize,
pub max_index_count: usize,
pub max_texture_size: usize,
pub max_patch_size: usize,
pub instance_base_supported: bool,
pub instance_call_supported: bool,
pub instance_rate_supported: bool,
pub vertex_base_supported: bool,
pub srgb_color_supported: bool,
pub constant_buffer_supported: bool,
pub unordered_access_view_supported: bool,
pub separate_blending_slots_supported: bool,
pub copy_buffer_supported: bool,
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
#[repr(u8)]
pub enum Primitive {
PointList,
LineList,
LineStrip,
TriangleList,
TriangleStrip,
LineListAdjacency,
LineStripAdjacency,
TriangleListAdjacency,
TriangleStripAdjacency,
PatchList(PatchSize),
}
#[allow(missing_docs)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
#[repr(u8)]
pub enum IndexType {
U16,
U32,
}
#[allow(missing_docs)]
pub trait Resources: Clone + Hash + Debug + Eq + PartialEq + Any {
type Buffer: Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync + Copy;
type Shader: Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync;
type Program: Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync;
type PipelineStateObject: Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync;
type Texture: Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync;
type ShaderResourceView: Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync + Copy;
type UnorderedAccessView: Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync + Copy;
type RenderTargetView: Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync + Copy;
type DepthStencilView: Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync;
type Sampler: Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync + Copy;
type Fence: Clone + Hash + Debug + Eq + PartialEq + Any + Send + Sync;
type Mapping: Hash + Debug + Eq + PartialEq + Any + Send + Sync + mapping::Gate<Self>;
}
#[allow(missing_docs)]
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
pub enum SubmissionError {
AccessOverlap,
}
impl fmt::Display for SubmissionError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::SubmissionError::*;
match *self {
AccessOverlap => write!(f, "{}", self.description()),
}
}
}
impl Error for SubmissionError {
fn description(&self) -> &str {
use self::SubmissionError::*;
match *self {
AccessOverlap => "A resource access overlaps with another"
}
}
}
#[allow(missing_docs)]
pub type SubmissionResult<T> = Result<T, SubmissionError>;
pub trait Device: Sized {
type Resources: Resources;
type CommandBuffer: command::Buffer<Self::Resources>;
fn get_capabilities(&self) -> &Capabilities;
fn pin_submitted_resources(&mut self, &handle::Manager<Self::Resources>);
fn submit(&mut self,
&mut Self::CommandBuffer,
access: &command::AccessInfo<Self::Resources>)
-> SubmissionResult<()>;
fn fenced_submit(&mut self,
&mut Self::CommandBuffer,
access: &command::AccessInfo<Self::Resources>,
after: Option<handle::Fence<Self::Resources>>)
-> SubmissionResult<handle::Fence<Self::Resources>>;
fn wait_fence(&mut self, &handle::Fence<Self::Resources>);
fn cleanup(&mut self);
}
pub trait Adapter: Sized {
type CommandQueue: CommandQueue;
type Device: Device;
type QueueFamily: QueueFamily;
fn enumerate_adapters() -> Vec<Self>;
fn open<'a, I>(&self, queue_descs: I) -> (Self::Device, Vec<Self::CommandQueue>)
where I: Iterator<Item=(&'a Self::QueueFamily, u32)>;
fn get_info(&self) -> &AdapterInfo;
fn get_queue_families(&self) -> &[Self::QueueFamily];
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
pub struct AdapterInfo {
pub name: String,
pub vendor: usize,
pub device: usize,
pub software_rendering: bool,
}
pub trait QueueFamily: 'static {
type Surface: Surface;
fn supports_present(&self, surface: &Self::Surface) -> bool;
fn num_queues(&self) -> u32;
}
pub trait CommandQueue { }
pub trait Surface {
type CommandQueue: CommandQueue;
type SwapChain: SwapChain;
type Window;
fn from_window(window: &Self::Window) -> Self;
fn build_swapchain<T: format::RenderFormat>(&self, present_queue: &Self::CommandQueue)
-> Self::SwapChain;
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
pub struct Frame(usize);
impl Frame {
#[doc(hidden)]
pub fn new(id: usize) -> Self {
Frame(id)
}
}
pub trait SwapChain {
fn acquire_frame(&mut self) -> Frame;
fn present(&mut self);
}