1use rs_ctypes::*;
31use rs_math3d::*;
32
33use core::sync::atomic::*;
34use core::ops::{Deref, DerefMut};
35
36pub trait IntrusiveCounter {
37 fn increment(&mut self);
38 fn decrement(&mut self) -> isize;
39}
40
41#[repr(C)]
42pub struct IntrusivePtr<T : IntrusiveCounter + ?Sized> {
43 object : *mut T,
44}
45
46impl<T: IntrusiveCounter> IntrusivePtr<T> {
47 pub fn new(mut t: T) -> Self {
48 t.increment();
49 let b = Box::new(t);
50 let r = Box::into_raw(b);
51 let s = Self { object: r };
52 s
53 }
54}
55
56impl<T: IntrusiveCounter + ?Sized> IntrusivePtr<T> {
57 pub fn as_ref(&self) -> *const T { self.object }
58 pub(crate) unsafe fn into_raw_mut(self) -> *mut T { let obj = self.object; std::mem::forget(self); obj }
59 pub(crate) unsafe fn from_raw_no_increment(raw: *mut T) -> Self { Self { object: raw } }
60 pub(crate) unsafe fn from_raw_increment(raw: *mut T) -> Self { (*raw).increment(); Self { object: raw } }
61}
62
63impl<T: IntrusiveCounter + ?Sized> Drop for IntrusivePtr<T> {
64 fn drop(&mut self) {
65 unsafe {
66 let rc = (*self.object).decrement();
67 if rc == 1 {
68 Box::from_raw(self.object);
69 }
70 }
71 }
72}
73
74impl<T: IntrusiveCounter + ?Sized> Clone for IntrusivePtr<T> {
75 fn clone(&self) -> Self {
76 unsafe { (*self.object).increment() };
77 Self { object : self.object }
78 }
79}
80
81impl<T: IntrusiveCounter + ?Sized> Deref for IntrusivePtr<T> {
82 type Target = T;
83
84 fn deref(&self) -> &Self::Target {
85 unsafe { &(*self.object) }
86 }
87}
88
89impl<T: IntrusiveCounter + ?Sized> DerefMut for IntrusivePtr<T> {
90 fn deref_mut(&mut self) -> &mut Self::Target {
91 unsafe { &mut (*self.object) }
92 }
93}
94
95impl<T: IntrusiveCounter + ?Sized> core::borrow::Borrow<T> for IntrusivePtr<T> {
96 fn borrow(&self) -> &T {
97 &**self
98 }
99}
100
101pub enum ResourceType {
102 DeviceBuffer,
103 Texture,
104 RenderTarget,
105 Shader,
106 Pipeline,
107 FrameBuffer,
108}
109
110#[repr(C)]
111pub struct Resource<Desc> {
112 res_type: ResourceType,
113 res_id : usize,
114 desc : Desc,
115 depends_on : Option<IntrusivePtr<dyn Driver>>, rc : AtomicIsize,
117}
118
119impl<Desc> Resource<Desc> {
120 pub(crate) fn new(res_type: ResourceType, res_id: usize, desc: Desc, depends_on : Option<IntrusivePtr<dyn Driver>>) -> Self {
121 Self { res_type: res_type, res_id : res_id, desc: desc, depends_on: depends_on, rc: AtomicIsize::new(0) }
122 }
123 pub(crate) fn res_id(&self) -> usize { self.res_id }
124 pub fn desc(&self) -> &Desc { &self.desc }
125}
126
127impl<Desc> IntrusiveCounter for Resource<Desc> {
128 fn increment(&mut self) { self.rc.fetch_add(1, Ordering::SeqCst); }
129 fn decrement(&mut self) -> isize {
130 self.rc.fetch_sub(1, Ordering::SeqCst)
131 }
132}
133
134impl<Desc> Drop for Resource<Desc> {
135 fn drop(&mut self) {
136 match &mut self.depends_on {
137 Some(driver) => driver.delete_resource(&self.res_type, self.res_id),
138 _ => panic!("No driver!")
139 }
140 }
141}
142
143pub trait AttributeDataTypeGetter {
148 fn get_attribute_type() -> VertexFormat;
149}
150
151impl AttributeDataTypeGetter for i8 {
153 fn get_attribute_type() -> VertexFormat { VertexFormat::SByte }
154}
155
156impl AttributeDataTypeGetter for Vector2<i8> {
157 fn get_attribute_type() -> VertexFormat { VertexFormat::SByte2 }
158}
159
160impl AttributeDataTypeGetter for Vector3<i8> {
161 fn get_attribute_type() -> VertexFormat { VertexFormat::SByte3 }
162}
163
164impl AttributeDataTypeGetter for Vector4<i8> {
165 fn get_attribute_type() -> VertexFormat { VertexFormat::SByte4 }
166}
167
168impl AttributeDataTypeGetter for u8 {
170 fn get_attribute_type() -> VertexFormat { VertexFormat::Byte }
171}
172
173impl AttributeDataTypeGetter for Vector2<u8> {
174 fn get_attribute_type() -> VertexFormat { VertexFormat::Byte2 }
175}
176
177impl AttributeDataTypeGetter for Vector3<u8> {
178 fn get_attribute_type() -> VertexFormat { VertexFormat::Byte3 }
179}
180
181impl AttributeDataTypeGetter for Vector4<u8> {
182 fn get_attribute_type() -> VertexFormat { VertexFormat::Byte4 }
183}
184
185impl AttributeDataTypeGetter for i16 {
187 fn get_attribute_type() -> VertexFormat { VertexFormat::Short }
188}
189
190impl AttributeDataTypeGetter for Vector2<i16> {
191 fn get_attribute_type() -> VertexFormat { VertexFormat::Short2 }
192}
193
194impl AttributeDataTypeGetter for Vector3<i16> {
195 fn get_attribute_type() -> VertexFormat { VertexFormat::Short3 }
196}
197
198impl AttributeDataTypeGetter for Vector4<i16> {
199 fn get_attribute_type() -> VertexFormat { VertexFormat::Short4 }
200}
201
202impl AttributeDataTypeGetter for f32 {
204 fn get_attribute_type() -> VertexFormat { VertexFormat::Float }
205}
206
207impl AttributeDataTypeGetter for Vector2<f32> {
208 fn get_attribute_type() -> VertexFormat { VertexFormat::Float2 }
209}
210
211impl AttributeDataTypeGetter for Vector3<f32> {
212 fn get_attribute_type() -> VertexFormat { VertexFormat::Float3 }
213}
214
215impl AttributeDataTypeGetter for Vector4<f32> {
216 fn get_attribute_type() -> VertexFormat { VertexFormat::Float4 }
217}
218
219impl AttributeDataTypeGetter for i32 {
221 fn get_attribute_type() -> VertexFormat { VertexFormat::Int }
222}
223
224impl AttributeDataTypeGetter for Vector2<i32> {
225 fn get_attribute_type() -> VertexFormat { VertexFormat::Int2 }
226}
227
228impl AttributeDataTypeGetter for Vector3<i32> {
229 fn get_attribute_type() -> VertexFormat { VertexFormat::Int3 }
230}
231
232impl AttributeDataTypeGetter for Vector4<i32> {
233 fn get_attribute_type() -> VertexFormat { VertexFormat::Int4 }
234}
235
236impl AttributeDataTypeGetter for u32 {
238 fn get_attribute_type() -> VertexFormat { VertexFormat::UInt }
239}
240
241impl AttributeDataTypeGetter for Vector2<u32> {
242 fn get_attribute_type() -> VertexFormat { VertexFormat::UInt2 }
243}
244
245impl AttributeDataTypeGetter for Vector3<u32> {
246 fn get_attribute_type() -> VertexFormat { VertexFormat::UInt3 }
247}
248
249impl AttributeDataTypeGetter for Vector4<u32> {
250 fn get_attribute_type() -> VertexFormat { VertexFormat::UInt4 }
251}
252
253
254impl AttributeDataTypeGetter for Matrix2<f32> {
256 fn get_attribute_type() -> VertexFormat { VertexFormat::Float2x2 }
257}
258
259impl AttributeDataTypeGetter for Matrix3<f32> {
260 fn get_attribute_type() -> VertexFormat { VertexFormat::Float3x3 }
261}
262
263impl AttributeDataTypeGetter for Matrix4<f32> {
264 fn get_attribute_type() -> VertexFormat { VertexFormat::Float4x4 }
265}
266
267pub trait UniformDataTypeGetter {
272 fn get_uniform_type() -> UniformDataType;
273}
274
275impl UniformDataTypeGetter for u32 {
276 fn get_uniform_type() -> UniformDataType { UniformDataType::UInt }
277}
278
279impl UniformDataTypeGetter for Vector2<u32> {
280 fn get_uniform_type() -> UniformDataType { UniformDataType::UInt2 }
281}
282
283impl UniformDataTypeGetter for Vector3<u32> {
284 fn get_uniform_type() -> UniformDataType { UniformDataType::UInt3 }
285}
286
287impl UniformDataTypeGetter for Vector4<u32> {
288 fn get_uniform_type() -> UniformDataType { UniformDataType::UInt4 }
289}
290
291impl UniformDataTypeGetter for i32 {
292 fn get_uniform_type() -> UniformDataType { UniformDataType::Int }
293}
294
295impl UniformDataTypeGetter for Vector2<i32> {
296 fn get_uniform_type() -> UniformDataType { UniformDataType::Int2 }
297}
298
299impl UniformDataTypeGetter for Vector3<i32> {
300 fn get_uniform_type() -> UniformDataType { UniformDataType::Int3 }
301}
302
303impl UniformDataTypeGetter for Vector4<i32> {
304 fn get_uniform_type() -> UniformDataType { UniformDataType::Int4 }
305}
306
307impl UniformDataTypeGetter for f32 {
308 fn get_uniform_type() -> UniformDataType { UniformDataType::Float }
309}
310
311impl UniformDataTypeGetter for Vector2<f32> {
312 fn get_uniform_type() -> UniformDataType { UniformDataType::Float2 }
313}
314
315impl UniformDataTypeGetter for Vector3<f32> {
316 fn get_uniform_type() -> UniformDataType { UniformDataType::Float3 }
317}
318
319impl UniformDataTypeGetter for Vector4<f32> {
320 fn get_uniform_type() -> UniformDataType { UniformDataType::Float4 }
321}
322
323impl UniformDataTypeGetter for Matrix2<f32> {
324 fn get_uniform_type() -> UniformDataType { UniformDataType::Float2x2 }
325}
326
327impl UniformDataTypeGetter for Matrix3<f32> {
328 fn get_uniform_type() -> UniformDataType { UniformDataType::Float3x3 }
329}
330
331impl UniformDataTypeGetter for Matrix4<f32> {
332 fn get_uniform_type() -> UniformDataType { UniformDataType::Float4x4 }
333}
334
335#[macro_export]
339macro_rules! offset_of {
340 ($Struct:path, $field:ident) => ({
341 fn offset() -> usize {
345 let u = std::mem::MaybeUninit::<$Struct>::uninit();
346 let &$Struct { $field: ref f, .. } = unsafe { &*u.as_ptr() };
348 let o = (f as *const _ as usize).wrapping_sub(&u as *const _ as usize);
349 assert!((0..=std::mem::size_of_val(&u)).contains(&o));
351 o
352 }
353 offset()
354 })
355}
356
357#[macro_export]
358macro_rules! render_data {
359 () => {};
360 (vertex $name:ident { $($field_name:ident: $field_type:ty,)* }) => {
361 #[repr(C)]
362 #[derive(Debug, Copy, Clone)]
363 struct $name {
364 $($field_name: $field_type,)*
365 }
366
367 impl $crate::VertexTrait for $name {
368 fn get_attribute_descriptors() -> Vec<$crate::VertexAttributeDesc> {
370 vec![$($crate::VertexAttributeDesc::new(stringify!($field_name).to_string(), <$field_type>::get_attribute_type(), $crate::offset_of!($name, $field_name))),*]
371 }
372
373 fn get_attribute_names() -> Vec<String> {
374 vec![$(stringify!($field_name).to_string()),*]
375 }
376
377 fn stride() -> usize {
378 core::mem::size_of::<Self>()
379 }
380 }
381 };
382
383 (vertex $name:ident { $($field_name:ident: $field_type:ty,)* } $($e:tt)*) => {
384 $crate::render_data! { vertex $name {
385 $($field_name: $field_type,)*
386 } }
387 $crate::render_data! { $($e)* }
388 };
389
390 (pub vertex $name:ident { $($field_name:ident: $field_type:ty,)* }) => {
391 #[repr(C)]
392 #[derive(Debug, Copy, Clone)]
393 pub struct $name {
394 $($field_name: $field_type,)*
395 }
396
397 impl $crate::renderer::VertexTrait for $name {
398 fn get_attribute_descriptors() -> Vec<$crate::VertexAttributeDesc> {
400 vec![$($crate::VertexAttributeDesc::new(stringify!($field_name).to_string(), <$field_type>::get_attribute_type(), $crate::offset_of!($name, $field_name))),*]
401 }
402
403 fn get_attribute_names() -> Vec<String> {
404 vec![$(stringify!($field_name).to_string()),*]
405 }
406
407 fn stride() -> usize {
408 core::mem::size_of::<Self>()
409 }
410 }
411 };
412
413 (pub vertex $name:ident { $($field_name:ident: $field_type:ty,)* } $($e:tt)*) => {
414 $crate::render_data! { pub vertex $name {
415 $($field_name: $field_type,)*
416 } }
417 $crate::render_data! { $($e)* }
418 };
419
420 (uniforms $name:ident {
421 $($field_name:ident: $field_type:ty,)*
422 }) => {
423 #[repr(C)]
424 #[derive(Debug, Copy, Clone)]
425 struct $name {
426 $($field_name: $field_type,)*
427 }
428
429 impl $crate::UniformBlockTrait for $name {
430 fn get_uniform_descriptors() -> Vec<UniformDataDesc> {
432 vec![$(UniformDataDesc::new(stringify!($field_name).to_string(), <$field_type>::get_uniform_type(), 1, $crate::offset_of!($name, $field_name))),*]
433 }
434
435 fn get_uniform_names() -> Vec<String> {
436 vec![$(stringify!($field_name).to_string()),*]
437 }
438 }
439 };
440
441 (uniforms $name:ident {
442 $($field_name:ident: $field_type:ty,)*
443 } $($e:tt)*) => {
444 $crate::render_data! { uniforms $name {
445 $($field_name: $field_type,)*
446 } }
447 $crate::render_data! { $($e)* }
448 };
449}
450
451#[derive(Clone)]
456pub enum VertexFormat {
457 Byte,
458 Byte2,
459 Byte3,
460 Byte4,
461
462 SByte,
463 SByte2,
464 SByte3,
465 SByte4,
466
467 Short,
468 Short2,
469 Short3,
470 Short4,
471
472 Int,
473 Int2,
474 Int3,
475 Int4,
476
477 UInt,
478 UInt2,
479 UInt3,
480 UInt4,
481
482 Float,
483 Float2,
484 Float3,
485 Float4,
486
487 Float2x2,
488 Float3x3,
489 Float4x4,
490}
491
492
493#[derive(Clone)]
494pub struct VertexAttributeDesc {
495 name : String,
496 format : VertexFormat,
497 offset : usize,
498}
499
500impl VertexAttributeDesc {
501 pub fn new(name: String, format: VertexFormat, offset: usize) -> Self {
502 Self {
503 name : name,
504 format : format,
505 offset : offset,
506 }
507 }
508
509 pub fn name(&self) -> &String { &self.name }
510 pub fn format(&self) -> VertexFormat { self.format.clone() }
511 pub fn offset(&self) -> usize { self.offset }
512}
513
514pub trait VertexTrait {
515 fn get_attribute_descriptors() -> Vec<VertexAttributeDesc>;
516 fn get_attribute_names() -> Vec<String>;
517 fn stride() -> usize;
518}
519
520
521
522#[derive(Clone)]
527pub enum UniformDataType {
528 UInt,
529 UInt2,
530 UInt3,
531 UInt4,
532 Int,
533 Int2,
534 Int3,
535 Int4,
536 Float,
537 Float2,
538 Float3,
539 Float4,
540 Float2x2,
541 Float3x3,
542 Float4x4,
543}
544
545#[derive(Clone)]
546pub struct UniformDesc {
547 name : String,
548 format : UniformDataType,
549 count : usize,
550}
551
552impl UniformDesc {
553 pub fn new(name: String, format: UniformDataType, count: usize) -> Self { Self { name: name, format: format, count: count } }
554 pub fn name(&self) -> &str { self.name.as_str() }
555 pub fn format(&self) -> UniformDataType { self.format.clone() }
556 pub fn count(&self) -> usize { self.count }
557}
558
559#[derive(Clone)]
560pub struct UniformDataDesc {
561 pub desc : UniformDesc,
562 pub offset : usize,
563}
564
565impl UniformDataDesc {
566 pub fn new(name: String, format: UniformDataType, count: usize, offset: usize) -> Self { Self { desc: UniformDesc::new(name, format, count), offset: offset } }
567 pub fn offset(&self) -> usize { self.offset }
568 pub fn desc(&self) -> &UniformDesc { &self.desc }
569}
570
571pub trait UniformBlockTrait {
572 fn get_uniform_descriptors() -> Vec<UniformDataDesc>;
573 fn get_uniform_names() -> Vec<String>;
574}
575
576pub trait Payload {
581 fn ptr(&self) -> *const u8;
582 fn size(&self) -> usize;
583}
584
585impl<T> Payload for Vec<T> {
586 fn ptr(&self) -> *const u8 { self.as_ptr() as *const u8 }
587 fn size(&self) -> usize { ::core::mem::size_of::<T>() * self.len() }
588}
589
590impl<T> Payload for &[T] {
591 fn ptr(&self) -> *const u8 { self.as_ptr() as *const u8 }
592 fn size(&self) -> usize { ::core::mem::size_of::<T>() * self.len() }
593}
594
595pub enum Usage {
596 Static(Box<dyn Payload>),
597 Dynamic(usize),
598 Streamed(usize),
599}
600
601impl Usage {
602 pub fn new_dynamic<T>(len: usize) -> Usage {
609 Self::Dynamic(len * std::mem::size_of::<T>())
610 }
611
612 pub fn new_streamed<T>(len: usize) -> Usage {
613 Self::Dynamic(len * std::mem::size_of::<T>())
614 }
615
616 pub fn size(&self) -> usize {
617 match self {
618 Usage::Static(b) => b.size(),
619 Usage::Dynamic(s) => *s,
620 Usage::Streamed(s) => *s,
621 }
622 }
623}
624
625
626pub struct DeviceBufferMapping {
627 pub ptr : *mut u8,
628 pub offset : usize,
629 pub size : usize,
630 pub buff : DeviceBufferPtr,
631}
632
633
634
635pub enum DeviceBufferDesc {
636 Vertex(Usage),
637 Index(Usage),
638 Pixel(Usage),
639}
640
641impl DeviceBufferDesc {
642 pub fn size(&self) -> usize {
643 match self {
644 Self::Vertex(u) |
645 Self::Index(u) |
646 Self::Pixel(u) => u.size(),
647 }
648 }
649}
650
651pub type DeviceBuffer = Resource<DeviceBufferDesc>;
652pub type DeviceBufferPtr = IntrusivePtr<DeviceBuffer>;
653
654#[derive(Clone, Copy)]
659pub enum WrapMode {
660 Repeat,
661 ClampToEdge,
662 ClampToBorder,
663 MirroredRepeat,
664}
665
666#[derive(Clone)]
667pub struct PixelChannel {
668 pub size : usize,
669 pub wrap : WrapMode,
670}
671
672impl PixelChannel {
673 pub fn default(size: usize) -> Self {
674 Self {
675 size : size,
676 wrap : WrapMode::Repeat,
677 }
678 }
679
680 pub fn resize(mut self, size: usize) -> Self {
681 self.size = size;
682 self
683 }
684
685 pub fn with_wrap(mut self, wrap: WrapMode) -> Self {
686 self.wrap = wrap;
687 self
688 }
689}
690
691#[derive(Clone)]
692pub enum SamplerType {
693 Sampler2D (PixelChannel, PixelChannel),
694}
695
696#[derive(Clone, Debug)]
697pub enum Filter {
698 Nearest,
699 Linear,
700 NearestMipmapNearest,
701 NearestMipmapLinear,
702 LinearMipmapNearest,
703 LinearMipmapLinear,
704}
705
706#[derive(Clone, Debug)]
707pub enum PixelFormat {
708 RGB8U,
709 RGBA8U,
710 R8U,
711 RGB32U,
712 RGBA32U,
713 R32U,
714
715 RGB32F,
716 RGBA32F,
717 R32F,
718
719 D16,
720 D32,
721 D24S8,
722 D32S8,
723
724 RGB8(MinMagFilter),
725 RGBA8(MinMagFilter),
726 R8(MinMagFilter),
727}
728
729#[derive(Clone, Debug)]
730pub struct MinMagFilter {
731 pub min_filter : Filter,
732 pub mag_filter : Filter,
733}
734
735impl MinMagFilter {
736 pub fn default() -> Self {
737 Self {
738 min_filter : Filter::Nearest,
739 mag_filter : Filter::Nearest,
740 }
741 }
742
743 pub fn with_min_filter(mut self, filter: Filter) -> Self {
744 self.min_filter = filter;
745 self
746 }
747
748 pub fn with_mag_filter(mut self, filter: Filter) -> Self {
749 self.mag_filter = filter;
750 self
751 }
752}
753
754#[derive(Debug)]
755pub enum OrigSurfaceType {
756 UInt,
757 Float,
758}
759
760pub enum OrigSurfaceClass {
761 Color,
762 Depth,
763}
764
765impl PixelFormat {
766 pub fn to_orig_surface_type(&self) -> OrigSurfaceType {
767 match self {
768 PixelFormat::RGB8U => OrigSurfaceType::UInt,
769 PixelFormat::RGBA8U => OrigSurfaceType::UInt,
770 PixelFormat::R8U => OrigSurfaceType::UInt,
771 PixelFormat::RGB32U => OrigSurfaceType::UInt,
772 PixelFormat::RGBA32U => OrigSurfaceType::UInt,
773 PixelFormat::R32U => OrigSurfaceType::UInt,
774
775 PixelFormat::RGB32F => OrigSurfaceType::Float,
776 PixelFormat::RGBA32F => OrigSurfaceType::Float,
777 PixelFormat::R32F => OrigSurfaceType::Float,
778 PixelFormat::D16 => OrigSurfaceType::Float,
779 PixelFormat::D32 => OrigSurfaceType::Float,
780 PixelFormat::D24S8 => OrigSurfaceType::Float,
781 PixelFormat::D32S8 => OrigSurfaceType::Float,
782 PixelFormat::RGB8(_) => OrigSurfaceType::Float,
783 PixelFormat::RGBA8(_) => OrigSurfaceType::Float,
784 PixelFormat::R8(_) => OrigSurfaceType::Float,
785 }
786 }
787}
788
789#[derive(Clone)]
790pub struct SamplerDesc {
791 pub image_type : SamplerType,
792 pub mip_maps : usize,
793 pub pixel_format: PixelFormat,
794}
795
796impl SamplerDesc {
797 pub fn default(width: usize, height: usize) -> Self {
798 Self {
799 image_type : SamplerType::Sampler2D(PixelChannel::default(width), PixelChannel::default(height)),
800 mip_maps : 0,
801 pixel_format: PixelFormat::RGBA8U,
802 }
803 }
804
805 pub fn with_wrap_mode(mut self, wrap: WrapMode) -> Self {
806 let image_type =
807 match self.image_type {
808 SamplerType::Sampler2D(mut w, mut h) => {
809 w.wrap = wrap;
810 h.wrap = wrap;
811 SamplerType::Sampler2D(w, h)
812 }
813 };
814 self.image_type = image_type;
815 self
816 }
817
818 pub fn with_pixel_format(mut self, pf: PixelFormat) -> Self {
819 self.pixel_format = pf;
820 self
821 }
822
823 pub fn with_mip_maps(mut self, levels: usize) -> Self {
824 self.mip_maps = levels;
825 self
826 }
827
828 pub fn width(&self) -> usize {
829 match self.image_type {
830 SamplerType::Sampler2D(PixelChannel { size, wrap: _ }, _) => size,
831 _ => panic!("no width!")
832 }
833 }
834
835 pub fn height(&self) -> usize {
836 match self.image_type {
837 SamplerType::Sampler2D(_, PixelChannel { size, wrap: _ }) => size,
838 _ => panic!("no height!")
839 }
840 }
841
842}
843pub struct TextureDesc {
844 pub sampler_desc : SamplerDesc,
845 pub payload : Option<Box<dyn Payload>>
846}
847
848pub struct RenderTargetDesc {
849 pub sampler_desc : SamplerDesc,
850 pub sample_count : usize
851}
852
853pub type Texture = Resource<TextureDesc>;
854pub type TexturePtr = IntrusivePtr<Texture>;
855
856pub type RenderTarget = Resource<RenderTargetDesc>;
857pub type RenderTargetPtr = IntrusivePtr<RenderTarget>;
858
859#[derive(Clone)]
863pub struct ShaderDesc {
864 pub vertex_shader : String,
865 pub pixel_shader : String,
866
867 pub vertex_attributes : Vec<Vec<String>>,
868 pub vertex_uniforms : Vec<String>,
869 pub vertex_surfaces : Vec<String>,
870
871 pub pixel_uniforms : Vec<String>,
872 pub pixel_surfaces : Vec<String>,
873}
874
875pub type Shader = Resource<ShaderDesc>;
876pub type ShaderPtr = IntrusivePtr<Shader>;
877
878#[derive(Clone, Eq, PartialEq)]
882pub enum IndexType {
883 None,
884 UInt16,
885 UInt32,
886}
887
888pub trait IndexTypeTrait {
889 fn to_index_type() -> IndexType;
890}
891
892impl IndexTypeTrait for u16 {
893 fn to_index_type() -> IndexType { IndexType::UInt16 }
894}
895
896impl IndexTypeTrait for u32 {
897 fn to_index_type() -> IndexType { IndexType::UInt32 }
898}
899
900#[derive(Clone)]
901pub struct Bindings {
902 pub vertex_buffers : Vec<DeviceBufferPtr>,
903 pub index_buffer : Option<DeviceBufferPtr>,
904
905 pub vertex_images : Vec<TexturePtr>,
906 pub pixel_images : Vec<TexturePtr>,
907}
908
909#[derive(Clone)]
913pub enum PrimitiveType {
914 Points,
915 Lines,
916 LineStrip,
917 Triangles,
918 TriangleStrip,
919}
920
921#[derive(Clone)]
922pub enum CullMode {
923 Winding,
924 None,
925}
926
927#[derive(Clone)]
928pub enum FaceWinding {
929 CCW,
930 CW,
931}
932
933#[derive(Clone)]
934pub struct VertexBufferLayout {
935 pub buffer_id : usize,
936 pub vertex_attributes : Vec<VertexAttributeDesc>,
937 pub stride : usize,
938 pub divisor : usize,
939}
940
941#[derive(Clone)]
942pub enum BlendFactor {
943 Zero,
944 One,
945
946 SrcColor,
947 OneMinusSrcColor,
948 SrcAlpha,
949 OneMinusSrcAlpha,
950
951 DstColor,
952 OneMinusDstColor,
953 DstAlpha,
954 OneMinusDstAlpha,
955
956 SrcAlphaSaturate,
957 ConstantColor,
958 OneMinusConstantColor,
959 ConstantAlpha,
960 OneMinusConstantAlpha,
961}
962
963
964#[derive(Clone)]
965pub struct Blend {
966 pub src_factor_rgb : BlendFactor,
967 pub src_factor_alpha : BlendFactor,
968
969 pub dst_factor_rgb : BlendFactor,
970 pub dst_factor_alpha : BlendFactor,
971}
972
973impl Blend {
974 pub fn default() -> Self {
975 Self {
976 src_factor_rgb : BlendFactor::One,
977 src_factor_alpha : BlendFactor::One,
978
979 dst_factor_rgb : BlendFactor::OneMinusSrcAlpha,
980 dst_factor_alpha : BlendFactor::OneMinusSrcAlpha,
981 }
982 }
983}
984
985#[derive(Clone)]
986pub enum BlendOp {
987 None,
988 Add(Blend),
989 Subtract(Blend),
990 ReverseSubtract(Blend),
991}
992
993
994#[derive(Clone)]
995pub struct PipelineDesc {
996 pub primitive_type : PrimitiveType,
997 pub shader : ShaderPtr,
998
999 pub buffer_layouts : Vec<VertexBufferLayout>,
1001
1002 pub uniform_descs : Vec<UniformDataDesc>,
1004 pub index_type : IndexType,
1005
1006 pub face_winding : FaceWinding,
1007 pub cull_mode : CullMode,
1008
1009 pub depth_write : bool,
1010 pub depth_test : bool,
1011
1012 pub blend : BlendOp,
1013}
1014
1015pub type Pipeline = Resource<PipelineDesc>;
1016pub type PipelinePtr= IntrusivePtr<Pipeline>;
1017
1018#[derive(Clone)]
1022pub enum ColorPassAction {
1023 Clear(Color4b),
1024 Previous,
1025}
1026
1027#[derive(Clone)]
1028pub enum DepthPassAction {
1029 Clear(f32),
1030 Previous,
1031}
1032
1033#[derive(Clone)]
1034pub enum SurfaceAttachment {
1035 Texture(TexturePtr),
1036 RenderTarget(RenderTargetPtr)
1037}
1038
1039impl SurfaceAttachment {
1040 pub fn pixel_format(&self) -> PixelFormat {
1041 match self {
1042 SurfaceAttachment::Texture(tex) => tex.desc.sampler_desc.pixel_format.clone(),
1043 SurfaceAttachment::RenderTarget(rt) => rt.desc.sampler_desc.pixel_format.clone(),
1044 }
1045 }
1046}
1047
1048#[derive(Clone)]
1049pub struct FrameBufferDesc {
1050 pub color_attachements : [Option<SurfaceAttachment>; 4],
1051 pub depth_stencil_attachement : SurfaceAttachment,
1052}
1053
1054pub type FrameBuffer = Resource<FrameBufferDesc>;
1055pub type FrameBufferPtr = IntrusivePtr<FrameBuffer>;
1056
1057pub struct Pass {
1058 pub width : usize,
1059 pub height : usize,
1060 pub frame_buffer : Option<FrameBufferPtr>,
1061 pub color_actions : [ColorPassAction; 4],
1062 pub depth_action : DepthPassAction,
1063}
1064
1065pub enum ReadbackPayload {
1069 RGB32U(Vec<Vector3<u32>>),
1070 RGBA32U(Vec<Vector4<u32>>),
1071 R32U(Vec<u32>),
1072
1073 RGB32F(Vec<Vec3f>),
1074 RGBA32F(Vec<Vec4f>),
1075 R32F(Vec<f32>),
1076
1077 Depth(Vec<f32>),
1078}
1079
1080pub enum ReadbackError {
1081 NoReadbackFromRenderTarget,
1082 RectOutOfBound,
1083}
1084
1085pub enum ReadbackResult {
1086 Ok(ReadbackPayload),
1087 Error(ReadbackError)
1088}
1089
1090pub struct DriverCaps {
1094 pub max_2d_surface_dimension : Dimensioni,
1095}
1096
1097pub trait Driver : IntrusiveCounter {
1101 fn get_caps(&self) -> &DriverCaps;
1102 fn create_device_buffer(&mut self, desc: DeviceBufferDesc) -> Option<DeviceBufferPtr>;
1103 fn create_texture(&mut self, desc: TextureDesc) -> Option<TexturePtr>;
1104 fn create_render_target(&mut self, desc: RenderTargetDesc) -> Option<RenderTargetPtr>;
1105 fn create_shader(&mut self, desc: ShaderDesc) -> Option<ShaderPtr>;
1106 fn create_pipeline(&mut self, desc: PipelineDesc) -> Option<PipelinePtr>;
1107 fn create_frame_buffer(&mut self, desc: FrameBufferDesc) -> Option<FrameBufferPtr>;
1108
1109 fn delete_resource(&mut self, resource_type: &ResourceType, res_id: usize);
1110
1111 fn update_device_buffer(&mut self, dev_buf: &mut DeviceBufferPtr, offset: usize, pl: &dyn Payload);
1112 fn update_texture(&mut self, dev_buf: &mut TexturePtr, pl: Box<dyn Payload>);
1113
1114 fn begin_pass(&mut self, pass: &Pass);
1115 fn end_pass(&mut self);
1116
1117 fn set_viewport(&mut self, x: u32, y: u32, w: u32, h: u32);
1118 fn set_scissor(&mut self, x: u32, y: u32, w: u32, h: u32);
1119
1120 fn draw(&mut self, pipe: &Pipeline, bindings: &Bindings, uniforms: *const c_void, prim_count: u32, instance_count: u32);
1121
1122 fn read_back(&mut self, surface: &TexturePtr, x: u32, y: u32, w: u32, h: u32) -> Option<ReadbackPayload>;
1123}
1124
1125pub type DriverPtr = IntrusivePtr<dyn Driver>;
1126
1127
1128#[cfg(test)]
1129mod tests {
1130 use super::*;
1131
1132 struct InTest {
1133 s: String,
1134 r: core::sync::atomic::AtomicIsize,
1135 }
1136
1137 impl IntrusiveCounter for InTest {
1138 fn increment(&mut self) { self.r.fetch_add(1, Ordering::SeqCst); }
1139 fn decrement(&mut self) -> isize {
1140 self.r.fetch_sub(1, Ordering::SeqCst)
1141 }
1142 }
1143
1144 impl Drop for InTest {
1145 fn drop(&mut self) {}
1146 }
1147
1148 #[test]
1149 fn test_intrusive() {
1150 let it = InTest { s: String::from("Hello World"), r : core::sync::atomic::AtomicIsize::new(0) };
1151 let p = IntrusivePtr::new(it);
1152 format!("r: {}", p.s);
1153 }
1154}