1#![allow(missing_docs)]
18
19use std::{fmt, cmp, hash};
20use std::error::Error;
21use {Resources};
22use {AttributeSlot, ColorSlot, ConstantBufferSlot, ResourceViewSlot, SamplerSlot, UnorderedViewSlot};
23
24#[cfg(feature = "mint")]
25use mint;
26
27pub type Dimension = u8;
29
30#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
32#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
33pub enum IsArray { Array, NoArray }
34
35#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
37#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
38pub enum IsComparison { Compare, NoCompare }
39
40#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
42#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
43pub enum IsMultiSample { MultiSample, NoMultiSample }
44
45#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
50#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
51pub enum IsRect { Rect, NoRect }
52
53#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
55#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
56pub enum MatrixFormat { ColumnMajor, RowMajor }
57
58#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
61#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
62pub enum TextureType {
63 Buffer,
65 D1(IsArray),
67 D2(IsArray, IsMultiSample),
69 D3,
71 Cube(IsArray),
73}
74
75impl TextureType {
76 pub fn can_sample(&self) -> bool {
78 match self {
79 &TextureType::Buffer => false,
80 &TextureType::D1(_) => true,
81 &TextureType::D2(_, IsMultiSample::MultiSample) => false,
82 &TextureType::D2(_, IsMultiSample::NoMultiSample) => true,
83 &TextureType::D3 => true,
84 &TextureType::Cube(_) => true,
85 }
86 }
87}
88
89#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
91#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
92pub struct SamplerType(pub IsComparison, pub IsRect);
93
94#[allow(missing_docs)]
96#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
97#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
98pub enum BaseType {
99 I32,
100 U32,
101 F32,
102 F64,
103 Bool,
104}
105
106#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
108#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
109pub enum ContainerType {
110 Single,
112 Vector(Dimension),
114 Matrix(MatrixFormat, Dimension, Dimension),
116}
117
118#[allow(missing_docs)]
122#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
123#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
124#[repr(u8)]
125pub enum Stage {
126 Vertex,
127 Hull,
128 Domain,
129 Geometry,
130 Pixel,
131}
132
133pub const STAGES: [Stage; 5] = [Stage::Vertex, Stage::Hull, Stage::Domain, Stage::Geometry, Stage::Pixel];
135
136pub type Location = usize;
140
141#[allow(missing_docs)]
144#[derive(Clone, Copy, PartialEq, PartialOrd)]
145#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
146pub enum UniformValue {
147 I32(i32),
148 U32(u32),
149 F32(f32),
150
151 I32Vector2([i32; 2]),
152 I32Vector3([i32; 3]),
153 I32Vector4([i32; 4]),
154
155 U32Vector2([u32; 2]),
156 U32Vector3([u32; 3]),
157 U32Vector4([u32; 4]),
158
159 F32Vector2([f32; 2]),
160 F32Vector3([f32; 3]),
161 F32Vector4([f32; 4]),
162
163 F32Matrix2([[f32; 2]; 2]),
164 F32Matrix3([[f32; 3]; 3]),
165 F32Matrix4([[f32; 4]; 4]),
166}
167
168impl fmt::Debug for UniformValue {
169 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
170 match *self {
171 UniformValue::I32(x) => write!(f, "ValueI32({:?})", x),
172 UniformValue::U32(x) => write!(f, "ValueU32({:?})", x),
173 UniformValue::F32(x) => write!(f, "ValueF32({:?})", x),
174
175 UniformValue::I32Vector2(ref v) => write!(f, "ValueI32Vector2({:?})", &v[..]),
176 UniformValue::I32Vector3(ref v) => write!(f, "ValueI32Vector3({:?})", &v[..]),
177 UniformValue::I32Vector4(ref v) => write!(f, "ValueI32Vector4({:?})", &v[..]),
178
179 UniformValue::U32Vector2(ref v) => write!(f, "ValueU32Vector2({:?})", &v[..]),
180 UniformValue::U32Vector3(ref v) => write!(f, "ValueU32Vector3({:?})", &v[..]),
181 UniformValue::U32Vector4(ref v) => write!(f, "ValueU32Vector4({:?})", &v[..]),
182
183 UniformValue::F32Vector2(ref v) => write!(f, "ValueF32Vector2({:?})", &v[..]),
184 UniformValue::F32Vector3(ref v) => write!(f, "ValueF32Vector3({:?})", &v[..]),
185 UniformValue::F32Vector4(ref v) => write!(f, "ValueF32Vector4({:?})", &v[..]),
186
187 UniformValue::F32Matrix2(ref m) => {
188 try!(write!(f, "ValueF32Matrix2("));
189 for v in m.iter() {
190 try!(write!(f, "{:?}", &v[..]));
191 }
192 write!(f, ")")
193 },
194 UniformValue::F32Matrix3(ref m) => {
195 try!(write!(f, "ValueF32Matrix3("));
196 for v in m.iter() {
197 try!(write!(f, "{:?}", &v[..]));
198 }
199 write!(f, ")")
200 },
201 UniformValue::F32Matrix4(ref m) => {
202 try!(write!(f, "ValueF32Matrix4("));
203 for v in m.iter() {
204 try!(write!(f, "{:?}", &v[..]));
205 }
206 write!(f, ")")
207 },
208 }
209 }
210}
211
212pub type ConstFormat = (BaseType, ContainerType);
214
215pub trait BaseTyped {
218 fn get_base_type() -> BaseType;
219}
220
221pub trait Formatted {
224 fn get_format() -> ConstFormat;
226}
227
228macro_rules! impl_base_type {
229 ( $($name:ty = $value:ident ,)* ) => {
230 $(
231 impl BaseTyped for $name {
232 fn get_base_type() -> BaseType {
233 BaseType::$value
234 }
235 }
236 )*
237 }
238}
239
240macro_rules! impl_const_vector {
241 ( $( $num:expr ),* ) => {
242 $(
243 impl<T: BaseTyped> Formatted for [T; $num] {
244 fn get_format() -> ConstFormat {
245 (T::get_base_type(), ContainerType::Vector($num))
246 }
247 }
248 )*
249 }
250}
251
252macro_rules! impl_const_matrix {
253 ( $( [$n:expr, $m:expr] ),* ) => {
254 $(
255 impl<T: BaseTyped> Formatted for [[T; $n]; $m] {
256 fn get_format() -> ConstFormat {
257 let mf = MatrixFormat::ColumnMajor;
258 (T::get_base_type(), ContainerType::Matrix(mf, $n, $m))
259 }
260 }
261 )*
262 }
263}
264
265#[cfg(feature = "mint")]
266macro_rules! impl_const_vector_mint {
267 ( $( $name:ident = $num:expr, )* ) => {
268 $(
269 impl<T: BaseTyped> Formatted for mint::$name<T> {
270 fn get_format() -> ConstFormat {
271 (T::get_base_type(), ContainerType::Vector($num))
272 }
273 }
274 )*
275 }
276}
277
278#[cfg(feature = "mint")]
279macro_rules! impl_const_matrix_mint {
280 ( $( $name:ident = $format:ident $size:expr, )* ) => {
281 $(
282 impl<T: BaseTyped> Formatted for mint::$name<T> {
283 fn get_format() -> ConstFormat {
284 let mf = MatrixFormat::$format;
285 (T::get_base_type(), ContainerType::Matrix(mf, $size, $size))
286 }
287 }
288 )*
289 }
290}
291
292impl_base_type! {
293 i32 = I32,
294 u32 = U32,
295 f32 = F32,
296 f64 = F64,
297 bool = Bool,
298}
299
300impl<T: BaseTyped> Formatted for T {
301 fn get_format() -> ConstFormat {
302 (T::get_base_type(), ContainerType::Single)
303 }
304}
305
306impl_const_vector!(2, 3, 4);
307impl_const_matrix!([2,2], [3,3], [4,4], [4,3]);
308
309#[cfg(feature = "mint")]
310impl_const_vector_mint! {
311 Point2 = 2,
312 Point3 = 3,
313 Vector2 = 2,
314 Vector3 = 3,
315 Vector4 = 4,
316}
317
318#[cfg(feature = "mint")]
319impl_const_matrix_mint! {
320 ColumnMatrix2 = ColumnMajor 2,
321 ColumnMatrix3 = ColumnMajor 3,
322 ColumnMatrix4 = ColumnMajor 4,
323 RowMatrix2 = RowMajor 2,
324 RowMatrix3 = RowMajor 3,
325 RowMatrix4 = RowMajor 4,
326}
327
328bitflags!(
329 #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
331 pub struct Usage: u8 {
332 const VERTEX = 0x1;
334 const GEOMETRY = 0x2;
336 const PIXEL = 0x4;
338 const HULL = 0x8;
340 const DOMAIN = 0x16;
342 }
343);
344
345impl From<Stage> for Usage {
346 fn from(stage: Stage) -> Self {
347 match stage {
348 Stage::Vertex => Self::VERTEX,
349 Stage::Geometry => Self::GEOMETRY,
350 Stage::Pixel => Self::PIXEL,
351 Stage::Hull => Self::HULL,
352 Stage::Domain => Self::DOMAIN,
353 }
354 }
355}
356
357#[derive(Clone, Debug, Eq, Hash, PartialEq)]
359#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
360pub struct AttributeVar {
361 pub name: String,
363 pub slot: AttributeSlot,
365 pub base_type: BaseType,
367 pub container: ContainerType,
369}
370
371#[derive(Clone, Debug, Eq, Hash, PartialEq)]
374#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
375pub struct ConstVar {
376 pub name: String,
378 pub location: Location,
381 pub count: usize,
383 pub base_type: BaseType,
385 pub container: ContainerType,
387}
388
389#[derive(Clone, Debug, Eq, Hash, PartialEq)]
391#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
392pub struct ConstantBufferVar {
393 pub name: String,
395 pub slot: ConstantBufferSlot,
397 pub size: usize,
399 pub usage: Usage,
401 pub elements: Vec<ConstVar>,
403}
404
405#[derive(Clone, Debug, Eq, Hash, PartialEq)]
407#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
408pub struct TextureVar {
409 pub name: String,
411 pub slot: ResourceViewSlot,
413 pub base_type: BaseType,
415 pub ty: TextureType,
417 pub usage: Usage,
419}
420
421#[derive(Clone, Debug, Eq, Hash, PartialEq)]
423#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
424pub struct UnorderedVar {
425 pub name: String,
427 pub slot: UnorderedViewSlot,
429 pub usage: Usage,
431}
432
433#[derive(Clone, Debug, Eq, Hash, PartialEq)]
435#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
436pub struct SamplerVar {
437 pub name: String,
439 pub slot: SamplerSlot,
441 pub ty: SamplerType,
443 pub usage: Usage,
445}
446
447#[derive(Clone, Debug, Eq, Hash, PartialEq)]
449#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
450pub struct OutputVar {
451 pub name: String,
453 pub slot: ColorSlot,
455 pub base_type: BaseType,
457 pub container: ContainerType,
459}
460
461#[derive(Clone, Debug, Eq, Hash, PartialEq)]
463#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
464pub struct ProgramInfo {
465 pub vertex_attributes: Vec<AttributeVar>,
467 pub globals: Vec<ConstVar>,
469 pub constant_buffers: Vec<ConstantBufferVar>,
471 pub textures: Vec<TextureVar>,
473 pub unordereds: Vec<UnorderedVar>,
475 pub samplers: Vec<SamplerVar>,
477 pub outputs: Vec<OutputVar>,
479 pub output_depth: bool,
481 pub knows_outputs: bool,
484}
485
486#[derive(Debug)]
488pub struct Program<R: Resources> {
489 resource: R::Program,
490 info: ProgramInfo,
491}
492
493impl<R: Resources> Program<R> {
494 #[doc(hidden)]
495 pub fn new(resource: R::Program, info: ProgramInfo) -> Self {
496 Program {
497 resource: resource,
498 info: info,
499 }
500 }
501
502 #[doc(hidden)]
503 pub fn resource(&self) -> &R::Program { &self.resource }
504
505 pub fn get_info(&self) -> &ProgramInfo { &self.info }
507}
508
509impl<R: Resources + cmp::PartialEq> cmp::PartialEq for Program<R> {
510 fn eq(&self, other: &Program<R>) -> bool {
511 self.resource().eq(other.resource())
512 }
513}
514
515impl<R: Resources + cmp::Eq> cmp::Eq for Program<R> {}
516
517impl<R: Resources + hash::Hash> hash::Hash for Program<R> {
518 fn hash<H>(&self, state: &mut H) where H: hash::Hasher {
519 self.resource().hash(state);
520 }
521}
522
523#[derive(Clone, Copy, Debug, Eq, PartialEq)]
525pub enum CompatibilityError {
526 ErrorArraySize,
528 ErrorBaseType,
530 ErrorContainer,
533}
534
535impl fmt::Display for CompatibilityError {
536 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
537 write!(f, "{}", self.description())
538 }
539}
540
541impl Error for CompatibilityError {
542 fn description(&self) -> &str {
543 match *self {
544 CompatibilityError::ErrorArraySize =>
545 "Array sizes differ between the value and the var \
546 (trying to upload a vec2 as a vec4, etc)",
547 CompatibilityError::ErrorBaseType =>
548 "Base types differ between the value and the var \
549 (trying to upload a f32 as a u16, etc)",
550 CompatibilityError::ErrorContainer =>
551 "Container-ness differs between the value and the var \
552 (trying to upload a scalar as a vec4, etc)",
553 }
554 }
555}
556
557impl ConstVar {
558 pub fn is_compatible(&self, value: &UniformValue) -> Result<(), CompatibilityError> {
561 if self.count != 1 {
562 return Err(CompatibilityError::ErrorArraySize)
563 }
564 match (self.base_type, self.container, *value) {
565 (BaseType::I32, ContainerType::Single, UniformValue::I32(_)) => Ok(()),
566 (BaseType::U32, ContainerType::Single, UniformValue::U32(_)) => Ok(()),
567 (BaseType::F32, ContainerType::Single, UniformValue::F32(_)) => Ok(()),
568
569 (BaseType::I32, ContainerType::Vector(2), UniformValue::I32Vector2(_)) => Ok(()),
570 (BaseType::I32, ContainerType::Vector(3), UniformValue::I32Vector3(_)) => Ok(()),
571 (BaseType::I32, ContainerType::Vector(4), UniformValue::I32Vector4(_)) => Ok(()),
572
573 (BaseType::U32, ContainerType::Vector(2), UniformValue::U32Vector2(_)) => Ok(()),
574 (BaseType::U32, ContainerType::Vector(3), UniformValue::U32Vector3(_)) => Ok(()),
575 (BaseType::U32, ContainerType::Vector(4), UniformValue::U32Vector4(_)) => Ok(()),
576
577 (BaseType::F32, ContainerType::Vector(2), UniformValue::F32Vector2(_)) => Ok(()),
578 (BaseType::F32, ContainerType::Vector(3), UniformValue::F32Vector3(_)) => Ok(()),
579 (BaseType::F32, ContainerType::Vector(4), UniformValue::F32Vector4(_)) => Ok(()),
580
581 (BaseType::F32, ContainerType::Matrix(_, 2,2), UniformValue::F32Matrix2(_)) => Ok(()),
582 (BaseType::F32, ContainerType::Matrix(_, 3,3), UniformValue::F32Matrix3(_)) => Ok(()),
583 (BaseType::F32, ContainerType::Matrix(_, 4,4), UniformValue::F32Matrix4(_)) => Ok(()),
584
585 _ => Err(CompatibilityError::ErrorBaseType)
586 }
587 }
588}
589
590#[derive(Clone, Debug, PartialEq)]
592pub enum CreateShaderError {
593 ModelNotSupported,
595 StageNotSupported(Stage),
597 CompilationFailed(String),
599}
600
601impl fmt::Display for CreateShaderError {
602 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
603 let desc = self.description();
604 match *self {
605 CreateShaderError::StageNotSupported(ref stage) => write!(f, "{}: {:?}", desc, stage),
606 CreateShaderError::CompilationFailed(ref string) => write!(f, "{}: {}", desc, string),
607 _ => write!(f, "{}", desc),
608 }
609 }
610}
611
612impl Error for CreateShaderError {
613 fn description(&self) -> &str {
614 match *self {
615 CreateShaderError::ModelNotSupported => "The device does not support the requested shader model",
616 CreateShaderError::StageNotSupported(_) => "The device does not support the shader stage",
617 CreateShaderError::CompilationFailed(_) => "The shader failed to compile",
618 }
619 }
620}
621
622#[derive(Clone, Debug, Eq, PartialEq)]
624pub struct CreateProgramError(String);
625
626impl fmt::Display for CreateProgramError {
627 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
628 f.pad(&self.0)
629 }
630}
631
632impl Error for CreateProgramError {
633 fn description(&self) -> &str {
634 &self.0
635 }
636}
637
638impl<S: Into<String>> From<S> for CreateProgramError {
639 fn from(s: S) -> CreateProgramError {
640 CreateProgramError(s.into())
641 }
642}