use crate::swizzle::{Format, SwizzleError};
use core::mem::transmute;
#[allow(non_camel_case_types, dead_code, clippy::upper_case_acronyms)]
#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Hash)]
pub enum DxgiFormat {
Unknown = 0,
R32G32B32A32_TYPELESS = 1,
R32G32B32A32_FLOAT = 2,
R32G32B32A32_UINT = 3,
R32G32B32A32_SINT = 4,
R32G32B32_TYPELESS = 5,
R32G32B32_FLOAT = 6,
R32G32B32_UINT = 7,
R32G32B32_SINT = 8,
R16G16B16A16_TYPELESS = 9,
R16G16B16A16_FLOAT = 10,
R16G16B16A16_UNORM = 11,
R16G16B16A16_UINT = 12,
R16G16B16A16_SNORM = 13,
R16G16B16A16_SINT = 14,
R32G32_TYPELESS = 15,
R32G32_FLOAT = 16,
R32G32_UINT = 17,
R32G32_SINT = 18,
R32G8X24_TYPELESS = 19,
D32_FLOAT_S8X24_UINT = 20,
R32_FLOAT_X8X24_TYPELESS = 21,
X32_TYPELESS_G8X24_UINT = 22,
R10G10B10A2_TYPELESS = 23,
R10G10B10A2_UNORM = 24,
R10G10B10A2_UINT = 25,
R11G11B10_FLOAT = 26,
R8G8B8A8_TYPELESS = 27,
R8G8B8A8_UNORM = 28,
R8G8B8A8_UNORM_SRGB = 29,
R8G8B8A8_UINT = 30,
R8G8B8A8_SNORM = 31,
R8G8B8A8_SINT = 32,
R16G16_TYPELESS = 33,
R16G16_FLOAT = 34,
R16G16_UNORM = 35,
R16G16_UINT = 36,
R16G16_SNORM = 37,
R16G16_SINT = 38,
R32_TYPELESS = 39,
D32_FLOAT = 40,
R32_FLOAT = 41,
R32_UINT = 42,
R32_SINT = 43,
R24G8_TYPELESS = 44,
D24_UNORM_S8_UINT = 45,
R24_UNORM_X8_TYPELESS = 46,
X24_TYPELESS_G8_UINT = 47,
R8G8_TYPELESS = 48,
R8G8_UNORM = 49,
R8G8_UINT = 50,
R8G8_SNORM = 51,
R8G8_SINT = 52,
R16_TYPELESS = 53,
R16_FLOAT = 54,
D16_UNORM = 55,
R16_UNORM = 56,
R16_UINT = 57,
R16_SNORM = 58,
R16_SINT = 59,
R8_TYPELESS = 60,
R8_UNORM = 61,
R8_UINT = 62,
R8_SNORM = 63,
R8_SINT = 64,
A8_UNORM = 65,
R1_UNORM = 66,
R9G9B9E5_SHAREDEXP = 67,
R8G8_B8G8_UNORM = 68,
G8R8_G8B8_UNORM = 69,
BC1_TYPELESS = 70,
BC1_UNORM = 71,
BC1_UNORM_SRGB = 72,
BC2_TYPELESS = 73,
BC2_UNORM = 74,
BC2_UNORM_SRGB = 75,
BC3_TYPELESS = 76,
BC3_UNORM = 77,
BC3_UNORM_SRGB = 78,
BC4_TYPELESS = 79,
BC4_UNORM = 80,
BC4_SNORM = 81,
BC5_TYPELESS = 82,
BC5_UNORM = 83,
BC5_SNORM = 84,
B5G6R5_UNORM = 85,
B5G5R5A1_UNORM = 86,
B8G8R8A8_UNORM = 87,
B8G8R8X8_UNORM = 88,
R10G10B10_XR_BIAS_A2_UNORM = 89,
B8G8R8A8_TYPELESS = 90,
B8G8R8A8_UNORM_SRGB = 91,
B8G8R8X8_TYPELESS = 92,
B8G8R8X8_UNORM_SRGB = 93,
BC6H_TYPELESS = 94,
BC6H_UF16 = 95,
BC6H_SF16 = 96,
BC7_TYPELESS = 97,
BC7_UNORM = 98,
BC7_UNORM_SRGB = 99,
AYUV = 100,
Y410 = 101,
Y416 = 102,
NV12 = 103,
P010 = 104,
P016 = 105,
OPAQUE420 = 106,
YUY2 = 107,
Y210 = 108,
Y216 = 109,
NV11 = 110,
AI44 = 111,
IA44 = 112,
P8 = 113,
A8P8 = 114,
B4G4R4A4_UNORM = 115,
P208 = 130,
V208 = 131,
V408 = 132,
SAMPLER_FEEDBACK_MIN_MIP_OPAQUE,
SAMPLER_FEEDBACK_MIP_REGION_USED_OPAQUE,
FORCE_UINT = 0xffffffff,
}
impl DxgiFormat {
pub fn is_srgb(&self) -> bool {
matches!(
self,
DxgiFormat::R8G8B8A8_UNORM_SRGB
| DxgiFormat::BC1_UNORM_SRGB
| DxgiFormat::BC2_UNORM_SRGB
| DxgiFormat::BC3_UNORM_SRGB
| DxgiFormat::B8G8R8A8_UNORM_SRGB
| DxgiFormat::B8G8R8X8_UNORM_SRGB
| DxgiFormat::BC7_UNORM_SRGB
)
}
pub fn calculate_pitch(&self, width: usize, height: usize) -> (usize, usize) {
match *self {
DxgiFormat::BC1_TYPELESS
| DxgiFormat::BC1_UNORM
| DxgiFormat::BC1_UNORM_SRGB
| DxgiFormat::BC4_TYPELESS
| DxgiFormat::BC4_UNORM
| DxgiFormat::BC4_SNORM => {
let nbw = ((width as i64 + 3) / 4).clamp(1, i64::MAX) as usize;
let nbh = ((height as i64 + 3) / 4).clamp(1, i64::MAX) as usize;
let pitch = nbw * 8;
(pitch, pitch * nbh)
}
DxgiFormat::BC2_TYPELESS
| DxgiFormat::BC2_UNORM
| DxgiFormat::BC2_UNORM_SRGB
| DxgiFormat::BC3_TYPELESS
| DxgiFormat::BC3_UNORM
| DxgiFormat::BC3_UNORM_SRGB
| DxgiFormat::BC5_TYPELESS
| DxgiFormat::BC5_UNORM
| DxgiFormat::BC5_SNORM
| DxgiFormat::BC6H_TYPELESS
| DxgiFormat::BC6H_UF16
| DxgiFormat::BC6H_SF16
| DxgiFormat::BC7_TYPELESS
| DxgiFormat::BC7_UNORM
| DxgiFormat::BC7_UNORM_SRGB => {
let nbw = ((width as i64 + 3) / 4).clamp(1, i64::MAX) as usize;
let nbh = ((height as i64 + 3) / 4).clamp(1, i64::MAX) as usize;
let pitch = nbw * 16;
(pitch, pitch * nbh)
}
_ => {
let pitch = (width * self.bpp()).div_ceil(8);
(pitch, height * pitch)
}
}
}
}
impl Format for DxgiFormat {
fn bpp(&self) -> usize {
match self {
DxgiFormat::R32G32B32A32_TYPELESS
| DxgiFormat::R32G32B32A32_FLOAT
| DxgiFormat::R32G32B32A32_UINT
| DxgiFormat::R32G32B32A32_SINT => 128,
DxgiFormat::R32G32B32_TYPELESS
| DxgiFormat::R32G32B32_FLOAT
| DxgiFormat::R32G32B32_UINT
| DxgiFormat::R32G32B32_SINT => 96,
DxgiFormat::R16G16B16A16_TYPELESS
| DxgiFormat::R16G16B16A16_FLOAT
| DxgiFormat::R16G16B16A16_UNORM
| DxgiFormat::R16G16B16A16_UINT
| DxgiFormat::R16G16B16A16_SNORM
| DxgiFormat::R16G16B16A16_SINT
| DxgiFormat::R32G32_TYPELESS
| DxgiFormat::R32G32_FLOAT
| DxgiFormat::R32G32_UINT
| DxgiFormat::R32G32_SINT
| DxgiFormat::R32G8X24_TYPELESS
| DxgiFormat::D32_FLOAT_S8X24_UINT
| DxgiFormat::R32_FLOAT_X8X24_TYPELESS
| DxgiFormat::X32_TYPELESS_G8X24_UINT
| DxgiFormat::Y416
| DxgiFormat::Y210
| DxgiFormat::Y216 => 64,
DxgiFormat::R10G10B10A2_TYPELESS
| DxgiFormat::R10G10B10A2_UNORM
| DxgiFormat::R10G10B10A2_UINT
| DxgiFormat::R11G11B10_FLOAT
| DxgiFormat::R8G8B8A8_TYPELESS
| DxgiFormat::R8G8B8A8_UNORM
| DxgiFormat::R8G8B8A8_UNORM_SRGB
| DxgiFormat::R8G8B8A8_UINT
| DxgiFormat::R8G8B8A8_SNORM
| DxgiFormat::R8G8B8A8_SINT
| DxgiFormat::R16G16_TYPELESS
| DxgiFormat::R16G16_FLOAT
| DxgiFormat::R16G16_UNORM
| DxgiFormat::R16G16_UINT
| DxgiFormat::R16G16_SNORM
| DxgiFormat::R16G16_SINT
| DxgiFormat::R32_TYPELESS
| DxgiFormat::D32_FLOAT
| DxgiFormat::R32_FLOAT
| DxgiFormat::R32_UINT
| DxgiFormat::R32_SINT
| DxgiFormat::R24G8_TYPELESS
| DxgiFormat::D24_UNORM_S8_UINT
| DxgiFormat::R24_UNORM_X8_TYPELESS
| DxgiFormat::X24_TYPELESS_G8_UINT
| DxgiFormat::R9G9B9E5_SHAREDEXP
| DxgiFormat::R8G8_B8G8_UNORM
| DxgiFormat::G8R8_G8B8_UNORM
| DxgiFormat::B8G8R8A8_UNORM
| DxgiFormat::B8G8R8X8_UNORM
| DxgiFormat::R10G10B10_XR_BIAS_A2_UNORM
| DxgiFormat::B8G8R8A8_TYPELESS
| DxgiFormat::B8G8R8A8_UNORM_SRGB
| DxgiFormat::B8G8R8X8_TYPELESS
| DxgiFormat::B8G8R8X8_UNORM_SRGB
| DxgiFormat::AYUV
| DxgiFormat::Y410
| DxgiFormat::YUY2 => 32,
DxgiFormat::P010 | DxgiFormat::P016 => 24,
DxgiFormat::R8G8_TYPELESS
| DxgiFormat::R8G8_UNORM
| DxgiFormat::R8G8_UINT
| DxgiFormat::R8G8_SNORM
| DxgiFormat::R8G8_SINT
| DxgiFormat::R16_TYPELESS
| DxgiFormat::R16_FLOAT
| DxgiFormat::D16_UNORM
| DxgiFormat::R16_UNORM
| DxgiFormat::R16_UINT
| DxgiFormat::R16_SNORM
| DxgiFormat::R16_SINT
| DxgiFormat::B5G6R5_UNORM
| DxgiFormat::B5G5R5A1_UNORM
| DxgiFormat::A8P8
| DxgiFormat::B4G4R4A4_UNORM => 16,
DxgiFormat::NV12 | DxgiFormat::OPAQUE420 | DxgiFormat::NV11 => 12,
DxgiFormat::R8_TYPELESS
| DxgiFormat::R8_UNORM
| DxgiFormat::R8_UINT
| DxgiFormat::R8_SNORM
| DxgiFormat::R8_SINT
| DxgiFormat::A8_UNORM
| DxgiFormat::AI44
| DxgiFormat::IA44
| DxgiFormat::P8 => 8,
DxgiFormat::R1_UNORM => 1,
DxgiFormat::BC1_TYPELESS
| DxgiFormat::BC1_UNORM
| DxgiFormat::BC1_UNORM_SRGB
| DxgiFormat::BC4_TYPELESS
| DxgiFormat::BC4_UNORM
| DxgiFormat::BC4_SNORM => 4,
DxgiFormat::BC2_TYPELESS
| DxgiFormat::BC2_UNORM
| DxgiFormat::BC2_UNORM_SRGB
| DxgiFormat::BC3_TYPELESS
| DxgiFormat::BC3_UNORM
| DxgiFormat::BC3_UNORM_SRGB
| DxgiFormat::BC5_TYPELESS
| DxgiFormat::BC5_UNORM
| DxgiFormat::BC5_SNORM
| DxgiFormat::BC6H_TYPELESS
| DxgiFormat::BC6H_UF16
| DxgiFormat::BC6H_SF16
| DxgiFormat::BC7_TYPELESS
| DxgiFormat::BC7_UNORM
| DxgiFormat::BC7_UNORM_SRGB => 8,
u => panic!("{u:?}"),
}
}
fn is_compressed(&self) -> bool {
matches!(
self,
DxgiFormat::BC1_TYPELESS
| DxgiFormat::BC1_UNORM
| DxgiFormat::BC1_UNORM_SRGB
| DxgiFormat::BC4_TYPELESS
| DxgiFormat::BC4_UNORM
| DxgiFormat::BC4_SNORM
| DxgiFormat::BC2_TYPELESS
| DxgiFormat::BC2_UNORM
| DxgiFormat::BC2_UNORM_SRGB
| DxgiFormat::BC3_TYPELESS
| DxgiFormat::BC3_UNORM
| DxgiFormat::BC3_UNORM_SRGB
| DxgiFormat::BC5_TYPELESS
| DxgiFormat::BC5_UNORM
| DxgiFormat::BC5_SNORM
| DxgiFormat::BC6H_TYPELESS
| DxgiFormat::BC6H_UF16
| DxgiFormat::BC6H_SF16
| DxgiFormat::BC7_TYPELESS
| DxgiFormat::BC7_UNORM
| DxgiFormat::BC7_UNORM_SRGB
)
}
fn block_size(&self) -> usize {
match self {
DxgiFormat::BC1_TYPELESS
| DxgiFormat::BC1_UNORM
| DxgiFormat::BC1_UNORM_SRGB
| DxgiFormat::BC4_SNORM
| DxgiFormat::BC4_TYPELESS
| DxgiFormat::BC4_UNORM => 8,
DxgiFormat::BC2_TYPELESS
| DxgiFormat::BC2_UNORM
| DxgiFormat::BC2_UNORM_SRGB
| DxgiFormat::BC3_TYPELESS
| DxgiFormat::BC3_UNORM
| DxgiFormat::BC3_UNORM_SRGB
| DxgiFormat::BC5_SNORM
| DxgiFormat::BC5_TYPELESS
| DxgiFormat::BC5_UNORM
| DxgiFormat::BC6H_SF16
| DxgiFormat::BC6H_TYPELESS
| DxgiFormat::BC6H_UF16
| DxgiFormat::BC7_TYPELESS
| DxgiFormat::BC7_UNORM
| DxgiFormat::BC7_UNORM_SRGB => 16,
u => u.bpp() / 8,
}
}
fn pixel_block_size(&self) -> usize {
match self {
DxgiFormat::BC1_TYPELESS
| DxgiFormat::BC1_UNORM
| DxgiFormat::BC1_UNORM_SRGB
| DxgiFormat::BC4_SNORM
| DxgiFormat::BC4_TYPELESS
| DxgiFormat::BC4_UNORM
| DxgiFormat::BC2_TYPELESS
| DxgiFormat::BC2_UNORM
| DxgiFormat::BC2_UNORM_SRGB
| DxgiFormat::BC3_TYPELESS
| DxgiFormat::BC3_UNORM
| DxgiFormat::BC3_UNORM_SRGB
| DxgiFormat::BC5_SNORM
| DxgiFormat::BC5_TYPELESS
| DxgiFormat::BC5_UNORM
| DxgiFormat::BC6H_SF16
| DxgiFormat::BC6H_TYPELESS
| DxgiFormat::BC6H_UF16
| DxgiFormat::BC7_TYPELESS
| DxgiFormat::BC7_UNORM
| DxgiFormat::BC7_UNORM_SRGB => 4,
_ => 1,
}
}
fn x360_swap(&self) -> bool {
false
}
}
impl From<DxgiFormat> for u32 {
fn from(val: DxgiFormat) -> Self {
unsafe { transmute(val) }
}
}
impl TryFrom<u32> for DxgiFormat {
type Error = SwizzleError;
fn try_from(value: u32) -> Result<Self, Self::Error> {
Ok(match value {
0..=115 | 130..=132 => unsafe { transmute::<u32, DxgiFormat>(value) },
e => return Err(SwizzleError::FormatOutOfRange(e)),
})
}
}
#[allow(non_camel_case_types, dead_code, clippy::upper_case_acronyms)]
#[repr(u16)]
#[derive(Debug, Clone, Copy, PartialEq, Hash)]
pub enum GcnSurfaceFormat {
Invalid = 0x00000000,
Format8 = 0x00000001,
Format16 = 0x00000002,
Format8_8 = 0x00000003,
Format32 = 0x00000004,
Format16_16 = 0x00000005,
Format10_11_11 = 0x00000006,
Format11_11_10 = 0x00000007,
Format10_10_10_2 = 0x00000008,
Format2_10_10_10 = 0x00000009,
Format8_8_8_8 = 0x0000000a,
Format32_32 = 0x0000000b,
Format16_16_16_16 = 0x0000000c,
Format32_32_32 = 0x0000000d,
Format32_32_32_32 = 0x0000000e,
Format5_6_5 = 0x00000010,
Format1_5_5_5 = 0x00000011,
Format5_5_5_1 = 0x00000012,
Format4_4_4_4 = 0x00000013,
Format8_24 = 0x00000014,
Format24_8 = 0x00000015,
FormatX24_8_32 = 0x00000016,
GbGr = 0x00000020,
BgRg = 0x00000021,
Format5_9_9_9 = 0x00000022,
BC1 = 0x00000023,
BC2 = 0x00000024,
BC3 = 0x00000025,
BC4 = 0x00000026,
BC5 = 0x00000027,
BC6 = 0x00000028,
BC7 = 0x00000029,
}
impl Format for GcnSurfaceFormat {
fn bpp(&self) -> usize {
match self {
GcnSurfaceFormat::Format8 => 8,
GcnSurfaceFormat::Format16 => 16,
GcnSurfaceFormat::Format8_8 => 16,
GcnSurfaceFormat::Format32 => 32,
GcnSurfaceFormat::Format16_16 => 32,
GcnSurfaceFormat::Format10_11_11 => 32,
GcnSurfaceFormat::Format10_10_10_2 => 32,
GcnSurfaceFormat::Format2_10_10_10 => 32,
GcnSurfaceFormat::Format8_8_8_8 => 32,
GcnSurfaceFormat::Format32_32 => 64,
GcnSurfaceFormat::Format16_16_16_16 => 64,
GcnSurfaceFormat::Format32_32_32_32 => 128,
GcnSurfaceFormat::Format8_24 => 32,
GcnSurfaceFormat::Invalid => 0,
GcnSurfaceFormat::Format1_5_5_5 => 16,
GcnSurfaceFormat::Format24_8 => 32,
GcnSurfaceFormat::FormatX24_8_32 => 64,
GcnSurfaceFormat::GbGr => 0,
GcnSurfaceFormat::BgRg => 0,
GcnSurfaceFormat::BC1 | GcnSurfaceFormat::BC4 => 4,
GcnSurfaceFormat::BC2
| GcnSurfaceFormat::BC3
| GcnSurfaceFormat::BC5
| GcnSurfaceFormat::BC6
| GcnSurfaceFormat::BC7 => 8,
GcnSurfaceFormat::Format11_11_10 => 32,
GcnSurfaceFormat::Format32_32_32 => 96,
GcnSurfaceFormat::Format5_6_5 => 16,
GcnSurfaceFormat::Format5_5_5_1 => 16,
GcnSurfaceFormat::Format4_4_4_4 => 16,
GcnSurfaceFormat::Format5_9_9_9 => 32,
}
}
fn block_size(&self) -> usize {
match self {
GcnSurfaceFormat::BC1 | GcnSurfaceFormat::BC4 => 8,
GcnSurfaceFormat::BC2
| GcnSurfaceFormat::BC3
| GcnSurfaceFormat::BC5
| GcnSurfaceFormat::BC6
| GcnSurfaceFormat::BC7 => 16,
u => u.bpp() / 8,
}
}
fn pixel_block_size(&self) -> usize {
match self {
GcnSurfaceFormat::BC1
| GcnSurfaceFormat::BC2
| GcnSurfaceFormat::BC3
| GcnSurfaceFormat::BC4
| GcnSurfaceFormat::BC5
| GcnSurfaceFormat::BC6
| GcnSurfaceFormat::BC7 => 4,
_ => 1,
}
}
fn is_compressed(&self) -> bool {
matches!(
self,
GcnSurfaceFormat::BC1
| GcnSurfaceFormat::BC2
| GcnSurfaceFormat::BC3
| GcnSurfaceFormat::BC4
| GcnSurfaceFormat::BC5
| GcnSurfaceFormat::BC6
| GcnSurfaceFormat::BC7
)
}
fn x360_swap(&self) -> bool {
false
}
}
impl TryFrom<u16> for GcnSurfaceFormat {
type Error = SwizzleError;
fn try_from(value: u16) -> Result<Self, Self::Error> {
Ok(match value {
0..=0x29 => unsafe { transmute::<u16, GcnSurfaceFormat>(value) },
e => return Err(SwizzleError::FormatOutOfRange(e.into())),
})
}
}
#[allow(non_camel_case_types, dead_code, clippy::upper_case_acronyms)]
#[derive(Debug, Clone, Copy, PartialEq, Hash)]
#[repr(u8)]
pub enum XenosSurfaceFormat {
k_1_REVERSE = 0,
k_1 = 1,
k_8 = 2,
k_1_5_5_5 = 3,
k_5_6_5 = 4,
k_6_5_5 = 5,
k_8_8_8_8 = 6,
k_2_10_10_10 = 7,
k_8_A = 8,
k_8_B = 9,
k_8_8 = 10,
k_Cr_Y1_Cb_Y0_REP = 11,
k_Y1_Cr_Y0_Cb_REP = 12,
k_16_16_EDRAM = 13,
k_8_8_8_8_A = 14,
k_4_4_4_4 = 15,
k_10_11_11 = 16,
k_11_11_10 = 17,
k_DXT1 = 18,
k_DXT2_3 = 19,
k_DXT4_5 = 20,
k_16_16_16_16_EDRAM = 21,
k_24_8 = 22,
k_24_8_FLOAT = 23,
k_16 = 24,
k_16_16 = 25,
k_16_16_16_16 = 26,
k_16_EXPAND = 27,
k_16_16_EXPAND = 28,
k_16_16_16_16_EXPAND = 29,
k_16_FLOAT = 30,
k_16_16_FLOAT = 31,
k_16_16_16_16_FLOAT = 32,
k_32 = 33,
k_32_32 = 34,
k_32_32_32_32 = 35,
k_32_FLOAT = 36,
k_32_32_FLOAT = 37,
k_32_32_32_32_FLOAT = 38,
k_32_AS_8 = 39,
k_32_AS_8_8 = 40,
k_16_MPEG = 41,
k_16_16_MPEG = 42,
k_8_INTERLACED = 43,
k_32_AS_8_INTERLACED = 44,
k_32_AS_8_8_INTERLACED = 45,
k_16_INTERLACED = 46,
k_16_MPEG_INTERLACED = 47,
k_16_16_MPEG_INTERLACED = 48,
k_DXN = 49,
k_8_8_8_8_AS_16_16_16_16 = 50,
k_DXT1_AS_16_16_16_16 = 51,
k_DXT2_3_AS_16_16_16_16 = 52,
k_DXT4_5_AS_16_16_16_16 = 53,
k_2_10_10_10_AS_16_16_16_16 = 54,
k_10_11_11_AS_16_16_16_16 = 55,
k_11_11_10_AS_16_16_16_16 = 56,
k_32_32_32_FLOAT = 57,
k_DXT3A = 58,
k_DXT5A = 59,
k_CTX1 = 60,
k_DXT3A_AS_1_1_1_1 = 61,
k_8_8_8_8_GAMMA_EDRAM = 62,
k_2_10_10_10_FLOAT_EDRAM = 63,
}
impl Format for XenosSurfaceFormat {
fn block_size(&self) -> usize {
match &self {
XenosSurfaceFormat::k_DXT1 | XenosSurfaceFormat::k_DXT1_AS_16_16_16_16 => 8,
XenosSurfaceFormat::k_DXN
| XenosSurfaceFormat::k_DXT2_3
| XenosSurfaceFormat::k_DXT2_3_AS_16_16_16_16
| XenosSurfaceFormat::k_DXT3A
| XenosSurfaceFormat::k_DXT3A_AS_1_1_1_1
| XenosSurfaceFormat::k_DXT4_5
| XenosSurfaceFormat::k_DXT4_5_AS_16_16_16_16
| XenosSurfaceFormat::k_DXT5A => 16,
u => u.bpp() / 8,
}
}
fn bpp(&self) -> usize {
match self {
XenosSurfaceFormat::k_1_REVERSE | XenosSurfaceFormat::k_1 => 1,
XenosSurfaceFormat::k_DXT1
| XenosSurfaceFormat::k_DXT3A
| XenosSurfaceFormat::k_DXT5A
| XenosSurfaceFormat::k_CTX1
| XenosSurfaceFormat::k_DXT1_AS_16_16_16_16
| XenosSurfaceFormat::k_DXT3A_AS_1_1_1_1 => 4,
XenosSurfaceFormat::k_32_AS_8
| XenosSurfaceFormat::k_8
| XenosSurfaceFormat::k_8_A
| XenosSurfaceFormat::k_8_B
| XenosSurfaceFormat::k_8_INTERLACED
| XenosSurfaceFormat::k_32_AS_8_INTERLACED
| XenosSurfaceFormat::k_DXT2_3
| XenosSurfaceFormat::k_DXT4_5
| XenosSurfaceFormat::k_DXN
| XenosSurfaceFormat::k_DXT2_3_AS_16_16_16_16
| XenosSurfaceFormat::k_DXT4_5_AS_16_16_16_16 => 8,
XenosSurfaceFormat::k_1_5_5_5
| XenosSurfaceFormat::k_5_6_5
| XenosSurfaceFormat::k_6_5_5
| XenosSurfaceFormat::k_8_8
| XenosSurfaceFormat::k_Cr_Y1_Cb_Y0_REP
| XenosSurfaceFormat::k_Y1_Cr_Y0_Cb_REP
| XenosSurfaceFormat::k_4_4_4_4
| XenosSurfaceFormat::k_16
| XenosSurfaceFormat::k_16_EXPAND
| XenosSurfaceFormat::k_16_MPEG
| XenosSurfaceFormat::k_32_AS_8_8
| XenosSurfaceFormat::k_32_AS_8_8_INTERLACED
| XenosSurfaceFormat::k_16_INTERLACED
| XenosSurfaceFormat::k_16_MPEG_INTERLACED
| XenosSurfaceFormat::k_16_FLOAT => 16,
XenosSurfaceFormat::k_8_8_8_8
| XenosSurfaceFormat::k_2_10_10_10
| XenosSurfaceFormat::k_8_8_8_8_A
| XenosSurfaceFormat::k_10_11_11
| XenosSurfaceFormat::k_11_11_10
| XenosSurfaceFormat::k_16_16_EDRAM
| XenosSurfaceFormat::k_24_8
| XenosSurfaceFormat::k_24_8_FLOAT
| XenosSurfaceFormat::k_16_16
| XenosSurfaceFormat::k_16_16_EXPAND
| XenosSurfaceFormat::k_16_16_MPEG
| XenosSurfaceFormat::k_16_16_MPEG_INTERLACED
| XenosSurfaceFormat::k_16_16_FLOAT
| XenosSurfaceFormat::k_32
| XenosSurfaceFormat::k_32_FLOAT
| XenosSurfaceFormat::k_8_8_8_8_AS_16_16_16_16
| XenosSurfaceFormat::k_2_10_10_10_AS_16_16_16_16
| XenosSurfaceFormat::k_10_11_11_AS_16_16_16_16
| XenosSurfaceFormat::k_11_11_10_AS_16_16_16_16
| XenosSurfaceFormat::k_8_8_8_8_GAMMA_EDRAM
| XenosSurfaceFormat::k_2_10_10_10_FLOAT_EDRAM => 32,
XenosSurfaceFormat::k_16_16_16_16
| XenosSurfaceFormat::k_16_16_16_16_EDRAM
| XenosSurfaceFormat::k_16_16_16_16_EXPAND
| XenosSurfaceFormat::k_16_16_16_16_FLOAT
| XenosSurfaceFormat::k_32_32
| XenosSurfaceFormat::k_32_32_FLOAT => 64,
XenosSurfaceFormat::k_32_32_32_FLOAT => 96,
XenosSurfaceFormat::k_32_32_32_32 | XenosSurfaceFormat::k_32_32_32_32_FLOAT => 128,
}
}
fn pixel_block_size(&self) -> usize {
match self {
XenosSurfaceFormat::k_DXT1
| XenosSurfaceFormat::k_DXT1_AS_16_16_16_16
| XenosSurfaceFormat::k_DXT2_3
| XenosSurfaceFormat::k_DXT2_3_AS_16_16_16_16
| XenosSurfaceFormat::k_DXT3A
| XenosSurfaceFormat::k_DXT3A_AS_1_1_1_1
| XenosSurfaceFormat::k_DXT4_5
| XenosSurfaceFormat::k_DXT4_5_AS_16_16_16_16
| XenosSurfaceFormat::k_DXT5A => 4,
_ => 1,
}
}
fn is_compressed(&self) -> bool {
matches!(
self,
XenosSurfaceFormat::k_DXT1
| XenosSurfaceFormat::k_DXT1_AS_16_16_16_16
| XenosSurfaceFormat::k_DXT2_3
| XenosSurfaceFormat::k_DXT2_3_AS_16_16_16_16
| XenosSurfaceFormat::k_DXT3A
| XenosSurfaceFormat::k_DXT3A_AS_1_1_1_1
| XenosSurfaceFormat::k_DXT4_5
| XenosSurfaceFormat::k_DXT4_5_AS_16_16_16_16
| XenosSurfaceFormat::k_DXT5A
)
}
fn x360_swap(&self) -> bool {
matches!(
self,
XenosSurfaceFormat::k_DXT1
| XenosSurfaceFormat::k_DXT1_AS_16_16_16_16
| XenosSurfaceFormat::k_DXN
| XenosSurfaceFormat::k_DXT2_3
| XenosSurfaceFormat::k_DXT2_3_AS_16_16_16_16
| XenosSurfaceFormat::k_DXT3A
| XenosSurfaceFormat::k_DXT3A_AS_1_1_1_1
| XenosSurfaceFormat::k_DXT4_5
| XenosSurfaceFormat::k_DXT4_5_AS_16_16_16_16
| XenosSurfaceFormat::k_DXT5A
)
}
}
impl TryFrom<u8> for XenosSurfaceFormat {
type Error = SwizzleError;
fn try_from(value: u8) -> Result<Self, Self::Error> {
Ok(match value {
0..=63 => unsafe { transmute::<u8, XenosSurfaceFormat>(value) },
e => return Err(SwizzleError::FormatOutOfRange(e.into())),
})
}
}
#[allow(non_camel_case_types, dead_code, clippy::upper_case_acronyms)]
#[derive(Debug, Clone, Copy, PartialEq, Hash)]
#[repr(u8)]
pub enum GcmSurfaceFormat {
B8 = 0x81,
A1R5G5B5 = 0x82,
A4R4G4B4 = 0x83,
R5G6B5 = 0x84,
A8R8G8B8 = 0x85,
COMPRESSED_DXT1 = 0x86,
COMPRESSED_DXT23 = 0x87,
COMPRESSED_DXT45 = 0x88,
G8B8 = 0x8B,
COMPRESSED_B8R8_G8R8 = 0x8D,
COMPRESSED_R8B8_R8G8 = 0x8E,
R6G5B5 = 0x8F,
DEPTH24_D8 = 0x90,
DEPTH24_D8_FLOAT = 0x91,
DEPTH16 = 0x92,
DEPTH16_FLOAT = 0x93,
X16 = 0x94,
Y16_X16 = 0x95,
R5G5B5A1 = 0x97,
COMPRESSED_HILO8 = 0x98,
COMPRESSED_HILO_S8 = 0x99,
W16_Z16_Y16_X16_FLOAT = 0x9A,
W32_Z32_Y32_X32_FLOAT = 0x9B,
X32_FLOAT = 0x9C,
D1R5G5B5 = 0x9D,
D8R8G8B8 = 0x9E,
Y16_X16_FLOAT = 0x9F,
}
impl Format for GcmSurfaceFormat {
fn bpp(&self) -> usize {
match self {
GcmSurfaceFormat::B8 => 8,
GcmSurfaceFormat::A1R5G5B5 => 16,
GcmSurfaceFormat::A4R4G4B4 => 16,
GcmSurfaceFormat::R5G6B5 => 16,
GcmSurfaceFormat::A8R8G8B8 => 32,
GcmSurfaceFormat::COMPRESSED_DXT1 => 4,
GcmSurfaceFormat::COMPRESSED_DXT23 | GcmSurfaceFormat::COMPRESSED_DXT45 => 8,
GcmSurfaceFormat::G8B8 => 16,
GcmSurfaceFormat::DEPTH24_D8 => 32,
GcmSurfaceFormat::DEPTH24_D8_FLOAT => 32,
GcmSurfaceFormat::DEPTH16 => 16,
GcmSurfaceFormat::DEPTH16_FLOAT => 16,
GcmSurfaceFormat::X16 => 16,
GcmSurfaceFormat::Y16_X16 => 32,
GcmSurfaceFormat::R5G5B5A1 => 16,
GcmSurfaceFormat::Y16_X16_FLOAT => 32,
u => unimplemented!("Unsupported GCM surface format bpp ({u:?} => ??)"),
}
}
fn block_size(&self) -> usize {
match self {
GcmSurfaceFormat::COMPRESSED_DXT1 => 8,
GcmSurfaceFormat::COMPRESSED_DXT23 | GcmSurfaceFormat::COMPRESSED_DXT45 => 16,
u => u.bpp() / 8,
}
}
fn pixel_block_size(&self) -> usize {
match self {
GcmSurfaceFormat::COMPRESSED_DXT1
| GcmSurfaceFormat::COMPRESSED_DXT23
| GcmSurfaceFormat::COMPRESSED_DXT45 => 4,
_ => 1,
}
}
fn is_compressed(&self) -> bool {
matches!(
self,
GcmSurfaceFormat::COMPRESSED_DXT1
| GcmSurfaceFormat::COMPRESSED_DXT23
| GcmSurfaceFormat::COMPRESSED_DXT45
| GcmSurfaceFormat::COMPRESSED_B8R8_G8R8
| GcmSurfaceFormat::COMPRESSED_R8B8_R8G8
| GcmSurfaceFormat::COMPRESSED_HILO8
| GcmSurfaceFormat::COMPRESSED_HILO_S8
)
}
fn x360_swap(&self) -> bool {
false
}
}
impl TryFrom<u8> for GcmSurfaceFormat {
type Error = SwizzleError;
fn try_from(value: u8) -> Result<Self, Self::Error> {
Ok(match value {
0x81..=0x9F => unsafe { transmute::<u8, GcmSurfaceFormat>(value) },
e => return Err(SwizzleError::FormatOutOfRange(e.into())),
})
}
}