1use alloc::vec::Vec;
2
3use crate::{Features, TextureAspect, TextureSampleType, TextureUsages};
4
5#[cfg(any(feature = "serde", test))]
6use serde::{Deserialize, Serialize};
7
8#[repr(C)]
10#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12pub enum AstcBlock {
13 B4x4,
15 B5x4,
17 B5x5,
19 B6x5,
21 B6x6,
23 B8x5,
25 B8x6,
27 B8x8,
29 B10x5,
31 B10x6,
33 B10x8,
35 B10x10,
37 B12x10,
39 B12x12,
41}
42
43#[repr(C)]
45#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
46#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
47pub enum AstcChannel {
48 Unorm,
52 UnormSrgb,
56 Hdr,
60}
61
62bitflags::bitflags! {
63 #[repr(transparent)]
65 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
66 #[cfg_attr(feature = "serde", serde(transparent))]
67 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
68 pub struct TextureChannel: u16 {
69 const RED = 1 << 0;
71 const GREEN = 1 << 1;
73 const BLUE = 1 << 2;
75 const ALPHA = 1 << 3;
77 const STENCIL = 1 << 4;
79 const DEPTH = 1 << 5;
81 const LUMINANCE = 1 << 6;
83 const CHROMINANCE_BLUE = 1 << 7;
85 const CHROMINANCE_RED = 1 << 8;
87
88 const RG = Self::RED.bits() | Self::GREEN.bits();
90 const RGB = Self::RG.bits() | Self::BLUE.bits();
92 const RGBA = Self::RGB.bits() | Self::ALPHA.bits();
94 const DEPTH_STENCIL = Self::DEPTH.bits() | Self::STENCIL.bits();
96 const LUMINANCE_CHROMINANCE = Self::LUMINANCE.bits() | Self::CHROMINANCE_BLUE.bits() | Self::CHROMINANCE_RED.bits();
98 }
99}
100
101#[repr(C)]
124#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
125pub enum TextureFormat {
126 R8Unorm,
129 R8Snorm,
131 R8Uint,
133 R8Sint,
135
136 R16Uint,
139 R16Sint,
141 R16Unorm,
145 R16Snorm,
149 R16Float,
151 Rg8Unorm,
153 Rg8Snorm,
155 Rg8Uint,
157 Rg8Sint,
159
160 R32Uint,
163 R32Sint,
165 R32Float,
167 Rg16Uint,
169 Rg16Sint,
171 Rg16Unorm,
175 Rg16Snorm,
179 Rg16Float,
181 Rgba8Unorm,
183 Rgba8UnormSrgb,
185 Rgba8Snorm,
187 Rgba8Uint,
189 Rgba8Sint,
191 Bgra8Unorm,
193 Bgra8UnormSrgb,
195
196 Rgb9e5Ufloat,
199 Rgb10a2Uint,
201 Rgb10a2Unorm,
203 Rg11b10Ufloat,
205
206 R64Uint,
211 Rg32Uint,
213 Rg32Sint,
215 Rg32Float,
217 Rgba16Uint,
219 Rgba16Sint,
221 Rgba16Unorm,
225 Rgba16Snorm,
229 Rgba16Float,
231
232 Rgba32Uint,
235 Rgba32Sint,
237 Rgba32Float,
239
240 Stencil8,
243 Depth16Unorm,
245 Depth24Plus,
247 Depth24PlusStencil8,
249 Depth32Float,
251 Depth32FloatStencil8,
255
256 NV12,
270
271 P010,
287
288 Bc1RgbaUnorm,
297 Bc1RgbaUnormSrgb,
305 Bc2RgbaUnorm,
313 Bc2RgbaUnormSrgb,
321 Bc3RgbaUnorm,
329 Bc3RgbaUnormSrgb,
337 Bc4RUnorm,
345 Bc4RSnorm,
353 Bc5RgUnorm,
361 Bc5RgSnorm,
369 Bc6hRgbUfloat,
376 Bc6hRgbFloat,
383 Bc7RgbaUnorm,
391 Bc7RgbaUnormSrgb,
399 Etc2Rgb8Unorm,
404 Etc2Rgb8UnormSrgb,
409 Etc2Rgb8A1Unorm,
414 Etc2Rgb8A1UnormSrgb,
419 Etc2Rgba8Unorm,
424 Etc2Rgba8UnormSrgb,
429 EacR11Unorm,
434 EacR11Snorm,
439 EacRg11Unorm,
444 EacRg11Snorm,
449 Astc {
457 block: AstcBlock,
459 channel: AstcChannel,
461 },
462}
463
464impl TextureFormat {
467 #[must_use]
471 pub fn aspect_specific_format(&self, aspect: TextureAspect) -> Option<Self> {
472 match (*self, aspect) {
473 (Self::Stencil8, TextureAspect::StencilOnly) => Some(*self),
474 (
475 Self::Depth16Unorm | Self::Depth24Plus | Self::Depth32Float,
476 TextureAspect::DepthOnly,
477 ) => Some(*self),
478 (
479 Self::Depth24PlusStencil8 | Self::Depth32FloatStencil8,
480 TextureAspect::StencilOnly,
481 ) => Some(Self::Stencil8),
482 (Self::Depth24PlusStencil8, TextureAspect::DepthOnly) => Some(Self::Depth24Plus),
483 (Self::Depth32FloatStencil8, TextureAspect::DepthOnly) => Some(Self::Depth32Float),
484 (Self::NV12, TextureAspect::Plane0) => Some(Self::R8Unorm),
485 (Self::NV12, TextureAspect::Plane1) => Some(Self::Rg8Unorm),
486 (Self::P010, TextureAspect::Plane0) => Some(Self::R16Unorm),
487 (Self::P010, TextureAspect::Plane1) => Some(Self::Rg16Unorm),
488 (format, TextureAspect::All) if !format.is_multi_planar_format() => Some(format),
490 _ => None,
491 }
492 }
493
494 #[must_use]
497 pub fn is_depth_stencil_component(&self, combined_format: Self) -> bool {
498 match (combined_format, *self) {
499 (Self::Depth24PlusStencil8, Self::Depth24Plus | Self::Stencil8)
500 | (Self::Depth32FloatStencil8, Self::Depth32Float | Self::Stencil8) => true,
501 _ => false,
502 }
503 }
504
505 #[must_use]
509 pub fn is_depth_stencil_format(&self) -> bool {
510 self.channels().intersects(TextureChannel::DEPTH_STENCIL)
511 }
512
513 #[must_use]
517 pub fn is_combined_depth_stencil_format(&self) -> bool {
518 self.channels().contains(TextureChannel::DEPTH_STENCIL)
519 }
520
521 #[must_use]
523 pub fn is_multi_planar_format(&self) -> bool {
524 self.planes().is_some()
525 }
526
527 #[must_use]
529 pub fn planes(&self) -> Option<u32> {
530 match *self {
531 Self::NV12 => Some(2),
532 Self::P010 => Some(2),
533 _ => None,
534 }
535 }
536
537 #[must_use]
539 pub fn subsampling_factors(&self, plane: Option<u32>) -> (u32, u32) {
540 match *self {
541 Self::NV12 | Self::P010 => match plane {
542 Some(0) => (1, 1),
543 Some(1) => (2, 2),
544 Some(plane) => unreachable!("plane {plane} is not valid for {self:?}"),
545 None => unreachable!("the plane must be specified for multi-planar formats"),
546 },
547 _ => (1, 1),
548 }
549 }
550
551 #[must_use]
574 pub fn channels(&self) -> TextureChannel {
575 match self {
576 Self::R8Unorm
577 | Self::R8Snorm
578 | Self::R8Uint
579 | Self::R8Sint
580 | Self::R16Uint
581 | Self::R16Sint
582 | Self::R16Unorm
583 | Self::R16Snorm
584 | Self::R32Uint
585 | Self::R32Sint
586 | Self::R32Float
587 | Self::R16Float
588 | Self::R64Uint
589 | Self::Bc4RUnorm
590 | Self::Bc4RSnorm
591 | Self::EacR11Unorm
592 | Self::EacR11Snorm => TextureChannel::RED,
593
594 Self::Rg8Unorm
595 | Self::Rg8Snorm
596 | Self::Rg8Uint
597 | Self::Rg8Sint
598 | Self::Rg16Uint
599 | Self::Rg16Sint
600 | Self::Rg16Unorm
601 | Self::Rg16Snorm
602 | Self::Rg16Float
603 | Self::Rg32Uint
604 | Self::Rg32Sint
605 | Self::Rg32Float
606 | Self::Bc5RgUnorm
607 | Self::Bc5RgSnorm
608 | Self::EacRg11Unorm
609 | Self::EacRg11Snorm => TextureChannel::RG,
610
611 Self::Rgb9e5Ufloat
612 | Self::Rg11b10Ufloat
613 | Self::Bc6hRgbUfloat
614 | Self::Bc6hRgbFloat
615 | Self::Etc2Rgb8Unorm
616 | Self::Etc2Rgb8UnormSrgb => TextureChannel::RGB,
617
618 Self::Rgba8Unorm
619 | Self::Rgba8UnormSrgb
620 | Self::Rgba8Snorm
621 | Self::Rgba8Uint
622 | Self::Rgba8Sint
623 | Self::Bgra8Unorm
624 | Self::Bgra8UnormSrgb
625 | Self::Rgb10a2Uint
626 | Self::Rgb10a2Unorm
627 | Self::Rgba16Uint
628 | Self::Rgba16Sint
629 | Self::Rgba16Unorm
630 | Self::Rgba16Snorm
631 | Self::Rgba16Float
632 | Self::Rgba32Uint
633 | Self::Rgba32Sint
634 | Self::Rgba32Float
635 | Self::Bc1RgbaUnorm
636 | Self::Bc1RgbaUnormSrgb
637 | Self::Bc2RgbaUnorm
638 | Self::Bc2RgbaUnormSrgb
639 | Self::Bc3RgbaUnorm
640 | Self::Bc3RgbaUnormSrgb
641 | Self::Bc7RgbaUnorm
642 | Self::Bc7RgbaUnormSrgb
643 | Self::Etc2Rgb8A1Unorm
644 | Self::Etc2Rgb8A1UnormSrgb
645 | Self::Etc2Rgba8Unorm
646 | Self::Etc2Rgba8UnormSrgb
647 | Self::Astc { .. } => TextureChannel::RGBA,
648
649 Self::Stencil8 => TextureChannel::STENCIL,
650 Self::Depth16Unorm | Self::Depth24Plus | Self::Depth32Float => TextureChannel::DEPTH,
651
652 Self::Depth24PlusStencil8 | Self::Depth32FloatStencil8 => TextureChannel::DEPTH_STENCIL,
653
654 Self::NV12 | Self::P010 => TextureChannel::LUMINANCE_CHROMINANCE,
655 }
656 }
657
658 #[must_use]
660 pub fn has_color_aspect(&self) -> bool {
661 self.channels().intersects(TextureChannel::RGBA)
662 }
663
664 #[must_use]
666 pub fn has_depth_aspect(&self) -> bool {
667 self.channels().intersects(TextureChannel::DEPTH)
668 }
669
670 #[must_use]
672 pub fn has_stencil_aspect(&self) -> bool {
673 self.channels().intersects(TextureChannel::STENCIL)
674 }
675
676 #[must_use]
682 pub fn size_multiple_requirement(&self) -> (u32, u32) {
683 match *self {
684 Self::NV12 => (2, 2),
685 Self::P010 => (2, 2),
686 _ => self.block_dimensions(),
687 }
688 }
689
690 #[must_use]
694 pub fn block_dimensions(&self) -> (u32, u32) {
695 match *self {
696 Self::R8Unorm
697 | Self::R8Snorm
698 | Self::R8Uint
699 | Self::R8Sint
700 | Self::R16Uint
701 | Self::R16Sint
702 | Self::R16Unorm
703 | Self::R16Snorm
704 | Self::R16Float
705 | Self::Rg8Unorm
706 | Self::Rg8Snorm
707 | Self::Rg8Uint
708 | Self::Rg8Sint
709 | Self::R32Uint
710 | Self::R32Sint
711 | Self::R32Float
712 | Self::Rg16Uint
713 | Self::Rg16Sint
714 | Self::Rg16Unorm
715 | Self::Rg16Snorm
716 | Self::Rg16Float
717 | Self::Rgba8Unorm
718 | Self::Rgba8UnormSrgb
719 | Self::Rgba8Snorm
720 | Self::Rgba8Uint
721 | Self::Rgba8Sint
722 | Self::Bgra8Unorm
723 | Self::Bgra8UnormSrgb
724 | Self::Rgb9e5Ufloat
725 | Self::Rgb10a2Uint
726 | Self::Rgb10a2Unorm
727 | Self::Rg11b10Ufloat
728 | Self::R64Uint
729 | Self::Rg32Uint
730 | Self::Rg32Sint
731 | Self::Rg32Float
732 | Self::Rgba16Uint
733 | Self::Rgba16Sint
734 | Self::Rgba16Unorm
735 | Self::Rgba16Snorm
736 | Self::Rgba16Float
737 | Self::Rgba32Uint
738 | Self::Rgba32Sint
739 | Self::Rgba32Float
740 | Self::Stencil8
741 | Self::Depth16Unorm
742 | Self::Depth24Plus
743 | Self::Depth24PlusStencil8
744 | Self::Depth32Float
745 | Self::Depth32FloatStencil8
746 | Self::NV12
747 | Self::P010 => (1, 1),
748
749 Self::Bc1RgbaUnorm
750 | Self::Bc1RgbaUnormSrgb
751 | Self::Bc2RgbaUnorm
752 | Self::Bc2RgbaUnormSrgb
753 | Self::Bc3RgbaUnorm
754 | Self::Bc3RgbaUnormSrgb
755 | Self::Bc4RUnorm
756 | Self::Bc4RSnorm
757 | Self::Bc5RgUnorm
758 | Self::Bc5RgSnorm
759 | Self::Bc6hRgbUfloat
760 | Self::Bc6hRgbFloat
761 | Self::Bc7RgbaUnorm
762 | Self::Bc7RgbaUnormSrgb => (4, 4),
763
764 Self::Etc2Rgb8Unorm
765 | Self::Etc2Rgb8UnormSrgb
766 | Self::Etc2Rgb8A1Unorm
767 | Self::Etc2Rgb8A1UnormSrgb
768 | Self::Etc2Rgba8Unorm
769 | Self::Etc2Rgba8UnormSrgb
770 | Self::EacR11Unorm
771 | Self::EacR11Snorm
772 | Self::EacRg11Unorm
773 | Self::EacRg11Snorm => (4, 4),
774
775 Self::Astc { block, .. } => match block {
776 AstcBlock::B4x4 => (4, 4),
777 AstcBlock::B5x4 => (5, 4),
778 AstcBlock::B5x5 => (5, 5),
779 AstcBlock::B6x5 => (6, 5),
780 AstcBlock::B6x6 => (6, 6),
781 AstcBlock::B8x5 => (8, 5),
782 AstcBlock::B8x6 => (8, 6),
783 AstcBlock::B8x8 => (8, 8),
784 AstcBlock::B10x5 => (10, 5),
785 AstcBlock::B10x6 => (10, 6),
786 AstcBlock::B10x8 => (10, 8),
787 AstcBlock::B10x10 => (10, 10),
788 AstcBlock::B12x10 => (12, 10),
789 AstcBlock::B12x12 => (12, 12),
790 },
791 }
792 }
793
794 #[must_use]
796 pub fn is_compressed(&self) -> bool {
797 self.block_dimensions() != (1, 1)
798 }
799
800 #[must_use]
802 pub fn is_bcn(&self) -> bool {
803 self.required_features() == Features::TEXTURE_COMPRESSION_BC
804 }
805
806 #[must_use]
808 pub fn is_astc(&self) -> bool {
809 self.required_features() == Features::TEXTURE_COMPRESSION_ASTC
810 || self.required_features() == Features::TEXTURE_COMPRESSION_ASTC_HDR
811 }
812
813 #[must_use]
815 pub fn required_features(&self) -> Features {
816 match *self {
817 Self::R8Unorm
818 | Self::R8Snorm
819 | Self::R8Uint
820 | Self::R8Sint
821 | Self::R16Uint
822 | Self::R16Sint
823 | Self::R16Float
824 | Self::Rg8Unorm
825 | Self::Rg8Snorm
826 | Self::Rg8Uint
827 | Self::Rg8Sint
828 | Self::R32Uint
829 | Self::R32Sint
830 | Self::R32Float
831 | Self::Rg16Uint
832 | Self::Rg16Sint
833 | Self::Rg16Float
834 | Self::Rgba8Unorm
835 | Self::Rgba8UnormSrgb
836 | Self::Rgba8Snorm
837 | Self::Rgba8Uint
838 | Self::Rgba8Sint
839 | Self::Bgra8Unorm
840 | Self::Bgra8UnormSrgb
841 | Self::Rgb9e5Ufloat
842 | Self::Rgb10a2Uint
843 | Self::Rgb10a2Unorm
844 | Self::Rg11b10Ufloat
845 | Self::Rg32Uint
846 | Self::Rg32Sint
847 | Self::Rg32Float
848 | Self::Rgba16Uint
849 | Self::Rgba16Sint
850 | Self::Rgba16Float
851 | Self::Rgba32Uint
852 | Self::Rgba32Sint
853 | Self::Rgba32Float
854 | Self::Stencil8
855 | Self::Depth16Unorm
856 | Self::Depth24Plus
857 | Self::Depth24PlusStencil8
858 | Self::Depth32Float => Features::empty(),
859
860 Self::R64Uint => Features::TEXTURE_INT64_ATOMIC,
861
862 Self::Depth32FloatStencil8 => Features::DEPTH32FLOAT_STENCIL8,
863
864 Self::NV12 => Features::TEXTURE_FORMAT_NV12,
865 Self::P010 => Features::TEXTURE_FORMAT_P010,
866
867 Self::R16Unorm
868 | Self::R16Snorm
869 | Self::Rg16Unorm
870 | Self::Rg16Snorm
871 | Self::Rgba16Unorm
872 | Self::Rgba16Snorm => Features::TEXTURE_FORMAT_16BIT_NORM,
873
874 Self::Bc1RgbaUnorm
875 | Self::Bc1RgbaUnormSrgb
876 | Self::Bc2RgbaUnorm
877 | Self::Bc2RgbaUnormSrgb
878 | Self::Bc3RgbaUnorm
879 | Self::Bc3RgbaUnormSrgb
880 | Self::Bc4RUnorm
881 | Self::Bc4RSnorm
882 | Self::Bc5RgUnorm
883 | Self::Bc5RgSnorm
884 | Self::Bc6hRgbUfloat
885 | Self::Bc6hRgbFloat
886 | Self::Bc7RgbaUnorm
887 | Self::Bc7RgbaUnormSrgb => Features::TEXTURE_COMPRESSION_BC,
888
889 Self::Etc2Rgb8Unorm
890 | Self::Etc2Rgb8UnormSrgb
891 | Self::Etc2Rgb8A1Unorm
892 | Self::Etc2Rgb8A1UnormSrgb
893 | Self::Etc2Rgba8Unorm
894 | Self::Etc2Rgba8UnormSrgb
895 | Self::EacR11Unorm
896 | Self::EacR11Snorm
897 | Self::EacRg11Unorm
898 | Self::EacRg11Snorm => Features::TEXTURE_COMPRESSION_ETC2,
899
900 Self::Astc { channel, .. } => match channel {
901 AstcChannel::Hdr => Features::TEXTURE_COMPRESSION_ASTC_HDR,
902 AstcChannel::Unorm | AstcChannel::UnormSrgb => Features::TEXTURE_COMPRESSION_ASTC,
903 },
904 }
905 }
906
907 #[must_use]
911 pub fn guaranteed_format_features(&self, device_features: Features) -> TextureFormatFeatures {
912 let none = TextureFormatFeatureFlags::empty();
914 let msaa = TextureFormatFeatureFlags::MULTISAMPLE_X4;
915 let msaa_resolve = msaa | TextureFormatFeatureFlags::MULTISAMPLE_RESOLVE;
916
917 let s_ro_wo = TextureFormatFeatureFlags::STORAGE_READ_ONLY
918 | TextureFormatFeatureFlags::STORAGE_WRITE_ONLY;
919 let s_all = s_ro_wo | TextureFormatFeatureFlags::STORAGE_READ_WRITE;
920
921 let basic =
923 TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING;
924 let attachment = basic | TextureUsages::RENDER_ATTACHMENT | TextureUsages::TRANSIENT;
925 let storage = basic | TextureUsages::STORAGE_BINDING;
926 let binding = TextureUsages::TEXTURE_BINDING;
927 let all_flags = attachment | storage | binding;
928 let atomic_64 = if device_features.contains(Features::TEXTURE_ATOMIC) {
929 storage | binding | TextureUsages::STORAGE_ATOMIC
930 } else {
931 storage | binding
932 };
933 let atomic = attachment | atomic_64;
934 let (rg11b10f_f, rg11b10f_u) =
935 if device_features.contains(Features::RG11B10UFLOAT_RENDERABLE) {
936 (msaa_resolve, attachment)
937 } else {
938 (msaa, basic)
939 };
940 let (bgra8unorm_f, bgra8unorm) = if device_features.contains(Features::BGRA8UNORM_STORAGE) {
941 (
942 msaa_resolve | TextureFormatFeatureFlags::STORAGE_WRITE_ONLY,
943 attachment | TextureUsages::STORAGE_BINDING,
944 )
945 } else {
946 (msaa_resolve, attachment)
947 };
948
949 #[rustfmt::skip] let (
951 mut flags,
952 allowed_usages,
953 ) = match *self {
954 Self::R8Unorm => (msaa_resolve, attachment),
955 Self::R8Snorm => ( none, basic),
956 Self::R8Uint => ( msaa, attachment),
957 Self::R8Sint => ( msaa, attachment),
958 Self::R16Uint => ( msaa, attachment),
959 Self::R16Sint => ( msaa, attachment),
960 Self::R16Float => (msaa_resolve, attachment),
961 Self::Rg8Unorm => (msaa_resolve, attachment),
962 Self::Rg8Snorm => ( none, basic),
963 Self::Rg8Uint => ( msaa, attachment),
964 Self::Rg8Sint => ( msaa, attachment),
965 Self::R32Uint => ( s_all, atomic),
966 Self::R32Sint => ( s_all, atomic),
967 Self::R32Float => (msaa | s_all, all_flags),
968 Self::Rg16Uint => ( msaa, attachment),
969 Self::Rg16Sint => ( msaa, attachment),
970 Self::Rg16Float => (msaa_resolve, attachment),
971 Self::Rgba8Unorm => (msaa_resolve | s_ro_wo, all_flags),
972 Self::Rgba8UnormSrgb => (msaa_resolve, attachment),
973 Self::Rgba8Snorm => ( s_ro_wo, storage),
974 Self::Rgba8Uint => ( msaa | s_ro_wo, all_flags),
975 Self::Rgba8Sint => ( msaa | s_ro_wo, all_flags),
976 Self::Bgra8Unorm => (bgra8unorm_f, bgra8unorm),
977 Self::Bgra8UnormSrgb => (msaa_resolve, attachment),
978 Self::Rgb10a2Uint => ( msaa, attachment),
979 Self::Rgb10a2Unorm => (msaa_resolve, attachment),
980 Self::Rg11b10Ufloat => ( rg11b10f_f, rg11b10f_u),
981 Self::R64Uint => ( s_ro_wo, atomic_64),
982 Self::Rg32Uint => ( s_ro_wo, all_flags),
983 Self::Rg32Sint => ( s_ro_wo, all_flags),
984 Self::Rg32Float => ( s_ro_wo, all_flags),
985 Self::Rgba16Uint => ( msaa | s_ro_wo, all_flags),
986 Self::Rgba16Sint => ( msaa | s_ro_wo, all_flags),
987 Self::Rgba16Float => (msaa_resolve | s_ro_wo, all_flags),
988 Self::Rgba32Uint => ( s_ro_wo, all_flags),
989 Self::Rgba32Sint => ( s_ro_wo, all_flags),
990 Self::Rgba32Float => ( s_ro_wo, all_flags),
991
992 Self::Stencil8 => ( msaa, attachment),
993 Self::Depth16Unorm => ( msaa, attachment),
994 Self::Depth24Plus => ( msaa, attachment),
995 Self::Depth24PlusStencil8 => ( msaa, attachment),
996 Self::Depth32Float => ( msaa, attachment),
997 Self::Depth32FloatStencil8 => ( msaa, attachment),
998
999 Self::NV12 => ( none, binding),
1002 Self::P010 => ( none, binding),
1003
1004 Self::R16Unorm => ( msaa | s_ro_wo, storage),
1005 Self::R16Snorm => ( msaa | s_ro_wo, storage),
1006 Self::Rg16Unorm => ( msaa | s_ro_wo, storage),
1007 Self::Rg16Snorm => ( msaa | s_ro_wo, storage),
1008 Self::Rgba16Unorm => ( msaa | s_ro_wo, storage),
1009 Self::Rgba16Snorm => ( msaa | s_ro_wo, storage),
1010
1011 Self::Rgb9e5Ufloat => ( none, basic),
1012
1013 Self::Bc1RgbaUnorm => ( none, basic),
1014 Self::Bc1RgbaUnormSrgb => ( none, basic),
1015 Self::Bc2RgbaUnorm => ( none, basic),
1016 Self::Bc2RgbaUnormSrgb => ( none, basic),
1017 Self::Bc3RgbaUnorm => ( none, basic),
1018 Self::Bc3RgbaUnormSrgb => ( none, basic),
1019 Self::Bc4RUnorm => ( none, basic),
1020 Self::Bc4RSnorm => ( none, basic),
1021 Self::Bc5RgUnorm => ( none, basic),
1022 Self::Bc5RgSnorm => ( none, basic),
1023 Self::Bc6hRgbUfloat => ( none, basic),
1024 Self::Bc6hRgbFloat => ( none, basic),
1025 Self::Bc7RgbaUnorm => ( none, basic),
1026 Self::Bc7RgbaUnormSrgb => ( none, basic),
1027
1028 Self::Etc2Rgb8Unorm => ( none, basic),
1029 Self::Etc2Rgb8UnormSrgb => ( none, basic),
1030 Self::Etc2Rgb8A1Unorm => ( none, basic),
1031 Self::Etc2Rgb8A1UnormSrgb => ( none, basic),
1032 Self::Etc2Rgba8Unorm => ( none, basic),
1033 Self::Etc2Rgba8UnormSrgb => ( none, basic),
1034 Self::EacR11Unorm => ( none, basic),
1035 Self::EacR11Snorm => ( none, basic),
1036 Self::EacRg11Unorm => ( none, basic),
1037 Self::EacRg11Snorm => ( none, basic),
1038
1039 Self::Astc { .. } => ( none, basic),
1040 };
1041
1042 let sample_type1 = self.sample_type(None, Some(device_features));
1044 let is_filterable = sample_type1 == Some(TextureSampleType::Float { filterable: true });
1045
1046 let sample_type2 = self.sample_type(None, None);
1048 let is_blendable = sample_type2 == Some(TextureSampleType::Float { filterable: true })
1049 || device_features.contains(Features::FLOAT32_BLENDABLE)
1050 && matches!(self, Self::R32Float | Self::Rg32Float | Self::Rgba32Float);
1051
1052 flags.set(TextureFormatFeatureFlags::FILTERABLE, is_filterable);
1053 flags.set(TextureFormatFeatureFlags::BLENDABLE, is_blendable);
1054 flags.set(
1055 TextureFormatFeatureFlags::STORAGE_ATOMIC,
1056 allowed_usages.contains(TextureUsages::STORAGE_ATOMIC),
1057 );
1058
1059 TextureFormatFeatures {
1060 allowed_usages,
1061 flags,
1062 }
1063 }
1064
1065 #[must_use]
1070 pub fn sample_type(
1071 &self,
1072 aspect: Option<TextureAspect>,
1073 device_features: Option<Features>,
1074 ) -> Option<TextureSampleType> {
1075 let float = TextureSampleType::Float { filterable: true };
1076 let unfilterable_float = TextureSampleType::Float { filterable: false };
1077 let float32_sample_type = TextureSampleType::Float {
1078 filterable: device_features
1079 .unwrap_or(Features::empty())
1080 .contains(Features::FLOAT32_FILTERABLE),
1081 };
1082 let depth = TextureSampleType::Depth;
1083 let uint = TextureSampleType::Uint;
1084 let sint = TextureSampleType::Sint;
1085
1086 match *self {
1087 Self::R8Unorm
1088 | Self::R8Snorm
1089 | Self::Rg8Unorm
1090 | Self::Rg8Snorm
1091 | Self::Rgba8Unorm
1092 | Self::Rgba8UnormSrgb
1093 | Self::Rgba8Snorm
1094 | Self::Bgra8Unorm
1095 | Self::Bgra8UnormSrgb
1096 | Self::R16Float
1097 | Self::Rg16Float
1098 | Self::Rgba16Float
1099 | Self::Rgb10a2Unorm
1100 | Self::Rg11b10Ufloat => Some(float),
1101
1102 Self::R32Float | Self::Rg32Float | Self::Rgba32Float => Some(float32_sample_type),
1103
1104 Self::R8Uint
1105 | Self::Rg8Uint
1106 | Self::Rgba8Uint
1107 | Self::R16Uint
1108 | Self::Rg16Uint
1109 | Self::Rgba16Uint
1110 | Self::R32Uint
1111 | Self::R64Uint
1112 | Self::Rg32Uint
1113 | Self::Rgba32Uint
1114 | Self::Rgb10a2Uint => Some(uint),
1115
1116 Self::R8Sint
1117 | Self::Rg8Sint
1118 | Self::Rgba8Sint
1119 | Self::R16Sint
1120 | Self::Rg16Sint
1121 | Self::Rgba16Sint
1122 | Self::R32Sint
1123 | Self::Rg32Sint
1124 | Self::Rgba32Sint => Some(sint),
1125
1126 Self::Stencil8 => Some(uint),
1127 Self::Depth16Unorm | Self::Depth24Plus | Self::Depth32Float => Some(depth),
1128 Self::Depth24PlusStencil8 | Self::Depth32FloatStencil8 => match aspect {
1129 Some(TextureAspect::DepthOnly) => Some(depth),
1130 Some(TextureAspect::StencilOnly) => Some(uint),
1131 _ => None,
1132 },
1133
1134 Self::NV12 | Self::P010 => match aspect {
1135 Some(TextureAspect::Plane0) | Some(TextureAspect::Plane1) => {
1136 Some(unfilterable_float)
1137 }
1138 _ => None,
1139 },
1140
1141 Self::R16Unorm
1142 | Self::R16Snorm
1143 | Self::Rg16Unorm
1144 | Self::Rg16Snorm
1145 | Self::Rgba16Unorm
1146 | Self::Rgba16Snorm => Some(float),
1147
1148 Self::Rgb9e5Ufloat => Some(float),
1149
1150 Self::Bc1RgbaUnorm
1151 | Self::Bc1RgbaUnormSrgb
1152 | Self::Bc2RgbaUnorm
1153 | Self::Bc2RgbaUnormSrgb
1154 | Self::Bc3RgbaUnorm
1155 | Self::Bc3RgbaUnormSrgb
1156 | Self::Bc4RUnorm
1157 | Self::Bc4RSnorm
1158 | Self::Bc5RgUnorm
1159 | Self::Bc5RgSnorm
1160 | Self::Bc6hRgbUfloat
1161 | Self::Bc6hRgbFloat
1162 | Self::Bc7RgbaUnorm
1163 | Self::Bc7RgbaUnormSrgb => Some(float),
1164
1165 Self::Etc2Rgb8Unorm
1166 | Self::Etc2Rgb8UnormSrgb
1167 | Self::Etc2Rgb8A1Unorm
1168 | Self::Etc2Rgb8A1UnormSrgb
1169 | Self::Etc2Rgba8Unorm
1170 | Self::Etc2Rgba8UnormSrgb
1171 | Self::EacR11Unorm
1172 | Self::EacR11Snorm
1173 | Self::EacRg11Unorm
1174 | Self::EacRg11Snorm => Some(float),
1175
1176 Self::Astc { .. } => Some(float),
1177 }
1178 }
1179
1180 #[deprecated(since = "0.19.0", note = "Use `block_copy_size` instead.")]
1193 #[must_use]
1194 pub fn block_size(&self, aspect: Option<TextureAspect>) -> Option<u32> {
1195 self.block_copy_size(aspect)
1196 }
1197
1198 #[must_use]
1211 pub fn block_copy_size(&self, aspect: Option<TextureAspect>) -> Option<u32> {
1212 match *self {
1213 Self::R8Unorm | Self::R8Snorm | Self::R8Uint | Self::R8Sint => Some(1),
1214
1215 Self::Rg8Unorm | Self::Rg8Snorm | Self::Rg8Uint | Self::Rg8Sint => Some(2),
1216 Self::R16Unorm | Self::R16Snorm | Self::R16Uint | Self::R16Sint | Self::R16Float => {
1217 Some(2)
1218 }
1219
1220 Self::Rgba8Unorm
1221 | Self::Rgba8UnormSrgb
1222 | Self::Rgba8Snorm
1223 | Self::Rgba8Uint
1224 | Self::Rgba8Sint
1225 | Self::Bgra8Unorm
1226 | Self::Bgra8UnormSrgb => Some(4),
1227 Self::Rg16Unorm
1228 | Self::Rg16Snorm
1229 | Self::Rg16Uint
1230 | Self::Rg16Sint
1231 | Self::Rg16Float => Some(4),
1232 Self::R32Uint | Self::R32Sint | Self::R32Float => Some(4),
1233 Self::Rgb9e5Ufloat | Self::Rgb10a2Uint | Self::Rgb10a2Unorm | Self::Rg11b10Ufloat => {
1234 Some(4)
1235 }
1236
1237 Self::Rgba16Unorm
1238 | Self::Rgba16Snorm
1239 | Self::Rgba16Uint
1240 | Self::Rgba16Sint
1241 | Self::Rgba16Float => Some(8),
1242 Self::R64Uint | Self::Rg32Uint | Self::Rg32Sint | Self::Rg32Float => Some(8),
1243
1244 Self::Rgba32Uint | Self::Rgba32Sint | Self::Rgba32Float => Some(16),
1245
1246 Self::Stencil8 => Some(1),
1247 Self::Depth16Unorm => Some(2),
1248 Self::Depth32Float => Some(4),
1249 Self::Depth24Plus => None,
1250 Self::Depth24PlusStencil8 => match aspect {
1251 Some(TextureAspect::DepthOnly) => None,
1252 Some(TextureAspect::StencilOnly) => Some(1),
1253 _ => None,
1254 },
1255 Self::Depth32FloatStencil8 => match aspect {
1256 Some(TextureAspect::DepthOnly) => Some(4),
1257 Some(TextureAspect::StencilOnly) => Some(1),
1258 _ => None,
1259 },
1260
1261 Self::NV12 => match aspect {
1262 Some(TextureAspect::Plane0) => Some(1),
1263 Some(TextureAspect::Plane1) => Some(2),
1264 _ => None,
1265 },
1266
1267 Self::P010 => match aspect {
1268 Some(TextureAspect::Plane0) => Some(2),
1269 Some(TextureAspect::Plane1) => Some(4),
1270 _ => None,
1271 },
1272
1273 Self::Bc1RgbaUnorm | Self::Bc1RgbaUnormSrgb | Self::Bc4RUnorm | Self::Bc4RSnorm => {
1274 Some(8)
1275 }
1276 Self::Bc2RgbaUnorm
1277 | Self::Bc2RgbaUnormSrgb
1278 | Self::Bc3RgbaUnorm
1279 | Self::Bc3RgbaUnormSrgb
1280 | Self::Bc5RgUnorm
1281 | Self::Bc5RgSnorm
1282 | Self::Bc6hRgbUfloat
1283 | Self::Bc6hRgbFloat
1284 | Self::Bc7RgbaUnorm
1285 | Self::Bc7RgbaUnormSrgb => Some(16),
1286
1287 Self::Etc2Rgb8Unorm
1288 | Self::Etc2Rgb8UnormSrgb
1289 | Self::Etc2Rgb8A1Unorm
1290 | Self::Etc2Rgb8A1UnormSrgb
1291 | Self::EacR11Unorm
1292 | Self::EacR11Snorm => Some(8),
1293 Self::Etc2Rgba8Unorm
1294 | Self::Etc2Rgba8UnormSrgb
1295 | Self::EacRg11Unorm
1296 | Self::EacRg11Snorm => Some(16),
1297
1298 Self::Astc { .. } => Some(16),
1299 }
1300 }
1301
1302 pub const MAX_TARGET_PIXEL_BYTE_COST: u32 = 16;
1304
1305 #[must_use]
1308 pub fn target_pixel_byte_cost(&self) -> Option<u32> {
1309 match *self {
1310 Self::R8Unorm | Self::R8Snorm | Self::R8Uint | Self::R8Sint => Some(1),
1311 Self::Rg8Unorm
1312 | Self::Rg8Snorm
1313 | Self::Rg8Uint
1314 | Self::Rg8Sint
1315 | Self::R16Uint
1316 | Self::R16Sint
1317 | Self::R16Unorm
1318 | Self::R16Snorm
1319 | Self::R16Float => Some(2),
1320 Self::Rgba8Uint
1321 | Self::Rgba8Sint
1322 | Self::Rg16Uint
1323 | Self::Rg16Sint
1324 | Self::Rg16Unorm
1325 | Self::Rg16Snorm
1326 | Self::Rg16Float
1327 | Self::R32Uint
1328 | Self::R32Sint
1329 | Self::R32Float => Some(4),
1330 Self::Rgba8Unorm
1332 | Self::Rgba8UnormSrgb
1333 | Self::Rgba8Snorm
1334 | Self::Bgra8Unorm
1335 | Self::Bgra8UnormSrgb
1336 | Self::Rgba16Uint
1338 | Self::Rgba16Sint
1339 | Self::Rgba16Unorm
1340 | Self::Rgba16Snorm
1341 | Self::Rgba16Float
1342 | Self::R64Uint
1343 | Self::Rg32Uint
1344 | Self::Rg32Sint
1345 | Self::Rg32Float
1346 | Self::Rgb10a2Uint
1347 | Self::Rgb10a2Unorm
1348 | Self::Rg11b10Ufloat => Some(8),
1349 Self::Rgba32Uint | Self::Rgba32Sint | Self::Rgba32Float => Some(16),
1350 Self::Stencil8
1352 | Self::Depth16Unorm
1353 | Self::Depth24Plus
1354 | Self::Depth24PlusStencil8
1355 | Self::Depth32Float
1356 | Self::Depth32FloatStencil8
1357 | Self::NV12
1358 | Self::P010
1359 | Self::Rgb9e5Ufloat
1360 | Self::Bc1RgbaUnorm
1361 | Self::Bc1RgbaUnormSrgb
1362 | Self::Bc2RgbaUnorm
1363 | Self::Bc2RgbaUnormSrgb
1364 | Self::Bc3RgbaUnorm
1365 | Self::Bc3RgbaUnormSrgb
1366 | Self::Bc4RUnorm
1367 | Self::Bc4RSnorm
1368 | Self::Bc5RgUnorm
1369 | Self::Bc5RgSnorm
1370 | Self::Bc6hRgbUfloat
1371 | Self::Bc6hRgbFloat
1372 | Self::Bc7RgbaUnorm
1373 | Self::Bc7RgbaUnormSrgb
1374 | Self::Etc2Rgb8Unorm
1375 | Self::Etc2Rgb8UnormSrgb
1376 | Self::Etc2Rgb8A1Unorm
1377 | Self::Etc2Rgb8A1UnormSrgb
1378 | Self::Etc2Rgba8Unorm
1379 | Self::Etc2Rgba8UnormSrgb
1380 | Self::EacR11Unorm
1381 | Self::EacR11Snorm
1382 | Self::EacRg11Unorm
1383 | Self::EacRg11Snorm
1384 | Self::Astc { .. } => None,
1385 }
1386 }
1387
1388 #[must_use]
1390 pub fn target_component_alignment(&self) -> Option<u32> {
1391 match *self {
1392 Self::R8Unorm
1393 | Self::R8Snorm
1394 | Self::R8Uint
1395 | Self::R8Sint
1396 | Self::Rg8Unorm
1397 | Self::Rg8Snorm
1398 | Self::Rg8Uint
1399 | Self::Rg8Sint
1400 | Self::Rgba8Unorm
1401 | Self::Rgba8UnormSrgb
1402 | Self::Rgba8Snorm
1403 | Self::Rgba8Uint
1404 | Self::Rgba8Sint
1405 | Self::Bgra8Unorm
1406 | Self::Bgra8UnormSrgb => Some(1),
1407 Self::R16Uint
1408 | Self::R16Sint
1409 | Self::R16Unorm
1410 | Self::R16Snorm
1411 | Self::R16Float
1412 | Self::Rg16Uint
1413 | Self::Rg16Sint
1414 | Self::Rg16Unorm
1415 | Self::Rg16Snorm
1416 | Self::Rg16Float
1417 | Self::Rgba16Uint
1418 | Self::Rgba16Sint
1419 | Self::Rgba16Unorm
1420 | Self::Rgba16Snorm
1421 | Self::Rgba16Float => Some(2),
1422 Self::R32Uint
1423 | Self::R32Sint
1424 | Self::R32Float
1425 | Self::R64Uint
1426 | Self::Rg32Uint
1427 | Self::Rg32Sint
1428 | Self::Rg32Float
1429 | Self::Rgba32Uint
1430 | Self::Rgba32Sint
1431 | Self::Rgba32Float
1432 | Self::Rgb10a2Uint
1433 | Self::Rgb10a2Unorm
1434 | Self::Rg11b10Ufloat => Some(4),
1435 Self::Stencil8
1436 | Self::Depth16Unorm
1437 | Self::Depth24Plus
1438 | Self::Depth24PlusStencil8
1439 | Self::Depth32Float
1440 | Self::Depth32FloatStencil8
1441 | Self::NV12
1442 | Self::P010
1443 | Self::Rgb9e5Ufloat
1444 | Self::Bc1RgbaUnorm
1445 | Self::Bc1RgbaUnormSrgb
1446 | Self::Bc2RgbaUnorm
1447 | Self::Bc2RgbaUnormSrgb
1448 | Self::Bc3RgbaUnorm
1449 | Self::Bc3RgbaUnormSrgb
1450 | Self::Bc4RUnorm
1451 | Self::Bc4RSnorm
1452 | Self::Bc5RgUnorm
1453 | Self::Bc5RgSnorm
1454 | Self::Bc6hRgbUfloat
1455 | Self::Bc6hRgbFloat
1456 | Self::Bc7RgbaUnorm
1457 | Self::Bc7RgbaUnormSrgb
1458 | Self::Etc2Rgb8Unorm
1459 | Self::Etc2Rgb8UnormSrgb
1460 | Self::Etc2Rgb8A1Unorm
1461 | Self::Etc2Rgb8A1UnormSrgb
1462 | Self::Etc2Rgba8Unorm
1463 | Self::Etc2Rgba8UnormSrgb
1464 | Self::EacR11Unorm
1465 | Self::EacR11Snorm
1466 | Self::EacRg11Unorm
1467 | Self::EacRg11Snorm
1468 | Self::Astc { .. } => None,
1469 }
1470 }
1471
1472 #[must_use]
1474 pub fn components(&self) -> u8 {
1475 self.components_with_aspect(TextureAspect::All)
1476 }
1477
1478 #[must_use]
1482 pub fn components_with_aspect(&self, aspect: TextureAspect) -> u8 {
1483 match *self {
1484 Self::R8Unorm
1485 | Self::R8Snorm
1486 | Self::R8Uint
1487 | Self::R8Sint
1488 | Self::R16Unorm
1489 | Self::R16Snorm
1490 | Self::R16Uint
1491 | Self::R16Sint
1492 | Self::R16Float
1493 | Self::R32Uint
1494 | Self::R32Sint
1495 | Self::R32Float
1496 | Self::R64Uint => 1,
1497
1498 Self::Rg8Unorm
1499 | Self::Rg8Snorm
1500 | Self::Rg8Uint
1501 | Self::Rg8Sint
1502 | Self::Rg16Unorm
1503 | Self::Rg16Snorm
1504 | Self::Rg16Uint
1505 | Self::Rg16Sint
1506 | Self::Rg16Float
1507 | Self::Rg32Uint
1508 | Self::Rg32Sint
1509 | Self::Rg32Float => 2,
1510
1511 Self::Rgba8Unorm
1512 | Self::Rgba8UnormSrgb
1513 | Self::Rgba8Snorm
1514 | Self::Rgba8Uint
1515 | Self::Rgba8Sint
1516 | Self::Bgra8Unorm
1517 | Self::Bgra8UnormSrgb
1518 | Self::Rgba16Unorm
1519 | Self::Rgba16Snorm
1520 | Self::Rgba16Uint
1521 | Self::Rgba16Sint
1522 | Self::Rgba16Float
1523 | Self::Rgba32Uint
1524 | Self::Rgba32Sint
1525 | Self::Rgba32Float => 4,
1526
1527 Self::Rgb9e5Ufloat | Self::Rg11b10Ufloat => 3,
1528 Self::Rgb10a2Uint | Self::Rgb10a2Unorm => 4,
1529
1530 Self::Stencil8 | Self::Depth16Unorm | Self::Depth24Plus | Self::Depth32Float => 1,
1531
1532 Self::Depth24PlusStencil8 | Self::Depth32FloatStencil8 => match aspect {
1533 TextureAspect::DepthOnly | TextureAspect::StencilOnly => 1,
1534 _ => 2,
1535 },
1536
1537 Self::NV12 | Self::P010 => match aspect {
1538 TextureAspect::Plane0 => 1,
1539 TextureAspect::Plane1 => 2,
1540 _ => 3,
1541 },
1542
1543 Self::Bc4RUnorm | Self::Bc4RSnorm => 1,
1544 Self::Bc5RgUnorm | Self::Bc5RgSnorm => 2,
1545 Self::Bc6hRgbUfloat | Self::Bc6hRgbFloat => 3,
1546 Self::Bc1RgbaUnorm
1547 | Self::Bc1RgbaUnormSrgb
1548 | Self::Bc2RgbaUnorm
1549 | Self::Bc2RgbaUnormSrgb
1550 | Self::Bc3RgbaUnorm
1551 | Self::Bc3RgbaUnormSrgb
1552 | Self::Bc7RgbaUnorm
1553 | Self::Bc7RgbaUnormSrgb => 4,
1554
1555 Self::EacR11Unorm | Self::EacR11Snorm => 1,
1556 Self::EacRg11Unorm | Self::EacRg11Snorm => 2,
1557 Self::Etc2Rgb8Unorm | Self::Etc2Rgb8UnormSrgb => 3,
1558 Self::Etc2Rgb8A1Unorm
1559 | Self::Etc2Rgb8A1UnormSrgb
1560 | Self::Etc2Rgba8Unorm
1561 | Self::Etc2Rgba8UnormSrgb => 4,
1562
1563 Self::Astc { .. } => 4,
1564 }
1565 }
1566
1567 #[must_use]
1569 pub fn remove_srgb_suffix(&self) -> TextureFormat {
1570 match *self {
1571 Self::Rgba8UnormSrgb => Self::Rgba8Unorm,
1572 Self::Bgra8UnormSrgb => Self::Bgra8Unorm,
1573 Self::Bc1RgbaUnormSrgb => Self::Bc1RgbaUnorm,
1574 Self::Bc2RgbaUnormSrgb => Self::Bc2RgbaUnorm,
1575 Self::Bc3RgbaUnormSrgb => Self::Bc3RgbaUnorm,
1576 Self::Bc7RgbaUnormSrgb => Self::Bc7RgbaUnorm,
1577 Self::Etc2Rgb8UnormSrgb => Self::Etc2Rgb8Unorm,
1578 Self::Etc2Rgb8A1UnormSrgb => Self::Etc2Rgb8A1Unorm,
1579 Self::Etc2Rgba8UnormSrgb => Self::Etc2Rgba8Unorm,
1580 Self::Astc {
1581 block,
1582 channel: AstcChannel::UnormSrgb,
1583 } => Self::Astc {
1584 block,
1585 channel: AstcChannel::Unorm,
1586 },
1587 _ => *self,
1588 }
1589 }
1590
1591 #[must_use]
1593 pub fn add_srgb_suffix(&self) -> TextureFormat {
1594 match *self {
1595 Self::Rgba8Unorm => Self::Rgba8UnormSrgb,
1596 Self::Bgra8Unorm => Self::Bgra8UnormSrgb,
1597 Self::Bc1RgbaUnorm => Self::Bc1RgbaUnormSrgb,
1598 Self::Bc2RgbaUnorm => Self::Bc2RgbaUnormSrgb,
1599 Self::Bc3RgbaUnorm => Self::Bc3RgbaUnormSrgb,
1600 Self::Bc7RgbaUnorm => Self::Bc7RgbaUnormSrgb,
1601 Self::Etc2Rgb8Unorm => Self::Etc2Rgb8UnormSrgb,
1602 Self::Etc2Rgb8A1Unorm => Self::Etc2Rgb8A1UnormSrgb,
1603 Self::Etc2Rgba8Unorm => Self::Etc2Rgba8UnormSrgb,
1604 Self::Astc {
1605 block,
1606 channel: AstcChannel::Unorm,
1607 } => Self::Astc {
1608 block,
1609 channel: AstcChannel::UnormSrgb,
1610 },
1611 _ => *self,
1612 }
1613 }
1614
1615 #[must_use]
1617 pub fn is_srgb(&self) -> bool {
1618 *self != self.remove_srgb_suffix()
1619 }
1620
1621 #[must_use]
1625 pub fn theoretical_memory_footprint(&self, size: crate::Extent3d) -> u64 {
1626 let (block_width, block_height) = self.block_dimensions();
1627
1628 let block_size = self.block_copy_size(None);
1629
1630 let approximate_block_size = match block_size {
1631 Some(size) => size,
1632 None => match self {
1633 Self::Depth16Unorm => 2,
1635 Self::Depth24Plus => 4,
1637 Self::Depth24PlusStencil8 => 4,
1639 Self::Depth32Float => 4,
1641 Self::Depth32FloatStencil8 => 8,
1643 Self::Stencil8 => 1,
1645 Self::NV12 => 3,
1647 Self::P010 => 6,
1649 f => {
1650 unimplemented!("Memory footprint for format {f:?} is not implemented");
1651 }
1652 },
1653 };
1654
1655 let width_blocks = size.width.div_ceil(block_width) as u64;
1656 let height_blocks = size.height.div_ceil(block_height) as u64;
1657
1658 let total_blocks = width_blocks * height_blocks * size.depth_or_array_layers as u64;
1659
1660 total_blocks * approximate_block_size as u64
1661 }
1662}
1663
1664#[cfg(any(feature = "serde", test))]
1665impl<'de> Deserialize<'de> for TextureFormat {
1666 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1667 where
1668 D: serde::Deserializer<'de>,
1669 {
1670 use serde::de::{self, Error, Unexpected};
1671
1672 struct TextureFormatVisitor;
1673
1674 impl de::Visitor<'_> for TextureFormatVisitor {
1675 type Value = TextureFormat;
1676
1677 fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
1678 formatter.write_str("a valid texture format")
1679 }
1680
1681 fn visit_str<E: Error>(self, s: &str) -> Result<Self::Value, E> {
1682 let format = match s {
1683 "r8unorm" => TextureFormat::R8Unorm,
1684 "r8snorm" => TextureFormat::R8Snorm,
1685 "r8uint" => TextureFormat::R8Uint,
1686 "r8sint" => TextureFormat::R8Sint,
1687 "r16uint" => TextureFormat::R16Uint,
1688 "r16sint" => TextureFormat::R16Sint,
1689 "r16unorm" => TextureFormat::R16Unorm,
1690 "r16snorm" => TextureFormat::R16Snorm,
1691 "r16float" => TextureFormat::R16Float,
1692 "rg8unorm" => TextureFormat::Rg8Unorm,
1693 "rg8snorm" => TextureFormat::Rg8Snorm,
1694 "rg8uint" => TextureFormat::Rg8Uint,
1695 "rg8sint" => TextureFormat::Rg8Sint,
1696 "r32uint" => TextureFormat::R32Uint,
1697 "r32sint" => TextureFormat::R32Sint,
1698 "r32float" => TextureFormat::R32Float,
1699 "rg16uint" => TextureFormat::Rg16Uint,
1700 "rg16sint" => TextureFormat::Rg16Sint,
1701 "rg16unorm" => TextureFormat::Rg16Unorm,
1702 "rg16snorm" => TextureFormat::Rg16Snorm,
1703 "rg16float" => TextureFormat::Rg16Float,
1704 "rgba8unorm" => TextureFormat::Rgba8Unorm,
1705 "rgba8unorm-srgb" => TextureFormat::Rgba8UnormSrgb,
1706 "rgba8snorm" => TextureFormat::Rgba8Snorm,
1707 "rgba8uint" => TextureFormat::Rgba8Uint,
1708 "rgba8sint" => TextureFormat::Rgba8Sint,
1709 "bgra8unorm" => TextureFormat::Bgra8Unorm,
1710 "bgra8unorm-srgb" => TextureFormat::Bgra8UnormSrgb,
1711 "rgb10a2uint" => TextureFormat::Rgb10a2Uint,
1712 "rgb10a2unorm" => TextureFormat::Rgb10a2Unorm,
1713 "rg11b10ufloat" => TextureFormat::Rg11b10Ufloat,
1714 "r64uint" => TextureFormat::R64Uint,
1715 "rg32uint" => TextureFormat::Rg32Uint,
1716 "rg32sint" => TextureFormat::Rg32Sint,
1717 "rg32float" => TextureFormat::Rg32Float,
1718 "rgba16uint" => TextureFormat::Rgba16Uint,
1719 "rgba16sint" => TextureFormat::Rgba16Sint,
1720 "rgba16unorm" => TextureFormat::Rgba16Unorm,
1721 "rgba16snorm" => TextureFormat::Rgba16Snorm,
1722 "rgba16float" => TextureFormat::Rgba16Float,
1723 "rgba32uint" => TextureFormat::Rgba32Uint,
1724 "rgba32sint" => TextureFormat::Rgba32Sint,
1725 "rgba32float" => TextureFormat::Rgba32Float,
1726 "stencil8" => TextureFormat::Stencil8,
1727 "depth32float" => TextureFormat::Depth32Float,
1728 "depth32float-stencil8" => TextureFormat::Depth32FloatStencil8,
1729 "depth16unorm" => TextureFormat::Depth16Unorm,
1730 "depth24plus" => TextureFormat::Depth24Plus,
1731 "depth24plus-stencil8" => TextureFormat::Depth24PlusStencil8,
1732 "nv12" => TextureFormat::NV12,
1733 "p010" => TextureFormat::P010,
1734 "rgb9e5ufloat" => TextureFormat::Rgb9e5Ufloat,
1735 "bc1-rgba-unorm" => TextureFormat::Bc1RgbaUnorm,
1736 "bc1-rgba-unorm-srgb" => TextureFormat::Bc1RgbaUnormSrgb,
1737 "bc2-rgba-unorm" => TextureFormat::Bc2RgbaUnorm,
1738 "bc2-rgba-unorm-srgb" => TextureFormat::Bc2RgbaUnormSrgb,
1739 "bc3-rgba-unorm" => TextureFormat::Bc3RgbaUnorm,
1740 "bc3-rgba-unorm-srgb" => TextureFormat::Bc3RgbaUnormSrgb,
1741 "bc4-r-unorm" => TextureFormat::Bc4RUnorm,
1742 "bc4-r-snorm" => TextureFormat::Bc4RSnorm,
1743 "bc5-rg-unorm" => TextureFormat::Bc5RgUnorm,
1744 "bc5-rg-snorm" => TextureFormat::Bc5RgSnorm,
1745 "bc6h-rgb-ufloat" => TextureFormat::Bc6hRgbUfloat,
1746 "bc6h-rgb-float" => TextureFormat::Bc6hRgbFloat,
1747 "bc7-rgba-unorm" => TextureFormat::Bc7RgbaUnorm,
1748 "bc7-rgba-unorm-srgb" => TextureFormat::Bc7RgbaUnormSrgb,
1749 "etc2-rgb8unorm" => TextureFormat::Etc2Rgb8Unorm,
1750 "etc2-rgb8unorm-srgb" => TextureFormat::Etc2Rgb8UnormSrgb,
1751 "etc2-rgb8a1unorm" => TextureFormat::Etc2Rgb8A1Unorm,
1752 "etc2-rgb8a1unorm-srgb" => TextureFormat::Etc2Rgb8A1UnormSrgb,
1753 "etc2-rgba8unorm" => TextureFormat::Etc2Rgba8Unorm,
1754 "etc2-rgba8unorm-srgb" => TextureFormat::Etc2Rgba8UnormSrgb,
1755 "eac-r11unorm" => TextureFormat::EacR11Unorm,
1756 "eac-r11snorm" => TextureFormat::EacR11Snorm,
1757 "eac-rg11unorm" => TextureFormat::EacRg11Unorm,
1758 "eac-rg11snorm" => TextureFormat::EacRg11Snorm,
1759 other => {
1760 if let Some(parts) = other.strip_prefix("astc-") {
1761 let (block, channel) = parts
1762 .split_once('-')
1763 .ok_or_else(|| E::invalid_value(Unexpected::Str(s), &self))?;
1764
1765 let block = match block {
1766 "4x4" => AstcBlock::B4x4,
1767 "5x4" => AstcBlock::B5x4,
1768 "5x5" => AstcBlock::B5x5,
1769 "6x5" => AstcBlock::B6x5,
1770 "6x6" => AstcBlock::B6x6,
1771 "8x5" => AstcBlock::B8x5,
1772 "8x6" => AstcBlock::B8x6,
1773 "8x8" => AstcBlock::B8x8,
1774 "10x5" => AstcBlock::B10x5,
1775 "10x6" => AstcBlock::B10x6,
1776 "10x8" => AstcBlock::B10x8,
1777 "10x10" => AstcBlock::B10x10,
1778 "12x10" => AstcBlock::B12x10,
1779 "12x12" => AstcBlock::B12x12,
1780 _ => return Err(E::invalid_value(Unexpected::Str(s), &self)),
1781 };
1782
1783 let channel = match channel {
1784 "unorm" => AstcChannel::Unorm,
1785 "unorm-srgb" => AstcChannel::UnormSrgb,
1786 "hdr" => AstcChannel::Hdr,
1787 _ => return Err(E::invalid_value(Unexpected::Str(s), &self)),
1788 };
1789
1790 TextureFormat::Astc { block, channel }
1791 } else {
1792 return Err(E::invalid_value(Unexpected::Str(s), &self));
1793 }
1794 }
1795 };
1796
1797 Ok(format)
1798 }
1799 }
1800
1801 deserializer.deserialize_str(TextureFormatVisitor)
1802 }
1803}
1804
1805#[cfg(any(feature = "serde", test))]
1806impl Serialize for TextureFormat {
1807 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1808 where
1809 S: serde::Serializer,
1810 {
1811 let s: alloc::string::String;
1812 let name = match *self {
1813 TextureFormat::R8Unorm => "r8unorm",
1814 TextureFormat::R8Snorm => "r8snorm",
1815 TextureFormat::R8Uint => "r8uint",
1816 TextureFormat::R8Sint => "r8sint",
1817 TextureFormat::R16Uint => "r16uint",
1818 TextureFormat::R16Sint => "r16sint",
1819 TextureFormat::R16Unorm => "r16unorm",
1820 TextureFormat::R16Snorm => "r16snorm",
1821 TextureFormat::R16Float => "r16float",
1822 TextureFormat::Rg8Unorm => "rg8unorm",
1823 TextureFormat::Rg8Snorm => "rg8snorm",
1824 TextureFormat::Rg8Uint => "rg8uint",
1825 TextureFormat::Rg8Sint => "rg8sint",
1826 TextureFormat::R32Uint => "r32uint",
1827 TextureFormat::R32Sint => "r32sint",
1828 TextureFormat::R32Float => "r32float",
1829 TextureFormat::Rg16Uint => "rg16uint",
1830 TextureFormat::Rg16Sint => "rg16sint",
1831 TextureFormat::Rg16Unorm => "rg16unorm",
1832 TextureFormat::Rg16Snorm => "rg16snorm",
1833 TextureFormat::Rg16Float => "rg16float",
1834 TextureFormat::Rgba8Unorm => "rgba8unorm",
1835 TextureFormat::Rgba8UnormSrgb => "rgba8unorm-srgb",
1836 TextureFormat::Rgba8Snorm => "rgba8snorm",
1837 TextureFormat::Rgba8Uint => "rgba8uint",
1838 TextureFormat::Rgba8Sint => "rgba8sint",
1839 TextureFormat::Bgra8Unorm => "bgra8unorm",
1840 TextureFormat::Bgra8UnormSrgb => "bgra8unorm-srgb",
1841 TextureFormat::Rgb10a2Uint => "rgb10a2uint",
1842 TextureFormat::Rgb10a2Unorm => "rgb10a2unorm",
1843 TextureFormat::Rg11b10Ufloat => "rg11b10ufloat",
1844 TextureFormat::R64Uint => "r64uint",
1845 TextureFormat::Rg32Uint => "rg32uint",
1846 TextureFormat::Rg32Sint => "rg32sint",
1847 TextureFormat::Rg32Float => "rg32float",
1848 TextureFormat::Rgba16Uint => "rgba16uint",
1849 TextureFormat::Rgba16Sint => "rgba16sint",
1850 TextureFormat::Rgba16Unorm => "rgba16unorm",
1851 TextureFormat::Rgba16Snorm => "rgba16snorm",
1852 TextureFormat::Rgba16Float => "rgba16float",
1853 TextureFormat::Rgba32Uint => "rgba32uint",
1854 TextureFormat::Rgba32Sint => "rgba32sint",
1855 TextureFormat::Rgba32Float => "rgba32float",
1856 TextureFormat::Stencil8 => "stencil8",
1857 TextureFormat::Depth32Float => "depth32float",
1858 TextureFormat::Depth16Unorm => "depth16unorm",
1859 TextureFormat::Depth32FloatStencil8 => "depth32float-stencil8",
1860 TextureFormat::Depth24Plus => "depth24plus",
1861 TextureFormat::Depth24PlusStencil8 => "depth24plus-stencil8",
1862 TextureFormat::NV12 => "nv12",
1863 TextureFormat::P010 => "p010",
1864 TextureFormat::Rgb9e5Ufloat => "rgb9e5ufloat",
1865 TextureFormat::Bc1RgbaUnorm => "bc1-rgba-unorm",
1866 TextureFormat::Bc1RgbaUnormSrgb => "bc1-rgba-unorm-srgb",
1867 TextureFormat::Bc2RgbaUnorm => "bc2-rgba-unorm",
1868 TextureFormat::Bc2RgbaUnormSrgb => "bc2-rgba-unorm-srgb",
1869 TextureFormat::Bc3RgbaUnorm => "bc3-rgba-unorm",
1870 TextureFormat::Bc3RgbaUnormSrgb => "bc3-rgba-unorm-srgb",
1871 TextureFormat::Bc4RUnorm => "bc4-r-unorm",
1872 TextureFormat::Bc4RSnorm => "bc4-r-snorm",
1873 TextureFormat::Bc5RgUnorm => "bc5-rg-unorm",
1874 TextureFormat::Bc5RgSnorm => "bc5-rg-snorm",
1875 TextureFormat::Bc6hRgbUfloat => "bc6h-rgb-ufloat",
1876 TextureFormat::Bc6hRgbFloat => "bc6h-rgb-float",
1877 TextureFormat::Bc7RgbaUnorm => "bc7-rgba-unorm",
1878 TextureFormat::Bc7RgbaUnormSrgb => "bc7-rgba-unorm-srgb",
1879 TextureFormat::Etc2Rgb8Unorm => "etc2-rgb8unorm",
1880 TextureFormat::Etc2Rgb8UnormSrgb => "etc2-rgb8unorm-srgb",
1881 TextureFormat::Etc2Rgb8A1Unorm => "etc2-rgb8a1unorm",
1882 TextureFormat::Etc2Rgb8A1UnormSrgb => "etc2-rgb8a1unorm-srgb",
1883 TextureFormat::Etc2Rgba8Unorm => "etc2-rgba8unorm",
1884 TextureFormat::Etc2Rgba8UnormSrgb => "etc2-rgba8unorm-srgb",
1885 TextureFormat::EacR11Unorm => "eac-r11unorm",
1886 TextureFormat::EacR11Snorm => "eac-r11snorm",
1887 TextureFormat::EacRg11Unorm => "eac-rg11unorm",
1888 TextureFormat::EacRg11Snorm => "eac-rg11snorm",
1889 TextureFormat::Astc { block, channel } => {
1890 let block = match block {
1891 AstcBlock::B4x4 => "4x4",
1892 AstcBlock::B5x4 => "5x4",
1893 AstcBlock::B5x5 => "5x5",
1894 AstcBlock::B6x5 => "6x5",
1895 AstcBlock::B6x6 => "6x6",
1896 AstcBlock::B8x5 => "8x5",
1897 AstcBlock::B8x6 => "8x6",
1898 AstcBlock::B8x8 => "8x8",
1899 AstcBlock::B10x5 => "10x5",
1900 AstcBlock::B10x6 => "10x6",
1901 AstcBlock::B10x8 => "10x8",
1902 AstcBlock::B10x10 => "10x10",
1903 AstcBlock::B12x10 => "12x10",
1904 AstcBlock::B12x12 => "12x12",
1905 };
1906
1907 let channel = match channel {
1908 AstcChannel::Unorm => "unorm",
1909 AstcChannel::UnormSrgb => "unorm-srgb",
1910 AstcChannel::Hdr => "hdr",
1911 };
1912
1913 s = alloc::format!("astc-{block}-{channel}");
1914 &s
1915 }
1916 };
1917 serializer.serialize_str(name)
1918 }
1919}
1920
1921bitflags::bitflags! {
1922 #[repr(transparent)]
1924 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1925 #[cfg_attr(feature = "serde", serde(transparent))]
1926 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1927 pub struct TextureFormatFeatureFlags: u32 {
1928 const FILTERABLE = 1 << 0;
1931 const MULTISAMPLE_X2 = 1 << 1;
1933 const MULTISAMPLE_X4 = 1 << 2 ;
1935 const MULTISAMPLE_X8 = 1 << 3 ;
1937 const MULTISAMPLE_X16 = 1 << 4;
1939 const MULTISAMPLE_RESOLVE = 1 << 5;
1942 const STORAGE_READ_ONLY = 1 << 6;
1945 const STORAGE_WRITE_ONLY = 1 << 7;
1948 const STORAGE_READ_WRITE = 1 << 8;
1951 const STORAGE_ATOMIC = 1 << 9;
1954 const BLENDABLE = 1 << 10;
1956 }
1957}
1958
1959impl TextureFormatFeatureFlags {
1960 #[must_use]
1964 pub fn sample_count_supported(&self, count: u32) -> bool {
1965 use TextureFormatFeatureFlags as tfsc;
1966
1967 match count {
1968 1 => true,
1969 2 => self.contains(tfsc::MULTISAMPLE_X2),
1970 4 => self.contains(tfsc::MULTISAMPLE_X4),
1971 8 => self.contains(tfsc::MULTISAMPLE_X8),
1972 16 => self.contains(tfsc::MULTISAMPLE_X16),
1973 _ => false,
1974 }
1975 }
1976
1977 #[must_use]
1979 pub fn supported_sample_counts(&self) -> Vec<u32> {
1980 let all_possible_sample_counts: [u32; 5] = [1, 2, 4, 8, 16];
1981 all_possible_sample_counts
1982 .into_iter()
1983 .filter(|&sc| self.sample_count_supported(sc))
1984 .collect()
1985 }
1986}
1987
1988#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1992#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1993pub struct TextureFormatFeatures {
1994 pub allowed_usages: TextureUsages,
1996 pub flags: TextureFormatFeatureFlags,
1998}
1999
2000#[cfg(test)]
2001mod tests {
2002 use super::*;
2003
2004 #[test]
2005 fn texture_format_serialize() {
2006 use alloc::string::ToString;
2007
2008 assert_eq!(
2009 serde_json::to_string(&TextureFormat::R8Unorm).unwrap(),
2010 "\"r8unorm\"".to_string()
2011 );
2012 assert_eq!(
2013 serde_json::to_string(&TextureFormat::R8Snorm).unwrap(),
2014 "\"r8snorm\"".to_string()
2015 );
2016 assert_eq!(
2017 serde_json::to_string(&TextureFormat::R8Uint).unwrap(),
2018 "\"r8uint\"".to_string()
2019 );
2020 assert_eq!(
2021 serde_json::to_string(&TextureFormat::R8Sint).unwrap(),
2022 "\"r8sint\"".to_string()
2023 );
2024 assert_eq!(
2025 serde_json::to_string(&TextureFormat::R16Uint).unwrap(),
2026 "\"r16uint\"".to_string()
2027 );
2028 assert_eq!(
2029 serde_json::to_string(&TextureFormat::R16Sint).unwrap(),
2030 "\"r16sint\"".to_string()
2031 );
2032 assert_eq!(
2033 serde_json::to_string(&TextureFormat::R16Unorm).unwrap(),
2034 "\"r16unorm\"".to_string()
2035 );
2036 assert_eq!(
2037 serde_json::to_string(&TextureFormat::R16Snorm).unwrap(),
2038 "\"r16snorm\"".to_string()
2039 );
2040 assert_eq!(
2041 serde_json::to_string(&TextureFormat::R16Float).unwrap(),
2042 "\"r16float\"".to_string()
2043 );
2044 assert_eq!(
2045 serde_json::to_string(&TextureFormat::Rg8Unorm).unwrap(),
2046 "\"rg8unorm\"".to_string()
2047 );
2048 assert_eq!(
2049 serde_json::to_string(&TextureFormat::Rg8Snorm).unwrap(),
2050 "\"rg8snorm\"".to_string()
2051 );
2052 assert_eq!(
2053 serde_json::to_string(&TextureFormat::Rg8Uint).unwrap(),
2054 "\"rg8uint\"".to_string()
2055 );
2056 assert_eq!(
2057 serde_json::to_string(&TextureFormat::Rg8Sint).unwrap(),
2058 "\"rg8sint\"".to_string()
2059 );
2060 assert_eq!(
2061 serde_json::to_string(&TextureFormat::R32Uint).unwrap(),
2062 "\"r32uint\"".to_string()
2063 );
2064 assert_eq!(
2065 serde_json::to_string(&TextureFormat::R32Sint).unwrap(),
2066 "\"r32sint\"".to_string()
2067 );
2068 assert_eq!(
2069 serde_json::to_string(&TextureFormat::R32Float).unwrap(),
2070 "\"r32float\"".to_string()
2071 );
2072 assert_eq!(
2073 serde_json::to_string(&TextureFormat::Rg16Uint).unwrap(),
2074 "\"rg16uint\"".to_string()
2075 );
2076 assert_eq!(
2077 serde_json::to_string(&TextureFormat::Rg16Sint).unwrap(),
2078 "\"rg16sint\"".to_string()
2079 );
2080 assert_eq!(
2081 serde_json::to_string(&TextureFormat::Rg16Unorm).unwrap(),
2082 "\"rg16unorm\"".to_string()
2083 );
2084 assert_eq!(
2085 serde_json::to_string(&TextureFormat::Rg16Snorm).unwrap(),
2086 "\"rg16snorm\"".to_string()
2087 );
2088 assert_eq!(
2089 serde_json::to_string(&TextureFormat::Rg16Float).unwrap(),
2090 "\"rg16float\"".to_string()
2091 );
2092 assert_eq!(
2093 serde_json::to_string(&TextureFormat::Rgba8Unorm).unwrap(),
2094 "\"rgba8unorm\"".to_string()
2095 );
2096 assert_eq!(
2097 serde_json::to_string(&TextureFormat::Rgba8UnormSrgb).unwrap(),
2098 "\"rgba8unorm-srgb\"".to_string()
2099 );
2100 assert_eq!(
2101 serde_json::to_string(&TextureFormat::Rgba8Snorm).unwrap(),
2102 "\"rgba8snorm\"".to_string()
2103 );
2104 assert_eq!(
2105 serde_json::to_string(&TextureFormat::Rgba8Uint).unwrap(),
2106 "\"rgba8uint\"".to_string()
2107 );
2108 assert_eq!(
2109 serde_json::to_string(&TextureFormat::Rgba8Sint).unwrap(),
2110 "\"rgba8sint\"".to_string()
2111 );
2112 assert_eq!(
2113 serde_json::to_string(&TextureFormat::Bgra8Unorm).unwrap(),
2114 "\"bgra8unorm\"".to_string()
2115 );
2116 assert_eq!(
2117 serde_json::to_string(&TextureFormat::Bgra8UnormSrgb).unwrap(),
2118 "\"bgra8unorm-srgb\"".to_string()
2119 );
2120 assert_eq!(
2121 serde_json::to_string(&TextureFormat::Rgb10a2Uint).unwrap(),
2122 "\"rgb10a2uint\"".to_string()
2123 );
2124 assert_eq!(
2125 serde_json::to_string(&TextureFormat::Rgb10a2Unorm).unwrap(),
2126 "\"rgb10a2unorm\"".to_string()
2127 );
2128 assert_eq!(
2129 serde_json::to_string(&TextureFormat::Rg11b10Ufloat).unwrap(),
2130 "\"rg11b10ufloat\"".to_string()
2131 );
2132 assert_eq!(
2133 serde_json::to_string(&TextureFormat::R64Uint).unwrap(),
2134 "\"r64uint\"".to_string()
2135 );
2136 assert_eq!(
2137 serde_json::to_string(&TextureFormat::Rg32Uint).unwrap(),
2138 "\"rg32uint\"".to_string()
2139 );
2140 assert_eq!(
2141 serde_json::to_string(&TextureFormat::Rg32Sint).unwrap(),
2142 "\"rg32sint\"".to_string()
2143 );
2144 assert_eq!(
2145 serde_json::to_string(&TextureFormat::Rg32Float).unwrap(),
2146 "\"rg32float\"".to_string()
2147 );
2148 assert_eq!(
2149 serde_json::to_string(&TextureFormat::Rgba16Uint).unwrap(),
2150 "\"rgba16uint\"".to_string()
2151 );
2152 assert_eq!(
2153 serde_json::to_string(&TextureFormat::Rgba16Sint).unwrap(),
2154 "\"rgba16sint\"".to_string()
2155 );
2156 assert_eq!(
2157 serde_json::to_string(&TextureFormat::Rgba16Unorm).unwrap(),
2158 "\"rgba16unorm\"".to_string()
2159 );
2160 assert_eq!(
2161 serde_json::to_string(&TextureFormat::Rgba16Snorm).unwrap(),
2162 "\"rgba16snorm\"".to_string()
2163 );
2164 assert_eq!(
2165 serde_json::to_string(&TextureFormat::Rgba16Float).unwrap(),
2166 "\"rgba16float\"".to_string()
2167 );
2168 assert_eq!(
2169 serde_json::to_string(&TextureFormat::Rgba32Uint).unwrap(),
2170 "\"rgba32uint\"".to_string()
2171 );
2172 assert_eq!(
2173 serde_json::to_string(&TextureFormat::Rgba32Sint).unwrap(),
2174 "\"rgba32sint\"".to_string()
2175 );
2176 assert_eq!(
2177 serde_json::to_string(&TextureFormat::Rgba32Float).unwrap(),
2178 "\"rgba32float\"".to_string()
2179 );
2180 assert_eq!(
2181 serde_json::to_string(&TextureFormat::Stencil8).unwrap(),
2182 "\"stencil8\"".to_string()
2183 );
2184 assert_eq!(
2185 serde_json::to_string(&TextureFormat::Depth32Float).unwrap(),
2186 "\"depth32float\"".to_string()
2187 );
2188 assert_eq!(
2189 serde_json::to_string(&TextureFormat::Depth16Unorm).unwrap(),
2190 "\"depth16unorm\"".to_string()
2191 );
2192 assert_eq!(
2193 serde_json::to_string(&TextureFormat::Depth32FloatStencil8).unwrap(),
2194 "\"depth32float-stencil8\"".to_string()
2195 );
2196 assert_eq!(
2197 serde_json::to_string(&TextureFormat::Depth24Plus).unwrap(),
2198 "\"depth24plus\"".to_string()
2199 );
2200 assert_eq!(
2201 serde_json::to_string(&TextureFormat::Depth24PlusStencil8).unwrap(),
2202 "\"depth24plus-stencil8\"".to_string()
2203 );
2204 assert_eq!(
2205 serde_json::to_string(&TextureFormat::Rgb9e5Ufloat).unwrap(),
2206 "\"rgb9e5ufloat\"".to_string()
2207 );
2208 assert_eq!(
2209 serde_json::to_string(&TextureFormat::Bc1RgbaUnorm).unwrap(),
2210 "\"bc1-rgba-unorm\"".to_string()
2211 );
2212 assert_eq!(
2213 serde_json::to_string(&TextureFormat::Bc1RgbaUnormSrgb).unwrap(),
2214 "\"bc1-rgba-unorm-srgb\"".to_string()
2215 );
2216 assert_eq!(
2217 serde_json::to_string(&TextureFormat::Bc2RgbaUnorm).unwrap(),
2218 "\"bc2-rgba-unorm\"".to_string()
2219 );
2220 assert_eq!(
2221 serde_json::to_string(&TextureFormat::Bc2RgbaUnormSrgb).unwrap(),
2222 "\"bc2-rgba-unorm-srgb\"".to_string()
2223 );
2224 assert_eq!(
2225 serde_json::to_string(&TextureFormat::Bc3RgbaUnorm).unwrap(),
2226 "\"bc3-rgba-unorm\"".to_string()
2227 );
2228 assert_eq!(
2229 serde_json::to_string(&TextureFormat::Bc3RgbaUnormSrgb).unwrap(),
2230 "\"bc3-rgba-unorm-srgb\"".to_string()
2231 );
2232 assert_eq!(
2233 serde_json::to_string(&TextureFormat::Bc4RUnorm).unwrap(),
2234 "\"bc4-r-unorm\"".to_string()
2235 );
2236 assert_eq!(
2237 serde_json::to_string(&TextureFormat::Bc4RSnorm).unwrap(),
2238 "\"bc4-r-snorm\"".to_string()
2239 );
2240 assert_eq!(
2241 serde_json::to_string(&TextureFormat::Bc5RgUnorm).unwrap(),
2242 "\"bc5-rg-unorm\"".to_string()
2243 );
2244 assert_eq!(
2245 serde_json::to_string(&TextureFormat::Bc5RgSnorm).unwrap(),
2246 "\"bc5-rg-snorm\"".to_string()
2247 );
2248 assert_eq!(
2249 serde_json::to_string(&TextureFormat::Bc6hRgbUfloat).unwrap(),
2250 "\"bc6h-rgb-ufloat\"".to_string()
2251 );
2252 assert_eq!(
2253 serde_json::to_string(&TextureFormat::Bc6hRgbFloat).unwrap(),
2254 "\"bc6h-rgb-float\"".to_string()
2255 );
2256 assert_eq!(
2257 serde_json::to_string(&TextureFormat::Bc7RgbaUnorm).unwrap(),
2258 "\"bc7-rgba-unorm\"".to_string()
2259 );
2260 assert_eq!(
2261 serde_json::to_string(&TextureFormat::Bc7RgbaUnormSrgb).unwrap(),
2262 "\"bc7-rgba-unorm-srgb\"".to_string()
2263 );
2264 assert_eq!(
2265 serde_json::to_string(&TextureFormat::Etc2Rgb8Unorm).unwrap(),
2266 "\"etc2-rgb8unorm\"".to_string()
2267 );
2268 assert_eq!(
2269 serde_json::to_string(&TextureFormat::Etc2Rgb8UnormSrgb).unwrap(),
2270 "\"etc2-rgb8unorm-srgb\"".to_string()
2271 );
2272 assert_eq!(
2273 serde_json::to_string(&TextureFormat::Etc2Rgb8A1Unorm).unwrap(),
2274 "\"etc2-rgb8a1unorm\"".to_string()
2275 );
2276 assert_eq!(
2277 serde_json::to_string(&TextureFormat::Etc2Rgb8A1UnormSrgb).unwrap(),
2278 "\"etc2-rgb8a1unorm-srgb\"".to_string()
2279 );
2280 assert_eq!(
2281 serde_json::to_string(&TextureFormat::Etc2Rgba8Unorm).unwrap(),
2282 "\"etc2-rgba8unorm\"".to_string()
2283 );
2284 assert_eq!(
2285 serde_json::to_string(&TextureFormat::Etc2Rgba8UnormSrgb).unwrap(),
2286 "\"etc2-rgba8unorm-srgb\"".to_string()
2287 );
2288 assert_eq!(
2289 serde_json::to_string(&TextureFormat::EacR11Unorm).unwrap(),
2290 "\"eac-r11unorm\"".to_string()
2291 );
2292 assert_eq!(
2293 serde_json::to_string(&TextureFormat::EacR11Snorm).unwrap(),
2294 "\"eac-r11snorm\"".to_string()
2295 );
2296 assert_eq!(
2297 serde_json::to_string(&TextureFormat::EacRg11Unorm).unwrap(),
2298 "\"eac-rg11unorm\"".to_string()
2299 );
2300 assert_eq!(
2301 serde_json::to_string(&TextureFormat::EacRg11Snorm).unwrap(),
2302 "\"eac-rg11snorm\"".to_string()
2303 );
2304 }
2305
2306 #[test]
2307 fn texture_format_deserialize() {
2308 assert_eq!(
2309 serde_json::from_str::<TextureFormat>("\"r8unorm\"").unwrap(),
2310 TextureFormat::R8Unorm
2311 );
2312 assert_eq!(
2313 serde_json::from_str::<TextureFormat>("\"r8snorm\"").unwrap(),
2314 TextureFormat::R8Snorm
2315 );
2316 assert_eq!(
2317 serde_json::from_str::<TextureFormat>("\"r8uint\"").unwrap(),
2318 TextureFormat::R8Uint
2319 );
2320 assert_eq!(
2321 serde_json::from_str::<TextureFormat>("\"r8sint\"").unwrap(),
2322 TextureFormat::R8Sint
2323 );
2324 assert_eq!(
2325 serde_json::from_str::<TextureFormat>("\"r16uint\"").unwrap(),
2326 TextureFormat::R16Uint
2327 );
2328 assert_eq!(
2329 serde_json::from_str::<TextureFormat>("\"r16sint\"").unwrap(),
2330 TextureFormat::R16Sint
2331 );
2332 assert_eq!(
2333 serde_json::from_str::<TextureFormat>("\"r16unorm\"").unwrap(),
2334 TextureFormat::R16Unorm
2335 );
2336 assert_eq!(
2337 serde_json::from_str::<TextureFormat>("\"r16snorm\"").unwrap(),
2338 TextureFormat::R16Snorm
2339 );
2340 assert_eq!(
2341 serde_json::from_str::<TextureFormat>("\"r16float\"").unwrap(),
2342 TextureFormat::R16Float
2343 );
2344 assert_eq!(
2345 serde_json::from_str::<TextureFormat>("\"rg8unorm\"").unwrap(),
2346 TextureFormat::Rg8Unorm
2347 );
2348 assert_eq!(
2349 serde_json::from_str::<TextureFormat>("\"rg8snorm\"").unwrap(),
2350 TextureFormat::Rg8Snorm
2351 );
2352 assert_eq!(
2353 serde_json::from_str::<TextureFormat>("\"rg8uint\"").unwrap(),
2354 TextureFormat::Rg8Uint
2355 );
2356 assert_eq!(
2357 serde_json::from_str::<TextureFormat>("\"rg8sint\"").unwrap(),
2358 TextureFormat::Rg8Sint
2359 );
2360 assert_eq!(
2361 serde_json::from_str::<TextureFormat>("\"r32uint\"").unwrap(),
2362 TextureFormat::R32Uint
2363 );
2364 assert_eq!(
2365 serde_json::from_str::<TextureFormat>("\"r32sint\"").unwrap(),
2366 TextureFormat::R32Sint
2367 );
2368 assert_eq!(
2369 serde_json::from_str::<TextureFormat>("\"r32float\"").unwrap(),
2370 TextureFormat::R32Float
2371 );
2372 assert_eq!(
2373 serde_json::from_str::<TextureFormat>("\"rg16uint\"").unwrap(),
2374 TextureFormat::Rg16Uint
2375 );
2376 assert_eq!(
2377 serde_json::from_str::<TextureFormat>("\"rg16sint\"").unwrap(),
2378 TextureFormat::Rg16Sint
2379 );
2380 assert_eq!(
2381 serde_json::from_str::<TextureFormat>("\"rg16unorm\"").unwrap(),
2382 TextureFormat::Rg16Unorm
2383 );
2384 assert_eq!(
2385 serde_json::from_str::<TextureFormat>("\"rg16snorm\"").unwrap(),
2386 TextureFormat::Rg16Snorm
2387 );
2388 assert_eq!(
2389 serde_json::from_str::<TextureFormat>("\"rg16float\"").unwrap(),
2390 TextureFormat::Rg16Float
2391 );
2392 assert_eq!(
2393 serde_json::from_str::<TextureFormat>("\"rgba8unorm\"").unwrap(),
2394 TextureFormat::Rgba8Unorm
2395 );
2396 assert_eq!(
2397 serde_json::from_str::<TextureFormat>("\"rgba8unorm-srgb\"").unwrap(),
2398 TextureFormat::Rgba8UnormSrgb
2399 );
2400 assert_eq!(
2401 serde_json::from_str::<TextureFormat>("\"rgba8snorm\"").unwrap(),
2402 TextureFormat::Rgba8Snorm
2403 );
2404 assert_eq!(
2405 serde_json::from_str::<TextureFormat>("\"rgba8uint\"").unwrap(),
2406 TextureFormat::Rgba8Uint
2407 );
2408 assert_eq!(
2409 serde_json::from_str::<TextureFormat>("\"rgba8sint\"").unwrap(),
2410 TextureFormat::Rgba8Sint
2411 );
2412 assert_eq!(
2413 serde_json::from_str::<TextureFormat>("\"bgra8unorm\"").unwrap(),
2414 TextureFormat::Bgra8Unorm
2415 );
2416 assert_eq!(
2417 serde_json::from_str::<TextureFormat>("\"bgra8unorm-srgb\"").unwrap(),
2418 TextureFormat::Bgra8UnormSrgb
2419 );
2420 assert_eq!(
2421 serde_json::from_str::<TextureFormat>("\"rgb10a2uint\"").unwrap(),
2422 TextureFormat::Rgb10a2Uint
2423 );
2424 assert_eq!(
2425 serde_json::from_str::<TextureFormat>("\"rgb10a2unorm\"").unwrap(),
2426 TextureFormat::Rgb10a2Unorm
2427 );
2428 assert_eq!(
2429 serde_json::from_str::<TextureFormat>("\"rg11b10ufloat\"").unwrap(),
2430 TextureFormat::Rg11b10Ufloat
2431 );
2432 assert_eq!(
2433 serde_json::from_str::<TextureFormat>("\"r64uint\"").unwrap(),
2434 TextureFormat::R64Uint
2435 );
2436 assert_eq!(
2437 serde_json::from_str::<TextureFormat>("\"rg32uint\"").unwrap(),
2438 TextureFormat::Rg32Uint
2439 );
2440 assert_eq!(
2441 serde_json::from_str::<TextureFormat>("\"rg32sint\"").unwrap(),
2442 TextureFormat::Rg32Sint
2443 );
2444 assert_eq!(
2445 serde_json::from_str::<TextureFormat>("\"rg32float\"").unwrap(),
2446 TextureFormat::Rg32Float
2447 );
2448 assert_eq!(
2449 serde_json::from_str::<TextureFormat>("\"rgba16uint\"").unwrap(),
2450 TextureFormat::Rgba16Uint
2451 );
2452 assert_eq!(
2453 serde_json::from_str::<TextureFormat>("\"rgba16sint\"").unwrap(),
2454 TextureFormat::Rgba16Sint
2455 );
2456 assert_eq!(
2457 serde_json::from_str::<TextureFormat>("\"rgba16unorm\"").unwrap(),
2458 TextureFormat::Rgba16Unorm
2459 );
2460 assert_eq!(
2461 serde_json::from_str::<TextureFormat>("\"rgba16snorm\"").unwrap(),
2462 TextureFormat::Rgba16Snorm
2463 );
2464 assert_eq!(
2465 serde_json::from_str::<TextureFormat>("\"rgba16float\"").unwrap(),
2466 TextureFormat::Rgba16Float
2467 );
2468 assert_eq!(
2469 serde_json::from_str::<TextureFormat>("\"rgba32uint\"").unwrap(),
2470 TextureFormat::Rgba32Uint
2471 );
2472 assert_eq!(
2473 serde_json::from_str::<TextureFormat>("\"rgba32sint\"").unwrap(),
2474 TextureFormat::Rgba32Sint
2475 );
2476 assert_eq!(
2477 serde_json::from_str::<TextureFormat>("\"rgba32float\"").unwrap(),
2478 TextureFormat::Rgba32Float
2479 );
2480 assert_eq!(
2481 serde_json::from_str::<TextureFormat>("\"stencil8\"").unwrap(),
2482 TextureFormat::Stencil8
2483 );
2484 assert_eq!(
2485 serde_json::from_str::<TextureFormat>("\"depth32float\"").unwrap(),
2486 TextureFormat::Depth32Float
2487 );
2488 assert_eq!(
2489 serde_json::from_str::<TextureFormat>("\"depth16unorm\"").unwrap(),
2490 TextureFormat::Depth16Unorm
2491 );
2492 assert_eq!(
2493 serde_json::from_str::<TextureFormat>("\"depth32float-stencil8\"").unwrap(),
2494 TextureFormat::Depth32FloatStencil8
2495 );
2496 assert_eq!(
2497 serde_json::from_str::<TextureFormat>("\"depth24plus\"").unwrap(),
2498 TextureFormat::Depth24Plus
2499 );
2500 assert_eq!(
2501 serde_json::from_str::<TextureFormat>("\"depth24plus-stencil8\"").unwrap(),
2502 TextureFormat::Depth24PlusStencil8
2503 );
2504 assert_eq!(
2505 serde_json::from_str::<TextureFormat>("\"rgb9e5ufloat\"").unwrap(),
2506 TextureFormat::Rgb9e5Ufloat
2507 );
2508 assert_eq!(
2509 serde_json::from_str::<TextureFormat>("\"bc1-rgba-unorm\"").unwrap(),
2510 TextureFormat::Bc1RgbaUnorm
2511 );
2512 assert_eq!(
2513 serde_json::from_str::<TextureFormat>("\"bc1-rgba-unorm-srgb\"").unwrap(),
2514 TextureFormat::Bc1RgbaUnormSrgb
2515 );
2516 assert_eq!(
2517 serde_json::from_str::<TextureFormat>("\"bc2-rgba-unorm\"").unwrap(),
2518 TextureFormat::Bc2RgbaUnorm
2519 );
2520 assert_eq!(
2521 serde_json::from_str::<TextureFormat>("\"bc2-rgba-unorm-srgb\"").unwrap(),
2522 TextureFormat::Bc2RgbaUnormSrgb
2523 );
2524 assert_eq!(
2525 serde_json::from_str::<TextureFormat>("\"bc3-rgba-unorm\"").unwrap(),
2526 TextureFormat::Bc3RgbaUnorm
2527 );
2528 assert_eq!(
2529 serde_json::from_str::<TextureFormat>("\"bc3-rgba-unorm-srgb\"").unwrap(),
2530 TextureFormat::Bc3RgbaUnormSrgb
2531 );
2532 assert_eq!(
2533 serde_json::from_str::<TextureFormat>("\"bc4-r-unorm\"").unwrap(),
2534 TextureFormat::Bc4RUnorm
2535 );
2536 assert_eq!(
2537 serde_json::from_str::<TextureFormat>("\"bc4-r-snorm\"").unwrap(),
2538 TextureFormat::Bc4RSnorm
2539 );
2540 assert_eq!(
2541 serde_json::from_str::<TextureFormat>("\"bc5-rg-unorm\"").unwrap(),
2542 TextureFormat::Bc5RgUnorm
2543 );
2544 assert_eq!(
2545 serde_json::from_str::<TextureFormat>("\"bc5-rg-snorm\"").unwrap(),
2546 TextureFormat::Bc5RgSnorm
2547 );
2548 assert_eq!(
2549 serde_json::from_str::<TextureFormat>("\"bc6h-rgb-ufloat\"").unwrap(),
2550 TextureFormat::Bc6hRgbUfloat
2551 );
2552 assert_eq!(
2553 serde_json::from_str::<TextureFormat>("\"bc6h-rgb-float\"").unwrap(),
2554 TextureFormat::Bc6hRgbFloat
2555 );
2556 assert_eq!(
2557 serde_json::from_str::<TextureFormat>("\"bc7-rgba-unorm\"").unwrap(),
2558 TextureFormat::Bc7RgbaUnorm
2559 );
2560 assert_eq!(
2561 serde_json::from_str::<TextureFormat>("\"bc7-rgba-unorm-srgb\"").unwrap(),
2562 TextureFormat::Bc7RgbaUnormSrgb
2563 );
2564 assert_eq!(
2565 serde_json::from_str::<TextureFormat>("\"etc2-rgb8unorm\"").unwrap(),
2566 TextureFormat::Etc2Rgb8Unorm
2567 );
2568 assert_eq!(
2569 serde_json::from_str::<TextureFormat>("\"etc2-rgb8unorm-srgb\"").unwrap(),
2570 TextureFormat::Etc2Rgb8UnormSrgb
2571 );
2572 assert_eq!(
2573 serde_json::from_str::<TextureFormat>("\"etc2-rgb8a1unorm\"").unwrap(),
2574 TextureFormat::Etc2Rgb8A1Unorm
2575 );
2576 assert_eq!(
2577 serde_json::from_str::<TextureFormat>("\"etc2-rgb8a1unorm-srgb\"").unwrap(),
2578 TextureFormat::Etc2Rgb8A1UnormSrgb
2579 );
2580 assert_eq!(
2581 serde_json::from_str::<TextureFormat>("\"etc2-rgba8unorm\"").unwrap(),
2582 TextureFormat::Etc2Rgba8Unorm
2583 );
2584 assert_eq!(
2585 serde_json::from_str::<TextureFormat>("\"etc2-rgba8unorm-srgb\"").unwrap(),
2586 TextureFormat::Etc2Rgba8UnormSrgb
2587 );
2588 assert_eq!(
2589 serde_json::from_str::<TextureFormat>("\"eac-r11unorm\"").unwrap(),
2590 TextureFormat::EacR11Unorm
2591 );
2592 assert_eq!(
2593 serde_json::from_str::<TextureFormat>("\"eac-r11snorm\"").unwrap(),
2594 TextureFormat::EacR11Snorm
2595 );
2596 assert_eq!(
2597 serde_json::from_str::<TextureFormat>("\"eac-rg11unorm\"").unwrap(),
2598 TextureFormat::EacRg11Unorm
2599 );
2600 assert_eq!(
2601 serde_json::from_str::<TextureFormat>("\"eac-rg11snorm\"").unwrap(),
2602 TextureFormat::EacRg11Snorm
2603 );
2604 }
2605
2606 #[test]
2608 fn is_depth_stencil_format() {
2609 let depth_stencil_formats = [
2610 TextureFormat::Stencil8,
2611 TextureFormat::Depth16Unorm,
2612 TextureFormat::Depth24Plus,
2613 TextureFormat::Depth24PlusStencil8,
2614 TextureFormat::Depth32Float,
2615 TextureFormat::Depth32FloatStencil8,
2616 ];
2617
2618 for format in depth_stencil_formats {
2619 assert!(format.is_depth_stencil_format());
2620 }
2621
2622 let non_depth_stencil_formats = [
2624 TextureFormat::R8Unorm,
2625 TextureFormat::Rgba8Unorm,
2626 TextureFormat::Rg16Uint,
2627 TextureFormat::NV12,
2628 ];
2629
2630 for format in non_depth_stencil_formats {
2631 assert!(!format.is_depth_stencil_format());
2632 }
2633 }
2634
2635 #[test]
2637 fn is_combined_depth_stencil_format() {
2638 let valid_formats = [
2639 TextureFormat::Depth24PlusStencil8,
2640 TextureFormat::Depth32FloatStencil8,
2641 ];
2642
2643 for format in valid_formats {
2644 assert!(format.is_combined_depth_stencil_format());
2645 }
2646
2647 let some_invalid_formats = [
2648 TextureFormat::Depth16Unorm,
2649 TextureFormat::Depth24Plus,
2650 TextureFormat::Stencil8,
2651 TextureFormat::Rgba8UnormSrgb,
2652 TextureFormat::Rgba8Unorm,
2653 ];
2654
2655 for format in some_invalid_formats {
2656 assert!(!format.is_combined_depth_stencil_format());
2657 }
2658 }
2659
2660 #[test]
2662 fn has_color_aspect() {
2663 let some_valid_formats = [
2664 TextureFormat::R8Unorm,
2665 TextureFormat::Rg8Unorm,
2666 TextureFormat::Bc7RgbaUnorm,
2667 TextureFormat::Rgba8Unorm,
2668 ];
2669
2670 for format in some_valid_formats {
2671 assert!(format.has_color_aspect());
2672 }
2673
2674 let some_invalid_formats = [
2675 TextureFormat::NV12,
2676 TextureFormat::Stencil8,
2677 TextureFormat::Depth24PlusStencil8,
2678 ];
2679
2680 for format in some_invalid_formats {
2681 assert!(!format.has_color_aspect());
2682 }
2683 }
2684
2685 #[test]
2687 fn has_depth_aspect() {
2688 let valid_formats = [
2689 TextureFormat::Depth16Unorm,
2690 TextureFormat::Depth24Plus,
2691 TextureFormat::Depth24PlusStencil8,
2692 TextureFormat::Depth32Float,
2693 TextureFormat::Depth32FloatStencil8,
2694 ];
2695
2696 for format in valid_formats {
2697 assert!(format.has_depth_aspect());
2698 }
2699
2700 let some_invalid_formats = [
2701 TextureFormat::Rgba8Unorm,
2702 TextureFormat::Bc7RgbaUnorm,
2703 TextureFormat::Stencil8,
2704 ];
2705
2706 for format in some_invalid_formats {
2707 assert!(!format.has_depth_aspect());
2708 }
2709 }
2710
2711 #[test]
2713 fn has_stencil_aspect() {
2714 let valid_formats = [
2715 TextureFormat::Stencil8,
2716 TextureFormat::Depth24PlusStencil8,
2717 TextureFormat::Depth32FloatStencil8,
2718 ];
2719
2720 for format in valid_formats {
2721 assert!(format.has_stencil_aspect());
2722 }
2723
2724 let some_invalid_formats = [
2725 TextureFormat::R8Unorm,
2726 TextureFormat::Depth16Unorm,
2727 TextureFormat::NV12,
2728 ];
2729
2730 for format in some_invalid_formats {
2731 assert!(!format.has_stencil_aspect());
2732 }
2733 }
2734}