diff options
Diffstat (limited to 'third_party/rust/metal/src/pipeline')
-rw-r--r-- | third_party/rust/metal/src/pipeline/compute.rs | 488 | ||||
-rw-r--r-- | third_party/rust/metal/src/pipeline/mod.rs | 70 | ||||
-rw-r--r-- | third_party/rust/metal/src/pipeline/render.rs | 510 |
3 files changed, 1068 insertions, 0 deletions
diff --git a/third_party/rust/metal/src/pipeline/compute.rs b/third_party/rust/metal/src/pipeline/compute.rs new file mode 100644 index 0000000000..138b561cb3 --- /dev/null +++ b/third_party/rust/metal/src/pipeline/compute.rs @@ -0,0 +1,488 @@ +// Copyright 2017 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use super::*; + +use objc::runtime::{NO, YES}; + +#[repr(u64)] +#[allow(non_camel_case_types)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +pub enum MTLAttributeFormat { + Invalid = 0, + UChar2 = 1, + UChar3 = 2, + UChar4 = 3, + Char2 = 4, + Char3 = 5, + Char4 = 6, + UChar2Normalized = 7, + UChar3Normalized = 8, + UChar4Normalized = 9, + Char2Normalized = 10, + Char3Normalized = 11, + Char4Normalized = 12, + UShort2 = 13, + UShort3 = 14, + UShort4 = 15, + Short2 = 16, + Short3 = 17, + Short4 = 18, + UShort2Normalized = 19, + UShort3Normalized = 20, + UShort4Normalized = 21, + Short2Normalized = 22, + Short3Normalized = 23, + Short4Normalized = 24, + Half2 = 25, + Half3 = 26, + Half4 = 27, + Float = 28, + Float2 = 29, + Float3 = 30, + Float4 = 31, + Int = 32, + Int2 = 33, + Int3 = 34, + Int4 = 35, + UInt = 36, + UInt2 = 37, + UInt3 = 38, + UInt4 = 39, + Int1010102Normalized = 40, + UInt1010102Normalized = 41, + UChar4Normalized_BGRA = 42, + UChar = 45, + Char = 46, + UCharNormalized = 47, + CharNormalized = 48, + UShort = 49, + Short = 50, + UShortNormalized = 51, + ShortNormalized = 52, + Half = 53, +} + +#[repr(u64)] +#[allow(non_camel_case_types)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +pub enum MTLStepFunction { + Constant = 0, + PerInstance = 1, + PerPatch = 2, + PerPatchControlPoint = 3, + PerVertex = 4, + ThreadPositionInGridX = 5, + ThreadPositionInGridXIndexed = 6, + ThreadPositionInGridY = 7, + ThreadPositionInGridYIndexed = 8, +} + +pub enum MTLComputePipelineDescriptor {} + +foreign_obj_type! { + type CType = MTLComputePipelineDescriptor; + pub struct ComputePipelineDescriptor; + pub struct ComputePipelineDescriptorRef; +} + +impl ComputePipelineDescriptor { + pub fn new() -> Self { + unsafe { + let class = class!(MTLComputePipelineDescriptor); + msg_send![class, new] + } + } +} + +impl ComputePipelineDescriptorRef { + pub fn label(&self) -> &str { + unsafe { + let label = msg_send![self, label]; + crate::nsstring_as_str(label) + } + } + + pub fn set_label(&self, label: &str) { + unsafe { + let nslabel = crate::nsstring_from_str(label); + let () = msg_send![self, setLabel: nslabel]; + } + } + + pub fn compute_function(&self) -> Option<&FunctionRef> { + unsafe { msg_send![self, computeFunction] } + } + + pub fn set_compute_function(&self, function: Option<&FunctionRef>) { + unsafe { msg_send![self, setComputeFunction: function] } + } + + pub fn thread_group_size_is_multiple_of_thread_execution_width(&self) -> bool { + unsafe { + match msg_send![self, threadGroupSizeIsMultipleOfThreadExecutionWidth] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn set_thread_group_size_is_multiple_of_thread_execution_width( + &self, + size_is_multiple_of_width: bool, + ) { + unsafe { + msg_send![ + self, + setThreadGroupSizeIsMultipleOfThreadExecutionWidth: size_is_multiple_of_width + ] + } + } + + /// API_AVAILABLE(macos(10.14), ios(12.0)); + pub fn max_total_threads_per_threadgroup(&self) -> NSUInteger { + unsafe { msg_send![self, maxTotalThreadsPerThreadgroup] } + } + + /// API_AVAILABLE(macos(10.14), ios(12.0)); + pub fn set_max_total_threads_per_threadgroup(&self, max_total_threads: NSUInteger) { + unsafe { msg_send![self, setMaxTotalThreadsPerThreadgroup: max_total_threads] } + } + + /// API_AVAILABLE(ios(13.0),macos(11.0)); + pub fn support_indirect_command_buffers(&self) -> bool { + unsafe { + match msg_send![self, supportIndirectCommandBuffers] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + /// API_AVAILABLE(ios(13.0),macos(11.0)); + pub fn set_support_indirect_command_buffers(&self, support: bool) { + unsafe { msg_send![self, setSupportIndirectCommandBuffers: support] } + } + + /// API_AVAILABLE(macos(11.0), ios(14.0)); + pub fn support_adding_binary_functions(&self) -> bool { + unsafe { + match msg_send![self, supportAddingBinaryFunctions] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + /// API_AVAILABLE(macos(11.0), ios(14.0)); + pub fn set_support_adding_binary_functions(&self, support: bool) { + unsafe { msg_send![self, setSupportAddingBinaryFunctions: support] } + } + + /// API_AVAILABLE(macos(11.0), ios(14.0)); + pub fn max_call_stack_depth(&self) -> NSUInteger { + unsafe { msg_send![self, maxCallStackDepth] } + } + + /// API_AVAILABLE(macos(11.0), ios(14.0)); + pub fn set_max_call_stack_depth(&self, depth: NSUInteger) { + unsafe { msg_send![self, setMaxCallStackDepth: depth] } + } + + /// API_AVAILABLE(macos(11.0), ios(14.0)); + /// Marshal to Rust Vec + pub fn insert_libraries(&self) -> Vec<DynamicLibrary> { + unsafe { + let libraries: *mut Object = msg_send![self, insertLibraries]; + let count: NSUInteger = msg_send![libraries, count]; + let ret = (0..count) + .map(|i| { + let lib = msg_send![libraries, objectAtIndex: i]; + DynamicLibrary::from_ptr(lib) + }) + .collect(); + ret + } + } + + /// Marshal from Rust slice + pub fn set_insert_libraries(&self, libraries: &[&DynamicLibraryRef]) { + let ns_array = Array::<DynamicLibrary>::from_slice(libraries); + unsafe { msg_send![self, setInsertLibraries: ns_array] } + } + + /// API_AVAILABLE(macos(11.0), ios(14.0)); + /// Marshal to Rust Vec + pub fn binary_archives(&self) -> Vec<BinaryArchive> { + unsafe { + let archives: *mut Object = msg_send![self, binaryArchives]; + let count: NSUInteger = msg_send![archives, count]; + let ret = (0..count) + .map(|i| { + let a = msg_send![archives, objectAtIndex: i]; + BinaryArchive::from_ptr(a) + }) + .collect(); + ret + } + } + + /// API_AVAILABLE(macos(11.0), ios(14.0)); + /// Marshal from Rust slice + pub fn set_binary_archives(&self, archives: &[&BinaryArchiveRef]) { + let ns_array = Array::<BinaryArchive>::from_slice(archives); + unsafe { msg_send![self, setBinaryArchives: ns_array] } + } + + /// API_AVAILABLE(macos(11.0), ios(14.0)); + pub fn linked_functions(&self) -> &LinkedFunctionsRef { + unsafe { msg_send![self, linkedFunctions] } + } + + /// API_AVAILABLE(macos(11.0), ios(14.0)); + pub fn set_linked_functions(&self, functions: &LinkedFunctionsRef) { + unsafe { msg_send![self, setLinkedFunctions: functions] } + } + + pub fn stage_input_descriptor(&self) -> Option<&StageInputOutputDescriptorRef> { + unsafe { msg_send![self, stageInputDescriptor] } + } + + pub fn set_stage_input_descriptor(&self, descriptor: Option<&StageInputOutputDescriptorRef>) { + unsafe { msg_send![self, setStageInputDescriptor: descriptor] } + } + + pub fn buffers(&self) -> Option<&PipelineBufferDescriptorArrayRef> { + unsafe { msg_send![self, buffers] } + } + + pub fn reset(&self) { + unsafe { msg_send![self, reset] } + } +} + +pub enum MTLComputePipelineState {} + +foreign_obj_type! { + type CType = MTLComputePipelineState; + pub struct ComputePipelineState; + pub struct ComputePipelineStateRef; +} + +impl ComputePipelineStateRef { + pub fn label(&self) -> &str { + unsafe { + let label = msg_send![self, label]; + crate::nsstring_as_str(label) + } + } + + pub fn max_total_threads_per_threadgroup(&self) -> NSUInteger { + unsafe { msg_send![self, maxTotalThreadsPerThreadgroup] } + } + + pub fn thread_execution_width(&self) -> NSUInteger { + unsafe { msg_send![self, threadExecutionWidth] } + } + + pub fn static_threadgroup_memory_length(&self) -> NSUInteger { + unsafe { msg_send![self, staticThreadgroupMemoryLength] } + } + + /// Only available on (ios(11.0), macos(11.0), macCatalyst(14.0)) NOT available on (tvos) + pub fn imageblock_memory_length_for_dimensions(&self, dimensions: MTLSize) -> NSUInteger { + unsafe { msg_send![self, imageblockMemoryLengthForDimensions: dimensions] } + } + + /// Only available on (ios(13.0), macos(11.0)) + pub fn support_indirect_command_buffers(&self) -> bool { + unsafe { + match msg_send![self, supportIndirectCommandBuffers] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + /// Only available on (macos(11.0), ios(14.0)) + pub fn function_handle_with_function( + &self, + function: &FunctionRef, + ) -> Option<&FunctionHandleRef> { + unsafe { msg_send![self, functionHandleWithFunction: function] } + } + + // API_AVAILABLE(macos(11.0), ios(14.0)); + // TODO: newComputePipelineStateWithAdditionalBinaryFunctions + // - (nullable id <MTLComputePipelineState>)newComputePipelineStateWithAdditionalBinaryFunctions:(nonnull NSArray<id<MTLFunction>> *)functions error:(__autoreleasing NSError **)error + + // API_AVAILABLE(macos(11.0), ios(14.0)); + // TODO: newVisibleFunctionTableWithDescriptor + // - (nullable id<MTLVisibleFunctionTable>)newVisibleFunctionTableWithDescriptor:(MTLVisibleFunctionTableDescriptor * __nonnull)descriptor + // API_AVAILABLE(macos(11.0), ios(14.0)); + // TODO: newIntersectionFunctionTableWithDescriptor + // - (nullable id <MTLIntersectionFunctionTable>)newIntersectionFunctionTableWithDescriptor:(MTLIntersectionFunctionTableDescriptor * _Nonnull)descriptor +} + +pub enum MTLStageInputOutputDescriptor {} + +foreign_obj_type! { + type CType = MTLStageInputOutputDescriptor; + pub struct StageInputOutputDescriptor; + pub struct StageInputOutputDescriptorRef; +} + +impl StageInputOutputDescriptor { + pub fn new<'a>() -> &'a StageInputOutputDescriptorRef { + unsafe { + let class = class!(MTLStageInputOutputDescriptor); + msg_send![class, stageInputOutputDescriptor] + } + } +} + +impl StageInputOutputDescriptorRef { + pub fn attributes(&self) -> Option<&AttributeDescriptorArrayRef> { + unsafe { msg_send![self, attributes] } + } + + pub fn index_buffer_index(&self) -> NSUInteger { + unsafe { msg_send![self, indexBufferIndex] } + } + + pub fn set_index_buffer_index(&self, idx_buffer_idx: NSUInteger) { + unsafe { msg_send![self, setIndexBufferIndex: idx_buffer_idx] } + } + + pub fn index_type(&self) -> MTLIndexType { + unsafe { msg_send![self, indexType] } + } + + pub fn set_index_type(&self, index_ty: MTLIndexType) { + unsafe { msg_send![self, setIndexType: index_ty] } + } + + pub fn layouts(&self) -> Option<&BufferLayoutDescriptorArrayRef> { + unsafe { msg_send![self, layouts] } + } + + pub fn reset(&self) { + unsafe { msg_send![self, reset] } + } +} + +pub enum MTLAttributeDescriptorArray {} + +foreign_obj_type! { + type CType = MTLAttributeDescriptorArray; + pub struct AttributeDescriptorArray; + pub struct AttributeDescriptorArrayRef; +} + +impl AttributeDescriptorArrayRef { + pub fn object_at(&self, index: NSUInteger) -> Option<&AttributeDescriptorRef> { + unsafe { msg_send![self, objectAtIndexedSubscript: index] } + } + + pub fn set_object_at(&self, index: NSUInteger, buffer_desc: Option<&AttributeDescriptorRef>) { + unsafe { msg_send![self, setObject:buffer_desc atIndexedSubscript:index] } + } +} + +pub enum MTLAttributeDescriptor {} + +foreign_obj_type! { + type CType = MTLAttributeDescriptor; + pub struct AttributeDescriptor; + pub struct AttributeDescriptorRef; +} + +impl AttributeDescriptorRef { + pub fn buffer_index(&self) -> NSUInteger { + unsafe { msg_send![self, bufferIndex] } + } + + pub fn set_buffer_index(&self, buffer_index: NSUInteger) { + unsafe { msg_send![self, setBufferIndex: buffer_index] } + } + + pub fn format(&self) -> MTLAttributeFormat { + unsafe { msg_send![self, format] } + } + + pub fn set_format(&self, format: MTLAttributeFormat) { + unsafe { msg_send![self, setFormat: format] } + } + + pub fn offset(&self) -> NSUInteger { + unsafe { msg_send![self, offset] } + } + + pub fn set_offset(&self, offset: NSUInteger) { + unsafe { msg_send![self, setOffset: offset] } + } +} + +pub enum MTLBufferLayoutDescriptorArray {} + +foreign_obj_type! { + type CType = MTLBufferLayoutDescriptorArray; + pub struct BufferLayoutDescriptorArray; + pub struct BufferLayoutDescriptorArrayRef; +} + +impl BufferLayoutDescriptorArrayRef { + pub fn object_at(&self, index: NSUInteger) -> Option<&BufferLayoutDescriptorRef> { + unsafe { msg_send![self, objectAtIndexedSubscript: index] } + } + + pub fn set_object_at( + &self, + index: NSUInteger, + buffer_desc: Option<&BufferLayoutDescriptorRef>, + ) { + unsafe { msg_send![self, setObject:buffer_desc atIndexedSubscript:index] } + } +} + +pub enum MTLBufferLayoutDescriptor {} + +foreign_obj_type! { + type CType = MTLBufferLayoutDescriptor; + pub struct BufferLayoutDescriptor; + pub struct BufferLayoutDescriptorRef; +} + +impl BufferLayoutDescriptorRef { + pub fn step_function(&self) -> MTLStepFunction { + unsafe { msg_send![self, stepFunction] } + } + + pub fn set_step_function(&self, step_function: MTLStepFunction) { + unsafe { msg_send![self, setStepFunction: step_function] } + } + + pub fn step_rate(&self) -> NSUInteger { + unsafe { msg_send![self, stepRate] } + } + + pub fn set_step_rate(&self, step_rate: NSUInteger) { + unsafe { msg_send![self, setStepRate: step_rate] } + } + + pub fn stride(&self) -> NSUInteger { + unsafe { msg_send![self, stride] } + } + + pub fn set_stride(&self, stride: NSUInteger) { + unsafe { msg_send![self, setStride: stride] } + } +} diff --git a/third_party/rust/metal/src/pipeline/mod.rs b/third_party/rust/metal/src/pipeline/mod.rs new file mode 100644 index 0000000000..e65d28d6ca --- /dev/null +++ b/third_party/rust/metal/src/pipeline/mod.rs @@ -0,0 +1,70 @@ +// Copyright 2017 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use super::*; + +mod compute; +mod render; + +pub use self::compute::*; +pub use self::render::*; + +#[repr(u64)] +#[allow(non_camel_case_types)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +pub enum MTLMutability { + Default = 0, + Mutable = 1, + Immutable = 2, +} + +impl Default for MTLMutability { + #[inline] + fn default() -> Self { + MTLMutability::Default + } +} + +pub enum MTLPipelineBufferDescriptorArray {} + +foreign_obj_type! { + type CType = MTLPipelineBufferDescriptorArray; + pub struct PipelineBufferDescriptorArray; + pub struct PipelineBufferDescriptorArrayRef; +} + +impl PipelineBufferDescriptorArrayRef { + pub fn object_at(&self, index: NSUInteger) -> Option<&PipelineBufferDescriptorRef> { + unsafe { msg_send![self, objectAtIndexedSubscript: index] } + } + + pub fn set_object_at( + &self, + index: NSUInteger, + buffer_desc: Option<&PipelineBufferDescriptorRef>, + ) { + unsafe { msg_send![self, setObject:buffer_desc atIndexedSubscript:index] } + } +} + +pub enum MTLPipelineBufferDescriptor {} + +foreign_obj_type! { + type CType = MTLPipelineBufferDescriptor; + pub struct PipelineBufferDescriptor; + pub struct PipelineBufferDescriptorRef; +} + +impl PipelineBufferDescriptorRef { + pub fn mutability(&self) -> MTLMutability { + unsafe { msg_send![self, mutability] } + } + + pub fn set_mutability(&self, new_mutability: MTLMutability) { + unsafe { msg_send![self, setMutability: new_mutability] } + } +} diff --git a/third_party/rust/metal/src/pipeline/render.rs b/third_party/rust/metal/src/pipeline/render.rs new file mode 100644 index 0000000000..a4b3a629e1 --- /dev/null +++ b/third_party/rust/metal/src/pipeline/render.rs @@ -0,0 +1,510 @@ +// Copyright 2017 GFX developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. + +use super::*; + +use objc::runtime::{NO, YES}; + +#[repr(u64)] +#[allow(non_camel_case_types)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +pub enum MTLBlendFactor { + Zero = 0, + One = 1, + SourceColor = 2, + OneMinusSourceColor = 3, + SourceAlpha = 4, + OneMinusSourceAlpha = 5, + DestinationColor = 6, + OneMinusDestinationColor = 7, + DestinationAlpha = 8, + OneMinusDestinationAlpha = 9, + SourceAlphaSaturated = 10, + BlendColor = 11, + OneMinusBlendColor = 12, + BlendAlpha = 13, + OneMinusBlendAlpha = 14, + Source1Color = 15, + OneMinusSource1Color = 16, + Source1Alpha = 17, + OneMinusSource1Alpha = 18, +} + +#[repr(u64)] +#[allow(non_camel_case_types)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +pub enum MTLBlendOperation { + Add = 0, + Subtract = 1, + ReverseSubtract = 2, + Min = 3, + Max = 4, +} + +bitflags! { + pub struct MTLColorWriteMask: NSUInteger { + const None = 0; + const Red = 0x1 << 3; + const Green = 0x1 << 2; + const Blue = 0x1 << 1; + const Alpha = 0x1 << 0; + const All = 0xf; + } +} + +#[repr(u64)] +#[allow(non_camel_case_types)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +pub enum MTLPrimitiveTopologyClass { + Unspecified = 0, + Point = 1, + Line = 2, + Triangle = 3, +} + +// TODO: MTLTessellationPartitionMode +// TODO: MTLTessellationFactorStepFunction +// TODO: MTLTessellationFactorFormat +// TODO: MTLTessellationControlPointIndexType + +pub enum MTLRenderPipelineColorAttachmentDescriptor {} + +foreign_obj_type! { + type CType = MTLRenderPipelineColorAttachmentDescriptor; + pub struct RenderPipelineColorAttachmentDescriptor; + pub struct RenderPipelineColorAttachmentDescriptorRef; +} + +impl RenderPipelineColorAttachmentDescriptorRef { + pub fn pixel_format(&self) -> MTLPixelFormat { + unsafe { msg_send![self, pixelFormat] } + } + + pub fn set_pixel_format(&self, pixel_format: MTLPixelFormat) { + unsafe { msg_send![self, setPixelFormat: pixel_format] } + } + + pub fn is_blending_enabled(&self) -> bool { + unsafe { + match msg_send![self, isBlendingEnabled] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn set_blending_enabled(&self, enabled: bool) { + unsafe { msg_send![self, setBlendingEnabled: enabled] } + } + + pub fn source_rgb_blend_factor(&self) -> MTLBlendFactor { + unsafe { msg_send![self, sourceRGBBlendFactor] } + } + + pub fn set_source_rgb_blend_factor(&self, blend_factor: MTLBlendFactor) { + unsafe { msg_send![self, setSourceRGBBlendFactor: blend_factor] } + } + + pub fn destination_rgb_blend_factor(&self) -> MTLBlendFactor { + unsafe { msg_send![self, destinationRGBBlendFactor] } + } + + pub fn set_destination_rgb_blend_factor(&self, blend_factor: MTLBlendFactor) { + unsafe { msg_send![self, setDestinationRGBBlendFactor: blend_factor] } + } + + pub fn rgb_blend_operation(&self) -> MTLBlendOperation { + unsafe { msg_send![self, rgbBlendOperation] } + } + + pub fn set_rgb_blend_operation(&self, blend_operation: MTLBlendOperation) { + unsafe { msg_send![self, setRgbBlendOperation: blend_operation] } + } + + pub fn source_alpha_blend_factor(&self) -> MTLBlendFactor { + unsafe { msg_send![self, sourceAlphaBlendFactor] } + } + + pub fn set_source_alpha_blend_factor(&self, blend_factor: MTLBlendFactor) { + unsafe { msg_send![self, setSourceAlphaBlendFactor: blend_factor] } + } + + pub fn destination_alpha_blend_factor(&self) -> MTLBlendFactor { + unsafe { msg_send![self, destinationAlphaBlendFactor] } + } + + pub fn set_destination_alpha_blend_factor(&self, blend_factor: MTLBlendFactor) { + unsafe { msg_send![self, setDestinationAlphaBlendFactor: blend_factor] } + } + + pub fn alpha_blend_operation(&self) -> MTLBlendOperation { + unsafe { msg_send![self, alphaBlendOperation] } + } + + pub fn set_alpha_blend_operation(&self, blend_operation: MTLBlendOperation) { + unsafe { msg_send![self, setAlphaBlendOperation: blend_operation] } + } + + pub fn write_mask(&self) -> MTLColorWriteMask { + unsafe { msg_send![self, writeMask] } + } + + pub fn set_write_mask(&self, mask: MTLColorWriteMask) { + unsafe { msg_send![self, setWriteMask: mask] } + } +} + +pub enum MTLRenderPipelineReflection {} + +foreign_obj_type! { + type CType = MTLRenderPipelineReflection; + pub struct RenderPipelineReflection; + pub struct RenderPipelineReflectionRef; +} + +impl RenderPipelineReflection { + #[cfg(feature = "private")] + pub unsafe fn new( + vertex_data: *mut std::ffi::c_void, + fragment_data: *mut std::ffi::c_void, + vertex_desc: *mut std::ffi::c_void, + device: &DeviceRef, + options: u64, + flags: u64, + ) -> Self { + let class = class!(MTLRenderPipelineReflection); + let this: RenderPipelineReflection = msg_send![class, alloc]; + let this_alias: *mut Object = msg_send![this.as_ref(), initWithVertexData:vertex_data + fragmentData:fragment_data + serializedVertexDescriptor:vertex_desc + device:device + options:options + flags:flags]; + if this_alias.is_null() { + panic!("[MTLRenderPipelineReflection init] failed"); + } + this + } +} + +impl RenderPipelineReflectionRef { + /// An array of objects that describe the arguments of a fragment function. + pub fn fragment_arguments(&self) -> &ArgumentArrayRef { + unsafe { msg_send![self, fragmentArguments] } + } + + /// An array of objects that describe the arguments of a vertex function. + pub fn vertex_arguments(&self) -> &ArgumentArrayRef { + unsafe { msg_send![self, vertexArguments] } + } + + /// An array of objects that describe the arguments of a tile shading function. + pub fn tile_arguments(&self) -> &ArgumentArrayRef { + unsafe { msg_send![self, tileArguments] } + } +} + +pub enum MTLArgumentArray {} + +foreign_obj_type! { + type CType = MTLArgumentArray; + pub struct ArgumentArray; + pub struct ArgumentArrayRef; +} + +impl ArgumentArrayRef { + pub fn object_at(&self, index: NSUInteger) -> Option<&ArgumentRef> { + unsafe { msg_send![self, objectAtIndexedSubscript: index] } + } + + pub fn count(&self) -> NSUInteger { + unsafe { msg_send![self, count] } + } +} + +pub enum MTLComputePipelineReflection {} + +foreign_obj_type! { + type CType = MTLComputePipelineReflection; + pub struct ComputePipelineReflection; + pub struct ComputePipelineReflectionRef; +} + +impl ComputePipelineReflectionRef { + /// An array of objects that describe the arguments of a compute function. + pub fn arguments(&self) -> &ArgumentArrayRef { + unsafe { msg_send![self, arguments] } + } +} + +pub enum MTLRenderPipelineDescriptor {} + +foreign_obj_type! { + type CType = MTLRenderPipelineDescriptor; + pub struct RenderPipelineDescriptor; + pub struct RenderPipelineDescriptorRef; +} + +impl RenderPipelineDescriptor { + pub fn new() -> Self { + unsafe { + let class = class!(MTLRenderPipelineDescriptor); + msg_send![class, new] + } + } +} + +impl RenderPipelineDescriptorRef { + pub fn label(&self) -> &str { + unsafe { + let label = msg_send![self, label]; + crate::nsstring_as_str(label) + } + } + + pub fn set_label(&self, label: &str) { + unsafe { + let nslabel = crate::nsstring_from_str(label); + let () = msg_send![self, setLabel: nslabel]; + } + } + + pub fn vertex_function(&self) -> Option<&FunctionRef> { + unsafe { msg_send![self, vertexFunction] } + } + + pub fn set_vertex_function(&self, function: Option<&FunctionRef>) { + unsafe { msg_send![self, setVertexFunction: function] } + } + + pub fn fragment_function(&self) -> Option<&FunctionRef> { + unsafe { msg_send![self, fragmentFunction] } + } + + pub fn set_fragment_function(&self, function: Option<&FunctionRef>) { + unsafe { msg_send![self, setFragmentFunction: function] } + } + + pub fn vertex_descriptor(&self) -> Option<&VertexDescriptorRef> { + unsafe { msg_send![self, vertexDescriptor] } + } + + pub fn set_vertex_descriptor(&self, descriptor: Option<&VertexDescriptorRef>) { + unsafe { msg_send![self, setVertexDescriptor: descriptor] } + } + + /// DEPRECATED - aliases rasterSampleCount property + pub fn sample_count(&self) -> NSUInteger { + unsafe { msg_send![self, sampleCount] } + } + + /// DEPRECATED - aliases rasterSampleCount property + pub fn set_sample_count(&self, count: NSUInteger) { + unsafe { msg_send![self, setSampleCount: count] } + } + + pub fn raster_sample_count(&self) -> NSUInteger { + unsafe { msg_send![self, rasterSampleCount] } + } + + pub fn set_raster_sample_count(&self, count: NSUInteger) { + unsafe { msg_send![self, setRasterSampleCount: count] } + } + + pub fn max_vertex_amplification_count(&self) -> NSUInteger { + unsafe { msg_send![self, maxVertexAmplificationCount] } + } + + pub fn set_max_vertex_amplification_count(&self, count: NSUInteger) { + unsafe { msg_send![self, setMaxVertexAmplificationCount: count] } + } + + pub fn is_alpha_to_coverage_enabled(&self) -> bool { + unsafe { + match msg_send![self, isAlphaToCoverageEnabled] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn set_alpha_to_coverage_enabled(&self, enabled: bool) { + unsafe { msg_send![self, setAlphaToCoverageEnabled: enabled] } + } + + pub fn is_alpha_to_one_enabled(&self) -> bool { + unsafe { + match msg_send![self, isAlphaToOneEnabled] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn set_alpha_to_one_enabled(&self, enabled: bool) { + unsafe { msg_send![self, setAlphaToOneEnabled: enabled] } + } + + pub fn is_rasterization_enabled(&self) -> bool { + unsafe { + match msg_send![self, isRasterizationEnabled] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn set_rasterization_enabled(&self, enabled: bool) { + unsafe { msg_send![self, setRasterizationEnabled: enabled] } + } + + pub fn color_attachments(&self) -> &RenderPipelineColorAttachmentDescriptorArrayRef { + unsafe { msg_send![self, colorAttachments] } + } + + pub fn depth_attachment_pixel_format(&self) -> MTLPixelFormat { + unsafe { msg_send![self, depthAttachmentPixelFormat] } + } + + pub fn set_depth_attachment_pixel_format(&self, pixel_format: MTLPixelFormat) { + unsafe { msg_send![self, setDepthAttachmentPixelFormat: pixel_format] } + } + + pub fn stencil_attachment_pixel_format(&self) -> MTLPixelFormat { + unsafe { msg_send![self, stencilAttachmentPixelFormat] } + } + + pub fn set_stencil_attachment_pixel_format(&self, pixel_format: MTLPixelFormat) { + unsafe { msg_send![self, setStencilAttachmentPixelFormat: pixel_format] } + } + + pub fn input_primitive_topology(&self) -> MTLPrimitiveTopologyClass { + unsafe { msg_send![self, inputPrimitiveTopology] } + } + + pub fn set_input_primitive_topology(&self, topology: MTLPrimitiveTopologyClass) { + unsafe { msg_send![self, setInputPrimitiveTopology: topology] } + } + + #[cfg(feature = "private")] + pub unsafe fn serialize_vertex_data(&self) -> *mut std::ffi::c_void { + use std::ptr; + let flags = 0; + let err: *mut Object = ptr::null_mut(); + msg_send![self, newSerializedVertexDataWithFlags:flags + error:err] + } + + #[cfg(feature = "private")] + pub unsafe fn serialize_fragment_data(&self) -> *mut std::ffi::c_void { + msg_send![self, serializeFragmentData] + } + + pub fn support_indirect_command_buffers(&self) -> bool { + unsafe { + match msg_send![self, supportIndirectCommandBuffers] { + YES => true, + NO => false, + _ => unreachable!(), + } + } + } + + pub fn set_support_indirect_command_buffers(&self, support: bool) { + unsafe { msg_send![self, setSupportIndirectCommandBuffers: support] } + } + + pub fn vertex_buffers(&self) -> Option<&PipelineBufferDescriptorArrayRef> { + unsafe { msg_send![self, vertexBuffers] } + } + + pub fn fragment_buffers(&self) -> Option<&PipelineBufferDescriptorArrayRef> { + unsafe { msg_send![self, fragmentBuffers] } + } + + // TODO: tesselation stuff + + /// API_AVAILABLE(macos(11.0), ios(14.0)); + /// Marshal to Rust Vec + pub fn binary_archives(&self) -> Vec<BinaryArchive> { + unsafe { + let archives: *mut Object = msg_send![self, binaryArchives]; + let count: NSUInteger = msg_send![archives, count]; + let ret = (0..count) + .map(|i| { + let a = msg_send![archives, objectAtIndex: i]; + BinaryArchive::from_ptr(a) + }) + .collect(); + ret + } + } + + /// API_AVAILABLE(macos(11.0), ios(14.0)); + /// Marshal from Rust slice + pub fn set_binary_archives(&self, archives: &[&BinaryArchiveRef]) { + let ns_array = Array::<BinaryArchive>::from_slice(archives); + unsafe { msg_send![self, setBinaryArchives: ns_array] } + } + + pub fn reset(&self) { + unsafe { msg_send![self, reset] } + } +} + +pub enum MTLRenderPipelineState {} + +foreign_obj_type! { + type CType = MTLRenderPipelineState; + pub struct RenderPipelineState; + pub struct RenderPipelineStateRef; +} + +impl RenderPipelineStateRef { + pub fn device(&self) -> &DeviceRef { + unsafe { msg_send![self, device] } + } + + pub fn label(&self) -> &str { + unsafe { + let label = msg_send![self, label]; + crate::nsstring_as_str(label) + } + } +} + +pub enum MTLRenderPipelineColorAttachmentDescriptorArray {} + +foreign_obj_type! { + type CType = MTLRenderPipelineColorAttachmentDescriptorArray; + pub struct RenderPipelineColorAttachmentDescriptorArray; + pub struct RenderPipelineColorAttachmentDescriptorArrayRef; +} + +impl RenderPipelineColorAttachmentDescriptorArrayRef { + pub fn object_at( + &self, + index: NSUInteger, + ) -> Option<&RenderPipelineColorAttachmentDescriptorRef> { + unsafe { msg_send![self, objectAtIndexedSubscript: index] } + } + + pub fn set_object_at( + &self, + index: NSUInteger, + attachment: Option<&RenderPipelineColorAttachmentDescriptorRef>, + ) { + unsafe { + msg_send![self, setObject:attachment + atIndexedSubscript:index] + } + } +} |