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
62#[repr(C)]
85#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
86pub enum TextureFormat {
87 R8Unorm,
90 R8Snorm,
92 R8Uint,
94 R8Sint,
96
97 R16Uint,
100 R16Sint,
102 R16Unorm,
106 R16Snorm,
110 R16Float,
112 Rg8Unorm,
114 Rg8Snorm,
116 Rg8Uint,
118 Rg8Sint,
120
121 R32Uint,
124 R32Sint,
126 R32Float,
128 Rg16Uint,
130 Rg16Sint,
132 Rg16Unorm,
136 Rg16Snorm,
140 Rg16Float,
142 Rgba8Unorm,
144 Rgba8UnormSrgb,
146 Rgba8Snorm,
148 Rgba8Uint,
150 Rgba8Sint,
152 Bgra8Unorm,
154 Bgra8UnormSrgb,
156
157 Rgb9e5Ufloat,
160 Rgb10a2Uint,
162 Rgb10a2Unorm,
164 Rg11b10Ufloat,
166
167 R64Uint,
172 Rg32Uint,
174 Rg32Sint,
176 Rg32Float,
178 Rgba16Uint,
180 Rgba16Sint,
182 Rgba16Unorm,
186 Rgba16Snorm,
190 Rgba16Float,
192
193 Rgba32Uint,
196 Rgba32Sint,
198 Rgba32Float,
200
201 Stencil8,
204 Depth16Unorm,
206 Depth24Plus,
208 Depth24PlusStencil8,
210 Depth32Float,
212 Depth32FloatStencil8,
216
217 NV12,
231
232 P010,
248
249 Bc1RgbaUnorm,
258 Bc1RgbaUnormSrgb,
266 Bc2RgbaUnorm,
274 Bc2RgbaUnormSrgb,
282 Bc3RgbaUnorm,
290 Bc3RgbaUnormSrgb,
298 Bc4RUnorm,
306 Bc4RSnorm,
314 Bc5RgUnorm,
322 Bc5RgSnorm,
330 Bc6hRgbUfloat,
337 Bc6hRgbFloat,
344 Bc7RgbaUnorm,
352 Bc7RgbaUnormSrgb,
360 Etc2Rgb8Unorm,
365 Etc2Rgb8UnormSrgb,
370 Etc2Rgb8A1Unorm,
375 Etc2Rgb8A1UnormSrgb,
380 Etc2Rgba8Unorm,
385 Etc2Rgba8UnormSrgb,
390 EacR11Unorm,
395 EacR11Snorm,
400 EacRg11Unorm,
405 EacRg11Snorm,
410 Astc {
418 block: AstcBlock,
420 channel: AstcChannel,
422 },
423}
424
425impl TextureFormat {
428 #[must_use]
432 pub fn aspect_specific_format(&self, aspect: TextureAspect) -> Option<Self> {
433 match (*self, aspect) {
434 (Self::Stencil8, TextureAspect::StencilOnly) => Some(*self),
435 (
436 Self::Depth16Unorm | Self::Depth24Plus | Self::Depth32Float,
437 TextureAspect::DepthOnly,
438 ) => Some(*self),
439 (
440 Self::Depth24PlusStencil8 | Self::Depth32FloatStencil8,
441 TextureAspect::StencilOnly,
442 ) => Some(Self::Stencil8),
443 (Self::Depth24PlusStencil8, TextureAspect::DepthOnly) => Some(Self::Depth24Plus),
444 (Self::Depth32FloatStencil8, TextureAspect::DepthOnly) => Some(Self::Depth32Float),
445 (Self::NV12, TextureAspect::Plane0) => Some(Self::R8Unorm),
446 (Self::NV12, TextureAspect::Plane1) => Some(Self::Rg8Unorm),
447 (Self::P010, TextureAspect::Plane0) => Some(Self::R16Unorm),
448 (Self::P010, TextureAspect::Plane1) => Some(Self::Rg16Unorm),
449 (format, TextureAspect::All) if !format.is_multi_planar_format() => Some(format),
451 _ => None,
452 }
453 }
454
455 #[must_use]
458 pub fn is_depth_stencil_component(&self, combined_format: Self) -> bool {
459 match (combined_format, *self) {
460 (Self::Depth24PlusStencil8, Self::Depth24Plus | Self::Stencil8)
461 | (Self::Depth32FloatStencil8, Self::Depth32Float | Self::Stencil8) => true,
462 _ => false,
463 }
464 }
465
466 #[must_use]
470 pub fn is_depth_stencil_format(&self) -> bool {
471 match *self {
472 Self::Stencil8
473 | Self::Depth16Unorm
474 | Self::Depth24Plus
475 | Self::Depth24PlusStencil8
476 | Self::Depth32Float
477 | Self::Depth32FloatStencil8 => true,
478 _ => false,
479 }
480 }
481
482 #[must_use]
486 pub fn is_combined_depth_stencil_format(&self) -> bool {
487 match *self {
488 Self::Depth24PlusStencil8 | Self::Depth32FloatStencil8 => true,
489 _ => false,
490 }
491 }
492
493 #[must_use]
495 pub fn is_multi_planar_format(&self) -> bool {
496 self.planes().is_some()
497 }
498
499 #[must_use]
501 pub fn planes(&self) -> Option<u32> {
502 match *self {
503 Self::NV12 => Some(2),
504 Self::P010 => Some(2),
505 _ => None,
506 }
507 }
508
509 #[must_use]
511 pub fn subsampling_factors(&self, plane: Option<u32>) -> (u32, u32) {
512 match *self {
513 Self::NV12 | Self::P010 => match plane {
514 Some(0) => (1, 1),
515 Some(1) => (2, 2),
516 Some(plane) => unreachable!("plane {plane} is not valid for {self:?}"),
517 None => unreachable!("the plane must be specified for multi-planar formats"),
518 },
519 _ => (1, 1),
520 }
521 }
522
523 #[must_use]
525 pub fn has_color_aspect(&self) -> bool {
526 !self.is_depth_stencil_format()
527 }
528
529 #[must_use]
531 pub fn has_depth_aspect(&self) -> bool {
532 match *self {
533 Self::Depth16Unorm
534 | Self::Depth24Plus
535 | Self::Depth24PlusStencil8
536 | Self::Depth32Float
537 | Self::Depth32FloatStencil8 => true,
538 _ => false,
539 }
540 }
541
542 #[must_use]
544 pub fn has_stencil_aspect(&self) -> bool {
545 match *self {
546 Self::Stencil8 | Self::Depth24PlusStencil8 | Self::Depth32FloatStencil8 => true,
547 _ => false,
548 }
549 }
550
551 #[must_use]
557 pub fn size_multiple_requirement(&self) -> (u32, u32) {
558 match *self {
559 Self::NV12 => (2, 2),
560 Self::P010 => (2, 2),
561 _ => self.block_dimensions(),
562 }
563 }
564
565 #[must_use]
569 pub fn block_dimensions(&self) -> (u32, u32) {
570 match *self {
571 Self::R8Unorm
572 | Self::R8Snorm
573 | Self::R8Uint
574 | Self::R8Sint
575 | Self::R16Uint
576 | Self::R16Sint
577 | Self::R16Unorm
578 | Self::R16Snorm
579 | Self::R16Float
580 | Self::Rg8Unorm
581 | Self::Rg8Snorm
582 | Self::Rg8Uint
583 | Self::Rg8Sint
584 | Self::R32Uint
585 | Self::R32Sint
586 | Self::R32Float
587 | Self::Rg16Uint
588 | Self::Rg16Sint
589 | Self::Rg16Unorm
590 | Self::Rg16Snorm
591 | Self::Rg16Float
592 | Self::Rgba8Unorm
593 | Self::Rgba8UnormSrgb
594 | Self::Rgba8Snorm
595 | Self::Rgba8Uint
596 | Self::Rgba8Sint
597 | Self::Bgra8Unorm
598 | Self::Bgra8UnormSrgb
599 | Self::Rgb9e5Ufloat
600 | Self::Rgb10a2Uint
601 | Self::Rgb10a2Unorm
602 | Self::Rg11b10Ufloat
603 | Self::R64Uint
604 | Self::Rg32Uint
605 | Self::Rg32Sint
606 | Self::Rg32Float
607 | Self::Rgba16Uint
608 | Self::Rgba16Sint
609 | Self::Rgba16Unorm
610 | Self::Rgba16Snorm
611 | Self::Rgba16Float
612 | Self::Rgba32Uint
613 | Self::Rgba32Sint
614 | Self::Rgba32Float
615 | Self::Stencil8
616 | Self::Depth16Unorm
617 | Self::Depth24Plus
618 | Self::Depth24PlusStencil8
619 | Self::Depth32Float
620 | Self::Depth32FloatStencil8
621 | Self::NV12
622 | Self::P010 => (1, 1),
623
624 Self::Bc1RgbaUnorm
625 | Self::Bc1RgbaUnormSrgb
626 | Self::Bc2RgbaUnorm
627 | Self::Bc2RgbaUnormSrgb
628 | Self::Bc3RgbaUnorm
629 | Self::Bc3RgbaUnormSrgb
630 | Self::Bc4RUnorm
631 | Self::Bc4RSnorm
632 | Self::Bc5RgUnorm
633 | Self::Bc5RgSnorm
634 | Self::Bc6hRgbUfloat
635 | Self::Bc6hRgbFloat
636 | Self::Bc7RgbaUnorm
637 | Self::Bc7RgbaUnormSrgb => (4, 4),
638
639 Self::Etc2Rgb8Unorm
640 | Self::Etc2Rgb8UnormSrgb
641 | Self::Etc2Rgb8A1Unorm
642 | Self::Etc2Rgb8A1UnormSrgb
643 | Self::Etc2Rgba8Unorm
644 | Self::Etc2Rgba8UnormSrgb
645 | Self::EacR11Unorm
646 | Self::EacR11Snorm
647 | Self::EacRg11Unorm
648 | Self::EacRg11Snorm => (4, 4),
649
650 Self::Astc { block, .. } => match block {
651 AstcBlock::B4x4 => (4, 4),
652 AstcBlock::B5x4 => (5, 4),
653 AstcBlock::B5x5 => (5, 5),
654 AstcBlock::B6x5 => (6, 5),
655 AstcBlock::B6x6 => (6, 6),
656 AstcBlock::B8x5 => (8, 5),
657 AstcBlock::B8x6 => (8, 6),
658 AstcBlock::B8x8 => (8, 8),
659 AstcBlock::B10x5 => (10, 5),
660 AstcBlock::B10x6 => (10, 6),
661 AstcBlock::B10x8 => (10, 8),
662 AstcBlock::B10x10 => (10, 10),
663 AstcBlock::B12x10 => (12, 10),
664 AstcBlock::B12x12 => (12, 12),
665 },
666 }
667 }
668
669 #[must_use]
671 pub fn is_compressed(&self) -> bool {
672 self.block_dimensions() != (1, 1)
673 }
674
675 #[must_use]
677 pub fn is_bcn(&self) -> bool {
678 self.required_features() == Features::TEXTURE_COMPRESSION_BC
679 }
680
681 #[must_use]
683 pub fn is_astc(&self) -> bool {
684 self.required_features() == Features::TEXTURE_COMPRESSION_ASTC
685 || self.required_features() == Features::TEXTURE_COMPRESSION_ASTC_HDR
686 }
687
688 #[must_use]
690 pub fn required_features(&self) -> Features {
691 match *self {
692 Self::R8Unorm
693 | Self::R8Snorm
694 | Self::R8Uint
695 | Self::R8Sint
696 | Self::R16Uint
697 | Self::R16Sint
698 | Self::R16Float
699 | Self::Rg8Unorm
700 | Self::Rg8Snorm
701 | Self::Rg8Uint
702 | Self::Rg8Sint
703 | Self::R32Uint
704 | Self::R32Sint
705 | Self::R32Float
706 | Self::Rg16Uint
707 | Self::Rg16Sint
708 | Self::Rg16Float
709 | Self::Rgba8Unorm
710 | Self::Rgba8UnormSrgb
711 | Self::Rgba8Snorm
712 | Self::Rgba8Uint
713 | Self::Rgba8Sint
714 | Self::Bgra8Unorm
715 | Self::Bgra8UnormSrgb
716 | Self::Rgb9e5Ufloat
717 | Self::Rgb10a2Uint
718 | Self::Rgb10a2Unorm
719 | Self::Rg11b10Ufloat
720 | Self::Rg32Uint
721 | Self::Rg32Sint
722 | Self::Rg32Float
723 | Self::Rgba16Uint
724 | Self::Rgba16Sint
725 | Self::Rgba16Float
726 | Self::Rgba32Uint
727 | Self::Rgba32Sint
728 | Self::Rgba32Float
729 | Self::Stencil8
730 | Self::Depth16Unorm
731 | Self::Depth24Plus
732 | Self::Depth24PlusStencil8
733 | Self::Depth32Float => Features::empty(),
734
735 Self::R64Uint => Features::TEXTURE_INT64_ATOMIC,
736
737 Self::Depth32FloatStencil8 => Features::DEPTH32FLOAT_STENCIL8,
738
739 Self::NV12 => Features::TEXTURE_FORMAT_NV12,
740 Self::P010 => Features::TEXTURE_FORMAT_P010,
741
742 Self::R16Unorm
743 | Self::R16Snorm
744 | Self::Rg16Unorm
745 | Self::Rg16Snorm
746 | Self::Rgba16Unorm
747 | Self::Rgba16Snorm => Features::TEXTURE_FORMAT_16BIT_NORM,
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 => Features::TEXTURE_COMPRESSION_BC,
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 => Features::TEXTURE_COMPRESSION_ETC2,
774
775 Self::Astc { channel, .. } => match channel {
776 AstcChannel::Hdr => Features::TEXTURE_COMPRESSION_ASTC_HDR,
777 AstcChannel::Unorm | AstcChannel::UnormSrgb => Features::TEXTURE_COMPRESSION_ASTC,
778 },
779 }
780 }
781
782 #[must_use]
786 pub fn guaranteed_format_features(&self, device_features: Features) -> TextureFormatFeatures {
787 let none = TextureFormatFeatureFlags::empty();
789 let msaa = TextureFormatFeatureFlags::MULTISAMPLE_X4;
790 let msaa_resolve = msaa | TextureFormatFeatureFlags::MULTISAMPLE_RESOLVE;
791
792 let s_ro_wo = TextureFormatFeatureFlags::STORAGE_READ_ONLY
793 | TextureFormatFeatureFlags::STORAGE_WRITE_ONLY;
794 let s_all = s_ro_wo | TextureFormatFeatureFlags::STORAGE_READ_WRITE;
795
796 let basic =
798 TextureUsages::COPY_SRC | TextureUsages::COPY_DST | TextureUsages::TEXTURE_BINDING;
799 let attachment = basic | TextureUsages::RENDER_ATTACHMENT | TextureUsages::TRANSIENT;
800 let storage = basic | TextureUsages::STORAGE_BINDING;
801 let binding = TextureUsages::TEXTURE_BINDING;
802 let all_flags = attachment | storage | binding;
803 let atomic_64 = if device_features.contains(Features::TEXTURE_ATOMIC) {
804 storage | binding | TextureUsages::STORAGE_ATOMIC
805 } else {
806 storage | binding
807 };
808 let atomic = attachment | atomic_64;
809 let (rg11b10f_f, rg11b10f_u) =
810 if device_features.contains(Features::RG11B10UFLOAT_RENDERABLE) {
811 (msaa_resolve, attachment)
812 } else {
813 (msaa, basic)
814 };
815 let (bgra8unorm_f, bgra8unorm) = if device_features.contains(Features::BGRA8UNORM_STORAGE) {
816 (
817 msaa_resolve | TextureFormatFeatureFlags::STORAGE_WRITE_ONLY,
818 attachment | TextureUsages::STORAGE_BINDING,
819 )
820 } else {
821 (msaa_resolve, attachment)
822 };
823
824 #[rustfmt::skip] let (
826 mut flags,
827 allowed_usages,
828 ) = match *self {
829 Self::R8Unorm => (msaa_resolve, attachment),
830 Self::R8Snorm => ( none, basic),
831 Self::R8Uint => ( msaa, attachment),
832 Self::R8Sint => ( msaa, attachment),
833 Self::R16Uint => ( msaa, attachment),
834 Self::R16Sint => ( msaa, attachment),
835 Self::R16Float => (msaa_resolve, attachment),
836 Self::Rg8Unorm => (msaa_resolve, attachment),
837 Self::Rg8Snorm => ( none, basic),
838 Self::Rg8Uint => ( msaa, attachment),
839 Self::Rg8Sint => ( msaa, attachment),
840 Self::R32Uint => ( s_all, atomic),
841 Self::R32Sint => ( s_all, atomic),
842 Self::R32Float => (msaa | s_all, all_flags),
843 Self::Rg16Uint => ( msaa, attachment),
844 Self::Rg16Sint => ( msaa, attachment),
845 Self::Rg16Float => (msaa_resolve, attachment),
846 Self::Rgba8Unorm => (msaa_resolve | s_ro_wo, all_flags),
847 Self::Rgba8UnormSrgb => (msaa_resolve, attachment),
848 Self::Rgba8Snorm => ( s_ro_wo, storage),
849 Self::Rgba8Uint => ( msaa | s_ro_wo, all_flags),
850 Self::Rgba8Sint => ( msaa | s_ro_wo, all_flags),
851 Self::Bgra8Unorm => (bgra8unorm_f, bgra8unorm),
852 Self::Bgra8UnormSrgb => (msaa_resolve, attachment),
853 Self::Rgb10a2Uint => ( msaa, attachment),
854 Self::Rgb10a2Unorm => (msaa_resolve, attachment),
855 Self::Rg11b10Ufloat => ( rg11b10f_f, rg11b10f_u),
856 Self::R64Uint => ( s_ro_wo, atomic_64),
857 Self::Rg32Uint => ( s_ro_wo, all_flags),
858 Self::Rg32Sint => ( s_ro_wo, all_flags),
859 Self::Rg32Float => ( s_ro_wo, all_flags),
860 Self::Rgba16Uint => ( msaa | s_ro_wo, all_flags),
861 Self::Rgba16Sint => ( msaa | s_ro_wo, all_flags),
862 Self::Rgba16Float => (msaa_resolve | s_ro_wo, all_flags),
863 Self::Rgba32Uint => ( s_ro_wo, all_flags),
864 Self::Rgba32Sint => ( s_ro_wo, all_flags),
865 Self::Rgba32Float => ( s_ro_wo, all_flags),
866
867 Self::Stencil8 => ( msaa, attachment),
868 Self::Depth16Unorm => ( msaa, attachment),
869 Self::Depth24Plus => ( msaa, attachment),
870 Self::Depth24PlusStencil8 => ( msaa, attachment),
871 Self::Depth32Float => ( msaa, attachment),
872 Self::Depth32FloatStencil8 => ( msaa, attachment),
873
874 Self::NV12 => ( none, binding),
877 Self::P010 => ( none, binding),
878
879 Self::R16Unorm => ( msaa | s_ro_wo, storage),
880 Self::R16Snorm => ( msaa | s_ro_wo, storage),
881 Self::Rg16Unorm => ( msaa | s_ro_wo, storage),
882 Self::Rg16Snorm => ( msaa | s_ro_wo, storage),
883 Self::Rgba16Unorm => ( msaa | s_ro_wo, storage),
884 Self::Rgba16Snorm => ( msaa | s_ro_wo, storage),
885
886 Self::Rgb9e5Ufloat => ( none, basic),
887
888 Self::Bc1RgbaUnorm => ( none, basic),
889 Self::Bc1RgbaUnormSrgb => ( none, basic),
890 Self::Bc2RgbaUnorm => ( none, basic),
891 Self::Bc2RgbaUnormSrgb => ( none, basic),
892 Self::Bc3RgbaUnorm => ( none, basic),
893 Self::Bc3RgbaUnormSrgb => ( none, basic),
894 Self::Bc4RUnorm => ( none, basic),
895 Self::Bc4RSnorm => ( none, basic),
896 Self::Bc5RgUnorm => ( none, basic),
897 Self::Bc5RgSnorm => ( none, basic),
898 Self::Bc6hRgbUfloat => ( none, basic),
899 Self::Bc6hRgbFloat => ( none, basic),
900 Self::Bc7RgbaUnorm => ( none, basic),
901 Self::Bc7RgbaUnormSrgb => ( none, basic),
902
903 Self::Etc2Rgb8Unorm => ( none, basic),
904 Self::Etc2Rgb8UnormSrgb => ( none, basic),
905 Self::Etc2Rgb8A1Unorm => ( none, basic),
906 Self::Etc2Rgb8A1UnormSrgb => ( none, basic),
907 Self::Etc2Rgba8Unorm => ( none, basic),
908 Self::Etc2Rgba8UnormSrgb => ( none, basic),
909 Self::EacR11Unorm => ( none, basic),
910 Self::EacR11Snorm => ( none, basic),
911 Self::EacRg11Unorm => ( none, basic),
912 Self::EacRg11Snorm => ( none, basic),
913
914 Self::Astc { .. } => ( none, basic),
915 };
916
917 let sample_type1 = self.sample_type(None, Some(device_features));
919 let is_filterable = sample_type1 == Some(TextureSampleType::Float { filterable: true });
920
921 let sample_type2 = self.sample_type(None, None);
923 let is_blendable = sample_type2 == Some(TextureSampleType::Float { filterable: true });
924
925 flags.set(TextureFormatFeatureFlags::FILTERABLE, is_filterable);
926 flags.set(TextureFormatFeatureFlags::BLENDABLE, is_blendable);
927 flags.set(
928 TextureFormatFeatureFlags::STORAGE_ATOMIC,
929 allowed_usages.contains(TextureUsages::STORAGE_ATOMIC),
930 );
931
932 TextureFormatFeatures {
933 allowed_usages,
934 flags,
935 }
936 }
937
938 #[must_use]
943 pub fn sample_type(
944 &self,
945 aspect: Option<TextureAspect>,
946 device_features: Option<Features>,
947 ) -> Option<TextureSampleType> {
948 let float = TextureSampleType::Float { filterable: true };
949 let unfilterable_float = TextureSampleType::Float { filterable: false };
950 let float32_sample_type = TextureSampleType::Float {
951 filterable: device_features
952 .unwrap_or(Features::empty())
953 .contains(Features::FLOAT32_FILTERABLE),
954 };
955 let depth = TextureSampleType::Depth;
956 let uint = TextureSampleType::Uint;
957 let sint = TextureSampleType::Sint;
958
959 match *self {
960 Self::R8Unorm
961 | Self::R8Snorm
962 | Self::Rg8Unorm
963 | Self::Rg8Snorm
964 | Self::Rgba8Unorm
965 | Self::Rgba8UnormSrgb
966 | Self::Rgba8Snorm
967 | Self::Bgra8Unorm
968 | Self::Bgra8UnormSrgb
969 | Self::R16Float
970 | Self::Rg16Float
971 | Self::Rgba16Float
972 | Self::Rgb10a2Unorm
973 | Self::Rg11b10Ufloat => Some(float),
974
975 Self::R32Float | Self::Rg32Float | Self::Rgba32Float => Some(float32_sample_type),
976
977 Self::R8Uint
978 | Self::Rg8Uint
979 | Self::Rgba8Uint
980 | Self::R16Uint
981 | Self::Rg16Uint
982 | Self::Rgba16Uint
983 | Self::R32Uint
984 | Self::R64Uint
985 | Self::Rg32Uint
986 | Self::Rgba32Uint
987 | Self::Rgb10a2Uint => Some(uint),
988
989 Self::R8Sint
990 | Self::Rg8Sint
991 | Self::Rgba8Sint
992 | Self::R16Sint
993 | Self::Rg16Sint
994 | Self::Rgba16Sint
995 | Self::R32Sint
996 | Self::Rg32Sint
997 | Self::Rgba32Sint => Some(sint),
998
999 Self::Stencil8 => Some(uint),
1000 Self::Depth16Unorm | Self::Depth24Plus | Self::Depth32Float => Some(depth),
1001 Self::Depth24PlusStencil8 | Self::Depth32FloatStencil8 => match aspect {
1002 Some(TextureAspect::DepthOnly) => Some(depth),
1003 Some(TextureAspect::StencilOnly) => Some(uint),
1004 _ => None,
1005 },
1006
1007 Self::NV12 | Self::P010 => match aspect {
1008 Some(TextureAspect::Plane0) | Some(TextureAspect::Plane1) => {
1009 Some(unfilterable_float)
1010 }
1011 _ => None,
1012 },
1013
1014 Self::R16Unorm
1015 | Self::R16Snorm
1016 | Self::Rg16Unorm
1017 | Self::Rg16Snorm
1018 | Self::Rgba16Unorm
1019 | Self::Rgba16Snorm => Some(float),
1020
1021 Self::Rgb9e5Ufloat => Some(float),
1022
1023 Self::Bc1RgbaUnorm
1024 | Self::Bc1RgbaUnormSrgb
1025 | Self::Bc2RgbaUnorm
1026 | Self::Bc2RgbaUnormSrgb
1027 | Self::Bc3RgbaUnorm
1028 | Self::Bc3RgbaUnormSrgb
1029 | Self::Bc4RUnorm
1030 | Self::Bc4RSnorm
1031 | Self::Bc5RgUnorm
1032 | Self::Bc5RgSnorm
1033 | Self::Bc6hRgbUfloat
1034 | Self::Bc6hRgbFloat
1035 | Self::Bc7RgbaUnorm
1036 | Self::Bc7RgbaUnormSrgb => Some(float),
1037
1038 Self::Etc2Rgb8Unorm
1039 | Self::Etc2Rgb8UnormSrgb
1040 | Self::Etc2Rgb8A1Unorm
1041 | Self::Etc2Rgb8A1UnormSrgb
1042 | Self::Etc2Rgba8Unorm
1043 | Self::Etc2Rgba8UnormSrgb
1044 | Self::EacR11Unorm
1045 | Self::EacR11Snorm
1046 | Self::EacRg11Unorm
1047 | Self::EacRg11Snorm => Some(float),
1048
1049 Self::Astc { .. } => Some(float),
1050 }
1051 }
1052
1053 #[deprecated(since = "0.19.0", note = "Use `block_copy_size` instead.")]
1066 #[must_use]
1067 pub fn block_size(&self, aspect: Option<TextureAspect>) -> Option<u32> {
1068 self.block_copy_size(aspect)
1069 }
1070
1071 #[must_use]
1084 pub fn block_copy_size(&self, aspect: Option<TextureAspect>) -> Option<u32> {
1085 match *self {
1086 Self::R8Unorm | Self::R8Snorm | Self::R8Uint | Self::R8Sint => Some(1),
1087
1088 Self::Rg8Unorm | Self::Rg8Snorm | Self::Rg8Uint | Self::Rg8Sint => Some(2),
1089 Self::R16Unorm | Self::R16Snorm | Self::R16Uint | Self::R16Sint | Self::R16Float => {
1090 Some(2)
1091 }
1092
1093 Self::Rgba8Unorm
1094 | Self::Rgba8UnormSrgb
1095 | Self::Rgba8Snorm
1096 | Self::Rgba8Uint
1097 | Self::Rgba8Sint
1098 | Self::Bgra8Unorm
1099 | Self::Bgra8UnormSrgb => Some(4),
1100 Self::Rg16Unorm
1101 | Self::Rg16Snorm
1102 | Self::Rg16Uint
1103 | Self::Rg16Sint
1104 | Self::Rg16Float => Some(4),
1105 Self::R32Uint | Self::R32Sint | Self::R32Float => Some(4),
1106 Self::Rgb9e5Ufloat | Self::Rgb10a2Uint | Self::Rgb10a2Unorm | Self::Rg11b10Ufloat => {
1107 Some(4)
1108 }
1109
1110 Self::Rgba16Unorm
1111 | Self::Rgba16Snorm
1112 | Self::Rgba16Uint
1113 | Self::Rgba16Sint
1114 | Self::Rgba16Float => Some(8),
1115 Self::R64Uint | Self::Rg32Uint | Self::Rg32Sint | Self::Rg32Float => Some(8),
1116
1117 Self::Rgba32Uint | Self::Rgba32Sint | Self::Rgba32Float => Some(16),
1118
1119 Self::Stencil8 => Some(1),
1120 Self::Depth16Unorm => Some(2),
1121 Self::Depth32Float => Some(4),
1122 Self::Depth24Plus => None,
1123 Self::Depth24PlusStencil8 => match aspect {
1124 Some(TextureAspect::DepthOnly) => None,
1125 Some(TextureAspect::StencilOnly) => Some(1),
1126 _ => None,
1127 },
1128 Self::Depth32FloatStencil8 => match aspect {
1129 Some(TextureAspect::DepthOnly) => Some(4),
1130 Some(TextureAspect::StencilOnly) => Some(1),
1131 _ => None,
1132 },
1133
1134 Self::NV12 => match aspect {
1135 Some(TextureAspect::Plane0) => Some(1),
1136 Some(TextureAspect::Plane1) => Some(2),
1137 _ => None,
1138 },
1139
1140 Self::P010 => match aspect {
1141 Some(TextureAspect::Plane0) => Some(2),
1142 Some(TextureAspect::Plane1) => Some(4),
1143 _ => None,
1144 },
1145
1146 Self::Bc1RgbaUnorm | Self::Bc1RgbaUnormSrgb | Self::Bc4RUnorm | Self::Bc4RSnorm => {
1147 Some(8)
1148 }
1149 Self::Bc2RgbaUnorm
1150 | Self::Bc2RgbaUnormSrgb
1151 | Self::Bc3RgbaUnorm
1152 | Self::Bc3RgbaUnormSrgb
1153 | Self::Bc5RgUnorm
1154 | Self::Bc5RgSnorm
1155 | Self::Bc6hRgbUfloat
1156 | Self::Bc6hRgbFloat
1157 | Self::Bc7RgbaUnorm
1158 | Self::Bc7RgbaUnormSrgb => Some(16),
1159
1160 Self::Etc2Rgb8Unorm
1161 | Self::Etc2Rgb8UnormSrgb
1162 | Self::Etc2Rgb8A1Unorm
1163 | Self::Etc2Rgb8A1UnormSrgb
1164 | Self::EacR11Unorm
1165 | Self::EacR11Snorm => Some(8),
1166 Self::Etc2Rgba8Unorm
1167 | Self::Etc2Rgba8UnormSrgb
1168 | Self::EacRg11Unorm
1169 | Self::EacRg11Snorm => Some(16),
1170
1171 Self::Astc { .. } => Some(16),
1172 }
1173 }
1174
1175 pub const MAX_TARGET_PIXEL_BYTE_COST: u32 = 16;
1177
1178 #[must_use]
1181 pub fn target_pixel_byte_cost(&self) -> Option<u32> {
1182 match *self {
1183 Self::R8Unorm | Self::R8Snorm | Self::R8Uint | Self::R8Sint => Some(1),
1184 Self::Rg8Unorm
1185 | Self::Rg8Snorm
1186 | Self::Rg8Uint
1187 | Self::Rg8Sint
1188 | Self::R16Uint
1189 | Self::R16Sint
1190 | Self::R16Unorm
1191 | Self::R16Snorm
1192 | Self::R16Float => Some(2),
1193 Self::Rgba8Uint
1194 | Self::Rgba8Sint
1195 | Self::Rg16Uint
1196 | Self::Rg16Sint
1197 | Self::Rg16Unorm
1198 | Self::Rg16Snorm
1199 | Self::Rg16Float
1200 | Self::R32Uint
1201 | Self::R32Sint
1202 | Self::R32Float => Some(4),
1203 Self::Rgba8Unorm
1205 | Self::Rgba8UnormSrgb
1206 | Self::Rgba8Snorm
1207 | Self::Bgra8Unorm
1208 | Self::Bgra8UnormSrgb
1209 | Self::Rgba16Uint
1211 | Self::Rgba16Sint
1212 | Self::Rgba16Unorm
1213 | Self::Rgba16Snorm
1214 | Self::Rgba16Float
1215 | Self::R64Uint
1216 | Self::Rg32Uint
1217 | Self::Rg32Sint
1218 | Self::Rg32Float
1219 | Self::Rgb10a2Uint
1220 | Self::Rgb10a2Unorm
1221 | Self::Rg11b10Ufloat => Some(8),
1222 Self::Rgba32Uint | Self::Rgba32Sint | Self::Rgba32Float => Some(16),
1223 Self::Stencil8
1225 | Self::Depth16Unorm
1226 | Self::Depth24Plus
1227 | Self::Depth24PlusStencil8
1228 | Self::Depth32Float
1229 | Self::Depth32FloatStencil8
1230 | Self::NV12
1231 | Self::P010
1232 | Self::Rgb9e5Ufloat
1233 | Self::Bc1RgbaUnorm
1234 | Self::Bc1RgbaUnormSrgb
1235 | Self::Bc2RgbaUnorm
1236 | Self::Bc2RgbaUnormSrgb
1237 | Self::Bc3RgbaUnorm
1238 | Self::Bc3RgbaUnormSrgb
1239 | Self::Bc4RUnorm
1240 | Self::Bc4RSnorm
1241 | Self::Bc5RgUnorm
1242 | Self::Bc5RgSnorm
1243 | Self::Bc6hRgbUfloat
1244 | Self::Bc6hRgbFloat
1245 | Self::Bc7RgbaUnorm
1246 | Self::Bc7RgbaUnormSrgb
1247 | Self::Etc2Rgb8Unorm
1248 | Self::Etc2Rgb8UnormSrgb
1249 | Self::Etc2Rgb8A1Unorm
1250 | Self::Etc2Rgb8A1UnormSrgb
1251 | Self::Etc2Rgba8Unorm
1252 | Self::Etc2Rgba8UnormSrgb
1253 | Self::EacR11Unorm
1254 | Self::EacR11Snorm
1255 | Self::EacRg11Unorm
1256 | Self::EacRg11Snorm
1257 | Self::Astc { .. } => None,
1258 }
1259 }
1260
1261 #[must_use]
1263 pub fn target_component_alignment(&self) -> Option<u32> {
1264 match *self {
1265 Self::R8Unorm
1266 | Self::R8Snorm
1267 | Self::R8Uint
1268 | Self::R8Sint
1269 | Self::Rg8Unorm
1270 | Self::Rg8Snorm
1271 | Self::Rg8Uint
1272 | Self::Rg8Sint
1273 | Self::Rgba8Unorm
1274 | Self::Rgba8UnormSrgb
1275 | Self::Rgba8Snorm
1276 | Self::Rgba8Uint
1277 | Self::Rgba8Sint
1278 | Self::Bgra8Unorm
1279 | Self::Bgra8UnormSrgb => Some(1),
1280 Self::R16Uint
1281 | Self::R16Sint
1282 | Self::R16Unorm
1283 | Self::R16Snorm
1284 | Self::R16Float
1285 | Self::Rg16Uint
1286 | Self::Rg16Sint
1287 | Self::Rg16Unorm
1288 | Self::Rg16Snorm
1289 | Self::Rg16Float
1290 | Self::Rgba16Uint
1291 | Self::Rgba16Sint
1292 | Self::Rgba16Unorm
1293 | Self::Rgba16Snorm
1294 | Self::Rgba16Float => Some(2),
1295 Self::R32Uint
1296 | Self::R32Sint
1297 | Self::R32Float
1298 | Self::R64Uint
1299 | Self::Rg32Uint
1300 | Self::Rg32Sint
1301 | Self::Rg32Float
1302 | Self::Rgba32Uint
1303 | Self::Rgba32Sint
1304 | Self::Rgba32Float
1305 | Self::Rgb10a2Uint
1306 | Self::Rgb10a2Unorm
1307 | Self::Rg11b10Ufloat => Some(4),
1308 Self::Stencil8
1309 | Self::Depth16Unorm
1310 | Self::Depth24Plus
1311 | Self::Depth24PlusStencil8
1312 | Self::Depth32Float
1313 | Self::Depth32FloatStencil8
1314 | Self::NV12
1315 | Self::P010
1316 | Self::Rgb9e5Ufloat
1317 | Self::Bc1RgbaUnorm
1318 | Self::Bc1RgbaUnormSrgb
1319 | Self::Bc2RgbaUnorm
1320 | Self::Bc2RgbaUnormSrgb
1321 | Self::Bc3RgbaUnorm
1322 | Self::Bc3RgbaUnormSrgb
1323 | Self::Bc4RUnorm
1324 | Self::Bc4RSnorm
1325 | Self::Bc5RgUnorm
1326 | Self::Bc5RgSnorm
1327 | Self::Bc6hRgbUfloat
1328 | Self::Bc6hRgbFloat
1329 | Self::Bc7RgbaUnorm
1330 | Self::Bc7RgbaUnormSrgb
1331 | Self::Etc2Rgb8Unorm
1332 | Self::Etc2Rgb8UnormSrgb
1333 | Self::Etc2Rgb8A1Unorm
1334 | Self::Etc2Rgb8A1UnormSrgb
1335 | Self::Etc2Rgba8Unorm
1336 | Self::Etc2Rgba8UnormSrgb
1337 | Self::EacR11Unorm
1338 | Self::EacR11Snorm
1339 | Self::EacRg11Unorm
1340 | Self::EacRg11Snorm
1341 | Self::Astc { .. } => None,
1342 }
1343 }
1344
1345 #[must_use]
1347 pub fn components(&self) -> u8 {
1348 self.components_with_aspect(TextureAspect::All)
1349 }
1350
1351 #[must_use]
1355 pub fn components_with_aspect(&self, aspect: TextureAspect) -> u8 {
1356 match *self {
1357 Self::R8Unorm
1358 | Self::R8Snorm
1359 | Self::R8Uint
1360 | Self::R8Sint
1361 | Self::R16Unorm
1362 | Self::R16Snorm
1363 | Self::R16Uint
1364 | Self::R16Sint
1365 | Self::R16Float
1366 | Self::R32Uint
1367 | Self::R32Sint
1368 | Self::R32Float
1369 | Self::R64Uint => 1,
1370
1371 Self::Rg8Unorm
1372 | Self::Rg8Snorm
1373 | Self::Rg8Uint
1374 | Self::Rg8Sint
1375 | Self::Rg16Unorm
1376 | Self::Rg16Snorm
1377 | Self::Rg16Uint
1378 | Self::Rg16Sint
1379 | Self::Rg16Float
1380 | Self::Rg32Uint
1381 | Self::Rg32Sint
1382 | Self::Rg32Float => 2,
1383
1384 Self::Rgba8Unorm
1385 | Self::Rgba8UnormSrgb
1386 | Self::Rgba8Snorm
1387 | Self::Rgba8Uint
1388 | Self::Rgba8Sint
1389 | Self::Bgra8Unorm
1390 | Self::Bgra8UnormSrgb
1391 | Self::Rgba16Unorm
1392 | Self::Rgba16Snorm
1393 | Self::Rgba16Uint
1394 | Self::Rgba16Sint
1395 | Self::Rgba16Float
1396 | Self::Rgba32Uint
1397 | Self::Rgba32Sint
1398 | Self::Rgba32Float => 4,
1399
1400 Self::Rgb9e5Ufloat | Self::Rg11b10Ufloat => 3,
1401 Self::Rgb10a2Uint | Self::Rgb10a2Unorm => 4,
1402
1403 Self::Stencil8 | Self::Depth16Unorm | Self::Depth24Plus | Self::Depth32Float => 1,
1404
1405 Self::Depth24PlusStencil8 | Self::Depth32FloatStencil8 => match aspect {
1406 TextureAspect::DepthOnly | TextureAspect::StencilOnly => 1,
1407 _ => 2,
1408 },
1409
1410 Self::NV12 | Self::P010 => match aspect {
1411 TextureAspect::Plane0 => 1,
1412 TextureAspect::Plane1 => 2,
1413 _ => 3,
1414 },
1415
1416 Self::Bc4RUnorm | Self::Bc4RSnorm => 1,
1417 Self::Bc5RgUnorm | Self::Bc5RgSnorm => 2,
1418 Self::Bc6hRgbUfloat | Self::Bc6hRgbFloat => 3,
1419 Self::Bc1RgbaUnorm
1420 | Self::Bc1RgbaUnormSrgb
1421 | Self::Bc2RgbaUnorm
1422 | Self::Bc2RgbaUnormSrgb
1423 | Self::Bc3RgbaUnorm
1424 | Self::Bc3RgbaUnormSrgb
1425 | Self::Bc7RgbaUnorm
1426 | Self::Bc7RgbaUnormSrgb => 4,
1427
1428 Self::EacR11Unorm | Self::EacR11Snorm => 1,
1429 Self::EacRg11Unorm | Self::EacRg11Snorm => 2,
1430 Self::Etc2Rgb8Unorm | Self::Etc2Rgb8UnormSrgb => 3,
1431 Self::Etc2Rgb8A1Unorm
1432 | Self::Etc2Rgb8A1UnormSrgb
1433 | Self::Etc2Rgba8Unorm
1434 | Self::Etc2Rgba8UnormSrgb => 4,
1435
1436 Self::Astc { .. } => 4,
1437 }
1438 }
1439
1440 #[must_use]
1442 pub fn remove_srgb_suffix(&self) -> TextureFormat {
1443 match *self {
1444 Self::Rgba8UnormSrgb => Self::Rgba8Unorm,
1445 Self::Bgra8UnormSrgb => Self::Bgra8Unorm,
1446 Self::Bc1RgbaUnormSrgb => Self::Bc1RgbaUnorm,
1447 Self::Bc2RgbaUnormSrgb => Self::Bc2RgbaUnorm,
1448 Self::Bc3RgbaUnormSrgb => Self::Bc3RgbaUnorm,
1449 Self::Bc7RgbaUnormSrgb => Self::Bc7RgbaUnorm,
1450 Self::Etc2Rgb8UnormSrgb => Self::Etc2Rgb8Unorm,
1451 Self::Etc2Rgb8A1UnormSrgb => Self::Etc2Rgb8A1Unorm,
1452 Self::Etc2Rgba8UnormSrgb => Self::Etc2Rgba8Unorm,
1453 Self::Astc {
1454 block,
1455 channel: AstcChannel::UnormSrgb,
1456 } => Self::Astc {
1457 block,
1458 channel: AstcChannel::Unorm,
1459 },
1460 _ => *self,
1461 }
1462 }
1463
1464 #[must_use]
1466 pub fn add_srgb_suffix(&self) -> TextureFormat {
1467 match *self {
1468 Self::Rgba8Unorm => Self::Rgba8UnormSrgb,
1469 Self::Bgra8Unorm => Self::Bgra8UnormSrgb,
1470 Self::Bc1RgbaUnorm => Self::Bc1RgbaUnormSrgb,
1471 Self::Bc2RgbaUnorm => Self::Bc2RgbaUnormSrgb,
1472 Self::Bc3RgbaUnorm => Self::Bc3RgbaUnormSrgb,
1473 Self::Bc7RgbaUnorm => Self::Bc7RgbaUnormSrgb,
1474 Self::Etc2Rgb8Unorm => Self::Etc2Rgb8UnormSrgb,
1475 Self::Etc2Rgb8A1Unorm => Self::Etc2Rgb8A1UnormSrgb,
1476 Self::Etc2Rgba8Unorm => Self::Etc2Rgba8UnormSrgb,
1477 Self::Astc {
1478 block,
1479 channel: AstcChannel::Unorm,
1480 } => Self::Astc {
1481 block,
1482 channel: AstcChannel::UnormSrgb,
1483 },
1484 _ => *self,
1485 }
1486 }
1487
1488 #[must_use]
1490 pub fn is_srgb(&self) -> bool {
1491 *self != self.remove_srgb_suffix()
1492 }
1493
1494 #[must_use]
1498 pub fn theoretical_memory_footprint(&self, size: crate::Extent3d) -> u64 {
1499 let (block_width, block_height) = self.block_dimensions();
1500
1501 let block_size = self.block_copy_size(None);
1502
1503 let approximate_block_size = match block_size {
1504 Some(size) => size,
1505 None => match self {
1506 Self::Depth16Unorm => 2,
1508 Self::Depth24Plus => 4,
1510 Self::Depth24PlusStencil8 => 4,
1512 Self::Depth32Float => 4,
1514 Self::Depth32FloatStencil8 => 8,
1516 Self::Stencil8 => 1,
1518 Self::NV12 => 3,
1520 Self::P010 => 6,
1522 f => {
1523 unimplemented!("Memory footprint for format {f:?} is not implemented");
1524 }
1525 },
1526 };
1527
1528 let width_blocks = size.width.div_ceil(block_width) as u64;
1529 let height_blocks = size.height.div_ceil(block_height) as u64;
1530
1531 let total_blocks = width_blocks * height_blocks * size.depth_or_array_layers as u64;
1532
1533 total_blocks * approximate_block_size as u64
1534 }
1535}
1536
1537#[cfg(any(feature = "serde", test))]
1538impl<'de> Deserialize<'de> for TextureFormat {
1539 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1540 where
1541 D: serde::Deserializer<'de>,
1542 {
1543 use serde::de::{self, Error, Unexpected};
1544
1545 struct TextureFormatVisitor;
1546
1547 impl de::Visitor<'_> for TextureFormatVisitor {
1548 type Value = TextureFormat;
1549
1550 fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
1551 formatter.write_str("a valid texture format")
1552 }
1553
1554 fn visit_str<E: Error>(self, s: &str) -> Result<Self::Value, E> {
1555 let format = match s {
1556 "r8unorm" => TextureFormat::R8Unorm,
1557 "r8snorm" => TextureFormat::R8Snorm,
1558 "r8uint" => TextureFormat::R8Uint,
1559 "r8sint" => TextureFormat::R8Sint,
1560 "r16uint" => TextureFormat::R16Uint,
1561 "r16sint" => TextureFormat::R16Sint,
1562 "r16unorm" => TextureFormat::R16Unorm,
1563 "r16snorm" => TextureFormat::R16Snorm,
1564 "r16float" => TextureFormat::R16Float,
1565 "rg8unorm" => TextureFormat::Rg8Unorm,
1566 "rg8snorm" => TextureFormat::Rg8Snorm,
1567 "rg8uint" => TextureFormat::Rg8Uint,
1568 "rg8sint" => TextureFormat::Rg8Sint,
1569 "r32uint" => TextureFormat::R32Uint,
1570 "r32sint" => TextureFormat::R32Sint,
1571 "r32float" => TextureFormat::R32Float,
1572 "rg16uint" => TextureFormat::Rg16Uint,
1573 "rg16sint" => TextureFormat::Rg16Sint,
1574 "rg16unorm" => TextureFormat::Rg16Unorm,
1575 "rg16snorm" => TextureFormat::Rg16Snorm,
1576 "rg16float" => TextureFormat::Rg16Float,
1577 "rgba8unorm" => TextureFormat::Rgba8Unorm,
1578 "rgba8unorm-srgb" => TextureFormat::Rgba8UnormSrgb,
1579 "rgba8snorm" => TextureFormat::Rgba8Snorm,
1580 "rgba8uint" => TextureFormat::Rgba8Uint,
1581 "rgba8sint" => TextureFormat::Rgba8Sint,
1582 "bgra8unorm" => TextureFormat::Bgra8Unorm,
1583 "bgra8unorm-srgb" => TextureFormat::Bgra8UnormSrgb,
1584 "rgb10a2uint" => TextureFormat::Rgb10a2Uint,
1585 "rgb10a2unorm" => TextureFormat::Rgb10a2Unorm,
1586 "rg11b10ufloat" => TextureFormat::Rg11b10Ufloat,
1587 "r64uint" => TextureFormat::R64Uint,
1588 "rg32uint" => TextureFormat::Rg32Uint,
1589 "rg32sint" => TextureFormat::Rg32Sint,
1590 "rg32float" => TextureFormat::Rg32Float,
1591 "rgba16uint" => TextureFormat::Rgba16Uint,
1592 "rgba16sint" => TextureFormat::Rgba16Sint,
1593 "rgba16unorm" => TextureFormat::Rgba16Unorm,
1594 "rgba16snorm" => TextureFormat::Rgba16Snorm,
1595 "rgba16float" => TextureFormat::Rgba16Float,
1596 "rgba32uint" => TextureFormat::Rgba32Uint,
1597 "rgba32sint" => TextureFormat::Rgba32Sint,
1598 "rgba32float" => TextureFormat::Rgba32Float,
1599 "stencil8" => TextureFormat::Stencil8,
1600 "depth32float" => TextureFormat::Depth32Float,
1601 "depth32float-stencil8" => TextureFormat::Depth32FloatStencil8,
1602 "depth16unorm" => TextureFormat::Depth16Unorm,
1603 "depth24plus" => TextureFormat::Depth24Plus,
1604 "depth24plus-stencil8" => TextureFormat::Depth24PlusStencil8,
1605 "nv12" => TextureFormat::NV12,
1606 "p010" => TextureFormat::P010,
1607 "rgb9e5ufloat" => TextureFormat::Rgb9e5Ufloat,
1608 "bc1-rgba-unorm" => TextureFormat::Bc1RgbaUnorm,
1609 "bc1-rgba-unorm-srgb" => TextureFormat::Bc1RgbaUnormSrgb,
1610 "bc2-rgba-unorm" => TextureFormat::Bc2RgbaUnorm,
1611 "bc2-rgba-unorm-srgb" => TextureFormat::Bc2RgbaUnormSrgb,
1612 "bc3-rgba-unorm" => TextureFormat::Bc3RgbaUnorm,
1613 "bc3-rgba-unorm-srgb" => TextureFormat::Bc3RgbaUnormSrgb,
1614 "bc4-r-unorm" => TextureFormat::Bc4RUnorm,
1615 "bc4-r-snorm" => TextureFormat::Bc4RSnorm,
1616 "bc5-rg-unorm" => TextureFormat::Bc5RgUnorm,
1617 "bc5-rg-snorm" => TextureFormat::Bc5RgSnorm,
1618 "bc6h-rgb-ufloat" => TextureFormat::Bc6hRgbUfloat,
1619 "bc6h-rgb-float" => TextureFormat::Bc6hRgbFloat,
1620 "bc7-rgba-unorm" => TextureFormat::Bc7RgbaUnorm,
1621 "bc7-rgba-unorm-srgb" => TextureFormat::Bc7RgbaUnormSrgb,
1622 "etc2-rgb8unorm" => TextureFormat::Etc2Rgb8Unorm,
1623 "etc2-rgb8unorm-srgb" => TextureFormat::Etc2Rgb8UnormSrgb,
1624 "etc2-rgb8a1unorm" => TextureFormat::Etc2Rgb8A1Unorm,
1625 "etc2-rgb8a1unorm-srgb" => TextureFormat::Etc2Rgb8A1UnormSrgb,
1626 "etc2-rgba8unorm" => TextureFormat::Etc2Rgba8Unorm,
1627 "etc2-rgba8unorm-srgb" => TextureFormat::Etc2Rgba8UnormSrgb,
1628 "eac-r11unorm" => TextureFormat::EacR11Unorm,
1629 "eac-r11snorm" => TextureFormat::EacR11Snorm,
1630 "eac-rg11unorm" => TextureFormat::EacRg11Unorm,
1631 "eac-rg11snorm" => TextureFormat::EacRg11Snorm,
1632 other => {
1633 if let Some(parts) = other.strip_prefix("astc-") {
1634 let (block, channel) = parts
1635 .split_once('-')
1636 .ok_or_else(|| E::invalid_value(Unexpected::Str(s), &self))?;
1637
1638 let block = match block {
1639 "4x4" => AstcBlock::B4x4,
1640 "5x4" => AstcBlock::B5x4,
1641 "5x5" => AstcBlock::B5x5,
1642 "6x5" => AstcBlock::B6x5,
1643 "6x6" => AstcBlock::B6x6,
1644 "8x5" => AstcBlock::B8x5,
1645 "8x6" => AstcBlock::B8x6,
1646 "8x8" => AstcBlock::B8x8,
1647 "10x5" => AstcBlock::B10x5,
1648 "10x6" => AstcBlock::B10x6,
1649 "10x8" => AstcBlock::B10x8,
1650 "10x10" => AstcBlock::B10x10,
1651 "12x10" => AstcBlock::B12x10,
1652 "12x12" => AstcBlock::B12x12,
1653 _ => return Err(E::invalid_value(Unexpected::Str(s), &self)),
1654 };
1655
1656 let channel = match channel {
1657 "unorm" => AstcChannel::Unorm,
1658 "unorm-srgb" => AstcChannel::UnormSrgb,
1659 "hdr" => AstcChannel::Hdr,
1660 _ => return Err(E::invalid_value(Unexpected::Str(s), &self)),
1661 };
1662
1663 TextureFormat::Astc { block, channel }
1664 } else {
1665 return Err(E::invalid_value(Unexpected::Str(s), &self));
1666 }
1667 }
1668 };
1669
1670 Ok(format)
1671 }
1672 }
1673
1674 deserializer.deserialize_str(TextureFormatVisitor)
1675 }
1676}
1677
1678#[cfg(any(feature = "serde", test))]
1679impl Serialize for TextureFormat {
1680 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1681 where
1682 S: serde::Serializer,
1683 {
1684 let s: alloc::string::String;
1685 let name = match *self {
1686 TextureFormat::R8Unorm => "r8unorm",
1687 TextureFormat::R8Snorm => "r8snorm",
1688 TextureFormat::R8Uint => "r8uint",
1689 TextureFormat::R8Sint => "r8sint",
1690 TextureFormat::R16Uint => "r16uint",
1691 TextureFormat::R16Sint => "r16sint",
1692 TextureFormat::R16Unorm => "r16unorm",
1693 TextureFormat::R16Snorm => "r16snorm",
1694 TextureFormat::R16Float => "r16float",
1695 TextureFormat::Rg8Unorm => "rg8unorm",
1696 TextureFormat::Rg8Snorm => "rg8snorm",
1697 TextureFormat::Rg8Uint => "rg8uint",
1698 TextureFormat::Rg8Sint => "rg8sint",
1699 TextureFormat::R32Uint => "r32uint",
1700 TextureFormat::R32Sint => "r32sint",
1701 TextureFormat::R32Float => "r32float",
1702 TextureFormat::Rg16Uint => "rg16uint",
1703 TextureFormat::Rg16Sint => "rg16sint",
1704 TextureFormat::Rg16Unorm => "rg16unorm",
1705 TextureFormat::Rg16Snorm => "rg16snorm",
1706 TextureFormat::Rg16Float => "rg16float",
1707 TextureFormat::Rgba8Unorm => "rgba8unorm",
1708 TextureFormat::Rgba8UnormSrgb => "rgba8unorm-srgb",
1709 TextureFormat::Rgba8Snorm => "rgba8snorm",
1710 TextureFormat::Rgba8Uint => "rgba8uint",
1711 TextureFormat::Rgba8Sint => "rgba8sint",
1712 TextureFormat::Bgra8Unorm => "bgra8unorm",
1713 TextureFormat::Bgra8UnormSrgb => "bgra8unorm-srgb",
1714 TextureFormat::Rgb10a2Uint => "rgb10a2uint",
1715 TextureFormat::Rgb10a2Unorm => "rgb10a2unorm",
1716 TextureFormat::Rg11b10Ufloat => "rg11b10ufloat",
1717 TextureFormat::R64Uint => "r64uint",
1718 TextureFormat::Rg32Uint => "rg32uint",
1719 TextureFormat::Rg32Sint => "rg32sint",
1720 TextureFormat::Rg32Float => "rg32float",
1721 TextureFormat::Rgba16Uint => "rgba16uint",
1722 TextureFormat::Rgba16Sint => "rgba16sint",
1723 TextureFormat::Rgba16Unorm => "rgba16unorm",
1724 TextureFormat::Rgba16Snorm => "rgba16snorm",
1725 TextureFormat::Rgba16Float => "rgba16float",
1726 TextureFormat::Rgba32Uint => "rgba32uint",
1727 TextureFormat::Rgba32Sint => "rgba32sint",
1728 TextureFormat::Rgba32Float => "rgba32float",
1729 TextureFormat::Stencil8 => "stencil8",
1730 TextureFormat::Depth32Float => "depth32float",
1731 TextureFormat::Depth16Unorm => "depth16unorm",
1732 TextureFormat::Depth32FloatStencil8 => "depth32float-stencil8",
1733 TextureFormat::Depth24Plus => "depth24plus",
1734 TextureFormat::Depth24PlusStencil8 => "depth24plus-stencil8",
1735 TextureFormat::NV12 => "nv12",
1736 TextureFormat::P010 => "p010",
1737 TextureFormat::Rgb9e5Ufloat => "rgb9e5ufloat",
1738 TextureFormat::Bc1RgbaUnorm => "bc1-rgba-unorm",
1739 TextureFormat::Bc1RgbaUnormSrgb => "bc1-rgba-unorm-srgb",
1740 TextureFormat::Bc2RgbaUnorm => "bc2-rgba-unorm",
1741 TextureFormat::Bc2RgbaUnormSrgb => "bc2-rgba-unorm-srgb",
1742 TextureFormat::Bc3RgbaUnorm => "bc3-rgba-unorm",
1743 TextureFormat::Bc3RgbaUnormSrgb => "bc3-rgba-unorm-srgb",
1744 TextureFormat::Bc4RUnorm => "bc4-r-unorm",
1745 TextureFormat::Bc4RSnorm => "bc4-r-snorm",
1746 TextureFormat::Bc5RgUnorm => "bc5-rg-unorm",
1747 TextureFormat::Bc5RgSnorm => "bc5-rg-snorm",
1748 TextureFormat::Bc6hRgbUfloat => "bc6h-rgb-ufloat",
1749 TextureFormat::Bc6hRgbFloat => "bc6h-rgb-float",
1750 TextureFormat::Bc7RgbaUnorm => "bc7-rgba-unorm",
1751 TextureFormat::Bc7RgbaUnormSrgb => "bc7-rgba-unorm-srgb",
1752 TextureFormat::Etc2Rgb8Unorm => "etc2-rgb8unorm",
1753 TextureFormat::Etc2Rgb8UnormSrgb => "etc2-rgb8unorm-srgb",
1754 TextureFormat::Etc2Rgb8A1Unorm => "etc2-rgb8a1unorm",
1755 TextureFormat::Etc2Rgb8A1UnormSrgb => "etc2-rgb8a1unorm-srgb",
1756 TextureFormat::Etc2Rgba8Unorm => "etc2-rgba8unorm",
1757 TextureFormat::Etc2Rgba8UnormSrgb => "etc2-rgba8unorm-srgb",
1758 TextureFormat::EacR11Unorm => "eac-r11unorm",
1759 TextureFormat::EacR11Snorm => "eac-r11snorm",
1760 TextureFormat::EacRg11Unorm => "eac-rg11unorm",
1761 TextureFormat::EacRg11Snorm => "eac-rg11snorm",
1762 TextureFormat::Astc { block, channel } => {
1763 let block = match block {
1764 AstcBlock::B4x4 => "4x4",
1765 AstcBlock::B5x4 => "5x4",
1766 AstcBlock::B5x5 => "5x5",
1767 AstcBlock::B6x5 => "6x5",
1768 AstcBlock::B6x6 => "6x6",
1769 AstcBlock::B8x5 => "8x5",
1770 AstcBlock::B8x6 => "8x6",
1771 AstcBlock::B8x8 => "8x8",
1772 AstcBlock::B10x5 => "10x5",
1773 AstcBlock::B10x6 => "10x6",
1774 AstcBlock::B10x8 => "10x8",
1775 AstcBlock::B10x10 => "10x10",
1776 AstcBlock::B12x10 => "12x10",
1777 AstcBlock::B12x12 => "12x12",
1778 };
1779
1780 let channel = match channel {
1781 AstcChannel::Unorm => "unorm",
1782 AstcChannel::UnormSrgb => "unorm-srgb",
1783 AstcChannel::Hdr => "hdr",
1784 };
1785
1786 s = alloc::format!("astc-{block}-{channel}");
1787 &s
1788 }
1789 };
1790 serializer.serialize_str(name)
1791 }
1792}
1793
1794bitflags::bitflags! {
1795 #[repr(transparent)]
1797 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1798 #[cfg_attr(feature = "serde", serde(transparent))]
1799 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1800 pub struct TextureFormatFeatureFlags: u32 {
1801 const FILTERABLE = 1 << 0;
1804 const MULTISAMPLE_X2 = 1 << 1;
1806 const MULTISAMPLE_X4 = 1 << 2 ;
1808 const MULTISAMPLE_X8 = 1 << 3 ;
1810 const MULTISAMPLE_X16 = 1 << 4;
1812 const MULTISAMPLE_RESOLVE = 1 << 5;
1815 const STORAGE_READ_ONLY = 1 << 6;
1818 const STORAGE_WRITE_ONLY = 1 << 7;
1821 const STORAGE_READ_WRITE = 1 << 8;
1824 const STORAGE_ATOMIC = 1 << 9;
1827 const BLENDABLE = 1 << 10;
1829 }
1830}
1831
1832impl TextureFormatFeatureFlags {
1833 #[must_use]
1837 pub fn sample_count_supported(&self, count: u32) -> bool {
1838 use TextureFormatFeatureFlags as tfsc;
1839
1840 match count {
1841 1 => true,
1842 2 => self.contains(tfsc::MULTISAMPLE_X2),
1843 4 => self.contains(tfsc::MULTISAMPLE_X4),
1844 8 => self.contains(tfsc::MULTISAMPLE_X8),
1845 16 => self.contains(tfsc::MULTISAMPLE_X16),
1846 _ => false,
1847 }
1848 }
1849
1850 #[must_use]
1852 pub fn supported_sample_counts(&self) -> Vec<u32> {
1853 let all_possible_sample_counts: [u32; 5] = [1, 2, 4, 8, 16];
1854 all_possible_sample_counts
1855 .into_iter()
1856 .filter(|&sc| self.sample_count_supported(sc))
1857 .collect()
1858 }
1859}
1860
1861#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
1865#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1866pub struct TextureFormatFeatures {
1867 pub allowed_usages: TextureUsages,
1869 pub flags: TextureFormatFeatureFlags,
1871}
1872
1873#[cfg(test)]
1874mod tests {
1875 use super::*;
1876
1877 #[test]
1878 fn texture_format_serialize() {
1879 use alloc::string::ToString;
1880
1881 assert_eq!(
1882 serde_json::to_string(&TextureFormat::R8Unorm).unwrap(),
1883 "\"r8unorm\"".to_string()
1884 );
1885 assert_eq!(
1886 serde_json::to_string(&TextureFormat::R8Snorm).unwrap(),
1887 "\"r8snorm\"".to_string()
1888 );
1889 assert_eq!(
1890 serde_json::to_string(&TextureFormat::R8Uint).unwrap(),
1891 "\"r8uint\"".to_string()
1892 );
1893 assert_eq!(
1894 serde_json::to_string(&TextureFormat::R8Sint).unwrap(),
1895 "\"r8sint\"".to_string()
1896 );
1897 assert_eq!(
1898 serde_json::to_string(&TextureFormat::R16Uint).unwrap(),
1899 "\"r16uint\"".to_string()
1900 );
1901 assert_eq!(
1902 serde_json::to_string(&TextureFormat::R16Sint).unwrap(),
1903 "\"r16sint\"".to_string()
1904 );
1905 assert_eq!(
1906 serde_json::to_string(&TextureFormat::R16Unorm).unwrap(),
1907 "\"r16unorm\"".to_string()
1908 );
1909 assert_eq!(
1910 serde_json::to_string(&TextureFormat::R16Snorm).unwrap(),
1911 "\"r16snorm\"".to_string()
1912 );
1913 assert_eq!(
1914 serde_json::to_string(&TextureFormat::R16Float).unwrap(),
1915 "\"r16float\"".to_string()
1916 );
1917 assert_eq!(
1918 serde_json::to_string(&TextureFormat::Rg8Unorm).unwrap(),
1919 "\"rg8unorm\"".to_string()
1920 );
1921 assert_eq!(
1922 serde_json::to_string(&TextureFormat::Rg8Snorm).unwrap(),
1923 "\"rg8snorm\"".to_string()
1924 );
1925 assert_eq!(
1926 serde_json::to_string(&TextureFormat::Rg8Uint).unwrap(),
1927 "\"rg8uint\"".to_string()
1928 );
1929 assert_eq!(
1930 serde_json::to_string(&TextureFormat::Rg8Sint).unwrap(),
1931 "\"rg8sint\"".to_string()
1932 );
1933 assert_eq!(
1934 serde_json::to_string(&TextureFormat::R32Uint).unwrap(),
1935 "\"r32uint\"".to_string()
1936 );
1937 assert_eq!(
1938 serde_json::to_string(&TextureFormat::R32Sint).unwrap(),
1939 "\"r32sint\"".to_string()
1940 );
1941 assert_eq!(
1942 serde_json::to_string(&TextureFormat::R32Float).unwrap(),
1943 "\"r32float\"".to_string()
1944 );
1945 assert_eq!(
1946 serde_json::to_string(&TextureFormat::Rg16Uint).unwrap(),
1947 "\"rg16uint\"".to_string()
1948 );
1949 assert_eq!(
1950 serde_json::to_string(&TextureFormat::Rg16Sint).unwrap(),
1951 "\"rg16sint\"".to_string()
1952 );
1953 assert_eq!(
1954 serde_json::to_string(&TextureFormat::Rg16Unorm).unwrap(),
1955 "\"rg16unorm\"".to_string()
1956 );
1957 assert_eq!(
1958 serde_json::to_string(&TextureFormat::Rg16Snorm).unwrap(),
1959 "\"rg16snorm\"".to_string()
1960 );
1961 assert_eq!(
1962 serde_json::to_string(&TextureFormat::Rg16Float).unwrap(),
1963 "\"rg16float\"".to_string()
1964 );
1965 assert_eq!(
1966 serde_json::to_string(&TextureFormat::Rgba8Unorm).unwrap(),
1967 "\"rgba8unorm\"".to_string()
1968 );
1969 assert_eq!(
1970 serde_json::to_string(&TextureFormat::Rgba8UnormSrgb).unwrap(),
1971 "\"rgba8unorm-srgb\"".to_string()
1972 );
1973 assert_eq!(
1974 serde_json::to_string(&TextureFormat::Rgba8Snorm).unwrap(),
1975 "\"rgba8snorm\"".to_string()
1976 );
1977 assert_eq!(
1978 serde_json::to_string(&TextureFormat::Rgba8Uint).unwrap(),
1979 "\"rgba8uint\"".to_string()
1980 );
1981 assert_eq!(
1982 serde_json::to_string(&TextureFormat::Rgba8Sint).unwrap(),
1983 "\"rgba8sint\"".to_string()
1984 );
1985 assert_eq!(
1986 serde_json::to_string(&TextureFormat::Bgra8Unorm).unwrap(),
1987 "\"bgra8unorm\"".to_string()
1988 );
1989 assert_eq!(
1990 serde_json::to_string(&TextureFormat::Bgra8UnormSrgb).unwrap(),
1991 "\"bgra8unorm-srgb\"".to_string()
1992 );
1993 assert_eq!(
1994 serde_json::to_string(&TextureFormat::Rgb10a2Uint).unwrap(),
1995 "\"rgb10a2uint\"".to_string()
1996 );
1997 assert_eq!(
1998 serde_json::to_string(&TextureFormat::Rgb10a2Unorm).unwrap(),
1999 "\"rgb10a2unorm\"".to_string()
2000 );
2001 assert_eq!(
2002 serde_json::to_string(&TextureFormat::Rg11b10Ufloat).unwrap(),
2003 "\"rg11b10ufloat\"".to_string()
2004 );
2005 assert_eq!(
2006 serde_json::to_string(&TextureFormat::R64Uint).unwrap(),
2007 "\"r64uint\"".to_string()
2008 );
2009 assert_eq!(
2010 serde_json::to_string(&TextureFormat::Rg32Uint).unwrap(),
2011 "\"rg32uint\"".to_string()
2012 );
2013 assert_eq!(
2014 serde_json::to_string(&TextureFormat::Rg32Sint).unwrap(),
2015 "\"rg32sint\"".to_string()
2016 );
2017 assert_eq!(
2018 serde_json::to_string(&TextureFormat::Rg32Float).unwrap(),
2019 "\"rg32float\"".to_string()
2020 );
2021 assert_eq!(
2022 serde_json::to_string(&TextureFormat::Rgba16Uint).unwrap(),
2023 "\"rgba16uint\"".to_string()
2024 );
2025 assert_eq!(
2026 serde_json::to_string(&TextureFormat::Rgba16Sint).unwrap(),
2027 "\"rgba16sint\"".to_string()
2028 );
2029 assert_eq!(
2030 serde_json::to_string(&TextureFormat::Rgba16Unorm).unwrap(),
2031 "\"rgba16unorm\"".to_string()
2032 );
2033 assert_eq!(
2034 serde_json::to_string(&TextureFormat::Rgba16Snorm).unwrap(),
2035 "\"rgba16snorm\"".to_string()
2036 );
2037 assert_eq!(
2038 serde_json::to_string(&TextureFormat::Rgba16Float).unwrap(),
2039 "\"rgba16float\"".to_string()
2040 );
2041 assert_eq!(
2042 serde_json::to_string(&TextureFormat::Rgba32Uint).unwrap(),
2043 "\"rgba32uint\"".to_string()
2044 );
2045 assert_eq!(
2046 serde_json::to_string(&TextureFormat::Rgba32Sint).unwrap(),
2047 "\"rgba32sint\"".to_string()
2048 );
2049 assert_eq!(
2050 serde_json::to_string(&TextureFormat::Rgba32Float).unwrap(),
2051 "\"rgba32float\"".to_string()
2052 );
2053 assert_eq!(
2054 serde_json::to_string(&TextureFormat::Stencil8).unwrap(),
2055 "\"stencil8\"".to_string()
2056 );
2057 assert_eq!(
2058 serde_json::to_string(&TextureFormat::Depth32Float).unwrap(),
2059 "\"depth32float\"".to_string()
2060 );
2061 assert_eq!(
2062 serde_json::to_string(&TextureFormat::Depth16Unorm).unwrap(),
2063 "\"depth16unorm\"".to_string()
2064 );
2065 assert_eq!(
2066 serde_json::to_string(&TextureFormat::Depth32FloatStencil8).unwrap(),
2067 "\"depth32float-stencil8\"".to_string()
2068 );
2069 assert_eq!(
2070 serde_json::to_string(&TextureFormat::Depth24Plus).unwrap(),
2071 "\"depth24plus\"".to_string()
2072 );
2073 assert_eq!(
2074 serde_json::to_string(&TextureFormat::Depth24PlusStencil8).unwrap(),
2075 "\"depth24plus-stencil8\"".to_string()
2076 );
2077 assert_eq!(
2078 serde_json::to_string(&TextureFormat::Rgb9e5Ufloat).unwrap(),
2079 "\"rgb9e5ufloat\"".to_string()
2080 );
2081 assert_eq!(
2082 serde_json::to_string(&TextureFormat::Bc1RgbaUnorm).unwrap(),
2083 "\"bc1-rgba-unorm\"".to_string()
2084 );
2085 assert_eq!(
2086 serde_json::to_string(&TextureFormat::Bc1RgbaUnormSrgb).unwrap(),
2087 "\"bc1-rgba-unorm-srgb\"".to_string()
2088 );
2089 assert_eq!(
2090 serde_json::to_string(&TextureFormat::Bc2RgbaUnorm).unwrap(),
2091 "\"bc2-rgba-unorm\"".to_string()
2092 );
2093 assert_eq!(
2094 serde_json::to_string(&TextureFormat::Bc2RgbaUnormSrgb).unwrap(),
2095 "\"bc2-rgba-unorm-srgb\"".to_string()
2096 );
2097 assert_eq!(
2098 serde_json::to_string(&TextureFormat::Bc3RgbaUnorm).unwrap(),
2099 "\"bc3-rgba-unorm\"".to_string()
2100 );
2101 assert_eq!(
2102 serde_json::to_string(&TextureFormat::Bc3RgbaUnormSrgb).unwrap(),
2103 "\"bc3-rgba-unorm-srgb\"".to_string()
2104 );
2105 assert_eq!(
2106 serde_json::to_string(&TextureFormat::Bc4RUnorm).unwrap(),
2107 "\"bc4-r-unorm\"".to_string()
2108 );
2109 assert_eq!(
2110 serde_json::to_string(&TextureFormat::Bc4RSnorm).unwrap(),
2111 "\"bc4-r-snorm\"".to_string()
2112 );
2113 assert_eq!(
2114 serde_json::to_string(&TextureFormat::Bc5RgUnorm).unwrap(),
2115 "\"bc5-rg-unorm\"".to_string()
2116 );
2117 assert_eq!(
2118 serde_json::to_string(&TextureFormat::Bc5RgSnorm).unwrap(),
2119 "\"bc5-rg-snorm\"".to_string()
2120 );
2121 assert_eq!(
2122 serde_json::to_string(&TextureFormat::Bc6hRgbUfloat).unwrap(),
2123 "\"bc6h-rgb-ufloat\"".to_string()
2124 );
2125 assert_eq!(
2126 serde_json::to_string(&TextureFormat::Bc6hRgbFloat).unwrap(),
2127 "\"bc6h-rgb-float\"".to_string()
2128 );
2129 assert_eq!(
2130 serde_json::to_string(&TextureFormat::Bc7RgbaUnorm).unwrap(),
2131 "\"bc7-rgba-unorm\"".to_string()
2132 );
2133 assert_eq!(
2134 serde_json::to_string(&TextureFormat::Bc7RgbaUnormSrgb).unwrap(),
2135 "\"bc7-rgba-unorm-srgb\"".to_string()
2136 );
2137 assert_eq!(
2138 serde_json::to_string(&TextureFormat::Etc2Rgb8Unorm).unwrap(),
2139 "\"etc2-rgb8unorm\"".to_string()
2140 );
2141 assert_eq!(
2142 serde_json::to_string(&TextureFormat::Etc2Rgb8UnormSrgb).unwrap(),
2143 "\"etc2-rgb8unorm-srgb\"".to_string()
2144 );
2145 assert_eq!(
2146 serde_json::to_string(&TextureFormat::Etc2Rgb8A1Unorm).unwrap(),
2147 "\"etc2-rgb8a1unorm\"".to_string()
2148 );
2149 assert_eq!(
2150 serde_json::to_string(&TextureFormat::Etc2Rgb8A1UnormSrgb).unwrap(),
2151 "\"etc2-rgb8a1unorm-srgb\"".to_string()
2152 );
2153 assert_eq!(
2154 serde_json::to_string(&TextureFormat::Etc2Rgba8Unorm).unwrap(),
2155 "\"etc2-rgba8unorm\"".to_string()
2156 );
2157 assert_eq!(
2158 serde_json::to_string(&TextureFormat::Etc2Rgba8UnormSrgb).unwrap(),
2159 "\"etc2-rgba8unorm-srgb\"".to_string()
2160 );
2161 assert_eq!(
2162 serde_json::to_string(&TextureFormat::EacR11Unorm).unwrap(),
2163 "\"eac-r11unorm\"".to_string()
2164 );
2165 assert_eq!(
2166 serde_json::to_string(&TextureFormat::EacR11Snorm).unwrap(),
2167 "\"eac-r11snorm\"".to_string()
2168 );
2169 assert_eq!(
2170 serde_json::to_string(&TextureFormat::EacRg11Unorm).unwrap(),
2171 "\"eac-rg11unorm\"".to_string()
2172 );
2173 assert_eq!(
2174 serde_json::to_string(&TextureFormat::EacRg11Snorm).unwrap(),
2175 "\"eac-rg11snorm\"".to_string()
2176 );
2177 }
2178
2179 #[test]
2180 fn texture_format_deserialize() {
2181 assert_eq!(
2182 serde_json::from_str::<TextureFormat>("\"r8unorm\"").unwrap(),
2183 TextureFormat::R8Unorm
2184 );
2185 assert_eq!(
2186 serde_json::from_str::<TextureFormat>("\"r8snorm\"").unwrap(),
2187 TextureFormat::R8Snorm
2188 );
2189 assert_eq!(
2190 serde_json::from_str::<TextureFormat>("\"r8uint\"").unwrap(),
2191 TextureFormat::R8Uint
2192 );
2193 assert_eq!(
2194 serde_json::from_str::<TextureFormat>("\"r8sint\"").unwrap(),
2195 TextureFormat::R8Sint
2196 );
2197 assert_eq!(
2198 serde_json::from_str::<TextureFormat>("\"r16uint\"").unwrap(),
2199 TextureFormat::R16Uint
2200 );
2201 assert_eq!(
2202 serde_json::from_str::<TextureFormat>("\"r16sint\"").unwrap(),
2203 TextureFormat::R16Sint
2204 );
2205 assert_eq!(
2206 serde_json::from_str::<TextureFormat>("\"r16unorm\"").unwrap(),
2207 TextureFormat::R16Unorm
2208 );
2209 assert_eq!(
2210 serde_json::from_str::<TextureFormat>("\"r16snorm\"").unwrap(),
2211 TextureFormat::R16Snorm
2212 );
2213 assert_eq!(
2214 serde_json::from_str::<TextureFormat>("\"r16float\"").unwrap(),
2215 TextureFormat::R16Float
2216 );
2217 assert_eq!(
2218 serde_json::from_str::<TextureFormat>("\"rg8unorm\"").unwrap(),
2219 TextureFormat::Rg8Unorm
2220 );
2221 assert_eq!(
2222 serde_json::from_str::<TextureFormat>("\"rg8snorm\"").unwrap(),
2223 TextureFormat::Rg8Snorm
2224 );
2225 assert_eq!(
2226 serde_json::from_str::<TextureFormat>("\"rg8uint\"").unwrap(),
2227 TextureFormat::Rg8Uint
2228 );
2229 assert_eq!(
2230 serde_json::from_str::<TextureFormat>("\"rg8sint\"").unwrap(),
2231 TextureFormat::Rg8Sint
2232 );
2233 assert_eq!(
2234 serde_json::from_str::<TextureFormat>("\"r32uint\"").unwrap(),
2235 TextureFormat::R32Uint
2236 );
2237 assert_eq!(
2238 serde_json::from_str::<TextureFormat>("\"r32sint\"").unwrap(),
2239 TextureFormat::R32Sint
2240 );
2241 assert_eq!(
2242 serde_json::from_str::<TextureFormat>("\"r32float\"").unwrap(),
2243 TextureFormat::R32Float
2244 );
2245 assert_eq!(
2246 serde_json::from_str::<TextureFormat>("\"rg16uint\"").unwrap(),
2247 TextureFormat::Rg16Uint
2248 );
2249 assert_eq!(
2250 serde_json::from_str::<TextureFormat>("\"rg16sint\"").unwrap(),
2251 TextureFormat::Rg16Sint
2252 );
2253 assert_eq!(
2254 serde_json::from_str::<TextureFormat>("\"rg16unorm\"").unwrap(),
2255 TextureFormat::Rg16Unorm
2256 );
2257 assert_eq!(
2258 serde_json::from_str::<TextureFormat>("\"rg16snorm\"").unwrap(),
2259 TextureFormat::Rg16Snorm
2260 );
2261 assert_eq!(
2262 serde_json::from_str::<TextureFormat>("\"rg16float\"").unwrap(),
2263 TextureFormat::Rg16Float
2264 );
2265 assert_eq!(
2266 serde_json::from_str::<TextureFormat>("\"rgba8unorm\"").unwrap(),
2267 TextureFormat::Rgba8Unorm
2268 );
2269 assert_eq!(
2270 serde_json::from_str::<TextureFormat>("\"rgba8unorm-srgb\"").unwrap(),
2271 TextureFormat::Rgba8UnormSrgb
2272 );
2273 assert_eq!(
2274 serde_json::from_str::<TextureFormat>("\"rgba8snorm\"").unwrap(),
2275 TextureFormat::Rgba8Snorm
2276 );
2277 assert_eq!(
2278 serde_json::from_str::<TextureFormat>("\"rgba8uint\"").unwrap(),
2279 TextureFormat::Rgba8Uint
2280 );
2281 assert_eq!(
2282 serde_json::from_str::<TextureFormat>("\"rgba8sint\"").unwrap(),
2283 TextureFormat::Rgba8Sint
2284 );
2285 assert_eq!(
2286 serde_json::from_str::<TextureFormat>("\"bgra8unorm\"").unwrap(),
2287 TextureFormat::Bgra8Unorm
2288 );
2289 assert_eq!(
2290 serde_json::from_str::<TextureFormat>("\"bgra8unorm-srgb\"").unwrap(),
2291 TextureFormat::Bgra8UnormSrgb
2292 );
2293 assert_eq!(
2294 serde_json::from_str::<TextureFormat>("\"rgb10a2uint\"").unwrap(),
2295 TextureFormat::Rgb10a2Uint
2296 );
2297 assert_eq!(
2298 serde_json::from_str::<TextureFormat>("\"rgb10a2unorm\"").unwrap(),
2299 TextureFormat::Rgb10a2Unorm
2300 );
2301 assert_eq!(
2302 serde_json::from_str::<TextureFormat>("\"rg11b10ufloat\"").unwrap(),
2303 TextureFormat::Rg11b10Ufloat
2304 );
2305 assert_eq!(
2306 serde_json::from_str::<TextureFormat>("\"r64uint\"").unwrap(),
2307 TextureFormat::R64Uint
2308 );
2309 assert_eq!(
2310 serde_json::from_str::<TextureFormat>("\"rg32uint\"").unwrap(),
2311 TextureFormat::Rg32Uint
2312 );
2313 assert_eq!(
2314 serde_json::from_str::<TextureFormat>("\"rg32sint\"").unwrap(),
2315 TextureFormat::Rg32Sint
2316 );
2317 assert_eq!(
2318 serde_json::from_str::<TextureFormat>("\"rg32float\"").unwrap(),
2319 TextureFormat::Rg32Float
2320 );
2321 assert_eq!(
2322 serde_json::from_str::<TextureFormat>("\"rgba16uint\"").unwrap(),
2323 TextureFormat::Rgba16Uint
2324 );
2325 assert_eq!(
2326 serde_json::from_str::<TextureFormat>("\"rgba16sint\"").unwrap(),
2327 TextureFormat::Rgba16Sint
2328 );
2329 assert_eq!(
2330 serde_json::from_str::<TextureFormat>("\"rgba16unorm\"").unwrap(),
2331 TextureFormat::Rgba16Unorm
2332 );
2333 assert_eq!(
2334 serde_json::from_str::<TextureFormat>("\"rgba16snorm\"").unwrap(),
2335 TextureFormat::Rgba16Snorm
2336 );
2337 assert_eq!(
2338 serde_json::from_str::<TextureFormat>("\"rgba16float\"").unwrap(),
2339 TextureFormat::Rgba16Float
2340 );
2341 assert_eq!(
2342 serde_json::from_str::<TextureFormat>("\"rgba32uint\"").unwrap(),
2343 TextureFormat::Rgba32Uint
2344 );
2345 assert_eq!(
2346 serde_json::from_str::<TextureFormat>("\"rgba32sint\"").unwrap(),
2347 TextureFormat::Rgba32Sint
2348 );
2349 assert_eq!(
2350 serde_json::from_str::<TextureFormat>("\"rgba32float\"").unwrap(),
2351 TextureFormat::Rgba32Float
2352 );
2353 assert_eq!(
2354 serde_json::from_str::<TextureFormat>("\"stencil8\"").unwrap(),
2355 TextureFormat::Stencil8
2356 );
2357 assert_eq!(
2358 serde_json::from_str::<TextureFormat>("\"depth32float\"").unwrap(),
2359 TextureFormat::Depth32Float
2360 );
2361 assert_eq!(
2362 serde_json::from_str::<TextureFormat>("\"depth16unorm\"").unwrap(),
2363 TextureFormat::Depth16Unorm
2364 );
2365 assert_eq!(
2366 serde_json::from_str::<TextureFormat>("\"depth32float-stencil8\"").unwrap(),
2367 TextureFormat::Depth32FloatStencil8
2368 );
2369 assert_eq!(
2370 serde_json::from_str::<TextureFormat>("\"depth24plus\"").unwrap(),
2371 TextureFormat::Depth24Plus
2372 );
2373 assert_eq!(
2374 serde_json::from_str::<TextureFormat>("\"depth24plus-stencil8\"").unwrap(),
2375 TextureFormat::Depth24PlusStencil8
2376 );
2377 assert_eq!(
2378 serde_json::from_str::<TextureFormat>("\"rgb9e5ufloat\"").unwrap(),
2379 TextureFormat::Rgb9e5Ufloat
2380 );
2381 assert_eq!(
2382 serde_json::from_str::<TextureFormat>("\"bc1-rgba-unorm\"").unwrap(),
2383 TextureFormat::Bc1RgbaUnorm
2384 );
2385 assert_eq!(
2386 serde_json::from_str::<TextureFormat>("\"bc1-rgba-unorm-srgb\"").unwrap(),
2387 TextureFormat::Bc1RgbaUnormSrgb
2388 );
2389 assert_eq!(
2390 serde_json::from_str::<TextureFormat>("\"bc2-rgba-unorm\"").unwrap(),
2391 TextureFormat::Bc2RgbaUnorm
2392 );
2393 assert_eq!(
2394 serde_json::from_str::<TextureFormat>("\"bc2-rgba-unorm-srgb\"").unwrap(),
2395 TextureFormat::Bc2RgbaUnormSrgb
2396 );
2397 assert_eq!(
2398 serde_json::from_str::<TextureFormat>("\"bc3-rgba-unorm\"").unwrap(),
2399 TextureFormat::Bc3RgbaUnorm
2400 );
2401 assert_eq!(
2402 serde_json::from_str::<TextureFormat>("\"bc3-rgba-unorm-srgb\"").unwrap(),
2403 TextureFormat::Bc3RgbaUnormSrgb
2404 );
2405 assert_eq!(
2406 serde_json::from_str::<TextureFormat>("\"bc4-r-unorm\"").unwrap(),
2407 TextureFormat::Bc4RUnorm
2408 );
2409 assert_eq!(
2410 serde_json::from_str::<TextureFormat>("\"bc4-r-snorm\"").unwrap(),
2411 TextureFormat::Bc4RSnorm
2412 );
2413 assert_eq!(
2414 serde_json::from_str::<TextureFormat>("\"bc5-rg-unorm\"").unwrap(),
2415 TextureFormat::Bc5RgUnorm
2416 );
2417 assert_eq!(
2418 serde_json::from_str::<TextureFormat>("\"bc5-rg-snorm\"").unwrap(),
2419 TextureFormat::Bc5RgSnorm
2420 );
2421 assert_eq!(
2422 serde_json::from_str::<TextureFormat>("\"bc6h-rgb-ufloat\"").unwrap(),
2423 TextureFormat::Bc6hRgbUfloat
2424 );
2425 assert_eq!(
2426 serde_json::from_str::<TextureFormat>("\"bc6h-rgb-float\"").unwrap(),
2427 TextureFormat::Bc6hRgbFloat
2428 );
2429 assert_eq!(
2430 serde_json::from_str::<TextureFormat>("\"bc7-rgba-unorm\"").unwrap(),
2431 TextureFormat::Bc7RgbaUnorm
2432 );
2433 assert_eq!(
2434 serde_json::from_str::<TextureFormat>("\"bc7-rgba-unorm-srgb\"").unwrap(),
2435 TextureFormat::Bc7RgbaUnormSrgb
2436 );
2437 assert_eq!(
2438 serde_json::from_str::<TextureFormat>("\"etc2-rgb8unorm\"").unwrap(),
2439 TextureFormat::Etc2Rgb8Unorm
2440 );
2441 assert_eq!(
2442 serde_json::from_str::<TextureFormat>("\"etc2-rgb8unorm-srgb\"").unwrap(),
2443 TextureFormat::Etc2Rgb8UnormSrgb
2444 );
2445 assert_eq!(
2446 serde_json::from_str::<TextureFormat>("\"etc2-rgb8a1unorm\"").unwrap(),
2447 TextureFormat::Etc2Rgb8A1Unorm
2448 );
2449 assert_eq!(
2450 serde_json::from_str::<TextureFormat>("\"etc2-rgb8a1unorm-srgb\"").unwrap(),
2451 TextureFormat::Etc2Rgb8A1UnormSrgb
2452 );
2453 assert_eq!(
2454 serde_json::from_str::<TextureFormat>("\"etc2-rgba8unorm\"").unwrap(),
2455 TextureFormat::Etc2Rgba8Unorm
2456 );
2457 assert_eq!(
2458 serde_json::from_str::<TextureFormat>("\"etc2-rgba8unorm-srgb\"").unwrap(),
2459 TextureFormat::Etc2Rgba8UnormSrgb
2460 );
2461 assert_eq!(
2462 serde_json::from_str::<TextureFormat>("\"eac-r11unorm\"").unwrap(),
2463 TextureFormat::EacR11Unorm
2464 );
2465 assert_eq!(
2466 serde_json::from_str::<TextureFormat>("\"eac-r11snorm\"").unwrap(),
2467 TextureFormat::EacR11Snorm
2468 );
2469 assert_eq!(
2470 serde_json::from_str::<TextureFormat>("\"eac-rg11unorm\"").unwrap(),
2471 TextureFormat::EacRg11Unorm
2472 );
2473 assert_eq!(
2474 serde_json::from_str::<TextureFormat>("\"eac-rg11snorm\"").unwrap(),
2475 TextureFormat::EacRg11Snorm
2476 );
2477 }
2478}