1#![allow(
2 clippy::match_like_matches_macro,
4 clippy::redundant_pattern_matching,
6 clippy::needless_lifetimes,
8 clippy::new_without_default,
10 clippy::single_match,
12 clippy::vec_init_then_push,
14 clippy::missing_safety_doc,
16)]
17#![warn(
18 trivial_numeric_casts,
19 unused_extern_crates,
20 clippy::pattern_type_mismatch,
24)]
25
26pub use naga::{StorageAccess, VectorSize};
27pub type Transform = mint::RowMatrix3x4<f32>;
28
29pub const IDENTITY_TRANSFORM: Transform = mint::RowMatrix3x4 {
30 x: mint::Vector4 {
31 x: 1.0,
32 y: 0.0,
33 z: 0.0,
34 w: 0.0,
35 },
36 y: mint::Vector4 {
37 x: 0.0,
38 y: 1.0,
39 z: 0.0,
40 w: 0.0,
41 },
42 z: mint::Vector4 {
43 x: 0.0,
44 y: 0.0,
45 z: 1.0,
46 w: 0.0,
47 },
48};
49
50pub mod derive;
51#[cfg_attr(
52 all(not(vulkan), not(gles), any(target_os = "ios", target_os = "macos")),
53 path = "metal/mod.rs"
54)]
55#[cfg_attr(
56 all(
57 not(gles),
58 any(
59 vulkan,
60 windows,
61 target_os = "linux",
62 target_os = "android",
63 target_os = "freebsd"
64 )
65 ),
66 path = "vulkan/mod.rs"
67)]
68#[cfg_attr(any(gles, target_arch = "wasm32"), path = "gles/mod.rs")]
69mod hal;
70mod shader;
71mod traits;
72pub mod util;
73pub mod limits {
74 pub const PASS_COUNT: usize = 100;
76 pub const PLAIN_DATA_SIZE: u32 = 256;
78 pub const RESOURCES_IN_GROUP: u32 = 8;
80 pub const STORAGE_BUFFER_ALIGNMENT: u64 = 256;
82 pub const ACCELERATION_STRUCTURE_SCRATCH_ALIGNMENT: u64 = 256;
84}
85
86pub use hal::*;
87
88#[cfg(target_arch = "wasm32")]
89pub const CANVAS_ID: &str = "blade";
90
91use std::{fmt, num::NonZeroU32};
92
93#[derive(Clone, Debug, Default)]
94pub struct ContextDesc {
95 pub presentation: bool,
97 pub validation: bool,
100 pub timing: bool,
102 pub capture: bool,
104 pub overlay: bool,
106 pub device_id: u32,
108}
109
110#[derive(Debug)]
111pub enum NotSupportedError {
112 Platform(PlatformError),
113 NoSupportedDeviceFound,
114 PlatformNotSupported,
115}
116
117impl From<PlatformError> for NotSupportedError {
118 fn from(error: PlatformError) -> Self {
119 Self::Platform(error)
120 }
121}
122
123#[derive(Clone, Debug, Default, PartialEq)]
124pub struct Capabilities {
125 pub ray_query: ShaderVisibility,
127}
128
129#[derive(Clone, Debug, Default)]
130pub struct DeviceInformation {
131 pub is_software_emulated: bool,
133 pub device_name: String,
135 pub driver_name: String,
137 pub driver_info: String,
139}
140
141impl Context {
142 pub fn create_surface_configured<
143 I: raw_window_handle::HasWindowHandle + raw_window_handle::HasDisplayHandle,
144 >(
145 &self,
146 window: &I,
147 config: SurfaceConfig,
148 ) -> Result<Surface, NotSupportedError> {
149 let mut surface = self.create_surface(window)?;
150 self.reconfigure_surface(&mut surface, config);
151 Ok(surface)
152 }
153}
154
155#[derive(Clone, Copy, Debug, PartialEq)]
156pub enum Memory {
157 Device,
159 Shared,
161 Upload,
163}
164
165impl Memory {
166 pub fn is_host_visible(&self) -> bool {
167 match *self {
168 Self::Device => false,
169 Self::Shared | Self::Upload => true,
170 }
171 }
172}
173
174#[derive(Debug)]
175pub struct BufferDesc<'a> {
176 pub name: &'a str,
177 pub size: u64,
178 pub memory: Memory,
179}
180
181#[derive(Clone, Copy, Debug)]
182pub struct BufferPiece {
183 pub buffer: Buffer,
184 pub offset: u64,
185}
186
187impl From<Buffer> for BufferPiece {
188 fn from(buffer: Buffer) -> Self {
189 Self { buffer, offset: 0 }
190 }
191}
192
193impl BufferPiece {
194 pub fn data(&self) -> *mut u8 {
195 let base = self.buffer.data();
196 assert!(!base.is_null());
197 unsafe { base.offset(self.offset as isize) }
198 }
199}
200
201impl Buffer {
202 pub fn at(self, offset: u64) -> BufferPiece {
203 BufferPiece {
204 buffer: self,
205 offset,
206 }
207 }
208}
209
210pub type ResourceIndex = u32;
211pub struct ResourceArray<T, const N: ResourceIndex> {
214 data: Vec<T>,
215 free_list: Vec<ResourceIndex>,
216}
217impl<T, const N: ResourceIndex> ResourceArray<T, N> {
218 pub fn new() -> Self {
219 Self {
220 data: Vec::with_capacity(N as usize),
221 free_list: Vec::new(),
222 }
223 }
224 pub fn alloc(&mut self, value: T) -> ResourceIndex {
225 if let Some(index) = self.free_list.pop() {
226 self.data[index as usize] = value;
227 index
228 } else {
229 let index = self.data.len() as u32;
230 assert!(index < N);
231 self.data.push(value);
232 index
233 }
234 }
235 pub fn free(&mut self, index: ResourceIndex) {
236 self.free_list.push(index);
237 }
238 pub fn clear(&mut self) {
239 self.data.clear();
240 self.free_list.clear();
241 }
242}
243impl<T, const N: ResourceIndex> std::ops::Index<ResourceIndex> for ResourceArray<T, N> {
244 type Output = T;
245 fn index(&self, index: ResourceIndex) -> &T {
246 &self.data[index as usize]
247 }
248}
249impl<T, const N: ResourceIndex> std::ops::IndexMut<ResourceIndex> for ResourceArray<T, N> {
250 fn index_mut(&mut self, index: ResourceIndex) -> &mut T {
251 &mut self.data[index as usize]
252 }
253}
254pub type BufferArray<const N: ResourceIndex> = ResourceArray<BufferPiece, N>;
255pub type TextureArray<const N: ResourceIndex> = ResourceArray<TextureView, N>;
256
257#[derive(Clone, Copy, Debug)]
258pub struct TexturePiece {
259 pub texture: Texture,
260 pub mip_level: u32,
261 pub array_layer: u32,
262 pub origin: [u32; 3],
263}
264
265impl From<Texture> for TexturePiece {
266 fn from(texture: Texture) -> Self {
267 Self {
268 texture,
269 mip_level: 0,
270 array_layer: 0,
271 origin: [0; 3],
272 }
273 }
274}
275
276#[non_exhaustive]
277#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
278pub enum TextureFormat {
279 R8Unorm,
281 Rg8Unorm,
282 Rg8Snorm,
283 Rgba8Unorm,
284 Rgba8UnormSrgb,
285 Bgra8Unorm,
286 Bgra8UnormSrgb,
287 Rgba8Snorm,
288 R16Float,
289 Rg16Float,
290 Rgba16Float,
291 R32Float,
292 Rg32Float,
293 Rgba32Float,
294 R32Uint,
295 Rg32Uint,
296 Rgba32Uint,
297 Depth32Float,
299 Bc1Unorm,
301 Bc1UnormSrgb,
302 Bc2Unorm,
303 Bc2UnormSrgb,
304 Bc3Unorm,
305 Bc3UnormSrgb,
306 Bc4Unorm,
307 Bc4Snorm,
308 Bc5Unorm,
309 Bc5Snorm,
310 Bc6hUfloat,
311 Bc6hFloat,
312 Bc7Unorm,
313 Bc7UnormSrgb,
314 Rgb10a2Unorm,
316 Rg11b10Ufloat,
317 Rgb9e5Ufloat,
318}
319
320#[derive(Clone, Copy, Debug)]
321pub struct TexelBlockInfo {
322 pub dimensions: (u8, u8),
323 pub size: u8,
324}
325
326bitflags::bitflags! {
327 #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)]
328 pub struct TexelAspects: u8 {
329 const COLOR = 0x1;
330 const DEPTH = 0x2;
331 const STENCIL = 0x4;
332 }
333}
334
335#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
337pub enum TextureDimension {
338 D1,
340 D2,
342 D3,
344}
345
346#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
347pub enum ViewDimension {
348 D1,
349 D1Array,
350 D2,
351 D2Array,
352 Cube,
353 CubeArray,
354 D3,
355}
356
357#[repr(C)]
358#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
359pub struct Extent {
360 pub width: u32,
361 pub height: u32,
362 pub depth: u32,
363}
364impl Default for Extent {
365 fn default() -> Self {
366 Self {
367 width: 1,
368 height: 1,
369 depth: 1,
370 }
371 }
372}
373impl fmt::Display for Extent {
374 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
375 write!(f, "{}x{}x{}", self.width, self.height, self.depth)
376 }
377}
378
379impl Extent {
380 pub fn max_mip_levels(&self) -> u32 {
381 self.width
382 .max(self.height)
383 .max(self.depth)
384 .next_power_of_two()
385 .trailing_zeros()
386 }
387 pub fn at_mip_level(&self, level: u32) -> Self {
388 Self {
389 width: (self.width >> level).max(1),
390 height: (self.height >> level).max(1),
391 depth: (self.depth >> level).max(1),
392 }
393 }
394}
395
396bitflags::bitflags! {
397 #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)]
398 pub struct TextureUsage: u32 {
399 const COPY = 1 << 0;
400 const TARGET = 1 << 1;
401 const RESOURCE = 1 << 2;
402 const STORAGE = 1 << 3;
403 }
404}
405
406#[derive(Debug)]
407pub struct TextureDesc<'a> {
408 pub name: &'a str,
409 pub format: TextureFormat,
410 pub size: Extent,
411 pub array_layer_count: u32,
412 pub mip_level_count: u32,
413 pub sample_count: u32,
414 pub dimension: TextureDimension,
415 pub usage: TextureUsage,
416}
417
418#[derive(Clone, Debug, Default, Eq, PartialEq)]
419pub struct TextureSubresources {
420 pub base_mip_level: u32,
421 pub mip_level_count: Option<NonZeroU32>,
422 pub base_array_layer: u32,
423 pub array_layer_count: Option<NonZeroU32>,
424}
425
426#[derive(Debug)]
427pub struct TextureViewDesc<'a> {
428 pub name: &'a str,
429 pub format: TextureFormat,
430 pub dimension: ViewDimension,
431 pub subresources: &'a TextureSubresources,
432}
433
434bitflags::bitflags! {
435 #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)]
436 pub struct ShaderVisibility: u32 {
437 const COMPUTE = 1 << 0;
438 const VERTEX = 1 << 1;
439 const FRAGMENT = 1 << 2;
440 }
441}
442
443#[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)]
445pub enum AddressMode {
446 #[default]
448 ClampToEdge,
449 Repeat,
451 MirrorRepeat,
453 ClampToBorder,
455}
456
457#[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)]
459pub enum FilterMode {
460 #[default]
462 Nearest,
463 Linear,
465}
466
467#[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)]
469pub enum CompareFunction {
470 Never,
472 Less,
474 Equal,
478 LessEqual,
480 Greater,
482 NotEqual,
486 GreaterEqual,
488 #[default]
490 Always,
491}
492
493#[derive(Clone, Copy, Debug)]
494pub enum TextureColor {
495 TransparentBlack,
496 OpaqueBlack,
497 White,
498}
499
500#[derive(Debug, Default)]
501pub struct SamplerDesc<'a> {
502 pub name: &'a str,
503 pub address_modes: [AddressMode; 3],
504 pub mag_filter: FilterMode,
505 pub min_filter: FilterMode,
506 pub mipmap_filter: FilterMode,
507 pub lod_min_clamp: f32,
508 pub lod_max_clamp: Option<f32>,
509 pub compare: Option<CompareFunction>,
510 pub anisotropy_clamp: u32,
511 pub border_color: Option<TextureColor>,
512}
513
514#[derive(Debug)]
515pub enum AccelerationStructureType {
516 TopLevel,
517 BottomLevel,
518}
519
520#[derive(Debug)]
521pub struct AccelerationStructureDesc<'a> {
522 pub name: &'a str,
523 pub ty: AccelerationStructureType,
524 pub size: u64,
525}
526
527#[non_exhaustive]
528#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
529pub enum VertexFormat {
530 F32,
531 F32Vec2,
532 F32Vec3,
533 F32Vec4,
534 U32,
535 U32Vec2,
536 U32Vec3,
537 U32Vec4,
538 I32,
539 I32Vec2,
540 I32Vec3,
541 I32Vec4,
542}
543
544#[derive(Clone, Debug)]
545pub struct AccelerationStructureMesh {
546 pub vertex_data: BufferPiece,
547 pub vertex_format: VertexFormat,
548 pub vertex_stride: u32,
549 pub vertex_count: u32,
550 pub index_data: BufferPiece,
551 pub index_type: Option<IndexType>,
552 pub triangle_count: u32,
553 pub transform_data: BufferPiece,
554 pub is_opaque: bool,
555}
556
557#[derive(Clone, Debug)]
558pub struct AccelerationStructureInstance {
559 pub acceleration_structure_index: u32,
560 pub transform: Transform,
561 pub mask: u32,
562 pub custom_index: u32,
563}
564
565#[derive(Clone, Copy, Debug, PartialEq)]
566pub struct AccelerationStructureSizes {
567 pub data: u64,
569 pub scratch: u64,
571}
572
573pub struct Shader {
574 module: naga::Module,
575 info: naga::valid::ModuleInfo,
576 source: String,
577}
578
579#[derive(Clone, Copy)]
580pub struct ShaderFunction<'a> {
581 pub shader: &'a Shader,
582 pub entry_point: &'a str,
583}
584
585impl ShaderFunction<'_> {
586 fn entry_point_index(&self) -> usize {
587 self.shader
588 .module
589 .entry_points
590 .iter()
591 .position(|ep| ep.name == self.entry_point)
592 .expect("Entry point not found in the shader")
593 }
594}
595
596#[derive(Clone, Copy, Debug, PartialEq)]
597pub enum ShaderBinding {
598 Texture,
599 TextureArray { count: u32 },
600 Sampler,
601 Buffer,
602 BufferArray { count: u32 },
603 AccelerationStructure,
604 Plain { size: u32 },
605}
606
607pub trait ShaderBindable: Clone + Copy + derive::HasShaderBinding {
608 fn bind_to(&self, context: &mut PipelineContext, index: u32);
609}
610
611#[derive(Debug)]
612struct ShaderDataInfo {
613 visibility: ShaderVisibility,
614 binding_access: Box<[StorageAccess]>,
615}
616
617#[derive(Clone, Debug, Default, PartialEq)]
618pub struct ShaderDataLayout {
619 pub bindings: Vec<(&'static str, ShaderBinding)>,
620}
621impl ShaderDataLayout {
622 pub const EMPTY: &'static Self = &Self {
623 bindings: Vec::new(),
624 };
625
626 fn to_info(&self) -> ShaderDataInfo {
627 ShaderDataInfo {
628 visibility: ShaderVisibility::empty(),
629 binding_access: vec![StorageAccess::empty(); self.bindings.len()].into_boxed_slice(),
630 }
631 }
632}
633
634pub trait ShaderData {
635 fn layout() -> ShaderDataLayout;
636 fn fill(&self, context: PipelineContext);
637}
638
639#[derive(Copy, Clone, Debug, PartialEq)]
640pub struct VertexAttribute {
641 pub offset: u32,
642 pub format: VertexFormat,
643}
644
645struct VertexAttributeMapping {
646 buffer_index: usize,
647 attribute_index: usize,
648}
649
650#[derive(Clone, Debug, Default, PartialEq)]
651pub struct VertexLayout {
652 pub attributes: Vec<(&'static str, VertexAttribute)>,
653 pub stride: u32,
654}
655
656pub trait Vertex {
657 fn layout() -> VertexLayout;
658}
659
660#[derive(Clone, Debug, PartialEq)]
661pub struct VertexFetchState<'a> {
662 pub layout: &'a VertexLayout,
663 pub instanced: bool,
664}
665
666pub struct ShaderDesc<'a> {
667 pub source: &'a str,
668}
669
670#[derive(Clone, Debug, Default, PartialEq)]
671pub enum CommandType {
672 Transfer,
673 Compute,
674 #[default]
675 General,
676}
677
678pub struct CommandEncoderDesc<'a> {
679 pub name: &'a str,
680 pub buffer_count: u32,
684}
685
686pub struct ComputePipelineDesc<'a> {
687 pub name: &'a str,
688 pub data_layouts: &'a [&'a ShaderDataLayout],
689 pub compute: ShaderFunction<'a>,
690}
691
692#[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)]
694pub enum PrimitiveTopology {
695 PointList,
697 LineList,
701 LineStrip,
705 #[default]
709 TriangleList,
710 TriangleStrip,
714}
715
716#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
718pub enum FrontFace {
719 #[default]
723 Ccw,
724 Cw,
728}
729
730#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
732pub enum Face {
733 Front,
735 Back,
737}
738
739#[derive(Clone, Debug, Default)]
740pub struct PrimitiveState {
741 pub topology: PrimitiveTopology,
743 pub front_face: FrontFace,
745 pub cull_mode: Option<Face>,
747 pub unclipped_depth: bool,
749 pub wireframe: bool,
751}
752
753#[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)]
755pub enum StencilOperation {
756 #[default]
758 Keep,
759 Zero,
761 Replace,
763 Invert,
765 IncrementClamp,
767 DecrementClamp,
769 IncrementWrap,
771 DecrementWrap,
773}
774
775#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
779pub struct StencilFaceState {
780 pub compare: CompareFunction,
782 pub fail_op: StencilOperation,
784 pub depth_fail_op: StencilOperation,
786 pub pass_op: StencilOperation,
788}
789
790impl StencilFaceState {
791 pub const IGNORE: Self = StencilFaceState {
793 compare: CompareFunction::Always,
794 fail_op: StencilOperation::Keep,
795 depth_fail_op: StencilOperation::Keep,
796 pass_op: StencilOperation::Keep,
797 };
798}
799
800impl Default for StencilFaceState {
801 fn default() -> Self {
802 Self::IGNORE
803 }
804}
805
806#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
810pub struct StencilState {
811 pub front: StencilFaceState,
813 pub back: StencilFaceState,
815 pub read_mask: u32,
817 pub write_mask: u32,
819}
820
821#[derive(Clone, Copy, Debug, Default, PartialEq)]
822pub struct DepthBiasState {
823 pub constant: i32,
825 pub slope_scale: f32,
827 pub clamp: f32,
829}
830
831#[derive(Clone, Debug)]
833pub struct DepthStencilState {
834 pub format: TextureFormat,
836 pub depth_write_enabled: bool,
838 pub depth_compare: CompareFunction,
840 pub stencil: StencilState,
842 pub bias: DepthBiasState,
844}
845
846#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
848pub enum BlendFactor {
849 Zero,
851 One,
853 Src,
855 OneMinusSrc,
857 SrcAlpha,
859 OneMinusSrcAlpha,
861 Dst,
863 OneMinusDst,
865 DstAlpha,
867 OneMinusDstAlpha,
869 SrcAlphaSaturated,
871 Constant,
873 OneMinusConstant,
875}
876
877#[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)]
879pub enum BlendOperation {
880 #[default]
882 Add,
883 Subtract,
885 ReverseSubtract,
887 Min,
889 Max,
891}
892
893#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
895pub struct BlendComponent {
896 pub src_factor: BlendFactor,
898 pub dst_factor: BlendFactor,
900 pub operation: BlendOperation,
903}
904
905impl BlendComponent {
906 pub const REPLACE: Self = Self {
908 src_factor: BlendFactor::One,
909 dst_factor: BlendFactor::Zero,
910 operation: BlendOperation::Add,
911 };
912
913 pub const OVER: Self = Self {
915 src_factor: BlendFactor::One,
916 dst_factor: BlendFactor::OneMinusSrcAlpha,
917 operation: BlendOperation::Add,
918 };
919
920 pub const ADDITIVE: Self = Self {
922 src_factor: BlendFactor::One,
923 dst_factor: BlendFactor::One,
924 operation: BlendOperation::Add,
925 };
926}
927
928impl Default for BlendComponent {
929 fn default() -> Self {
930 Self::REPLACE
931 }
932}
933
934#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
937pub struct BlendState {
938 pub color: BlendComponent,
940 pub alpha: BlendComponent,
942}
943
944impl BlendState {
945 pub const REPLACE: Self = Self {
947 color: BlendComponent::REPLACE,
948 alpha: BlendComponent::REPLACE,
949 };
950
951 pub const ALPHA_BLENDING: Self = Self {
953 color: BlendComponent {
954 src_factor: BlendFactor::SrcAlpha,
955 dst_factor: BlendFactor::OneMinusSrcAlpha,
956 operation: BlendOperation::Add,
957 },
958 alpha: BlendComponent::OVER,
959 };
960
961 pub const PREMULTIPLIED_ALPHA_BLENDING: Self = Self {
963 color: BlendComponent::OVER,
964 alpha: BlendComponent::OVER,
965 };
966
967 pub const ADDITIVE: Self = Self {
969 color: BlendComponent::ADDITIVE,
970 alpha: BlendComponent::ADDITIVE,
971 };
972}
973
974bitflags::bitflags! {
975 #[repr(transparent)]
977 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
978 pub struct ColorWrites: u32 {
979 const RED = 1 << 0;
981 const GREEN = 1 << 1;
983 const BLUE = 1 << 2;
985 const ALPHA = 1 << 3;
987 const COLOR = Self::RED.bits() | Self::GREEN.bits() | Self::BLUE.bits();
989 const ALL = Self::RED.bits() | Self::GREEN.bits() | Self::BLUE.bits() | Self::ALPHA.bits();
991 }
992}
993
994impl Default for ColorWrites {
995 fn default() -> Self {
996 Self::ALL
997 }
998}
999
1000#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1002pub struct ColorTargetState {
1003 pub format: TextureFormat,
1005 pub blend: Option<BlendState>,
1007 pub write_mask: ColorWrites,
1009}
1010
1011impl From<TextureFormat> for ColorTargetState {
1012 fn from(format: TextureFormat) -> Self {
1013 Self {
1014 format,
1015 blend: None,
1016 write_mask: ColorWrites::ALL,
1017 }
1018 }
1019}
1020
1021pub struct RenderPipelineDesc<'a> {
1022 pub name: &'a str,
1023 pub data_layouts: &'a [&'a ShaderDataLayout],
1024 pub vertex: ShaderFunction<'a>,
1025 pub vertex_fetches: &'a [VertexFetchState<'a>],
1026 pub primitive: PrimitiveState,
1027 pub depth_stencil: Option<DepthStencilState>,
1028 pub fragment: Option<ShaderFunction<'a>>,
1029 pub color_targets: &'a [ColorTargetState],
1030 pub multisample_state: MultisampleState,
1031}
1032
1033#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1034pub struct MultisampleState {
1035 pub sample_count: u32,
1036 pub sample_mask: u64,
1037 pub alpha_to_coverage: bool,
1038}
1039
1040impl Default for MultisampleState {
1041 fn default() -> Self {
1042 Self {
1043 sample_count: 1,
1044 sample_mask: !0,
1045 alpha_to_coverage: false,
1046 }
1047 }
1048}
1049
1050#[derive(Clone, Copy, Debug)]
1051pub enum InitOp {
1052 Load,
1053 Clear(TextureColor),
1054 DontCare,
1055}
1056
1057#[derive(Clone, Copy, Debug)]
1058pub enum FinishOp {
1059 Store,
1060 Discard,
1061 ResolveTo(TextureView),
1064 Ignore,
1065}
1066
1067#[derive(Debug)]
1068pub struct RenderTarget {
1069 pub view: TextureView,
1070 pub init_op: InitOp,
1071 pub finish_op: FinishOp,
1072}
1073
1074#[derive(Debug)]
1075pub struct RenderTargetSet<'a> {
1076 pub colors: &'a [RenderTarget],
1077 pub depth_stencil: Option<RenderTarget>,
1078}
1079
1080#[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)]
1082pub enum DisplaySync {
1083 #[default]
1085 Block,
1086 Recent,
1089 Tear,
1091}
1092
1093#[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)]
1094pub enum ColorSpace {
1095 #[default]
1096 Linear,
1097 Srgb,
1098}
1099
1100#[derive(Clone, Copy, Debug, Default, PartialEq)]
1101pub struct SurfaceConfig {
1102 pub size: Extent,
1103 pub usage: TextureUsage,
1104 pub display_sync: DisplaySync,
1105 pub color_space: ColorSpace,
1112 pub transparent: bool,
1113 pub allow_exclusive_full_screen: bool,
1114}
1115
1116#[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq)]
1117pub enum AlphaMode {
1118 #[default]
1119 Ignored,
1120 PreMultiplied,
1121 PostMultiplied,
1122}
1123
1124#[derive(Clone, Copy, Debug, PartialEq)]
1125pub struct SurfaceInfo {
1126 pub format: TextureFormat,
1127 pub alpha: AlphaMode,
1128}
1129
1130#[derive(Clone, Copy, Debug, PartialEq)]
1131pub enum IndexType {
1132 U16,
1133 U32,
1134}
1135
1136#[derive(Clone, Debug, PartialEq)]
1137pub struct ScissorRect {
1138 pub x: i32,
1139 pub y: i32,
1140 pub w: u32,
1141 pub h: u32,
1142}
1143
1144#[derive(Clone, Debug, PartialEq)]
1145pub struct Viewport {
1146 pub x: f32,
1147 pub y: f32,
1148 pub w: f32,
1149 pub h: f32,
1150}
1151
1152pub type Timings = std::collections::HashMap<String, std::time::Duration>;