use objc2::{
extern_class, extern_conformance, extern_methods, msg_send,
rc::{Allocated, Retained},
runtime::{NSObject, ProtocolObject},
};
use objc2_foundation::{CopyingHelper, NSArray, NSCopying, NSObjectProtocol, NSString};
use crate::{
MTLBinaryArchive, MTLDynamicLibrary, MTLLinkedFunctions, MTLPipelineBufferDescriptorArray,
MTLStageInputOutputDescriptor, library::MTLFunction,
};
extern_class!(
#[unsafe(super(NSObject))]
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct MTLComputePipelineDescriptor;
);
extern_conformance!(
unsafe impl NSCopying for MTLComputePipelineDescriptor {}
);
unsafe impl CopyingHelper for MTLComputePipelineDescriptor {
type Result = Self;
}
extern_conformance!(
unsafe impl NSObjectProtocol for MTLComputePipelineDescriptor {}
);
impl MTLComputePipelineDescriptor {
extern_methods!(
#[unsafe(method(computeFunction))]
#[unsafe(method_family = none)]
pub fn compute_function(&self) -> Option<Retained<ProtocolObject<dyn MTLFunction>>>;
#[unsafe(method(setComputeFunction:))]
#[unsafe(method_family = none)]
pub fn set_compute_function(
&self,
compute_function: Option<&ProtocolObject<dyn MTLFunction>>,
);
#[unsafe(method(threadGroupSizeIsMultipleOfThreadExecutionWidth))]
#[unsafe(method_family = none)]
pub fn thread_group_size_is_multiple_of_thread_execution_width(&self) -> bool;
#[unsafe(method(setThreadGroupSizeIsMultipleOfThreadExecutionWidth:))]
#[unsafe(method_family = none)]
pub fn set_thread_group_size_is_multiple_of_thread_execution_width(
&self,
value: bool,
);
#[unsafe(method(maxTotalThreadsPerThreadgroup))]
#[unsafe(method_family = none)]
pub fn max_total_threads_per_threadgroup(&self) -> usize;
#[unsafe(method(setMaxTotalThreadsPerThreadgroup:))]
#[unsafe(method_family = none)]
pub fn set_max_total_threads_per_threadgroup(
&self,
value: usize,
);
#[unsafe(method(stageInputDescriptor))]
#[unsafe(method_family = none)]
pub fn stage_input_descriptor(&self) -> Option<Retained<MTLStageInputOutputDescriptor>>;
#[unsafe(method(setStageInputDescriptor:))]
#[unsafe(method_family = none)]
pub fn set_stage_input_descriptor(
&self,
descriptor: Option<&MTLStageInputOutputDescriptor>,
);
#[unsafe(method(buffers))]
#[unsafe(method_family = none)]
pub fn buffers(&self) -> Retained<MTLPipelineBufferDescriptorArray>;
#[unsafe(method(supportIndirectCommandBuffers))]
#[unsafe(method_family = none)]
pub fn support_indirect_command_buffers(&self) -> bool;
#[unsafe(method(setSupportIndirectCommandBuffers:))]
#[unsafe(method_family = none)]
pub fn set_support_indirect_command_buffers(
&self,
enabled: bool,
);
#[unsafe(method(linkedFunctions))]
#[unsafe(method_family = none)]
pub fn linked_functions(&self) -> Option<Retained<MTLLinkedFunctions>>;
#[unsafe(method(setLinkedFunctions:))]
#[unsafe(method_family = none)]
pub fn set_linked_functions(
&self,
linked: Option<&MTLLinkedFunctions>,
);
#[unsafe(method(supportAddingBinaryFunctions))]
#[unsafe(method_family = none)]
pub fn support_adding_binary_functions(&self) -> bool;
#[unsafe(method(setSupportAddingBinaryFunctions:))]
#[unsafe(method_family = none)]
pub fn set_support_adding_binary_functions(
&self,
supported: bool,
);
#[unsafe(method(maxCallStackDepth))]
#[unsafe(method_family = none)]
pub fn max_call_stack_depth(&self) -> usize;
#[unsafe(method(setMaxCallStackDepth:))]
#[unsafe(method_family = none)]
pub fn set_max_call_stack_depth(
&self,
depth: usize,
);
#[unsafe(method(reset))]
#[unsafe(method_family = none)]
pub fn reset(&self);
#[unsafe(method(shaderValidation))]
#[unsafe(method_family = none)]
pub fn shader_validation(&self) -> crate::pipeline::MTLShaderValidation;
#[unsafe(method(setShaderValidation:))]
#[unsafe(method_family = none)]
pub fn set_shader_validation(
&self,
value: crate::pipeline::MTLShaderValidation,
);
#[unsafe(method(requiredThreadsPerThreadgroup))]
#[unsafe(method_family = none)]
pub fn required_threads_per_threadgroup(&self) -> crate::types::MTLSize;
#[unsafe(method(setRequiredThreadsPerThreadgroup:))]
#[unsafe(method_family = none)]
pub fn set_required_threads_per_threadgroup(
&self,
size: crate::types::MTLSize,
);
);
}
impl MTLComputePipelineDescriptor {
extern_methods!(
#[unsafe(method(init))]
#[unsafe(method_family = init)]
pub fn init(this: Allocated<Self>) -> Retained<Self>;
#[unsafe(method(new))]
#[unsafe(method_family = new)]
pub fn new() -> Retained<Self>;
);
}
impl MTLComputePipelineDescriptor {
#[deprecated(note = "use preloaded_libraries")]
pub fn insert_libraries(&self) -> Option<Box<[Retained<ProtocolObject<dyn MTLDynamicLibrary>>]>> {
let libraries: Option<Retained<NSArray<ProtocolObject<dyn MTLDynamicLibrary>>>> =
unsafe { msg_send![self, insertLibraries] };
libraries.map(|libraries| libraries.to_vec().into_boxed_slice())
}
#[deprecated(note = "use set_preloaded_libraries")]
pub fn set_insert_libraries(
&self,
libraries: Option<&[&ProtocolObject<dyn MTLDynamicLibrary>]>,
) {
let libraries = libraries.map(NSArray::from_slice);
unsafe {
let _: () = msg_send![self, setInsertLibraries: libraries.as_deref()];
}
}
pub fn preloaded_libraries(&self) -> Box<[Retained<ProtocolObject<dyn MTLDynamicLibrary>>]> {
let libraries: Retained<NSArray<ProtocolObject<dyn MTLDynamicLibrary>>> =
unsafe { msg_send![self, preloadedLibraries] };
libraries.to_vec().into_boxed_slice()
}
pub fn set_preloaded_libraries(
&self,
libraries: &[&ProtocolObject<dyn MTLDynamicLibrary>],
) {
let libraries = NSArray::from_slice(libraries);
unsafe {
let _: () = msg_send![self, setPreloadedLibraries: &*libraries];
}
}
pub fn binary_archives(&self) -> Option<Box<[Retained<ProtocolObject<dyn MTLBinaryArchive>>]>> {
let archives: Option<Retained<NSArray<ProtocolObject<dyn MTLBinaryArchive>>>> =
unsafe { msg_send![self, binaryArchives] };
archives.map(|archives| archives.to_vec().into_boxed_slice())
}
pub fn set_binary_archives(
&self,
archives: Option<&[&ProtocolObject<dyn MTLBinaryArchive>]>,
) {
let archives = archives.map(NSArray::from_slice);
unsafe {
let _: () = msg_send![self, setBinaryArchives: archives.as_deref()];
}
}
pub fn label(&self) -> Option<String> {
let label: Option<Retained<NSString>> = unsafe { msg_send![self, label] };
label.map(|s| s.to_string())
}
pub fn set_label(
&self,
label: Option<&str>,
) {
unsafe {
let _: () = msg_send![self, setLabel: label.map(NSString::from_str).as_deref()];
}
}
}
#[cfg(test)]
mod tests {
use objc2::{rc::Retained, runtime::ProtocolObject};
use super::MTLComputePipelineDescriptor;
use crate::{MTLBinaryArchive, MTLDynamicLibrary};
#[test]
#[expect(deprecated, reason = "verifies the deprecated Rust-native compatibility API")]
fn collection_methods_have_rust_native_signatures() {
let _: fn(&MTLComputePipelineDescriptor) -> Option<Box<[Retained<ProtocolObject<dyn MTLDynamicLibrary>>]>> =
MTLComputePipelineDescriptor::insert_libraries;
let _: fn(&MTLComputePipelineDescriptor) -> Box<[Retained<ProtocolObject<dyn MTLDynamicLibrary>>]> =
MTLComputePipelineDescriptor::preloaded_libraries;
let _: fn(&MTLComputePipelineDescriptor) -> Option<Box<[Retained<ProtocolObject<dyn MTLBinaryArchive>>]>> =
MTLComputePipelineDescriptor::binary_archives;
let _: fn(&MTLComputePipelineDescriptor, &[&ProtocolObject<dyn MTLDynamicLibrary>]) =
MTLComputePipelineDescriptor::set_preloaded_libraries;
let _: fn(&MTLComputePipelineDescriptor, Option<&[&ProtocolObject<dyn MTLBinaryArchive>]>) =
MTLComputePipelineDescriptor::set_binary_archives;
}
}