pebble/graphics/types/
flags.rs1macro_rules! bitflags_mirror {
4 (
5 $(#[$doc:meta])*
6 pub struct $Name:ident => $Wgpu:ty {
7 $(const $Flag:ident = $val:expr;)*
8 }
9 ) => {
10 $(#[$doc])*
11 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
12 pub struct $Name(u32);
13
14 impl $Name {
15 $(pub const $Flag: Self = Self($val);)*
16
17 pub const fn empty() -> Self {
18 Self(0)
19 }
20
21 pub const fn bits(self) -> u32 {
22 self.0
23 }
24
25 pub const fn contains(self, other: Self) -> bool {
26 (self.0 & other.0) == other.0
27 }
28
29 pub const fn intersects(self, other: Self) -> bool {
30 (self.0 & other.0) != 0
31 }
32 }
33
34 impl core::ops::BitOr for $Name {
35 type Output = Self;
36 fn bitor(self, rhs: Self) -> Self {
37 Self(self.0 | rhs.0)
38 }
39 }
40
41 impl core::ops::BitOrAssign for $Name {
42 fn bitor_assign(&mut self, rhs: Self) {
43 self.0 |= rhs.0;
44 }
45 }
46
47 impl From<$Name> for $Wgpu {
48 fn from(value: $Name) -> Self {
49 <$Wgpu>::from_bits_truncate(value.0)
50 }
51 }
52 };
53}
54
55bitflags_mirror! {
56 pub struct ShaderStages => wgpu::ShaderStages {
58 const NONE = 0;
59 const VERTEX = 1 << 0;
60 const FRAGMENT = 1 << 1;
61 const COMPUTE = 1 << 2;
62 const VERTEX_FRAGMENT = (1 << 0) | (1 << 1);
63 const TASK = 1 << 3;
64 const MESH = 1 << 4;
65 const RAY_GENERATION = 1 << 5;
66 const ANY_HIT = 1 << 6;
67 const CLOSEST_HIT = 1 << 7;
68 const MISS = 1 << 8;
69 }
70}
71
72bitflags_mirror! {
73 pub struct BufferUsages => wgpu::BufferUsages {
75 const MAP_READ = 1 << 0;
76 const MAP_WRITE = 1 << 1;
77 const COPY_SRC = 1 << 2;
78 const COPY_DST = 1 << 3;
79 const INDEX = 1 << 4;
80 const VERTEX = 1 << 5;
81 const UNIFORM = 1 << 6;
82 const STORAGE = 1 << 7;
83 const INDIRECT = 1 << 8;
84 const QUERY_RESOLVE = 1 << 9;
85 const BLAS_INPUT = 1 << 10;
86 const TLAS_INPUT = 1 << 11;
87 }
88}
89
90bitflags_mirror! {
91 pub struct TextureUsages => wgpu::TextureUsages {
93 const COPY_SRC = 1 << 0;
94 const COPY_DST = 1 << 1;
95 const TEXTURE_BINDING = 1 << 2;
96 const STORAGE_BINDING = 1 << 3;
97 const RENDER_ATTACHMENT = 1 << 4;
98 const STORAGE_ATOMIC = 1 << 16;
99 const TRANSIENT = 1 << 17;
100 }
101}
102
103bitflags_mirror! {
104 pub struct ColorWrites => wgpu::ColorWrites {
106 const RED = 1 << 0;
107 const GREEN = 1 << 1;
108 const BLUE = 1 << 2;
109 const ALPHA = 1 << 3;
110 const COLOR = (1 << 0) | (1 << 1) | (1 << 2);
111 const ALL = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3);
112 }
113}
114
115impl Default for ColorWrites {
116 fn default() -> Self {
117 Self::ALL
118 }
119}
120
121#[derive(Copy, Clone, PartialEq, Eq, Hash)]
133pub struct DeviceFeatures(u32);
134
135impl DeviceFeatures {
136 pub const ADDRESS_MODE_CLAMP_TO_BORDER: Self = Self(1 << 0);
137 pub const TIMESTAMP_QUERY: Self = Self(1 << 1);
138 pub const PIPELINE_STATISTICS_QUERY: Self = Self(1 << 2);
139 pub const INDIRECT_FIRST_INSTANCE: Self = Self(1 << 3);
140 pub const TEXTURE_COMPRESSION_BC: Self = Self(1 << 4);
141 pub const TEXTURE_COMPRESSION_ETC2: Self = Self(1 << 5);
142 pub const TEXTURE_COMPRESSION_ASTC: Self = Self(1 << 6);
143 pub const POLYGON_MODE_LINE: Self = Self(1 << 7);
144 pub const FLOAT32_FILTERABLE: Self = Self(1 << 8);
145 pub const SHADER_F16: Self = Self(1 << 9);
146 pub const SUBGROUP: Self = Self(1 << 10);
147 pub const RAY_QUERY: Self = Self(1 << 11);
148 pub const MESH_SHADER: Self = Self(1 << 12);
149
150 pub const fn empty() -> Self {
151 Self(0)
152 }
153
154 pub const fn bits(self) -> u32 {
155 self.0
156 }
157
158 pub const fn contains(self, other: Self) -> bool {
159 (self.0 & other.0) == other.0
160 }
161
162 pub const fn intersects(self, other: Self) -> bool {
163 (self.0 & other.0) != 0
164 }
165}
166
167impl core::ops::BitOr for DeviceFeatures {
168 type Output = Self;
169 fn bitor(self, rhs: Self) -> Self {
170 Self(self.0 | rhs.0)
171 }
172}
173
174impl core::ops::BitOrAssign for DeviceFeatures {
175 fn bitor_assign(&mut self, rhs: Self) {
176 self.0 |= rhs.0;
177 }
178}
179
180impl From<DeviceFeatures> for wgpu::Features {
181 fn from(value: DeviceFeatures) -> Self {
182 let mut features = wgpu::Features::empty();
183 let checks: &[(DeviceFeatures, wgpu::Features)] = &[
184 (
185 DeviceFeatures::ADDRESS_MODE_CLAMP_TO_BORDER,
186 wgpu::Features::ADDRESS_MODE_CLAMP_TO_BORDER,
187 ),
188 (DeviceFeatures::TIMESTAMP_QUERY, wgpu::Features::TIMESTAMP_QUERY),
189 (
190 DeviceFeatures::PIPELINE_STATISTICS_QUERY,
191 wgpu::Features::PIPELINE_STATISTICS_QUERY,
192 ),
193 (
194 DeviceFeatures::INDIRECT_FIRST_INSTANCE,
195 wgpu::Features::INDIRECT_FIRST_INSTANCE,
196 ),
197 (
198 DeviceFeatures::TEXTURE_COMPRESSION_BC,
199 wgpu::Features::TEXTURE_COMPRESSION_BC,
200 ),
201 (
202 DeviceFeatures::TEXTURE_COMPRESSION_ETC2,
203 wgpu::Features::TEXTURE_COMPRESSION_ETC2,
204 ),
205 (
206 DeviceFeatures::TEXTURE_COMPRESSION_ASTC,
207 wgpu::Features::TEXTURE_COMPRESSION_ASTC,
208 ),
209 (DeviceFeatures::POLYGON_MODE_LINE, wgpu::Features::POLYGON_MODE_LINE),
210 (DeviceFeatures::FLOAT32_FILTERABLE, wgpu::Features::FLOAT32_FILTERABLE),
211 (DeviceFeatures::SHADER_F16, wgpu::Features::SHADER_F16),
212 (DeviceFeatures::SUBGROUP, wgpu::Features::SUBGROUP),
213 (DeviceFeatures::RAY_QUERY, wgpu::Features::EXPERIMENTAL_RAY_QUERY),
214 (DeviceFeatures::MESH_SHADER, wgpu::Features::EXPERIMENTAL_MESH_SHADER),
215 ];
216 for (flag, wgpu_flag) in checks {
217 if value.contains(*flag) {
218 features |= *wgpu_flag;
219 }
220 }
221 features
222 }
223}
224
225impl From<wgpu::Features> for DeviceFeatures {
226 fn from(value: wgpu::Features) -> Self {
227 let mut result = DeviceFeatures::empty();
228 let checks: &[(wgpu::Features, DeviceFeatures)] = &[
229 (
230 wgpu::Features::ADDRESS_MODE_CLAMP_TO_BORDER,
231 DeviceFeatures::ADDRESS_MODE_CLAMP_TO_BORDER,
232 ),
233 (wgpu::Features::TIMESTAMP_QUERY, DeviceFeatures::TIMESTAMP_QUERY),
234 (
235 wgpu::Features::PIPELINE_STATISTICS_QUERY,
236 DeviceFeatures::PIPELINE_STATISTICS_QUERY,
237 ),
238 (
239 wgpu::Features::INDIRECT_FIRST_INSTANCE,
240 DeviceFeatures::INDIRECT_FIRST_INSTANCE,
241 ),
242 (
243 wgpu::Features::TEXTURE_COMPRESSION_BC,
244 DeviceFeatures::TEXTURE_COMPRESSION_BC,
245 ),
246 (
247 wgpu::Features::TEXTURE_COMPRESSION_ETC2,
248 DeviceFeatures::TEXTURE_COMPRESSION_ETC2,
249 ),
250 (
251 wgpu::Features::TEXTURE_COMPRESSION_ASTC,
252 DeviceFeatures::TEXTURE_COMPRESSION_ASTC,
253 ),
254 (wgpu::Features::POLYGON_MODE_LINE, DeviceFeatures::POLYGON_MODE_LINE),
255 (wgpu::Features::FLOAT32_FILTERABLE, DeviceFeatures::FLOAT32_FILTERABLE),
256 (wgpu::Features::SHADER_F16, DeviceFeatures::SHADER_F16),
257 (wgpu::Features::SUBGROUP, DeviceFeatures::SUBGROUP),
258 (wgpu::Features::EXPERIMENTAL_RAY_QUERY, DeviceFeatures::RAY_QUERY),
259 (wgpu::Features::EXPERIMENTAL_MESH_SHADER, DeviceFeatures::MESH_SHADER),
260 ];
261 for (wgpu_flag, flag) in checks {
262 if value.contains(*wgpu_flag) {
263 result |= *flag;
264 }
265 }
266 result
267 }
268}