Bug 1874684 - Part 10: Replace BigInt with Int128 in RoundNumberToIncrement. r=mgaudet
[gecko.git] / third_party / rust / metal / src / mps.rs
blobedd4936e8e8fa9131e3cd9f4336753083c7410a7
1 // Copyright 2020 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.
8 use super::*;
10 use objc::runtime::{BOOL, YES};
12 #[cfg_attr(feature = "link", link(name = "MetalPerformanceShaders", kind = "framework"))]
13 extern "C" {
14     fn MPSSupportsMTLDevice(device: *const std::ffi::c_void) -> BOOL;
17 pub fn mps_supports_device(device: &DeviceRef) -> bool {
18     let b: BOOL = unsafe {
19         let ptr: *const DeviceRef = device;
20         MPSSupportsMTLDevice(ptr as _)
21     };
22     b == YES
25 /// See <https://developer.apple.com/documentation/metalperformanceshaders/mpskernel>
26 pub enum MPSKernel {}
28 foreign_obj_type! {
29     type CType = MPSKernel;
30     pub struct Kernel;
33 /// See <https://developer.apple.com/documentation/metalperformanceshaders/mpsraydatatype>
34 pub enum MPSRayDataType {
35     OriginDirection = 0,
36     OriginMinDistanceDirectionMaxDistance = 1,
37     OriginMaskDirectionMaxDistance = 2,
40 bitflags! {
41     /// See <https://developer.apple.com/documentation/metalperformanceshaders/mpsraymaskoptions>
42     #[allow(non_upper_case_globals)]
43     #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
44     pub struct MPSRayMaskOptions: NSUInteger {
45         /// Enable primitive masks
46         const Primitive = 1;
47         /// Enable instance masks
48         const Instance = 2;
49     }
52 /// Options that determine the data contained in an intersection result.
53 ///
54 /// See <https://developer.apple.com/documentation/metalperformanceshaders/mpsintersectiondatatype>
55 pub enum MPSIntersectionDataType {
56     Distance = 0,
57     DistancePrimitiveIndex = 1,
58     DistancePrimitiveIndexCoordinates = 2,
59     DistancePrimitiveIndexInstanceIndex = 3,
60     DistancePrimitiveIndexInstanceIndexCoordinates = 4,
63 /// See <https://developer.apple.com/documentation/metalperformanceshaders/mpsintersectiontype>
64 pub enum MPSIntersectionType {
65     /// Find the closest intersection to the ray's origin along the ray direction.
66     /// This is potentially slower than `Any` but is well suited to primary visibility rays.
67     Nearest = 0,
68     /// Find any intersection along the ray direction. This is potentially faster than `Nearest` and
69     /// is well suited to shadow and occlusion rays.
70     Any = 1,
73 /// See <https://developer.apple.com/documentation/metalperformanceshaders/mpsraymaskoperator>
74 pub enum MPSRayMaskOperator {
75     /// Accept the intersection if `(primitive mask & ray mask) != 0`.
76     And = 0,
77     /// Accept the intersection if `~(primitive mask & ray mask) != 0`.
78     NotAnd = 1,
79     /// Accept the intersection if `(primitive mask | ray mask) != 0`.
80     Or = 2,
81     /// Accept the intersection if `~(primitive mask | ray mask) != 0`.
82     NotOr = 3,
83     /// Accept the intersection if `(primitive mask ^ ray mask) != 0`.
84     /// Note that this is equivalent to the "!=" operator.
85     Xor = 4,
86     /// Accept the intersection if `~(primitive mask ^ ray mask) != 0`.
87     /// Note that this is equivalent to the "==" operator.
88     NotXor = 5,
89     /// Accept the intersection if `(primitive mask < ray mask) != 0`.
90     LessThan = 6,
91     /// Accept the intersection if `(primitive mask <= ray mask) != 0`.
92     LessThanOrEqualTo = 7,
93     /// Accept the intersection if `(primitive mask > ray mask) != 0`.
94     GreaterThan = 8,
95     /// Accept the intersection if `(primitive mask >= ray mask) != 0`.
96     GreaterThanOrEqualTo = 9,
99 /// See <https://developer.apple.com/documentation/metalperformanceshaders/mpstriangleintersectiontesttype>
100 pub enum MPSTriangleIntersectionTestType {
101     /// Use the default ray/triangle intersection test
102     Default = 0,
103     /// Use a watertight ray/triangle intersection test which avoids gaps along shared triangle edges.
104     /// Shared vertices may still have gaps.
105     /// This intersection test may be slower than `Default`.
106     Watertight = 1,
109 /// See <https://developer.apple.com/documentation/metalperformanceshaders/mpsaccelerationstructurestatus>
110 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
111 pub enum MPSAccelerationStructureStatus {
112     Unbuilt = 0,
113     Built = 1,
116 bitflags! {
117     /// See <https://developer.apple.com/documentation/metalperformanceshaders/mpsaccelerationstructureusage>
118     #[allow(non_upper_case_globals)]
119     #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
120     pub struct MPSAccelerationStructureUsage: NSUInteger {
121         /// No usage options specified
122         const None = 0;
123         /// Option that enables support for refitting the acceleration structure after it has been built.
124         const Refit = 1;
125         /// Option indicating that the acceleration structure will be rebuilt frequently.
126         const FrequentRebuild = 2;
127         const PreferGPUBuild = 4;
128         const PreferCPUBuild = 8;
129     }
132 /// A common bit for all floating point data types.
133 const MPSDataTypeFloatBit: isize = 0x10000000;
134 const MPSDataTypeSignedBit: isize = 0x20000000;
135 const MPSDataTypeNormalizedBit: isize = 0x40000000;
137 /// See <https://developer.apple.com/documentation/metalperformanceshaders/mpsdatatype>
138 pub enum MPSDataType {
139     Invalid = 0,
141     Float32 = MPSDataTypeFloatBit | 32,
142     Float16 = MPSDataTypeFloatBit | 16,
144     // Signed integers.
145     Int8 = MPSDataTypeSignedBit | 8,
146     Int16 = MPSDataTypeSignedBit | 16,
147     Int32 = MPSDataTypeSignedBit | 32,
149     // Unsigned integers. Range: [0, UTYPE_MAX]
150     UInt8 = 8,
151     UInt16 = 16,
152     UInt32 = 32,
154     // Unsigned normalized. Range: [0, 1.0]
155     Unorm1 = MPSDataTypeNormalizedBit | 1,
156     Unorm8 = MPSDataTypeNormalizedBit | 8,
159 /// A kernel that performs intersection tests between rays and geometry.
161 /// See <https://developer.apple.com/documentation/metalperformanceshaders/mpsrayintersector>
162 pub enum MPSRayIntersector {}
164 foreign_obj_type! {
165     type CType = MPSRayIntersector;
166     pub struct RayIntersector;
167     type ParentType = Kernel;
170 impl RayIntersector {
171     pub fn from_device(device: &DeviceRef) -> Option<Self> {
172         unsafe {
173             let intersector: RayIntersector = msg_send![class!(MPSRayIntersector), alloc];
174             let ptr: *mut Object = msg_send![intersector.as_ref(), initWithDevice: device];
175             if ptr.is_null() {
176                 None
177             } else {
178                 Some(intersector)
179             }
180         }
181     }
184 impl RayIntersectorRef {
185     pub fn set_cull_mode(&self, mode: MTLCullMode) {
186         unsafe { msg_send![self, setCullMode: mode] }
187     }
189     pub fn set_front_facing_winding(&self, winding: MTLWinding) {
190         unsafe { msg_send![self, setFrontFacingWinding: winding] }
191     }
193     pub fn set_intersection_data_type(&self, options: MPSIntersectionDataType) {
194         unsafe { msg_send![self, setIntersectionDataType: options] }
195     }
197     pub fn set_intersection_stride(&self, stride: NSUInteger) {
198         unsafe { msg_send![self, setIntersectionStride: stride] }
199     }
201     pub fn set_ray_data_type(&self, ty: MPSRayDataType) {
202         unsafe { msg_send![self, setRayDataType: ty] }
203     }
205     pub fn set_ray_index_data_type(&self, ty: MPSDataType) {
206         unsafe { msg_send![self, setRayIndexDataType: ty] }
207     }
209     pub fn set_ray_mask(&self, ray_mask: u32) {
210         unsafe { msg_send![self, setRayMask: ray_mask] }
211     }
213     pub fn set_ray_mask_operator(&self, operator: MPSRayMaskOperator) {
214         unsafe { msg_send![self, setRayMaskOperator: operator] }
215     }
217     pub fn set_ray_mask_options(&self, options: MPSRayMaskOptions) {
218         unsafe { msg_send![self, setRayMaskOptions: options] }
219     }
221     pub fn set_ray_stride(&self, stride: NSUInteger) {
222         unsafe { msg_send![self, setRayStride: stride] }
223     }
225     pub fn set_triangle_intersection_test_type(&self, test_type: MPSTriangleIntersectionTestType) {
226         unsafe { msg_send![self, setTriangleIntersectionTestType: test_type] }
227     }
229     pub fn encode_intersection_to_command_buffer(
230         &self,
231         command_buffer: &CommandBufferRef,
232         intersection_type: MPSIntersectionType,
233         ray_buffer: &BufferRef,
234         ray_buffer_offset: NSUInteger,
235         intersection_buffer: &BufferRef,
236         intersection_buffer_offset: NSUInteger,
237         ray_count: NSUInteger,
238         acceleration_structure: &AccelerationStructureRef,
239     ) {
240         unsafe {
241             msg_send![
242                 self,
243                 encodeIntersectionToCommandBuffer: command_buffer
244                 intersectionType: intersection_type
245                 rayBuffer: ray_buffer
246                 rayBufferOffset: ray_buffer_offset
247                 intersectionBuffer: intersection_buffer
248                 intersectionBufferOffset: intersection_buffer_offset
249                 rayCount: ray_count
250                 accelerationStructure: acceleration_structure
251             ]
252         }
253     }
255     pub fn recommended_minimum_ray_batch_size_for_ray_count(
256         &self,
257         ray_count: NSUInteger,
258     ) -> NSUInteger {
259         unsafe { msg_send![self, recommendedMinimumRayBatchSizeForRayCount: ray_count] }
260     }
263 /// A group of acceleration structures which may be used together in an instance acceleration structure.
265 /// See <https://developer.apple.com/documentation/metalperformanceshaders/mpsaccelerationstructuregroup>
266 pub enum MPSAccelerationStructureGroup {}
268 foreign_obj_type! {
269     type CType = MPSAccelerationStructureGroup;
270     pub struct AccelerationStructureGroup;
273 impl AccelerationStructureGroup {
274     pub fn new_with_device(device: &DeviceRef) -> Option<Self> {
275         unsafe {
276             let group: AccelerationStructureGroup =
277                 msg_send![class!(MPSAccelerationStructureGroup), alloc];
278             let ptr: *mut Object = msg_send![group.as_ref(), initWithDevice: device];
279             if ptr.is_null() {
280                 None
281             } else {
282                 Some(group)
283             }
284         }
285     }
288 impl AccelerationStructureGroupRef {
289     pub fn device(&self) -> &DeviceRef {
290         unsafe { msg_send![self, device] }
291     }
294 /// The base class for data structures that are built over geometry and used to accelerate ray tracing.
296 /// See <https://developer.apple.com/documentation/metalperformanceshaders/mpsaccelerationstructure>
297 pub enum MPSAccelerationStructure {}
299 foreign_obj_type! {
300     type CType = MPSAccelerationStructure;
301     pub struct AccelerationStructure;
304 impl AccelerationStructureRef {
305     pub fn status(&self) -> MPSAccelerationStructureStatus {
306         unsafe { msg_send![self, status] }
307     }
309     pub fn usage(&self) -> MPSAccelerationStructureUsage {
310         unsafe { msg_send![self, usage] }
311     }
313     pub fn set_usage(&self, usage: MPSAccelerationStructureUsage) {
314         unsafe { msg_send![self, setUsage: usage] }
315     }
317     pub fn group(&self) -> &AccelerationStructureGroupRef {
318         unsafe { msg_send![self, group] }
319     }
321     pub fn encode_refit_to_command_buffer(&self, buffer: &CommandBufferRef) {
322         unsafe { msg_send![self, encodeRefitToCommandBuffer: buffer] }
323     }
325     pub fn rebuild(&self) {
326         unsafe { msg_send![self, rebuild] }
327     }
330 /// See <https://developer.apple.com/documentation/metalperformanceshaders/mpspolygonaccelerationstructure>
331 pub enum MPSPolygonAccelerationStructure {}
333 foreign_obj_type! {
334     type CType = MPSPolygonAccelerationStructure;
335     pub struct PolygonAccelerationStructure;
336     type ParentType = AccelerationStructure;
339 impl PolygonAccelerationStructureRef {
340     pub fn set_index_buffer(&self, buffer: Option<&BufferRef>) {
341         unsafe { msg_send![self, setIndexBuffer: buffer] }
342     }
344     pub fn set_index_buffer_offset(&self, offset: NSUInteger) {
345         unsafe { msg_send![self, setIndexBufferOffset: offset] }
346     }
348     pub fn set_index_type(&self, data_type: MPSDataType) {
349         unsafe { msg_send![self, setIndexType: data_type] }
350     }
352     pub fn set_mask_buffer(&self, buffer: Option<&BufferRef>) {
353         unsafe { msg_send![self, setMaskBuffer: buffer] }
354     }
356     pub fn set_mask_buffer_offset(&self, offset: NSUInteger) {
357         unsafe { msg_send![self, setMaskBufferOffset: offset] }
358     }
360     pub fn set_vertex_buffer(&self, buffer: Option<&BufferRef>) {
361         unsafe { msg_send![self, setVertexBuffer: buffer] }
362     }
364     pub fn set_vertex_buffer_offset(&self, offset: NSUInteger) {
365         unsafe { msg_send![self, setVertexBufferOffset: offset] }
366     }
368     pub fn set_vertex_stride(&self, stride: NSUInteger) {
369         unsafe { msg_send![self, setVertexStride: stride] }
370     }
373 /// An acceleration structure built over triangles.
375 /// See <https://developer.apple.com/documentation/metalperformanceshaders/mpstriangleaccelerationstructure>
376 pub enum MPSTriangleAccelerationStructure {}
378 foreign_obj_type! {
379     type CType = MPSTriangleAccelerationStructure;
380     pub struct TriangleAccelerationStructure;
381     type ParentType = PolygonAccelerationStructure;
384 impl TriangleAccelerationStructure {
385     pub fn from_device(device: &DeviceRef) -> Option<Self> {
386         unsafe {
387             let structure: TriangleAccelerationStructure =
388                 msg_send![class!(MPSTriangleAccelerationStructure), alloc];
389             let ptr: *mut Object = msg_send![structure.as_ref(), initWithDevice: device];
390             if ptr.is_null() {
391                 None
392             } else {
393                 Some(structure)
394             }
395         }
396     }
399 impl TriangleAccelerationStructureRef {
400     pub fn triangle_count(&self) -> NSUInteger {
401         unsafe { msg_send![self, triangleCount] }
402     }
404     pub fn set_triangle_count(&self, count: NSUInteger) {
405         unsafe { msg_send![self, setTriangleCount: count] }
406     }
409 /// See <https://developer.apple.com/documentation/metalperformanceshaders/mpstransformtype>
410 #[repr(u64)]
411 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
412 pub enum MPSTransformType {
413     Float4x4 = 0,
414     Identity = 1,
417 /// An acceleration structure built over instances of other acceleration structures
419 /// See <https://developer.apple.com/documentation/metalperformanceshaders/mpsinstanceaccelerationstructure>
420 pub enum MPSInstanceAccelerationStructure {}
422 foreign_obj_type! {
423     type CType = MPSInstanceAccelerationStructure;
424     pub struct InstanceAccelerationStructure;
425     type ParentType = AccelerationStructure;
428 impl InstanceAccelerationStructure {
429     pub fn init_with_group(group: &AccelerationStructureGroupRef) -> Option<Self> {
430         unsafe {
431             let structure: InstanceAccelerationStructure =
432                 msg_send![class!(MPSInstanceAccelerationStructure), alloc];
433             let ptr: *mut Object = msg_send![structure.as_ref(), initWithGroup: group];
434             if ptr.is_null() {
435                 None
436             } else {
437                 Some(structure)
438             }
439         }
440     }
443 impl InstanceAccelerationStructureRef {
444     /// Marshal to Rust Vec
445     pub fn acceleration_structures(&self) -> Vec<PolygonAccelerationStructure> {
446         unsafe {
447             let acs: *mut Object = msg_send![self, accelerationStructures];
448             let count: NSUInteger = msg_send![acs, count];
449             let ret = (0..count)
450                 .map(|i| {
451                     let ac = msg_send![acs, objectAtIndex: i];
452                     PolygonAccelerationStructure::from_ptr(ac)
453                 })
454                 .collect();
455             ret
456         }
457     }
459     /// Marshal from Rust slice
460     pub fn set_acceleration_structures(&self, acs: &[&PolygonAccelerationStructureRef]) {
461         let ns_array = Array::<PolygonAccelerationStructure>::from_slice(acs);
462         unsafe { msg_send![self, setAccelerationStructures: ns_array] }
463     }
465     pub fn instance_buffer(&self) -> &BufferRef {
466         unsafe { msg_send![self, instanceBuffer] }
467     }
469     pub fn set_instance_buffer(&self, buffer: &BufferRef) {
470         unsafe { msg_send![self, setInstanceBuffer: buffer] }
471     }
473     pub fn instance_buffer_offset(&self) -> NSUInteger {
474         unsafe { msg_send![self, instanceBufferOffset] }
475     }
477     pub fn set_instance_buffer_offset(&self, offset: NSUInteger) {
478         unsafe { msg_send![self, setInstanceBufferOffset: offset] }
479     }
481     pub fn transform_buffer(&self) -> &BufferRef {
482         unsafe { msg_send![self, transformBuffer] }
483     }
485     pub fn set_transform_buffer(&self, buffer: &BufferRef) {
486         unsafe { msg_send![self, setTransformBuffer: buffer] }
487     }
489     pub fn transform_buffer_offset(&self) -> NSUInteger {
490         unsafe { msg_send![self, transformBufferOffset] }
491     }
493     pub fn set_transform_buffer_offset(&self, offset: NSUInteger) {
494         unsafe { msg_send![self, setTransformBufferOffset: offset] }
495     }
497     pub fn transform_type(&self) -> MPSTransformType {
498         unsafe { msg_send![self, transformType] }
499     }
501     pub fn set_transform_type(&self, transform_type: MPSTransformType) {
502         unsafe { msg_send![self, setTransformType: transform_type] }
503     }
505     pub fn mask_buffer(&self) -> &BufferRef {
506         unsafe { msg_send![self, maskBuffer] }
507     }
509     pub fn set_mask_buffer(&self, buffer: &BufferRef) {
510         unsafe { msg_send![self, setMaskBuffer: buffer] }
511     }
513     pub fn mask_buffer_offset(&self) -> NSUInteger {
514         unsafe { msg_send![self, maskBufferOffset] }
515     }
517     pub fn set_mask_buffer_offset(&self, offset: NSUInteger) {
518         unsafe { msg_send![self, setMaskBufferOffset: offset] }
519     }
521     pub fn instance_count(&self) -> NSUInteger {
522         unsafe { msg_send![self, instanceCount] }
523     }
525     pub fn set_instance_count(&self, count: NSUInteger) {
526         unsafe { msg_send![self, setInstanceCount: count] }
527     }
530 #[repr(C)]
531 pub struct MPSPackedFloat3 {
532     pub elements: [f32; 3],
535 /// Represents a 3D ray with an origin, a direction, and an intersection distance range from the origin.
537 /// See <https://developer.apple.com/documentation/metalperformanceshaders/mpsrayoriginmindistancedirectionmaxdistance>
538 #[repr(C)]
539 pub struct MPSRayOriginMinDistanceDirectionMaxDistance {
540     /// Ray origin. The intersection test will be skipped if the origin contains NaNs or infinities.
541     pub origin: MPSPackedFloat3,
542     /// Minimum intersection distance from the origin along the ray direction.
543     /// The intersection test will be skipped if the minimum distance is equal to positive infinity or NaN.
544     pub min_distance: f32,
545     /// Ray direction. Does not need to be normalized. The intersection test will be skipped if
546     /// the direction has length zero or contains NaNs or infinities.
547     pub direction: MPSPackedFloat3,
548     /// Maximum intersection distance from the origin along the ray direction. May be infinite.
549     /// The intersection test will be skipped if the maximum distance is less than zero, NaN, or
550     /// less than the minimum intersection distance.
551     pub max_distance: f32,
554 /// Intersection result which contains the distance from the ray origin to the intersection point,
555 /// the index of the intersected primitive, and the first two barycentric coordinates of the intersection point.
557 /// See <https://developer.apple.com/documentation/metalperformanceshaders/mpsintersectiondistanceprimitiveindexcoordinates>
558 #[repr(C)]
559 pub struct MPSIntersectionDistancePrimitiveIndexCoordinates {
560     /// Distance from the ray origin to the intersection point along the ray direction vector such
561     /// that `intersection = ray.origin + ray.direction * distance`.
562     /// Is negative if there is no intersection. If the intersection type is `MPSIntersectionTypeAny`,
563     /// is a positive value for a hit or a negative value for a miss.
564     pub distance: f32,
565     /// Index of the intersected primitive. Undefined if the ray does not intersect a primitive or
566     /// if the intersection type is `MPSIntersectionTypeAny`.
567     pub primitive_index: u32,
568     /// The first two barycentric coordinates `U` and `V` of the intersection point.
569     /// The third coordinate `W = 1 - U - V`. Undefined if the ray does not intersect a primitive or
570     /// if the intersection type is `MPSIntersectionTypeAny`.
571     pub coordinates: [f32; 2],