1 use hal;
2
3 use crate::PrivateCapabilities;
4
5 use hal::{
6 format::{Format, Properties, Swizzle},
7 image, pass, pso,
8 pso::{Comparison, StencilOp},
9 IndexType,
10 };
11 use metal::*;
12 use std::num::NonZeroU32;
13
14 impl PrivateCapabilities {
map_format(&self, format: Format) -> Option<MTLPixelFormat>15 pub fn map_format(&self, format: Format) -> Option<MTLPixelFormat> {
16 use self::hal::format::Format as f;
17 use metal::MTLPixelFormat::*;
18 Some(match format {
19 f::R5g6b5Unorm if self.format_b5 => B5G6R5Unorm,
20 f::R5g5b5a1Unorm if self.format_b5 => A1BGR5Unorm,
21 f::A1r5g5b5Unorm if self.format_b5 => BGR5A1Unorm,
22 f::Rgba4Unorm if self.format_b5 => ABGR4Unorm,
23 f::R8Srgb if self.format_min_srgb_channels <= 1 => R8Unorm_sRGB,
24 f::Rg8Srgb if self.format_min_srgb_channels <= 2 => RG8Unorm_sRGB,
25 f::Rgba8Srgb if self.format_min_srgb_channels <= 4 => RGBA8Unorm_sRGB,
26 f::Bgra8Srgb if self.format_min_srgb_channels <= 4 => BGRA8Unorm_sRGB,
27 f::D16Unorm if self.format_depth16unorm => Depth16Unorm,
28 f::D24UnormS8Uint if self.format_depth24_stencil8 => Depth24Unorm_Stencil8,
29 f::D32Sfloat => Depth32Float,
30 f::D32SfloatS8Uint => Depth32Float_Stencil8,
31 f::R8Unorm => R8Unorm,
32 f::R8Snorm => R8Snorm,
33 f::R8Uint => R8Uint,
34 f::R8Sint => R8Sint,
35 f::Rg8Unorm => RG8Unorm,
36 f::Rg8Snorm => RG8Snorm,
37 f::Rg8Uint => RG8Uint,
38 f::Rg8Sint => RG8Sint,
39 f::Rgba8Unorm => RGBA8Unorm,
40 f::Rgba8Snorm => RGBA8Snorm,
41 f::Rgba8Uint => RGBA8Uint,
42 f::Rgba8Sint => RGBA8Sint,
43 f::Bgra8Unorm => BGRA8Unorm,
44 f::R16Unorm => R16Unorm,
45 f::R16Snorm => R16Snorm,
46 f::R16Uint => R16Uint,
47 f::R16Sint => R16Sint,
48 f::R16Sfloat => R16Float,
49 f::Rg16Unorm => RG16Unorm,
50 f::Rg16Snorm => RG16Snorm,
51 f::Rg16Uint => RG16Uint,
52 f::Rg16Sint => RG16Sint,
53 f::Rg16Sfloat => RG16Float,
54 f::Rgba16Unorm => RGBA16Unorm,
55 f::Rgba16Snorm => RGBA16Snorm,
56 f::Rgba16Uint => RGBA16Uint,
57 f::Rgba16Sint => RGBA16Sint,
58 f::Rgba16Sfloat => RGBA16Float,
59 f::A2r10g10b10Unorm => BGR10A2Unorm,
60 f::A2b10g10r10Unorm => RGB10A2Unorm,
61 f::B10g11r11Ufloat => RG11B10Float,
62 f::E5b9g9r9Ufloat => RGB9E5Float,
63 f::R32Uint => R32Uint,
64 f::R32Sint => R32Sint,
65 f::R32Sfloat => R32Float,
66 f::Rg32Uint => RG32Uint,
67 f::Rg32Sint => RG32Sint,
68 f::Rg32Sfloat => RG32Float,
69 f::Rgba32Uint => RGBA32Uint,
70 f::Rgba32Sint => RGBA32Sint,
71 f::Rgba32Sfloat => RGBA32Float,
72 f::Bc1RgbaUnorm if self.format_bc => BC1_RGBA,
73 f::Bc1RgbaSrgb if self.format_bc => BC1_RGBA_sRGB,
74 f::Bc1RgbUnorm if self.format_bc => BC1_RGBA, //TODO?
75 f::Bc1RgbSrgb if self.format_bc => BC1_RGBA_sRGB, //TODO?
76 f::Bc2Unorm if self.format_bc => BC2_RGBA,
77 f::Bc2Srgb if self.format_bc => BC2_RGBA_sRGB,
78 f::Bc3Unorm if self.format_bc => BC3_RGBA,
79 f::Bc3Srgb if self.format_bc => BC3_RGBA_sRGB,
80 f::Bc4Unorm if self.format_bc => BC4_RUnorm,
81 f::Bc4Snorm if self.format_bc => BC4_RSnorm,
82 f::Bc5Unorm if self.format_bc => BC5_RGUnorm,
83 f::Bc5Snorm if self.format_bc => BC5_RGSnorm,
84 f::Bc6hUfloat if self.format_bc => BC6H_RGBUfloat,
85 f::Bc6hSfloat if self.format_bc => BC6H_RGBFloat,
86 f::Bc7Unorm if self.format_bc => BC7_RGBAUnorm,
87 f::Bc7Srgb if self.format_bc => BC7_RGBAUnorm_sRGB,
88 f::EacR11Unorm if self.format_eac_etc => EAC_R11Unorm,
89 f::EacR11Snorm if self.format_eac_etc => EAC_R11Snorm,
90 f::EacR11g11Unorm if self.format_eac_etc => EAC_RG11Unorm,
91 f::EacR11g11Snorm if self.format_eac_etc => EAC_RG11Snorm,
92 f::Etc2R8g8b8Unorm if self.format_eac_etc => ETC2_RGB8,
93 f::Etc2R8g8b8Srgb if self.format_eac_etc => ETC2_RGB8_sRGB,
94 f::Etc2R8g8b8a1Unorm if self.format_eac_etc => ETC2_RGB8A1,
95 f::Etc2R8g8b8a1Srgb if self.format_eac_etc => ETC2_RGB8A1_sRGB,
96 f::Astc4x4Unorm if self.format_astc => ASTC_4x4_LDR,
97 f::Astc4x4Srgb if self.format_astc => ASTC_4x4_sRGB,
98 f::Astc5x4Unorm if self.format_astc => ASTC_5x4_LDR,
99 f::Astc5x4Srgb if self.format_astc => ASTC_5x4_sRGB,
100 f::Astc5x5Unorm if self.format_astc => ASTC_5x5_LDR,
101 f::Astc5x5Srgb if self.format_astc => ASTC_5x5_sRGB,
102 f::Astc6x5Unorm if self.format_astc => ASTC_6x5_LDR,
103 f::Astc6x5Srgb if self.format_astc => ASTC_6x5_sRGB,
104 f::Astc6x6Unorm if self.format_astc => ASTC_6x6_LDR,
105 f::Astc6x6Srgb if self.format_astc => ASTC_6x6_sRGB,
106 f::Astc8x5Unorm if self.format_astc => ASTC_8x5_LDR,
107 f::Astc8x5Srgb if self.format_astc => ASTC_8x5_sRGB,
108 f::Astc8x6Unorm if self.format_astc => ASTC_8x6_LDR,
109 f::Astc8x6Srgb if self.format_astc => ASTC_8x6_sRGB,
110 f::Astc8x8Unorm if self.format_astc => ASTC_8x8_LDR,
111 f::Astc8x8Srgb if self.format_astc => ASTC_8x8_sRGB,
112 f::Astc10x5Unorm if self.format_astc => ASTC_10x5_LDR,
113 f::Astc10x5Srgb if self.format_astc => ASTC_10x5_sRGB,
114 f::Astc10x6Unorm if self.format_astc => ASTC_10x6_LDR,
115 f::Astc10x6Srgb if self.format_astc => ASTC_10x6_sRGB,
116 f::Astc10x8Unorm if self.format_astc => ASTC_10x8_LDR,
117 f::Astc10x8Srgb if self.format_astc => ASTC_10x8_sRGB,
118 f::Astc10x10Unorm if self.format_astc => ASTC_10x10_LDR,
119 f::Astc10x10Srgb if self.format_astc => ASTC_10x10_sRGB,
120 f::Astc12x10Unorm if self.format_astc => ASTC_12x10_LDR,
121 f::Astc12x10Srgb if self.format_astc => ASTC_12x10_sRGB,
122 f::Astc12x12Unorm if self.format_astc => ASTC_12x12_LDR,
123 f::Astc12x12Srgb if self.format_astc => ASTC_12x12_sRGB,
124 // Not supported:
125 // a8Unorm
126 // agbr4Unorm
127 // pvrtc_rgb_2bpp
128 // pvrtc_rgb_2bpp_srgb
129 // pvrtc_rgb_4bpp
130 // pvrtc_rgb_4bpp_srgb
131 // pvrtc_rgba_2bpp
132 // pvrtc_rgba_2bpp_srgb
133 // pvrtc_rgba_4bpp
134 // pvrtc_rgba_4bpp_srgb
135 // eac_rgba8
136 // eac_rgba8_srgb
137 // gbgr422
138 // bgrg422
139 // stencil8 (float-version)
140 // x32_stencil8 (float-version)
141 // x24_stencil8 (float-version)
142 // bgra10_xr
143 // bgra10_xr_srgb
144 // bgr10_xr
145 // bgr10_xr_srgb
146 _ => return None,
147 })
148 }
149
map_format_with_swizzle( &self, format: Format, swizzle: Swizzle, ) -> Option<MTLPixelFormat>150 pub fn map_format_with_swizzle(
151 &self,
152 format: Format,
153 swizzle: Swizzle,
154 ) -> Option<MTLPixelFormat> {
155 use self::hal::format::{Component::*, Format::*};
156 use metal::MTLPixelFormat as Pf;
157 match (format, swizzle) {
158 (R8Unorm, Swizzle(Zero, Zero, Zero, R)) => Some(Pf::A8Unorm),
159 (Rgba8Unorm, Swizzle(B, G, R, A)) => Some(Pf::BGRA8Unorm),
160 (Bgra8Unorm, Swizzle(B, G, R, A)) => Some(Pf::RGBA8Unorm),
161 (Bgra8Srgb, Swizzle(B, G, R, A)) => Some(Pf::RGBA8Unorm_sRGB),
162 (B5g6r5Unorm, Swizzle(B, G, R, A)) if self.format_b5 => Some(Pf::B5G6R5Unorm),
163 _ => {
164 let bits = format.base_format().0.describe_bits();
165 if swizzle != Swizzle::NO && !(bits.alpha == 0 && swizzle == Swizzle(R, G, B, One))
166 {
167 error!("Unsupported swizzle {:?} for format {:?}", swizzle, format);
168 }
169 self.map_format(format)
170 }
171 }
172 }
173
map_format_properties(&self, format: Format) -> Properties174 pub fn map_format_properties(&self, format: Format) -> Properties {
175 use self::hal::format::{BufferFeature as Bf, ImageFeature as If};
176 use metal::MTLPixelFormat::*;
177
178 // Affected formats documented at:
179 // https://developer.apple.com/documentation/metal/mtlreadwritetexturetier/mtlreadwritetexturetier1?language=objc
180 // https://developer.apple.com/documentation/metal/mtlreadwritetexturetier/mtlreadwritetexturetier2?language=objc
181 let (read_write_tier1_if, read_write_tier2_if) = match self.read_write_texture_tier {
182 MTLReadWriteTextureTier::TierNone => (If::empty(), If::empty()),
183 MTLReadWriteTextureTier::Tier1 => (If::STORAGE_READ_WRITE, If::empty()),
184 MTLReadWriteTextureTier::Tier2 => (If::STORAGE_READ_WRITE, If::STORAGE_READ_WRITE),
185 };
186
187 let mtl_format = match self.map_format(format) {
188 Some(mtl_format) => mtl_format,
189 None => {
190 return Properties {
191 buffer_features: if map_vertex_format(format).is_some() {
192 Bf::VERTEX
193 } else {
194 Bf::empty()
195 },
196 optimal_tiling: If::empty(),
197 linear_tiling: If::empty(),
198 }
199 }
200 };
201 let extra_optimal = match mtl_format {
202 A8Unorm => If::SAMPLED_LINEAR,
203 R8Unorm => {
204 read_write_tier2_if
205 | If::SAMPLED_LINEAR
206 | If::STORAGE
207 | If::COLOR_ATTACHMENT
208 | If::COLOR_ATTACHMENT_BLEND
209 }
210 R8Unorm_sRGB if self.format_any8_unorm_srgb_all => {
211 If::SAMPLED_LINEAR | If::STORAGE | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
212 }
213 R8Unorm_sRGB if self.format_any8_unorm_srgb_no_write => {
214 If::SAMPLED_LINEAR | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
215 }
216 R8Snorm if self.format_any8_snorm_all => {
217 If::SAMPLED_LINEAR | If::STORAGE | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
218 }
219 R8Uint => read_write_tier2_if | If::STORAGE | If::COLOR_ATTACHMENT,
220 R8Sint => read_write_tier2_if | If::STORAGE | If::COLOR_ATTACHMENT,
221 R16Unorm if self.format_r16_norm_all => {
222 If::SAMPLED_LINEAR | If::STORAGE | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
223 }
224 R16Snorm if self.format_r16_norm_all => {
225 If::SAMPLED_LINEAR | If::STORAGE | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
226 }
227 R16Uint => read_write_tier2_if | If::STORAGE | If::COLOR_ATTACHMENT,
228 R16Sint => read_write_tier2_if | If::STORAGE | If::COLOR_ATTACHMENT,
229 R16Float => {
230 read_write_tier2_if
231 | If::SAMPLED_LINEAR
232 | If::STORAGE
233 | If::COLOR_ATTACHMENT
234 | If::COLOR_ATTACHMENT_BLEND
235 }
236 RG8Unorm => {
237 If::SAMPLED_LINEAR | If::STORAGE | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
238 }
239 RG8Unorm_sRGB if self.format_any8_unorm_srgb_all => {
240 If::SAMPLED_LINEAR | If::STORAGE | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
241 }
242 RG8Unorm_sRGB if self.format_any8_unorm_srgb_no_write => {
243 If::SAMPLED_LINEAR | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
244 }
245 RG8Snorm if self.format_any8_snorm_all => {
246 If::SAMPLED_LINEAR | If::STORAGE | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
247 }
248 RG8Uint => If::SAMPLED_LINEAR | If::COLOR_ATTACHMENT,
249 RG8Sint => If::SAMPLED_LINEAR | If::COLOR_ATTACHMENT,
250 B5G6R5Unorm if self.format_b5 => {
251 If::SAMPLED_LINEAR | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
252 }
253 A1BGR5Unorm if self.format_b5 => {
254 If::SAMPLED_LINEAR | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
255 }
256 ABGR4Unorm if self.format_b5 => {
257 If::SAMPLED_LINEAR | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
258 }
259 BGR5A1Unorm if self.format_b5 => {
260 If::SAMPLED_LINEAR | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
261 }
262 R32Uint if self.format_r32_all => {
263 read_write_tier1_if | If::STORAGE | If::COLOR_ATTACHMENT
264 }
265 R32Uint if self.format_r32_no_write => If::COLOR_ATTACHMENT,
266 R32Sint if self.format_r32_all => {
267 read_write_tier1_if | If::STORAGE | If::COLOR_ATTACHMENT
268 }
269 R32Sint if self.format_r32_no_write => If::COLOR_ATTACHMENT,
270 R32Float if self.format_r32float_no_write_no_filter => {
271 If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
272 }
273 R32Float if self.format_r32float_no_filter => {
274 If::SAMPLED_LINEAR | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
275 }
276 R32Float if self.format_r32float_all => {
277 read_write_tier1_if
278 | If::SAMPLED_LINEAR
279 | If::STORAGE
280 | If::COLOR_ATTACHMENT
281 | If::COLOR_ATTACHMENT_BLEND
282 }
283 RG16Unorm => {
284 If::SAMPLED_LINEAR | If::STORAGE | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
285 }
286 RG16Snorm => {
287 If::SAMPLED_LINEAR | If::STORAGE | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
288 }
289 RG16Float => {
290 If::SAMPLED_LINEAR | If::STORAGE | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
291 }
292 RGBA8Unorm => {
293 read_write_tier2_if
294 | If::SAMPLED_LINEAR
295 | If::STORAGE
296 | If::COLOR_ATTACHMENT
297 | If::COLOR_ATTACHMENT_BLEND
298 }
299 RGBA8Unorm_sRGB if self.format_rgba8_srgb_no_write => {
300 If::SAMPLED_LINEAR | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
301 }
302 RGBA8Unorm_sRGB if self.format_rgba8_srgb_all => {
303 If::SAMPLED_LINEAR | If::STORAGE | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
304 }
305 RGBA8Snorm => {
306 If::SAMPLED_LINEAR | If::STORAGE | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
307 }
308 RGBA8Uint => read_write_tier2_if | If::STORAGE | If::COLOR_ATTACHMENT,
309 RGBA8Sint => read_write_tier2_if | If::STORAGE | If::COLOR_ATTACHMENT,
310 BGRA8Unorm => {
311 If::SAMPLED_LINEAR | If::STORAGE | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
312 }
313 BGRA8Unorm_sRGB if self.format_rgba8_srgb_no_write => {
314 If::SAMPLED_LINEAR | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
315 }
316 BGRA8Unorm_sRGB if self.format_rgba8_srgb_all => {
317 If::SAMPLED_LINEAR | If::STORAGE | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
318 }
319 RGB10A2Unorm if self.format_rgb10a2_unorm_all => {
320 If::SAMPLED_LINEAR | If::STORAGE | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
321 }
322 RGB10A2Unorm if self.format_rgb10a2_unorm_no_write => {
323 If::SAMPLED_LINEAR | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
324 }
325 RGB10A2Uint if self.format_rgb10a2_uint_color => If::COLOR_ATTACHMENT,
326 RGB10A2Uint if self.format_rgb10a2_uint_color_write => {
327 If::STORAGE | If::COLOR_ATTACHMENT
328 }
329 RG11B10Float if self.format_rg11b10_all => {
330 If::SAMPLED_LINEAR | If::STORAGE | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
331 }
332 RG11B10Float if self.format_rg11b10_no_write => {
333 If::SAMPLED_LINEAR | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
334 }
335 RGB9E5Float if self.format_rgb9e5_all => {
336 If::SAMPLED_LINEAR | If::STORAGE | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
337 }
338 RGB9E5Float if self.format_rgb9e5_filter_only => If::SAMPLED_LINEAR,
339 RGB9E5Float if self.format_rgb9e5_no_write => {
340 If::SAMPLED_LINEAR | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
341 }
342 RG32Uint if self.format_rg32_color => If::COLOR_ATTACHMENT,
343 RG32Sint if self.format_rg32_color => If::COLOR_ATTACHMENT,
344 RG32Uint if self.format_rg32_color_write => If::COLOR_ATTACHMENT | If::STORAGE,
345 RG32Sint if self.format_rg32_color_write => If::COLOR_ATTACHMENT | If::STORAGE,
346 RG32Float if self.format_rg32float_all => {
347 If::SAMPLED_LINEAR | If::STORAGE | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
348 }
349 RG32Float if self.format_rg32float_color_blend => {
350 If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
351 }
352 RG32Float if self.format_rg32float_no_filter => {
353 If::STORAGE | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
354 }
355 RGBA16Unorm => {
356 If::SAMPLED_LINEAR | If::STORAGE | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
357 }
358 RGBA16Snorm => {
359 If::SAMPLED_LINEAR | If::STORAGE | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
360 }
361 RGBA16Uint => read_write_tier2_if | If::STORAGE | If::COLOR_ATTACHMENT,
362 RGBA16Sint => read_write_tier2_if | If::STORAGE | If::COLOR_ATTACHMENT,
363 RGBA16Float => {
364 read_write_tier2_if
365 | If::SAMPLED_LINEAR
366 | If::STORAGE
367 | If::COLOR_ATTACHMENT
368 | If::COLOR_ATTACHMENT_BLEND
369 }
370 RGBA32Uint if self.format_rgba32int_color => If::COLOR_ATTACHMENT,
371 RGBA32Uint if self.format_rgba32int_color_write => {
372 read_write_tier2_if | If::COLOR_ATTACHMENT | If::STORAGE
373 }
374 RGBA32Sint if self.format_rgba32int_color => If::COLOR_ATTACHMENT,
375 RGBA32Sint if self.format_rgba32int_color_write => {
376 read_write_tier2_if | If::COLOR_ATTACHMENT | If::STORAGE
377 }
378 RGBA32Float if self.format_rgba32float_all => {
379 read_write_tier2_if
380 | If::SAMPLED_LINEAR
381 | If::STORAGE
382 | If::COLOR_ATTACHMENT
383 | If::COLOR_ATTACHMENT_BLEND
384 }
385 RGBA32Float if self.format_rgba32float_color => If::COLOR_ATTACHMENT,
386 RGBA32Float if self.format_rgba32float_color_write => {
387 read_write_tier2_if | If::COLOR_ATTACHMENT | If::STORAGE
388 }
389 EAC_R11Unorm if self.format_eac_etc => If::SAMPLED_LINEAR,
390 EAC_R11Snorm if self.format_eac_etc => If::SAMPLED_LINEAR,
391 EAC_RG11Unorm if self.format_eac_etc => If::SAMPLED_LINEAR,
392 EAC_RG11Snorm if self.format_eac_etc => If::SAMPLED_LINEAR,
393 ETC2_RGB8 if self.format_eac_etc => If::SAMPLED_LINEAR,
394 ETC2_RGB8_sRGB if self.format_eac_etc => If::SAMPLED_LINEAR,
395 ETC2_RGB8A1 if self.format_eac_etc => If::SAMPLED_LINEAR,
396 ETC2_RGB8A1_sRGB if self.format_eac_etc => If::SAMPLED_LINEAR,
397 ASTC_4x4_LDR if self.format_astc => If::SAMPLED_LINEAR,
398 ASTC_4x4_sRGB if self.format_astc => If::SAMPLED_LINEAR,
399 ASTC_5x4_LDR if self.format_astc => If::SAMPLED_LINEAR,
400 ASTC_5x4_sRGB if self.format_astc => If::SAMPLED_LINEAR,
401 ASTC_5x5_LDR if self.format_astc => If::SAMPLED_LINEAR,
402 ASTC_5x5_sRGB if self.format_astc => If::SAMPLED_LINEAR,
403 ASTC_6x5_LDR if self.format_astc => If::SAMPLED_LINEAR,
404 ASTC_6x5_sRGB if self.format_astc => If::SAMPLED_LINEAR,
405 ASTC_6x6_LDR if self.format_astc => If::SAMPLED_LINEAR,
406 ASTC_6x6_sRGB if self.format_astc => If::SAMPLED_LINEAR,
407 ASTC_8x5_LDR if self.format_astc => If::SAMPLED_LINEAR,
408 ASTC_8x5_sRGB if self.format_astc => If::SAMPLED_LINEAR,
409 ASTC_8x6_LDR if self.format_astc => If::SAMPLED_LINEAR,
410 ASTC_8x6_sRGB if self.format_astc => If::SAMPLED_LINEAR,
411 ASTC_8x8_LDR if self.format_astc => If::SAMPLED_LINEAR,
412 ASTC_8x8_sRGB if self.format_astc => If::SAMPLED_LINEAR,
413 ASTC_10x5_LDR if self.format_astc => If::SAMPLED_LINEAR,
414 ASTC_10x5_sRGB if self.format_astc => If::SAMPLED_LINEAR,
415 ASTC_10x6_LDR if self.format_astc => If::SAMPLED_LINEAR,
416 ASTC_10x6_sRGB if self.format_astc => If::SAMPLED_LINEAR,
417 ASTC_10x8_LDR if self.format_astc => If::SAMPLED_LINEAR,
418 ASTC_10x8_sRGB if self.format_astc => If::SAMPLED_LINEAR,
419 ASTC_10x10_LDR if self.format_astc => If::SAMPLED_LINEAR,
420 ASTC_10x10_sRGB if self.format_astc => If::SAMPLED_LINEAR,
421 ASTC_12x10_LDR if self.format_astc => If::SAMPLED_LINEAR,
422 ASTC_12x10_sRGB if self.format_astc => If::SAMPLED_LINEAR,
423 ASTC_12x12_LDR if self.format_astc => If::SAMPLED_LINEAR,
424 ASTC_12x12_sRGB if self.format_astc => If::SAMPLED_LINEAR,
425 BC1_RGBA if self.format_bc => If::SAMPLED_LINEAR,
426 BC1_RGBA_sRGB if self.format_bc => If::SAMPLED_LINEAR,
427 BC2_RGBA if self.format_bc => If::SAMPLED_LINEAR,
428 BC2_RGBA_sRGB if self.format_bc => If::SAMPLED_LINEAR,
429 BC3_RGBA if self.format_bc => If::SAMPLED_LINEAR,
430 BC3_RGBA_sRGB if self.format_bc => If::SAMPLED_LINEAR,
431 BC4_RUnorm if self.format_bc => If::SAMPLED_LINEAR,
432 BC4_RSnorm if self.format_bc => If::SAMPLED_LINEAR,
433 BC5_RGUnorm if self.format_bc => If::SAMPLED_LINEAR,
434 BC5_RGSnorm if self.format_bc => If::SAMPLED_LINEAR,
435 BC6H_RGBUfloat if self.format_bc => If::SAMPLED_LINEAR,
436 BC6H_RGBFloat if self.format_bc => If::SAMPLED_LINEAR,
437 BC7_RGBAUnorm if self.format_bc => If::SAMPLED_LINEAR,
438 BC7_RGBAUnorm_sRGB if self.format_bc => If::SAMPLED_LINEAR,
439 Depth16Unorm if self.format_depth16unorm => {
440 If::DEPTH_STENCIL_ATTACHMENT | If::SAMPLED_LINEAR
441 }
442 Depth32Float if self.format_depth32float_filter => {
443 If::DEPTH_STENCIL_ATTACHMENT | If::SAMPLED_LINEAR
444 }
445 Depth32Float if self.format_depth32float_none => If::DEPTH_STENCIL_ATTACHMENT,
446 Stencil8 => If::empty(),
447 Depth24Unorm_Stencil8 if self.format_depth24_stencil8 => If::DEPTH_STENCIL_ATTACHMENT,
448 Depth32Float_Stencil8 if self.format_depth32_stencil8_filter => {
449 If::DEPTH_STENCIL_ATTACHMENT | If::SAMPLED_LINEAR
450 }
451 Depth32Float_Stencil8 if self.format_depth32_stencil8_none => {
452 If::DEPTH_STENCIL_ATTACHMENT
453 }
454 BGR10A2Unorm if self.format_bgr10a2_all => {
455 If::SAMPLED_LINEAR | If::STORAGE | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
456 }
457 BGR10A2Unorm if self.format_bgr10a2_no_write => {
458 If::SAMPLED_LINEAR | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND
459 }
460 _ => If::empty(),
461 };
462
463 Properties {
464 linear_tiling: If::TRANSFER_SRC | If::TRANSFER_DST,
465 optimal_tiling: If::SAMPLED
466 | If::BLIT_SRC
467 | If::BLIT_DST
468 | If::TRANSFER_SRC
469 | If::TRANSFER_DST
470 | extra_optimal,
471 buffer_features: Bf::all(),
472 }
473 }
474 }
475
map_load_operation(operation: pass::AttachmentLoadOp) -> MTLLoadAction476 pub fn map_load_operation(operation: pass::AttachmentLoadOp) -> MTLLoadAction {
477 use self::pass::AttachmentLoadOp::*;
478
479 match operation {
480 Load => MTLLoadAction::Load,
481 Clear => MTLLoadAction::Clear,
482 DontCare => MTLLoadAction::DontCare,
483 }
484 }
485
map_store_operation(operation: pass::AttachmentStoreOp) -> MTLStoreAction486 pub fn map_store_operation(operation: pass::AttachmentStoreOp) -> MTLStoreAction {
487 use self::pass::AttachmentStoreOp::*;
488
489 match operation {
490 Store => MTLStoreAction::Store,
491 DontCare => MTLStoreAction::DontCare,
492 }
493 }
494
map_resolved_store_operation(operation: pass::AttachmentStoreOp) -> MTLStoreAction495 pub fn map_resolved_store_operation(operation: pass::AttachmentStoreOp) -> MTLStoreAction {
496 use self::pass::AttachmentStoreOp::*;
497
498 match operation {
499 Store => MTLStoreAction::StoreAndMultisampleResolve,
500 DontCare => MTLStoreAction::MultisampleResolve,
501 }
502 }
503
map_write_mask(mask: pso::ColorMask) -> MTLColorWriteMask504 pub fn map_write_mask(mask: pso::ColorMask) -> MTLColorWriteMask {
505 let mut mtl_mask = MTLColorWriteMask::empty();
506
507 if mask.contains(pso::ColorMask::RED) {
508 mtl_mask |= MTLColorWriteMask::Red;
509 }
510 if mask.contains(pso::ColorMask::GREEN) {
511 mtl_mask |= MTLColorWriteMask::Green;
512 }
513 if mask.contains(pso::ColorMask::BLUE) {
514 mtl_mask |= MTLColorWriteMask::Blue;
515 }
516 if mask.contains(pso::ColorMask::ALPHA) {
517 mtl_mask |= MTLColorWriteMask::Alpha;
518 }
519
520 mtl_mask
521 }
522
map_factor(factor: pso::Factor) -> MTLBlendFactor523 fn map_factor(factor: pso::Factor) -> MTLBlendFactor {
524 use self::hal::pso::Factor::*;
525
526 match factor {
527 Zero => MTLBlendFactor::Zero,
528 One => MTLBlendFactor::One,
529 SrcColor => MTLBlendFactor::SourceColor,
530 OneMinusSrcColor => MTLBlendFactor::OneMinusSourceColor,
531 DstColor => MTLBlendFactor::DestinationColor,
532 OneMinusDstColor => MTLBlendFactor::OneMinusDestinationColor,
533 SrcAlpha => MTLBlendFactor::SourceAlpha,
534 OneMinusSrcAlpha => MTLBlendFactor::OneMinusSourceAlpha,
535 DstAlpha => MTLBlendFactor::DestinationAlpha,
536 OneMinusDstAlpha => MTLBlendFactor::OneMinusDestinationAlpha,
537 ConstColor => MTLBlendFactor::BlendColor,
538 OneMinusConstColor => MTLBlendFactor::OneMinusBlendColor,
539 ConstAlpha => MTLBlendFactor::BlendAlpha,
540 OneMinusConstAlpha => MTLBlendFactor::OneMinusBlendAlpha,
541 SrcAlphaSaturate => MTLBlendFactor::SourceAlphaSaturated,
542 Src1Color => MTLBlendFactor::Source1Color,
543 OneMinusSrc1Color => MTLBlendFactor::OneMinusSource1Color,
544 Src1Alpha => MTLBlendFactor::Source1Alpha,
545 OneMinusSrc1Alpha => MTLBlendFactor::OneMinusSource1Alpha,
546 }
547 }
548
map_blend_op( operation: pso::BlendOp, ) -> (MTLBlendOperation, MTLBlendFactor, MTLBlendFactor)549 pub fn map_blend_op(
550 operation: pso::BlendOp,
551 ) -> (MTLBlendOperation, MTLBlendFactor, MTLBlendFactor) {
552 use self::hal::pso::BlendOp::*;
553
554 match operation {
555 Add { src, dst } => (MTLBlendOperation::Add, map_factor(src), map_factor(dst)),
556 Sub { src, dst } => (
557 MTLBlendOperation::Subtract,
558 map_factor(src),
559 map_factor(dst),
560 ),
561 RevSub { src, dst } => (
562 MTLBlendOperation::ReverseSubtract,
563 map_factor(src),
564 map_factor(dst),
565 ),
566 Min => (
567 MTLBlendOperation::Min,
568 MTLBlendFactor::Zero,
569 MTLBlendFactor::Zero,
570 ),
571 Max => (
572 MTLBlendOperation::Max,
573 MTLBlendFactor::Zero,
574 MTLBlendFactor::Zero,
575 ),
576 }
577 }
578
map_vertex_format(format: Format) -> Option<MTLVertexFormat>579 pub fn map_vertex_format(format: Format) -> Option<MTLVertexFormat> {
580 use self::hal::format::Format as f;
581 use metal::MTLVertexFormat::*;
582 Some(match format {
583 f::R8Unorm => UCharNormalized,
584 f::R8Snorm => CharNormalized,
585 f::R8Uint => UChar,
586 f::R8Sint => Char,
587 f::Rg8Unorm => UChar2Normalized,
588 f::Rg8Snorm => Char2Normalized,
589 f::Rg8Uint => UChar2,
590 f::Rg8Sint => Char2,
591 f::Rgb8Unorm => UChar3Normalized,
592 f::Rgb8Snorm => Char3Normalized,
593 f::Rgb8Uint => UChar3,
594 f::Rgb8Sint => Char3,
595 f::Rgba8Unorm => UChar4Normalized,
596 f::Rgba8Snorm => Char4Normalized,
597 f::Rgba8Uint => UChar4,
598 f::Rgba8Sint => Char4,
599 f::Bgra8Unorm => UChar4Normalized_BGRA,
600 f::R16Unorm => UShortNormalized,
601 f::R16Snorm => ShortNormalized,
602 f::R16Uint => UShort,
603 f::R16Sint => Short,
604 f::R16Sfloat => Half,
605 f::Rg16Unorm => UShort2Normalized,
606 f::Rg16Snorm => Short2Normalized,
607 f::Rg16Uint => UShort2,
608 f::Rg16Sint => Short2,
609 f::Rg16Sfloat => Half2,
610 f::Rgb16Unorm => UShort3Normalized,
611 f::Rgb16Snorm => Short3Normalized,
612 f::Rgb16Uint => UShort3,
613 f::Rgb16Sint => Short3,
614 f::Rgb16Sfloat => Half3,
615 f::Rgba16Unorm => UShort4Normalized,
616 f::Rgba16Snorm => Short4Normalized,
617 f::Rgba16Uint => UShort4,
618 f::Rgba16Sint => Short4,
619 f::Rgba16Sfloat => Half4,
620 f::R32Uint => UInt,
621 f::R32Sint => Int,
622 f::R32Sfloat => Float,
623 f::Rg32Uint => UInt2,
624 f::Rg32Sint => Int2,
625 f::Rg32Sfloat => Float2,
626 f::Rgb32Uint => UInt3,
627 f::Rgb32Sint => Int3,
628 f::Rgb32Sfloat => Float3,
629 f::Rgba32Uint => UInt4,
630 f::Rgba32Sint => Int4,
631 f::Rgba32Sfloat => Float4,
632 _ => return None,
633 })
634 }
635
resource_options_from_storage_and_cache( storage: MTLStorageMode, cache: MTLCPUCacheMode, ) -> MTLResourceOptions636 pub fn resource_options_from_storage_and_cache(
637 storage: MTLStorageMode,
638 cache: MTLCPUCacheMode,
639 ) -> MTLResourceOptions {
640 MTLResourceOptions::from_bits(
641 ((storage as u64) << MTLResourceStorageModeShift)
642 | ((cache as u64) << MTLResourceCPUCacheModeShift),
643 )
644 .unwrap()
645 }
646
map_texture_usage( usage: image::Usage, tiling: image::Tiling, view_caps: image::ViewCapabilities, ) -> MTLTextureUsage647 pub fn map_texture_usage(
648 usage: image::Usage,
649 tiling: image::Tiling,
650 view_caps: image::ViewCapabilities,
651 ) -> MTLTextureUsage {
652 use self::hal::image::Usage as U;
653
654 let mut texture_usage = MTLTextureUsage::Unknown;
655 // We have to view the texture with a different format
656 // in `clear_image` and `copy_image` destinations.
657 if view_caps.contains(image::ViewCapabilities::MUTABLE_FORMAT)
658 || usage.contains(U::TRANSFER_DST)
659 {
660 texture_usage |= MTLTextureUsage::PixelFormatView;
661 }
662
663 if usage.intersects(U::COLOR_ATTACHMENT | U::DEPTH_STENCIL_ATTACHMENT) {
664 texture_usage |= MTLTextureUsage::RenderTarget;
665 }
666 if usage.intersects(U::SAMPLED | U::INPUT_ATTACHMENT) {
667 texture_usage |= MTLTextureUsage::ShaderRead;
668 }
669 if usage.intersects(U::STORAGE) {
670 texture_usage |= MTLTextureUsage::ShaderRead | MTLTextureUsage::ShaderWrite;
671 }
672
673 // Note: for blitting, we do actual rendering, so we add more flags for TRANSFER_* usage
674 if usage.contains(U::TRANSFER_DST) && tiling == image::Tiling::Optimal {
675 texture_usage |= MTLTextureUsage::RenderTarget;
676 }
677 if usage.contains(U::TRANSFER_SRC) {
678 texture_usage |= MTLTextureUsage::ShaderRead;
679 }
680
681 texture_usage
682 }
683
map_texture_type(view_kind: image::ViewKind) -> MTLTextureType684 pub fn map_texture_type(view_kind: image::ViewKind) -> MTLTextureType {
685 use self::hal::image::ViewKind as Vk;
686 match view_kind {
687 Vk::D1 => MTLTextureType::D1,
688 Vk::D1Array => MTLTextureType::D1Array,
689 Vk::D2 => MTLTextureType::D2,
690 Vk::D2Array => MTLTextureType::D2Array,
691 Vk::D3 => MTLTextureType::D3,
692 Vk::Cube => MTLTextureType::Cube,
693 Vk::CubeArray => MTLTextureType::CubeArray,
694 }
695 }
696
_map_index_type(index_type: IndexType) -> MTLIndexType697 pub fn _map_index_type(index_type: IndexType) -> MTLIndexType {
698 match index_type {
699 IndexType::U16 => MTLIndexType::UInt16,
700 IndexType::U32 => MTLIndexType::UInt32,
701 }
702 }
703
map_compare_function(fun: Comparison) -> MTLCompareFunction704 pub fn map_compare_function(fun: Comparison) -> MTLCompareFunction {
705 match fun {
706 Comparison::Never => MTLCompareFunction::Never,
707 Comparison::Less => MTLCompareFunction::Less,
708 Comparison::LessEqual => MTLCompareFunction::LessEqual,
709 Comparison::Equal => MTLCompareFunction::Equal,
710 Comparison::GreaterEqual => MTLCompareFunction::GreaterEqual,
711 Comparison::Greater => MTLCompareFunction::Greater,
712 Comparison::NotEqual => MTLCompareFunction::NotEqual,
713 Comparison::Always => MTLCompareFunction::Always,
714 }
715 }
716
map_filter(filter: image::Filter) -> MTLSamplerMinMagFilter717 pub fn map_filter(filter: image::Filter) -> MTLSamplerMinMagFilter {
718 match filter {
719 image::Filter::Nearest => MTLSamplerMinMagFilter::Nearest,
720 image::Filter::Linear => MTLSamplerMinMagFilter::Linear,
721 }
722 }
723
map_wrap_mode(wrap: image::WrapMode) -> MTLSamplerAddressMode724 pub fn map_wrap_mode(wrap: image::WrapMode) -> MTLSamplerAddressMode {
725 match wrap {
726 image::WrapMode::Tile => MTLSamplerAddressMode::Repeat,
727 image::WrapMode::Mirror => MTLSamplerAddressMode::MirrorRepeat,
728 image::WrapMode::Clamp => MTLSamplerAddressMode::ClampToEdge,
729 image::WrapMode::Border => MTLSamplerAddressMode::ClampToBorderColor,
730 image::WrapMode::MirrorClamp => MTLSamplerAddressMode::MirrorClampToEdge,
731 }
732 }
733
map_border_color(border_color: image::BorderColor) -> MTLSamplerBorderColor734 pub fn map_border_color(border_color: image::BorderColor) -> MTLSamplerBorderColor {
735 match border_color {
736 image::BorderColor::TransparentBlack => MTLSamplerBorderColor::TransparentBlack,
737 image::BorderColor::OpaqueBlack => MTLSamplerBorderColor::OpaqueBlack,
738 image::BorderColor::OpaqueWhite => MTLSamplerBorderColor::OpaqueWhite,
739 }
740 }
741
map_extent(extent: image::Extent) -> MTLSize742 pub fn map_extent(extent: image::Extent) -> MTLSize {
743 MTLSize {
744 width: extent.width as _,
745 height: extent.height as _,
746 depth: extent.depth as _,
747 }
748 }
749
map_offset(offset: image::Offset) -> MTLOrigin750 pub fn map_offset(offset: image::Offset) -> MTLOrigin {
751 MTLOrigin {
752 x: offset.x as _,
753 y: offset.y as _,
754 z: offset.z as _,
755 }
756 }
757
map_stencil_op(op: StencilOp) -> MTLStencilOperation758 pub fn map_stencil_op(op: StencilOp) -> MTLStencilOperation {
759 match op {
760 StencilOp::Keep => MTLStencilOperation::Keep,
761 StencilOp::Zero => MTLStencilOperation::Zero,
762 StencilOp::Replace => MTLStencilOperation::Replace,
763 StencilOp::IncrementClamp => MTLStencilOperation::IncrementClamp,
764 StencilOp::IncrementWrap => MTLStencilOperation::IncrementWrap,
765 StencilOp::DecrementClamp => MTLStencilOperation::DecrementClamp,
766 StencilOp::DecrementWrap => MTLStencilOperation::DecrementWrap,
767 StencilOp::Invert => MTLStencilOperation::Invert,
768 }
769 }
770
map_winding(face: pso::FrontFace) -> MTLWinding771 pub fn map_winding(face: pso::FrontFace) -> MTLWinding {
772 match face {
773 pso::FrontFace::Clockwise => MTLWinding::Clockwise,
774 pso::FrontFace::CounterClockwise => MTLWinding::CounterClockwise,
775 }
776 }
777
map_polygon_mode(mode: pso::PolygonMode) -> MTLTriangleFillMode778 pub fn map_polygon_mode(mode: pso::PolygonMode) -> MTLTriangleFillMode {
779 match mode {
780 pso::PolygonMode::Point => {
781 warn!("Unable to fill with points");
782 MTLTriangleFillMode::Lines
783 }
784 pso::PolygonMode::Line => MTLTriangleFillMode::Lines,
785 pso::PolygonMode::Fill => MTLTriangleFillMode::Fill,
786 }
787 }
788
map_cull_face(face: pso::Face) -> Option<MTLCullMode>789 pub fn map_cull_face(face: pso::Face) -> Option<MTLCullMode> {
790 match face {
791 pso::Face::NONE => Some(MTLCullMode::None),
792 pso::Face::FRONT => Some(MTLCullMode::Front),
793 pso::Face::BACK => Some(MTLCullMode::Back),
794 _ => None,
795 }
796 }
797
798 #[cfg(feature = "cross")]
map_naga_stage_to_cross(stage: naga::ShaderStage) -> spirv_cross::spirv::ExecutionModel799 pub fn map_naga_stage_to_cross(stage: naga::ShaderStage) -> spirv_cross::spirv::ExecutionModel {
800 use spirv_cross::spirv::ExecutionModel as Em;
801 match stage {
802 naga::ShaderStage::Vertex => Em::Vertex,
803 naga::ShaderStage::Fragment => Em::Fragment,
804 naga::ShaderStage::Compute => Em::GlCompute,
805 }
806 }
807
808 #[cfg(feature = "cross")]
map_sampler_data_to_cross(info: &image::SamplerDesc) -> spirv_cross::msl::SamplerData809 pub fn map_sampler_data_to_cross(info: &image::SamplerDesc) -> spirv_cross::msl::SamplerData {
810 use spirv_cross::msl;
811 fn map_address(wrap: image::WrapMode) -> msl::SamplerAddress {
812 match wrap {
813 image::WrapMode::Tile => msl::SamplerAddress::Repeat,
814 image::WrapMode::Mirror => msl::SamplerAddress::MirroredRepeat,
815 image::WrapMode::Clamp => msl::SamplerAddress::ClampToEdge,
816 image::WrapMode::Border => msl::SamplerAddress::ClampToBorder,
817 image::WrapMode::MirrorClamp => {
818 unimplemented!("https://github.com/grovesNL/spirv_cross/issues/138")
819 }
820 }
821 }
822
823 let lods = info.lod_range.start.0..info.lod_range.end.0;
824 msl::SamplerData {
825 coord: if info.normalized {
826 msl::SamplerCoord::Normalized
827 } else {
828 msl::SamplerCoord::Pixel
829 },
830 min_filter: match info.min_filter {
831 image::Filter::Nearest => msl::SamplerFilter::Nearest,
832 image::Filter::Linear => msl::SamplerFilter::Linear,
833 },
834 mag_filter: match info.mag_filter {
835 image::Filter::Nearest => msl::SamplerFilter::Nearest,
836 image::Filter::Linear => msl::SamplerFilter::Linear,
837 },
838 mip_filter: match info.min_filter {
839 image::Filter::Nearest if info.lod_range.end.0 < 0.5 => msl::SamplerMipFilter::None,
840 image::Filter::Nearest => msl::SamplerMipFilter::Nearest,
841 image::Filter::Linear => msl::SamplerMipFilter::Linear,
842 },
843 s_address: map_address(info.wrap_mode.0),
844 t_address: map_address(info.wrap_mode.1),
845 r_address: map_address(info.wrap_mode.2),
846 compare_func: match info.comparison {
847 Some(func) => unsafe { std::mem::transmute(map_compare_function(func) as u32) },
848 None => msl::SamplerCompareFunc::Always,
849 },
850 border_color: match info.border {
851 image::BorderColor::TransparentBlack => msl::SamplerBorderColor::TransparentBlack,
852 image::BorderColor::OpaqueBlack => msl::SamplerBorderColor::OpaqueBlack,
853 image::BorderColor::OpaqueWhite => msl::SamplerBorderColor::OpaqueWhite,
854 },
855 lod_clamp_min: lods.start.into(),
856 lod_clamp_max: lods.end.into(),
857 max_anisotropy: info.anisotropy_clamp.map_or(0, |aniso| aniso as i32),
858 planes: 0,
859 resolution: msl::FormatResolution::_444,
860 chroma_filter: msl::SamplerFilter::Nearest,
861 x_chroma_offset: msl::ChromaLocation::CositedEven,
862 y_chroma_offset: msl::ChromaLocation::CositedEven,
863 swizzle: [
864 msl::ComponentSwizzle::Identity,
865 msl::ComponentSwizzle::Identity,
866 msl::ComponentSwizzle::Identity,
867 msl::ComponentSwizzle::Identity,
868 ],
869 ycbcr_conversion_enable: false,
870 ycbcr_model: msl::SamplerYCbCrModelConversion::RgbIdentity,
871 ycbcr_range: msl::SamplerYCbCrRange::ItuFull,
872 bpc: 8,
873 }
874 }
875
map_sampler_data_to_naga( info: &image::SamplerDesc, ) -> naga::back::msl::sampler::InlineSampler876 pub fn map_sampler_data_to_naga(
877 info: &image::SamplerDesc,
878 ) -> naga::back::msl::sampler::InlineSampler {
879 use naga::back::msl::sampler as sm;
880 fn map_address(wrap: image::WrapMode) -> sm::Address {
881 match wrap {
882 image::WrapMode::Tile => sm::Address::Repeat,
883 image::WrapMode::Mirror => sm::Address::MirroredRepeat,
884 image::WrapMode::Clamp => sm::Address::ClampToEdge,
885 image::WrapMode::Border => sm::Address::ClampToBorder,
886 image::WrapMode::MirrorClamp => {
887 error!("Unsupported address mode - MirrorClamp");
888 sm::Address::ClampToEdge
889 }
890 }
891 }
892
893 sm::InlineSampler {
894 coord: if info.normalized {
895 sm::Coord::Normalized
896 } else {
897 sm::Coord::Pixel
898 },
899 min_filter: match info.min_filter {
900 image::Filter::Nearest => sm::Filter::Nearest,
901 image::Filter::Linear => sm::Filter::Linear,
902 },
903 mag_filter: match info.mag_filter {
904 image::Filter::Nearest => sm::Filter::Nearest,
905 image::Filter::Linear => sm::Filter::Linear,
906 },
907 mip_filter: match info.min_filter {
908 image::Filter::Nearest if info.lod_range.end.0 < 0.5 => None,
909 image::Filter::Nearest => Some(sm::Filter::Nearest),
910 image::Filter::Linear => Some(sm::Filter::Linear),
911 },
912 address: [
913 map_address(info.wrap_mode.0),
914 map_address(info.wrap_mode.1),
915 map_address(info.wrap_mode.2),
916 ],
917 compare_func: match info.comparison {
918 Some(func) => match func {
919 Comparison::Never => sm::CompareFunc::Never,
920 Comparison::Less => sm::CompareFunc::Less,
921 Comparison::LessEqual => sm::CompareFunc::LessEqual,
922 Comparison::Equal => sm::CompareFunc::Equal,
923 Comparison::GreaterEqual => sm::CompareFunc::GreaterEqual,
924 Comparison::Greater => sm::CompareFunc::Greater,
925 Comparison::NotEqual => sm::CompareFunc::NotEqual,
926 Comparison::Always => sm::CompareFunc::Always,
927 },
928 None => sm::CompareFunc::Never,
929 },
930 border_color: match info.border {
931 image::BorderColor::TransparentBlack => sm::BorderColor::TransparentBlack,
932 image::BorderColor::OpaqueBlack => sm::BorderColor::OpaqueBlack,
933 image::BorderColor::OpaqueWhite => sm::BorderColor::OpaqueWhite,
934 },
935 lod_clamp: if info.lod_range.start.0 > 0.0 || info.lod_range.end.0 < 100.0 {
936 Some(info.lod_range.start.0..info.lod_range.end.0)
937 } else {
938 None
939 },
940 max_anisotropy: info
941 .anisotropy_clamp
942 .and_then(|aniso| NonZeroU32::new(aniso as u32)),
943 }
944 }
945