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 block::{Block, ConcreteBlock}; 9 use cocoa_foundation::base::id; 10 use cocoa_foundation::foundation::NSUInteger; 11 use foreign_types::ForeignType; 12 use objc::runtime::{Object, NO, YES}; 13 14 use super::*; 15 16 use std::ffi::CStr; 17 use std::os::raw::c_char; 18 use std::path::Path; 19 use std::ptr; 20 21 #[allow(non_camel_case_types)] 22 #[repr(u64)] 23 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] 24 pub enum MTLFeatureSet { 25 iOS_GPUFamily1_v1 = 0, 26 iOS_GPUFamily2_v1 = 1, 27 iOS_GPUFamily1_v2 = 2, 28 iOS_GPUFamily2_v2 = 3, 29 iOS_GPUFamily3_v1 = 4, 30 iOS_GPUFamily1_v3 = 5, 31 iOS_GPUFamily2_v3 = 6, 32 iOS_GPUFamily3_v2 = 7, 33 iOS_GPUFamily1_v4 = 8, 34 iOS_GPUFamily2_v4 = 9, 35 iOS_GPUFamily3_v3 = 10, 36 iOS_GPUFamily4_v1 = 11, 37 iOS_GPUFamily1_v5 = 12, 38 iOS_GPUFamily2_v5 = 13, 39 iOS_GPUFamily3_v4 = 14, 40 iOS_GPUFamily4_v2 = 15, 41 iOS_GPUFamily5_v1 = 16, 42 43 tvOS_GPUFamily1_v1 = 30000, 44 tvOS_GPUFamily1_v2 = 30001, 45 tvOS_GPUFamily1_v3 = 30002, 46 tvOS_GPUFamily2_v1 = 30003, 47 tvOS_GPUFamily1_v4 = 30004, 48 tvOS_GPUFamily2_v2 = 30005, 49 50 macOS_GPUFamily1_v1 = 10000, 51 macOS_GPUFamily1_v2 = 10001, 52 //macOS_ReadWriteTextureTier2 = 10002, TODO: Uncomment when feature tables updated 53 macOS_GPUFamily1_v3 = 10003, 54 macOS_GPUFamily1_v4 = 10004, 55 macOS_GPUFamily2_v1 = 10005, 56 } 57 58 #[repr(i64)] 59 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] 60 pub enum MTLGPUFamily { 61 Common1 = 3001, 62 Common2 = 3002, 63 Common3 = 3003, 64 Apple1 = 1001, 65 Apple2 = 1002, 66 Apple3 = 1003, 67 Apple4 = 1004, 68 Apple5 = 1005, 69 Apple6 = 1006, 70 Mac1 = 2001, 71 Mac2 = 2002, 72 MacCatalyst1 = 4001, 73 MacCatalyst2 = 4002, 74 } 75 76 #[repr(u64)] 77 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] 78 pub enum MTLDeviceLocation { 79 BuiltIn = 0, 80 Slot = 1, 81 External = 2, 82 Unspecified = u64::MAX, 83 } 84 85 bitflags! { 86 pub struct PixelFormatCapabilities: u32 { 87 const Filter = 1 << 0; 88 const Write = 1 << 1; 89 const Color = 1 << 2; 90 const Blend = 1 << 3; 91 const Msaa = 1 << 4; 92 const Resolve = 1 << 5; 93 } 94 } 95 96 #[allow(non_camel_case_types)] 97 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] 98 enum OS { 99 iOS, 100 tvOS, 101 macOS, 102 } 103 104 const KB: u32 = 1024; 105 const MB: u32 = 1024 * KB; 106 const GB: u32 = 1024 * MB; 107 108 impl MTLFeatureSet { os(&self) -> OS109 fn os(&self) -> OS { 110 let value = *self as u64; 111 if value < 10_000 { 112 OS::iOS 113 } else if value < 20_000 { 114 OS::macOS 115 } else if value >= 30_000 || value < 40_000 { 116 OS::tvOS 117 } else { 118 unreachable!() 119 } 120 } 121 122 // returns the minor version on macos os_version(&self) -> u32123 fn os_version(&self) -> u32 { 124 use MTLFeatureSet::*; 125 match self { 126 iOS_GPUFamily1_v1 | iOS_GPUFamily2_v1 => 8, 127 iOS_GPUFamily1_v2 | iOS_GPUFamily2_v2 | iOS_GPUFamily3_v1 => 9, 128 iOS_GPUFamily1_v3 | iOS_GPUFamily2_v3 | iOS_GPUFamily3_v2 => 10, 129 iOS_GPUFamily1_v4 | iOS_GPUFamily2_v4 | iOS_GPUFamily3_v3 | iOS_GPUFamily4_v1 => 11, 130 iOS_GPUFamily1_v5 | iOS_GPUFamily2_v5 | iOS_GPUFamily3_v4 | iOS_GPUFamily4_v2 131 | iOS_GPUFamily5_v1 => 12, 132 tvOS_GPUFamily1_v1 => 9, 133 tvOS_GPUFamily1_v2 => 10, 134 tvOS_GPUFamily1_v3 | tvOS_GPUFamily2_v1 => 11, 135 tvOS_GPUFamily1_v4 | tvOS_GPUFamily2_v2 => 12, 136 macOS_GPUFamily1_v1 => 11, 137 macOS_GPUFamily1_v2 => 12, 138 macOS_GPUFamily1_v3 => 13, 139 macOS_GPUFamily1_v4 | macOS_GPUFamily2_v1 => 14, 140 } 141 } 142 gpu_family(&self) -> u32143 fn gpu_family(&self) -> u32 { 144 use MTLFeatureSet::*; 145 match self { 146 iOS_GPUFamily1_v1 | iOS_GPUFamily1_v2 | iOS_GPUFamily1_v3 | iOS_GPUFamily1_v4 147 | iOS_GPUFamily1_v5 | tvOS_GPUFamily1_v1 | tvOS_GPUFamily1_v2 | tvOS_GPUFamily1_v3 148 | tvOS_GPUFamily1_v4 | macOS_GPUFamily1_v1 | macOS_GPUFamily1_v2 149 | macOS_GPUFamily1_v3 | macOS_GPUFamily1_v4 => 1, 150 iOS_GPUFamily2_v1 | iOS_GPUFamily2_v2 | iOS_GPUFamily2_v3 | iOS_GPUFamily2_v4 151 | iOS_GPUFamily2_v5 | tvOS_GPUFamily2_v1 | tvOS_GPUFamily2_v2 | macOS_GPUFamily2_v1 => { 152 2 153 } 154 iOS_GPUFamily3_v1 | iOS_GPUFamily3_v2 | iOS_GPUFamily3_v3 | iOS_GPUFamily3_v4 => 3, 155 iOS_GPUFamily4_v1 | iOS_GPUFamily4_v2 => 4, 156 iOS_GPUFamily5_v1 => 5, 157 } 158 } 159 version(&self) -> u32160 fn version(&self) -> u32 { 161 use MTLFeatureSet::*; 162 match self { 163 iOS_GPUFamily1_v1 | iOS_GPUFamily2_v1 | iOS_GPUFamily3_v1 | iOS_GPUFamily4_v1 164 | iOS_GPUFamily5_v1 | macOS_GPUFamily1_v1 | macOS_GPUFamily2_v1 165 | tvOS_GPUFamily1_v1 | tvOS_GPUFamily2_v1 => 1, 166 iOS_GPUFamily1_v2 | iOS_GPUFamily2_v2 | iOS_GPUFamily3_v2 | iOS_GPUFamily4_v2 167 | macOS_GPUFamily1_v2 | tvOS_GPUFamily1_v2 | tvOS_GPUFamily2_v2 => 2, 168 iOS_GPUFamily1_v3 | iOS_GPUFamily2_v3 | iOS_GPUFamily3_v3 | macOS_GPUFamily1_v3 169 | tvOS_GPUFamily1_v3 => 3, 170 iOS_GPUFamily1_v4 | iOS_GPUFamily2_v4 | iOS_GPUFamily3_v4 | tvOS_GPUFamily1_v4 171 | macOS_GPUFamily1_v4 => 4, 172 iOS_GPUFamily1_v5 | iOS_GPUFamily2_v5 => 5, 173 } 174 } 175 supports_metal_kit(&self) -> bool176 pub fn supports_metal_kit(&self) -> bool { 177 true 178 } 179 supports_metal_performance_shaders(&self) -> bool180 pub fn supports_metal_performance_shaders(&self) -> bool { 181 match self.os() { 182 OS::iOS => self.gpu_family() >= 2, 183 OS::tvOS => true, 184 OS::macOS => self.os_version() >= 13, 185 } 186 } 187 supports_programmable_blending(&self) -> bool188 pub fn supports_programmable_blending(&self) -> bool { 189 self.os() != OS::macOS 190 } 191 supports_pvrtc_pixel_formats(&self) -> bool192 pub fn supports_pvrtc_pixel_formats(&self) -> bool { 193 self.os() != OS::macOS 194 } 195 supports_eac_etc_pixel_formats(&self) -> bool196 pub fn supports_eac_etc_pixel_formats(&self) -> bool { 197 self.os() != OS::macOS 198 } 199 supports_astc_pixel_formats(&self) -> bool200 pub fn supports_astc_pixel_formats(&self) -> bool { 201 match self.os() { 202 OS::iOS => self.gpu_family() >= 2, 203 OS::tvOS => true, 204 OS::macOS => false, 205 } 206 } 207 supports_linear_textures(&self) -> bool208 pub fn supports_linear_textures(&self) -> bool { 209 self.os() != OS::macOS || self.os_version() >= 13 210 } 211 supports_bc_pixel_formats(&self) -> bool212 pub fn supports_bc_pixel_formats(&self) -> bool { 213 self.os() == OS::macOS 214 } 215 supports_msaa_depth_resolve(&self) -> bool216 pub fn supports_msaa_depth_resolve(&self) -> bool { 217 match self.os() { 218 OS::iOS => self.gpu_family() >= 3, 219 OS::tvOS => self.gpu_family() >= 2, 220 OS::macOS => false, 221 } 222 } 223 supports_counting_occlusion_query(&self) -> bool224 pub fn supports_counting_occlusion_query(&self) -> bool { 225 match self.os() { 226 OS::iOS => self.gpu_family() >= 3, 227 OS::tvOS => self.gpu_family() >= 2, 228 OS::macOS => true, 229 } 230 } 231 supports_base_vertex_instance_drawing(&self) -> bool232 pub fn supports_base_vertex_instance_drawing(&self) -> bool { 233 match self.os() { 234 OS::iOS => self.gpu_family() >= 3, 235 OS::tvOS => self.gpu_family() >= 2, 236 OS::macOS => true, 237 } 238 } 239 supports_indirect_buffers(&self) -> bool240 pub fn supports_indirect_buffers(&self) -> bool { 241 match self.os() { 242 OS::iOS => self.gpu_family() >= 3, 243 OS::tvOS => self.gpu_family() >= 2, 244 OS::macOS => true, 245 } 246 } 247 supports_cube_map_texture_arrays(&self) -> bool248 pub fn supports_cube_map_texture_arrays(&self) -> bool { 249 match self.os() { 250 OS::iOS => self.gpu_family() >= 4, 251 OS::tvOS => false, 252 OS::macOS => true, 253 } 254 } 255 supports_texture_barriers(&self) -> bool256 pub fn supports_texture_barriers(&self) -> bool { 257 self.os() == OS::macOS 258 } 259 supports_layered_rendering(&self) -> bool260 pub fn supports_layered_rendering(&self) -> bool { 261 match self.os() { 262 OS::iOS => self.gpu_family() >= 5, 263 OS::tvOS => false, 264 OS::macOS => true, 265 } 266 } 267 supports_tessellation(&self) -> bool268 pub fn supports_tessellation(&self) -> bool { 269 match self.os() { 270 OS::iOS => self.gpu_family() >= 3 && self.os_version() >= 10, 271 OS::tvOS => self.gpu_family() >= 2, 272 OS::macOS => self.os_version() >= 12, 273 } 274 } 275 supports_resource_heaps(&self) -> bool276 pub fn supports_resource_heaps(&self) -> bool { 277 match self.os() { 278 OS::iOS => self.os_version() >= 10, 279 OS::tvOS => self.os_version() >= 10, 280 OS::macOS => self.os_version() >= 13, 281 } 282 } 283 supports_memoryless_render_targets(&self) -> bool284 pub fn supports_memoryless_render_targets(&self) -> bool { 285 match self.os() { 286 OS::iOS => self.os_version() >= 10, 287 OS::tvOS => self.os_version() >= 10, 288 OS::macOS => false, 289 } 290 } 291 supports_function_specialization(&self) -> bool292 pub fn supports_function_specialization(&self) -> bool { 293 match self.os() { 294 OS::iOS => self.os_version() >= 10, 295 OS::tvOS => self.os_version() >= 10, 296 OS::macOS => self.os_version() >= 12, 297 } 298 } 299 supports_function_buffer_read_writes(&self) -> bool300 pub fn supports_function_buffer_read_writes(&self) -> bool { 301 match self.os() { 302 OS::iOS => self.gpu_family() >= 3 && self.os_version() >= 10, 303 OS::tvOS => self.gpu_family() >= 2, 304 OS::macOS => self.os_version() >= 12, 305 } 306 } 307 supports_function_texture_read_writes(&self) -> bool308 pub fn supports_function_texture_read_writes(&self) -> bool { 309 match self.os() { 310 OS::iOS => self.gpu_family() >= 4, 311 OS::tvOS => false, 312 OS::macOS => self.os_version() >= 12, 313 } 314 } 315 supports_array_of_textures(&self) -> bool316 pub fn supports_array_of_textures(&self) -> bool { 317 match self.os() { 318 OS::iOS => self.gpu_family() >= 3 && self.os_version() >= 10, 319 OS::tvOS => self.gpu_family() >= 2, 320 OS::macOS => self.os_version() >= 13, 321 } 322 } 323 supports_array_of_samplers(&self) -> bool324 pub fn supports_array_of_samplers(&self) -> bool { 325 match self.os() { 326 OS::iOS => self.gpu_family() >= 3 && self.os_version() >= 11, 327 OS::tvOS => self.gpu_family() >= 2, 328 OS::macOS => self.os_version() >= 12, 329 } 330 } 331 supports_stencil_texture_views(&self) -> bool332 pub fn supports_stencil_texture_views(&self) -> bool { 333 match self.os() { 334 OS::iOS => self.os_version() >= 10, 335 OS::tvOS => self.os_version() >= 10, 336 OS::macOS => self.os_version() >= 12, 337 } 338 } 339 supports_depth_16_pixel_format(&self) -> bool340 pub fn supports_depth_16_pixel_format(&self) -> bool { 341 self.os() == OS::macOS && self.os_version() >= 12 342 } 343 supports_extended_range_pixel_formats(&self) -> bool344 pub fn supports_extended_range_pixel_formats(&self) -> bool { 345 match self.os() { 346 OS::iOS => self.gpu_family() >= 3 && self.os_version() >= 10, 347 OS::tvOS => self.gpu_family() >= 2, 348 OS::macOS => false, 349 } 350 } 351 supports_wide_color_pixel_format(&self) -> bool352 pub fn supports_wide_color_pixel_format(&self) -> bool { 353 match self.os() { 354 OS::iOS => self.os_version() >= 11, 355 OS::tvOS => self.os_version() >= 11, 356 OS::macOS => self.os_version() >= 13, 357 } 358 } 359 supports_combined_msaa_store_and_resolve_action(&self) -> bool360 pub fn supports_combined_msaa_store_and_resolve_action(&self) -> bool { 361 match self.os() { 362 OS::iOS => self.gpu_family() >= 3 && self.os_version() >= 10, 363 OS::tvOS => self.gpu_family() >= 2, 364 OS::macOS => self.os_version() >= 12, 365 } 366 } 367 supports_deferred_store_action(&self) -> bool368 pub fn supports_deferred_store_action(&self) -> bool { 369 match self.os() { 370 OS::iOS => self.os_version() >= 10, 371 OS::tvOS => self.os_version() >= 10, 372 OS::macOS => self.os_version() >= 12, 373 } 374 } 375 supports_msaa_blits(&self) -> bool376 pub fn supports_msaa_blits(&self) -> bool { 377 match self.os() { 378 OS::iOS => self.os_version() >= 10, 379 OS::tvOS => self.os_version() >= 10, 380 OS::macOS => true, 381 } 382 } 383 supports_srgb_writes(&self) -> bool384 pub fn supports_srgb_writes(&self) -> bool { 385 match self.os() { 386 OS::iOS => self.gpu_family() >= 3 || (self.gpu_family() >= 2 && self.version() >= 3), 387 OS::tvOS => self.os_version() >= 10, 388 OS::macOS => self.gpu_family() >= 2, 389 } 390 } 391 supports_16_bit_unsigned_integer_coordinates(&self) -> bool392 pub fn supports_16_bit_unsigned_integer_coordinates(&self) -> bool { 393 match self.os() { 394 OS::iOS => self.os_version() >= 10, 395 OS::tvOS => self.os_version() >= 10, 396 OS::macOS => self.os_version() >= 12, 397 } 398 } 399 supports_extract_insert_and_reverse_bits(&self) -> bool400 pub fn supports_extract_insert_and_reverse_bits(&self) -> bool { 401 match self.os() { 402 OS::iOS => self.os_version() >= 10, 403 OS::tvOS => self.os_version() >= 10, 404 OS::macOS => self.os_version() >= 12, 405 } 406 } 407 supports_simd_barrier(&self) -> bool408 pub fn supports_simd_barrier(&self) -> bool { 409 match self.os() { 410 OS::iOS => self.os_version() >= 10, 411 OS::tvOS => self.os_version() >= 10, 412 OS::macOS => self.os_version() >= 13, 413 } 414 } 415 supports_sampler_max_anisotropy(&self) -> bool416 pub fn supports_sampler_max_anisotropy(&self) -> bool { 417 match self.os() { 418 OS::iOS => self.os_version() >= 10, 419 OS::tvOS => self.os_version() >= 10, 420 OS::macOS => self.os_version() >= 13, 421 } 422 } 423 supports_sampler_lod_clamp(&self) -> bool424 pub fn supports_sampler_lod_clamp(&self) -> bool { 425 match self.os() { 426 OS::iOS => self.os_version() >= 10, 427 OS::tvOS => self.os_version() >= 10, 428 OS::macOS => self.os_version() >= 13, 429 } 430 } 431 supports_border_color(&self) -> bool432 pub fn supports_border_color(&self) -> bool { 433 self.os() == OS::macOS && self.os_version() >= 12 434 } 435 supports_dual_source_blending(&self) -> bool436 pub fn supports_dual_source_blending(&self) -> bool { 437 match self.os() { 438 OS::iOS => self.os_version() >= 11, 439 OS::tvOS => self.os_version() >= 11, 440 OS::macOS => self.os_version() >= 12, 441 } 442 } 443 supports_argument_buffers(&self) -> bool444 pub fn supports_argument_buffers(&self) -> bool { 445 match self.os() { 446 OS::iOS => self.os_version() >= 11, 447 OS::tvOS => self.os_version() >= 11, 448 OS::macOS => self.os_version() >= 13, 449 } 450 } 451 supports_programmable_sample_positions(&self) -> bool452 pub fn supports_programmable_sample_positions(&self) -> bool { 453 match self.os() { 454 OS::iOS => self.os_version() >= 11, 455 OS::tvOS => self.os_version() >= 11, 456 OS::macOS => self.os_version() >= 13, 457 } 458 } 459 supports_uniform_type(&self) -> bool460 pub fn supports_uniform_type(&self) -> bool { 461 match self.os() { 462 OS::iOS => self.os_version() >= 11, 463 OS::tvOS => self.os_version() >= 11, 464 OS::macOS => self.os_version() >= 13, 465 } 466 } 467 supports_imageblocks(&self) -> bool468 pub fn supports_imageblocks(&self) -> bool { 469 self.os() == OS::iOS && self.gpu_family() >= 4 470 } 471 supports_tile_shaders(&self) -> bool472 pub fn supports_tile_shaders(&self) -> bool { 473 self.os() == OS::iOS && self.gpu_family() >= 4 474 } 475 supports_imageblock_sample_coverage_control(&self) -> bool476 pub fn supports_imageblock_sample_coverage_control(&self) -> bool { 477 self.os() == OS::iOS && self.gpu_family() >= 4 478 } 479 supports_threadgroup_sharing(&self) -> bool480 pub fn supports_threadgroup_sharing(&self) -> bool { 481 self.os() == OS::iOS && self.gpu_family() >= 4 482 } 483 supports_post_depth_coverage(&self) -> bool484 pub fn supports_post_depth_coverage(&self) -> bool { 485 self.os() == OS::iOS && self.gpu_family() >= 4 486 } 487 supports_quad_scoped_permute_operations(&self) -> bool488 pub fn supports_quad_scoped_permute_operations(&self) -> bool { 489 match self.os() { 490 OS::iOS => self.gpu_family() >= 4, 491 OS::tvOS => false, 492 OS::macOS => self.os_version() >= 13, 493 } 494 } 495 supports_raster_order_groups(&self) -> bool496 pub fn supports_raster_order_groups(&self) -> bool { 497 match self.os() { 498 OS::iOS => self.gpu_family() >= 4, 499 OS::tvOS => false, 500 OS::macOS => self.os_version() >= 13, 501 } 502 } 503 supports_non_uniform_threadgroup_size(&self) -> bool504 pub fn supports_non_uniform_threadgroup_size(&self) -> bool { 505 match self.os() { 506 OS::iOS => self.gpu_family() >= 4, 507 OS::tvOS => false, 508 OS::macOS => self.os_version() >= 13, 509 } 510 } 511 supports_multiple_viewports(&self) -> bool512 pub fn supports_multiple_viewports(&self) -> bool { 513 match self.os() { 514 OS::iOS => self.gpu_family() >= 5, 515 OS::tvOS => false, 516 OS::macOS => self.os_version() >= 13, 517 } 518 } 519 supports_device_notifications(&self) -> bool520 pub fn supports_device_notifications(&self) -> bool { 521 self.os() == OS::macOS && self.os_version() >= 13 522 } 523 supports_stencil_feedback(&self) -> bool524 pub fn supports_stencil_feedback(&self) -> bool { 525 match self.os() { 526 OS::iOS => self.gpu_family() >= 5, 527 OS::tvOS => false, 528 OS::macOS => self.gpu_family() >= 2, 529 } 530 } 531 supports_stencil_resolve(&self) -> bool532 pub fn supports_stencil_resolve(&self) -> bool { 533 match self.os() { 534 OS::iOS => self.gpu_family() >= 5, 535 OS::tvOS => false, 536 OS::macOS => self.gpu_family() >= 2, 537 } 538 } 539 supports_binary_archive(&self) -> bool540 pub fn supports_binary_archive(&self) -> bool { 541 match self.os() { 542 OS::iOS => self.gpu_family() >= 3, 543 OS::tvOS => self.gpu_family() >= 3, 544 OS::macOS => self.gpu_family() >= 1, 545 } 546 } 547 max_vertex_attributes(&self) -> u32548 pub fn max_vertex_attributes(&self) -> u32 { 549 31 550 } 551 max_buffer_argument_entries(&self) -> u32552 pub fn max_buffer_argument_entries(&self) -> u32 { 553 31 554 } 555 max_texture_argument_entries(&self) -> u32556 pub fn max_texture_argument_entries(&self) -> u32 { 557 if self.os() == OS::macOS { 558 128 559 } else { 560 31 561 } 562 } 563 max_sampler_state_argument_entries(&self) -> u32564 pub fn max_sampler_state_argument_entries(&self) -> u32 { 565 16 566 } 567 max_threadgroup_memory_argument_entries(&self) -> u32568 pub fn max_threadgroup_memory_argument_entries(&self) -> u32 { 569 31 570 } 571 max_inlined_constant_data_buffers(&self) -> u32572 pub fn max_inlined_constant_data_buffers(&self) -> u32 { 573 if self.os() == OS::macOS { 574 14 575 } else { 576 31 577 } 578 } 579 max_inline_constant_buffer_length(&self) -> u32580 pub fn max_inline_constant_buffer_length(&self) -> u32 { 581 4 * KB 582 } 583 max_threads_per_threadgroup(&self) -> u32584 pub fn max_threads_per_threadgroup(&self) -> u32 { 585 if self.os() == OS::macOS || self.gpu_family() >= 4 { 586 1024 587 } else { 588 512 589 } 590 } 591 max_total_threadgroup_memory_allocation(&self) -> u32592 pub fn max_total_threadgroup_memory_allocation(&self) -> u32 { 593 match (self.os(), self.gpu_family()) { 594 (OS::iOS, 5) => 64 * KB, 595 (OS::iOS, 4) => { 596 if self.os_version() >= 12 { 597 64 * KB 598 } else { 599 32 * KB 600 } 601 } 602 (OS::iOS, 3) => 16 * KB, 603 (OS::iOS, _) => 16 * KB - 32, 604 (OS::tvOS, 1) => 16 * KB - 32, 605 (OS::tvOS, _) => 16 * KB, 606 (OS::macOS, _) => 32 * KB, 607 } 608 } 609 max_total_tile_memory_allocation(&self) -> u32610 pub fn max_total_tile_memory_allocation(&self) -> u32 { 611 if self.os() == OS::iOS && self.gpu_family() == 4 { 612 32 * KB 613 } else { 614 0 615 } 616 } 617 threadgroup_memory_length_alignment(&self) -> u32618 pub fn threadgroup_memory_length_alignment(&self) -> u32 { 619 16 620 } 621 max_constant_buffer_function_memory_allocation(&self) -> Option<u32>622 pub fn max_constant_buffer_function_memory_allocation(&self) -> Option<u32> { 623 if self.os() == OS::macOS { 624 Some(64 * KB) 625 } else { 626 None 627 } 628 } 629 max_fragment_inputs(&self) -> u32630 pub fn max_fragment_inputs(&self) -> u32 { 631 if self.os() == OS::macOS { 632 32 633 } else { 634 60 635 } 636 } 637 max_fragment_input_components(&self) -> u32638 pub fn max_fragment_input_components(&self) -> u32 { 639 if self.os() == OS::macOS { 640 128 641 } else { 642 60 643 } 644 } 645 max_function_constants(&self) -> u32646 pub fn max_function_constants(&self) -> u32 { 647 match self.os() { 648 OS::iOS if self.os_version() >= 11 => 65536, 649 OS::tvOS if self.os_version() >= 10 => 65536, 650 OS::macOS if self.os_version() >= 12 => 65536, 651 _ => 0, 652 } 653 } 654 max_tessellation_factor(&self) -> u32655 pub fn max_tessellation_factor(&self) -> u32 { 656 if self.supports_tessellation() { 657 match self.os() { 658 OS::iOS if self.gpu_family() >= 5 => 64, 659 OS::iOS => 16, 660 OS::tvOS => 16, 661 OS::macOS => 64, 662 } 663 } else { 664 0 665 } 666 } 667 max_viewports_and_scissor_rectangles(&self) -> u32668 pub fn max_viewports_and_scissor_rectangles(&self) -> u32 { 669 if self.supports_multiple_viewports() { 670 16 671 } else { 672 1 673 } 674 } 675 max_raster_order_groups(&self) -> u32676 pub fn max_raster_order_groups(&self) -> u32 { 677 if self.supports_raster_order_groups() { 678 8 679 } else { 680 0 681 } 682 } 683 max_buffer_length(&self) -> u32684 pub fn max_buffer_length(&self) -> u32 { 685 if self.os() == OS::macOS && self.os_version() >= 12 { 686 1 * GB 687 } else { 688 256 * MB 689 } 690 } 691 min_buffer_offset_alignment(&self) -> u32692 pub fn min_buffer_offset_alignment(&self) -> u32 { 693 if self.os() == OS::macOS { 694 256 695 } else { 696 4 697 } 698 } 699 max_1d_texture_size(&self) -> u32700 pub fn max_1d_texture_size(&self) -> u32 { 701 match (self.os(), self.gpu_family()) { 702 (OS::iOS, 1) | (OS::iOS, 2) => { 703 if self.version() <= 2 { 704 4096 705 } else { 706 8192 707 } 708 } 709 (OS::tvOS, 1) => 8192, 710 _ => 16384, 711 } 712 } 713 max_2d_texture_size(&self) -> u32714 pub fn max_2d_texture_size(&self) -> u32 { 715 match (self.os(), self.gpu_family()) { 716 (OS::iOS, 1) | (OS::iOS, 2) => { 717 if self.version() <= 2 { 718 4096 719 } else { 720 8192 721 } 722 } 723 (OS::tvOS, 1) => 8192, 724 _ => 16384, 725 } 726 } 727 max_cube_map_texture_size(&self) -> u32728 pub fn max_cube_map_texture_size(&self) -> u32 { 729 match (self.os(), self.gpu_family()) { 730 (OS::iOS, 1) | (OS::iOS, 2) => { 731 if self.version() <= 2 { 732 4096 733 } else { 734 8192 735 } 736 } 737 (OS::tvOS, 1) => 8192, 738 _ => 16384, 739 } 740 } 741 max_3d_texture_size(&self) -> u32742 pub fn max_3d_texture_size(&self) -> u32 { 743 2048 744 } 745 max_array_layers(&self) -> u32746 pub fn max_array_layers(&self) -> u32 { 747 2048 748 } 749 copy_texture_buffer_alignment(&self) -> u32750 pub fn copy_texture_buffer_alignment(&self) -> u32 { 751 match (self.os(), self.gpu_family()) { 752 (OS::iOS, 1) | (OS::iOS, 2) | (OS::tvOS, 1) => 64, 753 (OS::iOS, _) | (OS::tvOS, _) => 16, 754 (OS::macOS, _) => 256, 755 } 756 } 757 758 /// If this function returns `None` but linear textures are supported, 759 /// the buffer alignment can be discovered via API query new_texture_buffer_alignment(&self) -> Option<u32>760 pub fn new_texture_buffer_alignment(&self) -> Option<u32> { 761 match self.os() { 762 OS::iOS => { 763 if self.os_version() >= 11 { 764 None 765 } else if self.gpu_family() == 3 { 766 Some(16) 767 } else { 768 Some(64) 769 } 770 } 771 OS::tvOS => { 772 if self.os_version() >= 11 { 773 None 774 } else { 775 Some(64) 776 } 777 } 778 OS::macOS => None, 779 } 780 } 781 max_color_render_targets(&self) -> u32782 pub fn max_color_render_targets(&self) -> u32 { 783 if self.os() == OS::iOS && self.gpu_family() == 1 { 784 4 785 } else { 786 8 787 } 788 } 789 max_point_primitive_size(&self) -> u32790 pub fn max_point_primitive_size(&self) -> u32 { 791 511 792 } 793 max_total_color_render_target_size(&self) -> Option<u32>794 pub fn max_total_color_render_target_size(&self) -> Option<u32> { 795 match (self.os(), self.gpu_family()) { 796 (OS::iOS, 1) => Some(128), 797 (OS::iOS, 2) | (OS::iOS, 3) => Some(256), 798 (OS::iOS, _) => Some(512), 799 (OS::tvOS, _) => Some(256), 800 (OS::macOS, _) => None, 801 } 802 } 803 max_visibility_query_offset(&self) -> u32804 pub fn max_visibility_query_offset(&self) -> u32 { 805 64 * KB - 8 806 } 807 a8_unorm_capabilities(&self) -> PixelFormatCapabilities808 pub fn a8_unorm_capabilities(&self) -> PixelFormatCapabilities { 809 PixelFormatCapabilities::Filter 810 } 811 r8_unorm_capabilities(&self) -> PixelFormatCapabilities812 pub fn r8_unorm_capabilities(&self) -> PixelFormatCapabilities { 813 PixelFormatCapabilities::all() 814 } 815 r8_unorm_srgb_capabilities(&self) -> PixelFormatCapabilities816 pub fn r8_unorm_srgb_capabilities(&self) -> PixelFormatCapabilities { 817 if self.os() == OS::macOS { 818 PixelFormatCapabilities::empty() 819 } else if self.supports_srgb_writes() { 820 PixelFormatCapabilities::all() 821 } else { 822 !PixelFormatCapabilities::Write 823 } 824 } 825 r8_snorm_capabilities(&self) -> PixelFormatCapabilities826 pub fn r8_snorm_capabilities(&self) -> PixelFormatCapabilities { 827 if self.os() == OS::iOS && self.gpu_family() == 1 { 828 !PixelFormatCapabilities::Resolve 829 } else { 830 PixelFormatCapabilities::all() 831 } 832 } 833 r8_uint_capabilities(&self) -> PixelFormatCapabilities834 pub fn r8_uint_capabilities(&self) -> PixelFormatCapabilities { 835 PixelFormatCapabilities::Write 836 | PixelFormatCapabilities::Color 837 | PixelFormatCapabilities::Msaa 838 } 839 r8_sint_capabilities(&self) -> PixelFormatCapabilities840 pub fn r8_sint_capabilities(&self) -> PixelFormatCapabilities { 841 PixelFormatCapabilities::Write 842 | PixelFormatCapabilities::Color 843 | PixelFormatCapabilities::Msaa 844 } 845 r16_unorm_capabilities(&self) -> PixelFormatCapabilities846 pub fn r16_unorm_capabilities(&self) -> PixelFormatCapabilities { 847 if self.os() != OS::macOS { 848 !PixelFormatCapabilities::Resolve 849 } else { 850 PixelFormatCapabilities::all() 851 } 852 } 853 r16_snorm_capabilities(&self) -> PixelFormatCapabilities854 pub fn r16_snorm_capabilities(&self) -> PixelFormatCapabilities { 855 if self.os() != OS::macOS { 856 !PixelFormatCapabilities::Resolve 857 } else { 858 PixelFormatCapabilities::all() 859 } 860 } 861 r16_uint_capabilities(&self) -> PixelFormatCapabilities862 pub fn r16_uint_capabilities(&self) -> PixelFormatCapabilities { 863 PixelFormatCapabilities::Write 864 | PixelFormatCapabilities::Color 865 | PixelFormatCapabilities::Msaa 866 } 867 r16_sint_capabilities(&self) -> PixelFormatCapabilities868 pub fn r16_sint_capabilities(&self) -> PixelFormatCapabilities { 869 PixelFormatCapabilities::Write 870 | PixelFormatCapabilities::Color 871 | PixelFormatCapabilities::Msaa 872 } 873 r16_float_capabilities(&self) -> PixelFormatCapabilities874 pub fn r16_float_capabilities(&self) -> PixelFormatCapabilities { 875 PixelFormatCapabilities::all() 876 } 877 rg8_unorm_capabilities(&self) -> PixelFormatCapabilities878 pub fn rg8_unorm_capabilities(&self) -> PixelFormatCapabilities { 879 PixelFormatCapabilities::all() 880 } 881 rg8_unorm_srgb_capabilities(&self) -> PixelFormatCapabilities882 pub fn rg8_unorm_srgb_capabilities(&self) -> PixelFormatCapabilities { 883 if self.os() == OS::macOS { 884 PixelFormatCapabilities::empty() 885 } else if self.supports_srgb_writes() { 886 PixelFormatCapabilities::all() 887 } else { 888 !PixelFormatCapabilities::Write 889 } 890 } 891 rg8_snorm_capabilities(&self) -> PixelFormatCapabilities892 pub fn rg8_snorm_capabilities(&self) -> PixelFormatCapabilities { 893 if self.os() == OS::iOS && self.gpu_family() == 1 { 894 !PixelFormatCapabilities::Resolve 895 } else { 896 PixelFormatCapabilities::all() 897 } 898 } 899 rg8_uint_capabilities(&self) -> PixelFormatCapabilities900 pub fn rg8_uint_capabilities(&self) -> PixelFormatCapabilities { 901 PixelFormatCapabilities::Write 902 | PixelFormatCapabilities::Color 903 | PixelFormatCapabilities::Msaa 904 } 905 rg8_sint_capabilities(&self) -> PixelFormatCapabilities906 pub fn rg8_sint_capabilities(&self) -> PixelFormatCapabilities { 907 PixelFormatCapabilities::Write 908 | PixelFormatCapabilities::Color 909 | PixelFormatCapabilities::Msaa 910 } 911 b5_g6_r5_unorm_capabilities(&self) -> PixelFormatCapabilities912 pub fn b5_g6_r5_unorm_capabilities(&self) -> PixelFormatCapabilities { 913 if self.os() == OS::macOS { 914 PixelFormatCapabilities::empty() 915 } else { 916 !PixelFormatCapabilities::Write 917 } 918 } 919 a1_bgr5_unorm_capabilities(&self) -> PixelFormatCapabilities920 pub fn a1_bgr5_unorm_capabilities(&self) -> PixelFormatCapabilities { 921 if self.os() == OS::macOS { 922 PixelFormatCapabilities::empty() 923 } else { 924 !PixelFormatCapabilities::Write 925 } 926 } 927 abgr4_unorm_capabilities(&self) -> PixelFormatCapabilities928 pub fn abgr4_unorm_capabilities(&self) -> PixelFormatCapabilities { 929 if self.os() == OS::macOS { 930 PixelFormatCapabilities::empty() 931 } else { 932 !PixelFormatCapabilities::Write 933 } 934 } 935 bgr5_a1_unorm_capabilities(&self) -> PixelFormatCapabilities936 pub fn bgr5_a1_unorm_capabilities(&self) -> PixelFormatCapabilities { 937 if self.os() == OS::macOS { 938 PixelFormatCapabilities::empty() 939 } else { 940 !PixelFormatCapabilities::Write 941 } 942 } 943 r32_uint_capabilities(&self) -> PixelFormatCapabilities944 pub fn r32_uint_capabilities(&self) -> PixelFormatCapabilities { 945 if self.os() == OS::iOS && self.os_version() == 8 { 946 PixelFormatCapabilities::Color 947 } else if self.os() == OS::macOS { 948 PixelFormatCapabilities::Color 949 | PixelFormatCapabilities::Write 950 | PixelFormatCapabilities::Msaa 951 } else { 952 PixelFormatCapabilities::Color | PixelFormatCapabilities::Write 953 } 954 } 955 r32_sint_capabilities(&self) -> PixelFormatCapabilities956 pub fn r32_sint_capabilities(&self) -> PixelFormatCapabilities { 957 if self.os() == OS::iOS && self.os_version() == 8 { 958 PixelFormatCapabilities::Color 959 } else if self.os() == OS::macOS { 960 PixelFormatCapabilities::Color 961 | PixelFormatCapabilities::Write 962 | PixelFormatCapabilities::Msaa 963 } else { 964 PixelFormatCapabilities::Color | PixelFormatCapabilities::Write 965 } 966 } 967 r32_float_capabilities(&self) -> PixelFormatCapabilities968 pub fn r32_float_capabilities(&self) -> PixelFormatCapabilities { 969 if self.os() == OS::iOS && self.os_version() == 8 { 970 PixelFormatCapabilities::Color 971 | PixelFormatCapabilities::Blend 972 | PixelFormatCapabilities::Msaa 973 } else if self.os() == OS::macOS { 974 PixelFormatCapabilities::all() 975 } else { 976 PixelFormatCapabilities::Write 977 | PixelFormatCapabilities::Color 978 | PixelFormatCapabilities::Blend 979 | PixelFormatCapabilities::Msaa 980 } 981 } 982 rg16_unorm_capabilities(&self) -> PixelFormatCapabilities983 pub fn rg16_unorm_capabilities(&self) -> PixelFormatCapabilities { 984 if self.os() == OS::macOS { 985 PixelFormatCapabilities::all() 986 } else { 987 !PixelFormatCapabilities::Resolve 988 } 989 } 990 rg16_snorm_capabilities(&self) -> PixelFormatCapabilities991 pub fn rg16_snorm_capabilities(&self) -> PixelFormatCapabilities { 992 if self.os() == OS::macOS { 993 PixelFormatCapabilities::all() 994 } else { 995 !PixelFormatCapabilities::Resolve 996 } 997 } 998 rg16_uint_capabilities(&self) -> PixelFormatCapabilities999 pub fn rg16_uint_capabilities(&self) -> PixelFormatCapabilities { 1000 PixelFormatCapabilities::Write 1001 | PixelFormatCapabilities::Color 1002 | PixelFormatCapabilities::Msaa 1003 } 1004 rg16_sint_capabilities(&self) -> PixelFormatCapabilities1005 pub fn rg16_sint_capabilities(&self) -> PixelFormatCapabilities { 1006 PixelFormatCapabilities::Write 1007 | PixelFormatCapabilities::Color 1008 | PixelFormatCapabilities::Msaa 1009 } 1010 rg16_float_capabilities(&self) -> PixelFormatCapabilities1011 pub fn rg16_float_capabilities(&self) -> PixelFormatCapabilities { 1012 PixelFormatCapabilities::all() 1013 } 1014 rgba8_unorm_capabilities(&self) -> PixelFormatCapabilities1015 pub fn rgba8_unorm_capabilities(&self) -> PixelFormatCapabilities { 1016 PixelFormatCapabilities::all() 1017 } 1018 rgba8_unorm_srgb_capabilities(&self) -> PixelFormatCapabilities1019 pub fn rgba8_unorm_srgb_capabilities(&self) -> PixelFormatCapabilities { 1020 if self.supports_srgb_writes() { 1021 PixelFormatCapabilities::all() 1022 } else { 1023 !PixelFormatCapabilities::Write 1024 } 1025 } 1026 rgba8_snorm_capabilities(&self) -> PixelFormatCapabilities1027 pub fn rgba8_snorm_capabilities(&self) -> PixelFormatCapabilities { 1028 if self.os() == OS::iOS && self.gpu_family() == 1 { 1029 !PixelFormatCapabilities::Resolve 1030 } else { 1031 PixelFormatCapabilities::all() 1032 } 1033 } 1034 rgba8_uint_capabilities(&self) -> PixelFormatCapabilities1035 pub fn rgba8_uint_capabilities(&self) -> PixelFormatCapabilities { 1036 PixelFormatCapabilities::Write 1037 | PixelFormatCapabilities::Color 1038 | PixelFormatCapabilities::Msaa 1039 } 1040 rgba8_sint_capabilities(&self) -> PixelFormatCapabilities1041 pub fn rgba8_sint_capabilities(&self) -> PixelFormatCapabilities { 1042 PixelFormatCapabilities::Write 1043 | PixelFormatCapabilities::Color 1044 | PixelFormatCapabilities::Msaa 1045 } 1046 bgra8_unorm_capabilities(&self) -> PixelFormatCapabilities1047 pub fn bgra8_unorm_capabilities(&self) -> PixelFormatCapabilities { 1048 PixelFormatCapabilities::all() 1049 } 1050 bgra8_unorm_srgb_capabilities(&self) -> PixelFormatCapabilities1051 pub fn bgra8_unorm_srgb_capabilities(&self) -> PixelFormatCapabilities { 1052 if self.supports_srgb_writes() { 1053 PixelFormatCapabilities::all() 1054 } else { 1055 !PixelFormatCapabilities::Write 1056 } 1057 } 1058 rgb10_a2_unorm_capabilities(&self) -> PixelFormatCapabilities1059 pub fn rgb10_a2_unorm_capabilities(&self) -> PixelFormatCapabilities { 1060 let supports_writes = match self.os() { 1061 OS::iOS => self.gpu_family() >= 3, 1062 OS::tvOS => self.gpu_family() >= 2, 1063 OS::macOS => true, 1064 }; 1065 if supports_writes { 1066 PixelFormatCapabilities::all() 1067 } else { 1068 !PixelFormatCapabilities::Write 1069 } 1070 } 1071 rgb10_a2_uint_capabilities(&self) -> PixelFormatCapabilities1072 pub fn rgb10_a2_uint_capabilities(&self) -> PixelFormatCapabilities { 1073 let supports_writes = match self.os() { 1074 OS::iOS => self.gpu_family() >= 3, 1075 OS::tvOS => self.gpu_family() >= 2, 1076 OS::macOS => true, 1077 }; 1078 if supports_writes { 1079 PixelFormatCapabilities::Write 1080 | PixelFormatCapabilities::Color 1081 | PixelFormatCapabilities::Msaa 1082 } else { 1083 PixelFormatCapabilities::Color | PixelFormatCapabilities::Msaa 1084 } 1085 } 1086 rg11_b10_float_capabilities(&self) -> PixelFormatCapabilities1087 pub fn rg11_b10_float_capabilities(&self) -> PixelFormatCapabilities { 1088 let supports_writes = match self.os() { 1089 OS::iOS => self.gpu_family() >= 3, 1090 OS::tvOS => self.gpu_family() >= 2, 1091 OS::macOS => true, 1092 }; 1093 if supports_writes { 1094 PixelFormatCapabilities::all() 1095 } else { 1096 !PixelFormatCapabilities::Write 1097 } 1098 } 1099 rgb9_e5_float_capabilities(&self) -> PixelFormatCapabilities1100 pub fn rgb9_e5_float_capabilities(&self) -> PixelFormatCapabilities { 1101 if self.os() == OS::macOS { 1102 PixelFormatCapabilities::Filter 1103 } else { 1104 let supports_writes = match self.os() { 1105 OS::iOS => self.gpu_family() >= 3, 1106 OS::tvOS => self.gpu_family() >= 2, 1107 OS::macOS => false, 1108 }; 1109 if supports_writes { 1110 PixelFormatCapabilities::all() 1111 } else { 1112 !PixelFormatCapabilities::Write 1113 } 1114 } 1115 } 1116 rg32_uint_capabilities(&self) -> PixelFormatCapabilities1117 pub fn rg32_uint_capabilities(&self) -> PixelFormatCapabilities { 1118 if self.os() == OS::iOS && self.os_version() == 8 { 1119 PixelFormatCapabilities::Color 1120 } else if self.os() == OS::macOS { 1121 PixelFormatCapabilities::Color 1122 | PixelFormatCapabilities::Write 1123 | PixelFormatCapabilities::Msaa 1124 } else { 1125 PixelFormatCapabilities::Color | PixelFormatCapabilities::Write 1126 } 1127 } 1128 rg32_sint_capabilities(&self) -> PixelFormatCapabilities1129 pub fn rg32_sint_capabilities(&self) -> PixelFormatCapabilities { 1130 if self.os() == OS::iOS && self.os_version() == 8 { 1131 PixelFormatCapabilities::Color 1132 } else if self.os() == OS::macOS { 1133 PixelFormatCapabilities::Color 1134 | PixelFormatCapabilities::Write 1135 | PixelFormatCapabilities::Msaa 1136 } else { 1137 PixelFormatCapabilities::Color | PixelFormatCapabilities::Write 1138 } 1139 } 1140 rg32_float_capabilities(&self) -> PixelFormatCapabilities1141 pub fn rg32_float_capabilities(&self) -> PixelFormatCapabilities { 1142 if self.os() == OS::macOS { 1143 PixelFormatCapabilities::all() 1144 } else if self.os() == OS::iOS && self.os_version() == 8 { 1145 PixelFormatCapabilities::Color | PixelFormatCapabilities::Blend 1146 } else { 1147 PixelFormatCapabilities::Write 1148 | PixelFormatCapabilities::Color 1149 | PixelFormatCapabilities::Blend 1150 } 1151 } 1152 rgba16_unorm_capabilities(&self) -> PixelFormatCapabilities1153 pub fn rgba16_unorm_capabilities(&self) -> PixelFormatCapabilities { 1154 if self.os() == OS::macOS { 1155 PixelFormatCapabilities::all() 1156 } else { 1157 !PixelFormatCapabilities::Write 1158 } 1159 } 1160 rgba16_snorm_capabilities(&self) -> PixelFormatCapabilities1161 pub fn rgba16_snorm_capabilities(&self) -> PixelFormatCapabilities { 1162 if self.os() == OS::macOS { 1163 PixelFormatCapabilities::all() 1164 } else { 1165 !PixelFormatCapabilities::Write 1166 } 1167 } 1168 rgba16_uint_capabilities(&self) -> PixelFormatCapabilities1169 pub fn rgba16_uint_capabilities(&self) -> PixelFormatCapabilities { 1170 PixelFormatCapabilities::Write 1171 | PixelFormatCapabilities::Color 1172 | PixelFormatCapabilities::Msaa 1173 } 1174 rgba16_sint_capabilities(&self) -> PixelFormatCapabilities1175 pub fn rgba16_sint_capabilities(&self) -> PixelFormatCapabilities { 1176 PixelFormatCapabilities::Write 1177 | PixelFormatCapabilities::Color 1178 | PixelFormatCapabilities::Msaa 1179 } 1180 rgba16_float_capabilities(&self) -> PixelFormatCapabilities1181 pub fn rgba16_float_capabilities(&self) -> PixelFormatCapabilities { 1182 PixelFormatCapabilities::all() 1183 } 1184 rgba32_uint_capabilities(&self) -> PixelFormatCapabilities1185 pub fn rgba32_uint_capabilities(&self) -> PixelFormatCapabilities { 1186 if self.os() == OS::iOS && self.os_version() == 8 { 1187 PixelFormatCapabilities::Color 1188 } else if self.os() == OS::macOS { 1189 PixelFormatCapabilities::Color 1190 | PixelFormatCapabilities::Write 1191 | PixelFormatCapabilities::Msaa 1192 } else { 1193 PixelFormatCapabilities::Color | PixelFormatCapabilities::Write 1194 } 1195 } 1196 rgba32_sint_capabilities(&self) -> PixelFormatCapabilities1197 pub fn rgba32_sint_capabilities(&self) -> PixelFormatCapabilities { 1198 if self.os() == OS::iOS && self.os_version() == 8 { 1199 PixelFormatCapabilities::Color 1200 } else if self.os() == OS::macOS { 1201 PixelFormatCapabilities::Color 1202 | PixelFormatCapabilities::Write 1203 | PixelFormatCapabilities::Msaa 1204 } else { 1205 PixelFormatCapabilities::Color | PixelFormatCapabilities::Write 1206 } 1207 } 1208 rgba32_float_capabilities(&self) -> PixelFormatCapabilities1209 pub fn rgba32_float_capabilities(&self) -> PixelFormatCapabilities { 1210 if self.os() == OS::macOS { 1211 PixelFormatCapabilities::all() 1212 } else if self.os() == OS::iOS && self.version() == 8 { 1213 PixelFormatCapabilities::Color 1214 } else { 1215 PixelFormatCapabilities::Write | PixelFormatCapabilities::Color 1216 } 1217 } 1218 pvrtc_pixel_formats_capabilities(&self) -> PixelFormatCapabilities1219 pub fn pvrtc_pixel_formats_capabilities(&self) -> PixelFormatCapabilities { 1220 if self.supports_pvrtc_pixel_formats() { 1221 PixelFormatCapabilities::Filter 1222 } else { 1223 PixelFormatCapabilities::empty() 1224 } 1225 } 1226 eac_etc_pixel_formats_capabilities(&self) -> PixelFormatCapabilities1227 pub fn eac_etc_pixel_formats_capabilities(&self) -> PixelFormatCapabilities { 1228 if self.supports_eac_etc_pixel_formats() { 1229 PixelFormatCapabilities::Filter 1230 } else { 1231 PixelFormatCapabilities::empty() 1232 } 1233 } 1234 astc_pixel_formats_capabilities(&self) -> PixelFormatCapabilities1235 pub fn astc_pixel_formats_capabilities(&self) -> PixelFormatCapabilities { 1236 if self.supports_astc_pixel_formats() { 1237 PixelFormatCapabilities::Filter 1238 } else { 1239 PixelFormatCapabilities::empty() 1240 } 1241 } 1242 bc_pixel_formats_capabilities(&self) -> PixelFormatCapabilities1243 pub fn bc_pixel_formats_capabilities(&self) -> PixelFormatCapabilities { 1244 if self.supports_bc_pixel_formats() { 1245 PixelFormatCapabilities::Filter 1246 } else { 1247 PixelFormatCapabilities::empty() 1248 } 1249 } 1250 gbgr422_capabilities(&self) -> PixelFormatCapabilities1251 pub fn gbgr422_capabilities(&self) -> PixelFormatCapabilities { 1252 PixelFormatCapabilities::Filter 1253 } 1254 bgrg422_capabilities(&self) -> PixelFormatCapabilities1255 pub fn bgrg422_capabilities(&self) -> PixelFormatCapabilities { 1256 PixelFormatCapabilities::Filter 1257 } 1258 depth16_unorm_capabilities(&self) -> PixelFormatCapabilities1259 pub fn depth16_unorm_capabilities(&self) -> PixelFormatCapabilities { 1260 if self.supports_depth_16_pixel_format() { 1261 PixelFormatCapabilities::Filter 1262 | PixelFormatCapabilities::Msaa 1263 | PixelFormatCapabilities::Resolve 1264 } else { 1265 PixelFormatCapabilities::empty() 1266 } 1267 } 1268 depth32_float_capabilities(&self) -> PixelFormatCapabilities1269 pub fn depth32_float_capabilities(&self) -> PixelFormatCapabilities { 1270 if self.os() == OS::macOS { 1271 PixelFormatCapabilities::Filter 1272 | PixelFormatCapabilities::Msaa 1273 | PixelFormatCapabilities::Resolve 1274 } else if self.supports_msaa_depth_resolve() { 1275 PixelFormatCapabilities::Msaa | PixelFormatCapabilities::Resolve 1276 } else { 1277 PixelFormatCapabilities::Msaa 1278 } 1279 } 1280 stencil8_capabilities(&self) -> PixelFormatCapabilities1281 pub fn stencil8_capabilities(&self) -> PixelFormatCapabilities { 1282 PixelFormatCapabilities::Msaa 1283 } 1284 depth24_unorm_stencil8_capabilities(&self) -> PixelFormatCapabilities1285 pub fn depth24_unorm_stencil8_capabilities(&self) -> PixelFormatCapabilities { 1286 if self.os() == OS::macOS { 1287 PixelFormatCapabilities::Filter 1288 | PixelFormatCapabilities::Msaa 1289 | PixelFormatCapabilities::Resolve 1290 } else { 1291 PixelFormatCapabilities::empty() 1292 } 1293 } 1294 depth32_float_stencil8_capabilities(&self) -> PixelFormatCapabilities1295 pub fn depth32_float_stencil8_capabilities(&self) -> PixelFormatCapabilities { 1296 if self.os() == OS::macOS { 1297 PixelFormatCapabilities::Filter 1298 | PixelFormatCapabilities::Msaa 1299 | PixelFormatCapabilities::Resolve 1300 } else if self.supports_msaa_depth_resolve() { 1301 PixelFormatCapabilities::Msaa | PixelFormatCapabilities::Resolve 1302 } else { 1303 PixelFormatCapabilities::Msaa 1304 } 1305 } 1306 x24_stencil8_capabilities(&self) -> PixelFormatCapabilities1307 pub fn x24_stencil8_capabilities(&self) -> PixelFormatCapabilities { 1308 if self.os() == OS::macOS { 1309 PixelFormatCapabilities::Msaa 1310 } else { 1311 PixelFormatCapabilities::empty() 1312 } 1313 } 1314 x32_stencil8_capabilities(&self) -> PixelFormatCapabilities1315 pub fn x32_stencil8_capabilities(&self) -> PixelFormatCapabilities { 1316 PixelFormatCapabilities::Msaa 1317 } 1318 bgra10_xr_capabilities(&self) -> PixelFormatCapabilities1319 pub fn bgra10_xr_capabilities(&self) -> PixelFormatCapabilities { 1320 if self.supports_extended_range_pixel_formats() { 1321 PixelFormatCapabilities::all() 1322 } else { 1323 PixelFormatCapabilities::empty() 1324 } 1325 } 1326 bgra10_xr_srgb_capabilities(&self) -> PixelFormatCapabilities1327 pub fn bgra10_xr_srgb_capabilities(&self) -> PixelFormatCapabilities { 1328 if self.supports_extended_range_pixel_formats() { 1329 PixelFormatCapabilities::all() 1330 } else { 1331 PixelFormatCapabilities::empty() 1332 } 1333 } 1334 bgr10_xr_capabilities(&self) -> PixelFormatCapabilities1335 pub fn bgr10_xr_capabilities(&self) -> PixelFormatCapabilities { 1336 if self.supports_extended_range_pixel_formats() { 1337 PixelFormatCapabilities::all() 1338 } else { 1339 PixelFormatCapabilities::empty() 1340 } 1341 } 1342 bgr10_xr_srgb_capabilities(&self) -> PixelFormatCapabilities1343 pub fn bgr10_xr_srgb_capabilities(&self) -> PixelFormatCapabilities { 1344 if self.supports_extended_range_pixel_formats() { 1345 PixelFormatCapabilities::all() 1346 } else { 1347 PixelFormatCapabilities::empty() 1348 } 1349 } 1350 bgr10_a2_unorm_capabilities(&self) -> PixelFormatCapabilities1351 pub fn bgr10_a2_unorm_capabilities(&self) -> PixelFormatCapabilities { 1352 if self.supports_wide_color_pixel_format() { 1353 if self.os() == OS::macOS { 1354 !PixelFormatCapabilities::Write 1355 } else { 1356 PixelFormatCapabilities::all() 1357 } 1358 } else { 1359 PixelFormatCapabilities::empty() 1360 } 1361 } 1362 } 1363 1364 #[repr(u64)] 1365 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] 1366 pub enum MTLArgumentBuffersTier { 1367 Tier1 = 0, 1368 Tier2 = 1, 1369 } 1370 1371 #[repr(u64)] 1372 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] 1373 pub enum MTLReadWriteTextureTier { 1374 TierNone = 0, 1375 Tier1 = 1, 1376 Tier2 = 2, 1377 } 1378 1379 /// Only available on (macos(11.0), ios(14.0)) 1380 #[repr(u64)] 1381 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] 1382 pub enum MTLCounterSamplingPoint { 1383 AtStageBoundary = 0, 1384 AtDrawBoundary = 1, 1385 AtDispatchBoundary = 2, 1386 AtTileDispatchBoundary = 3, 1387 AtBlitBoundary = 4, 1388 } 1389 1390 /// Only available on (macos(11.0), macCatalyst(14.0), ios(13.0)) 1391 #[repr(u64)] 1392 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] 1393 pub enum MTLSparseTextureRegionAlignmentMode { 1394 Outward = 0, 1395 Inward = 1, 1396 } 1397 1398 bitflags! { 1399 struct MTLPipelineOption: NSUInteger { 1400 const None = 0; 1401 const ArgumentInfo = 1 << 0; 1402 const BufferTypeInfo = 1 << 1; 1403 /// Only available on (macos(11.0), ios(14.0)) 1404 const FailOnBinaryArchiveMiss = 1 << 2; 1405 } 1406 } 1407 1408 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] 1409 #[repr(C)] 1410 pub struct MTLAccelerationStructureSizes { 1411 pub acceleration_structure_size: NSUInteger, 1412 pub build_scratch_buffer_size: NSUInteger, 1413 pub refit_scratch_buffer_size: NSUInteger, 1414 } 1415 1416 #[link(name = "Metal", kind = "framework")] 1417 extern "C" { MTLCreateSystemDefaultDevice() -> *mut MTLDevice1418 fn MTLCreateSystemDefaultDevice() -> *mut MTLDevice; 1419 #[cfg(not(target_os = "ios"))] MTLCopyAllDevices() -> *mut Object1420 fn MTLCopyAllDevices() -> *mut Object; //TODO: Array 1421 } 1422 1423 #[allow(non_camel_case_types)] 1424 type dispatch_data_t = id; 1425 #[allow(non_camel_case_types)] 1426 pub type dispatch_queue_t = id; 1427 #[allow(non_camel_case_types)] 1428 type dispatch_block_t = *const Block<(), ()>; 1429 1430 #[cfg_attr( 1431 any(target_os = "macos", target_os = "ios"), 1432 link(name = "System", kind = "dylib") 1433 )] 1434 #[cfg_attr( 1435 not(any(target_os = "macos", target_os = "ios")), 1436 link(name = "dispatch", kind = "dylib") 1437 )] 1438 #[allow(improper_ctypes)] 1439 extern "C" { 1440 static _dispatch_main_q: dispatch_queue_t; 1441 dispatch_data_create( buffer: *const std::ffi::c_void, size: crate::c_size_t, queue: dispatch_queue_t, destructor: dispatch_block_t, ) -> dispatch_data_t1442 fn dispatch_data_create( 1443 buffer: *const std::ffi::c_void, 1444 size: crate::c_size_t, 1445 queue: dispatch_queue_t, 1446 destructor: dispatch_block_t, 1447 ) -> dispatch_data_t; dispatch_release(object: dispatch_data_t)1448 fn dispatch_release(object: dispatch_data_t); // actually dispatch_object_t 1449 } 1450 1451 /*type MTLNewLibraryCompletionHandler = extern fn(library: id, error: id); 1452 type MTLNewRenderPipelineStateCompletionHandler = extern fn(renderPipelineState: id, error: id); 1453 type MTLNewRenderPipelineStateWithReflectionCompletionHandler = extern fn(renderPipelineState: id, reflection: id, error: id); 1454 type MTLNewComputePipelineStateCompletionHandler = extern fn(computePipelineState: id, error: id); 1455 type MTLNewComputePipelineStateWithReflectionCompletionHandler = extern fn(computePipelineState: id, reflection: id, error: id);*/ 1456 1457 pub enum MTLDevice {} 1458 1459 foreign_obj_type! { 1460 type CType = MTLDevice; 1461 pub struct Device; 1462 pub struct DeviceRef; 1463 } 1464 1465 impl Device { system_default() -> Option<Self>1466 pub fn system_default() -> Option<Self> { 1467 // `MTLCreateSystemDefaultDevice` may return null if Metal is not supported 1468 unsafe { MTLCreateSystemDefaultDevice().as_mut().map(|x| Self(x)) } 1469 } 1470 all() -> Vec<Self>1471 pub fn all() -> Vec<Self> { 1472 #[cfg(target_os = "ios")] 1473 { 1474 Self::system_default().into_iter().collect() 1475 } 1476 #[cfg(not(target_os = "ios"))] 1477 unsafe { 1478 let array = MTLCopyAllDevices(); 1479 let count: NSUInteger = msg_send![array, count]; 1480 let ret = (0..count) 1481 .map(|i| msg_send![array, objectAtIndex: i]) 1482 // The elements of this array are references---we convert them to owned references 1483 // (which just means that we increment the reference count here, and it is 1484 // decremented in the `Drop` impl for `Device`) 1485 .map(|device: *mut Object| msg_send![device, retain]) 1486 .collect(); 1487 let () = msg_send![array, release]; 1488 ret 1489 } 1490 } 1491 } 1492 1493 impl DeviceRef { name(&self) -> &str1494 pub fn name(&self) -> &str { 1495 unsafe { 1496 let name = msg_send![self, name]; 1497 crate::nsstring_as_str(name) 1498 } 1499 } 1500 1501 #[cfg(feature = "private")] vendor(&self) -> &str1502 pub unsafe fn vendor(&self) -> &str { 1503 let name = msg_send![self, vendorName]; 1504 crate::nsstring_as_str(name) 1505 } 1506 1507 #[cfg(feature = "private")] family_name(&self) -> &str1508 pub unsafe fn family_name(&self) -> &str { 1509 let name = msg_send![self, familyName]; 1510 crate::nsstring_as_str(name) 1511 } 1512 registry_id(&self) -> u641513 pub fn registry_id(&self) -> u64 { 1514 unsafe { msg_send![self, registryID] } 1515 } 1516 location(&self) -> MTLDeviceLocation1517 pub fn location(&self) -> MTLDeviceLocation { 1518 unsafe { msg_send![self, location] } 1519 } 1520 location_number(&self) -> NSUInteger1521 pub fn location_number(&self) -> NSUInteger { 1522 unsafe { msg_send![self, locationNumber] } 1523 } 1524 max_threadgroup_memory_length(&self) -> NSUInteger1525 pub fn max_threadgroup_memory_length(&self) -> NSUInteger { 1526 unsafe { msg_send![self, maxThreadgroupMemoryLength] } 1527 } 1528 max_threads_per_threadgroup(&self) -> MTLSize1529 pub fn max_threads_per_threadgroup(&self) -> MTLSize { 1530 unsafe { msg_send![self, maxThreadsPerThreadgroup] } 1531 } 1532 is_low_power(&self) -> bool1533 pub fn is_low_power(&self) -> bool { 1534 unsafe { 1535 match msg_send![self, isLowPower] { 1536 YES => true, 1537 NO => false, 1538 _ => unreachable!(), 1539 } 1540 } 1541 } 1542 is_headless(&self) -> bool1543 pub fn is_headless(&self) -> bool { 1544 unsafe { 1545 match msg_send![self, isHeadless] { 1546 YES => true, 1547 NO => false, 1548 _ => unreachable!(), 1549 } 1550 } 1551 } 1552 is_removable(&self) -> bool1553 pub fn is_removable(&self) -> bool { 1554 unsafe { 1555 match msg_send![self, isRemovable] { 1556 YES => true, 1557 NO => false, 1558 _ => unreachable!(), 1559 } 1560 } 1561 } 1562 1563 /// Only available on (macos(11.0), ios(14.0)) supports_raytracing(&self) -> bool1564 pub fn supports_raytracing(&self) -> bool { 1565 unsafe { 1566 match msg_send![self, supportsRaytracing] { 1567 YES => true, 1568 NO => false, 1569 _ => unreachable!(), 1570 } 1571 } 1572 } 1573 has_unified_memory(&self) -> bool1574 pub fn has_unified_memory(&self) -> bool { 1575 unsafe { 1576 match msg_send![self, hasUnifiedMemory] { 1577 YES => true, 1578 NO => false, 1579 _ => unreachable!(), 1580 } 1581 } 1582 } 1583 recommended_max_working_set_size(&self) -> u641584 pub fn recommended_max_working_set_size(&self) -> u64 { 1585 unsafe { msg_send![self, recommendedMaxWorkingSetSize] } 1586 } 1587 max_transfer_rate(&self) -> u641588 pub fn max_transfer_rate(&self) -> u64 { 1589 unsafe { msg_send![self, maxTransferRate] } 1590 } 1591 supports_feature_set(&self, feature: MTLFeatureSet) -> bool1592 pub fn supports_feature_set(&self, feature: MTLFeatureSet) -> bool { 1593 unsafe { 1594 match msg_send![self, supportsFeatureSet: feature] { 1595 YES => true, 1596 NO => false, 1597 _ => unreachable!(), 1598 } 1599 } 1600 } 1601 supports_family(&self, family: MTLGPUFamily) -> bool1602 pub fn supports_family(&self, family: MTLGPUFamily) -> bool { 1603 unsafe { 1604 match msg_send![self, supportsFamily: family] { 1605 YES => true, 1606 NO => false, 1607 _ => unreachable!(), 1608 } 1609 } 1610 } 1611 supports_vertex_amplification_count(&self, count: NSUInteger) -> bool1612 pub fn supports_vertex_amplification_count(&self, count: NSUInteger) -> bool { 1613 unsafe { 1614 match msg_send![self, supportsVertexAmplificationCount: count] { 1615 YES => true, 1616 NO => false, 1617 _ => unreachable!(), 1618 } 1619 } 1620 } 1621 supports_texture_sample_count(&self, count: NSUInteger) -> bool1622 pub fn supports_texture_sample_count(&self, count: NSUInteger) -> bool { 1623 unsafe { 1624 match msg_send![self, supportsTextureSampleCount: count] { 1625 YES => true, 1626 NO => false, 1627 _ => unreachable!(), 1628 } 1629 } 1630 } 1631 supports_shader_barycentric_coordinates(&self) -> bool1632 pub fn supports_shader_barycentric_coordinates(&self) -> bool { 1633 unsafe { 1634 match msg_send![self, supportsShaderBarycentricCoordinates] { 1635 YES => true, 1636 NO => false, 1637 _ => unreachable!(), 1638 } 1639 } 1640 } 1641 supports_function_pointers(&self) -> bool1642 pub fn supports_function_pointers(&self) -> bool { 1643 unsafe { 1644 match msg_send![self, supportsFunctionPointers] { 1645 YES => true, 1646 NO => false, 1647 _ => unreachable!(), 1648 } 1649 } 1650 } 1651 1652 /// Only available on (macos(11.0), ios(14.0)) supports_dynamic_libraries(&self) -> bool1653 pub fn supports_dynamic_libraries(&self) -> bool { 1654 unsafe { 1655 match msg_send![self, supportsDynamicLibraries] { 1656 YES => true, 1657 NO => false, 1658 _ => unreachable!(), 1659 } 1660 } 1661 } 1662 1663 /// Only available on (macos(11.0), ios(14.0)) supports_counter_sampling(&self, sampling_point: MTLCounterSamplingPoint) -> bool1664 pub fn supports_counter_sampling(&self, sampling_point: MTLCounterSamplingPoint) -> bool { 1665 unsafe { 1666 match msg_send![self, supportsCounterSampling: sampling_point] { 1667 YES => true, 1668 NO => false, 1669 _ => unreachable!(), 1670 } 1671 } 1672 } 1673 d24_s8_supported(&self) -> bool1674 pub fn d24_s8_supported(&self) -> bool { 1675 unsafe { 1676 match msg_send![self, isDepth24Stencil8PixelFormatSupported] { 1677 YES => true, 1678 NO => false, 1679 _ => unreachable!(), 1680 } 1681 } 1682 } 1683 new_fence(&self) -> Fence1684 pub fn new_fence(&self) -> Fence { 1685 unsafe { msg_send![self, newFence] } 1686 } 1687 new_command_queue(&self) -> CommandQueue1688 pub fn new_command_queue(&self) -> CommandQueue { 1689 unsafe { msg_send![self, newCommandQueue] } 1690 } 1691 new_command_queue_with_max_command_buffer_count( &self, count: NSUInteger, ) -> CommandQueue1692 pub fn new_command_queue_with_max_command_buffer_count( 1693 &self, 1694 count: NSUInteger, 1695 ) -> CommandQueue { 1696 unsafe { msg_send![self, newCommandQueueWithMaxCommandBufferCount: count] } 1697 } 1698 new_default_library(&self) -> Library1699 pub fn new_default_library(&self) -> Library { 1700 unsafe { msg_send![self, newDefaultLibrary] } 1701 } 1702 new_library_with_source( &self, src: &str, options: &CompileOptionsRef, ) -> Result<Library, String>1703 pub fn new_library_with_source( 1704 &self, 1705 src: &str, 1706 options: &CompileOptionsRef, 1707 ) -> Result<Library, String> { 1708 use cocoa_foundation::base::nil as cocoa_nil; 1709 use cocoa_foundation::foundation::NSString as cocoa_NSString; 1710 1711 unsafe { 1712 let source = cocoa_NSString::alloc(cocoa_nil).init_str(src); 1713 let mut err: *mut Object = ptr::null_mut(); 1714 let library: *mut MTLLibrary = msg_send![self, newLibraryWithSource:source 1715 options:options 1716 error:&mut err]; 1717 let () = msg_send![source, release]; 1718 if !err.is_null() { 1719 let desc: *mut Object = msg_send![err, localizedDescription]; 1720 let compile_error: *const c_char = msg_send![desc, UTF8String]; 1721 let message = CStr::from_ptr(compile_error).to_string_lossy().into_owned(); 1722 if library.is_null() { 1723 return Err(message); 1724 } else { 1725 warn!("Shader warnings: {}", message); 1726 } 1727 } 1728 1729 assert!(!library.is_null()); 1730 Ok(Library::from_ptr(library)) 1731 } 1732 } 1733 new_library_with_file<P: AsRef<Path>>(&self, file: P) -> Result<Library, String>1734 pub fn new_library_with_file<P: AsRef<Path>>(&self, file: P) -> Result<Library, String> { 1735 use cocoa_foundation::base::nil as cocoa_nil; 1736 use cocoa_foundation::foundation::NSString as cocoa_NSString; 1737 1738 unsafe { 1739 let filename = 1740 cocoa_NSString::alloc(cocoa_nil).init_str(file.as_ref().to_string_lossy().as_ref()); 1741 1742 let library: *mut MTLLibrary = try_objc! { err => 1743 msg_send![self, newLibraryWithFile:filename.as_ref() 1744 error:&mut err] 1745 }; 1746 1747 Ok(Library::from_ptr(library)) 1748 } 1749 } 1750 new_library_with_data(&self, library_data: &[u8]) -> Result<Library, String>1751 pub fn new_library_with_data(&self, library_data: &[u8]) -> Result<Library, String> { 1752 unsafe { 1753 let destructor_block = ConcreteBlock::new(|| {}).copy(); 1754 let data = dispatch_data_create( 1755 library_data.as_ptr() as *const std::ffi::c_void, 1756 library_data.len() as crate::c_size_t, 1757 &_dispatch_main_q as *const _ as dispatch_queue_t, 1758 &*destructor_block.deref(), 1759 ); 1760 1761 let library: *mut MTLLibrary = try_objc! { err => 1762 msg_send![self, newLibraryWithData:data 1763 error:&mut err] 1764 }; 1765 dispatch_release(data); 1766 Ok(Library::from_ptr(library)) 1767 } 1768 } 1769 1770 /// Only available on (macos(11.0), ios(14.0)) new_dynamic_library(&self, library: &LibraryRef) -> Result<DynamicLibrary, String>1771 pub fn new_dynamic_library(&self, library: &LibraryRef) -> Result<DynamicLibrary, String> { 1772 unsafe { 1773 let mut err: *mut Object = ptr::null_mut(); 1774 let dynamic_library: *mut MTLDynamicLibrary = msg_send![self, newDynamicLibrary:library 1775 error:&mut err]; 1776 if !err.is_null() { 1777 // FIXME: copy pasta 1778 let desc: *mut Object = msg_send![err, localizedDescription]; 1779 let compile_error: *const c_char = msg_send![desc, UTF8String]; 1780 let message = CStr::from_ptr(compile_error).to_string_lossy().into_owned(); 1781 Err(message) 1782 } else { 1783 Ok(DynamicLibrary::from_ptr(dynamic_library)) 1784 } 1785 } 1786 } 1787 1788 /// Only available on (macos(11.0), ios(14.0)) new_dynamic_library_with_url(&self, url: &URLRef) -> Result<DynamicLibrary, String>1789 pub fn new_dynamic_library_with_url(&self, url: &URLRef) -> Result<DynamicLibrary, String> { 1790 unsafe { 1791 let mut err: *mut Object = ptr::null_mut(); 1792 let dynamic_library: *mut MTLDynamicLibrary = msg_send![self, newDynamicLibraryWithURL:url 1793 error:&mut err]; 1794 if !err.is_null() { 1795 // FIXME: copy pasta 1796 let desc: *mut Object = msg_send![err, localizedDescription]; 1797 let compile_error: *const c_char = msg_send![desc, UTF8String]; 1798 let message = CStr::from_ptr(compile_error).to_string_lossy().into_owned(); 1799 Err(message) 1800 } else { 1801 Ok(DynamicLibrary::from_ptr(dynamic_library)) 1802 } 1803 } 1804 } 1805 1806 /// Only available on (macos(11.0), ios(14.0)) new_binary_archive_with_descriptor( &self, descriptor: &BinaryArchiveDescriptorRef, ) -> Result<BinaryArchive, String>1807 pub fn new_binary_archive_with_descriptor( 1808 &self, 1809 descriptor: &BinaryArchiveDescriptorRef, 1810 ) -> Result<BinaryArchive, String> { 1811 unsafe { 1812 let mut err: *mut Object = ptr::null_mut(); 1813 let binary_archive: *mut MTLBinaryArchive = msg_send![self, newBinaryArchiveWithDescriptor:descriptor 1814 error:&mut err]; 1815 if !err.is_null() { 1816 // TODO: copy pasta 1817 let desc: *mut Object = msg_send![err, localizedDescription]; 1818 let c_msg: *const c_char = msg_send![desc, UTF8String]; 1819 let message = CStr::from_ptr(c_msg).to_string_lossy().into_owned(); 1820 Err(message) 1821 } else { 1822 Ok(BinaryArchive::from_ptr(binary_archive)) 1823 } 1824 } 1825 } 1826 new_render_pipeline_state_with_reflection( &self, descriptor: &RenderPipelineDescriptorRef, reflection: &RenderPipelineReflectionRef, ) -> Result<RenderPipelineState, String>1827 pub fn new_render_pipeline_state_with_reflection( 1828 &self, 1829 descriptor: &RenderPipelineDescriptorRef, 1830 reflection: &RenderPipelineReflectionRef, 1831 ) -> Result<RenderPipelineState, String> { 1832 unsafe { 1833 let reflection_options = 1834 MTLPipelineOption::ArgumentInfo | MTLPipelineOption::BufferTypeInfo; 1835 1836 let pipeline_state: *mut MTLRenderPipelineState = try_objc! { err => 1837 msg_send![self, newRenderPipelineStateWithDescriptor:descriptor 1838 options:reflection_options 1839 reflection:reflection 1840 error:&mut err] 1841 }; 1842 1843 Ok(RenderPipelineState::from_ptr(pipeline_state)) 1844 } 1845 } 1846 1847 /// Useful for debugging binary archives. new_render_pipeline_state_with_fail_on_binary_archive_miss( &self, descriptor: &RenderPipelineDescriptorRef, ) -> Result<RenderPipelineState, String>1848 pub fn new_render_pipeline_state_with_fail_on_binary_archive_miss( 1849 &self, 1850 descriptor: &RenderPipelineDescriptorRef, 1851 ) -> Result<RenderPipelineState, String> { 1852 unsafe { 1853 let pipeline_options = MTLPipelineOption::FailOnBinaryArchiveMiss; 1854 1855 let reflection: *mut MTLRenderPipelineReflection = std::ptr::null_mut(); 1856 1857 let pipeline_state: *mut MTLRenderPipelineState = try_objc! { err => 1858 msg_send![self, newRenderPipelineStateWithDescriptor:descriptor 1859 options:pipeline_options 1860 reflection:reflection 1861 error:&mut err] 1862 }; 1863 1864 Ok(RenderPipelineState::from_ptr(pipeline_state)) 1865 } 1866 } 1867 new_render_pipeline_state( &self, descriptor: &RenderPipelineDescriptorRef, ) -> Result<RenderPipelineState, String>1868 pub fn new_render_pipeline_state( 1869 &self, 1870 descriptor: &RenderPipelineDescriptorRef, 1871 ) -> Result<RenderPipelineState, String> { 1872 unsafe { 1873 let pipeline_state: *mut MTLRenderPipelineState = try_objc! { err => 1874 msg_send![self, newRenderPipelineStateWithDescriptor:descriptor 1875 error:&mut err] 1876 }; 1877 1878 Ok(RenderPipelineState::from_ptr(pipeline_state)) 1879 } 1880 } 1881 new_compute_pipeline_state_with_function( &self, function: &FunctionRef, ) -> Result<ComputePipelineState, String>1882 pub fn new_compute_pipeline_state_with_function( 1883 &self, 1884 function: &FunctionRef, 1885 ) -> Result<ComputePipelineState, String> { 1886 unsafe { 1887 let pipeline_state: *mut MTLComputePipelineState = try_objc! { err => 1888 msg_send![self, newComputePipelineStateWithFunction:function 1889 error:&mut err] 1890 }; 1891 1892 Ok(ComputePipelineState::from_ptr(pipeline_state)) 1893 } 1894 } 1895 new_compute_pipeline_state( &self, descriptor: &ComputePipelineDescriptorRef, ) -> Result<ComputePipelineState, String>1896 pub fn new_compute_pipeline_state( 1897 &self, 1898 descriptor: &ComputePipelineDescriptorRef, 1899 ) -> Result<ComputePipelineState, String> { 1900 unsafe { 1901 let pipeline_state: *mut MTLComputePipelineState = try_objc! { err => 1902 msg_send![self, newComputePipelineStateWithDescriptor:descriptor 1903 error:&mut err] 1904 }; 1905 1906 Ok(ComputePipelineState::from_ptr(pipeline_state)) 1907 } 1908 } 1909 new_buffer(&self, length: u64, options: MTLResourceOptions) -> Buffer1910 pub fn new_buffer(&self, length: u64, options: MTLResourceOptions) -> Buffer { 1911 unsafe { 1912 msg_send![self, newBufferWithLength:length 1913 options:options] 1914 } 1915 } 1916 new_buffer_with_data( &self, bytes: *const std::ffi::c_void, length: NSUInteger, options: MTLResourceOptions, ) -> Buffer1917 pub fn new_buffer_with_data( 1918 &self, 1919 bytes: *const std::ffi::c_void, 1920 length: NSUInteger, 1921 options: MTLResourceOptions, 1922 ) -> Buffer { 1923 unsafe { 1924 msg_send![self, newBufferWithBytes:bytes 1925 length:length 1926 options:options] 1927 } 1928 } 1929 new_texture(&self, descriptor: &TextureDescriptorRef) -> Texture1930 pub fn new_texture(&self, descriptor: &TextureDescriptorRef) -> Texture { 1931 unsafe { msg_send![self, newTextureWithDescriptor: descriptor] } 1932 } 1933 new_sampler(&self, descriptor: &SamplerDescriptorRef) -> SamplerState1934 pub fn new_sampler(&self, descriptor: &SamplerDescriptorRef) -> SamplerState { 1935 unsafe { msg_send![self, newSamplerStateWithDescriptor: descriptor] } 1936 } 1937 new_depth_stencil_state( &self, descriptor: &DepthStencilDescriptorRef, ) -> DepthStencilState1938 pub fn new_depth_stencil_state( 1939 &self, 1940 descriptor: &DepthStencilDescriptorRef, 1941 ) -> DepthStencilState { 1942 unsafe { msg_send![self, newDepthStencilStateWithDescriptor: descriptor] } 1943 } 1944 argument_buffers_support(&self) -> MTLArgumentBuffersTier1945 pub fn argument_buffers_support(&self) -> MTLArgumentBuffersTier { 1946 unsafe { msg_send![self, argumentBuffersSupport] } 1947 } 1948 read_write_texture_support(&self) -> MTLReadWriteTextureTier1949 pub fn read_write_texture_support(&self) -> MTLReadWriteTextureTier { 1950 unsafe { msg_send![self, readWriteTextureSupport] } 1951 } 1952 raster_order_groups_supported(&self) -> bool1953 pub fn raster_order_groups_supported(&self) -> bool { 1954 unsafe { 1955 match msg_send![self, rasterOrderGroupsSupported] { 1956 YES => true, 1957 NO => false, 1958 _ => unreachable!(), 1959 } 1960 } 1961 } 1962 1963 /// Only available on (macos(11.0), ios(14.0)) supports_32bit_float_filtering(&self) -> bool1964 pub fn supports_32bit_float_filtering(&self) -> bool { 1965 unsafe { 1966 match msg_send![self, supports32BitFloatFiltering] { 1967 YES => true, 1968 NO => false, 1969 _ => unreachable!(), 1970 } 1971 } 1972 } 1973 1974 /// Only available on (macos(11.0), ios(14.0)) supports_32bit_MSAA(&self) -> bool1975 pub fn supports_32bit_MSAA(&self) -> bool { 1976 unsafe { 1977 match msg_send![self, supports32BitMSAA] { 1978 YES => true, 1979 NO => false, 1980 _ => unreachable!(), 1981 } 1982 } 1983 } 1984 1985 /// Only available on (macos(11.0), ios(14.0)) supports_query_texture_LOD(&self) -> bool1986 pub fn supports_query_texture_LOD(&self) -> bool { 1987 unsafe { 1988 match msg_send![self, supportsQueryTextureLOD] { 1989 YES => true, 1990 NO => false, 1991 _ => unreachable!(), 1992 } 1993 } 1994 } 1995 1996 /// Only available on (macos(11.0), ios(14.0)) supports_BC_texture_compression(&self) -> bool1997 pub fn supports_BC_texture_compression(&self) -> bool { 1998 unsafe { 1999 match msg_send![self, supportsBCTextureCompression] { 2000 YES => true, 2001 NO => false, 2002 _ => unreachable!(), 2003 } 2004 } 2005 } 2006 2007 /// Only available on (macos(11.0), ios(14.0)) supports_pull_model_interpolation(&self) -> bool2008 pub fn supports_pull_model_interpolation(&self) -> bool { 2009 unsafe { 2010 match msg_send![self, supportsPullModelInterpolation] { 2011 YES => true, 2012 NO => false, 2013 _ => unreachable!(), 2014 } 2015 } 2016 } 2017 new_argument_encoder( &self, arguments: &ArrayRef<ArgumentDescriptor>, ) -> ArgumentEncoder2018 pub fn new_argument_encoder( 2019 &self, 2020 arguments: &ArrayRef<ArgumentDescriptor>, 2021 ) -> ArgumentEncoder { 2022 unsafe { msg_send![self, newArgumentEncoderWithArguments: arguments] } 2023 } 2024 new_heap(&self, descriptor: &HeapDescriptorRef) -> Heap2025 pub fn new_heap(&self, descriptor: &HeapDescriptorRef) -> Heap { 2026 unsafe { msg_send![self, newHeapWithDescriptor: descriptor] } 2027 } 2028 new_event(&self) -> Event2029 pub fn new_event(&self) -> Event { 2030 unsafe { msg_send![self, newEvent] } 2031 } 2032 new_shared_event(&self) -> SharedEvent2033 pub fn new_shared_event(&self) -> SharedEvent { 2034 unsafe { msg_send![self, newSharedEvent] } 2035 } 2036 heap_buffer_size_and_align( &self, length: NSUInteger, options: MTLResourceOptions, ) -> MTLSizeAndAlign2037 pub fn heap_buffer_size_and_align( 2038 &self, 2039 length: NSUInteger, 2040 options: MTLResourceOptions, 2041 ) -> MTLSizeAndAlign { 2042 unsafe { msg_send![self, heapBufferSizeAndAlignWithLength: length options: options] } 2043 } 2044 heap_texture_size_and_align( &self, descriptor: &TextureDescriptorRef, ) -> MTLSizeAndAlign2045 pub fn heap_texture_size_and_align( 2046 &self, 2047 descriptor: &TextureDescriptorRef, 2048 ) -> MTLSizeAndAlign { 2049 unsafe { msg_send![self, heapTextureSizeAndAlignWithDescriptor: descriptor] } 2050 } 2051 minimum_linear_texture_alignment_for_pixel_format( &self, format: MTLPixelFormat, ) -> NSUInteger2052 pub fn minimum_linear_texture_alignment_for_pixel_format( 2053 &self, 2054 format: MTLPixelFormat, 2055 ) -> NSUInteger { 2056 unsafe { msg_send![self, minimumLinearTextureAlignmentForPixelFormat: format] } 2057 } 2058 minimum_texture_buffer_alignment_for_pixel_format( &self, format: MTLPixelFormat, ) -> NSUInteger2059 pub fn minimum_texture_buffer_alignment_for_pixel_format( 2060 &self, 2061 format: MTLPixelFormat, 2062 ) -> NSUInteger { 2063 unsafe { msg_send![self, minimumTextureBufferAlignmentForPixelFormat: format] } 2064 } 2065 max_argument_buffer_sampler_count(&self) -> NSUInteger2066 pub fn max_argument_buffer_sampler_count(&self) -> NSUInteger { 2067 unsafe { msg_send![self, maxArgumentBufferSamplerCount] } 2068 } 2069 current_allocated_size(&self) -> NSUInteger2070 pub fn current_allocated_size(&self) -> NSUInteger { 2071 unsafe { msg_send![self, currentAllocatedSize] } 2072 } 2073 2074 /// Only available on (macos(10.14), ios(12.0), tvos(12.0)) max_buffer_length(&self) -> NSUInteger2075 pub fn max_buffer_length(&self) -> NSUInteger { 2076 unsafe { msg_send![self, maxBufferLength] } 2077 } 2078 } 2079