1use binrw::{BinRead, BinWrite};
2use bitfield_struct::bitfield;
3use directxtex::{DXGI_FORMAT, TEX_DIMENSION};
4use serde::{Deserialize, Serialize};
5use thiserror::Error;
6
7#[derive(BinRead, BinWrite, Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Default)]
8#[brw(repr = u16)]
9pub enum TextureType
10{
11 Colour = 0,
12 #[default]
13 Normal = 1,
14 Height = 2,
15 CompoundNormal = 3,
16 Billboard = 4,
17 Projection = 6,
18 Emission = 16,
19 Cubemap = 256, UNKNOWN512 = 512, }
26
27#[derive(BinRead, BinWrite, Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Default)]
28#[brw(repr = u8)]
29pub enum InterpretAs
30{
31 Colour = 0,
32 #[default]
33 Normal = 1,
34 Height = 2,
35 CompoundNormal = 3,
36 Billboard = 4,
37 Cubemap = 6,
38 Emission = 16, Volume = 64, }
41
42
43#[derive(BinRead, BinWrite, Serialize, Deserialize, Debug, Copy)]
44#[brw(repr = u16)]
45#[derive(Clone, PartialEq, Hash, Eq)]
46pub enum RenderFormat
47{
48 R16G16B16A16 = 0x0A,
49 R8G8B8A8 = 0x1C,
50 R8G8 = 0x34,
51 A8 = 0x42,
52 BC1 = 0x49,
53 BC2 = 0x4C,
54 BC3 = 0x4F,
55 BC4 = 0x52,
56 BC5 = 0x55,
57 BC7 = 0x5A,
58}
59
60impl RenderFormat {
61 pub fn is_compressed(&self) -> bool {
62 matches!(self, RenderFormat::BC1|
63 RenderFormat::BC2|
64 RenderFormat::BC3|
65 RenderFormat::BC4|
66 RenderFormat::BC5|
67 RenderFormat::BC7)
68 }
69
70 pub fn num_channels(&self) -> usize {
71 match self {
72 RenderFormat::A8 | RenderFormat::BC4 => 1,
73 RenderFormat::R8G8 | RenderFormat::BC5 => 2,
74 RenderFormat::BC1 | RenderFormat::R16G16B16A16 |
76 RenderFormat::R8G8B8A8 |
77 RenderFormat::BC2 |
78 RenderFormat::BC3 |
79 RenderFormat::BC7 => 4,
80 }
81 }
82}
83
84impl From<RenderFormat> for DXGI_FORMAT {
85 fn from(value: RenderFormat) -> Self {
86 match value {
87 RenderFormat::R16G16B16A16 => { DXGI_FORMAT::DXGI_FORMAT_R16G16B16A16_FLOAT } RenderFormat::R8G8B8A8 => { DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM }
89 RenderFormat::R8G8 => { DXGI_FORMAT::DXGI_FORMAT_R8G8_UNORM }
90 RenderFormat::A8 => { DXGI_FORMAT::DXGI_FORMAT_A8_UNORM }
91 RenderFormat::BC1 => { DXGI_FORMAT::DXGI_FORMAT_BC1_UNORM }
92 RenderFormat::BC2 => { DXGI_FORMAT::DXGI_FORMAT_BC2_UNORM }
93 RenderFormat::BC3 => { DXGI_FORMAT::DXGI_FORMAT_BC3_UNORM }
94 RenderFormat::BC4 => { DXGI_FORMAT::DXGI_FORMAT_BC4_UNORM }
95 RenderFormat::BC5 => { DXGI_FORMAT::DXGI_FORMAT_BC5_UNORM }
96 RenderFormat::BC7 => { DXGI_FORMAT::DXGI_FORMAT_BC7_UNORM }
97 }
98 }
99}
100
101#[derive(Debug, Error)]
102#[error("Unsupported DXGI_FORMAT")]
103pub struct UnsupportedFormatError;
104
105impl TryFrom<DXGI_FORMAT> for RenderFormat {
106 type Error = UnsupportedFormatError;
107
108 fn try_from(value: DXGI_FORMAT) -> Result<Self, Self::Error> {
109 match value {
110 DXGI_FORMAT::DXGI_FORMAT_R16G16B16A16_UNORM => Ok(RenderFormat::R16G16B16A16),
111 DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM => Ok(RenderFormat::R8G8B8A8),
112 DXGI_FORMAT::DXGI_FORMAT_R8G8_UNORM => Ok(RenderFormat::R8G8),
113 DXGI_FORMAT::DXGI_FORMAT_A8_UNORM => Ok(RenderFormat::A8),
114 DXGI_FORMAT::DXGI_FORMAT_BC1_UNORM => Ok(RenderFormat::BC1),
115 DXGI_FORMAT::DXGI_FORMAT_BC2_UNORM => Ok(RenderFormat::BC2),
116 DXGI_FORMAT::DXGI_FORMAT_BC3_UNORM => Ok(RenderFormat::BC3),
117 DXGI_FORMAT::DXGI_FORMAT_BC4_UNORM => Ok(RenderFormat::BC4),
118 DXGI_FORMAT::DXGI_FORMAT_BC5_UNORM => Ok(RenderFormat::BC5),
119 DXGI_FORMAT::DXGI_FORMAT_BC7_UNORM => Ok(RenderFormat::BC7),
120 _ => Err(UnsupportedFormatError),
121 }
122 }
123}
124
125#[derive(BinRead, BinWrite, Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Default)]
126#[brw(repr = u8)]
127pub enum Dimensions
128{
129 #[default]
130 _2D = 0,
131 Cube = 1,
132 Volume = 2,
133}
134
135impl From<Dimensions> for TEX_DIMENSION {
136 fn from(val: Dimensions) -> Self {
137 match val {
138 Dimensions::_2D => { TEX_DIMENSION::TEX_DIMENSION_TEXTURE2D }
139 Dimensions::Cube => { TEX_DIMENSION::TEX_DIMENSION_TEXTURE3D }
140 Dimensions::Volume => { TEX_DIMENSION::TEX_DIMENSION_TEXTURE2D }
141 }
142 }
143}
144
145#[bitfield(u32)]
146#[derive(BinRead, BinWrite, Serialize, Deserialize)]
147pub(crate) struct TextureFlagsInner
150{
151 pub(crate) swizzled: bool,
152 pub(crate) deferred: bool, pub(crate) memory_read_xbox_360: bool,
154 pub(crate) unknown1: bool, pub(crate) atlas: bool, pub(crate) ddsc_encoded: bool,
157 pub(crate) unknown3: bool, #[bits(25)]
160 __: u32,
161}
162
163pub struct TextureFlags{
164 pub(crate) inner: TextureFlagsInner
167}
168
169impl TextureFlags{
173
174 pub fn deferred(&self) -> bool { self.inner.deferred() }
175 pub fn unknown1(&self) -> bool { self.inner.unknown1() }
176 pub fn atlas(&self) -> bool { self.inner.atlas() }
177 pub fn unknown3(&self) -> bool { self.inner.unknown3() }
178
179 pub fn set_deferred(&mut self, value: bool) {
180 self.inner.set_deferred(value)
181 }
182 pub fn set_unknown1(&mut self, value: bool) {
183 self.inner.set_unknown1(value)
184 }
185 pub fn set_unknown3(&mut self, value: bool) {
186 self.inner.set_unknown3(value)
187 }
188
189 pub fn set_atlas(&mut self, value: bool) {
190 self.inner.set_atlas(value)
191 }
192 pub fn with_deferred(&self, value: bool) -> Self{
193 Self{
194 inner: self.inner.with_deferred(value)
195 }
196 }
197 pub fn with_unknown1(&mut self, value: bool) -> Self{
198 Self{
199 inner: self.inner.with_unknown1(value)
200 }
201 }
202 pub fn with_atlas(&mut self, value: bool) -> Self{
203 Self{
204 inner: self.inner.with_atlas(value)
205 }
206 }
207 pub fn with_unknown3(&mut self, value: bool) -> Self{
208 Self{
209 inner: self.inner.with_unknown3(value)
210 }
211 }
212
213 #[cfg(feature = "unstable")]
214 pub fn swizzled(&self) -> bool { self.inner.swizzled() }
215
216 #[cfg(feature = "unstable")]
217 pub fn memory_read_xbox_360(&self) -> bool { self.inner.memory_read_xbox_360() }
218
219 #[cfg(feature = "unstable")]
220 pub fn ddsc_encoded(&self) -> bool { self.inner.ddsc_encoded() }
221
222 #[cfg(feature = "unstable")]
223 pub fn set_swizzled(&mut self, value: bool) {
224 self.inner.set_swizzled(value)
225 }
226
227 #[cfg(feature = "unstable")]
228 pub fn set_memory_read_xbox_360(&mut self, value: bool) {
229 self.inner.set_memory_read_xbox_360(value)
230 }
231
232 #[cfg(feature = "unstable")]
233 pub fn set_ddsc_encoded(&mut self, value: bool) {
234 self.inner.set_ddsc_encoded(value)
235 }
236
237 #[cfg(feature = "unstable")]
238 pub fn with_swizzled(&self, value: bool) -> Self {
239 Self {
240 inner: self.inner.with_swizzled(value),
241 }
242 }
243
244 #[cfg(feature = "unstable")]
245 pub fn with_memory_read_xbox_360(&self, value: bool) -> Self {
246 Self {
247 inner: self.inner.with_memory_read_xbox_360(value),
248 }
249 }
250
251 #[cfg(feature = "unstable")]
252 pub fn with_ddsc_encoded(&self, value: bool) -> Self {
253 Self {
254 inner: self.inner.with_ddsc_encoded(value),
255 }
256 }
257}