use std::{ffi::c_void, path::Path, ptr::NonNull};
use dispatch2::DispatchData;
use objc2::{Message, extern_protocol, msg_send, rc::Retained, runtime::ProtocolObject};
use objc2_foundation::{NSArray, NSError, NSObjectProtocol, NSString, NSURL};
use super::{MTLArchitecture, MTLSizeAndAlign};
use crate::{
MTL4Archive, MTL4ArgumentTable, MTL4ArgumentTableDescriptor, MTL4BinaryFunction,
MTL4CommandAllocatorDescriptor, MTL4CommandQueueDescriptor, MTL4CompilerDescriptor, MTL4CounterHeap,
MTL4CounterHeapDescriptor, MTL4CounterHeapType, MTL4PipelineDataSetSerializer,
MTL4PipelineDataSetSerializerDescriptor, MTLAccelerationStructure, MTLArgumentBuffersTier, MTLArgumentEncoder,
MTLBinaryArchive, MTLBinaryArchiveDescriptor, MTLBuffer, MTLBufferBinding, MTLCommandQueue,
MTLCommandQueueDescriptor, MTLCompileOptions, MTLComputePipelineDescriptor, MTLComputePipelineState,
MTLCounterSampleBuffer, MTLCounterSampleBufferDescriptor, MTLCounterSamplingPoint, MTLCounterSet,
MTLDepthStencilDescriptor, MTLDepthStencilState, MTLDeviceLocation, MTLDynamicLibrary, MTLEvent, MTLFeatureSet,
MTLFence, MTLFunction, MTLFunctionHandle, MTLGPUFamily, MTLHeap, MTLHeapDescriptor,
MTLIOCommandQueue, MTLIOCommandQueueDescriptor, MTLIOCompressionMethod, MTLIOFileHandle,
MTLIndirectCommandBuffer, MTLIndirectCommandBufferDescriptor, MTLLibrary, MTLLogState, MTLLogStateDescriptor,
MTLPipelineOption, MTLPixelFormat, MTLRasterizationRateMap, MTLRasterizationRateMapDescriptor,
MTLReadWriteTextureTier, MTLRenderPipelineDescriptor, MTLRenderPipelineReflection, MTLRenderPipelineState,
MTLResidencySet, MTLResidencySetDescriptor, MTLResourceOptions, MTLResourceViewPoolDescriptor,
MTLSamplePosition, MTLSamplerDescriptor, MTLSamplerState, MTLSharedEvent, MTLSharedEventHandle,
MTLSharedTextureHandle, MTLSize, MTLSparsePageSize, MTLTensor, MTLTensorDescriptor, MTLTexture,
MTLTextureDescriptor, MTLTextureType, MTLTextureViewPool,
acceleration_structure::{MTLAccelerationStructureDescriptor, MTLAccelerationStructureSizes},
argument::MTLArgumentDescriptor, compute_pipeline::MTLComputePipelineReflection,
function_stitching::MTLStitchedLibraryDescriptor,
render_pipeline::MTLTileRenderPipelineDescriptor,
};
extern_protocol!(
pub unsafe trait MTLDevice: NSObjectProtocol + Send + Sync {
#[unsafe(method(registryID))]
#[unsafe(method_family = none)]
fn registry_id(&self) -> u64;
#[unsafe(method(architecture))]
#[unsafe(method_family = none)]
fn architecture(&self) -> Retained<MTLArchitecture>;
#[unsafe(method(maxThreadsPerThreadgroup))]
#[unsafe(method_family = none)]
fn max_threads_per_threadgroup(&self) -> MTLSize;
#[unsafe(method(isLowPower))]
#[unsafe(method_family = none)]
fn is_low_power(&self) -> bool;
#[unsafe(method(isHeadless))]
#[unsafe(method_family = none)]
fn is_headless(&self) -> bool;
#[unsafe(method(hasUnifiedMemory))]
#[unsafe(method_family = none)]
fn has_unified_memory(&self) -> bool;
#[unsafe(method(recommendedMaxWorkingSetSize))]
#[unsafe(method_family = none)]
fn recommended_max_working_set_size(&self) -> u64;
#[unsafe(method(location))]
#[unsafe(method_family = none)]
fn location(&self) -> MTLDeviceLocation;
#[unsafe(method(locationNumber))]
#[unsafe(method_family = none)]
fn location_number(&self) -> usize;
#[unsafe(method(maxTransferRate))]
#[unsafe(method_family = none)]
fn max_transfer_rate(&self) -> u64;
#[unsafe(method(readWriteTextureSupport))]
#[unsafe(method_family = none)]
fn read_write_texture_support(&self) -> MTLReadWriteTextureTier;
#[unsafe(method(argumentBuffersSupport))]
#[unsafe(method_family = none)]
fn argument_buffers_support(&self) -> MTLArgumentBuffersTier;
#[unsafe(method(isDepth24Stencil8PixelFormatSupported))]
#[unsafe(method_family = none)]
fn is_depth24_stencil8_pixel_format_supported(&self) -> bool;
#[unsafe(method(supportsFamily:))]
#[unsafe(method_family = none)]
fn supports_family(
&self,
family: MTLGPUFamily,
) -> bool;
#[unsafe(method(supportsTextureSampleCount:))]
#[unsafe(method_family = none)]
fn supports_texture_sample_count(
&self,
sample_count: usize,
) -> bool;
#[unsafe(method(minimumLinearTextureAlignmentForPixelFormat:))]
#[unsafe(method_family = none)]
fn minimum_linear_texture_alignment_for_pixel_format(
&self,
format: MTLPixelFormat,
) -> usize;
#[unsafe(method(minimumTextureBufferAlignmentForPixelFormat:))]
#[unsafe(method_family = none)]
fn minimum_texture_buffer_alignment_for_pixel_format(
&self,
format: MTLPixelFormat,
) -> usize;
#[unsafe(method(newDepthStencilStateWithDescriptor:))]
#[unsafe(method_family = new)]
fn new_depth_stencil_state_with_descriptor(
&self,
descriptor: &MTLDepthStencilDescriptor,
) -> Option<Retained<ProtocolObject<dyn MTLDepthStencilState>>>;
#[unsafe(method(newCounterSampleBufferWithDescriptor:error:_))]
#[unsafe(method_family = none)]
fn new_counter_sample_buffer_with_descriptor_error(
&self,
descriptor: &MTLCounterSampleBufferDescriptor,
) -> Result<Retained<ProtocolObject<dyn MTLCounterSampleBuffer>>, Retained<NSError>>;
#[unsafe(method(sampleTimestamps:gpuTimestamp:))]
#[unsafe(method_family = none)]
fn sample_timestamps_gpu_timestamp(
&self,
cpu_timestamp: *mut u64,
gpu_timestamp: *mut u64,
);
#[unsafe(method(supportsCounterSampling:))]
#[unsafe(method_family = none)]
fn supports_counter_sampling(
&self,
sampling_point: MTLCounterSamplingPoint,
) -> bool;
#[unsafe(method(supportsQueryTextureLOD))]
#[unsafe(method_family = none)]
fn supports_query_texture_lod(&self) -> bool;
#[unsafe(method(supportsBCTextureCompression))]
#[unsafe(method_family = none)]
fn supports_bc_texture_compression(&self) -> bool;
#[unsafe(method(supportsPullModelInterpolation))]
#[unsafe(method_family = none)]
fn supports_pull_model_interpolation(&self) -> bool;
#[unsafe(method(areBarycentricCoordsSupported))]
#[unsafe(method_family = none)]
fn barycentric_coords_supported(&self) -> bool;
#[unsafe(method(supportsShaderBarycentricCoordinates))]
#[unsafe(method_family = none)]
fn supports_shader_barycentric_coordinates(&self) -> bool;
#[unsafe(method(currentAllocatedSize))]
#[unsafe(method_family = none)]
fn current_allocated_size(&self) -> usize;
#[unsafe(method(isRemovable))]
#[unsafe(method_family = none)]
fn is_removable(&self) -> bool;
#[unsafe(method(supports32BitFloatFiltering))]
#[unsafe(method_family = none)]
fn supports_32bit_float_filtering(&self) -> bool;
#[unsafe(method(supports32BitMSAA))]
#[unsafe(method_family = none)]
fn supports_32bit_msaa(&self) -> bool;
#[unsafe(method(maxArgumentBufferSamplerCount))]
#[unsafe(method_family = none)]
fn max_argument_buffer_sampler_count(&self) -> usize;
#[unsafe(method(areProgrammableSamplePositionsSupported))]
#[unsafe(method_family = none)]
fn are_programmable_sample_positions_supported(&self) -> bool;
#[unsafe(method(peerGroupID))]
#[unsafe(method_family = none)]
fn peer_group_id(&self) -> u64;
#[unsafe(method(peerIndex))]
#[unsafe(method_family = none)]
fn peer_index(&self) -> u32;
#[unsafe(method(peerCount))]
#[unsafe(method_family = none)]
fn peer_count(&self) -> u32;
#[unsafe(method(sparseTileSizeInBytes))]
#[unsafe(method_family = none)]
fn sparse_tile_size_in_bytes(&self) -> usize;
#[unsafe(method(supportsDynamicLibraries))]
#[unsafe(method_family = none)]
fn supports_dynamic_libraries(&self) -> bool;
#[unsafe(method(supportsRenderDynamicLibraries))]
#[unsafe(method_family = none)]
fn supports_render_dynamic_libraries(&self) -> bool;
#[unsafe(method(supportsPlacementSparse))]
#[unsafe(method_family = none)]
fn supports_placement_sparse(&self) -> bool;
#[unsafe(method(supportsRaytracing))]
#[unsafe(method_family = none)]
fn supports_raytracing(&self) -> bool;
#[unsafe(method(supportsFunctionPointers))]
#[unsafe(method_family = none)]
fn supports_function_pointers(&self) -> bool;
#[unsafe(method(supportsFunctionPointersFromRender))]
#[unsafe(method_family = none)]
fn supports_function_pointers_from_render(&self) -> bool;
#[unsafe(method(supportsRaytracingFromRender))]
#[unsafe(method_family = none)]
fn supports_raytracing_from_render(&self) -> bool;
#[unsafe(method(supportsPrimitiveMotionBlur))]
#[unsafe(method_family = none)]
fn supports_primitive_motion_blur(&self) -> bool;
#[unsafe(method(shouldMaximizeConcurrentCompilation))]
#[unsafe(method_family = none)]
fn should_maximize_concurrent_compilation(&self) -> bool;
#[unsafe(method(setShouldMaximizeConcurrentCompilation:))]
#[unsafe(method_family = none)]
fn set_should_maximize_concurrent_compilation(
&self,
value: bool,
);
#[unsafe(method(maximumConcurrentCompilationTaskCount))]
#[unsafe(method_family = none)]
fn maximum_concurrent_compilation_task_count(&self) -> usize;
#[unsafe(method(supportsRasterizationRateMapWithLayerCount:))]
#[unsafe(method_family = none)]
fn supports_rasterization_rate_map_with_layer_count(
&self,
layer_count: usize,
) -> bool;
#[unsafe(method(supportsVertexAmplificationCount:))]
#[unsafe(method_family = none)]
fn supports_vertex_amplification_count(
&self,
count: usize,
) -> bool;
#[unsafe(method(sparseTileSizeWithTextureType:pixelFormat:sampleCount:))]
#[unsafe(method_family = none)]
fn sparse_tile_size(
&self,
texture_type: MTLTextureType,
pixel_format: MTLPixelFormat,
sample_count: usize,
) -> MTLSize;
#[unsafe(method(sparseTileSizeInBytesForSparsePageSize:))]
#[unsafe(method_family = none)]
fn sparse_tile_size_in_bytes_for_sparse_page_size(
&self,
sparse_page_size: MTLSparsePageSize,
) -> usize;
#[unsafe(method(sparseTileSizeWithTextureType:pixelFormat:sampleCount:sparsePageSize:))]
#[unsafe(method_family = none)]
fn sparse_tile_size_with_page_size(
&self,
texture_type: MTLTextureType,
pixel_format: MTLPixelFormat,
sample_count: usize,
sparse_page_size: MTLSparsePageSize,
) -> MTLSize;
#[unsafe(method(heapTextureSizeAndAlignWithDescriptor:))]
#[unsafe(method_family = none)]
fn heap_texture_size_and_align(
&self,
descriptor: &MTLTextureDescriptor,
) -> MTLSizeAndAlign;
#[unsafe(method(heapBufferSizeAndAlignWithLength:options:))]
#[unsafe(method_family = none)]
fn heap_buffer_size_and_align(
&self,
length: usize,
options: MTLResourceOptions,
) -> MTLSizeAndAlign;
#[unsafe(method(heapAccelerationStructureSizeAndAlignWithSize:))]
#[unsafe(method_family = none)]
fn heap_acceleration_structure_size_and_align_with_size(
&self,
size: usize,
) -> MTLSizeAndAlign;
#[unsafe(method(heapAccelerationStructureSizeAndAlignWithDescriptor:))]
#[unsafe(method_family = none)]
fn heap_acceleration_structure_size_and_align_with_descriptor(
&self,
descriptor: &MTLAccelerationStructureDescriptor,
) -> MTLSizeAndAlign;
#[unsafe(method(accelerationStructureSizesWithDescriptor:))]
#[unsafe(method_family = none)]
fn acceleration_structure_sizes_with_descriptor(
&self,
descriptor: &MTLAccelerationStructureDescriptor,
) -> MTLAccelerationStructureSizes;
#[unsafe(method(newCommandQueueWithDescriptor:))]
#[unsafe(method_family = new)]
fn new_command_queue_with_descriptor(
&self,
descriptor: &MTLCommandQueueDescriptor,
) -> Option<Retained<ProtocolObject<dyn MTLCommandQueue>>>;
#[unsafe(method(newSharedTextureWithDescriptor:))]
#[unsafe(method_family = new)]
fn new_shared_texture_with_descriptor(
&self,
descriptor: &MTLTextureDescriptor,
) -> Option<Retained<ProtocolObject<dyn MTLTexture>>>;
#[unsafe(method(newSharedTextureWithHandle:))]
#[unsafe(method_family = new)]
fn new_shared_texture_with_handle(
&self,
shared_handle: &MTLSharedTextureHandle,
) -> Option<Retained<ProtocolObject<dyn MTLTexture>>>;
#[unsafe(method(newRasterizationRateMapWithDescriptor:))]
#[unsafe(method_family = new)]
fn new_rasterization_rate_map_with_descriptor(
&self,
descriptor: &MTLRasterizationRateMapDescriptor,
) -> Option<Retained<ProtocolObject<dyn MTLRasterizationRateMap>>>;
#[unsafe(method(newIndirectCommandBufferWithDescriptor:maxCommandCount:options:))]
#[unsafe(method_family = new)]
fn new_indirect_command_buffer_with_descriptor(
&self,
descriptor: &MTLIndirectCommandBufferDescriptor,
max_count: usize,
options: MTLResourceOptions,
) -> Option<Retained<ProtocolObject<dyn MTLIndirectCommandBuffer>>>;
#[unsafe(method(newBinaryArchiveWithDescriptor:error:_))]
#[unsafe(method_family = none)]
fn new_binary_archive_with_descriptor(
&self,
descriptor: &MTLBinaryArchiveDescriptor,
) -> Result<Retained<ProtocolObject<dyn MTLBinaryArchive>>, Retained<NSError>>;
#[unsafe(method(newArgumentEncoderWithBufferBinding:))]
#[unsafe(method_family = new)]
fn new_argument_encoder_with_buffer_binding(
&self,
buffer_binding: &ProtocolObject<dyn MTLBufferBinding>,
) -> Retained<ProtocolObject<dyn MTLArgumentEncoder>>;
}
);
#[allow(unused)]
pub trait MTLDeviceExt: MTLDevice + Message {
fn name(&self) -> String;
fn raster_order_groups_supported(&self) -> bool;
fn max_threadgroup_memory_length(&self) -> usize;
fn max_buffer_length(&self) -> usize;
fn counter_sets(&self) -> Option<Box<[Retained<ProtocolObject<dyn MTLCounterSet>>]>>;
fn new_log_state_with_descriptor(&self, descriptor: &MTLLogStateDescriptor) -> Result<Retained<ProtocolObject<dyn MTLLogState>>, Retained<NSError>>;
fn new_command_queue(&self) -> Option<Retained<ProtocolObject<dyn MTLCommandQueue>>>;
fn new_command_queue_with_max_command_buffer_count(&self, max_count: usize) -> Option<Retained<ProtocolObject<dyn MTLCommandQueue>>>;
fn new_heap_with_descriptor(&self, descriptor: &MTLHeapDescriptor) -> Option<Retained<ProtocolObject<dyn MTLHeap>>>;
fn new_buffer(&self, length: usize, options: MTLResourceOptions) -> Option<Retained<ProtocolObject<dyn MTLBuffer>>>;
fn new_buffer_with_data(&self, data: &[u8], options: MTLResourceOptions) -> Option<Retained<ProtocolObject<dyn MTLBuffer>>>;
fn new_buffer_with_bytes_no_copy(&self, ptr: NonNull<c_void>, length: usize, options: MTLResourceOptions) -> Option<Retained<ProtocolObject<dyn MTLBuffer>>>;
fn new_texture_with_descriptor(&self, descriptor: &MTLTextureDescriptor) -> Option<Retained<ProtocolObject<dyn MTLTexture>>>;
fn new_sampler_state_with_descriptor(&self, descriptor: &MTLSamplerDescriptor) -> Option<Retained<ProtocolObject<dyn MTLSamplerState>>>;
fn new_default_library(&self) -> Option<Retained<ProtocolObject<dyn MTLLibrary>>>;
fn new_library_with_path(&self, path: &Path) -> Result<Retained<ProtocolObject<dyn MTLLibrary>>, Retained<NSError>>;
fn new_library_with_data(&self, data: &[u8]) -> Result<Retained<ProtocolObject<dyn MTLLibrary>>, Retained<NSError>>;
fn new_library_with_source(&self, source: &str, options: Option<&MTLCompileOptions>) -> Result<Retained<ProtocolObject<dyn MTLLibrary>>, Retained<NSError>>;
fn new_library_with_stitched_descriptor(&self, descriptor: &MTLStitchedLibraryDescriptor) -> Result<Retained<ProtocolObject<dyn MTLLibrary>>, Retained<NSError>>;
fn new_render_pipeline_state_with_descriptor(&self, descriptor: &MTLRenderPipelineDescriptor) -> Result<Retained<ProtocolObject<dyn MTLRenderPipelineState>>, Retained<NSError>>;
fn new_compute_pipeline_state_with_function(&self, function: &ProtocolObject<dyn MTLFunction>) -> Result<Retained<ProtocolObject<dyn MTLComputePipelineState>>, Retained<NSError>>;
fn new_compute_pipeline_state_with_descriptor(&self, descriptor: &MTLComputePipelineDescriptor, options: MTLPipelineOption) -> Result<(Retained<ProtocolObject<dyn MTLComputePipelineState>>, Option<Retained<MTLComputePipelineReflection>>), Retained<NSError>>;
fn new_fence(&self) -> Option<Retained<ProtocolObject<dyn MTLFence>>>;
fn supports_feature_set(&self, feature_set: MTLFeatureSet) -> bool;
fn new_argument_encoder_with_arguments(&self, arguments: &[&MTLArgumentDescriptor]) -> Option<Retained<ProtocolObject<dyn MTLArgumentEncoder>>>;
fn new_event(&self) -> Option<Retained<ProtocolObject<dyn MTLEvent>>>;
fn new_shared_event(&self) -> Option<Retained<ProtocolObject<dyn MTLSharedEvent>>>;
fn new_shared_event_with_handle(&self, handle: &MTLSharedEventHandle) -> Option<Retained<ProtocolObject<dyn MTLSharedEvent>>>;
fn new_io_command_queue_with_descriptor(&self, descriptor: &MTLIOCommandQueueDescriptor) -> Result<Retained<ProtocolObject<dyn MTLIOCommandQueue>>, Retained<NSError>>;
fn new_dynamic_library(&self, library: &ProtocolObject<dyn MTLLibrary>) -> Result<Retained<ProtocolObject<dyn MTLDynamicLibrary>>, Retained<NSError>>;
fn new_dynamic_library_with_path(&self, path: &Path) -> Result<Retained<ProtocolObject<dyn MTLDynamicLibrary>>, Retained<NSError>>;
fn new_acceleration_structure_with_size(&self, size: usize) -> Option<Retained<ProtocolObject<dyn MTLAccelerationStructure>>>;
fn new_acceleration_structure_with_descriptor(&self, descriptor: &MTLAccelerationStructureDescriptor) -> Option<Retained<ProtocolObject<dyn MTLAccelerationStructure>>>;
fn new_residency_set_with_descriptor(&self, descriptor: &MTLResidencySetDescriptor) -> Result<Retained<ProtocolObject<dyn MTLResidencySet>>, Retained<NSError>>;
fn tensor_size_and_align_with_descriptor(&self, descriptor: &MTLTensorDescriptor) -> MTLSizeAndAlign;
fn new_tensor_with_descriptor(&self, descriptor: &MTLTensorDescriptor) -> Result<Retained<ProtocolObject<dyn MTLTensor>>, Retained<NSError>>;
fn function_handle_with_function(&self, function: &ProtocolObject<dyn MTLFunction>) -> Option<Retained<ProtocolObject<dyn MTLFunctionHandle>>>;
fn new_command_allocator(&self) -> Option<Retained<ProtocolObject<dyn crate::MTL4CommandAllocator>>>;
fn new_command_allocator_with_descriptor(&self, descriptor: &MTL4CommandAllocatorDescriptor) -> Result<Retained<ProtocolObject<dyn crate::MTL4CommandAllocator>>, Retained<NSError>>;
fn new_mtl4_command_queue(&self) -> Option<Retained<ProtocolObject<dyn crate::MTL4CommandQueue>>>;
fn new_mtl4_command_queue_with_descriptor(&self, descriptor: &MTL4CommandQueueDescriptor) -> Result<Retained<ProtocolObject<dyn crate::MTL4CommandQueue>>, Retained<NSError>>;
fn new_mtl4_command_buffer(&self) -> Option<Retained<ProtocolObject<dyn crate::MTL4CommandBuffer>>>;
fn new_argument_table_with_descriptor(&self, descriptor: &MTL4ArgumentTableDescriptor) -> Result<Retained<ProtocolObject<dyn MTL4ArgumentTable>>, Retained<NSError>>;
fn new_texture_view_pool_with_descriptor(&self, descriptor: &MTLResourceViewPoolDescriptor) -> Result<Retained<ProtocolObject<dyn MTLTextureViewPool>>, Retained<NSError>>;
fn new_compiler_with_descriptor(&self, descriptor: &MTL4CompilerDescriptor) -> Result<Retained<ProtocolObject<dyn crate::MTL4Compiler>>, Retained<NSError>>;
fn new_archive_with_url(&self, url: &NSURL) -> Result<Retained<ProtocolObject<dyn MTL4Archive>>, Retained<NSError>>;
fn new_pipeline_data_set_serializer_with_descriptor(&self, descriptor: &MTL4PipelineDataSetSerializerDescriptor) -> Retained<ProtocolObject<dyn MTL4PipelineDataSetSerializer>>;
fn new_buffer_with_length_options_placement_sparse_page_size(&self, length: usize, options: MTLResourceOptions, placement_sparse_page_size: MTLSparsePageSize) -> Option<Retained<ProtocolObject<dyn MTLBuffer>>>;
fn new_counter_heap_with_descriptor(&self, descriptor: &MTL4CounterHeapDescriptor) -> Result<Retained<ProtocolObject<dyn MTL4CounterHeap>>, Retained<NSError>>;
fn size_of_counter_heap_entry(&self, counter_heap_type: MTL4CounterHeapType) -> usize;
fn query_timestamp_frequency(&self) -> u64;
fn function_handle_with_binary_function(&self, function: &ProtocolObject<dyn MTL4BinaryFunction>) -> Option<Retained<ProtocolObject<dyn MTLFunctionHandle>>>;
fn default_sample_positions(&self, sample_count: usize) -> Box<[MTLSamplePosition]>;
fn get_default_sample_positions(&self, positions: &mut [MTLSamplePosition]);
fn new_io_file_handle_with_url(&self, path: &Path) -> Result<Retained<ProtocolObject<dyn MTLIOFileHandle>>, Retained<NSError>>;
fn new_io_file_handle_with_url_compression_method(&self, path: &Path, compression_method: MTLIOCompressionMethod) -> Result<Retained<ProtocolObject<dyn MTLIOFileHandle>>, Retained<NSError>>;
fn new_render_pipeline_state_with_descriptor_options(&self, descriptor: &MTLRenderPipelineDescriptor, options: MTLPipelineOption) -> Result<(Retained<ProtocolObject<dyn MTLRenderPipelineState>>, Option<Retained<MTLRenderPipelineReflection>>), Retained<NSError>>;
fn new_compute_pipeline_state_with_function_options(&self, function: &ProtocolObject<dyn MTLFunction>, options: MTLPipelineOption) -> Result<(Retained<ProtocolObject<dyn MTLComputePipelineState>>, Option<Retained<MTLComputePipelineReflection>>), Retained<NSError>>;
fn new_render_pipeline_state_with_tile_descriptor(&self, descriptor: &MTLTileRenderPipelineDescriptor, options: MTLPipelineOption) -> Result<(Retained<ProtocolObject<dyn MTLRenderPipelineState>>, Option<Retained<MTLRenderPipelineReflection>>), Retained<NSError>>;
}
impl MTLDeviceExt for ProtocolObject<dyn MTLDevice> {
fn name(&self) -> String {
let ns: Retained<NSString> = unsafe { msg_send![self, name] };
ns.to_string()
}
fn raster_order_groups_supported(&self) -> bool {
unsafe { msg_send![self, areRasterOrderGroupsSupported] }
}
fn max_threadgroup_memory_length(&self) -> usize {
unsafe { msg_send![self, maxThreadgroupMemoryLength] }
}
fn max_buffer_length(&self) -> usize {
unsafe { msg_send![self, maxBufferLength] }
}
fn counter_sets(&self) -> Option<Box<[Retained<ProtocolObject<dyn MTLCounterSet>>]>> {
let array: Option<Retained<NSArray<ProtocolObject<dyn MTLCounterSet>>>> =
unsafe { msg_send![self, counterSets] };
array.map(|a| a.to_vec().into_boxed_slice())
}
fn new_log_state_with_descriptor(
&self,
descriptor: &MTLLogStateDescriptor,
) -> Result<Retained<ProtocolObject<dyn MTLLogState>>, Retained<NSError>> {
unsafe { msg_send![self, newLogStateWithDescriptor: descriptor, error: _] }
}
fn new_command_queue(&self) -> Option<Retained<ProtocolObject<dyn MTLCommandQueue>>> {
unsafe { msg_send![self, newCommandQueue] }
}
fn new_command_queue_with_max_command_buffer_count(
&self,
max_count: usize,
) -> Option<Retained<ProtocolObject<dyn MTLCommandQueue>>> {
unsafe { msg_send![self, newCommandQueueWithMaxCommandBufferCount: max_count] }
}
fn new_heap_with_descriptor(
&self,
descriptor: &MTLHeapDescriptor,
) -> Option<Retained<ProtocolObject<dyn MTLHeap>>> {
unsafe { msg_send![self, newHeapWithDescriptor: descriptor] }
}
fn new_buffer(
&self,
length: usize,
options: MTLResourceOptions,
) -> Option<Retained<ProtocolObject<dyn MTLBuffer>>> {
unsafe { msg_send![self, newBufferWithLength: length, options: options] }
}
fn new_buffer_with_data(
&self,
data: &[u8],
options: MTLResourceOptions,
) -> Option<Retained<ProtocolObject<dyn MTLBuffer>>> {
unsafe {
msg_send![
self,
newBufferWithBytes: data.as_ptr() as *const c_void,
length: data.len(),
options: options
]
}
}
fn new_buffer_with_bytes_no_copy(
&self,
ptr: NonNull<c_void>,
length: usize,
options: MTLResourceOptions,
) -> Option<Retained<ProtocolObject<dyn MTLBuffer>>> {
let deallocator: Option<&crate::block2::Block<dyn Fn(*mut c_void, usize)>> = None;
unsafe {
msg_send![
self,
newBufferWithBytesNoCopy: ptr.as_ptr(),
length: length,
options: options,
deallocator: deallocator
]
}
}
fn new_texture_with_descriptor(
&self,
descriptor: &MTLTextureDescriptor,
) -> Option<Retained<ProtocolObject<dyn MTLTexture>>> {
unsafe { msg_send![self, newTextureWithDescriptor: descriptor] }
}
fn new_sampler_state_with_descriptor(
&self,
descriptor: &MTLSamplerDescriptor,
) -> Option<Retained<ProtocolObject<dyn MTLSamplerState>>> {
unsafe { msg_send![self, newSamplerStateWithDescriptor: descriptor] }
}
fn new_default_library(&self) -> Option<Retained<ProtocolObject<dyn MTLLibrary>>> {
unsafe { msg_send![self, newDefaultLibrary] }
}
fn new_library_with_path(
&self,
path: &Path,
) -> Result<Retained<ProtocolObject<dyn MTLLibrary>>, Retained<NSError>> {
let url = NSURL::from_file_path(path).expect("path must be a valid file URL path");
unsafe { msg_send![self, newLibraryWithURL: &*url, error: _] }
}
fn new_library_with_data(
&self,
data: &[u8],
) -> Result<Retained<ProtocolObject<dyn MTLLibrary>>, Retained<NSError>> {
let dispatch_data = DispatchData::from_bytes(data);
unsafe { msg_send![self, newLibraryWithData: &*dispatch_data, error: _] }
}
fn new_library_with_source(
&self,
source: &str,
options: Option<&MTLCompileOptions>,
) -> Result<Retained<ProtocolObject<dyn MTLLibrary>>, Retained<NSError>> {
let source = NSString::from_str(source);
unsafe { msg_send![self, newLibraryWithSource: &*source, options: options, error: _] }
}
fn new_library_with_stitched_descriptor(
&self,
descriptor: &MTLStitchedLibraryDescriptor,
) -> Result<Retained<ProtocolObject<dyn MTLLibrary>>, Retained<NSError>> {
unsafe { msg_send![self, newLibraryWithStitchedDescriptor: descriptor, error: _] }
}
fn new_render_pipeline_state_with_descriptor(
&self,
descriptor: &MTLRenderPipelineDescriptor,
) -> Result<Retained<ProtocolObject<dyn MTLRenderPipelineState>>, Retained<NSError>> {
unsafe { msg_send![self, newRenderPipelineStateWithDescriptor: descriptor, error: _] }
}
fn new_compute_pipeline_state_with_function(
&self,
function: &ProtocolObject<dyn MTLFunction>,
) -> Result<Retained<ProtocolObject<dyn MTLComputePipelineState>>, Retained<NSError>> {
unsafe { msg_send![self, newComputePipelineStateWithFunction: function, error: _] }
}
fn new_compute_pipeline_state_with_descriptor(
&self,
descriptor: &MTLComputePipelineDescriptor,
options: MTLPipelineOption,
) -> Result<
(Retained<ProtocolObject<dyn MTLComputePipelineState>>, Option<Retained<MTLComputePipelineReflection>>),
Retained<NSError>,
> {
let mut reflection: *mut MTLComputePipelineReflection = std::ptr::null_mut();
let mut error: *mut NSError = std::ptr::null_mut();
let result: Option<Retained<ProtocolObject<dyn MTLComputePipelineState>>> = unsafe {
msg_send![
self,
newComputePipelineStateWithDescriptor: descriptor,
options: options,
reflection: &mut reflection,
error: &mut error
]
};
match result {
Some(pso) => {
let reflection_obj = if reflection.is_null() {
None
} else {
unsafe { Retained::retain(reflection) }
};
Ok((pso, reflection_obj))
},
None => Err(unsafe { Retained::retain(error).unwrap() }),
}
}
fn new_fence(&self) -> Option<Retained<ProtocolObject<dyn MTLFence>>> {
unsafe { msg_send![self, newFence] }
}
fn supports_feature_set(&self, feature_set: MTLFeatureSet) -> bool {
unsafe { msg_send![self, supportsFeatureSet: feature_set] }
}
fn new_argument_encoder_with_arguments(
&self,
arguments: &[&MTLArgumentDescriptor],
) -> Option<Retained<ProtocolObject<dyn MTLArgumentEncoder>>> {
let arguments = NSArray::from_slice(arguments);
unsafe { msg_send![self, newArgumentEncoderWithArguments: &*arguments] }
}
fn new_event(&self) -> Option<Retained<ProtocolObject<dyn MTLEvent>>> {
unsafe { msg_send![self, newEvent] }
}
fn new_shared_event(&self) -> Option<Retained<ProtocolObject<dyn MTLSharedEvent>>> {
unsafe { msg_send![self, newSharedEvent] }
}
fn new_shared_event_with_handle(
&self,
handle: &MTLSharedEventHandle,
) -> Option<Retained<ProtocolObject<dyn MTLSharedEvent>>> {
unsafe { msg_send![self, newSharedEventWithHandle: handle] }
}
fn new_io_command_queue_with_descriptor(
&self,
descriptor: &MTLIOCommandQueueDescriptor,
) -> Result<Retained<ProtocolObject<dyn MTLIOCommandQueue>>, Retained<NSError>> {
unsafe { msg_send![self, newIOCommandQueueWithDescriptor: descriptor, error: _] }
}
fn new_dynamic_library(
&self,
library: &ProtocolObject<dyn MTLLibrary>,
) -> Result<Retained<ProtocolObject<dyn MTLDynamicLibrary>>, Retained<NSError>> {
unsafe { msg_send![self, newDynamicLibrary: library, error: _] }
}
fn new_dynamic_library_with_path(
&self,
path: &Path,
) -> Result<Retained<ProtocolObject<dyn MTLDynamicLibrary>>, Retained<NSError>> {
let url = NSURL::from_file_path(path).expect("path must be a valid file URL path");
unsafe { msg_send![self, newDynamicLibraryWithURL: &*url, error: _] }
}
fn new_acceleration_structure_with_size(
&self,
size: usize,
) -> Option<Retained<ProtocolObject<dyn MTLAccelerationStructure>>> {
unsafe { msg_send![self, newAccelerationStructureWithSize: size] }
}
fn new_acceleration_structure_with_descriptor(
&self,
descriptor: &MTLAccelerationStructureDescriptor,
) -> Option<Retained<ProtocolObject<dyn MTLAccelerationStructure>>> {
unsafe { msg_send![self, newAccelerationStructureWithDescriptor: descriptor] }
}
fn new_residency_set_with_descriptor(
&self,
descriptor: &MTLResidencySetDescriptor,
) -> Result<Retained<ProtocolObject<dyn MTLResidencySet>>, Retained<NSError>> {
unsafe { msg_send![self, newResidencySetWithDescriptor: descriptor, error: _] }
}
fn tensor_size_and_align_with_descriptor(
&self,
descriptor: &MTLTensorDescriptor,
) -> MTLSizeAndAlign {
unsafe { msg_send![self, tensorSizeAndAlignWithDescriptor: descriptor] }
}
fn new_tensor_with_descriptor(
&self,
descriptor: &MTLTensorDescriptor,
) -> Result<Retained<ProtocolObject<dyn MTLTensor>>, Retained<NSError>> {
unsafe { msg_send![self, newTensorWithDescriptor: descriptor, error: _] }
}
fn function_handle_with_function(
&self,
function: &ProtocolObject<dyn MTLFunction>,
) -> Option<Retained<ProtocolObject<dyn MTLFunctionHandle>>> {
unsafe { msg_send![self, functionHandleWithFunction: function] }
}
fn new_command_allocator(&self) -> Option<Retained<ProtocolObject<dyn crate::MTL4CommandAllocator>>> {
unsafe { msg_send![self, newCommandAllocator] }
}
fn new_command_allocator_with_descriptor(
&self,
descriptor: &MTL4CommandAllocatorDescriptor,
) -> Result<Retained<ProtocolObject<dyn crate::MTL4CommandAllocator>>, Retained<NSError>> {
unsafe { msg_send![self, newCommandAllocatorWithDescriptor: descriptor, error: _] }
}
fn new_mtl4_command_queue(&self) -> Option<Retained<ProtocolObject<dyn crate::MTL4CommandQueue>>> {
unsafe { msg_send![self, newMTL4CommandQueue] }
}
fn new_mtl4_command_queue_with_descriptor(
&self,
descriptor: &MTL4CommandQueueDescriptor,
) -> Result<Retained<ProtocolObject<dyn crate::MTL4CommandQueue>>, Retained<NSError>> {
unsafe { msg_send![self, newMTL4CommandQueueWithDescriptor: descriptor, error: _] }
}
fn new_mtl4_command_buffer(&self) -> Option<Retained<ProtocolObject<dyn crate::MTL4CommandBuffer>>> {
unsafe { msg_send![self, newCommandBuffer] }
}
fn new_argument_table_with_descriptor(
&self,
descriptor: &MTL4ArgumentTableDescriptor,
) -> Result<Retained<ProtocolObject<dyn MTL4ArgumentTable>>, Retained<NSError>> {
unsafe { msg_send![self, newArgumentTableWithDescriptor: descriptor, error: _] }
}
fn new_texture_view_pool_with_descriptor(
&self,
descriptor: &MTLResourceViewPoolDescriptor,
) -> Result<Retained<ProtocolObject<dyn MTLTextureViewPool>>, Retained<NSError>> {
unsafe { msg_send![self, newTextureViewPoolWithDescriptor: descriptor, error: _] }
}
fn new_compiler_with_descriptor(
&self,
descriptor: &MTL4CompilerDescriptor,
) -> Result<Retained<ProtocolObject<dyn crate::MTL4Compiler>>, Retained<NSError>> {
unsafe { msg_send![self, newCompilerWithDescriptor: descriptor, error: _] }
}
fn new_archive_with_url(
&self,
url: &NSURL,
) -> Result<Retained<ProtocolObject<dyn MTL4Archive>>, Retained<NSError>> {
unsafe { msg_send![self, newArchiveWithURL: url, error: _] }
}
fn new_pipeline_data_set_serializer_with_descriptor(
&self,
descriptor: &MTL4PipelineDataSetSerializerDescriptor,
) -> Retained<ProtocolObject<dyn MTL4PipelineDataSetSerializer>> {
unsafe { msg_send![self, newPipelineDataSetSerializerWithDescriptor: descriptor] }
}
fn new_buffer_with_length_options_placement_sparse_page_size(
&self,
length: usize,
options: MTLResourceOptions,
placement_sparse_page_size: MTLSparsePageSize,
) -> Option<Retained<ProtocolObject<dyn MTLBuffer>>> {
unsafe {
msg_send![
self,
newBufferWithLength: length,
options: options,
placementSparsePageSize: placement_sparse_page_size
]
}
}
fn new_counter_heap_with_descriptor(
&self,
descriptor: &MTL4CounterHeapDescriptor,
) -> Result<Retained<ProtocolObject<dyn MTL4CounterHeap>>, Retained<NSError>> {
unsafe { msg_send![self, newCounterHeapWithDescriptor: descriptor, error: _] }
}
fn size_of_counter_heap_entry(&self, counter_heap_type: MTL4CounterHeapType) -> usize {
unsafe { msg_send![self, sizeOfCounterHeapEntry: counter_heap_type] }
}
fn query_timestamp_frequency(&self) -> u64 {
unsafe { msg_send![self, queryTimestampFrequency] }
}
fn function_handle_with_binary_function(
&self,
function: &ProtocolObject<dyn MTL4BinaryFunction>,
) -> Option<Retained<ProtocolObject<dyn MTLFunctionHandle>>> {
unsafe { msg_send![self, functionHandleWithBinaryFunction: function] }
}
fn default_sample_positions(
&self,
sample_count: usize,
) -> Box<[MTLSamplePosition]> {
let mut positions: Box<[MTLSamplePosition]> =
vec![MTLSamplePosition { x: 0.0, y: 0.0 }; sample_count].into_boxed_slice();
unsafe {
let _: () = msg_send![
self,
getDefaultSamplePositions: positions.as_mut_ptr(),
count: sample_count
];
}
positions
}
fn get_default_sample_positions(
&self,
positions: &mut [MTLSamplePosition],
) {
let count = positions.len();
unsafe {
let _: () = msg_send![
self,
getDefaultSamplePositions: positions.as_mut_ptr(),
count: count
];
}
}
fn new_io_file_handle_with_url(
&self,
path: &Path,
) -> Result<Retained<ProtocolObject<dyn MTLIOFileHandle>>, Retained<NSError>> {
let url = NSURL::from_file_path(path).expect("path must be a valid file URL path");
unsafe { msg_send![self, newIOFileHandleWithURL: &*url, error: _] }
}
fn new_io_file_handle_with_url_compression_method(
&self,
path: &Path,
compression_method: MTLIOCompressionMethod,
) -> Result<Retained<ProtocolObject<dyn MTLIOFileHandle>>, Retained<NSError>> {
let url = NSURL::from_file_path(path).expect("path must be a valid file URL path");
unsafe {
msg_send![
self,
newIOFileHandleWithURL: &*url,
compressionMethod: compression_method,
error: _
]
}
}
fn new_render_pipeline_state_with_descriptor_options(
&self,
descriptor: &MTLRenderPipelineDescriptor,
options: MTLPipelineOption,
) -> Result<
(Retained<ProtocolObject<dyn MTLRenderPipelineState>>, Option<Retained<MTLRenderPipelineReflection>>),
Retained<NSError>,
> {
let mut reflection: *mut MTLRenderPipelineReflection = std::ptr::null_mut();
let mut error: *mut NSError = std::ptr::null_mut();
let result: Option<Retained<ProtocolObject<dyn MTLRenderPipelineState>>> = unsafe {
msg_send![
self,
newRenderPipelineStateWithDescriptor: descriptor,
options: options,
reflection: &mut reflection,
error: &mut error
]
};
match result {
Some(pso) => {
let reflection_obj = if reflection.is_null() {
None
} else {
unsafe { Retained::retain(reflection) }
};
Ok((pso, reflection_obj))
},
None => Err(unsafe { Retained::retain(error).unwrap() }),
}
}
fn new_compute_pipeline_state_with_function_options(
&self,
function: &ProtocolObject<dyn MTLFunction>,
options: MTLPipelineOption,
) -> Result<
(Retained<ProtocolObject<dyn MTLComputePipelineState>>, Option<Retained<MTLComputePipelineReflection>>),
Retained<NSError>,
> {
let mut reflection: *mut MTLComputePipelineReflection = std::ptr::null_mut();
let mut error: *mut NSError = std::ptr::null_mut();
let result: Option<Retained<ProtocolObject<dyn MTLComputePipelineState>>> = unsafe {
msg_send![
self,
newComputePipelineStateWithFunction: function,
options: options,
reflection: &mut reflection,
error: &mut error
]
};
match result {
Some(pso) => {
let reflection_obj = if reflection.is_null() {
None
} else {
unsafe { Retained::retain(reflection) }
};
Ok((pso, reflection_obj))
},
None => Err(unsafe { Retained::retain(error).unwrap() }),
}
}
fn new_render_pipeline_state_with_tile_descriptor(
&self,
descriptor: &MTLTileRenderPipelineDescriptor,
options: MTLPipelineOption,
) -> Result<
(Retained<ProtocolObject<dyn MTLRenderPipelineState>>, Option<Retained<MTLRenderPipelineReflection>>),
Retained<NSError>,
> {
let mut reflection: *mut MTLRenderPipelineReflection = std::ptr::null_mut();
let mut error: *mut NSError = std::ptr::null_mut();
let result: Option<Retained<ProtocolObject<dyn MTLRenderPipelineState>>> = unsafe {
msg_send![
self,
newRenderPipelineStateWithTileDescriptor: descriptor,
options: options,
reflection: &mut reflection,
error: &mut error
]
};
match result {
Some(pso) => {
let reflection_obj = if reflection.is_null() {
None
} else {
unsafe { Retained::retain(reflection) }
};
Ok((pso, reflection_obj))
},
None => Err(unsafe { Retained::retain(error).unwrap() }),
}
}
}
impl dyn MTLDevice {
#[inline]
pub fn system_default() -> Option<Retained<ProtocolObject<dyn MTLDevice>>> {
unsafe extern "C" {
fn MTLCreateSystemDefaultDevice() -> *mut ProtocolObject<dyn MTLDevice>;
}
let ret = unsafe { MTLCreateSystemDefaultDevice() };
unsafe { Retained::from_raw(ret) }
}
}