1 use hal;
2 
3 use crate::PrivateCapabilities;
4 
5 use hal::{
6     format::{Format, Properties, Swizzle},
7     image,
8     pass,
9     pso,
10     pso::{Comparison, StencilOp},
11     IndexType,
12 };
13 use metal::*;
14 
15 impl PrivateCapabilities {
map_format(&self, format: Format) -> Option<MTLPixelFormat>16     pub fn map_format(&self, format: Format) -> Option<MTLPixelFormat> {
17         use self::hal::format::Format as f;
18         use metal::MTLPixelFormat::*;
19         Some(match format {
20             f::R5g6b5Unorm if self.format_b5 => B5G6R5Unorm,
21             f::R5g5b5a1Unorm if self.format_b5 => A1BGR5Unorm,
22             f::A1r5g5b5Unorm if self.format_b5 => BGR5A1Unorm,
23             f::Rgba4Unorm if self.format_b5 => ABGR4Unorm,
24             f::R8Srgb if self.format_min_srgb_channels <= 1 => R8Unorm_sRGB,
25             f::Rg8Srgb if self.format_min_srgb_channels <= 2 => RG8Unorm_sRGB,
26             f::Rgba8Srgb if self.format_min_srgb_channels <= 4 => RGBA8Unorm_sRGB,
27             f::Bgra8Srgb if self.format_min_srgb_channels <= 4 => BGRA8Unorm_sRGB,
28             f::D16Unorm if self.format_depth16unorm => Depth16Unorm,
29             f::D24UnormS8Uint if self.format_depth24_stencil8 => Depth24Unorm_Stencil8,
30             f::D32Sfloat => Depth32Float,
31             f::D32SfloatS8Uint => Depth32Float_Stencil8,
32             f::R8Unorm => R8Unorm,
33             f::R8Snorm => R8Snorm,
34             f::R8Uint => R8Uint,
35             f::R8Sint => R8Sint,
36             f::Rg8Unorm => RG8Unorm,
37             f::Rg8Snorm => RG8Snorm,
38             f::Rg8Uint => RG8Uint,
39             f::Rg8Sint => RG8Sint,
40             f::Rgba8Unorm => RGBA8Unorm,
41             f::Rgba8Snorm => RGBA8Snorm,
42             f::Rgba8Uint => RGBA8Uint,
43             f::Rgba8Sint => RGBA8Sint,
44             f::Bgra8Unorm => BGRA8Unorm,
45             f::R16Unorm => R16Unorm,
46             f::R16Snorm => R16Snorm,
47             f::R16Uint => R16Uint,
48             f::R16Sint => R16Sint,
49             f::R16Sfloat => R16Float,
50             f::Rg16Unorm => RG16Unorm,
51             f::Rg16Snorm => RG16Snorm,
52             f::Rg16Uint => RG16Uint,
53             f::Rg16Sint => RG16Sint,
54             f::Rg16Sfloat => RG16Float,
55             f::Rgba16Unorm => RGBA16Unorm,
56             f::Rgba16Snorm => RGBA16Snorm,
57             f::Rgba16Uint => RGBA16Uint,
58             f::Rgba16Sint => RGBA16Sint,
59             f::Rgba16Sfloat => RGBA16Float,
60             f::A2r10g10b10Unorm => BGR10A2Unorm,
61             f::A2b10g10r10Unorm => RGB10A2Unorm,
62             f::B10g11r11Ufloat => RG11B10Float,
63             f::E5b9g9r9Ufloat => RGB9E5Float,
64             f::R32Uint => R32Uint,
65             f::R32Sint => R32Sint,
66             f::R32Sfloat => R32Float,
67             f::Rg32Uint => RG32Uint,
68             f::Rg32Sint => RG32Sint,
69             f::Rg32Sfloat => RG32Float,
70             f::Rgba32Uint => RGBA32Uint,
71             f::Rgba32Sint => RGBA32Sint,
72             f::Rgba32Sfloat => RGBA32Float,
73             f::Bc1RgbaUnorm if self.format_bc => BC1_RGBA,
74             f::Bc1RgbaSrgb if self.format_bc => BC1_RGBA_sRGB,
75             f::Bc1RgbUnorm if self.format_bc => BC1_RGBA, //TODO?
76             f::Bc1RgbSrgb if self.format_bc => BC1_RGBA_sRGB, //TODO?
77             f::Bc2Unorm if self.format_bc => BC2_RGBA,
78             f::Bc2Srgb if self.format_bc => BC2_RGBA_sRGB,
79             f::Bc3Unorm if self.format_bc => BC3_RGBA,
80             f::Bc3Srgb if self.format_bc => BC3_RGBA_sRGB,
81             f::Bc4Unorm if self.format_bc => BC4_RUnorm,
82             f::Bc4Snorm if self.format_bc => BC4_RSnorm,
83             f::Bc5Unorm if self.format_bc => BC5_RGUnorm,
84             f::Bc5Snorm if self.format_bc => BC5_RGSnorm,
85             f::Bc6hUfloat if self.format_bc => BC6H_RGBUfloat,
86             f::Bc6hSfloat if self.format_bc => BC6H_RGBFloat,
87             f::Bc7Unorm if self.format_bc => BC7_RGBAUnorm,
88             f::Bc7Srgb if self.format_bc => BC7_RGBAUnorm_sRGB,
89             f::EacR11Unorm if self.format_eac_etc => EAC_R11Unorm,
90             f::EacR11Snorm if self.format_eac_etc => EAC_R11Snorm,
91             f::EacR11g11Unorm if self.format_eac_etc => EAC_RG11Unorm,
92             f::EacR11g11Snorm if self.format_eac_etc => EAC_RG11Snorm,
93             f::Etc2R8g8b8Unorm if self.format_eac_etc => ETC2_RGB8,
94             f::Etc2R8g8b8Srgb if self.format_eac_etc => ETC2_RGB8_sRGB,
95             f::Etc2R8g8b8a1Unorm if self.format_eac_etc => ETC2_RGB8A1,
96             f::Etc2R8g8b8a1Srgb if self.format_eac_etc => ETC2_RGB8A1_sRGB,
97             f::Astc4x4Unorm if self.format_astc => ASTC_4x4_LDR,
98             f::Astc4x4Srgb if self.format_astc => ASTC_4x4_sRGB,
99             f::Astc5x4Unorm if self.format_astc => ASTC_5x4_LDR,
100             f::Astc5x4Srgb if self.format_astc => ASTC_5x4_sRGB,
101             f::Astc5x5Unorm if self.format_astc => ASTC_5x5_LDR,
102             f::Astc5x5Srgb if self.format_astc => ASTC_5x5_sRGB,
103             f::Astc6x5Unorm if self.format_astc => ASTC_6x5_LDR,
104             f::Astc6x5Srgb if self.format_astc => ASTC_6x5_sRGB,
105             f::Astc6x6Unorm if self.format_astc => ASTC_6x6_LDR,
106             f::Astc6x6Srgb if self.format_astc => ASTC_6x6_sRGB,
107             f::Astc8x5Unorm if self.format_astc => ASTC_8x5_LDR,
108             f::Astc8x5Srgb if self.format_astc => ASTC_8x5_sRGB,
109             f::Astc8x6Unorm if self.format_astc => ASTC_8x6_LDR,
110             f::Astc8x6Srgb if self.format_astc => ASTC_8x6_sRGB,
111             f::Astc8x8Unorm if self.format_astc => ASTC_8x8_LDR,
112             f::Astc8x8Srgb if self.format_astc => ASTC_8x8_sRGB,
113             f::Astc10x5Unorm if self.format_astc => ASTC_10x5_LDR,
114             f::Astc10x5Srgb if self.format_astc => ASTC_10x5_sRGB,
115             f::Astc10x6Unorm if self.format_astc => ASTC_10x6_LDR,
116             f::Astc10x6Srgb if self.format_astc => ASTC_10x6_sRGB,
117             f::Astc10x8Unorm if self.format_astc => ASTC_10x8_LDR,
118             f::Astc10x8Srgb if self.format_astc => ASTC_10x8_sRGB,
119             f::Astc10x10Unorm if self.format_astc => ASTC_10x10_LDR,
120             f::Astc10x10Srgb if self.format_astc => ASTC_10x10_sRGB,
121             f::Astc12x10Unorm if self.format_astc => ASTC_12x10_LDR,
122             f::Astc12x10Srgb if self.format_astc => ASTC_12x10_sRGB,
123             f::Astc12x12Unorm if self.format_astc => ASTC_12x12_LDR,
124             f::Astc12x12Srgb if self.format_astc => ASTC_12x12_sRGB,
125             // Not supported:
126             // a8Unorm
127             // agbr4Unorm
128             // pvrtc_rgb_2bpp
129             // pvrtc_rgb_2bpp_srgb
130             // pvrtc_rgb_4bpp
131             // pvrtc_rgb_4bpp_srgb
132             // pvrtc_rgba_2bpp
133             // pvrtc_rgba_2bpp_srgb
134             // pvrtc_rgba_4bpp
135             // pvrtc_rgba_4bpp_srgb
136             // eac_rgba8
137             // eac_rgba8_srgb
138             // gbgr422
139             // bgrg422
140             // stencil8 (float-version)
141             // x32_stencil8 (float-version)
142             // x24_stencil8 (float-version)
143             // bgra10_xr
144             // bgra10_xr_srgb
145             // bgr10_xr
146             // bgr10_xr_srgb
147             _ => return None,
148         })
149     }
150 
map_format_with_swizzle( &self, format: Format, swizzle: Swizzle, ) -> Option<MTLPixelFormat>151     pub fn map_format_with_swizzle(
152         &self,
153         format: Format,
154         swizzle: Swizzle,
155     ) -> Option<MTLPixelFormat> {
156         use self::hal::format::{Component::*, Format::*};
157         use metal::MTLPixelFormat as Pf;
158         match (format, swizzle) {
159             (R8Unorm, Swizzle(Zero, Zero, Zero, R)) => Some(Pf::A8Unorm),
160             (Rgba8Unorm, Swizzle(B, G, R, A)) => Some(Pf::BGRA8Unorm),
161             (Bgra8Unorm, Swizzle(B, G, R, A)) => Some(Pf::RGBA8Unorm),
162             (Bgra8Srgb, Swizzle(B, G, R, A)) => Some(Pf::RGBA8Unorm_sRGB),
163             (B5g6r5Unorm, Swizzle(B, G, R, A)) if self.format_b5 => Some(Pf::B5G6R5Unorm),
164             _ => {
165                 let bits = format.base_format().0.describe_bits();
166                 if swizzle != Swizzle::NO && !(bits.alpha == 0 && swizzle == Swizzle(R, G, B, One))
167                 {
168                     error!("Unsupported swizzle {:?} for format {:?}", swizzle, format);
169                 }
170                 self.map_format(format)
171             }
172         }
173     }
174 
map_format_properties(&self, format: Format) -> Properties175     pub fn map_format_properties(&self, format: Format) -> Properties {
176         use self::hal::format::{BufferFeature as Bf, ImageFeature as If};
177         use metal::MTLPixelFormat::*;
178 
179         let buffer_features = Bf::all();
180         let color_if = If::SAMPLED | If::BLIT_SRC | If::BLIT_DST;
181         let compressed_if = color_if | If::SAMPLED_LINEAR;
182         let depth_if = color_if | If::DEPTH_STENCIL_ATTACHMENT;
183 
184         match self.map_format(format) {
185             Some(A8Unorm) => Properties {
186                 optimal_tiling: compressed_if,
187                 buffer_features,
188                 ..Properties::default()
189             },
190             Some(R8Unorm) => Properties {
191                 optimal_tiling: color_if
192                     | If::SAMPLED_LINEAR
193                     | If::STORAGE
194                     | If::COLOR_ATTACHMENT
195                     | If::COLOR_ATTACHMENT_BLEND,
196                 buffer_features,
197                 ..Properties::default()
198             },
199             Some(R8Unorm_sRGB) if self.format_r8unorm_srgb_all => Properties {
200                 optimal_tiling: color_if
201                     | If::SAMPLED_LINEAR
202                     | If::STORAGE
203                     | If::COLOR_ATTACHMENT
204                     | If::COLOR_ATTACHMENT_BLEND,
205                 buffer_features,
206                 ..Properties::default()
207             },
208             Some(R8Unorm_sRGB) if self.format_r8unorm_srgb_no_write => Properties {
209                 optimal_tiling: color_if
210                     | If::SAMPLED_LINEAR
211                     | If::COLOR_ATTACHMENT
212                     | If::COLOR_ATTACHMENT_BLEND,
213                 buffer_features,
214                 ..Properties::default()
215             },
216             Some(R8Snorm) if self.format_r8snorm_all => Properties {
217                 optimal_tiling: color_if
218                     | If::SAMPLED_LINEAR
219                     | If::STORAGE
220                     | If::COLOR_ATTACHMENT
221                     | If::COLOR_ATTACHMENT_BLEND,
222                 buffer_features,
223                 ..Properties::default()
224             },
225             Some(R8Uint) => Properties {
226                 optimal_tiling: color_if | If::STORAGE | If::COLOR_ATTACHMENT,
227                 buffer_features,
228                 ..Properties::default()
229             },
230             Some(R8Sint) => Properties {
231                 optimal_tiling: color_if | If::STORAGE | If::COLOR_ATTACHMENT,
232                 buffer_features,
233                 ..Properties::default()
234             },
235             Some(R16Unorm) if self.format_r16_norm_all => Properties {
236                 optimal_tiling: color_if
237                     | If::SAMPLED_LINEAR
238                     | If::STORAGE
239                     | If::COLOR_ATTACHMENT
240                     | If::COLOR_ATTACHMENT_BLEND,
241                 buffer_features,
242                 ..Properties::default()
243             },
244             Some(R16Snorm) if self.format_r16_norm_all => Properties {
245                 optimal_tiling: color_if
246                     | If::SAMPLED_LINEAR
247                     | If::STORAGE
248                     | If::COLOR_ATTACHMENT
249                     | If::COLOR_ATTACHMENT_BLEND,
250                 buffer_features,
251                 ..Properties::default()
252             },
253             Some(R16Uint) => Properties {
254                 optimal_tiling: color_if | If::STORAGE | If::COLOR_ATTACHMENT,
255                 buffer_features,
256                 ..Properties::default()
257             },
258             Some(R16Sint) => Properties {
259                 optimal_tiling: color_if | If::STORAGE | If::COLOR_ATTACHMENT,
260                 buffer_features,
261                 ..Properties::default()
262             },
263             Some(R16Float) => Properties {
264                 optimal_tiling: color_if
265                     | If::SAMPLED_LINEAR
266                     | If::STORAGE
267                     | If::COLOR_ATTACHMENT
268                     | If::COLOR_ATTACHMENT_BLEND,
269                 buffer_features,
270                 ..Properties::default()
271             },
272             Some(RG8Unorm) => Properties {
273                 optimal_tiling: color_if
274                     | If::SAMPLED_LINEAR
275                     | If::STORAGE
276                     | If::COLOR_ATTACHMENT
277                     | If::COLOR_ATTACHMENT_BLEND,
278                 buffer_features,
279                 ..Properties::default()
280             },
281             Some(RG8Unorm_sRGB) if self.format_rg8unorm_srgb_all => Properties {
282                 optimal_tiling: color_if
283                     | If::SAMPLED_LINEAR
284                     | If::STORAGE
285                     | If::COLOR_ATTACHMENT
286                     | If::COLOR_ATTACHMENT_BLEND,
287                 buffer_features,
288                 ..Properties::default()
289             },
290             Some(RG8Unorm_sRGB) if self.format_rg8unorm_srgb_no_write => Properties {
291                 optimal_tiling: color_if
292                     | If::SAMPLED_LINEAR
293                     | If::COLOR_ATTACHMENT
294                     | If::COLOR_ATTACHMENT_BLEND,
295                 buffer_features,
296                 ..Properties::default()
297             },
298             Some(RG8Snorm) if self.format_rg8snorm_all => Properties {
299                 optimal_tiling: color_if
300                     | If::SAMPLED_LINEAR
301                     | If::STORAGE
302                     | If::COLOR_ATTACHMENT
303                     | If::COLOR_ATTACHMENT_BLEND,
304                 buffer_features,
305                 ..Properties::default()
306             },
307             Some(RG8Uint) => Properties {
308                 optimal_tiling: color_if | If::SAMPLED_LINEAR | If::COLOR_ATTACHMENT,
309                 buffer_features,
310                 ..Properties::default()
311             },
312             Some(RG8Sint) => Properties {
313                 optimal_tiling: color_if | If::SAMPLED_LINEAR | If::COLOR_ATTACHMENT,
314                 buffer_features,
315                 ..Properties::default()
316             },
317             Some(B5G6R5Unorm) if self.format_b5 => Properties {
318                 optimal_tiling: color_if
319                     | If::SAMPLED_LINEAR
320                     | If::COLOR_ATTACHMENT
321                     | If::COLOR_ATTACHMENT_BLEND,
322                 buffer_features,
323                 ..Properties::default()
324             },
325             Some(A1BGR5Unorm) if self.format_b5 => Properties {
326                 optimal_tiling: color_if
327                     | If::SAMPLED_LINEAR
328                     | If::COLOR_ATTACHMENT
329                     | If::COLOR_ATTACHMENT_BLEND,
330                 buffer_features,
331                 ..Properties::default()
332             },
333             Some(ABGR4Unorm) if self.format_b5 => Properties {
334                 optimal_tiling: color_if
335                     | If::SAMPLED_LINEAR
336                     | If::COLOR_ATTACHMENT
337                     | If::COLOR_ATTACHMENT_BLEND,
338                 buffer_features,
339                 ..Properties::default()
340             },
341             Some(BGR5A1Unorm) if self.format_b5 => Properties {
342                 optimal_tiling: color_if
343                     | If::SAMPLED_LINEAR
344                     | If::COLOR_ATTACHMENT
345                     | If::COLOR_ATTACHMENT_BLEND,
346                 buffer_features,
347                 ..Properties::default()
348             },
349             Some(R32Uint) if self.format_r32_all => Properties {
350                 optimal_tiling: color_if | If::STORAGE | If::COLOR_ATTACHMENT,
351                 buffer_features,
352                 ..Properties::default()
353             },
354             Some(R32Uint) if self.format_r32_no_write => Properties {
355                 optimal_tiling: color_if | If::COLOR_ATTACHMENT,
356                 buffer_features,
357                 ..Properties::default()
358             },
359             Some(R32Sint) if self.format_r32_all => Properties {
360                 optimal_tiling: color_if | If::STORAGE | If::COLOR_ATTACHMENT,
361                 buffer_features,
362                 ..Properties::default()
363             },
364             Some(R32Sint) if self.format_r32_no_write => Properties {
365                 optimal_tiling: color_if | If::COLOR_ATTACHMENT,
366                 buffer_features,
367                 ..Properties::default()
368             },
369             Some(R32Float) if self.format_r32float_no_write_no_filter => Properties {
370                 optimal_tiling: color_if | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND,
371                 buffer_features,
372                 ..Properties::default()
373             },
374             Some(R32Float) if self.format_r32float_no_filter => Properties {
375                 optimal_tiling: color_if
376                     | If::SAMPLED_LINEAR
377                     | If::COLOR_ATTACHMENT
378                     | If::COLOR_ATTACHMENT_BLEND,
379                 buffer_features,
380                 ..Properties::default()
381             },
382             Some(R32Float) if self.format_r32float_all => Properties {
383                 optimal_tiling: color_if
384                     | If::SAMPLED_LINEAR
385                     | If::STORAGE
386                     | If::COLOR_ATTACHMENT
387                     | If::COLOR_ATTACHMENT_BLEND,
388                 buffer_features,
389                 ..Properties::default()
390             },
391             Some(RG16Unorm) => Properties {
392                 optimal_tiling: color_if
393                     | If::SAMPLED_LINEAR
394                     | If::STORAGE
395                     | If::COLOR_ATTACHMENT
396                     | If::COLOR_ATTACHMENT_BLEND,
397                 buffer_features,
398                 ..Properties::default()
399             },
400             Some(RG16Snorm) => Properties {
401                 optimal_tiling: color_if
402                     | If::SAMPLED_LINEAR
403                     | If::STORAGE
404                     | If::COLOR_ATTACHMENT
405                     | If::COLOR_ATTACHMENT_BLEND,
406                 buffer_features,
407                 ..Properties::default()
408             },
409             Some(RG16Float) => Properties {
410                 optimal_tiling: color_if
411                     | If::SAMPLED_LINEAR
412                     | If::STORAGE
413                     | If::COLOR_ATTACHMENT
414                     | If::COLOR_ATTACHMENT_BLEND,
415                 buffer_features,
416                 ..Properties::default()
417             },
418             Some(RGBA8Unorm) => Properties {
419                 optimal_tiling: color_if
420                     | If::SAMPLED_LINEAR
421                     | If::STORAGE
422                     | If::COLOR_ATTACHMENT
423                     | If::COLOR_ATTACHMENT_BLEND,
424                 buffer_features,
425                 ..Properties::default()
426             },
427             Some(RGBA8Unorm_sRGB) if self.format_rgba8_srgb_no_write => Properties {
428                 optimal_tiling: color_if
429                     | If::SAMPLED_LINEAR
430                     | If::COLOR_ATTACHMENT
431                     | If::COLOR_ATTACHMENT_BLEND,
432                 buffer_features,
433                 ..Properties::default()
434             },
435             Some(RGBA8Unorm_sRGB) if self.format_rgba8_srgb_all => Properties {
436                 optimal_tiling: color_if
437                     | If::SAMPLED_LINEAR
438                     | If::STORAGE
439                     | If::COLOR_ATTACHMENT
440                     | If::COLOR_ATTACHMENT_BLEND,
441                 buffer_features,
442                 ..Properties::default()
443             },
444             Some(RGBA8Snorm) => Properties {
445                 optimal_tiling: color_if
446                     | If::SAMPLED_LINEAR
447                     | If::STORAGE
448                     | If::COLOR_ATTACHMENT
449                     | If::COLOR_ATTACHMENT_BLEND,
450                 buffer_features,
451                 ..Properties::default()
452             },
453             Some(RGBA8Uint) => Properties {
454                 optimal_tiling: color_if | If::STORAGE | If::COLOR_ATTACHMENT,
455                 buffer_features,
456                 ..Properties::default()
457             },
458             Some(RGBA8Sint) => Properties {
459                 optimal_tiling: color_if | If::STORAGE | If::COLOR_ATTACHMENT,
460                 buffer_features,
461                 ..Properties::default()
462             },
463             Some(BGRA8Unorm) => Properties {
464                 optimal_tiling: color_if
465                     | If::SAMPLED_LINEAR
466                     | If::STORAGE
467                     | If::COLOR_ATTACHMENT
468                     | If::COLOR_ATTACHMENT_BLEND,
469                 buffer_features,
470                 ..Properties::default()
471             },
472             Some(BGRA8Unorm_sRGB) if self.format_rgba8_srgb_no_write => Properties {
473                 optimal_tiling: color_if
474                     | If::SAMPLED_LINEAR
475                     | If::COLOR_ATTACHMENT
476                     | If::COLOR_ATTACHMENT_BLEND,
477                 buffer_features,
478                 ..Properties::default()
479             },
480             Some(BGRA8Unorm_sRGB) if self.format_rgba8_srgb_all => Properties {
481                 optimal_tiling: color_if
482                     | If::SAMPLED_LINEAR
483                     | If::STORAGE
484                     | If::COLOR_ATTACHMENT
485                     | If::COLOR_ATTACHMENT_BLEND,
486                 buffer_features,
487                 ..Properties::default()
488             },
489             Some(RGB10A2Unorm) if self.format_rgb10a2_unorm_all => Properties {
490                 optimal_tiling: color_if
491                     | If::SAMPLED_LINEAR
492                     | If::STORAGE
493                     | If::COLOR_ATTACHMENT
494                     | If::COLOR_ATTACHMENT_BLEND,
495                 buffer_features,
496                 ..Properties::default()
497             },
498             Some(RGB10A2Unorm) if self.format_rgb10a2_unorm_no_write => Properties {
499                 optimal_tiling: color_if
500                     | If::SAMPLED_LINEAR
501                     | If::COLOR_ATTACHMENT
502                     | If::COLOR_ATTACHMENT_BLEND,
503                 buffer_features,
504                 ..Properties::default()
505             },
506             Some(RGB10A2Uint) if self.format_rgb10a2_uint_color => Properties {
507                 optimal_tiling: color_if | If::COLOR_ATTACHMENT,
508                 buffer_features,
509                 ..Properties::default()
510             },
511             Some(RGB10A2Uint) if self.format_rgb10a2_uint_color_write => Properties {
512                 optimal_tiling: color_if | If::STORAGE | If::COLOR_ATTACHMENT,
513                 buffer_features,
514                 ..Properties::default()
515             },
516             Some(RG11B10Float) if self.format_rg11b10_all => Properties {
517                 optimal_tiling: color_if
518                     | If::SAMPLED_LINEAR
519                     | If::STORAGE
520                     | If::COLOR_ATTACHMENT
521                     | If::COLOR_ATTACHMENT_BLEND,
522                 buffer_features,
523                 ..Properties::default()
524             },
525             Some(RG11B10Float) if self.format_rg11b10_no_write => Properties {
526                 optimal_tiling: color_if
527                     | If::SAMPLED_LINEAR
528                     | If::COLOR_ATTACHMENT
529                     | If::COLOR_ATTACHMENT_BLEND,
530                 buffer_features,
531                 ..Properties::default()
532             },
533             Some(RGB9E5Float) if self.format_rgb9e5_all => Properties {
534                 optimal_tiling: color_if
535                     | If::SAMPLED_LINEAR
536                     | If::STORAGE
537                     | If::COLOR_ATTACHMENT
538                     | If::COLOR_ATTACHMENT_BLEND,
539                 buffer_features,
540                 ..Properties::default()
541             },
542             Some(RGB9E5Float) if self.format_rgb9e5_filter_only => Properties {
543                 optimal_tiling: compressed_if,
544                 buffer_features,
545                 ..Properties::default()
546             },
547             Some(RGB9E5Float) if self.format_rgb9e5_no_write => Properties {
548                 optimal_tiling: color_if
549                     | If::SAMPLED_LINEAR
550                     | If::COLOR_ATTACHMENT
551                     | If::COLOR_ATTACHMENT_BLEND,
552                 buffer_features,
553                 ..Properties::default()
554             },
555             Some(RG32Uint) if self.format_rg32_color => Properties {
556                 optimal_tiling: color_if | If::COLOR_ATTACHMENT,
557                 buffer_features,
558                 ..Properties::default()
559             },
560             Some(RG32Sint) if self.format_rg32_color => Properties {
561                 optimal_tiling: color_if | If::COLOR_ATTACHMENT,
562                 buffer_features,
563                 ..Properties::default()
564             },
565             Some(RG32Uint) if self.format_rg32_color_write => Properties {
566                 optimal_tiling: color_if | If::COLOR_ATTACHMENT | If::STORAGE,
567                 buffer_features,
568                 ..Properties::default()
569             },
570             Some(RG32Sint) if self.format_rg32_color_write => Properties {
571                 optimal_tiling: color_if | If::COLOR_ATTACHMENT | If::STORAGE,
572                 buffer_features,
573                 ..Properties::default()
574             },
575             Some(RG32Float) if self.format_rg32float_all => Properties {
576                 optimal_tiling: color_if
577                     | If::SAMPLED_LINEAR
578                     | If::STORAGE
579                     | If::COLOR_ATTACHMENT
580                     | If::COLOR_ATTACHMENT_BLEND,
581                 buffer_features,
582                 ..Properties::default()
583             },
584             Some(RG32Float) if self.format_rg32float_color_blend => Properties {
585                 optimal_tiling: color_if | If::COLOR_ATTACHMENT | If::COLOR_ATTACHMENT_BLEND,
586                 buffer_features,
587                 ..Properties::default()
588             },
589             Some(RG32Float) if self.format_rg32float_no_filter => Properties {
590                 optimal_tiling: color_if
591                     | If::STORAGE
592                     | If::COLOR_ATTACHMENT
593                     | If::COLOR_ATTACHMENT_BLEND,
594                 buffer_features,
595                 ..Properties::default()
596             },
597             Some(RGBA16Unorm) => Properties {
598                 optimal_tiling: color_if
599                     | If::SAMPLED_LINEAR
600                     | If::STORAGE
601                     | If::COLOR_ATTACHMENT
602                     | If::COLOR_ATTACHMENT_BLEND,
603                 buffer_features,
604                 ..Properties::default()
605             },
606             Some(RGBA16Snorm) => Properties {
607                 optimal_tiling: color_if
608                     | If::SAMPLED_LINEAR
609                     | If::STORAGE
610                     | If::COLOR_ATTACHMENT
611                     | If::COLOR_ATTACHMENT_BLEND,
612                 buffer_features,
613                 ..Properties::default()
614             },
615             Some(RGBA16Uint) => Properties {
616                 optimal_tiling: color_if | If::STORAGE | If::COLOR_ATTACHMENT,
617                 buffer_features,
618                 ..Properties::default()
619             },
620             Some(RGBA16Sint) => Properties {
621                 optimal_tiling: color_if | If::STORAGE | If::COLOR_ATTACHMENT,
622                 buffer_features,
623                 ..Properties::default()
624             },
625             Some(RGBA16Float) => Properties {
626                 optimal_tiling: color_if
627                     | If::SAMPLED_LINEAR
628                     | If::STORAGE
629                     | If::COLOR_ATTACHMENT
630                     | If::COLOR_ATTACHMENT_BLEND,
631                 buffer_features,
632                 ..Properties::default()
633             },
634             Some(RGBA32Uint) if self.format_rgba32int_color => Properties {
635                 optimal_tiling: color_if | If::COLOR_ATTACHMENT,
636                 buffer_features,
637                 ..Properties::default()
638             },
639             Some(RGBA32Uint) if self.format_rgba32int_color_write => Properties {
640                 optimal_tiling: color_if | If::COLOR_ATTACHMENT | If::STORAGE,
641                 buffer_features,
642                 ..Properties::default()
643             },
644             Some(RGBA32Sint) if self.format_rgba32int_color => Properties {
645                 optimal_tiling: color_if | If::COLOR_ATTACHMENT,
646                 buffer_features,
647                 ..Properties::default()
648             },
649             Some(RGBA32Sint) if self.format_rgba32int_color_write => Properties {
650                 optimal_tiling: color_if | If::COLOR_ATTACHMENT | If::STORAGE,
651                 buffer_features,
652                 ..Properties::default()
653             },
654             Some(RGBA32Float) if self.format_rgba32float_all => Properties {
655                 optimal_tiling: color_if
656                     | If::SAMPLED_LINEAR
657                     | If::STORAGE
658                     | If::COLOR_ATTACHMENT
659                     | If::COLOR_ATTACHMENT_BLEND,
660                 buffer_features,
661                 ..Properties::default()
662             },
663             Some(RGBA32Float) if self.format_rgba32float_color => Properties {
664                 optimal_tiling: color_if | If::COLOR_ATTACHMENT,
665                 buffer_features,
666                 ..Properties::default()
667             },
668             Some(RGBA32Float) if self.format_rgba32float_color_write => Properties {
669                 optimal_tiling: color_if | If::COLOR_ATTACHMENT | If::STORAGE,
670                 buffer_features,
671                 ..Properties::default()
672             },
673             Some(EAC_R11Unorm) if self.format_eac_etc => Properties {
674                 optimal_tiling: compressed_if,
675                 ..Properties::default()
676             },
677             Some(EAC_R11Snorm) if self.format_eac_etc => Properties {
678                 optimal_tiling: compressed_if,
679                 ..Properties::default()
680             },
681             Some(EAC_RG11Unorm) if self.format_eac_etc => Properties {
682                 optimal_tiling: compressed_if,
683                 ..Properties::default()
684             },
685             Some(EAC_RG11Snorm) if self.format_eac_etc => Properties {
686                 optimal_tiling: compressed_if,
687                 ..Properties::default()
688             },
689             Some(ETC2_RGB8) if self.format_eac_etc => Properties {
690                 optimal_tiling: compressed_if,
691                 ..Properties::default()
692             },
693             Some(ETC2_RGB8_sRGB) if self.format_eac_etc => Properties {
694                 optimal_tiling: compressed_if,
695                 ..Properties::default()
696             },
697             Some(ETC2_RGB8A1) if self.format_eac_etc => Properties {
698                 optimal_tiling: compressed_if,
699                 ..Properties::default()
700             },
701             Some(ETC2_RGB8A1_sRGB) if self.format_eac_etc => Properties {
702                 optimal_tiling: compressed_if,
703                 ..Properties::default()
704             },
705             Some(ASTC_4x4_LDR) if self.format_astc => Properties {
706                 optimal_tiling: compressed_if,
707                 ..Properties::default()
708             },
709             Some(ASTC_4x4_sRGB) if self.format_astc => Properties {
710                 optimal_tiling: compressed_if,
711                 ..Properties::default()
712             },
713             Some(ASTC_5x4_LDR) if self.format_astc => Properties {
714                 optimal_tiling: compressed_if,
715                 ..Properties::default()
716             },
717             Some(ASTC_5x4_sRGB) if self.format_astc => Properties {
718                 optimal_tiling: compressed_if,
719                 ..Properties::default()
720             },
721             Some(ASTC_5x5_LDR) if self.format_astc => Properties {
722                 optimal_tiling: compressed_if,
723                 ..Properties::default()
724             },
725             Some(ASTC_5x5_sRGB) if self.format_astc => Properties {
726                 optimal_tiling: compressed_if,
727                 ..Properties::default()
728             },
729             Some(ASTC_6x5_LDR) if self.format_astc => Properties {
730                 optimal_tiling: compressed_if,
731                 ..Properties::default()
732             },
733             Some(ASTC_6x5_sRGB) if self.format_astc => Properties {
734                 optimal_tiling: compressed_if,
735                 ..Properties::default()
736             },
737             Some(ASTC_6x6_LDR) if self.format_astc => Properties {
738                 optimal_tiling: compressed_if,
739                 ..Properties::default()
740             },
741             Some(ASTC_6x6_sRGB) if self.format_astc => Properties {
742                 optimal_tiling: compressed_if,
743                 ..Properties::default()
744             },
745             Some(ASTC_8x5_LDR) if self.format_astc => Properties {
746                 optimal_tiling: compressed_if,
747                 ..Properties::default()
748             },
749             Some(ASTC_8x5_sRGB) if self.format_astc => Properties {
750                 optimal_tiling: compressed_if,
751                 ..Properties::default()
752             },
753             Some(ASTC_8x6_LDR) if self.format_astc => Properties {
754                 optimal_tiling: compressed_if,
755                 ..Properties::default()
756             },
757             Some(ASTC_8x6_sRGB) if self.format_astc => Properties {
758                 optimal_tiling: compressed_if,
759                 ..Properties::default()
760             },
761             Some(ASTC_8x8_LDR) if self.format_astc => Properties {
762                 optimal_tiling: compressed_if,
763                 ..Properties::default()
764             },
765             Some(ASTC_8x8_sRGB) if self.format_astc => Properties {
766                 optimal_tiling: compressed_if,
767                 ..Properties::default()
768             },
769             Some(ASTC_10x5_LDR) if self.format_astc => Properties {
770                 optimal_tiling: compressed_if,
771                 ..Properties::default()
772             },
773             Some(ASTC_10x5_sRGB) if self.format_astc => Properties {
774                 optimal_tiling: compressed_if,
775                 ..Properties::default()
776             },
777             Some(ASTC_10x6_LDR) if self.format_astc => Properties {
778                 optimal_tiling: compressed_if,
779                 ..Properties::default()
780             },
781             Some(ASTC_10x6_sRGB) if self.format_astc => Properties {
782                 optimal_tiling: compressed_if,
783                 ..Properties::default()
784             },
785             Some(ASTC_10x8_LDR) if self.format_astc => Properties {
786                 optimal_tiling: compressed_if,
787                 ..Properties::default()
788             },
789             Some(ASTC_10x8_sRGB) if self.format_astc => Properties {
790                 optimal_tiling: compressed_if,
791                 ..Properties::default()
792             },
793             Some(ASTC_10x10_LDR) if self.format_astc => Properties {
794                 optimal_tiling: compressed_if,
795                 ..Properties::default()
796             },
797             Some(ASTC_10x10_sRGB) if self.format_astc => Properties {
798                 optimal_tiling: compressed_if,
799                 ..Properties::default()
800             },
801             Some(ASTC_12x10_LDR) if self.format_astc => Properties {
802                 optimal_tiling: compressed_if,
803                 ..Properties::default()
804             },
805             Some(ASTC_12x10_sRGB) if self.format_astc => Properties {
806                 optimal_tiling: compressed_if,
807                 ..Properties::default()
808             },
809             Some(ASTC_12x12_LDR) if self.format_astc => Properties {
810                 optimal_tiling: compressed_if,
811                 ..Properties::default()
812             },
813             Some(ASTC_12x12_sRGB) if self.format_astc => Properties {
814                 optimal_tiling: compressed_if,
815                 ..Properties::default()
816             },
817             Some(BC1_RGBA) if self.format_bc => Properties {
818                 optimal_tiling: compressed_if,
819                 ..Properties::default()
820             },
821             Some(BC1_RGBA_sRGB) if self.format_bc => Properties {
822                 optimal_tiling: compressed_if,
823                 ..Properties::default()
824             },
825             Some(BC2_RGBA) if self.format_bc => Properties {
826                 optimal_tiling: compressed_if,
827                 ..Properties::default()
828             },
829             Some(BC2_RGBA_sRGB) if self.format_bc => Properties {
830                 optimal_tiling: compressed_if,
831                 ..Properties::default()
832             },
833             Some(BC3_RGBA) if self.format_bc => Properties {
834                 optimal_tiling: compressed_if,
835                 ..Properties::default()
836             },
837             Some(BC3_RGBA_sRGB) if self.format_bc => Properties {
838                 optimal_tiling: compressed_if,
839                 ..Properties::default()
840             },
841             Some(BC4_RUnorm) if self.format_bc => Properties {
842                 optimal_tiling: compressed_if,
843                 ..Properties::default()
844             },
845             Some(BC4_RSnorm) if self.format_bc => Properties {
846                 optimal_tiling: compressed_if,
847                 ..Properties::default()
848             },
849             Some(BC5_RGUnorm) if self.format_bc => Properties {
850                 optimal_tiling: compressed_if,
851                 ..Properties::default()
852             },
853             Some(BC5_RGSnorm) if self.format_bc => Properties {
854                 optimal_tiling: compressed_if,
855                 ..Properties::default()
856             },
857             Some(BC6H_RGBUfloat) if self.format_bc => Properties {
858                 optimal_tiling: compressed_if,
859                 ..Properties::default()
860             },
861             Some(BC6H_RGBFloat) if self.format_bc => Properties {
862                 optimal_tiling: compressed_if,
863                 ..Properties::default()
864             },
865             Some(BC7_RGBAUnorm) if self.format_bc => Properties {
866                 optimal_tiling: compressed_if,
867                 ..Properties::default()
868             },
869             Some(BC7_RGBAUnorm_sRGB) if self.format_bc => Properties {
870                 optimal_tiling: compressed_if,
871                 ..Properties::default()
872             },
873             Some(Depth16Unorm) if self.format_depth16unorm => Properties {
874                 optimal_tiling: depth_if | If::SAMPLED_LINEAR,
875                 ..Properties::default()
876             },
877             Some(Depth32Float) if self.format_depth32float_filter => Properties {
878                 optimal_tiling: depth_if | If::SAMPLED_LINEAR,
879                 ..Properties::default()
880             },
881             Some(Depth32Float) if self.format_depth32float_none => Properties {
882                 optimal_tiling: depth_if,
883                 ..Properties::default()
884             },
885             Some(Stencil8) => Properties {
886                 ..Properties::default()
887             },
888             Some(Depth24Unorm_Stencil8) if self.format_depth24_stencil8 => Properties {
889                 optimal_tiling: depth_if,
890                 ..Properties::default()
891             },
892             Some(Depth32Float_Stencil8) if self.format_depth32_stencil8_filter => Properties {
893                 optimal_tiling: depth_if | If::SAMPLED_LINEAR,
894                 ..Properties::default()
895             },
896             Some(Depth32Float_Stencil8) if self.format_depth32_stencil8_none => Properties {
897                 optimal_tiling: depth_if,
898                 ..Properties::default()
899             },
900             Some(BGR10A2Unorm) if self.format_bgr10a2_all => Properties {
901                 optimal_tiling: color_if
902                     | If::SAMPLED_LINEAR
903                     | If::STORAGE
904                     | If::COLOR_ATTACHMENT
905                     | If::COLOR_ATTACHMENT_BLEND,
906                 ..Properties::default()
907             },
908             Some(BGR10A2Unorm) if self.format_bgr10a2_no_write => Properties {
909                 optimal_tiling: color_if
910                     | If::SAMPLED_LINEAR
911                     | If::COLOR_ATTACHMENT
912                     | If::COLOR_ATTACHMENT_BLEND,
913                 ..Properties::default()
914             },
915             _ if map_vertex_format(format).is_some() => Properties {
916                 buffer_features: Bf::VERTEX,
917                 ..Properties::default()
918             },
919             _ => Properties::default(),
920         }
921     }
922 }
923 
map_load_operation(operation: pass::AttachmentLoadOp) -> MTLLoadAction924 pub fn map_load_operation(operation: pass::AttachmentLoadOp) -> MTLLoadAction {
925     use self::pass::AttachmentLoadOp::*;
926 
927     match operation {
928         Load => MTLLoadAction::Load,
929         Clear => MTLLoadAction::Clear,
930         DontCare => MTLLoadAction::DontCare,
931     }
932 }
933 
map_store_operation(operation: pass::AttachmentStoreOp) -> MTLStoreAction934 pub fn map_store_operation(operation: pass::AttachmentStoreOp) -> MTLStoreAction {
935     use self::pass::AttachmentStoreOp::*;
936 
937     match operation {
938         Store => MTLStoreAction::Store,
939         DontCare => MTLStoreAction::DontCare,
940     }
941 }
942 
map_resolved_store_operation(operation: pass::AttachmentStoreOp) -> MTLStoreAction943 pub fn map_resolved_store_operation(operation: pass::AttachmentStoreOp) -> MTLStoreAction {
944     use self::pass::AttachmentStoreOp::*;
945 
946     match operation {
947         Store => MTLStoreAction::StoreAndMultisampleResolve,
948         DontCare => MTLStoreAction::MultisampleResolve,
949     }
950 }
951 
map_write_mask(mask: pso::ColorMask) -> MTLColorWriteMask952 pub fn map_write_mask(mask: pso::ColorMask) -> MTLColorWriteMask {
953     let mut mtl_mask = MTLColorWriteMask::empty();
954 
955     if mask.contains(pso::ColorMask::RED) {
956         mtl_mask |= MTLColorWriteMask::Red;
957     }
958     if mask.contains(pso::ColorMask::GREEN) {
959         mtl_mask |= MTLColorWriteMask::Green;
960     }
961     if mask.contains(pso::ColorMask::BLUE) {
962         mtl_mask |= MTLColorWriteMask::Blue;
963     }
964     if mask.contains(pso::ColorMask::ALPHA) {
965         mtl_mask |= MTLColorWriteMask::Alpha;
966     }
967 
968     mtl_mask
969 }
970 
map_factor(factor: pso::Factor) -> MTLBlendFactor971 fn map_factor(factor: pso::Factor) -> MTLBlendFactor {
972     use self::hal::pso::Factor::*;
973 
974     match factor {
975         Zero => MTLBlendFactor::Zero,
976         One => MTLBlendFactor::One,
977         SrcColor => MTLBlendFactor::SourceColor,
978         OneMinusSrcColor => MTLBlendFactor::OneMinusSourceColor,
979         DstColor => MTLBlendFactor::DestinationColor,
980         OneMinusDstColor => MTLBlendFactor::OneMinusDestinationColor,
981         SrcAlpha => MTLBlendFactor::SourceAlpha,
982         OneMinusSrcAlpha => MTLBlendFactor::OneMinusSourceAlpha,
983         DstAlpha => MTLBlendFactor::DestinationAlpha,
984         OneMinusDstAlpha => MTLBlendFactor::OneMinusDestinationAlpha,
985         ConstColor => MTLBlendFactor::BlendColor,
986         OneMinusConstColor => MTLBlendFactor::OneMinusBlendColor,
987         ConstAlpha => MTLBlendFactor::BlendAlpha,
988         OneMinusConstAlpha => MTLBlendFactor::OneMinusBlendAlpha,
989         SrcAlphaSaturate => MTLBlendFactor::SourceAlphaSaturated,
990         Src1Color => MTLBlendFactor::Source1Color,
991         OneMinusSrc1Color => MTLBlendFactor::OneMinusSource1Color,
992         Src1Alpha => MTLBlendFactor::Source1Alpha,
993         OneMinusSrc1Alpha => MTLBlendFactor::OneMinusSource1Alpha,
994     }
995 }
996 
map_blend_op( operation: pso::BlendOp, ) -> (MTLBlendOperation, MTLBlendFactor, MTLBlendFactor)997 pub fn map_blend_op(
998     operation: pso::BlendOp,
999 ) -> (MTLBlendOperation, MTLBlendFactor, MTLBlendFactor) {
1000     use self::hal::pso::BlendOp::*;
1001 
1002     match operation {
1003         Add { src, dst } => (MTLBlendOperation::Add, map_factor(src), map_factor(dst)),
1004         Sub { src, dst } => (
1005             MTLBlendOperation::Subtract,
1006             map_factor(src),
1007             map_factor(dst),
1008         ),
1009         RevSub { src, dst } => (
1010             MTLBlendOperation::ReverseSubtract,
1011             map_factor(src),
1012             map_factor(dst),
1013         ),
1014         Min => (
1015             MTLBlendOperation::Min,
1016             MTLBlendFactor::Zero,
1017             MTLBlendFactor::Zero,
1018         ),
1019         Max => (
1020             MTLBlendOperation::Max,
1021             MTLBlendFactor::Zero,
1022             MTLBlendFactor::Zero,
1023         ),
1024     }
1025 }
1026 
map_vertex_format(format: Format) -> Option<MTLVertexFormat>1027 pub fn map_vertex_format(format: Format) -> Option<MTLVertexFormat> {
1028     use self::hal::format::Format as f;
1029     use metal::MTLVertexFormat::*;
1030     Some(match format {
1031         f::R8Unorm => UCharNormalized,
1032         f::R8Snorm => CharNormalized,
1033         f::R8Uint => UChar,
1034         f::R8Sint => Char,
1035         f::Rg8Unorm => UChar2Normalized,
1036         f::Rg8Snorm => Char2Normalized,
1037         f::Rg8Uint => UChar2,
1038         f::Rg8Sint => Char2,
1039         f::Rgb8Unorm => UChar3Normalized,
1040         f::Rgb8Snorm => Char3Normalized,
1041         f::Rgb8Uint => UChar3,
1042         f::Rgb8Sint => Char3,
1043         f::Rgba8Unorm => UChar4Normalized,
1044         f::Rgba8Snorm => Char4Normalized,
1045         f::Rgba8Uint => UChar4,
1046         f::Rgba8Sint => Char4,
1047         f::Bgra8Unorm => UChar4Normalized_BGRA,
1048         f::R16Unorm => UShortNormalized,
1049         f::R16Snorm => ShortNormalized,
1050         f::R16Uint => UShort,
1051         f::R16Sint => Short,
1052         f::R16Sfloat => Half,
1053         f::Rg16Unorm => UShort2Normalized,
1054         f::Rg16Snorm => Short2Normalized,
1055         f::Rg16Uint => UShort2,
1056         f::Rg16Sint => Short2,
1057         f::Rg16Sfloat => Half2,
1058         f::Rgb16Unorm => UShort3Normalized,
1059         f::Rgb16Snorm => Short3Normalized,
1060         f::Rgb16Uint => UShort3,
1061         f::Rgb16Sint => Short3,
1062         f::Rgb16Sfloat => Half3,
1063         f::Rgba16Unorm => UShort4Normalized,
1064         f::Rgba16Snorm => Short4Normalized,
1065         f::Rgba16Uint => UShort4,
1066         f::Rgba16Sint => Short4,
1067         f::Rgba16Sfloat => Half4,
1068         f::R32Uint => UInt,
1069         f::R32Sint => Int,
1070         f::R32Sfloat => Float,
1071         f::Rg32Uint => UInt2,
1072         f::Rg32Sint => Int2,
1073         f::Rg32Sfloat => Float2,
1074         f::Rgb32Uint => UInt3,
1075         f::Rgb32Sint => Int3,
1076         f::Rgb32Sfloat => Float3,
1077         f::Rgba32Uint => UInt4,
1078         f::Rgba32Sint => Int4,
1079         f::Rgba32Sfloat => Float4,
1080         _ => return None,
1081     })
1082 }
1083 
resource_options_from_storage_and_cache( storage: MTLStorageMode, cache: MTLCPUCacheMode, ) -> MTLResourceOptions1084 pub fn resource_options_from_storage_and_cache(
1085     storage: MTLStorageMode,
1086     cache: MTLCPUCacheMode,
1087 ) -> MTLResourceOptions {
1088     MTLResourceOptions::from_bits(
1089         ((storage as u64) << MTLResourceStorageModeShift)
1090             | ((cache as u64) << MTLResourceCPUCacheModeShift),
1091     )
1092     .unwrap()
1093 }
1094 
map_texture_usage(usage: image::Usage, tiling: image::Tiling) -> MTLTextureUsage1095 pub fn map_texture_usage(usage: image::Usage, tiling: image::Tiling) -> MTLTextureUsage {
1096     use self::hal::image::Usage as U;
1097 
1098     let mut texture_usage = MTLTextureUsage::PixelFormatView;
1099     if usage.intersects(U::COLOR_ATTACHMENT | U::DEPTH_STENCIL_ATTACHMENT) {
1100         texture_usage |= MTLTextureUsage::RenderTarget;
1101     }
1102     if usage.intersects(U::SAMPLED | U::INPUT_ATTACHMENT) {
1103         texture_usage |= MTLTextureUsage::ShaderRead;
1104     }
1105     if usage.intersects(U::STORAGE) {
1106         texture_usage |= MTLTextureUsage::ShaderRead | MTLTextureUsage::ShaderWrite;
1107     }
1108 
1109     // Note: for blitting, we do actual rendering, so we add more flags for TRANSFER_* usage
1110     if usage.contains(U::TRANSFER_DST) && tiling == image::Tiling::Optimal {
1111         texture_usage |= MTLTextureUsage::RenderTarget;
1112     }
1113     if usage.contains(U::TRANSFER_SRC) {
1114         texture_usage |= MTLTextureUsage::ShaderRead;
1115     }
1116 
1117     texture_usage
1118 }
1119 
map_texture_type(view_kind: image::ViewKind) -> MTLTextureType1120 pub fn map_texture_type(view_kind: image::ViewKind) -> MTLTextureType {
1121     use self::hal::image::ViewKind as Vk;
1122     match view_kind {
1123         Vk::D1 => MTLTextureType::D1,
1124         Vk::D1Array => MTLTextureType::D1Array,
1125         Vk::D2 => MTLTextureType::D2,
1126         Vk::D2Array => MTLTextureType::D2Array,
1127         Vk::D3 => MTLTextureType::D3,
1128         Vk::Cube => MTLTextureType::Cube,
1129         Vk::CubeArray => MTLTextureType::CubeArray,
1130     }
1131 }
1132 
_map_index_type(index_type: IndexType) -> MTLIndexType1133 pub fn _map_index_type(index_type: IndexType) -> MTLIndexType {
1134     match index_type {
1135         IndexType::U16 => MTLIndexType::UInt16,
1136         IndexType::U32 => MTLIndexType::UInt32,
1137     }
1138 }
1139 
map_compare_function(fun: Comparison) -> MTLCompareFunction1140 pub fn map_compare_function(fun: Comparison) -> MTLCompareFunction {
1141     match fun {
1142         Comparison::Never => MTLCompareFunction::Never,
1143         Comparison::Less => MTLCompareFunction::Less,
1144         Comparison::LessEqual => MTLCompareFunction::LessEqual,
1145         Comparison::Equal => MTLCompareFunction::Equal,
1146         Comparison::GreaterEqual => MTLCompareFunction::GreaterEqual,
1147         Comparison::Greater => MTLCompareFunction::Greater,
1148         Comparison::NotEqual => MTLCompareFunction::NotEqual,
1149         Comparison::Always => MTLCompareFunction::Always,
1150     }
1151 }
1152 
map_filter(filter: image::Filter) -> MTLSamplerMinMagFilter1153 pub fn map_filter(filter: image::Filter) -> MTLSamplerMinMagFilter {
1154     match filter {
1155         image::Filter::Nearest => MTLSamplerMinMagFilter::Nearest,
1156         image::Filter::Linear => MTLSamplerMinMagFilter::Linear,
1157     }
1158 }
1159 
map_wrap_mode(wrap: image::WrapMode) -> MTLSamplerAddressMode1160 pub fn map_wrap_mode(wrap: image::WrapMode) -> MTLSamplerAddressMode {
1161     match wrap {
1162         image::WrapMode::Tile => MTLSamplerAddressMode::Repeat,
1163         image::WrapMode::Mirror => MTLSamplerAddressMode::MirrorRepeat,
1164         image::WrapMode::Clamp => MTLSamplerAddressMode::ClampToEdge,
1165         image::WrapMode::Border => MTLSamplerAddressMode::ClampToBorderColor,
1166     }
1167 }
1168 
map_extent(extent: image::Extent) -> MTLSize1169 pub fn map_extent(extent: image::Extent) -> MTLSize {
1170     MTLSize {
1171         width: extent.width as _,
1172         height: extent.height as _,
1173         depth: extent.depth as _,
1174     }
1175 }
1176 
map_offset(offset: image::Offset) -> MTLOrigin1177 pub fn map_offset(offset: image::Offset) -> MTLOrigin {
1178     MTLOrigin {
1179         x: offset.x as _,
1180         y: offset.y as _,
1181         z: offset.z as _,
1182     }
1183 }
1184 
map_stencil_op(op: StencilOp) -> MTLStencilOperation1185 pub fn map_stencil_op(op: StencilOp) -> MTLStencilOperation {
1186     match op {
1187         StencilOp::Keep => MTLStencilOperation::Keep,
1188         StencilOp::Zero => MTLStencilOperation::Zero,
1189         StencilOp::Replace => MTLStencilOperation::Replace,
1190         StencilOp::IncrementClamp => MTLStencilOperation::IncrementClamp,
1191         StencilOp::IncrementWrap => MTLStencilOperation::IncrementWrap,
1192         StencilOp::DecrementClamp => MTLStencilOperation::DecrementClamp,
1193         StencilOp::DecrementWrap => MTLStencilOperation::DecrementWrap,
1194         StencilOp::Invert => MTLStencilOperation::Invert,
1195     }
1196 }
1197 
map_winding(face: pso::FrontFace) -> MTLWinding1198 pub fn map_winding(face: pso::FrontFace) -> MTLWinding {
1199     match face {
1200         pso::FrontFace::Clockwise => MTLWinding::Clockwise,
1201         pso::FrontFace::CounterClockwise => MTLWinding::CounterClockwise,
1202     }
1203 }
1204 
map_polygon_mode(mode: pso::PolygonMode) -> MTLTriangleFillMode1205 pub fn map_polygon_mode(mode: pso::PolygonMode) -> MTLTriangleFillMode {
1206     match mode {
1207         pso::PolygonMode::Point => {
1208             warn!("Unable to fill with points");
1209             MTLTriangleFillMode::Lines
1210         }
1211         pso::PolygonMode::Line(width) => {
1212             match width {
1213                 pso::State::Static(w) if w != 1.0 => {
1214                     warn!("Unsupported line width: {:?}", w);
1215                 }
1216                 _ => {}
1217             }
1218             MTLTriangleFillMode::Lines
1219         }
1220         pso::PolygonMode::Fill => MTLTriangleFillMode::Fill,
1221     }
1222 }
1223 
map_cull_face(face: pso::Face) -> Option<MTLCullMode>1224 pub fn map_cull_face(face: pso::Face) -> Option<MTLCullMode> {
1225     match face {
1226         pso::Face::NONE => Some(MTLCullMode::None),
1227         pso::Face::FRONT => Some(MTLCullMode::Front),
1228         pso::Face::BACK => Some(MTLCullMode::Back),
1229         _ => None,
1230     }
1231 }
1232