use super::*;
use objc::runtime::{BOOL, YES};
#[link(name = "MetalPerformanceShaders", kind = "framework")]
extern "C" {
fn MPSSupportsMTLDevice(device: *const std::ffi::c_void) -> BOOL;
}
pub fn mps_supports_device(device: &DeviceRef) -> bool {
let b: BOOL = unsafe {
let ptr: *const DeviceRef = device;
MPSSupportsMTLDevice(ptr as _)
};
b == YES
}
pub enum MPSKernel {}
foreign_obj_type! {
type CType = MPSKernel;
pub struct Kernel;
pub struct KernelRef;
}
pub enum MPSRayDataType {
OriginDirection = 0,
OriginMinDistanceDirectionMaxDistance = 1,
OriginMaskDirectionMaxDistance = 2,
}
bitflags! {
#[allow(non_upper_case_globals)]
pub struct MPSRayMaskOptions: NSUInteger {
const Primitive = 1;
const Instance = 2;
}
}
pub enum MPSIntersectionDataType {
Distance = 0,
DistancePrimitiveIndex = 1,
DistancePrimitiveIndexCoordinates = 2,
DistancePrimitiveIndexInstanceIndex = 3,
DistancePrimitiveIndexInstanceIndexCoordinates = 4,
}
pub enum MPSIntersectionType {
Nearest = 0,
Any = 1,
}
pub enum MPSRayMaskOperator {
And = 0,
NotAnd = 1,
Or = 2,
NotOr = 3,
Xor = 4,
NotXor = 5,
LessThan = 6,
LessThanOrEqualTo = 7,
GreaterThan = 8,
GreaterThanOrEqualTo = 9,
}
pub enum MPSTriangleIntersectionTestType {
Default = 0,
Watertight = 1,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum MPSAccelerationStructureStatus {
Unbuilt = 0,
Built = 1,
}
bitflags! {
#[allow(non_upper_case_globals)]
pub struct MPSAccelerationStructureUsage: NSUInteger {
const None = 0;
const Refit = 1;
const FrequentRebuild = 2;
const PreferGPUBuild = 4;
const PreferCPUBuild = 8;
}
}
const MPSDataTypeFloatBit: isize = 0x10000000;
const MPSDataTypeSignedBit: isize = 0x20000000;
const MPSDataTypeNormalizedBit: isize = 0x40000000;
pub enum MPSDataType {
Invalid = 0,
Float32 = MPSDataTypeFloatBit | 32,
Float16 = MPSDataTypeFloatBit | 16,
Int8 = MPSDataTypeSignedBit | 8,
Int16 = MPSDataTypeSignedBit | 16,
Int32 = MPSDataTypeSignedBit | 32,
UInt8 = 8,
UInt16 = 16,
UInt32 = 32,
Unorm1 = MPSDataTypeNormalizedBit | 1,
Unorm8 = MPSDataTypeNormalizedBit | 8,
}
pub enum MPSRayIntersector {}
foreign_obj_type! {
type CType = MPSRayIntersector;
pub struct RayIntersector;
pub struct RayIntersectorRef;
type ParentType = KernelRef;
}
impl RayIntersector {
pub fn from_device(device: &DeviceRef) -> Option<Self> {
unsafe {
let intersector: RayIntersector = msg_send![class!(MPSRayIntersector), alloc];
let ptr: *mut Object = msg_send![intersector.as_ref(), initWithDevice: device];
if ptr.is_null() {
None
} else {
Some(intersector)
}
}
}
}
impl RayIntersectorRef {
pub fn set_cull_mode(&self, mode: MTLCullMode) {
unsafe { msg_send![self, setCullMode: mode] }
}
pub fn set_front_facing_winding(&self, winding: MTLWinding) {
unsafe { msg_send![self, setFrontFacingWinding: winding] }
}
pub fn set_intersection_data_type(&self, options: MPSIntersectionDataType) {
unsafe { msg_send![self, setIntersectionDataType: options] }
}
pub fn set_intersection_stride(&self, stride: NSUInteger) {
unsafe { msg_send![self, setIntersectionStride: stride] }
}
pub fn set_ray_data_type(&self, ty: MPSRayDataType) {
unsafe { msg_send![self, setRayDataType: ty] }
}
pub fn set_ray_index_data_type(&self, ty: MPSDataType) {
unsafe { msg_send![self, setRayIndexDataType: ty] }
}
pub fn set_ray_mask(&self, ray_mask: u32) {
unsafe { msg_send![self, setRayMask: ray_mask] }
}
pub fn set_ray_mask_operator(&self, operator: MPSRayMaskOperator) {
unsafe { msg_send![self, setRayMaskOperator: operator] }
}
pub fn set_ray_mask_options(&self, options: MPSRayMaskOptions) {
unsafe { msg_send![self, setRayMaskOptions: options] }
}
pub fn set_ray_stride(&self, stride: NSUInteger) {
unsafe { msg_send![self, setRayStride: stride] }
}
pub fn set_triangle_intersection_test_type(&self, test_type: MPSTriangleIntersectionTestType) {
unsafe { msg_send![self, setTriangleIntersectionTestType: test_type] }
}
pub fn encode_intersection_to_command_buffer(
&self,
command_buffer: &CommandBufferRef,
intersection_type: MPSIntersectionType,
ray_buffer: &BufferRef,
ray_buffer_offset: NSUInteger,
intersection_buffer: &BufferRef,
intersection_buffer_offset: NSUInteger,
ray_count: NSUInteger,
acceleration_structure: &AccelerationStructureRef,
) {
unsafe {
msg_send![
self,
encodeIntersectionToCommandBuffer: command_buffer
intersectionType: intersection_type
rayBuffer: ray_buffer
rayBufferOffset: ray_buffer_offset
intersectionBuffer: intersection_buffer
intersectionBufferOffset: intersection_buffer_offset
rayCount: ray_count
accelerationStructure: acceleration_structure
]
}
}
pub fn recommended_minimum_ray_batch_size_for_ray_count(
&self,
ray_count: NSUInteger,
) -> NSUInteger {
unsafe { msg_send![self, recommendedMinimumRayBatchSizeForRayCount: ray_count] }
}
}
pub enum MPSAccelerationStructureGroup {}
foreign_obj_type! {
type CType = MPSAccelerationStructureGroup;
pub struct AccelerationStructureGroup;
pub struct AccelerationStructureGroupRef;
}
impl AccelerationStructureGroup {
pub fn new_with_device(device: &DeviceRef) -> Option<Self> {
unsafe {
let group: AccelerationStructureGroup =
msg_send![class!(MPSAccelerationStructureGroup), alloc];
let ptr: *mut Object = msg_send![group.as_ref(), initWithDevice: device];
if ptr.is_null() {
None
} else {
Some(group)
}
}
}
}
impl AccelerationStructureGroupRef {
pub fn device(&self) -> &DeviceRef {
unsafe { msg_send![self, device] }
}
}
pub enum MPSAccelerationStructure {}
foreign_obj_type! {
type CType = MPSAccelerationStructure;
pub struct AccelerationStructure;
pub struct AccelerationStructureRef;
}
impl AccelerationStructureRef {
pub fn status(&self) -> MPSAccelerationStructureStatus {
unsafe { msg_send![self, status] }
}
pub fn usage(&self) -> MPSAccelerationStructureUsage {
unsafe { msg_send![self, usage] }
}
pub fn set_usage(&self, usage: MPSAccelerationStructureUsage) {
unsafe { msg_send![self, setUsage: usage] }
}
pub fn group(&self) -> &AccelerationStructureGroupRef {
unsafe { msg_send![self, group] }
}
pub fn encode_refit_to_command_buffer(&self, buffer: &CommandBufferRef) {
unsafe { msg_send![self, encodeRefitToCommandBuffer: buffer] }
}
pub fn rebuild(&self) {
unsafe { msg_send![self, rebuild] }
}
}
pub enum MPSPolygonAccelerationStructure {}
foreign_obj_type! {
type CType = MPSPolygonAccelerationStructure;
pub struct PolygonAccelerationStructure;
pub struct PolygonAccelerationStructureRef;
type ParentType = AccelerationStructureRef;
}
impl PolygonAccelerationStructureRef {
pub fn set_index_buffer(&self, buffer: Option<&BufferRef>) {
unsafe { msg_send![self, setIndexBuffer: buffer] }
}
pub fn set_index_buffer_offset(&self, offset: NSUInteger) {
unsafe { msg_send![self, setIndexBufferOffset: offset] }
}
pub fn set_index_type(&self, data_type: MPSDataType) {
unsafe { msg_send![self, setIndexType: data_type] }
}
pub fn set_mask_buffer(&self, buffer: Option<&BufferRef>) {
unsafe { msg_send![self, setMaskBuffer: buffer] }
}
pub fn set_mask_buffer_offset(&self, offset: NSUInteger) {
unsafe { msg_send![self, setMaskBufferOffset: offset] }
}
pub fn set_vertex_buffer(&self, buffer: Option<&BufferRef>) {
unsafe { msg_send![self, setVertexBuffer: buffer] }
}
pub fn set_vertex_buffer_offset(&self, offset: NSUInteger) {
unsafe { msg_send![self, setVertexBufferOffset: offset] }
}
pub fn set_vertex_stride(&self, stride: NSUInteger) {
unsafe { msg_send![self, setVertexStride: stride] }
}
}
pub enum MPSTriangleAccelerationStructure {}
foreign_obj_type! {
type CType = MPSTriangleAccelerationStructure;
pub struct TriangleAccelerationStructure;
pub struct TriangleAccelerationStructureRef;
type ParentType = PolygonAccelerationStructureRef;
}
impl TriangleAccelerationStructure {
pub fn from_device(device: &DeviceRef) -> Option<Self> {
unsafe {
let structure: TriangleAccelerationStructure =
msg_send![class!(MPSTriangleAccelerationStructure), alloc];
let ptr: *mut Object = msg_send![structure.as_ref(), initWithDevice: device];
if ptr.is_null() {
None
} else {
Some(structure)
}
}
}
}
impl TriangleAccelerationStructureRef {
pub fn triangle_count(&self) -> NSUInteger {
unsafe { msg_send![self, triangleCount] }
}
pub fn set_triangle_count(&self, count: NSUInteger) {
unsafe { msg_send![self, setTriangleCount: count] }
}
}
#[repr(u64)]
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum MPSTransformType {
Float4x4 = 0,
Identity = 1,
}
pub enum MPSInstanceAccelerationStructure {}
foreign_obj_type! {
type CType = MPSInstanceAccelerationStructure;
pub struct InstanceAccelerationStructure;
pub struct InstanceAccelerationStructureRef;
type ParentType = AccelerationStructureRef;
}
impl InstanceAccelerationStructure {
pub fn init_with_group(group: &AccelerationStructureGroupRef) -> Option<Self> {
unsafe {
let structure: InstanceAccelerationStructure =
msg_send![class!(MPSInstanceAccelerationStructure), alloc];
let ptr: *mut Object = msg_send![structure.as_ref(), initWithGroup: group];
if ptr.is_null() {
None
} else {
Some(structure)
}
}
}
}
impl InstanceAccelerationStructureRef {
pub fn acceleration_structures(&self) -> Vec<PolygonAccelerationStructure> {
unsafe {
let acs: *mut Object = msg_send![self, accelerationStructures];
let count: NSUInteger = msg_send![acs, count];
let ret = (0..count)
.map(|i| {
let ac = msg_send![acs, objectAtIndex: i];
PolygonAccelerationStructure::from_ptr(ac)
})
.collect();
ret
}
}
pub fn set_acceleration_structures(&self, acs: &[&PolygonAccelerationStructureRef]) {
let ns_array = Array::<PolygonAccelerationStructure>::from_slice(acs);
unsafe { msg_send![self, setAccelerationStructures: ns_array] }
}
pub fn instance_buffer(&self) -> &BufferRef {
unsafe { msg_send![self, instanceBuffer] }
}
pub fn set_instance_buffer(&self, buffer: &BufferRef) {
unsafe { msg_send![self, setInstanceBuffer: buffer] }
}
pub fn instance_buffer_offset(&self) -> NSUInteger {
unsafe { msg_send![self, instanceBufferOffset] }
}
pub fn set_instance_buffer_offset(&self, offset: NSUInteger) {
unsafe { msg_send![self, setInstanceBufferOffset: offset] }
}
pub fn transform_buffer(&self) -> &BufferRef {
unsafe { msg_send![self, transformBuffer] }
}
pub fn set_transform_buffer(&self, buffer: &BufferRef) {
unsafe { msg_send![self, setTransformBuffer: buffer] }
}
pub fn transform_buffer_offset(&self) -> NSUInteger {
unsafe { msg_send![self, transformBufferOffset] }
}
pub fn set_transform_buffer_offset(&self, offset: NSUInteger) {
unsafe { msg_send![self, setTransformBufferOffset: offset] }
}
pub fn transform_type(&self) -> MPSTransformType {
unsafe { msg_send![self, transformType] }
}
pub fn set_transform_type(&self, transform_type: MPSTransformType) {
unsafe { msg_send![self, setTransformType: transform_type] }
}
pub fn mask_buffer(&self) -> &BufferRef {
unsafe { msg_send![self, maskBuffer] }
}
pub fn set_mask_buffer(&self, buffer: &BufferRef) {
unsafe { msg_send![self, setMaskBuffer: buffer] }
}
pub fn mask_buffer_offset(&self) -> NSUInteger {
unsafe { msg_send![self, maskBufferOffset] }
}
pub fn set_mask_buffer_offset(&self, offset: NSUInteger) {
unsafe { msg_send![self, setMaskBufferOffset: offset] }
}
pub fn instance_count(&self) -> NSUInteger {
unsafe { msg_send![self, instanceCount] }
}
pub fn set_instance_count(&self, count: NSUInteger) {
unsafe { msg_send![self, setInstanceCount: count] }
}
}
#[repr(C)]
pub struct MPSPackedFloat3 {
pub elements: [f32; 3],
}
#[repr(C)]
pub struct MPSRayOriginMinDistanceDirectionMaxDistance {
pub origin: MPSPackedFloat3,
pub min_distance: f32,
pub direction: MPSPackedFloat3,
pub max_distance: f32,
}
#[repr(C)]
pub struct MPSIntersectionDistancePrimitiveIndexCoordinates {
pub distance: f32,
pub primitive_index: u32,
pub coordinates: [f32; 2],
}