@bloomengine/engine 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/native/tvos/metal-patched/Cargo.toml +178 -0
  2. package/native/tvos/metal-patched/LICENSE-APACHE +201 -0
  3. package/native/tvos/metal-patched/LICENSE-MIT +25 -0
  4. package/native/tvos/metal-patched/src/acceleration_structure.rs +667 -0
  5. package/native/tvos/metal-patched/src/acceleration_structure_pass.rs +108 -0
  6. package/native/tvos/metal-patched/src/argument.rs +366 -0
  7. package/native/tvos/metal-patched/src/blitpass.rs +102 -0
  8. package/native/tvos/metal-patched/src/buffer.rs +71 -0
  9. package/native/tvos/metal-patched/src/capturedescriptor.rs +76 -0
  10. package/native/tvos/metal-patched/src/capturemanager.rs +113 -0
  11. package/native/tvos/metal-patched/src/commandbuffer.rs +192 -0
  12. package/native/tvos/metal-patched/src/commandqueue.rs +44 -0
  13. package/native/tvos/metal-patched/src/computepass.rs +107 -0
  14. package/native/tvos/metal-patched/src/constants.rs +152 -0
  15. package/native/tvos/metal-patched/src/counters.rs +119 -0
  16. package/native/tvos/metal-patched/src/depthstencil.rs +190 -0
  17. package/native/tvos/metal-patched/src/device.rs +2134 -0
  18. package/native/tvos/metal-patched/src/drawable.rs +39 -0
  19. package/native/tvos/metal-patched/src/encoder.rs +2041 -0
  20. package/native/tvos/metal-patched/src/heap.rs +281 -0
  21. package/native/tvos/metal-patched/src/indirect_encoder.rs +344 -0
  22. package/native/tvos/metal-patched/src/lib.rs +657 -0
  23. package/native/tvos/metal-patched/src/library.rs +902 -0
  24. package/native/tvos/metal-patched/src/mps.rs +575 -0
  25. package/native/tvos/metal-patched/src/pipeline/compute.rs +475 -0
  26. package/native/tvos/metal-patched/src/pipeline/mod.rs +71 -0
  27. package/native/tvos/metal-patched/src/pipeline/render.rs +762 -0
  28. package/native/tvos/metal-patched/src/renderpass.rs +443 -0
  29. package/native/tvos/metal-patched/src/resource.rs +182 -0
  30. package/native/tvos/metal-patched/src/sampler.rs +165 -0
  31. package/native/tvos/metal-patched/src/sync.rs +178 -0
  32. package/native/tvos/metal-patched/src/texture.rs +352 -0
  33. package/native/tvos/metal-patched/src/types.rs +90 -0
  34. package/native/tvos/metal-patched/src/vertexdescriptor.rs +250 -0
  35. package/package.json +5 -1
@@ -0,0 +1,2134 @@
1
+ // Copyright 2017 GFX developers
2
+ //
3
+ // Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4
+ // http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5
+ // http://opensource.org/licenses/MIT>, at your option. This file may not be
6
+ // copied, modified, or distributed except according to those terms.
7
+
8
+ use super::*;
9
+
10
+ use block::Block;
11
+ use log::warn;
12
+ use objc::runtime::{NO, YES};
13
+
14
+ use std::{ffi::CStr, os::raw::c_char, path::Path, ptr};
15
+
16
+ /// Available on macOS 10.11+, iOS 8.0+, tvOS 9.0+
17
+ ///
18
+ /// See <https://developer.apple.com/documentation/metal/mtlfeatureset>
19
+ #[allow(non_camel_case_types)]
20
+ #[deprecated(
21
+ note = "Since iOS 8.0–16.0 iPadOS 8.0–16.0 macOS 10.11–13.0 Mac Catalyst 13.1–16.0 tvOS 9.0–16.0"
22
+ )]
23
+ #[repr(u64)]
24
+ #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
25
+ pub enum MTLFeatureSet {
26
+ iOS_GPUFamily1_v1 = 0,
27
+ iOS_GPUFamily2_v1 = 1,
28
+ iOS_GPUFamily1_v2 = 2,
29
+ iOS_GPUFamily2_v2 = 3,
30
+ iOS_GPUFamily3_v1 = 4,
31
+ iOS_GPUFamily1_v3 = 5,
32
+ iOS_GPUFamily2_v3 = 6,
33
+ iOS_GPUFamily3_v2 = 7,
34
+ iOS_GPUFamily1_v4 = 8,
35
+ iOS_GPUFamily2_v4 = 9,
36
+ iOS_GPUFamily3_v3 = 10,
37
+ iOS_GPUFamily4_v1 = 11,
38
+ iOS_GPUFamily1_v5 = 12,
39
+ iOS_GPUFamily2_v5 = 13,
40
+ iOS_GPUFamily3_v4 = 14,
41
+ iOS_GPUFamily4_v2 = 15,
42
+ iOS_GPUFamily5_v1 = 16,
43
+
44
+ tvOS_GPUFamily1_v1 = 30000,
45
+ tvOS_GPUFamily1_v2 = 30001,
46
+ tvOS_GPUFamily1_v3 = 30002,
47
+ tvOS_GPUFamily2_v1 = 30003,
48
+ tvOS_GPUFamily1_v4 = 30004,
49
+ tvOS_GPUFamily2_v2 = 30005,
50
+
51
+ macOS_GPUFamily1_v1 = 10000,
52
+ macOS_GPUFamily1_v2 = 10001,
53
+ // Available on macOS 10.12+
54
+ macOS_ReadWriteTextureTier2 = 10002,
55
+ macOS_GPUFamily1_v3 = 10003,
56
+ macOS_GPUFamily1_v4 = 10004,
57
+ macOS_GPUFamily2_v1 = 10005,
58
+ }
59
+
60
+ /// Available on macOS 10.15+, iOS 13.0+
61
+ ///
62
+ /// See <https://developer.apple.com/documentation/metal/mtlgpufamily>
63
+ #[repr(i64)]
64
+ #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
65
+ #[non_exhaustive]
66
+ pub enum MTLGPUFamily {
67
+ Common1 = 3001,
68
+ Common2 = 3002,
69
+ Common3 = 3003,
70
+ Apple1 = 1001,
71
+ Apple2 = 1002,
72
+ Apple3 = 1003,
73
+ Apple4 = 1004,
74
+ Apple5 = 1005,
75
+ Apple6 = 1006,
76
+ Apple7 = 1007,
77
+ Apple8 = 1008,
78
+ Apple9 = 1009,
79
+ Mac1 = 2001,
80
+ Mac2 = 2002,
81
+ MacCatalyst1 = 4001,
82
+ MacCatalyst2 = 4002,
83
+ Metal3 = 5001,
84
+ }
85
+
86
+ /// See <https://developer.apple.com/documentation/metal/mtldevicelocation>
87
+ #[repr(u64)]
88
+ #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
89
+ pub enum MTLDeviceLocation {
90
+ BuiltIn = 0,
91
+ Slot = 1,
92
+ External = 2,
93
+ Unspecified = u64::MAX,
94
+ }
95
+
96
+ bitflags::bitflags! {
97
+ #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
98
+ pub struct PixelFormatCapabilities: u32 {
99
+ const Filter = 1 << 0;
100
+ const Write = 1 << 1;
101
+ const Color = 1 << 2;
102
+ const Blend = 1 << 3;
103
+ const Msaa = 1 << 4;
104
+ const Resolve = 1 << 5;
105
+ }
106
+ }
107
+
108
+ #[allow(non_camel_case_types)]
109
+ #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
110
+ enum OS {
111
+ iOS,
112
+ tvOS,
113
+ macOS,
114
+ }
115
+
116
+ const KB: u32 = 1024;
117
+ const MB: u32 = 1024 * KB;
118
+ const GB: u32 = 1024 * MB;
119
+
120
+ impl MTLFeatureSet {
121
+ fn os(&self) -> OS {
122
+ let value = *self as u64;
123
+ if value < 10_000 {
124
+ OS::iOS
125
+ } else if value < 20_000 {
126
+ OS::macOS
127
+ } else if value >= 30_000 || value < 40_000 {
128
+ OS::tvOS
129
+ } else {
130
+ unreachable!()
131
+ }
132
+ }
133
+
134
+ // returns the minor version on macos
135
+ fn os_version(&self) -> u32 {
136
+ use MTLFeatureSet::*;
137
+ match self {
138
+ iOS_GPUFamily1_v1 | iOS_GPUFamily2_v1 => 8,
139
+ iOS_GPUFamily1_v2 | iOS_GPUFamily2_v2 | iOS_GPUFamily3_v1 => 9,
140
+ iOS_GPUFamily1_v3 | iOS_GPUFamily2_v3 | iOS_GPUFamily3_v2 => 10,
141
+ iOS_GPUFamily1_v4 | iOS_GPUFamily2_v4 | iOS_GPUFamily3_v3 | iOS_GPUFamily4_v1 => 11,
142
+ iOS_GPUFamily1_v5 | iOS_GPUFamily2_v5 | iOS_GPUFamily3_v4 | iOS_GPUFamily4_v2
143
+ | iOS_GPUFamily5_v1 => 12,
144
+ tvOS_GPUFamily1_v1 => 9,
145
+ tvOS_GPUFamily1_v2 => 10,
146
+ tvOS_GPUFamily1_v3 | tvOS_GPUFamily2_v1 => 11,
147
+ tvOS_GPUFamily1_v4 | tvOS_GPUFamily2_v2 => 12,
148
+ macOS_GPUFamily1_v1 => 11,
149
+ macOS_GPUFamily1_v2 | macOS_ReadWriteTextureTier2 => 12,
150
+ macOS_GPUFamily1_v3 => 13,
151
+ macOS_GPUFamily1_v4 | macOS_GPUFamily2_v1 => 14,
152
+ }
153
+ }
154
+
155
+ fn gpu_family(&self) -> u32 {
156
+ use MTLFeatureSet::*;
157
+ match self {
158
+ iOS_GPUFamily1_v1
159
+ | iOS_GPUFamily1_v2
160
+ | iOS_GPUFamily1_v3
161
+ | iOS_GPUFamily1_v4
162
+ | iOS_GPUFamily1_v5
163
+ | tvOS_GPUFamily1_v1
164
+ | tvOS_GPUFamily1_v2
165
+ | tvOS_GPUFamily1_v3
166
+ | tvOS_GPUFamily1_v4
167
+ | macOS_GPUFamily1_v1
168
+ | macOS_GPUFamily1_v2
169
+ | macOS_ReadWriteTextureTier2
170
+ | macOS_GPUFamily1_v3
171
+ | macOS_GPUFamily1_v4 => 1,
172
+ iOS_GPUFamily2_v1 | iOS_GPUFamily2_v2 | iOS_GPUFamily2_v3 | iOS_GPUFamily2_v4
173
+ | iOS_GPUFamily2_v5 | tvOS_GPUFamily2_v1 | tvOS_GPUFamily2_v2 | macOS_GPUFamily2_v1 => {
174
+ 2
175
+ }
176
+ iOS_GPUFamily3_v1 | iOS_GPUFamily3_v2 | iOS_GPUFamily3_v3 | iOS_GPUFamily3_v4 => 3,
177
+ iOS_GPUFamily4_v1 | iOS_GPUFamily4_v2 => 4,
178
+ iOS_GPUFamily5_v1 => 5,
179
+ }
180
+ }
181
+
182
+ fn version(&self) -> u32 {
183
+ use MTLFeatureSet::*;
184
+ match self {
185
+ iOS_GPUFamily1_v1
186
+ | iOS_GPUFamily2_v1
187
+ | iOS_GPUFamily3_v1
188
+ | iOS_GPUFamily4_v1
189
+ | iOS_GPUFamily5_v1
190
+ | macOS_GPUFamily1_v1
191
+ | macOS_GPUFamily2_v1
192
+ | macOS_ReadWriteTextureTier2
193
+ | tvOS_GPUFamily1_v1
194
+ | tvOS_GPUFamily2_v1 => 1,
195
+ iOS_GPUFamily1_v2 | iOS_GPUFamily2_v2 | iOS_GPUFamily3_v2 | iOS_GPUFamily4_v2
196
+ | macOS_GPUFamily1_v2 | tvOS_GPUFamily1_v2 | tvOS_GPUFamily2_v2 => 2,
197
+ iOS_GPUFamily1_v3 | iOS_GPUFamily2_v3 | iOS_GPUFamily3_v3 | macOS_GPUFamily1_v3
198
+ | tvOS_GPUFamily1_v3 => 3,
199
+ iOS_GPUFamily1_v4 | iOS_GPUFamily2_v4 | iOS_GPUFamily3_v4 | tvOS_GPUFamily1_v4
200
+ | macOS_GPUFamily1_v4 => 4,
201
+ iOS_GPUFamily1_v5 | iOS_GPUFamily2_v5 => 5,
202
+ }
203
+ }
204
+
205
+ pub fn supports_metal_kit(&self) -> bool {
206
+ true
207
+ }
208
+
209
+ pub fn supports_metal_performance_shaders(&self) -> bool {
210
+ match self.os() {
211
+ OS::iOS => self.gpu_family() >= 2,
212
+ OS::tvOS => true,
213
+ OS::macOS => self.os_version() >= 13,
214
+ }
215
+ }
216
+
217
+ pub fn supports_programmable_blending(&self) -> bool {
218
+ self.os() != OS::macOS
219
+ }
220
+
221
+ pub fn supports_pvrtc_pixel_formats(&self) -> bool {
222
+ self.os() != OS::macOS
223
+ }
224
+
225
+ pub fn supports_eac_etc_pixel_formats(&self) -> bool {
226
+ self.os() != OS::macOS
227
+ }
228
+
229
+ pub fn supports_astc_pixel_formats(&self) -> bool {
230
+ match self.os() {
231
+ OS::iOS => self.gpu_family() >= 2,
232
+ OS::tvOS => true,
233
+ OS::macOS => false,
234
+ }
235
+ }
236
+
237
+ pub fn supports_linear_textures(&self) -> bool {
238
+ self.os() != OS::macOS || self.os_version() >= 13
239
+ }
240
+
241
+ pub fn supports_bc_pixel_formats(&self) -> bool {
242
+ self.os() == OS::macOS
243
+ }
244
+
245
+ pub fn supports_msaa_depth_resolve(&self) -> bool {
246
+ match self.os() {
247
+ OS::iOS => self.gpu_family() >= 3,
248
+ OS::tvOS => self.gpu_family() >= 2,
249
+ OS::macOS => false,
250
+ }
251
+ }
252
+
253
+ pub fn supports_counting_occlusion_query(&self) -> bool {
254
+ match self.os() {
255
+ OS::iOS => self.gpu_family() >= 3,
256
+ OS::tvOS => self.gpu_family() >= 2,
257
+ OS::macOS => true,
258
+ }
259
+ }
260
+
261
+ pub fn supports_base_vertex_instance_drawing(&self) -> bool {
262
+ match self.os() {
263
+ OS::iOS => self.gpu_family() >= 3,
264
+ OS::tvOS => self.gpu_family() >= 2,
265
+ OS::macOS => true,
266
+ }
267
+ }
268
+
269
+ pub fn supports_indirect_buffers(&self) -> bool {
270
+ match self.os() {
271
+ OS::iOS => self.gpu_family() >= 3,
272
+ OS::tvOS => self.gpu_family() >= 2,
273
+ OS::macOS => true,
274
+ }
275
+ }
276
+
277
+ pub fn supports_cube_map_texture_arrays(&self) -> bool {
278
+ match self.os() {
279
+ OS::iOS => self.gpu_family() >= 4,
280
+ OS::tvOS => false,
281
+ OS::macOS => true,
282
+ }
283
+ }
284
+
285
+ pub fn supports_texture_barriers(&self) -> bool {
286
+ self.os() == OS::macOS
287
+ }
288
+
289
+ pub fn supports_layered_rendering(&self) -> bool {
290
+ match self.os() {
291
+ OS::iOS => self.gpu_family() >= 5,
292
+ OS::tvOS => false,
293
+ OS::macOS => true,
294
+ }
295
+ }
296
+
297
+ pub fn supports_tessellation(&self) -> bool {
298
+ match self.os() {
299
+ OS::iOS => self.gpu_family() >= 3 && self.os_version() >= 10,
300
+ OS::tvOS => self.gpu_family() >= 2,
301
+ OS::macOS => self.os_version() >= 12,
302
+ }
303
+ }
304
+
305
+ pub fn supports_resource_heaps(&self) -> bool {
306
+ match self.os() {
307
+ OS::iOS => self.os_version() >= 10,
308
+ OS::tvOS => self.os_version() >= 10,
309
+ OS::macOS => self.os_version() >= 13,
310
+ }
311
+ }
312
+
313
+ pub fn supports_memoryless_render_targets(&self) -> bool {
314
+ match self.os() {
315
+ OS::iOS => self.os_version() >= 10,
316
+ OS::tvOS => self.os_version() >= 10,
317
+ OS::macOS => false,
318
+ }
319
+ }
320
+
321
+ pub fn supports_function_specialization(&self) -> bool {
322
+ match self.os() {
323
+ OS::iOS => self.os_version() >= 10,
324
+ OS::tvOS => self.os_version() >= 10,
325
+ OS::macOS => self.os_version() >= 12,
326
+ }
327
+ }
328
+
329
+ pub fn supports_function_buffer_read_writes(&self) -> bool {
330
+ match self.os() {
331
+ OS::iOS => self.gpu_family() >= 3 && self.os_version() >= 10,
332
+ OS::tvOS => self.gpu_family() >= 2,
333
+ OS::macOS => self.os_version() >= 12,
334
+ }
335
+ }
336
+
337
+ pub fn supports_function_texture_read_writes(&self) -> bool {
338
+ match self.os() {
339
+ OS::iOS => self.gpu_family() >= 4,
340
+ OS::tvOS => false,
341
+ OS::macOS => self.os_version() >= 12,
342
+ }
343
+ }
344
+
345
+ pub fn supports_array_of_textures(&self) -> bool {
346
+ match self.os() {
347
+ OS::iOS => self.gpu_family() >= 3 && self.os_version() >= 10,
348
+ OS::tvOS => self.gpu_family() >= 2,
349
+ OS::macOS => self.os_version() >= 13,
350
+ }
351
+ }
352
+
353
+ pub fn supports_array_of_samplers(&self) -> bool {
354
+ match self.os() {
355
+ OS::iOS => self.gpu_family() >= 3 && self.os_version() >= 11,
356
+ OS::tvOS => self.gpu_family() >= 2,
357
+ OS::macOS => self.os_version() >= 12,
358
+ }
359
+ }
360
+
361
+ pub fn supports_stencil_texture_views(&self) -> bool {
362
+ match self.os() {
363
+ OS::iOS => self.os_version() >= 10,
364
+ OS::tvOS => self.os_version() >= 10,
365
+ OS::macOS => self.os_version() >= 12,
366
+ }
367
+ }
368
+
369
+ pub fn supports_depth_16_pixel_format(&self) -> bool {
370
+ self.os() == OS::macOS && self.os_version() >= 12
371
+ }
372
+
373
+ pub fn supports_extended_range_pixel_formats(&self) -> bool {
374
+ match self.os() {
375
+ OS::iOS => self.gpu_family() >= 3 && self.os_version() >= 10,
376
+ OS::tvOS => self.gpu_family() >= 2,
377
+ OS::macOS => false,
378
+ }
379
+ }
380
+
381
+ pub fn supports_wide_color_pixel_format(&self) -> bool {
382
+ match self.os() {
383
+ OS::iOS => self.os_version() >= 11,
384
+ OS::tvOS => self.os_version() >= 11,
385
+ OS::macOS => self.os_version() >= 13,
386
+ }
387
+ }
388
+
389
+ pub fn supports_combined_msaa_store_and_resolve_action(&self) -> bool {
390
+ match self.os() {
391
+ OS::iOS => self.gpu_family() >= 3 && self.os_version() >= 10,
392
+ OS::tvOS => self.gpu_family() >= 2,
393
+ OS::macOS => self.os_version() >= 12,
394
+ }
395
+ }
396
+
397
+ pub fn supports_deferred_store_action(&self) -> bool {
398
+ match self.os() {
399
+ OS::iOS => self.os_version() >= 10,
400
+ OS::tvOS => self.os_version() >= 10,
401
+ OS::macOS => self.os_version() >= 12,
402
+ }
403
+ }
404
+
405
+ pub fn supports_msaa_blits(&self) -> bool {
406
+ match self.os() {
407
+ OS::iOS => self.os_version() >= 10,
408
+ OS::tvOS => self.os_version() >= 10,
409
+ OS::macOS => true,
410
+ }
411
+ }
412
+
413
+ pub fn supports_srgb_writes(&self) -> bool {
414
+ match self.os() {
415
+ OS::iOS => self.gpu_family() >= 3 || (self.gpu_family() >= 2 && self.version() >= 3),
416
+ OS::tvOS => self.os_version() >= 10,
417
+ OS::macOS => self.gpu_family() >= 2,
418
+ }
419
+ }
420
+
421
+ pub fn supports_16_bit_unsigned_integer_coordinates(&self) -> bool {
422
+ match self.os() {
423
+ OS::iOS => self.os_version() >= 10,
424
+ OS::tvOS => self.os_version() >= 10,
425
+ OS::macOS => self.os_version() >= 12,
426
+ }
427
+ }
428
+
429
+ pub fn supports_extract_insert_and_reverse_bits(&self) -> bool {
430
+ match self.os() {
431
+ OS::iOS => self.os_version() >= 10,
432
+ OS::tvOS => self.os_version() >= 10,
433
+ OS::macOS => self.os_version() >= 12,
434
+ }
435
+ }
436
+
437
+ pub fn supports_simd_barrier(&self) -> bool {
438
+ match self.os() {
439
+ OS::iOS => self.os_version() >= 10,
440
+ OS::tvOS => self.os_version() >= 10,
441
+ OS::macOS => self.os_version() >= 13,
442
+ }
443
+ }
444
+
445
+ pub fn supports_sampler_max_anisotropy(&self) -> bool {
446
+ match self.os() {
447
+ OS::iOS => self.os_version() >= 10,
448
+ OS::tvOS => self.os_version() >= 10,
449
+ OS::macOS => self.os_version() >= 13,
450
+ }
451
+ }
452
+
453
+ pub fn supports_sampler_lod_clamp(&self) -> bool {
454
+ match self.os() {
455
+ OS::iOS => self.os_version() >= 10,
456
+ OS::tvOS => self.os_version() >= 10,
457
+ OS::macOS => self.os_version() >= 13,
458
+ }
459
+ }
460
+
461
+ pub fn supports_border_color(&self) -> bool {
462
+ self.os() == OS::macOS && self.os_version() >= 12
463
+ }
464
+
465
+ pub fn supports_dual_source_blending(&self) -> bool {
466
+ match self.os() {
467
+ OS::iOS => self.os_version() >= 11,
468
+ OS::tvOS => self.os_version() >= 11,
469
+ OS::macOS => self.os_version() >= 12,
470
+ }
471
+ }
472
+
473
+ pub fn supports_argument_buffers(&self) -> bool {
474
+ match self.os() {
475
+ OS::iOS => self.os_version() >= 11,
476
+ OS::tvOS => self.os_version() >= 11,
477
+ OS::macOS => self.os_version() >= 13,
478
+ }
479
+ }
480
+
481
+ pub fn supports_programmable_sample_positions(&self) -> bool {
482
+ match self.os() {
483
+ OS::iOS => self.os_version() >= 11,
484
+ OS::tvOS => self.os_version() >= 11,
485
+ OS::macOS => self.os_version() >= 13,
486
+ }
487
+ }
488
+
489
+ pub fn supports_uniform_type(&self) -> bool {
490
+ match self.os() {
491
+ OS::iOS => self.os_version() >= 11,
492
+ OS::tvOS => self.os_version() >= 11,
493
+ OS::macOS => self.os_version() >= 13,
494
+ }
495
+ }
496
+
497
+ pub fn supports_imageblocks(&self) -> bool {
498
+ self.os() == OS::iOS && self.gpu_family() >= 4
499
+ }
500
+
501
+ pub fn supports_tile_shaders(&self) -> bool {
502
+ self.os() == OS::iOS && self.gpu_family() >= 4
503
+ }
504
+
505
+ pub fn supports_imageblock_sample_coverage_control(&self) -> bool {
506
+ self.os() == OS::iOS && self.gpu_family() >= 4
507
+ }
508
+
509
+ pub fn supports_threadgroup_sharing(&self) -> bool {
510
+ self.os() == OS::iOS && self.gpu_family() >= 4
511
+ }
512
+
513
+ pub fn supports_post_depth_coverage(&self) -> bool {
514
+ self.os() == OS::iOS && self.gpu_family() >= 4
515
+ }
516
+
517
+ pub fn supports_quad_scoped_permute_operations(&self) -> bool {
518
+ match self.os() {
519
+ OS::iOS => self.gpu_family() >= 4,
520
+ OS::tvOS => false,
521
+ OS::macOS => self.os_version() >= 13,
522
+ }
523
+ }
524
+
525
+ pub fn supports_raster_order_groups(&self) -> bool {
526
+ match self.os() {
527
+ OS::iOS => self.gpu_family() >= 4,
528
+ OS::tvOS => false,
529
+ OS::macOS => self.os_version() >= 13,
530
+ }
531
+ }
532
+
533
+ pub fn supports_non_uniform_threadgroup_size(&self) -> bool {
534
+ match self.os() {
535
+ OS::iOS => self.gpu_family() >= 4,
536
+ OS::tvOS => false,
537
+ OS::macOS => self.os_version() >= 13,
538
+ }
539
+ }
540
+
541
+ pub fn supports_multiple_viewports(&self) -> bool {
542
+ match self.os() {
543
+ OS::iOS => self.gpu_family() >= 5,
544
+ OS::tvOS => false,
545
+ OS::macOS => self.os_version() >= 13,
546
+ }
547
+ }
548
+
549
+ pub fn supports_device_notifications(&self) -> bool {
550
+ self.os() == OS::macOS && self.os_version() >= 13
551
+ }
552
+
553
+ pub fn supports_stencil_feedback(&self) -> bool {
554
+ match self.os() {
555
+ OS::iOS => self.gpu_family() >= 5,
556
+ OS::tvOS => false,
557
+ OS::macOS => self.gpu_family() >= 2,
558
+ }
559
+ }
560
+
561
+ pub fn supports_stencil_resolve(&self) -> bool {
562
+ match self.os() {
563
+ OS::iOS => self.gpu_family() >= 5,
564
+ OS::tvOS => false,
565
+ OS::macOS => self.gpu_family() >= 2,
566
+ }
567
+ }
568
+
569
+ pub fn supports_binary_archive(&self) -> bool {
570
+ match self.os() {
571
+ OS::iOS => self.gpu_family() >= 3,
572
+ OS::tvOS => self.gpu_family() >= 3,
573
+ OS::macOS => self.gpu_family() >= 1,
574
+ }
575
+ }
576
+
577
+ pub fn max_vertex_attributes(&self) -> u32 {
578
+ 31
579
+ }
580
+
581
+ pub fn max_buffer_argument_entries(&self) -> u32 {
582
+ 31
583
+ }
584
+
585
+ pub fn max_texture_argument_entries(&self) -> u32 {
586
+ if self.os() == OS::macOS {
587
+ 128
588
+ } else {
589
+ 31
590
+ }
591
+ }
592
+
593
+ pub fn max_sampler_state_argument_entries(&self) -> u32 {
594
+ 16
595
+ }
596
+
597
+ pub fn max_threadgroup_memory_argument_entries(&self) -> u32 {
598
+ 31
599
+ }
600
+
601
+ pub fn max_inlined_constant_data_buffers(&self) -> u32 {
602
+ if self.os() == OS::macOS {
603
+ 14
604
+ } else {
605
+ 31
606
+ }
607
+ }
608
+
609
+ pub fn max_inline_constant_buffer_length(&self) -> u32 {
610
+ 4 * KB
611
+ }
612
+
613
+ pub fn max_threads_per_threadgroup(&self) -> u32 {
614
+ if self.os() == OS::macOS || self.gpu_family() >= 4 {
615
+ 1024
616
+ } else {
617
+ 512
618
+ }
619
+ }
620
+
621
+ pub fn max_total_threadgroup_memory_allocation(&self) -> u32 {
622
+ match (self.os(), self.gpu_family()) {
623
+ (OS::iOS, 5) => 64 * KB,
624
+ (OS::iOS, 4) => {
625
+ if self.os_version() >= 12 {
626
+ 64 * KB
627
+ } else {
628
+ 32 * KB
629
+ }
630
+ }
631
+ (OS::iOS, 3) => 16 * KB,
632
+ (OS::iOS, _) => 16 * KB - 32,
633
+ (OS::tvOS, 1) => 16 * KB - 32,
634
+ (OS::tvOS, _) => 16 * KB,
635
+ (OS::macOS, _) => 32 * KB,
636
+ }
637
+ }
638
+
639
+ pub fn max_total_tile_memory_allocation(&self) -> u32 {
640
+ if self.os() == OS::iOS && self.gpu_family() == 4 {
641
+ 32 * KB
642
+ } else {
643
+ 0
644
+ }
645
+ }
646
+
647
+ pub fn threadgroup_memory_length_alignment(&self) -> u32 {
648
+ 16
649
+ }
650
+
651
+ pub fn max_constant_buffer_function_memory_allocation(&self) -> Option<u32> {
652
+ if self.os() == OS::macOS {
653
+ Some(64 * KB)
654
+ } else {
655
+ None
656
+ }
657
+ }
658
+
659
+ pub fn max_fragment_inputs(&self) -> u32 {
660
+ if self.os() == OS::macOS {
661
+ 32
662
+ } else {
663
+ 60
664
+ }
665
+ }
666
+
667
+ pub fn max_fragment_input_components(&self) -> u32 {
668
+ if self.os() == OS::macOS {
669
+ 128
670
+ } else {
671
+ 60
672
+ }
673
+ }
674
+
675
+ pub fn max_function_constants(&self) -> u32 {
676
+ match self.os() {
677
+ OS::iOS if self.os_version() >= 11 => 65536,
678
+ OS::tvOS if self.os_version() >= 10 => 65536,
679
+ OS::macOS if self.os_version() >= 12 => 65536,
680
+ _ => 0,
681
+ }
682
+ }
683
+
684
+ pub fn max_tessellation_factor(&self) -> u32 {
685
+ if self.supports_tessellation() {
686
+ match self.os() {
687
+ OS::iOS if self.gpu_family() >= 5 => 64,
688
+ OS::iOS => 16,
689
+ OS::tvOS => 16,
690
+ OS::macOS => 64,
691
+ }
692
+ } else {
693
+ 0
694
+ }
695
+ }
696
+
697
+ pub fn max_viewports_and_scissor_rectangles(&self) -> u32 {
698
+ if self.supports_multiple_viewports() {
699
+ 16
700
+ } else {
701
+ 1
702
+ }
703
+ }
704
+
705
+ pub fn max_raster_order_groups(&self) -> u32 {
706
+ if self.supports_raster_order_groups() {
707
+ 8
708
+ } else {
709
+ 0
710
+ }
711
+ }
712
+
713
+ pub fn max_buffer_length(&self) -> u32 {
714
+ if self.os() == OS::macOS && self.os_version() >= 12 {
715
+ 1 * GB
716
+ } else {
717
+ 256 * MB
718
+ }
719
+ }
720
+
721
+ pub fn min_buffer_offset_alignment(&self) -> u32 {
722
+ if self.os() == OS::macOS {
723
+ 256
724
+ } else {
725
+ 4
726
+ }
727
+ }
728
+
729
+ pub fn max_1d_texture_size(&self) -> u32 {
730
+ match (self.os(), self.gpu_family()) {
731
+ (OS::iOS, 1) | (OS::iOS, 2) => {
732
+ if self.version() <= 2 {
733
+ 4096
734
+ } else {
735
+ 8192
736
+ }
737
+ }
738
+ (OS::tvOS, 1) => 8192,
739
+ _ => 16384,
740
+ }
741
+ }
742
+
743
+ pub fn max_2d_texture_size(&self) -> u32 {
744
+ match (self.os(), self.gpu_family()) {
745
+ (OS::iOS, 1) | (OS::iOS, 2) => {
746
+ if self.version() <= 2 {
747
+ 4096
748
+ } else {
749
+ 8192
750
+ }
751
+ }
752
+ (OS::tvOS, 1) => 8192,
753
+ _ => 16384,
754
+ }
755
+ }
756
+
757
+ pub fn max_cube_map_texture_size(&self) -> u32 {
758
+ match (self.os(), self.gpu_family()) {
759
+ (OS::iOS, 1) | (OS::iOS, 2) => {
760
+ if self.version() <= 2 {
761
+ 4096
762
+ } else {
763
+ 8192
764
+ }
765
+ }
766
+ (OS::tvOS, 1) => 8192,
767
+ _ => 16384,
768
+ }
769
+ }
770
+
771
+ pub fn max_3d_texture_size(&self) -> u32 {
772
+ 2048
773
+ }
774
+
775
+ pub fn max_array_layers(&self) -> u32 {
776
+ 2048
777
+ }
778
+
779
+ pub fn copy_texture_buffer_alignment(&self) -> u32 {
780
+ match (self.os(), self.gpu_family()) {
781
+ (OS::iOS, 1) | (OS::iOS, 2) | (OS::tvOS, 1) => 64,
782
+ (OS::iOS, _) | (OS::tvOS, _) => 16,
783
+ (OS::macOS, _) => 256,
784
+ }
785
+ }
786
+
787
+ /// If this function returns `None` but linear textures are supported,
788
+ /// the buffer alignment can be discovered via API query
789
+ pub fn new_texture_buffer_alignment(&self) -> Option<u32> {
790
+ match self.os() {
791
+ OS::iOS => {
792
+ if self.os_version() >= 11 {
793
+ None
794
+ } else if self.gpu_family() == 3 {
795
+ Some(16)
796
+ } else {
797
+ Some(64)
798
+ }
799
+ }
800
+ OS::tvOS => {
801
+ if self.os_version() >= 11 {
802
+ None
803
+ } else {
804
+ Some(64)
805
+ }
806
+ }
807
+ OS::macOS => None,
808
+ }
809
+ }
810
+
811
+ pub fn max_color_render_targets(&self) -> u32 {
812
+ if self.os() == OS::iOS && self.gpu_family() == 1 {
813
+ 4
814
+ } else {
815
+ 8
816
+ }
817
+ }
818
+
819
+ pub fn max_point_primitive_size(&self) -> u32 {
820
+ 511
821
+ }
822
+
823
+ pub fn max_total_color_render_target_size(&self) -> Option<u32> {
824
+ match (self.os(), self.gpu_family()) {
825
+ (OS::iOS, 1) => Some(128),
826
+ (OS::iOS, 2) | (OS::iOS, 3) => Some(256),
827
+ (OS::iOS, _) => Some(512),
828
+ (OS::tvOS, _) => Some(256),
829
+ (OS::macOS, _) => None,
830
+ }
831
+ }
832
+
833
+ pub fn max_visibility_query_offset(&self) -> u32 {
834
+ 64 * KB - 8
835
+ }
836
+
837
+ pub fn a8_unorm_capabilities(&self) -> PixelFormatCapabilities {
838
+ PixelFormatCapabilities::Filter
839
+ }
840
+
841
+ pub fn r8_unorm_capabilities(&self) -> PixelFormatCapabilities {
842
+ PixelFormatCapabilities::all()
843
+ }
844
+
845
+ pub fn r8_unorm_srgb_capabilities(&self) -> PixelFormatCapabilities {
846
+ if self.os() == OS::macOS {
847
+ PixelFormatCapabilities::empty()
848
+ } else if self.supports_srgb_writes() {
849
+ PixelFormatCapabilities::all()
850
+ } else {
851
+ !PixelFormatCapabilities::Write
852
+ }
853
+ }
854
+
855
+ pub fn r8_snorm_capabilities(&self) -> PixelFormatCapabilities {
856
+ if self.os() == OS::iOS && self.gpu_family() == 1 {
857
+ !PixelFormatCapabilities::Resolve
858
+ } else {
859
+ PixelFormatCapabilities::all()
860
+ }
861
+ }
862
+
863
+ pub fn r8_uint_capabilities(&self) -> PixelFormatCapabilities {
864
+ PixelFormatCapabilities::Write
865
+ | PixelFormatCapabilities::Color
866
+ | PixelFormatCapabilities::Msaa
867
+ }
868
+
869
+ pub fn r8_sint_capabilities(&self) -> PixelFormatCapabilities {
870
+ PixelFormatCapabilities::Write
871
+ | PixelFormatCapabilities::Color
872
+ | PixelFormatCapabilities::Msaa
873
+ }
874
+
875
+ pub fn r16_unorm_capabilities(&self) -> PixelFormatCapabilities {
876
+ if self.os() != OS::macOS {
877
+ !PixelFormatCapabilities::Resolve
878
+ } else {
879
+ PixelFormatCapabilities::all()
880
+ }
881
+ }
882
+
883
+ pub fn r16_snorm_capabilities(&self) -> PixelFormatCapabilities {
884
+ if self.os() != OS::macOS {
885
+ !PixelFormatCapabilities::Resolve
886
+ } else {
887
+ PixelFormatCapabilities::all()
888
+ }
889
+ }
890
+
891
+ pub fn r16_uint_capabilities(&self) -> PixelFormatCapabilities {
892
+ PixelFormatCapabilities::Write
893
+ | PixelFormatCapabilities::Color
894
+ | PixelFormatCapabilities::Msaa
895
+ }
896
+
897
+ pub fn r16_sint_capabilities(&self) -> PixelFormatCapabilities {
898
+ PixelFormatCapabilities::Write
899
+ | PixelFormatCapabilities::Color
900
+ | PixelFormatCapabilities::Msaa
901
+ }
902
+
903
+ pub fn r16_float_capabilities(&self) -> PixelFormatCapabilities {
904
+ PixelFormatCapabilities::all()
905
+ }
906
+
907
+ pub fn rg8_unorm_capabilities(&self) -> PixelFormatCapabilities {
908
+ PixelFormatCapabilities::all()
909
+ }
910
+
911
+ pub fn rg8_unorm_srgb_capabilities(&self) -> PixelFormatCapabilities {
912
+ if self.os() == OS::macOS {
913
+ PixelFormatCapabilities::empty()
914
+ } else if self.supports_srgb_writes() {
915
+ PixelFormatCapabilities::all()
916
+ } else {
917
+ !PixelFormatCapabilities::Write
918
+ }
919
+ }
920
+
921
+ pub fn rg8_snorm_capabilities(&self) -> PixelFormatCapabilities {
922
+ if self.os() == OS::iOS && self.gpu_family() == 1 {
923
+ !PixelFormatCapabilities::Resolve
924
+ } else {
925
+ PixelFormatCapabilities::all()
926
+ }
927
+ }
928
+
929
+ pub fn rg8_uint_capabilities(&self) -> PixelFormatCapabilities {
930
+ PixelFormatCapabilities::Write
931
+ | PixelFormatCapabilities::Color
932
+ | PixelFormatCapabilities::Msaa
933
+ }
934
+
935
+ pub fn rg8_sint_capabilities(&self) -> PixelFormatCapabilities {
936
+ PixelFormatCapabilities::Write
937
+ | PixelFormatCapabilities::Color
938
+ | PixelFormatCapabilities::Msaa
939
+ }
940
+
941
+ pub fn b5_g6_r5_unorm_capabilities(&self) -> PixelFormatCapabilities {
942
+ if self.os() == OS::macOS {
943
+ PixelFormatCapabilities::empty()
944
+ } else {
945
+ !PixelFormatCapabilities::Write
946
+ }
947
+ }
948
+
949
+ pub fn a1_bgr5_unorm_capabilities(&self) -> PixelFormatCapabilities {
950
+ if self.os() == OS::macOS {
951
+ PixelFormatCapabilities::empty()
952
+ } else {
953
+ !PixelFormatCapabilities::Write
954
+ }
955
+ }
956
+
957
+ pub fn abgr4_unorm_capabilities(&self) -> PixelFormatCapabilities {
958
+ if self.os() == OS::macOS {
959
+ PixelFormatCapabilities::empty()
960
+ } else {
961
+ !PixelFormatCapabilities::Write
962
+ }
963
+ }
964
+
965
+ pub fn bgr5_a1_unorm_capabilities(&self) -> PixelFormatCapabilities {
966
+ if self.os() == OS::macOS {
967
+ PixelFormatCapabilities::empty()
968
+ } else {
969
+ !PixelFormatCapabilities::Write
970
+ }
971
+ }
972
+
973
+ pub fn r32_uint_capabilities(&self) -> PixelFormatCapabilities {
974
+ if self.os() == OS::iOS && self.os_version() == 8 {
975
+ PixelFormatCapabilities::Color
976
+ } else if self.os() == OS::macOS {
977
+ PixelFormatCapabilities::Color
978
+ | PixelFormatCapabilities::Write
979
+ | PixelFormatCapabilities::Msaa
980
+ } else {
981
+ PixelFormatCapabilities::Color | PixelFormatCapabilities::Write
982
+ }
983
+ }
984
+
985
+ pub fn r32_sint_capabilities(&self) -> PixelFormatCapabilities {
986
+ if self.os() == OS::iOS && self.os_version() == 8 {
987
+ PixelFormatCapabilities::Color
988
+ } else if self.os() == OS::macOS {
989
+ PixelFormatCapabilities::Color
990
+ | PixelFormatCapabilities::Write
991
+ | PixelFormatCapabilities::Msaa
992
+ } else {
993
+ PixelFormatCapabilities::Color | PixelFormatCapabilities::Write
994
+ }
995
+ }
996
+
997
+ pub fn r32_float_capabilities(&self) -> PixelFormatCapabilities {
998
+ if self.os() == OS::iOS && self.os_version() == 8 {
999
+ PixelFormatCapabilities::Color
1000
+ | PixelFormatCapabilities::Blend
1001
+ | PixelFormatCapabilities::Msaa
1002
+ } else if self.os() == OS::macOS {
1003
+ PixelFormatCapabilities::all()
1004
+ } else {
1005
+ PixelFormatCapabilities::Write
1006
+ | PixelFormatCapabilities::Color
1007
+ | PixelFormatCapabilities::Blend
1008
+ | PixelFormatCapabilities::Msaa
1009
+ }
1010
+ }
1011
+
1012
+ pub fn rg16_unorm_capabilities(&self) -> PixelFormatCapabilities {
1013
+ if self.os() == OS::macOS {
1014
+ PixelFormatCapabilities::all()
1015
+ } else {
1016
+ !PixelFormatCapabilities::Resolve
1017
+ }
1018
+ }
1019
+
1020
+ pub fn rg16_snorm_capabilities(&self) -> PixelFormatCapabilities {
1021
+ if self.os() == OS::macOS {
1022
+ PixelFormatCapabilities::all()
1023
+ } else {
1024
+ !PixelFormatCapabilities::Resolve
1025
+ }
1026
+ }
1027
+
1028
+ pub fn rg16_uint_capabilities(&self) -> PixelFormatCapabilities {
1029
+ PixelFormatCapabilities::Write
1030
+ | PixelFormatCapabilities::Color
1031
+ | PixelFormatCapabilities::Msaa
1032
+ }
1033
+
1034
+ pub fn rg16_sint_capabilities(&self) -> PixelFormatCapabilities {
1035
+ PixelFormatCapabilities::Write
1036
+ | PixelFormatCapabilities::Color
1037
+ | PixelFormatCapabilities::Msaa
1038
+ }
1039
+
1040
+ pub fn rg16_float_capabilities(&self) -> PixelFormatCapabilities {
1041
+ PixelFormatCapabilities::all()
1042
+ }
1043
+
1044
+ pub fn rgba8_unorm_capabilities(&self) -> PixelFormatCapabilities {
1045
+ PixelFormatCapabilities::all()
1046
+ }
1047
+
1048
+ pub fn rgba8_unorm_srgb_capabilities(&self) -> PixelFormatCapabilities {
1049
+ if self.supports_srgb_writes() {
1050
+ PixelFormatCapabilities::all()
1051
+ } else {
1052
+ !PixelFormatCapabilities::Write
1053
+ }
1054
+ }
1055
+
1056
+ pub fn rgba8_snorm_capabilities(&self) -> PixelFormatCapabilities {
1057
+ if self.os() == OS::iOS && self.gpu_family() == 1 {
1058
+ !PixelFormatCapabilities::Resolve
1059
+ } else {
1060
+ PixelFormatCapabilities::all()
1061
+ }
1062
+ }
1063
+
1064
+ pub fn rgba8_uint_capabilities(&self) -> PixelFormatCapabilities {
1065
+ PixelFormatCapabilities::Write
1066
+ | PixelFormatCapabilities::Color
1067
+ | PixelFormatCapabilities::Msaa
1068
+ }
1069
+
1070
+ pub fn rgba8_sint_capabilities(&self) -> PixelFormatCapabilities {
1071
+ PixelFormatCapabilities::Write
1072
+ | PixelFormatCapabilities::Color
1073
+ | PixelFormatCapabilities::Msaa
1074
+ }
1075
+
1076
+ pub fn bgra8_unorm_capabilities(&self) -> PixelFormatCapabilities {
1077
+ PixelFormatCapabilities::all()
1078
+ }
1079
+
1080
+ pub fn bgra8_unorm_srgb_capabilities(&self) -> PixelFormatCapabilities {
1081
+ if self.supports_srgb_writes() {
1082
+ PixelFormatCapabilities::all()
1083
+ } else {
1084
+ !PixelFormatCapabilities::Write
1085
+ }
1086
+ }
1087
+
1088
+ pub fn rgb10_a2_unorm_capabilities(&self) -> PixelFormatCapabilities {
1089
+ let supports_writes = match self.os() {
1090
+ OS::iOS => self.gpu_family() >= 3,
1091
+ OS::tvOS => self.gpu_family() >= 2,
1092
+ OS::macOS => true,
1093
+ };
1094
+ if supports_writes {
1095
+ PixelFormatCapabilities::all()
1096
+ } else {
1097
+ !PixelFormatCapabilities::Write
1098
+ }
1099
+ }
1100
+
1101
+ pub fn rgb10_a2_uint_capabilities(&self) -> PixelFormatCapabilities {
1102
+ let supports_writes = match self.os() {
1103
+ OS::iOS => self.gpu_family() >= 3,
1104
+ OS::tvOS => self.gpu_family() >= 2,
1105
+ OS::macOS => true,
1106
+ };
1107
+ if supports_writes {
1108
+ PixelFormatCapabilities::Write
1109
+ | PixelFormatCapabilities::Color
1110
+ | PixelFormatCapabilities::Msaa
1111
+ } else {
1112
+ PixelFormatCapabilities::Color | PixelFormatCapabilities::Msaa
1113
+ }
1114
+ }
1115
+
1116
+ pub fn rg11_b10_float_capabilities(&self) -> PixelFormatCapabilities {
1117
+ let supports_writes = match self.os() {
1118
+ OS::iOS => self.gpu_family() >= 3,
1119
+ OS::tvOS => self.gpu_family() >= 2,
1120
+ OS::macOS => true,
1121
+ };
1122
+ if supports_writes {
1123
+ PixelFormatCapabilities::all()
1124
+ } else {
1125
+ !PixelFormatCapabilities::Write
1126
+ }
1127
+ }
1128
+
1129
+ pub fn rgb9_e5_float_capabilities(&self) -> PixelFormatCapabilities {
1130
+ if self.os() == OS::macOS {
1131
+ PixelFormatCapabilities::Filter
1132
+ } else {
1133
+ let supports_writes = match self.os() {
1134
+ OS::iOS => self.gpu_family() >= 3,
1135
+ OS::tvOS => self.gpu_family() >= 2,
1136
+ OS::macOS => false,
1137
+ };
1138
+ if supports_writes {
1139
+ PixelFormatCapabilities::all()
1140
+ } else {
1141
+ !PixelFormatCapabilities::Write
1142
+ }
1143
+ }
1144
+ }
1145
+
1146
+ pub fn rg32_uint_capabilities(&self) -> PixelFormatCapabilities {
1147
+ if self.os() == OS::iOS && self.os_version() == 8 {
1148
+ PixelFormatCapabilities::Color
1149
+ } else if self.os() == OS::macOS {
1150
+ PixelFormatCapabilities::Color
1151
+ | PixelFormatCapabilities::Write
1152
+ | PixelFormatCapabilities::Msaa
1153
+ } else {
1154
+ PixelFormatCapabilities::Color | PixelFormatCapabilities::Write
1155
+ }
1156
+ }
1157
+
1158
+ pub fn rg32_sint_capabilities(&self) -> PixelFormatCapabilities {
1159
+ if self.os() == OS::iOS && self.os_version() == 8 {
1160
+ PixelFormatCapabilities::Color
1161
+ } else if self.os() == OS::macOS {
1162
+ PixelFormatCapabilities::Color
1163
+ | PixelFormatCapabilities::Write
1164
+ | PixelFormatCapabilities::Msaa
1165
+ } else {
1166
+ PixelFormatCapabilities::Color | PixelFormatCapabilities::Write
1167
+ }
1168
+ }
1169
+
1170
+ pub fn rg32_float_capabilities(&self) -> PixelFormatCapabilities {
1171
+ if self.os() == OS::macOS {
1172
+ PixelFormatCapabilities::all()
1173
+ } else if self.os() == OS::iOS && self.os_version() == 8 {
1174
+ PixelFormatCapabilities::Color | PixelFormatCapabilities::Blend
1175
+ } else {
1176
+ PixelFormatCapabilities::Write
1177
+ | PixelFormatCapabilities::Color
1178
+ | PixelFormatCapabilities::Blend
1179
+ }
1180
+ }
1181
+
1182
+ pub fn rgba16_unorm_capabilities(&self) -> PixelFormatCapabilities {
1183
+ if self.os() == OS::macOS {
1184
+ PixelFormatCapabilities::all()
1185
+ } else {
1186
+ !PixelFormatCapabilities::Write
1187
+ }
1188
+ }
1189
+
1190
+ pub fn rgba16_snorm_capabilities(&self) -> PixelFormatCapabilities {
1191
+ if self.os() == OS::macOS {
1192
+ PixelFormatCapabilities::all()
1193
+ } else {
1194
+ !PixelFormatCapabilities::Write
1195
+ }
1196
+ }
1197
+
1198
+ pub fn rgba16_uint_capabilities(&self) -> PixelFormatCapabilities {
1199
+ PixelFormatCapabilities::Write
1200
+ | PixelFormatCapabilities::Color
1201
+ | PixelFormatCapabilities::Msaa
1202
+ }
1203
+
1204
+ pub fn rgba16_sint_capabilities(&self) -> PixelFormatCapabilities {
1205
+ PixelFormatCapabilities::Write
1206
+ | PixelFormatCapabilities::Color
1207
+ | PixelFormatCapabilities::Msaa
1208
+ }
1209
+
1210
+ pub fn rgba16_float_capabilities(&self) -> PixelFormatCapabilities {
1211
+ PixelFormatCapabilities::all()
1212
+ }
1213
+
1214
+ pub fn rgba32_uint_capabilities(&self) -> PixelFormatCapabilities {
1215
+ if self.os() == OS::iOS && self.os_version() == 8 {
1216
+ PixelFormatCapabilities::Color
1217
+ } else if self.os() == OS::macOS {
1218
+ PixelFormatCapabilities::Color
1219
+ | PixelFormatCapabilities::Write
1220
+ | PixelFormatCapabilities::Msaa
1221
+ } else {
1222
+ PixelFormatCapabilities::Color | PixelFormatCapabilities::Write
1223
+ }
1224
+ }
1225
+
1226
+ pub fn rgba32_sint_capabilities(&self) -> PixelFormatCapabilities {
1227
+ if self.os() == OS::iOS && self.os_version() == 8 {
1228
+ PixelFormatCapabilities::Color
1229
+ } else if self.os() == OS::macOS {
1230
+ PixelFormatCapabilities::Color
1231
+ | PixelFormatCapabilities::Write
1232
+ | PixelFormatCapabilities::Msaa
1233
+ } else {
1234
+ PixelFormatCapabilities::Color | PixelFormatCapabilities::Write
1235
+ }
1236
+ }
1237
+
1238
+ pub fn rgba32_float_capabilities(&self) -> PixelFormatCapabilities {
1239
+ if self.os() == OS::macOS {
1240
+ PixelFormatCapabilities::all()
1241
+ } else if self.os() == OS::iOS && self.version() == 8 {
1242
+ PixelFormatCapabilities::Color
1243
+ } else {
1244
+ PixelFormatCapabilities::Write | PixelFormatCapabilities::Color
1245
+ }
1246
+ }
1247
+
1248
+ pub fn pvrtc_pixel_formats_capabilities(&self) -> PixelFormatCapabilities {
1249
+ if self.supports_pvrtc_pixel_formats() {
1250
+ PixelFormatCapabilities::Filter
1251
+ } else {
1252
+ PixelFormatCapabilities::empty()
1253
+ }
1254
+ }
1255
+
1256
+ pub fn eac_etc_pixel_formats_capabilities(&self) -> PixelFormatCapabilities {
1257
+ if self.supports_eac_etc_pixel_formats() {
1258
+ PixelFormatCapabilities::Filter
1259
+ } else {
1260
+ PixelFormatCapabilities::empty()
1261
+ }
1262
+ }
1263
+
1264
+ pub fn astc_pixel_formats_capabilities(&self) -> PixelFormatCapabilities {
1265
+ if self.supports_astc_pixel_formats() {
1266
+ PixelFormatCapabilities::Filter
1267
+ } else {
1268
+ PixelFormatCapabilities::empty()
1269
+ }
1270
+ }
1271
+
1272
+ pub fn bc_pixel_formats_capabilities(&self) -> PixelFormatCapabilities {
1273
+ if self.supports_bc_pixel_formats() {
1274
+ PixelFormatCapabilities::Filter
1275
+ } else {
1276
+ PixelFormatCapabilities::empty()
1277
+ }
1278
+ }
1279
+
1280
+ pub fn gbgr422_capabilities(&self) -> PixelFormatCapabilities {
1281
+ PixelFormatCapabilities::Filter
1282
+ }
1283
+
1284
+ pub fn bgrg422_capabilities(&self) -> PixelFormatCapabilities {
1285
+ PixelFormatCapabilities::Filter
1286
+ }
1287
+
1288
+ pub fn depth16_unorm_capabilities(&self) -> PixelFormatCapabilities {
1289
+ if self.supports_depth_16_pixel_format() {
1290
+ PixelFormatCapabilities::Filter
1291
+ | PixelFormatCapabilities::Msaa
1292
+ | PixelFormatCapabilities::Resolve
1293
+ } else {
1294
+ PixelFormatCapabilities::empty()
1295
+ }
1296
+ }
1297
+
1298
+ pub fn depth32_float_capabilities(&self) -> PixelFormatCapabilities {
1299
+ if self.os() == OS::macOS {
1300
+ PixelFormatCapabilities::Filter
1301
+ | PixelFormatCapabilities::Msaa
1302
+ | PixelFormatCapabilities::Resolve
1303
+ } else if self.supports_msaa_depth_resolve() {
1304
+ PixelFormatCapabilities::Msaa | PixelFormatCapabilities::Resolve
1305
+ } else {
1306
+ PixelFormatCapabilities::Msaa
1307
+ }
1308
+ }
1309
+
1310
+ pub fn stencil8_capabilities(&self) -> PixelFormatCapabilities {
1311
+ PixelFormatCapabilities::Msaa
1312
+ }
1313
+
1314
+ pub fn depth24_unorm_stencil8_capabilities(&self) -> PixelFormatCapabilities {
1315
+ if self.os() == OS::macOS {
1316
+ PixelFormatCapabilities::Filter
1317
+ | PixelFormatCapabilities::Msaa
1318
+ | PixelFormatCapabilities::Resolve
1319
+ } else {
1320
+ PixelFormatCapabilities::empty()
1321
+ }
1322
+ }
1323
+
1324
+ pub fn depth32_float_stencil8_capabilities(&self) -> PixelFormatCapabilities {
1325
+ if self.os() == OS::macOS {
1326
+ PixelFormatCapabilities::Filter
1327
+ | PixelFormatCapabilities::Msaa
1328
+ | PixelFormatCapabilities::Resolve
1329
+ } else if self.supports_msaa_depth_resolve() {
1330
+ PixelFormatCapabilities::Msaa | PixelFormatCapabilities::Resolve
1331
+ } else {
1332
+ PixelFormatCapabilities::Msaa
1333
+ }
1334
+ }
1335
+
1336
+ pub fn x24_stencil8_capabilities(&self) -> PixelFormatCapabilities {
1337
+ if self.os() == OS::macOS {
1338
+ PixelFormatCapabilities::Msaa
1339
+ } else {
1340
+ PixelFormatCapabilities::empty()
1341
+ }
1342
+ }
1343
+
1344
+ pub fn x32_stencil8_capabilities(&self) -> PixelFormatCapabilities {
1345
+ PixelFormatCapabilities::Msaa
1346
+ }
1347
+
1348
+ pub fn bgra10_xr_capabilities(&self) -> PixelFormatCapabilities {
1349
+ if self.supports_extended_range_pixel_formats() {
1350
+ PixelFormatCapabilities::all()
1351
+ } else {
1352
+ PixelFormatCapabilities::empty()
1353
+ }
1354
+ }
1355
+
1356
+ pub fn bgra10_xr_srgb_capabilities(&self) -> PixelFormatCapabilities {
1357
+ if self.supports_extended_range_pixel_formats() {
1358
+ PixelFormatCapabilities::all()
1359
+ } else {
1360
+ PixelFormatCapabilities::empty()
1361
+ }
1362
+ }
1363
+
1364
+ pub fn bgr10_xr_capabilities(&self) -> PixelFormatCapabilities {
1365
+ if self.supports_extended_range_pixel_formats() {
1366
+ PixelFormatCapabilities::all()
1367
+ } else {
1368
+ PixelFormatCapabilities::empty()
1369
+ }
1370
+ }
1371
+
1372
+ pub fn bgr10_xr_srgb_capabilities(&self) -> PixelFormatCapabilities {
1373
+ if self.supports_extended_range_pixel_formats() {
1374
+ PixelFormatCapabilities::all()
1375
+ } else {
1376
+ PixelFormatCapabilities::empty()
1377
+ }
1378
+ }
1379
+
1380
+ pub fn bgr10_a2_unorm_capabilities(&self) -> PixelFormatCapabilities {
1381
+ if self.supports_wide_color_pixel_format() {
1382
+ if self.os() == OS::macOS {
1383
+ !PixelFormatCapabilities::Write
1384
+ } else {
1385
+ PixelFormatCapabilities::all()
1386
+ }
1387
+ } else {
1388
+ PixelFormatCapabilities::empty()
1389
+ }
1390
+ }
1391
+ }
1392
+
1393
+ /// See <https://developer.apple.com/documentation/metal/mtlargumentbufferstier>
1394
+ #[repr(u64)]
1395
+ #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
1396
+ pub enum MTLArgumentBuffersTier {
1397
+ Tier1 = 0,
1398
+ Tier2 = 1,
1399
+ }
1400
+
1401
+ /// See <https://developer.apple.com/documentation/metal/mtlreadwritetexturetier>
1402
+ #[repr(u64)]
1403
+ #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
1404
+ pub enum MTLReadWriteTextureTier {
1405
+ TierNone = 0,
1406
+ Tier1 = 1,
1407
+ Tier2 = 2,
1408
+ }
1409
+
1410
+ /// Only available on (macos(11.0), ios(14.0))
1411
+ ///
1412
+ /// See <https://developer.apple.com/documentation/metal/mtlcountersamplingpoint>
1413
+ #[repr(u64)]
1414
+ #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
1415
+ pub enum MTLCounterSamplingPoint {
1416
+ AtStageBoundary = 0,
1417
+ AtDrawBoundary = 1,
1418
+ AtDispatchBoundary = 2,
1419
+ AtTileDispatchBoundary = 3,
1420
+ AtBlitBoundary = 4,
1421
+ }
1422
+
1423
+ /// Only available on (macos(11.0), macCatalyst(14.0), ios(13.0))
1424
+ /// Kinda a long name!
1425
+ ///
1426
+ /// See <https://developer.apple.com/documentation/metal/mtlsparsetextureregionalignmentmode>
1427
+ #[repr(u64)]
1428
+ #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
1429
+ pub enum MTLSparseTextureRegionAlignmentMode {
1430
+ Outward = 0,
1431
+ Inward = 1,
1432
+ }
1433
+
1434
+ bitflags::bitflags! {
1435
+ /// Options that determine how Metal prepares the pipeline.
1436
+ #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
1437
+ pub struct MTLPipelineOption: NSUInteger {
1438
+ /// Do not provide any reflection information.
1439
+ const None = 0;
1440
+ /// An option that requests argument information for buffers, textures, and threadgroup memory.
1441
+ const ArgumentInfo = 1 << 0;
1442
+ /// An option that requests detailed buffer type information for buffer arguments.
1443
+ const BufferTypeInfo = 1 << 1;
1444
+ /// An option that specifies that Metal should create the pipeline state object only if the
1445
+ /// compiled shader is present inside the binary archive.
1446
+ ///
1447
+ /// Only available on (macos(11.0), ios(14.0))
1448
+ const FailOnBinaryArchiveMiss = 1 << 2;
1449
+ }
1450
+ }
1451
+
1452
+ /// See <https://developer.apple.com/documentation/metal/mtlaccelerationstructuresizes>
1453
+ #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
1454
+ #[repr(C)]
1455
+ pub struct MTLAccelerationStructureSizes {
1456
+ pub acceleration_structure_size: NSUInteger,
1457
+ pub build_scratch_buffer_size: NSUInteger,
1458
+ pub refit_scratch_buffer_size: NSUInteger,
1459
+ }
1460
+
1461
+ #[cfg_attr(feature = "link", link(name = "Metal", kind = "framework"))]
1462
+ extern "C" {
1463
+ fn MTLCreateSystemDefaultDevice() -> *mut MTLDevice;
1464
+ #[cfg(not(any(target_os = "ios", target_os = "tvos", target_os = "visionos")))]
1465
+ fn MTLCopyAllDevices() -> *mut Object; //TODO: Array
1466
+ }
1467
+
1468
+ #[allow(non_camel_case_types)]
1469
+ type dispatch_data_t = *mut Object;
1470
+ #[allow(non_camel_case_types)]
1471
+ pub type dispatch_queue_t = *mut Object;
1472
+ #[allow(non_camel_case_types)]
1473
+ type dispatch_block_t = *const Block<(), ()>;
1474
+
1475
+ const DISPATCH_DATA_DESTRUCTOR_DEFAULT: dispatch_block_t = ptr::null();
1476
+
1477
+ #[cfg_attr(
1478
+ all(feature = "link", any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos")),
1479
+ link(name = "System", kind = "dylib")
1480
+ )]
1481
+ #[cfg_attr(
1482
+ all(feature = "link", not(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "visionos"))),
1483
+ link(name = "dispatch", kind = "dylib")
1484
+ )]
1485
+ #[allow(improper_ctypes)]
1486
+ extern "C" {
1487
+ static _dispatch_main_q: dispatch_queue_t;
1488
+
1489
+ fn dispatch_data_create(
1490
+ buffer: *const std::ffi::c_void,
1491
+ size: crate::c_size_t,
1492
+ queue: dispatch_queue_t,
1493
+ destructor: dispatch_block_t,
1494
+ ) -> dispatch_data_t;
1495
+ fn dispatch_release(object: dispatch_data_t); // actually dispatch_object_t
1496
+ }
1497
+
1498
+ /*type MTLNewLibraryCompletionHandler = extern fn(library: id, error: id);
1499
+ type MTLNewRenderPipelineStateCompletionHandler = extern fn(renderPipelineState: id, error: id);
1500
+ type MTLNewRenderPipelineStateWithReflectionCompletionHandler = extern fn(renderPipelineState: id, reflection: id, error: id);
1501
+ type MTLNewComputePipelineStateCompletionHandler = extern fn(computePipelineState: id, error: id);
1502
+ type MTLNewComputePipelineStateWithReflectionCompletionHandler = extern fn(computePipelineState: id, reflection: id, error: id);*/
1503
+
1504
+ /// See <https://developer.apple.com/documentation/metal/mtldevice>
1505
+ pub enum MTLDevice {}
1506
+
1507
+ foreign_obj_type! {
1508
+ type CType = MTLDevice;
1509
+ pub struct Device;
1510
+ }
1511
+
1512
+ impl Device {
1513
+ pub fn system_default() -> Option<Self> {
1514
+ // `MTLCreateSystemDefaultDevice` may return null if Metal is not supported
1515
+ unsafe {
1516
+ MTLCreateSystemDefaultDevice()
1517
+ .as_mut()
1518
+ .map(|x| Self(x.into()))
1519
+ }
1520
+ }
1521
+
1522
+ pub fn all() -> Vec<Self> {
1523
+ #[cfg(any(target_os = "ios", target_os = "tvos", target_os = "visionos"))]
1524
+ {
1525
+ Self::system_default().into_iter().collect()
1526
+ }
1527
+ #[cfg(not(any(target_os = "ios", target_os = "tvos", target_os = "visionos")))]
1528
+ unsafe {
1529
+ let array = MTLCopyAllDevices();
1530
+ let count: NSUInteger = msg_send![array, count];
1531
+ let ret = (0..count)
1532
+ .map(|i| msg_send![array, objectAtIndex: i])
1533
+ // The elements of this array are references---we convert them to owned references
1534
+ // (which just means that we increment the reference count here, and it is
1535
+ // decremented in the `Drop` impl for `Device`)
1536
+ .map(|device: *mut Object| msg_send![device, retain])
1537
+ .collect();
1538
+ let () = msg_send![array, release];
1539
+ ret
1540
+ }
1541
+ }
1542
+ }
1543
+
1544
+ impl DeviceRef {
1545
+ pub fn name(&self) -> &str {
1546
+ unsafe {
1547
+ let name = msg_send![self, name];
1548
+ crate::nsstring_as_str(name)
1549
+ }
1550
+ }
1551
+
1552
+ #[cfg(feature = "private")]
1553
+ pub unsafe fn vendor(&self) -> &str {
1554
+ let name = msg_send![self, vendorName];
1555
+ crate::nsstring_as_str(name)
1556
+ }
1557
+
1558
+ #[cfg(feature = "private")]
1559
+ pub unsafe fn family_name(&self) -> &str {
1560
+ let name = msg_send![self, familyName];
1561
+ crate::nsstring_as_str(name)
1562
+ }
1563
+
1564
+ pub fn registry_id(&self) -> u64 {
1565
+ unsafe { msg_send![self, registryID] }
1566
+ }
1567
+
1568
+ pub fn location(&self) -> MTLDeviceLocation {
1569
+ unsafe { msg_send![self, location] }
1570
+ }
1571
+
1572
+ pub fn location_number(&self) -> NSUInteger {
1573
+ unsafe { msg_send![self, locationNumber] }
1574
+ }
1575
+
1576
+ pub fn max_threadgroup_memory_length(&self) -> NSUInteger {
1577
+ unsafe { msg_send![self, maxThreadgroupMemoryLength] }
1578
+ }
1579
+
1580
+ pub fn max_threads_per_threadgroup(&self) -> MTLSize {
1581
+ unsafe { msg_send![self, maxThreadsPerThreadgroup] }
1582
+ }
1583
+
1584
+ pub fn is_low_power(&self) -> bool {
1585
+ unsafe { msg_send_bool![self, isLowPower] }
1586
+ }
1587
+
1588
+ pub fn is_headless(&self) -> bool {
1589
+ unsafe { msg_send_bool![self, isHeadless] }
1590
+ }
1591
+
1592
+ pub fn is_removable(&self) -> bool {
1593
+ unsafe { msg_send_bool![self, isRemovable] }
1594
+ }
1595
+
1596
+ /// Only available on (macos(11.0), ios(14.0))
1597
+ pub fn supports_raytracing(&self) -> bool {
1598
+ unsafe { msg_send_bool![self, supportsRaytracing] }
1599
+ }
1600
+
1601
+ pub fn has_unified_memory(&self) -> bool {
1602
+ unsafe { msg_send![self, hasUnifiedMemory] }
1603
+ }
1604
+
1605
+ pub fn recommended_max_working_set_size(&self) -> u64 {
1606
+ unsafe { msg_send![self, recommendedMaxWorkingSetSize] }
1607
+ }
1608
+
1609
+ pub fn max_transfer_rate(&self) -> u64 {
1610
+ unsafe { msg_send![self, maxTransferRate] }
1611
+ }
1612
+
1613
+ pub fn supports_feature_set(&self, feature: MTLFeatureSet) -> bool {
1614
+ unsafe { msg_send_bool![self, supportsFeatureSet: feature] }
1615
+ }
1616
+
1617
+ pub fn supports_family(&self, family: MTLGPUFamily) -> bool {
1618
+ unsafe { msg_send_bool![self, supportsFamily: family] }
1619
+ }
1620
+
1621
+ pub fn supports_vertex_amplification_count(&self, count: NSUInteger) -> bool {
1622
+ unsafe { msg_send_bool![self, supportsVertexAmplificationCount: count] }
1623
+ }
1624
+
1625
+ pub fn supports_texture_sample_count(&self, count: NSUInteger) -> bool {
1626
+ unsafe { msg_send_bool![self, supportsTextureSampleCount: count] }
1627
+ }
1628
+
1629
+ pub fn supports_shader_barycentric_coordinates(&self) -> bool {
1630
+ unsafe { msg_send_bool![self, supportsShaderBarycentricCoordinates] }
1631
+ }
1632
+
1633
+ pub fn supports_function_pointers(&self) -> bool {
1634
+ unsafe { msg_send_bool![self, supportsFunctionPointers] }
1635
+ }
1636
+
1637
+ /// Only available on (macos(11.0), ios(14.0))
1638
+ pub fn supports_dynamic_libraries(&self) -> bool {
1639
+ unsafe { msg_send_bool![self, supportsDynamicLibraries] }
1640
+ }
1641
+
1642
+ /// Only available on (macos(11.0), ios(14.0))
1643
+ pub fn supports_counter_sampling(&self, sampling_point: MTLCounterSamplingPoint) -> bool {
1644
+ unsafe { msg_send_bool![self, supportsCounterSampling: sampling_point] }
1645
+ }
1646
+
1647
+ pub fn d24_s8_supported(&self) -> bool {
1648
+ unsafe { msg_send_bool![self, isDepth24Stencil8PixelFormatSupported] }
1649
+ }
1650
+
1651
+ pub fn new_fence(&self) -> Fence {
1652
+ unsafe { msg_send![self, newFence] }
1653
+ }
1654
+
1655
+ pub fn new_command_queue(&self) -> CommandQueue {
1656
+ unsafe { msg_send![self, newCommandQueue] }
1657
+ }
1658
+
1659
+ pub fn new_command_queue_with_max_command_buffer_count(
1660
+ &self,
1661
+ count: NSUInteger,
1662
+ ) -> CommandQueue {
1663
+ unsafe { msg_send![self, newCommandQueueWithMaxCommandBufferCount: count] }
1664
+ }
1665
+
1666
+ pub fn new_default_library(&self) -> Library {
1667
+ unsafe { msg_send![self, newDefaultLibrary] }
1668
+ }
1669
+
1670
+ pub fn new_library_with_source(
1671
+ &self,
1672
+ src: &str,
1673
+ options: &CompileOptionsRef,
1674
+ ) -> Result<Library, String> {
1675
+ let source = nsstring_from_str(src);
1676
+ unsafe {
1677
+ let mut err: *mut Object = ptr::null_mut();
1678
+ let library: *mut MTLLibrary = msg_send![self, newLibraryWithSource:source
1679
+ options:options
1680
+ error:&mut err];
1681
+ if !err.is_null() {
1682
+ let desc: *mut Object = msg_send![err, localizedDescription];
1683
+ let compile_error: *const c_char = msg_send![desc, UTF8String];
1684
+ let message = CStr::from_ptr(compile_error).to_string_lossy().into_owned();
1685
+ if library.is_null() {
1686
+ return Err(message);
1687
+ } else {
1688
+ warn!("Shader warnings: {}", message);
1689
+ }
1690
+ }
1691
+
1692
+ assert!(!library.is_null());
1693
+ Ok(Library::from_ptr(library))
1694
+ }
1695
+ }
1696
+
1697
+ pub fn new_library_with_file<P: AsRef<Path>>(&self, file: P) -> Result<Library, String> {
1698
+ let filename = nsstring_from_str(file.as_ref().to_string_lossy().as_ref());
1699
+ unsafe {
1700
+ let library: *mut MTLLibrary = try_objc! { err =>
1701
+ msg_send![self, newLibraryWithFile:filename.as_ref()
1702
+ error:&mut err]
1703
+ };
1704
+ Ok(Library::from_ptr(library))
1705
+ }
1706
+ }
1707
+
1708
+ pub fn new_library_with_data(&self, library_data: &[u8]) -> Result<Library, String> {
1709
+ unsafe {
1710
+ // SAFETY:
1711
+ // `library_data` does not necessarily outlive the dispatch data
1712
+ // in which it will be contained (since the dispatch data will be
1713
+ // contained in the MTLLibrary returned by this function).
1714
+ //
1715
+ // To prevent the MTLLibrary from referencing the data outside of
1716
+ // its lifetime, we use DISPATCH_DATA_DESTRUCTOR_DEFAULT as the
1717
+ // destructor block, which will make `dispatch_data_create` copy
1718
+ // the buffer for us automatically.
1719
+ let data = dispatch_data_create(
1720
+ library_data.as_ptr() as *const std::ffi::c_void,
1721
+ library_data.len() as crate::c_size_t,
1722
+ &_dispatch_main_q as *const _ as dispatch_queue_t,
1723
+ DISPATCH_DATA_DESTRUCTOR_DEFAULT,
1724
+ );
1725
+
1726
+ let library: *mut MTLLibrary = try_objc! { err =>
1727
+ msg_send![self, newLibraryWithData:data
1728
+ error:&mut err]
1729
+ };
1730
+ dispatch_release(data);
1731
+ Ok(Library::from_ptr(library))
1732
+ }
1733
+ }
1734
+
1735
+ /// Only available on (macos(11.0), ios(14.0))
1736
+ pub fn new_dynamic_library(&self, library: &LibraryRef) -> Result<DynamicLibrary, String> {
1737
+ unsafe {
1738
+ let mut err: *mut Object = ptr::null_mut();
1739
+ let dynamic_library: *mut MTLDynamicLibrary = msg_send![self, newDynamicLibrary:library
1740
+ error:&mut err];
1741
+ if !err.is_null() {
1742
+ // FIXME: copy pasta
1743
+ let desc: *mut Object = msg_send![err, localizedDescription];
1744
+ let compile_error: *const c_char = msg_send![desc, UTF8String];
1745
+ let message = CStr::from_ptr(compile_error).to_string_lossy().into_owned();
1746
+ Err(message)
1747
+ } else {
1748
+ Ok(DynamicLibrary::from_ptr(dynamic_library))
1749
+ }
1750
+ }
1751
+ }
1752
+
1753
+ /// Only available on (macos(11.0), ios(14.0))
1754
+ pub fn new_dynamic_library_with_url(&self, url: &URLRef) -> Result<DynamicLibrary, String> {
1755
+ unsafe {
1756
+ let mut err: *mut Object = ptr::null_mut();
1757
+ let dynamic_library: *mut MTLDynamicLibrary = msg_send![self, newDynamicLibraryWithURL:url
1758
+ error:&mut err];
1759
+ if !err.is_null() {
1760
+ // FIXME: copy pasta
1761
+ let desc: *mut Object = msg_send![err, localizedDescription];
1762
+ let compile_error: *const c_char = msg_send![desc, UTF8String];
1763
+ let message = CStr::from_ptr(compile_error).to_string_lossy().into_owned();
1764
+ Err(message)
1765
+ } else {
1766
+ Ok(DynamicLibrary::from_ptr(dynamic_library))
1767
+ }
1768
+ }
1769
+ }
1770
+
1771
+ /// Only available on (macos(11.0), ios(14.0))
1772
+ pub fn new_binary_archive_with_descriptor(
1773
+ &self,
1774
+ descriptor: &BinaryArchiveDescriptorRef,
1775
+ ) -> Result<BinaryArchive, String> {
1776
+ unsafe {
1777
+ let mut err: *mut Object = ptr::null_mut();
1778
+ let binary_archive: *mut MTLBinaryArchive = msg_send![self, newBinaryArchiveWithDescriptor:descriptor
1779
+ error:&mut err];
1780
+ if !err.is_null() {
1781
+ // TODO: copy pasta
1782
+ let desc: *mut Object = msg_send![err, localizedDescription];
1783
+ let c_msg: *const c_char = msg_send![desc, UTF8String];
1784
+ let message = CStr::from_ptr(c_msg).to_string_lossy().into_owned();
1785
+ Err(message)
1786
+ } else {
1787
+ Ok(BinaryArchive::from_ptr(binary_archive))
1788
+ }
1789
+ }
1790
+ }
1791
+
1792
+ /// Synchronously creates a render pipeline state object and associated reflection information.
1793
+ pub fn new_render_pipeline_state_with_reflection(
1794
+ &self,
1795
+ descriptor: &RenderPipelineDescriptorRef,
1796
+ reflection_options: MTLPipelineOption,
1797
+ ) -> Result<(RenderPipelineState, RenderPipelineReflection), String> {
1798
+ unsafe {
1799
+ let mut reflection: *mut Object = ptr::null_mut();
1800
+ let pipeline_state: *mut MTLRenderPipelineState = try_objc! { err =>
1801
+ msg_send![self, newRenderPipelineStateWithDescriptor:descriptor
1802
+ options:reflection_options
1803
+ reflection:&mut reflection
1804
+ error:&mut err]
1805
+ };
1806
+
1807
+ let state = RenderPipelineState::from_ptr(pipeline_state);
1808
+
1809
+ let () = msg_send![reflection, retain];
1810
+ let reflection = RenderPipelineReflection::from_ptr(reflection as _);
1811
+
1812
+ Ok((state, reflection))
1813
+ }
1814
+ }
1815
+
1816
+ pub fn new_render_pipeline_state(
1817
+ &self,
1818
+ descriptor: &RenderPipelineDescriptorRef,
1819
+ ) -> Result<RenderPipelineState, String> {
1820
+ unsafe {
1821
+ let pipeline_state: *mut MTLRenderPipelineState = try_objc! { err =>
1822
+ msg_send![self, newRenderPipelineStateWithDescriptor:descriptor
1823
+ error:&mut err]
1824
+ };
1825
+
1826
+ Ok(RenderPipelineState::from_ptr(pipeline_state))
1827
+ }
1828
+ }
1829
+
1830
+ /// Only available on (macos(13.0), ios(16.0))
1831
+ pub fn new_mesh_render_pipeline_state_with_reflection(
1832
+ &self,
1833
+ descriptor: &MeshRenderPipelineDescriptorRef,
1834
+ reflection_options: MTLPipelineOption,
1835
+ ) -> Result<(RenderPipelineState, RenderPipelineReflection), String> {
1836
+ unsafe {
1837
+ let mut reflection: *mut Object = ptr::null_mut();
1838
+ let pipeline_state: *mut MTLRenderPipelineState = try_objc! { err =>
1839
+ msg_send![self, newRenderPipelineStateWithMeshDescriptor:descriptor
1840
+ options:reflection_options
1841
+ reflection:&mut reflection
1842
+ error:&mut err]
1843
+ };
1844
+
1845
+ let state = RenderPipelineState::from_ptr(pipeline_state);
1846
+
1847
+ let () = msg_send![reflection, retain];
1848
+ let reflection = RenderPipelineReflection::from_ptr(reflection as _);
1849
+
1850
+ Ok((state, reflection))
1851
+ }
1852
+ }
1853
+
1854
+ /// Only available on (macos(13.0), ios(16.0))
1855
+ pub fn new_mesh_render_pipeline_state(
1856
+ &self,
1857
+ descriptor: &MeshRenderPipelineDescriptorRef,
1858
+ ) -> Result<RenderPipelineState, String> {
1859
+ unsafe {
1860
+ let pipeline_state: *mut MTLRenderPipelineState = try_objc! { err =>
1861
+ msg_send![self, newRenderPipelineStateWithMeshDescriptor:descriptor
1862
+ error:&mut err]
1863
+ };
1864
+
1865
+ Ok(RenderPipelineState::from_ptr(pipeline_state))
1866
+ }
1867
+ }
1868
+
1869
+ pub fn new_compute_pipeline_state_with_function(
1870
+ &self,
1871
+ function: &FunctionRef,
1872
+ ) -> Result<ComputePipelineState, String> {
1873
+ unsafe {
1874
+ let pipeline_state: *mut MTLComputePipelineState = try_objc! { err =>
1875
+ msg_send![self, newComputePipelineStateWithFunction:function
1876
+ error:&mut err]
1877
+ };
1878
+
1879
+ Ok(ComputePipelineState::from_ptr(pipeline_state))
1880
+ }
1881
+ }
1882
+
1883
+ pub fn new_compute_pipeline_state(
1884
+ &self,
1885
+ descriptor: &ComputePipelineDescriptorRef,
1886
+ ) -> Result<ComputePipelineState, String> {
1887
+ unsafe {
1888
+ let pipeline_state: *mut MTLComputePipelineState = try_objc! { err =>
1889
+ msg_send![self, newComputePipelineStateWithDescriptor:descriptor
1890
+ error:&mut err]
1891
+ };
1892
+
1893
+ Ok(ComputePipelineState::from_ptr(pipeline_state))
1894
+ }
1895
+ }
1896
+
1897
+ /// Synchronously creates a compute pipeline state object and associated reflection information,
1898
+ /// using a compute pipeline descriptor.
1899
+ pub fn new_compute_pipeline_state_with_reflection(
1900
+ &self,
1901
+ descriptor: &ComputePipelineDescriptorRef,
1902
+ reflection_options: MTLPipelineOption,
1903
+ ) -> Result<(ComputePipelineState, ComputePipelineReflection), String> {
1904
+ unsafe {
1905
+ let mut reflection: *mut Object = ptr::null_mut();
1906
+ let pipeline_state: *mut MTLComputePipelineState = try_objc! { err =>
1907
+ msg_send![self, newComputePipelineStateWithDescriptor:descriptor
1908
+ options:reflection_options
1909
+ reflection:&mut reflection
1910
+ error:&mut err]
1911
+ };
1912
+
1913
+ let state = ComputePipelineState::from_ptr(pipeline_state);
1914
+
1915
+ let () = msg_send![reflection, retain];
1916
+ let reflection = ComputePipelineReflection::from_ptr(reflection as _);
1917
+
1918
+ Ok((state, reflection))
1919
+ }
1920
+ }
1921
+
1922
+ pub fn new_buffer(&self, length: u64, options: MTLResourceOptions) -> Buffer {
1923
+ unsafe {
1924
+ msg_send![self, newBufferWithLength:length
1925
+ options:options]
1926
+ }
1927
+ }
1928
+
1929
+ pub fn new_buffer_with_bytes_no_copy(
1930
+ &self,
1931
+ bytes: *const std::ffi::c_void,
1932
+ length: NSUInteger,
1933
+ options: MTLResourceOptions,
1934
+ deallocator: Option<&Block<(*const std::ffi::c_void, NSUInteger), ()>>,
1935
+ ) -> Buffer {
1936
+ unsafe {
1937
+ msg_send![self, newBufferWithBytesNoCopy:bytes
1938
+ length:length
1939
+ options:options
1940
+ deallocator:deallocator]
1941
+ }
1942
+ }
1943
+
1944
+ pub fn new_buffer_with_data(
1945
+ &self,
1946
+ bytes: *const std::ffi::c_void,
1947
+ length: NSUInteger,
1948
+ options: MTLResourceOptions,
1949
+ ) -> Buffer {
1950
+ unsafe {
1951
+ msg_send![self, newBufferWithBytes:bytes
1952
+ length:length
1953
+ options:options]
1954
+ }
1955
+ }
1956
+
1957
+ pub fn new_counter_sample_buffer_with_descriptor(
1958
+ &self,
1959
+ descriptor: &CounterSampleBufferDescriptorRef,
1960
+ ) -> Result<CounterSampleBuffer, String> {
1961
+ unsafe {
1962
+ let counter_sample_buffer: *mut MTLCounterSampleBuffer = try_objc! { err =>
1963
+ msg_send![self, newCounterSampleBufferWithDescriptor: descriptor error:&mut err]
1964
+ };
1965
+
1966
+ assert!(!counter_sample_buffer.is_null());
1967
+ Ok(CounterSampleBuffer::from_ptr(counter_sample_buffer))
1968
+ }
1969
+ }
1970
+
1971
+ pub fn new_indirect_command_buffer_with_descriptor(
1972
+ &self,
1973
+ descriptor: &IndirectCommandBufferDescriptorRef,
1974
+ max_command_count: NSUInteger,
1975
+ options: MTLResourceOptions,
1976
+ ) -> IndirectCommandBuffer {
1977
+ unsafe {
1978
+ msg_send![self, newIndirectCommandBufferWithDescriptor:descriptor
1979
+ maxCommandCount:max_command_count
1980
+ options:options]
1981
+ }
1982
+ }
1983
+
1984
+ pub fn new_texture(&self, descriptor: &TextureDescriptorRef) -> Texture {
1985
+ unsafe { msg_send![self, newTextureWithDescriptor: descriptor] }
1986
+ }
1987
+
1988
+ pub fn new_sampler(&self, descriptor: &SamplerDescriptorRef) -> SamplerState {
1989
+ unsafe { msg_send![self, newSamplerStateWithDescriptor: descriptor] }
1990
+ }
1991
+
1992
+ pub fn new_depth_stencil_state(
1993
+ &self,
1994
+ descriptor: &DepthStencilDescriptorRef,
1995
+ ) -> DepthStencilState {
1996
+ unsafe { msg_send![self, newDepthStencilStateWithDescriptor: descriptor] }
1997
+ }
1998
+
1999
+ pub fn argument_buffers_support(&self) -> MTLArgumentBuffersTier {
2000
+ unsafe { msg_send![self, argumentBuffersSupport] }
2001
+ }
2002
+
2003
+ pub fn read_write_texture_support(&self) -> MTLReadWriteTextureTier {
2004
+ unsafe { msg_send![self, readWriteTextureSupport] }
2005
+ }
2006
+
2007
+ pub fn raster_order_groups_supported(&self) -> bool {
2008
+ unsafe { msg_send_bool![self, rasterOrderGroupsSupported] }
2009
+ }
2010
+
2011
+ /// Only available on (macos(11.0), ios(14.0))
2012
+ pub fn supports_32bit_float_filtering(&self) -> bool {
2013
+ unsafe { msg_send_bool![self, supports32BitFloatFiltering] }
2014
+ }
2015
+
2016
+ /// Only available on (macos(11.0), ios(14.0))
2017
+ pub fn supports_32bit_MSAA(&self) -> bool {
2018
+ unsafe { msg_send_bool![self, supports32BitMSAA] }
2019
+ }
2020
+
2021
+ /// Only available on (macos(11.0), ios(14.0))
2022
+ pub fn supports_query_texture_LOD(&self) -> bool {
2023
+ unsafe { msg_send_bool![self, supportsQueryTextureLOD] }
2024
+ }
2025
+
2026
+ /// Only available on (macos(11.0), ios(14.0))
2027
+ pub fn supports_BC_texture_compression(&self) -> bool {
2028
+ unsafe { msg_send_bool![self, supportsBCTextureCompression] }
2029
+ }
2030
+
2031
+ /// Only available on (macos(11.0), ios(14.0))
2032
+ pub fn supports_pull_model_interpolation(&self) -> bool {
2033
+ unsafe { msg_send_bool![self, supportsPullModelInterpolation] }
2034
+ }
2035
+
2036
+ pub fn new_argument_encoder(
2037
+ &self,
2038
+ arguments: &ArrayRef<ArgumentDescriptor>,
2039
+ ) -> ArgumentEncoder {
2040
+ unsafe { msg_send![self, newArgumentEncoderWithArguments: arguments] }
2041
+ }
2042
+
2043
+ pub fn new_heap(&self, descriptor: &HeapDescriptorRef) -> Heap {
2044
+ unsafe { msg_send![self, newHeapWithDescriptor: descriptor] }
2045
+ }
2046
+
2047
+ pub fn new_event(&self) -> Event {
2048
+ unsafe { msg_send![self, newEvent] }
2049
+ }
2050
+
2051
+ pub fn new_shared_event(&self) -> SharedEvent {
2052
+ unsafe { msg_send![self, newSharedEvent] }
2053
+ }
2054
+
2055
+ pub fn heap_buffer_size_and_align(
2056
+ &self,
2057
+ length: NSUInteger,
2058
+ options: MTLResourceOptions,
2059
+ ) -> MTLSizeAndAlign {
2060
+ unsafe { msg_send![self, heapBufferSizeAndAlignWithLength: length options: options] }
2061
+ }
2062
+
2063
+ /// Only available on macos(13.0), ios(16.0)
2064
+ pub fn heap_acceleration_structure_size_and_align_with_size(
2065
+ &self,
2066
+ size: NSUInteger,
2067
+ ) -> MTLSizeAndAlign {
2068
+ unsafe { msg_send![self, heapAccelerationStructureSizeAndAlignWithSize: size] }
2069
+ }
2070
+
2071
+ pub fn heap_texture_size_and_align(
2072
+ &self,
2073
+ descriptor: &TextureDescriptorRef,
2074
+ ) -> MTLSizeAndAlign {
2075
+ unsafe { msg_send![self, heapTextureSizeAndAlignWithDescriptor: descriptor] }
2076
+ }
2077
+
2078
+ pub fn minimum_linear_texture_alignment_for_pixel_format(
2079
+ &self,
2080
+ format: MTLPixelFormat,
2081
+ ) -> NSUInteger {
2082
+ unsafe { msg_send![self, minimumLinearTextureAlignmentForPixelFormat: format] }
2083
+ }
2084
+
2085
+ pub fn minimum_texture_buffer_alignment_for_pixel_format(
2086
+ &self,
2087
+ format: MTLPixelFormat,
2088
+ ) -> NSUInteger {
2089
+ unsafe { msg_send![self, minimumTextureBufferAlignmentForPixelFormat: format] }
2090
+ }
2091
+
2092
+ pub fn max_argument_buffer_sampler_count(&self) -> NSUInteger {
2093
+ unsafe { msg_send![self, maxArgumentBufferSamplerCount] }
2094
+ }
2095
+
2096
+ pub fn current_allocated_size(&self) -> NSUInteger {
2097
+ unsafe { msg_send![self, currentAllocatedSize] }
2098
+ }
2099
+
2100
+ /// Only available on (macos(10.14), ios(12.0), tvos(12.0))
2101
+ pub fn max_buffer_length(&self) -> NSUInteger {
2102
+ unsafe { msg_send![self, maxBufferLength] }
2103
+ }
2104
+
2105
+ pub fn acceleration_structure_sizes_with_descriptor(
2106
+ &self,
2107
+ desc: &AccelerationStructureDescriptorRef,
2108
+ ) -> MTLAccelerationStructureSizes {
2109
+ unsafe { msg_send![self, accelerationStructureSizesWithDescriptor: desc] }
2110
+ }
2111
+
2112
+ pub fn new_acceleration_structure_with_size(&self, size: NSUInteger) -> AccelerationStructure {
2113
+ unsafe { msg_send![self, newAccelerationStructureWithSize: size] }
2114
+ }
2115
+
2116
+ pub fn sample_timestamps(&self, cpu_timestamp: &mut u64, gpu_timestamp: &mut u64) {
2117
+ unsafe { msg_send![self, sampleTimestamps: cpu_timestamp gpuTimestamp: gpu_timestamp] }
2118
+ }
2119
+
2120
+ pub fn counter_sets(&self) -> Vec<CounterSet> {
2121
+ unsafe {
2122
+ let counter_sets: *mut Object = msg_send![self, counterSets];
2123
+ let count: NSUInteger = msg_send![counter_sets, count];
2124
+ let ret = (0..count)
2125
+ .map(|i| {
2126
+ let csp: *mut MTLCounterSet = msg_send![counter_sets, objectAtIndex: i];
2127
+ let () = msg_send![csp, retain];
2128
+ CounterSet::from_ptr(csp)
2129
+ })
2130
+ .collect();
2131
+ ret
2132
+ }
2133
+ }
2134
+ }