//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::ffi::*;
use core::ptr::NonNull;
use objc2::__framework_prelude::*;
use objc2_foundation::*;

use crate::*;

/// [Apple's documentation](https://developer.apple.com/documentation/metal/mtlblendfactor?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTLBlendFactor(pub NSUInteger);
impl MTLBlendFactor {
    #[doc(alias = "MTLBlendFactorZero")]
    pub const Zero: Self = Self(0);
    #[doc(alias = "MTLBlendFactorOne")]
    pub const One: Self = Self(1);
    #[doc(alias = "MTLBlendFactorSourceColor")]
    pub const SourceColor: Self = Self(2);
    #[doc(alias = "MTLBlendFactorOneMinusSourceColor")]
    pub const OneMinusSourceColor: Self = Self(3);
    #[doc(alias = "MTLBlendFactorSourceAlpha")]
    pub const SourceAlpha: Self = Self(4);
    #[doc(alias = "MTLBlendFactorOneMinusSourceAlpha")]
    pub const OneMinusSourceAlpha: Self = Self(5);
    #[doc(alias = "MTLBlendFactorDestinationColor")]
    pub const DestinationColor: Self = Self(6);
    #[doc(alias = "MTLBlendFactorOneMinusDestinationColor")]
    pub const OneMinusDestinationColor: Self = Self(7);
    #[doc(alias = "MTLBlendFactorDestinationAlpha")]
    pub const DestinationAlpha: Self = Self(8);
    #[doc(alias = "MTLBlendFactorOneMinusDestinationAlpha")]
    pub const OneMinusDestinationAlpha: Self = Self(9);
    #[doc(alias = "MTLBlendFactorSourceAlphaSaturated")]
    pub const SourceAlphaSaturated: Self = Self(10);
    #[doc(alias = "MTLBlendFactorBlendColor")]
    pub const BlendColor: Self = Self(11);
    #[doc(alias = "MTLBlendFactorOneMinusBlendColor")]
    pub const OneMinusBlendColor: Self = Self(12);
    #[doc(alias = "MTLBlendFactorBlendAlpha")]
    pub const BlendAlpha: Self = Self(13);
    #[doc(alias = "MTLBlendFactorOneMinusBlendAlpha")]
    pub const OneMinusBlendAlpha: Self = Self(14);
    #[doc(alias = "MTLBlendFactorSource1Color")]
    pub const Source1Color: Self = Self(15);
    #[doc(alias = "MTLBlendFactorOneMinusSource1Color")]
    pub const OneMinusSource1Color: Self = Self(16);
    #[doc(alias = "MTLBlendFactorSource1Alpha")]
    pub const Source1Alpha: Self = Self(17);
    #[doc(alias = "MTLBlendFactorOneMinusSource1Alpha")]
    pub const OneMinusSource1Alpha: Self = Self(18);
    /// Defers assigning the blend factor.
    ///
    /// Until you specialize this value in the pipeline state, it:
    /// * behaves as `MTLBlendFactorOne` for `sourceRGBBlendFactor` and `sourceAlphaBlendFactor`
    /// * behaves as `MTLBlendFactorZero` for `destinationRGBBlendFactor` and `destinationAlphaBlendFactor`
    #[doc(alias = "MTLBlendFactorUnspecialized")]
    pub const Unspecialized: Self = Self(19);
}

unsafe impl Encode for MTLBlendFactor {
    const ENCODING: Encoding = NSUInteger::ENCODING;
}

unsafe impl RefEncode for MTLBlendFactor {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// [Apple's documentation](https://developer.apple.com/documentation/metal/mtlblendoperation?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTLBlendOperation(pub NSUInteger);
impl MTLBlendOperation {
    #[doc(alias = "MTLBlendOperationAdd")]
    pub const Add: Self = Self(0);
    #[doc(alias = "MTLBlendOperationSubtract")]
    pub const Subtract: Self = Self(1);
    #[doc(alias = "MTLBlendOperationReverseSubtract")]
    pub const ReverseSubtract: Self = Self(2);
    #[doc(alias = "MTLBlendOperationMin")]
    pub const Min: Self = Self(3);
    #[doc(alias = "MTLBlendOperationMax")]
    pub const Max: Self = Self(4);
    /// Defers assigning the blend operation.
    #[doc(alias = "MTLBlendOperationUnspecialized")]
    pub const Unspecialized: Self = Self(5);
}

unsafe impl Encode for MTLBlendOperation {
    const ENCODING: Encoding = NSUInteger::ENCODING;
}

unsafe impl RefEncode for MTLBlendOperation {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// [Apple's documentation](https://developer.apple.com/documentation/metal/mtlcolorwritemask?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTLColorWriteMask(pub NSUInteger);
bitflags::bitflags! {
    impl MTLColorWriteMask: NSUInteger {
        #[doc(alias = "MTLColorWriteMaskNone")]
        const None = 0;
        #[doc(alias = "MTLColorWriteMaskRed")]
        const Red = 0x1<<3;
        #[doc(alias = "MTLColorWriteMaskGreen")]
        const Green = 0x1<<2;
        #[doc(alias = "MTLColorWriteMaskBlue")]
        const Blue = 0x1<<1;
        #[doc(alias = "MTLColorWriteMaskAlpha")]
        const Alpha = 0x1<<0;
        #[doc(alias = "MTLColorWriteMaskAll")]
        const All = 0xf;
/// Defers assigning the color write mask.
///
/// Until you specialize this value in the pipeline state, it behaves as `MTLColorWriteMaskAll`.
        #[doc(alias = "MTLColorWriteMaskUnspecialized")]
        const Unspecialized = 0x10;
    }
}

unsafe impl Encode for MTLColorWriteMask {
    const ENCODING: Encoding = NSUInteger::ENCODING;
}

unsafe impl RefEncode for MTLColorWriteMask {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// [Apple's documentation](https://developer.apple.com/documentation/metal/mtlprimitivetopologyclass?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTLPrimitiveTopologyClass(pub NSUInteger);
impl MTLPrimitiveTopologyClass {
    #[doc(alias = "MTLPrimitiveTopologyClassUnspecified")]
    pub const Unspecified: Self = Self(0);
    #[doc(alias = "MTLPrimitiveTopologyClassPoint")]
    pub const Point: Self = Self(1);
    #[doc(alias = "MTLPrimitiveTopologyClassLine")]
    pub const Line: Self = Self(2);
    #[doc(alias = "MTLPrimitiveTopologyClassTriangle")]
    pub const Triangle: Self = Self(3);
}

unsafe impl Encode for MTLPrimitiveTopologyClass {
    const ENCODING: Encoding = NSUInteger::ENCODING;
}

unsafe impl RefEncode for MTLPrimitiveTopologyClass {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// [Apple's documentation](https://developer.apple.com/documentation/metal/mtltessellationpartitionmode?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTLTessellationPartitionMode(pub NSUInteger);
impl MTLTessellationPartitionMode {
    #[doc(alias = "MTLTessellationPartitionModePow2")]
    pub const Pow2: Self = Self(0);
    #[doc(alias = "MTLTessellationPartitionModeInteger")]
    pub const Integer: Self = Self(1);
    #[doc(alias = "MTLTessellationPartitionModeFractionalOdd")]
    pub const FractionalOdd: Self = Self(2);
    #[doc(alias = "MTLTessellationPartitionModeFractionalEven")]
    pub const FractionalEven: Self = Self(3);
}

unsafe impl Encode for MTLTessellationPartitionMode {
    const ENCODING: Encoding = NSUInteger::ENCODING;
}

unsafe impl RefEncode for MTLTessellationPartitionMode {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// [Apple's documentation](https://developer.apple.com/documentation/metal/mtltessellationfactorstepfunction?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTLTessellationFactorStepFunction(pub NSUInteger);
impl MTLTessellationFactorStepFunction {
    #[doc(alias = "MTLTessellationFactorStepFunctionConstant")]
    pub const Constant: Self = Self(0);
    #[doc(alias = "MTLTessellationFactorStepFunctionPerPatch")]
    pub const PerPatch: Self = Self(1);
    #[doc(alias = "MTLTessellationFactorStepFunctionPerInstance")]
    pub const PerInstance: Self = Self(2);
    #[doc(alias = "MTLTessellationFactorStepFunctionPerPatchAndPerInstance")]
    pub const PerPatchAndPerInstance: Self = Self(3);
}

unsafe impl Encode for MTLTessellationFactorStepFunction {
    const ENCODING: Encoding = NSUInteger::ENCODING;
}

unsafe impl RefEncode for MTLTessellationFactorStepFunction {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// [Apple's documentation](https://developer.apple.com/documentation/metal/mtltessellationfactorformat?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTLTessellationFactorFormat(pub NSUInteger);
impl MTLTessellationFactorFormat {
    #[doc(alias = "MTLTessellationFactorFormatHalf")]
    pub const Half: Self = Self(0);
}

unsafe impl Encode for MTLTessellationFactorFormat {
    const ENCODING: Encoding = NSUInteger::ENCODING;
}

unsafe impl RefEncode for MTLTessellationFactorFormat {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// [Apple's documentation](https://developer.apple.com/documentation/metal/mtltessellationcontrolpointindextype?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTLTessellationControlPointIndexType(pub NSUInteger);
impl MTLTessellationControlPointIndexType {
    #[doc(alias = "MTLTessellationControlPointIndexTypeNone")]
    pub const None: Self = Self(0);
    #[doc(alias = "MTLTessellationControlPointIndexTypeUInt16")]
    pub const UInt16: Self = Self(1);
    #[doc(alias = "MTLTessellationControlPointIndexTypeUInt32")]
    pub const UInt32: Self = Self(2);
}

unsafe impl Encode for MTLTessellationControlPointIndexType {
    const ENCODING: Encoding = NSUInteger::ENCODING;
}

unsafe impl RefEncode for MTLTessellationControlPointIndexType {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/metal/mtlrenderpipelinecolorattachmentdescriptor?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct MTLRenderPipelineColorAttachmentDescriptor;
);

extern_conformance!(
    unsafe impl NSCopying for MTLRenderPipelineColorAttachmentDescriptor {}
);

unsafe impl CopyingHelper for MTLRenderPipelineColorAttachmentDescriptor {
    type Result = Self;
}

extern_conformance!(
    unsafe impl NSObjectProtocol for MTLRenderPipelineColorAttachmentDescriptor {}
);

impl MTLRenderPipelineColorAttachmentDescriptor {
    extern_methods!(
        #[cfg(feature = "MTLPixelFormat")]
        /// Pixel format.  Defaults to MTLPixelFormatInvalid
        #[unsafe(method(pixelFormat))]
        #[unsafe(method_family = none)]
        pub fn pixelFormat(&self) -> MTLPixelFormat;

        #[cfg(feature = "MTLPixelFormat")]
        /// Setter for [`pixelFormat`][Self::pixelFormat].
        #[unsafe(method(setPixelFormat:))]
        #[unsafe(method_family = none)]
        pub fn setPixelFormat(&self, pixel_format: MTLPixelFormat);

        /// Enable blending.  Defaults to NO.
        #[unsafe(method(isBlendingEnabled))]
        #[unsafe(method_family = none)]
        pub fn isBlendingEnabled(&self) -> bool;

        /// Setter for [`isBlendingEnabled`][Self::isBlendingEnabled].
        #[unsafe(method(setBlendingEnabled:))]
        #[unsafe(method_family = none)]
        pub fn setBlendingEnabled(&self, blending_enabled: bool);

        /// Defaults to MTLBlendFactorOne
        #[unsafe(method(sourceRGBBlendFactor))]
        #[unsafe(method_family = none)]
        pub fn sourceRGBBlendFactor(&self) -> MTLBlendFactor;

        /// Setter for [`sourceRGBBlendFactor`][Self::sourceRGBBlendFactor].
        #[unsafe(method(setSourceRGBBlendFactor:))]
        #[unsafe(method_family = none)]
        pub fn setSourceRGBBlendFactor(&self, source_rgb_blend_factor: MTLBlendFactor);

        /// Defaults to MTLBlendFactorZero
        #[unsafe(method(destinationRGBBlendFactor))]
        #[unsafe(method_family = none)]
        pub fn destinationRGBBlendFactor(&self) -> MTLBlendFactor;

        /// Setter for [`destinationRGBBlendFactor`][Self::destinationRGBBlendFactor].
        #[unsafe(method(setDestinationRGBBlendFactor:))]
        #[unsafe(method_family = none)]
        pub fn setDestinationRGBBlendFactor(&self, destination_rgb_blend_factor: MTLBlendFactor);

        /// Defaults to MTLBlendOperationAdd
        #[unsafe(method(rgbBlendOperation))]
        #[unsafe(method_family = none)]
        pub fn rgbBlendOperation(&self) -> MTLBlendOperation;

        /// Setter for [`rgbBlendOperation`][Self::rgbBlendOperation].
        #[unsafe(method(setRgbBlendOperation:))]
        #[unsafe(method_family = none)]
        pub fn setRgbBlendOperation(&self, rgb_blend_operation: MTLBlendOperation);

        /// Defaults to MTLBlendFactorOne
        #[unsafe(method(sourceAlphaBlendFactor))]
        #[unsafe(method_family = none)]
        pub fn sourceAlphaBlendFactor(&self) -> MTLBlendFactor;

        /// Setter for [`sourceAlphaBlendFactor`][Self::sourceAlphaBlendFactor].
        #[unsafe(method(setSourceAlphaBlendFactor:))]
        #[unsafe(method_family = none)]
        pub fn setSourceAlphaBlendFactor(&self, source_alpha_blend_factor: MTLBlendFactor);

        /// Defaults to MTLBlendFactorZero
        #[unsafe(method(destinationAlphaBlendFactor))]
        #[unsafe(method_family = none)]
        pub fn destinationAlphaBlendFactor(&self) -> MTLBlendFactor;

        /// Setter for [`destinationAlphaBlendFactor`][Self::destinationAlphaBlendFactor].
        #[unsafe(method(setDestinationAlphaBlendFactor:))]
        #[unsafe(method_family = none)]
        pub fn setDestinationAlphaBlendFactor(
            &self,
            destination_alpha_blend_factor: MTLBlendFactor,
        );

        /// Defaults to MTLBlendOperationAdd
        #[unsafe(method(alphaBlendOperation))]
        #[unsafe(method_family = none)]
        pub fn alphaBlendOperation(&self) -> MTLBlendOperation;

        /// Setter for [`alphaBlendOperation`][Self::alphaBlendOperation].
        #[unsafe(method(setAlphaBlendOperation:))]
        #[unsafe(method_family = none)]
        pub fn setAlphaBlendOperation(&self, alpha_blend_operation: MTLBlendOperation);

        /// Defaults to MTLColorWriteMaskAll
        #[unsafe(method(writeMask))]
        #[unsafe(method_family = none)]
        pub fn writeMask(&self) -> MTLColorWriteMask;

        /// Setter for [`writeMask`][Self::writeMask].
        #[unsafe(method(setWriteMask:))]
        #[unsafe(method_family = none)]
        pub fn setWriteMask(&self, write_mask: MTLColorWriteMask);
    );
}

/// Methods declared on superclass `NSObject`.
impl MTLRenderPipelineColorAttachmentDescriptor {
    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 DefaultRetained for MTLRenderPipelineColorAttachmentDescriptor {
    #[inline]
    fn default_retained() -> Retained<Self> {
        Self::new()
    }
}

extern_class!(
    /// Allows you to easily specify color attachment remapping from logical to physical indices.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtllogicaltophysicalcolorattachmentmap?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct MTLLogicalToPhysicalColorAttachmentMap;
);

extern_conformance!(
    unsafe impl NSCopying for MTLLogicalToPhysicalColorAttachmentMap {}
);

unsafe impl CopyingHelper for MTLLogicalToPhysicalColorAttachmentMap {
    type Result = Self;
}

extern_conformance!(
    unsafe impl NSObjectProtocol for MTLLogicalToPhysicalColorAttachmentMap {}
);

impl MTLLogicalToPhysicalColorAttachmentMap {
    extern_methods!(
        /// Maps a physical color attachment index to a logical index.
        ///
        /// - Parameters:
        /// - physicalIndex: index of the color attachment's physical mapping.
        /// - logicalIndex: index of the color attachment's logical mapping.
        ///
        /// # Safety
        ///
        /// - `physicalIndex` might not be bounds-checked.
        /// - `logicalIndex` might not be bounds-checked.
        #[unsafe(method(setPhysicalIndex:forLogicalIndex:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setPhysicalIndex_forLogicalIndex(
            &self,
            physical_index: NSUInteger,
            logical_index: NSUInteger,
        );

        /// Queries the physical color attachment index corresponding to a logical index.
        ///
        /// # Safety
        ///
        /// `logicalIndex` might not be bounds-checked.
        #[unsafe(method(getPhysicalIndexForLogicalIndex:))]
        #[unsafe(method_family = none)]
        pub unsafe fn getPhysicalIndexForLogicalIndex(
            &self,
            logical_index: NSUInteger,
        ) -> NSUInteger;

        #[unsafe(method(reset))]
        #[unsafe(method_family = none)]
        pub fn reset(&self);
    );
}

/// Methods declared on superclass `NSObject`.
impl MTLLogicalToPhysicalColorAttachmentMap {
    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 DefaultRetained for MTLLogicalToPhysicalColorAttachmentMap {
    #[inline]
    fn default_retained() -> Retained<Self> {
        Self::new()
    }
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/metal/mtlrenderpipelinereflection?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct MTLRenderPipelineReflection;
);

unsafe impl Send for MTLRenderPipelineReflection {}

unsafe impl Sync for MTLRenderPipelineReflection {}

extern_conformance!(
    unsafe impl NSObjectProtocol for MTLRenderPipelineReflection {}
);

impl MTLRenderPipelineReflection {
    extern_methods!(
        #[cfg(feature = "MTLArgument")]
        #[unsafe(method(vertexBindings))]
        #[unsafe(method_family = none)]
        pub fn vertexBindings(&self) -> Retained<NSArray<ProtocolObject<dyn MTLBinding>>>;

        #[cfg(feature = "MTLArgument")]
        #[unsafe(method(fragmentBindings))]
        #[unsafe(method_family = none)]
        pub fn fragmentBindings(&self) -> Retained<NSArray<ProtocolObject<dyn MTLBinding>>>;

        #[cfg(feature = "MTLArgument")]
        #[unsafe(method(tileBindings))]
        #[unsafe(method_family = none)]
        pub fn tileBindings(&self) -> Retained<NSArray<ProtocolObject<dyn MTLBinding>>>;

        #[cfg(feature = "MTLArgument")]
        #[unsafe(method(objectBindings))]
        #[unsafe(method_family = none)]
        pub fn objectBindings(&self) -> Retained<NSArray<ProtocolObject<dyn MTLBinding>>>;

        #[cfg(feature = "MTLArgument")]
        #[unsafe(method(meshBindings))]
        #[unsafe(method_family = none)]
        pub fn meshBindings(&self) -> Retained<NSArray<ProtocolObject<dyn MTLBinding>>>;

        #[cfg(feature = "MTLArgument")]
        #[deprecated]
        #[unsafe(method(vertexArguments))]
        #[unsafe(method_family = none)]
        pub fn vertexArguments(&self) -> Option<Retained<NSArray<MTLArgument>>>;

        #[cfg(feature = "MTLArgument")]
        #[deprecated]
        #[unsafe(method(fragmentArguments))]
        #[unsafe(method_family = none)]
        pub fn fragmentArguments(&self) -> Option<Retained<NSArray<MTLArgument>>>;

        #[cfg(feature = "MTLArgument")]
        #[deprecated]
        #[unsafe(method(tileArguments))]
        #[unsafe(method_family = none)]
        pub fn tileArguments(&self) -> Option<Retained<NSArray<MTLArgument>>>;
    );
}

/// Methods declared on superclass `NSObject`.
impl MTLRenderPipelineReflection {
    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 DefaultRetained for MTLRenderPipelineReflection {
    #[inline]
    fn default_retained() -> Retained<Self> {
        Self::new()
    }
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/metal/mtlrenderpipelinedescriptor?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct MTLRenderPipelineDescriptor;
);

extern_conformance!(
    unsafe impl NSCopying for MTLRenderPipelineDescriptor {}
);

unsafe impl CopyingHelper for MTLRenderPipelineDescriptor {
    type Result = Self;
}

extern_conformance!(
    unsafe impl NSObjectProtocol for MTLRenderPipelineDescriptor {}
);

impl MTLRenderPipelineDescriptor {
    extern_methods!(
        #[unsafe(method(label))]
        #[unsafe(method_family = none)]
        pub fn label(&self) -> Option<Retained<NSString>>;

        /// Setter for [`label`][Self::label].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setLabel:))]
        #[unsafe(method_family = none)]
        pub fn setLabel(&self, label: Option<&NSString>);

        #[cfg(feature = "MTLLibrary")]
        #[unsafe(method(vertexFunction))]
        #[unsafe(method_family = none)]
        pub fn vertexFunction(&self) -> Option<Retained<ProtocolObject<dyn MTLFunction>>>;

        #[cfg(feature = "MTLLibrary")]
        /// Setter for [`vertexFunction`][Self::vertexFunction].
        #[unsafe(method(setVertexFunction:))]
        #[unsafe(method_family = none)]
        pub fn setVertexFunction(&self, vertex_function: Option<&ProtocolObject<dyn MTLFunction>>);

        #[cfg(feature = "MTLLibrary")]
        #[unsafe(method(fragmentFunction))]
        #[unsafe(method_family = none)]
        pub fn fragmentFunction(&self) -> Option<Retained<ProtocolObject<dyn MTLFunction>>>;

        #[cfg(feature = "MTLLibrary")]
        /// Setter for [`fragmentFunction`][Self::fragmentFunction].
        #[unsafe(method(setFragmentFunction:))]
        #[unsafe(method_family = none)]
        pub fn setFragmentFunction(
            &self,
            fragment_function: Option<&ProtocolObject<dyn MTLFunction>>,
        );

        #[cfg(feature = "MTLVertexDescriptor")]
        #[unsafe(method(vertexDescriptor))]
        #[unsafe(method_family = none)]
        pub fn vertexDescriptor(&self) -> Option<Retained<MTLVertexDescriptor>>;

        #[cfg(feature = "MTLVertexDescriptor")]
        /// Setter for [`vertexDescriptor`][Self::vertexDescriptor].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setVertexDescriptor:))]
        #[unsafe(method_family = none)]
        pub fn setVertexDescriptor(&self, vertex_descriptor: Option<&MTLVertexDescriptor>);

        #[deprecated]
        #[unsafe(method(sampleCount))]
        #[unsafe(method_family = none)]
        pub fn sampleCount(&self) -> NSUInteger;

        /// Setter for [`sampleCount`][Self::sampleCount].
        #[deprecated]
        #[unsafe(method(setSampleCount:))]
        #[unsafe(method_family = none)]
        pub fn setSampleCount(&self, sample_count: NSUInteger);

        #[unsafe(method(rasterSampleCount))]
        #[unsafe(method_family = none)]
        pub fn rasterSampleCount(&self) -> NSUInteger;

        /// Setter for [`rasterSampleCount`][Self::rasterSampleCount].
        #[unsafe(method(setRasterSampleCount:))]
        #[unsafe(method_family = none)]
        pub fn setRasterSampleCount(&self, raster_sample_count: NSUInteger);

        #[unsafe(method(isAlphaToCoverageEnabled))]
        #[unsafe(method_family = none)]
        pub fn isAlphaToCoverageEnabled(&self) -> bool;

        /// Setter for [`isAlphaToCoverageEnabled`][Self::isAlphaToCoverageEnabled].
        #[unsafe(method(setAlphaToCoverageEnabled:))]
        #[unsafe(method_family = none)]
        pub fn setAlphaToCoverageEnabled(&self, alpha_to_coverage_enabled: bool);

        #[unsafe(method(isAlphaToOneEnabled))]
        #[unsafe(method_family = none)]
        pub fn isAlphaToOneEnabled(&self) -> bool;

        /// Setter for [`isAlphaToOneEnabled`][Self::isAlphaToOneEnabled].
        #[unsafe(method(setAlphaToOneEnabled:))]
        #[unsafe(method_family = none)]
        pub fn setAlphaToOneEnabled(&self, alpha_to_one_enabled: bool);

        #[unsafe(method(isRasterizationEnabled))]
        #[unsafe(method_family = none)]
        pub fn isRasterizationEnabled(&self) -> bool;

        /// Setter for [`isRasterizationEnabled`][Self::isRasterizationEnabled].
        #[unsafe(method(setRasterizationEnabled:))]
        #[unsafe(method_family = none)]
        pub fn setRasterizationEnabled(&self, rasterization_enabled: bool);

        #[unsafe(method(maxVertexAmplificationCount))]
        #[unsafe(method_family = none)]
        pub fn maxVertexAmplificationCount(&self) -> NSUInteger;

        /// Setter for [`maxVertexAmplificationCount`][Self::maxVertexAmplificationCount].
        ///
        /// # Safety
        ///
        /// This might not be bounds-checked.
        #[unsafe(method(setMaxVertexAmplificationCount:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setMaxVertexAmplificationCount(
            &self,
            max_vertex_amplification_count: NSUInteger,
        );

        #[unsafe(method(colorAttachments))]
        #[unsafe(method_family = none)]
        pub fn colorAttachments(&self)
            -> Retained<MTLRenderPipelineColorAttachmentDescriptorArray>;

        #[cfg(feature = "MTLPixelFormat")]
        #[unsafe(method(depthAttachmentPixelFormat))]
        #[unsafe(method_family = none)]
        pub fn depthAttachmentPixelFormat(&self) -> MTLPixelFormat;

        #[cfg(feature = "MTLPixelFormat")]
        /// Setter for [`depthAttachmentPixelFormat`][Self::depthAttachmentPixelFormat].
        #[unsafe(method(setDepthAttachmentPixelFormat:))]
        #[unsafe(method_family = none)]
        pub fn setDepthAttachmentPixelFormat(&self, depth_attachment_pixel_format: MTLPixelFormat);

        #[cfg(feature = "MTLPixelFormat")]
        #[unsafe(method(stencilAttachmentPixelFormat))]
        #[unsafe(method_family = none)]
        pub fn stencilAttachmentPixelFormat(&self) -> MTLPixelFormat;

        #[cfg(feature = "MTLPixelFormat")]
        /// Setter for [`stencilAttachmentPixelFormat`][Self::stencilAttachmentPixelFormat].
        #[unsafe(method(setStencilAttachmentPixelFormat:))]
        #[unsafe(method_family = none)]
        pub fn setStencilAttachmentPixelFormat(
            &self,
            stencil_attachment_pixel_format: MTLPixelFormat,
        );

        #[unsafe(method(inputPrimitiveTopology))]
        #[unsafe(method_family = none)]
        pub fn inputPrimitiveTopology(&self) -> MTLPrimitiveTopologyClass;

        /// Setter for [`inputPrimitiveTopology`][Self::inputPrimitiveTopology].
        #[unsafe(method(setInputPrimitiveTopology:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setInputPrimitiveTopology(
            &self,
            input_primitive_topology: MTLPrimitiveTopologyClass,
        );

        #[unsafe(method(tessellationPartitionMode))]
        #[unsafe(method_family = none)]
        pub fn tessellationPartitionMode(&self) -> MTLTessellationPartitionMode;

        /// Setter for [`tessellationPartitionMode`][Self::tessellationPartitionMode].
        #[unsafe(method(setTessellationPartitionMode:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setTessellationPartitionMode(
            &self,
            tessellation_partition_mode: MTLTessellationPartitionMode,
        );

        #[unsafe(method(maxTessellationFactor))]
        #[unsafe(method_family = none)]
        pub fn maxTessellationFactor(&self) -> NSUInteger;

        /// Setter for [`maxTessellationFactor`][Self::maxTessellationFactor].
        #[unsafe(method(setMaxTessellationFactor:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setMaxTessellationFactor(&self, max_tessellation_factor: NSUInteger);

        #[unsafe(method(isTessellationFactorScaleEnabled))]
        #[unsafe(method_family = none)]
        pub fn isTessellationFactorScaleEnabled(&self) -> bool;

        /// Setter for [`isTessellationFactorScaleEnabled`][Self::isTessellationFactorScaleEnabled].
        #[unsafe(method(setTessellationFactorScaleEnabled:))]
        #[unsafe(method_family = none)]
        pub fn setTessellationFactorScaleEnabled(&self, tessellation_factor_scale_enabled: bool);

        #[unsafe(method(tessellationFactorFormat))]
        #[unsafe(method_family = none)]
        pub fn tessellationFactorFormat(&self) -> MTLTessellationFactorFormat;

        /// Setter for [`tessellationFactorFormat`][Self::tessellationFactorFormat].
        #[unsafe(method(setTessellationFactorFormat:))]
        #[unsafe(method_family = none)]
        pub fn setTessellationFactorFormat(
            &self,
            tessellation_factor_format: MTLTessellationFactorFormat,
        );

        #[unsafe(method(tessellationControlPointIndexType))]
        #[unsafe(method_family = none)]
        pub fn tessellationControlPointIndexType(&self) -> MTLTessellationControlPointIndexType;

        /// Setter for [`tessellationControlPointIndexType`][Self::tessellationControlPointIndexType].
        #[unsafe(method(setTessellationControlPointIndexType:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setTessellationControlPointIndexType(
            &self,
            tessellation_control_point_index_type: MTLTessellationControlPointIndexType,
        );

        #[unsafe(method(tessellationFactorStepFunction))]
        #[unsafe(method_family = none)]
        pub fn tessellationFactorStepFunction(&self) -> MTLTessellationFactorStepFunction;

        /// Setter for [`tessellationFactorStepFunction`][Self::tessellationFactorStepFunction].
        #[unsafe(method(setTessellationFactorStepFunction:))]
        #[unsafe(method_family = none)]
        pub fn setTessellationFactorStepFunction(
            &self,
            tessellation_factor_step_function: MTLTessellationFactorStepFunction,
        );

        #[cfg(feature = "MTLRenderCommandEncoder")]
        #[unsafe(method(tessellationOutputWindingOrder))]
        #[unsafe(method_family = none)]
        pub fn tessellationOutputWindingOrder(&self) -> MTLWinding;

        #[cfg(feature = "MTLRenderCommandEncoder")]
        /// Setter for [`tessellationOutputWindingOrder`][Self::tessellationOutputWindingOrder].
        #[unsafe(method(setTessellationOutputWindingOrder:))]
        #[unsafe(method_family = none)]
        pub fn setTessellationOutputWindingOrder(
            &self,
            tessellation_output_winding_order: MTLWinding,
        );

        #[cfg(feature = "MTLPipeline")]
        #[unsafe(method(vertexBuffers))]
        #[unsafe(method_family = none)]
        pub fn vertexBuffers(&self) -> Retained<MTLPipelineBufferDescriptorArray>;

        #[cfg(feature = "MTLPipeline")]
        #[unsafe(method(fragmentBuffers))]
        #[unsafe(method_family = none)]
        pub fn fragmentBuffers(&self) -> Retained<MTLPipelineBufferDescriptorArray>;

        #[unsafe(method(supportIndirectCommandBuffers))]
        #[unsafe(method_family = none)]
        pub fn supportIndirectCommandBuffers(&self) -> bool;

        /// Setter for [`supportIndirectCommandBuffers`][Self::supportIndirectCommandBuffers].
        #[unsafe(method(setSupportIndirectCommandBuffers:))]
        #[unsafe(method_family = none)]
        pub fn setSupportIndirectCommandBuffers(&self, support_indirect_command_buffers: bool);

        #[cfg(feature = "MTLBinaryArchive")]
        /// The set of MTLBinaryArchive to search for compiled code when creating the pipeline state.
        ///
        /// Accelerate pipeline state creation by providing archives of compiled code such that no compilation needs to happen on the fast path.
        ///
        /// See: MTLBinaryArchive
        #[unsafe(method(binaryArchives))]
        #[unsafe(method_family = none)]
        pub fn binaryArchives(
            &self,
        ) -> Option<Retained<NSArray<ProtocolObject<dyn MTLBinaryArchive>>>>;

        #[cfg(feature = "MTLBinaryArchive")]
        /// Setter for [`binaryArchives`][Self::binaryArchives].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setBinaryArchives:))]
        #[unsafe(method_family = none)]
        pub fn setBinaryArchives(
            &self,
            binary_archives: Option<&NSArray<ProtocolObject<dyn MTLBinaryArchive>>>,
        );

        #[cfg(feature = "MTLDynamicLibrary")]
        /// The set of MTLDynamicLibrary to use to resolve external symbols for the vertexFunction before considering symbols from dependent MTLDynamicLibrary.
        ///
        /// Typical workflows use the libraries property of MTLCompileOptions to record dependent libraries at compile time without having to use vertexPreloadedLibraries.
        /// This property can be used to override symbols from dependent libraries for experimentation or evaluating alternative implementations.
        /// It can also be used to provide dynamic libraries that are dynamically created (for example, from source) that have no stable installName that can be used to automatically load from the file system.
        ///
        /// See: MTLDynamicLibrary
        #[unsafe(method(vertexPreloadedLibraries))]
        #[unsafe(method_family = none)]
        pub fn vertexPreloadedLibraries(
            &self,
        ) -> Retained<NSArray<ProtocolObject<dyn MTLDynamicLibrary>>>;

        #[cfg(feature = "MTLDynamicLibrary")]
        /// Setter for [`vertexPreloadedLibraries`][Self::vertexPreloadedLibraries].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setVertexPreloadedLibraries:))]
        #[unsafe(method_family = none)]
        pub fn setVertexPreloadedLibraries(
            &self,
            vertex_preloaded_libraries: &NSArray<ProtocolObject<dyn MTLDynamicLibrary>>,
        );

        #[cfg(feature = "MTLDynamicLibrary")]
        /// The set of MTLDynamicLibrary to use to resolve external symbols for the fragmentFunction before considering symbols from dependent MTLDynamicLibrary.
        ///
        /// Typical workflows use the libraries property of MTLCompileOptions to record dependent libraries at compile time without having to use fragmentPreloadedLibraries.
        /// This property can be used to override symbols from dependent libraries for experimentation or evaluating alternative implementations.
        /// It can also be used to provide dynamic libraries that are dynamically created (for example, from source) that have no stable installName that can be used to automatically load from the file system.
        ///
        /// See: MTLDynamicLibrary
        #[unsafe(method(fragmentPreloadedLibraries))]
        #[unsafe(method_family = none)]
        pub fn fragmentPreloadedLibraries(
            &self,
        ) -> Retained<NSArray<ProtocolObject<dyn MTLDynamicLibrary>>>;

        #[cfg(feature = "MTLDynamicLibrary")]
        /// Setter for [`fragmentPreloadedLibraries`][Self::fragmentPreloadedLibraries].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setFragmentPreloadedLibraries:))]
        #[unsafe(method_family = none)]
        pub fn setFragmentPreloadedLibraries(
            &self,
            fragment_preloaded_libraries: &NSArray<ProtocolObject<dyn MTLDynamicLibrary>>,
        );

        #[cfg(feature = "MTLLinkedFunctions")]
        /// The set of functions to be linked with the pipeline state and accessed from the vertex function.
        ///
        /// See: MTLLinkedFunctions
        #[unsafe(method(vertexLinkedFunctions))]
        #[unsafe(method_family = none)]
        pub fn vertexLinkedFunctions(&self) -> Retained<MTLLinkedFunctions>;

        #[cfg(feature = "MTLLinkedFunctions")]
        /// Setter for [`vertexLinkedFunctions`][Self::vertexLinkedFunctions].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setVertexLinkedFunctions:))]
        #[unsafe(method_family = none)]
        pub fn setVertexLinkedFunctions(
            &self,
            vertex_linked_functions: Option<&MTLLinkedFunctions>,
        );

        #[cfg(feature = "MTLLinkedFunctions")]
        /// The set of functions to be linked with the pipeline state and accessed from the fragment function.
        ///
        /// See: MTLLinkedFunctions
        #[unsafe(method(fragmentLinkedFunctions))]
        #[unsafe(method_family = none)]
        pub fn fragmentLinkedFunctions(&self) -> Retained<MTLLinkedFunctions>;

        #[cfg(feature = "MTLLinkedFunctions")]
        /// Setter for [`fragmentLinkedFunctions`][Self::fragmentLinkedFunctions].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setFragmentLinkedFunctions:))]
        #[unsafe(method_family = none)]
        pub fn setFragmentLinkedFunctions(
            &self,
            fragment_linked_functions: Option<&MTLLinkedFunctions>,
        );

        /// This flag makes this pipeline support creating a new pipeline by adding binary functions.
        #[unsafe(method(supportAddingVertexBinaryFunctions))]
        #[unsafe(method_family = none)]
        pub fn supportAddingVertexBinaryFunctions(&self) -> bool;

        /// Setter for [`supportAddingVertexBinaryFunctions`][Self::supportAddingVertexBinaryFunctions].
        #[unsafe(method(setSupportAddingVertexBinaryFunctions:))]
        #[unsafe(method_family = none)]
        pub fn setSupportAddingVertexBinaryFunctions(
            &self,
            support_adding_vertex_binary_functions: bool,
        );

        /// This flag makes this pipeline support creating a new pipeline by adding binary functions.
        #[unsafe(method(supportAddingFragmentBinaryFunctions))]
        #[unsafe(method_family = none)]
        pub fn supportAddingFragmentBinaryFunctions(&self) -> bool;

        /// Setter for [`supportAddingFragmentBinaryFunctions`][Self::supportAddingFragmentBinaryFunctions].
        #[unsafe(method(setSupportAddingFragmentBinaryFunctions:))]
        #[unsafe(method_family = none)]
        pub fn setSupportAddingFragmentBinaryFunctions(
            &self,
            support_adding_fragment_binary_functions: bool,
        );

        /// The maximum depth of the call stack in stack frames from the shader. Defaults to 1 additional stack frame.
        #[unsafe(method(maxVertexCallStackDepth))]
        #[unsafe(method_family = none)]
        pub fn maxVertexCallStackDepth(&self) -> NSUInteger;

        /// Setter for [`maxVertexCallStackDepth`][Self::maxVertexCallStackDepth].
        #[unsafe(method(setMaxVertexCallStackDepth:))]
        #[unsafe(method_family = none)]
        pub fn setMaxVertexCallStackDepth(&self, max_vertex_call_stack_depth: NSUInteger);

        /// The maximum depth of the call stack in stack frames from the shader. Defaults to 1 additional stack frame.
        #[unsafe(method(maxFragmentCallStackDepth))]
        #[unsafe(method_family = none)]
        pub fn maxFragmentCallStackDepth(&self) -> NSUInteger;

        /// Setter for [`maxFragmentCallStackDepth`][Self::maxFragmentCallStackDepth].
        #[unsafe(method(setMaxFragmentCallStackDepth:))]
        #[unsafe(method_family = none)]
        pub fn setMaxFragmentCallStackDepth(&self, max_fragment_call_stack_depth: NSUInteger);

        /// Restore all pipeline descriptor properties to their default values.
        #[unsafe(method(reset))]
        #[unsafe(method_family = none)]
        pub fn reset(&self);

        #[cfg(feature = "MTLPipeline")]
        /// Toggle that determines whether Metal Shader Validation should be enabled or disabled for the pipeline.
        ///
        /// The value can be overridden using `MTL_SHADER_VALIDATION_ENABLE_PIPELINES` or `MTL_SHADER_VALIDATION_DISABLE_PIPELINES` Environment Variables.
        #[unsafe(method(shaderValidation))]
        #[unsafe(method_family = none)]
        pub fn shaderValidation(&self) -> MTLShaderValidation;

        #[cfg(feature = "MTLPipeline")]
        /// Setter for [`shaderValidation`][Self::shaderValidation].
        #[unsafe(method(setShaderValidation:))]
        #[unsafe(method_family = none)]
        pub fn setShaderValidation(&self, shader_validation: MTLShaderValidation);
    );
}

/// Methods declared on superclass `NSObject`.
impl MTLRenderPipelineDescriptor {
    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 DefaultRetained for MTLRenderPipelineDescriptor {
    #[inline]
    fn default_retained() -> Retained<Self> {
        Self::new()
    }
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/metal/mtlrenderpipelinefunctionsdescriptor?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct MTLRenderPipelineFunctionsDescriptor;
);

extern_conformance!(
    unsafe impl NSCopying for MTLRenderPipelineFunctionsDescriptor {}
);

unsafe impl CopyingHelper for MTLRenderPipelineFunctionsDescriptor {
    type Result = Self;
}

extern_conformance!(
    unsafe impl NSObjectProtocol for MTLRenderPipelineFunctionsDescriptor {}
);

impl MTLRenderPipelineFunctionsDescriptor {
    extern_methods!(
        #[cfg(feature = "MTLLibrary")]
        /// The set of additional binary functions to be accessed from the vertex function in an incrementally created pipeline state.
        #[unsafe(method(vertexAdditionalBinaryFunctions))]
        #[unsafe(method_family = none)]
        pub fn vertexAdditionalBinaryFunctions(
            &self,
        ) -> Option<Retained<NSArray<ProtocolObject<dyn MTLFunction>>>>;

        #[cfg(feature = "MTLLibrary")]
        /// Setter for [`vertexAdditionalBinaryFunctions`][Self::vertexAdditionalBinaryFunctions].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        ///
        /// # Safety
        ///
        /// - `vertex_additional_binary_functions` generic must be safe to call.
        /// - `vertex_additional_binary_functions` generic must have the correct argument and return types.
        #[unsafe(method(setVertexAdditionalBinaryFunctions:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setVertexAdditionalBinaryFunctions(
            &self,
            vertex_additional_binary_functions: Option<&NSArray<ProtocolObject<dyn MTLFunction>>>,
        );

        #[cfg(feature = "MTLLibrary")]
        /// The set of additional binary functions to be accessed from the fragment function in an incrementally created pipeline state.
        #[unsafe(method(fragmentAdditionalBinaryFunctions))]
        #[unsafe(method_family = none)]
        pub fn fragmentAdditionalBinaryFunctions(
            &self,
        ) -> Option<Retained<NSArray<ProtocolObject<dyn MTLFunction>>>>;

        #[cfg(feature = "MTLLibrary")]
        /// Setter for [`fragmentAdditionalBinaryFunctions`][Self::fragmentAdditionalBinaryFunctions].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        ///
        /// # Safety
        ///
        /// - `fragment_additional_binary_functions` generic must be safe to call.
        /// - `fragment_additional_binary_functions` generic must have the correct argument and return types.
        #[unsafe(method(setFragmentAdditionalBinaryFunctions:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setFragmentAdditionalBinaryFunctions(
            &self,
            fragment_additional_binary_functions: Option<&NSArray<ProtocolObject<dyn MTLFunction>>>,
        );

        #[cfg(feature = "MTLLibrary")]
        /// The set of additional binary functions to be accessed from the tile function in an incrementally created pipeline state.
        #[unsafe(method(tileAdditionalBinaryFunctions))]
        #[unsafe(method_family = none)]
        pub fn tileAdditionalBinaryFunctions(
            &self,
        ) -> Option<Retained<NSArray<ProtocolObject<dyn MTLFunction>>>>;

        #[cfg(feature = "MTLLibrary")]
        /// Setter for [`tileAdditionalBinaryFunctions`][Self::tileAdditionalBinaryFunctions].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        ///
        /// # Safety
        ///
        /// - `tile_additional_binary_functions` generic must be safe to call.
        /// - `tile_additional_binary_functions` generic must have the correct argument and return types.
        #[unsafe(method(setTileAdditionalBinaryFunctions:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setTileAdditionalBinaryFunctions(
            &self,
            tile_additional_binary_functions: Option<&NSArray<ProtocolObject<dyn MTLFunction>>>,
        );
    );
}

/// Methods declared on superclass `NSObject`.
impl MTLRenderPipelineFunctionsDescriptor {
    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 DefaultRetained for MTLRenderPipelineFunctionsDescriptor {
    #[inline]
    fn default_retained() -> Retained<Self> {
        Self::new()
    }
}

extern_protocol!(
    /// MTLRenderPipelineState represents a compiled render pipeline
    ///
    ///
    /// MTLRenderPipelineState is a compiled render pipeline and can be set on a MTLRenderCommandEncoder.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtlrenderpipelinestate?language=objc)
    #[cfg(feature = "MTLAllocation")]
    pub unsafe trait MTLRenderPipelineState:
        MTLAllocation + NSObjectProtocol + Send + Sync
    {
        #[unsafe(method(label))]
        #[unsafe(method_family = none)]
        fn label(&self) -> Option<Retained<NSString>>;

        #[cfg(feature = "MTLDevice")]
        #[unsafe(method(device))]
        #[unsafe(method_family = none)]
        fn device(&self) -> Retained<ProtocolObject<dyn MTLDevice>>;

        /// Obtains a reflection object for this render pipeline.
        ///
        /// When you create the pipeline through an ``MTLDevice`` instance, reflection is `nil`.
        #[unsafe(method(reflection))]
        #[unsafe(method_family = none)]
        fn reflection(&self) -> Option<Retained<MTLRenderPipelineReflection>>;

        #[cfg(all(feature = "MTLFunctionHandle", feature = "MTLRenderCommandEncoder"))]
        /// Obtains a function handle for the a specific function this pipeline links at the Metal IR level.
        ///
        /// - Parameters:
        /// - name: A string containing the name of the function.
        /// - stage: The shader stage that uses the function.
        ///
        /// - Returns: a function handle representing the function if present, otherwise `nil`.
        #[unsafe(method(functionHandleWithName:stage:))]
        #[unsafe(method_family = none)]
        fn functionHandleWithName_stage(
            &self,
            name: &NSString,
            stage: MTLRenderStages,
        ) -> Option<Retained<ProtocolObject<dyn MTLFunctionHandle>>>;

        #[cfg(all(
            feature = "MTL4BinaryFunction",
            feature = "MTLFunctionHandle",
            feature = "MTLRenderCommandEncoder"
        ))]
        /// Obtains the function handle for a specific function this pipeline state links at the binary level.
        ///
        /// - Parameters:
        /// - function: a binary function to retrieve the handle.
        /// - stage: The shader stage that uses the function.
        ///
        /// - Returns: a function handle representing the function if present, otherwise `nil`.
        #[unsafe(method(functionHandleWithBinaryFunction:stage:))]
        #[unsafe(method_family = none)]
        fn functionHandleWithBinaryFunction_stage(
            &self,
            function: &ProtocolObject<dyn MTL4BinaryFunction>,
            stage: MTLRenderStages,
        ) -> Option<Retained<ProtocolObject<dyn MTLFunctionHandle>>>;

        #[cfg(feature = "MTL4RenderPipeline")]
        /// Creates a new render pipeline state by adding binary functions to each stage of this pipeline
        /// state.
        ///
        /// - Parameters:
        /// - binaryFunctionsDescriptor: A non-`nil` dynamic linking descriptor.
        /// - error: An optional pointer that Metal populates with information in case of an error.
        ///
        /// - Returns: A new render pipeline state upon success, otherwise `nil`.
        #[unsafe(method(newRenderPipelineStateWithBinaryFunctions:error:_))]
        #[unsafe(method_family = new)]
        fn newRenderPipelineStateWithBinaryFunctions_error(
            &self,
            binary_functions_descriptor: &MTL4RenderPipelineBinaryFunctionsDescriptor,
        ) -> Result<Retained<ProtocolObject<dyn MTLRenderPipelineState>>, Retained<NSError>>;

        #[cfg(feature = "MTL4PipelineState")]
        /// Creates a render pipeline descriptor from this pipeline that you can use for pipeline specialization.
        ///
        /// Use this method to obtain a new ``MTL4PipelineDescriptor`` instance that you can use to specialize any unspecialized
        /// properties in this pipeline state object.
        ///
        /// The returned descriptor contains every unspecialized field in the current pipeline state object, set to unspecialized.
        /// It may, however, not contain valid or accurate properties in any other field.
        ///
        /// This descriptor is only valid for the purpose of calling specialization functions on the ``MTL4Compiler`` to
        /// specialize this pipeline, for example: ``MTL4Compiler/newRenderPipelineStateBySpecializationWithDescriptor:pipeline:error:``.
        ///
        /// Although this method returns the ``MTL4PipelineDescriptor`` base class, the concrete instance this method returns
        /// corresponds to the specific descriptor type for the creation of this pipeline state, for example if a ``MTL4Compiler``
        /// instance creates this current pipeline form a ``MTLTileRenderPipelineDescriptor``, this method returns a concrete
        /// ``MTLTileRenderPipelineDescriptor`` instance.
        ///
        /// - Returns: a new pipeline descriptor that you use for pipeline state specialization.
        #[unsafe(method(newRenderPipelineDescriptorForSpecialization))]
        #[unsafe(method_family = new)]
        fn newRenderPipelineDescriptorForSpecialization(&self) -> Retained<MTL4PipelineDescriptor>;

        /// The maximum total number of threads that can be in a single tile shader threadgroup.
        #[unsafe(method(maxTotalThreadsPerThreadgroup))]
        #[unsafe(method_family = none)]
        fn maxTotalThreadsPerThreadgroup(&self) -> NSUInteger;

        /// Returns true when the pipeline state requires a tile shader threadgroup size equal to the tile size
        #[unsafe(method(threadgroupSizeMatchesTileSize))]
        #[unsafe(method_family = none)]
        fn threadgroupSizeMatchesTileSize(&self) -> bool;

        /// Returns imageblock memory length used by a single sample when rendered using this pipeline.
        #[unsafe(method(imageblockSampleLength))]
        #[unsafe(method_family = none)]
        fn imageblockSampleLength(&self) -> NSUInteger;

        #[cfg(feature = "MTLTypes")]
        /// Returns imageblock memory length for given image block dimensions. Dimensions must be valid tile dimensions.
        #[unsafe(method(imageblockMemoryLengthForDimensions:))]
        #[unsafe(method_family = none)]
        fn imageblockMemoryLengthForDimensions(&self, imageblock_dimensions: MTLSize)
            -> NSUInteger;

        #[unsafe(method(supportIndirectCommandBuffers))]
        #[unsafe(method_family = none)]
        fn supportIndirectCommandBuffers(&self) -> bool;

        /// The maximum total number of threads that can be in a single object shader threadgroup.
        ///
        /// This value is set in MTLMeshRenderPipelineDescriptor.
        #[unsafe(method(maxTotalThreadsPerObjectThreadgroup))]
        #[unsafe(method_family = none)]
        fn maxTotalThreadsPerObjectThreadgroup(&self) -> NSUInteger;

        /// The maximum total number of threads that can be in a single mesh shader threadgroup.
        ///
        /// This value is set in MTLMeshRenderPipelineDescriptor.
        #[unsafe(method(maxTotalThreadsPerMeshThreadgroup))]
        #[unsafe(method_family = none)]
        fn maxTotalThreadsPerMeshThreadgroup(&self) -> NSUInteger;

        /// The number of threads in a SIMD group of the object shader.
        ///
        /// This value is also available in the shader with the [[threads_per_simdgroup]] attribute.
        #[unsafe(method(objectThreadExecutionWidth))]
        #[unsafe(method_family = none)]
        fn objectThreadExecutionWidth(&self) -> NSUInteger;

        /// The number of threads in a SIMD group of the mesh shader.
        ///
        /// This value is also available in the shader with the [[threads_per_simdgroup]] attribute.
        #[unsafe(method(meshThreadExecutionWidth))]
        #[unsafe(method_family = none)]
        fn meshThreadExecutionWidth(&self) -> NSUInteger;

        /// The maximum total number of threadgroups that can be in a single mesh shader grid.
        ///
        /// This value is set in MTLMeshRenderPipelineDescriptor.
        #[unsafe(method(maxTotalThreadgroupsPerMeshGrid))]
        #[unsafe(method_family = none)]
        fn maxTotalThreadgroupsPerMeshGrid(&self) -> NSUInteger;

        #[cfg(feature = "MTLTypes")]
        /// Handle of the GPU resource suitable for storing in an Argument Buffer
        #[unsafe(method(gpuResourceID))]
        #[unsafe(method_family = none)]
        fn gpuResourceID(&self) -> MTLResourceID;

        #[cfg(all(
            feature = "MTLFunctionHandle",
            feature = "MTLLibrary",
            feature = "MTLRenderCommandEncoder"
        ))]
        /// Gets the function handle for the specified function on the specified stage of the pipeline.
        ///
        /// # Safety
        ///
        /// - `function` must be safe to call.
        /// - `function` must have the correct argument and return types.
        #[unsafe(method(functionHandleWithFunction:stage:))]
        #[unsafe(method_family = none)]
        unsafe fn functionHandleWithFunction_stage(
            &self,
            function: &ProtocolObject<dyn MTLFunction>,
            stage: MTLRenderStages,
        ) -> Option<Retained<ProtocolObject<dyn MTLFunctionHandle>>>;

        #[cfg(all(
            feature = "MTLRenderCommandEncoder",
            feature = "MTLResource",
            feature = "MTLVisibleFunctionTable"
        ))]
        /// Allocate a visible function table for the specified stage of the pipeline with the provided descriptor.
        #[unsafe(method(newVisibleFunctionTableWithDescriptor:stage:))]
        #[unsafe(method_family = new)]
        fn newVisibleFunctionTableWithDescriptor_stage(
            &self,
            descriptor: &MTLVisibleFunctionTableDescriptor,
            stage: MTLRenderStages,
        ) -> Option<Retained<ProtocolObject<dyn MTLVisibleFunctionTable>>>;

        #[cfg(all(
            feature = "MTLIntersectionFunctionTable",
            feature = "MTLRenderCommandEncoder",
            feature = "MTLResource"
        ))]
        /// Allocate an intersection function table for the specified stage of the pipeline with the provided descriptor.
        #[unsafe(method(newIntersectionFunctionTableWithDescriptor:stage:))]
        #[unsafe(method_family = new)]
        fn newIntersectionFunctionTableWithDescriptor_stage(
            &self,
            descriptor: &MTLIntersectionFunctionTableDescriptor,
            stage: MTLRenderStages,
        ) -> Option<Retained<ProtocolObject<dyn MTLIntersectionFunctionTable>>>;

        /// Allocate a new render pipeline state by adding binary functions for each stage of this pipeline state.
        #[unsafe(method(newRenderPipelineStateWithAdditionalBinaryFunctions:error:_))]
        #[unsafe(method_family = new)]
        fn newRenderPipelineStateWithAdditionalBinaryFunctions_error(
            &self,
            additional_binary_functions: &MTLRenderPipelineFunctionsDescriptor,
        ) -> Result<Retained<ProtocolObject<dyn MTLRenderPipelineState>>, Retained<NSError>>;

        #[cfg(feature = "MTLPipeline")]
        /// Current state of Shader Validation for the pipeline.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(shaderValidation))]
        #[unsafe(method_family = none)]
        unsafe fn shaderValidation(&self) -> MTLShaderValidation;

        #[cfg(feature = "MTLTypes")]
        /// The required size of every tile shader threadgroup.
        #[unsafe(method(requiredThreadsPerTileThreadgroup))]
        #[unsafe(method_family = none)]
        fn requiredThreadsPerTileThreadgroup(&self) -> MTLSize;

        #[cfg(feature = "MTLTypes")]
        /// The required size of every object shader threadgroup.
        ///
        /// This value is set in MTLMeshRenderPipelineDescriptor.
        #[unsafe(method(requiredThreadsPerObjectThreadgroup))]
        #[unsafe(method_family = none)]
        fn requiredThreadsPerObjectThreadgroup(&self) -> MTLSize;

        #[cfg(feature = "MTLTypes")]
        /// The required size of every mesh shader threadgroup.
        ///
        /// This value is set in MTLMeshRenderPipelineDescriptor.
        #[unsafe(method(requiredThreadsPerMeshThreadgroup))]
        #[unsafe(method_family = none)]
        fn requiredThreadsPerMeshThreadgroup(&self) -> MTLSize;
    }
);

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/metal/mtlrenderpipelinecolorattachmentdescriptorarray?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct MTLRenderPipelineColorAttachmentDescriptorArray;
);

extern_conformance!(
    unsafe impl NSObjectProtocol for MTLRenderPipelineColorAttachmentDescriptorArray {}
);

impl MTLRenderPipelineColorAttachmentDescriptorArray {
    extern_methods!(
        /// # Safety
        ///
        /// `attachmentIndex` might not be bounds-checked.
        #[unsafe(method(objectAtIndexedSubscript:))]
        #[unsafe(method_family = none)]
        pub unsafe fn objectAtIndexedSubscript(
            &self,
            attachment_index: NSUInteger,
        ) -> Retained<MTLRenderPipelineColorAttachmentDescriptor>;

        /// # Safety
        ///
        /// `attachmentIndex` might not be bounds-checked.
        #[unsafe(method(setObject:atIndexedSubscript:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setObject_atIndexedSubscript(
            &self,
            attachment: Option<&MTLRenderPipelineColorAttachmentDescriptor>,
            attachment_index: NSUInteger,
        );
    );
}

/// Methods declared on superclass `NSObject`.
impl MTLRenderPipelineColorAttachmentDescriptorArray {
    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 DefaultRetained for MTLRenderPipelineColorAttachmentDescriptorArray {
    #[inline]
    fn default_retained() -> Retained<Self> {
        Self::new()
    }
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/metal/mtltilerenderpipelinecolorattachmentdescriptor?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct MTLTileRenderPipelineColorAttachmentDescriptor;
);

extern_conformance!(
    unsafe impl NSCopying for MTLTileRenderPipelineColorAttachmentDescriptor {}
);

unsafe impl CopyingHelper for MTLTileRenderPipelineColorAttachmentDescriptor {
    type Result = Self;
}

extern_conformance!(
    unsafe impl NSObjectProtocol for MTLTileRenderPipelineColorAttachmentDescriptor {}
);

impl MTLTileRenderPipelineColorAttachmentDescriptor {
    extern_methods!(
        #[cfg(feature = "MTLPixelFormat")]
        /// Pixel format.  Defaults to MTLPixelFormatInvalid
        #[unsafe(method(pixelFormat))]
        #[unsafe(method_family = none)]
        pub fn pixelFormat(&self) -> MTLPixelFormat;

        #[cfg(feature = "MTLPixelFormat")]
        /// Setter for [`pixelFormat`][Self::pixelFormat].
        #[unsafe(method(setPixelFormat:))]
        #[unsafe(method_family = none)]
        pub fn setPixelFormat(&self, pixel_format: MTLPixelFormat);
    );
}

/// Methods declared on superclass `NSObject`.
impl MTLTileRenderPipelineColorAttachmentDescriptor {
    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 DefaultRetained for MTLTileRenderPipelineColorAttachmentDescriptor {
    #[inline]
    fn default_retained() -> Retained<Self> {
        Self::new()
    }
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/metal/mtltilerenderpipelinecolorattachmentdescriptorarray?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct MTLTileRenderPipelineColorAttachmentDescriptorArray;
);

extern_conformance!(
    unsafe impl NSObjectProtocol for MTLTileRenderPipelineColorAttachmentDescriptorArray {}
);

impl MTLTileRenderPipelineColorAttachmentDescriptorArray {
    extern_methods!(
        /// # Safety
        ///
        /// `attachmentIndex` might not be bounds-checked.
        #[unsafe(method(objectAtIndexedSubscript:))]
        #[unsafe(method_family = none)]
        pub unsafe fn objectAtIndexedSubscript(
            &self,
            attachment_index: NSUInteger,
        ) -> Retained<MTLTileRenderPipelineColorAttachmentDescriptor>;

        /// # Safety
        ///
        /// `attachmentIndex` might not be bounds-checked.
        #[unsafe(method(setObject:atIndexedSubscript:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setObject_atIndexedSubscript(
            &self,
            attachment: &MTLTileRenderPipelineColorAttachmentDescriptor,
            attachment_index: NSUInteger,
        );
    );
}

/// Methods declared on superclass `NSObject`.
impl MTLTileRenderPipelineColorAttachmentDescriptorArray {
    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 DefaultRetained for MTLTileRenderPipelineColorAttachmentDescriptorArray {
    #[inline]
    fn default_retained() -> Retained<Self> {
        Self::new()
    }
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/metal/mtltilerenderpipelinedescriptor?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct MTLTileRenderPipelineDescriptor;
);

extern_conformance!(
    unsafe impl NSCopying for MTLTileRenderPipelineDescriptor {}
);

unsafe impl CopyingHelper for MTLTileRenderPipelineDescriptor {
    type Result = Self;
}

extern_conformance!(
    unsafe impl NSObjectProtocol for MTLTileRenderPipelineDescriptor {}
);

impl MTLTileRenderPipelineDescriptor {
    extern_methods!(
        /// The descriptor label.
        #[unsafe(method(label))]
        #[unsafe(method_family = none)]
        pub fn label(&self) -> Option<Retained<NSString>>;

        /// Setter for [`label`][Self::label].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setLabel:))]
        #[unsafe(method_family = none)]
        pub fn setLabel(&self, label: Option<&NSString>);

        #[cfg(feature = "MTLLibrary")]
        /// The kernel or fragment function that serves as the tile shader for this pipeline.
        ///
        /// Both kernel-based and fragment-based tile pipelines dispatches will barrier against previous
        /// draws and other dispatches. Kernel-based pipelines will wait until all prior access to the tile completes.
        /// Fragment-based pipelines will only wait until all prior access to the fragment's location completes.
        #[unsafe(method(tileFunction))]
        #[unsafe(method_family = none)]
        pub fn tileFunction(&self) -> Retained<ProtocolObject<dyn MTLFunction>>;

        #[cfg(feature = "MTLLibrary")]
        /// Setter for [`tileFunction`][Self::tileFunction].
        ///
        /// # Safety
        ///
        /// - `tile_function` must be safe to call.
        /// - `tile_function` must have the correct argument and return types.
        #[unsafe(method(setTileFunction:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setTileFunction(&self, tile_function: &ProtocolObject<dyn MTLFunction>);

        #[unsafe(method(rasterSampleCount))]
        #[unsafe(method_family = none)]
        pub fn rasterSampleCount(&self) -> NSUInteger;

        /// Setter for [`rasterSampleCount`][Self::rasterSampleCount].
        ///
        /// # Safety
        ///
        /// This might not be bounds-checked.
        #[unsafe(method(setRasterSampleCount:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setRasterSampleCount(&self, raster_sample_count: NSUInteger);

        #[unsafe(method(colorAttachments))]
        #[unsafe(method_family = none)]
        pub fn colorAttachments(
            &self,
        ) -> Retained<MTLTileRenderPipelineColorAttachmentDescriptorArray>;

        /// Whether all threadgroups associated with this pipeline will cover tiles entirely.
        ///
        /// Metal can optimize code generation for this case.
        #[unsafe(method(threadgroupSizeMatchesTileSize))]
        #[unsafe(method_family = none)]
        pub fn threadgroupSizeMatchesTileSize(&self) -> bool;

        /// Setter for [`threadgroupSizeMatchesTileSize`][Self::threadgroupSizeMatchesTileSize].
        #[unsafe(method(setThreadgroupSizeMatchesTileSize:))]
        #[unsafe(method_family = none)]
        pub fn setThreadgroupSizeMatchesTileSize(&self, threadgroup_size_matches_tile_size: bool);

        #[cfg(feature = "MTLPipeline")]
        #[unsafe(method(tileBuffers))]
        #[unsafe(method_family = none)]
        pub fn tileBuffers(&self) -> Retained<MTLPipelineBufferDescriptorArray>;

        /// Optional property. Set the maxTotalThreadsPerThreadgroup. If it is not set, returns zero.
        #[unsafe(method(maxTotalThreadsPerThreadgroup))]
        #[unsafe(method_family = none)]
        pub fn maxTotalThreadsPerThreadgroup(&self) -> NSUInteger;

        /// Setter for [`maxTotalThreadsPerThreadgroup`][Self::maxTotalThreadsPerThreadgroup].
        #[unsafe(method(setMaxTotalThreadsPerThreadgroup:))]
        #[unsafe(method_family = none)]
        pub fn setMaxTotalThreadsPerThreadgroup(
            &self,
            max_total_threads_per_threadgroup: NSUInteger,
        );

        #[cfg(feature = "MTLBinaryArchive")]
        /// The set of MTLBinaryArchive to search for compiled code when creating the pipeline state.
        ///
        /// Accelerate pipeline state creation by providing archives of compiled code such that no compilation needs to happen on the fast path.
        ///
        /// See: MTLBinaryArchive
        #[unsafe(method(binaryArchives))]
        #[unsafe(method_family = none)]
        pub fn binaryArchives(
            &self,
        ) -> Option<Retained<NSArray<ProtocolObject<dyn MTLBinaryArchive>>>>;

        #[cfg(feature = "MTLBinaryArchive")]
        /// Setter for [`binaryArchives`][Self::binaryArchives].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setBinaryArchives:))]
        #[unsafe(method_family = none)]
        pub fn setBinaryArchives(
            &self,
            binary_archives: Option<&NSArray<ProtocolObject<dyn MTLBinaryArchive>>>,
        );

        #[cfg(feature = "MTLDynamicLibrary")]
        /// The set of MTLDynamicLibrary to use to resolve external symbols before considering symbols from dependent MTLDynamicLibrary.
        ///
        /// Typical workflows use the libraries property of MTLCompileOptions to record dependent libraries at compile time without having to use preloadedLibraries.
        /// This property can be used to override symbols from dependent libraries for experimentation or evaluating alternative implementations.
        /// It can also be used to provide dynamic libraries that are dynamically created (for example, from source) that have no stable installName that can be used to automatically load from the file system.
        ///
        /// See: MTLDynamicLibrary
        #[unsafe(method(preloadedLibraries))]
        #[unsafe(method_family = none)]
        pub fn preloadedLibraries(
            &self,
        ) -> Retained<NSArray<ProtocolObject<dyn MTLDynamicLibrary>>>;

        #[cfg(feature = "MTLDynamicLibrary")]
        /// Setter for [`preloadedLibraries`][Self::preloadedLibraries].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setPreloadedLibraries:))]
        #[unsafe(method_family = none)]
        pub fn setPreloadedLibraries(
            &self,
            preloaded_libraries: &NSArray<ProtocolObject<dyn MTLDynamicLibrary>>,
        );

        #[cfg(feature = "MTLLinkedFunctions")]
        /// The set of functions to be linked with the pipeline state and accessed from the tile function.
        ///
        /// See: MTLLinkedFunctions
        #[unsafe(method(linkedFunctions))]
        #[unsafe(method_family = none)]
        pub fn linkedFunctions(&self) -> Retained<MTLLinkedFunctions>;

        #[cfg(feature = "MTLLinkedFunctions")]
        /// Setter for [`linkedFunctions`][Self::linkedFunctions].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setLinkedFunctions:))]
        #[unsafe(method_family = none)]
        pub fn setLinkedFunctions(&self, linked_functions: Option<&MTLLinkedFunctions>);

        /// This flag makes this pipeline support creating a new pipeline by adding binary functions.
        #[unsafe(method(supportAddingBinaryFunctions))]
        #[unsafe(method_family = none)]
        pub fn supportAddingBinaryFunctions(&self) -> bool;

        /// Setter for [`supportAddingBinaryFunctions`][Self::supportAddingBinaryFunctions].
        #[unsafe(method(setSupportAddingBinaryFunctions:))]
        #[unsafe(method_family = none)]
        pub fn setSupportAddingBinaryFunctions(&self, support_adding_binary_functions: bool);

        /// The maximum depth of the call stack in stack frames from the tile function. Defaults to 1 additional stack frame.
        #[unsafe(method(maxCallStackDepth))]
        #[unsafe(method_family = none)]
        pub fn maxCallStackDepth(&self) -> NSUInteger;

        /// Setter for [`maxCallStackDepth`][Self::maxCallStackDepth].
        #[unsafe(method(setMaxCallStackDepth:))]
        #[unsafe(method_family = none)]
        pub fn setMaxCallStackDepth(&self, max_call_stack_depth: NSUInteger);

        #[unsafe(method(reset))]
        #[unsafe(method_family = none)]
        pub fn reset(&self);

        #[cfg(feature = "MTLPipeline")]
        /// Toggle that determines whether Metal Shader Validation should be enabled or disabled for the pipeline.
        ///
        /// The value can be overridden using `MTL_SHADER_VALIDATION_ENABLE_PIPELINES` or `MTL_SHADER_VALIDATION_DISABLE_PIPELINES` Environment Variables.
        #[unsafe(method(shaderValidation))]
        #[unsafe(method_family = none)]
        pub fn shaderValidation(&self) -> MTLShaderValidation;

        #[cfg(feature = "MTLPipeline")]
        /// Setter for [`shaderValidation`][Self::shaderValidation].
        #[unsafe(method(setShaderValidation:))]
        #[unsafe(method_family = none)]
        pub fn setShaderValidation(&self, shader_validation: MTLShaderValidation);

        #[cfg(feature = "MTLTypes")]
        /// Sets the required threads-per-threadgroup during tile dispatches. The `threadsPerTile` argument of any tile dispatch must match to this value if it is set.
        /// Optional, unless the pipeline is going to use CooperativeTensors in which case this must be set.
        /// Setting this to a size of 0 in every dimension disables this property
        #[unsafe(method(requiredThreadsPerThreadgroup))]
        #[unsafe(method_family = none)]
        pub fn requiredThreadsPerThreadgroup(&self) -> MTLSize;

        #[cfg(feature = "MTLTypes")]
        /// Setter for [`requiredThreadsPerThreadgroup`][Self::requiredThreadsPerThreadgroup].
        #[unsafe(method(setRequiredThreadsPerThreadgroup:))]
        #[unsafe(method_family = none)]
        pub fn setRequiredThreadsPerThreadgroup(&self, required_threads_per_threadgroup: MTLSize);
    );
}

/// Methods declared on superclass `NSObject`.
impl MTLTileRenderPipelineDescriptor {
    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 DefaultRetained for MTLTileRenderPipelineDescriptor {
    #[inline]
    fn default_retained() -> Retained<Self> {
        Self::new()
    }
}

extern_class!(
    /// As an alternative to a vertex + fragment shader render pipeline, this render pipeline uses a (object +) mesh + fragment shader for rendering geometry.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtlmeshrenderpipelinedescriptor?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct MTLMeshRenderPipelineDescriptor;
);

extern_conformance!(
    unsafe impl NSCopying for MTLMeshRenderPipelineDescriptor {}
);

unsafe impl CopyingHelper for MTLMeshRenderPipelineDescriptor {
    type Result = Self;
}

extern_conformance!(
    unsafe impl NSObjectProtocol for MTLMeshRenderPipelineDescriptor {}
);

impl MTLMeshRenderPipelineDescriptor {
    extern_methods!(
        /// A name or description provided by the application that will be displayed in debugging tools.
        /// The default value is nil.
        #[unsafe(method(label))]
        #[unsafe(method_family = none)]
        pub fn label(&self) -> Option<Retained<NSString>>;

        /// Setter for [`label`][Self::label].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setLabel:))]
        #[unsafe(method_family = none)]
        pub fn setLabel(&self, label: Option<&NSString>);

        #[cfg(feature = "MTLLibrary")]
        /// Optional shader function responsible for determining how many threadgroups of the mesh shader to run, can optionally provide payload data for the mesh stage.
        /// If this is nil, no payload data is available to the mesh function, and the draw command determines how many threadgroups of the mesh stage to run.
        /// The default value is nil.
        #[unsafe(method(objectFunction))]
        #[unsafe(method_family = none)]
        pub fn objectFunction(&self) -> Option<Retained<ProtocolObject<dyn MTLFunction>>>;

        #[cfg(feature = "MTLLibrary")]
        /// Setter for [`objectFunction`][Self::objectFunction].
        ///
        /// # Safety
        ///
        /// - `object_function` must be safe to call.
        /// - `object_function` must have the correct argument and return types.
        #[unsafe(method(setObjectFunction:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setObjectFunction(
            &self,
            object_function: Option<&ProtocolObject<dyn MTLFunction>>,
        );

        #[cfg(feature = "MTLLibrary")]
        /// Shader function responsible for exporting a chunk of geometry per threadgroup for the rasterizer.
        /// The default value is nil.
        #[unsafe(method(meshFunction))]
        #[unsafe(method_family = none)]
        pub fn meshFunction(&self) -> Option<Retained<ProtocolObject<dyn MTLFunction>>>;

        #[cfg(feature = "MTLLibrary")]
        /// Setter for [`meshFunction`][Self::meshFunction].
        ///
        /// # Safety
        ///
        /// - `mesh_function` must be safe to call.
        /// - `mesh_function` must have the correct argument and return types.
        #[unsafe(method(setMeshFunction:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setMeshFunction(
            &self,
            mesh_function: Option<&ProtocolObject<dyn MTLFunction>>,
        );

        #[cfg(feature = "MTLLibrary")]
        /// Like a classical render pipeline, this fragments covered by the rasterized geometry are shaded with this function.
        /// The default value is nil. To create a pipeline, you must either set fragmentFunction to non-nil, or set rasterizationEnabled to NO.
        #[unsafe(method(fragmentFunction))]
        #[unsafe(method_family = none)]
        pub fn fragmentFunction(&self) -> Option<Retained<ProtocolObject<dyn MTLFunction>>>;

        #[cfg(feature = "MTLLibrary")]
        /// Setter for [`fragmentFunction`][Self::fragmentFunction].
        ///
        /// # Safety
        ///
        /// - `fragment_function` must be safe to call.
        /// - `fragment_function` must have the correct argument and return types.
        #[unsafe(method(setFragmentFunction:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setFragmentFunction(
            &self,
            fragment_function: Option<&ProtocolObject<dyn MTLFunction>>,
        );

        /// The maximum size of the product of threadsPerObjectThreadgroup that can be used for draws with this pipeline.
        /// This information can be used by the optimizer to generate more efficient code, specifically when the specified value does not exceed the thread execution width of the underlying GPU.
        /// The default value is 0, which means that the value specified with the [[max_total_threads_per_threadgroup(N)]] specified on objectFunction will be used.
        /// When both the [[max_total_threads_per_threadgroup(N)]] attribute and a non-zero value are specified, both values must match.
        /// Any value specified cannot exceed the device limit as documented in the "Metal Feature Set Tables" for "Maximum threads per threadgroup".
        #[unsafe(method(maxTotalThreadsPerObjectThreadgroup))]
        #[unsafe(method_family = none)]
        pub fn maxTotalThreadsPerObjectThreadgroup(&self) -> NSUInteger;

        /// Setter for [`maxTotalThreadsPerObjectThreadgroup`][Self::maxTotalThreadsPerObjectThreadgroup].
        #[unsafe(method(setMaxTotalThreadsPerObjectThreadgroup:))]
        #[unsafe(method_family = none)]
        pub fn setMaxTotalThreadsPerObjectThreadgroup(
            &self,
            max_total_threads_per_object_threadgroup: NSUInteger,
        );

        /// The maximum size of the product of threadsPerMeshThreadgroup that can be used for draws with this pipeline.
        /// This information can be used by the optimizer to generate more efficient code, specifically when the specified value does not exceed the thread execution width of the underlying GPU.
        /// The default value is 0, which means that the value specified with the [[max_total_threads_per_threadgroup(N)]] specified on meshFunction will be used.
        /// When both the [[max_total_threads_per_threadgroup(N)]] attribute and a non-zero value are specified, both values must match.
        /// Any value specified cannot exceed the device limit as documented in the "Metal Feature Set Tables" for "Maximum threads per threadgroup".
        #[unsafe(method(maxTotalThreadsPerMeshThreadgroup))]
        #[unsafe(method_family = none)]
        pub fn maxTotalThreadsPerMeshThreadgroup(&self) -> NSUInteger;

        /// Setter for [`maxTotalThreadsPerMeshThreadgroup`][Self::maxTotalThreadsPerMeshThreadgroup].
        #[unsafe(method(setMaxTotalThreadsPerMeshThreadgroup:))]
        #[unsafe(method_family = none)]
        pub fn setMaxTotalThreadsPerMeshThreadgroup(
            &self,
            max_total_threads_per_mesh_threadgroup: NSUInteger,
        );

        /// Set this value to YES when you will only use draws with the product of threadsPerObjectThreadgroup set to a multiple of the objectThreadExecutionWidth of the returned pipeline state.
        /// This information can be used by the optimizer to generate more efficient code.
        /// The default value is NO.
        #[unsafe(method(objectThreadgroupSizeIsMultipleOfThreadExecutionWidth))]
        #[unsafe(method_family = none)]
        pub fn objectThreadgroupSizeIsMultipleOfThreadExecutionWidth(&self) -> bool;

        /// Setter for [`objectThreadgroupSizeIsMultipleOfThreadExecutionWidth`][Self::objectThreadgroupSizeIsMultipleOfThreadExecutionWidth].
        #[unsafe(method(setObjectThreadgroupSizeIsMultipleOfThreadExecutionWidth:))]
        #[unsafe(method_family = none)]
        pub fn setObjectThreadgroupSizeIsMultipleOfThreadExecutionWidth(
            &self,
            object_threadgroup_size_is_multiple_of_thread_execution_width: bool,
        );

        /// Set this value to YES when you will only use draws with the product of threadsPerMeshThreadgroup set to a multiple of the meshThreadExecutionWidth of the returned pipeline state.
        /// This information can be used by the optimizer to generate more efficient code.
        /// The default value is NO.
        #[unsafe(method(meshThreadgroupSizeIsMultipleOfThreadExecutionWidth))]
        #[unsafe(method_family = none)]
        pub fn meshThreadgroupSizeIsMultipleOfThreadExecutionWidth(&self) -> bool;

        /// Setter for [`meshThreadgroupSizeIsMultipleOfThreadExecutionWidth`][Self::meshThreadgroupSizeIsMultipleOfThreadExecutionWidth].
        #[unsafe(method(setMeshThreadgroupSizeIsMultipleOfThreadExecutionWidth:))]
        #[unsafe(method_family = none)]
        pub fn setMeshThreadgroupSizeIsMultipleOfThreadExecutionWidth(
            &self,
            mesh_threadgroup_size_is_multiple_of_thread_execution_width: bool,
        );

        /// The size, in bytes, of the buffer indicated by [[payload]] in the object and mesh shader.
        /// If this value is 0, the size of the dereferenced type declared in the object shader for the buffer is used (space for a single element is assumed for pointers).
        /// The default value is 0.
        #[unsafe(method(payloadMemoryLength))]
        #[unsafe(method_family = none)]
        pub fn payloadMemoryLength(&self) -> NSUInteger;

        /// Setter for [`payloadMemoryLength`][Self::payloadMemoryLength].
        #[unsafe(method(setPayloadMemoryLength:))]
        #[unsafe(method_family = none)]
        pub fn setPayloadMemoryLength(&self, payload_memory_length: NSUInteger);

        /// The maximum value of the product of vector elements that the object shader may pass to the mesh_grid_properties::set_threadgroups_per_grid built-in function.
        /// The default value is 0, which means that the value specified with the [[max_total_threadgroups_per_mesh_grid(N)]] specified on objectFunction will be used.
        /// When both the [[max_total_threadgroups_per_mesh_grid(N)]] attribute and a non-zero value are specified, both values must match.
        /// Any value specified cannot exceed the device limit as documented in the "Metal Feature Set Tables" for "Maximum threadgroups per mesh grid".
        /// Specifying this value is optional; it may be used to improve scheduling of the workload. If neither this value nor the shader attribute are used, the device's maximum supported value is used instead.
        #[unsafe(method(maxTotalThreadgroupsPerMeshGrid))]
        #[unsafe(method_family = none)]
        pub fn maxTotalThreadgroupsPerMeshGrid(&self) -> NSUInteger;

        /// Setter for [`maxTotalThreadgroupsPerMeshGrid`][Self::maxTotalThreadgroupsPerMeshGrid].
        #[unsafe(method(setMaxTotalThreadgroupsPerMeshGrid:))]
        #[unsafe(method_family = none)]
        pub fn setMaxTotalThreadgroupsPerMeshGrid(
            &self,
            max_total_threadgroups_per_mesh_grid: NSUInteger,
        );

        #[cfg(feature = "MTLPipeline")]
        /// Provide mutability information on the buffers used by objectFunction.
        ///
        /// Specifying these values is optional; it may be used to optimize the shader code.
        #[unsafe(method(objectBuffers))]
        #[unsafe(method_family = none)]
        pub fn objectBuffers(&self) -> Retained<MTLPipelineBufferDescriptorArray>;

        #[cfg(feature = "MTLPipeline")]
        /// Provide mutability information on the buffers used by meshFunction.
        ///
        /// Specifying these values is optional; it may be used to optimize the shader code.
        #[unsafe(method(meshBuffers))]
        #[unsafe(method_family = none)]
        pub fn meshBuffers(&self) -> Retained<MTLPipelineBufferDescriptorArray>;

        #[cfg(feature = "MTLPipeline")]
        /// Provide mutability information on the buffers used by fragmentFunction.
        ///
        /// Specifying these values is optional; it may be used to optimize the shader code.
        #[unsafe(method(fragmentBuffers))]
        #[unsafe(method_family = none)]
        pub fn fragmentBuffers(&self) -> Retained<MTLPipelineBufferDescriptorArray>;

        /// The number of samples per fragment of the render pass in which this pipeline will be used.
        #[unsafe(method(rasterSampleCount))]
        #[unsafe(method_family = none)]
        pub fn rasterSampleCount(&self) -> NSUInteger;

        /// Setter for [`rasterSampleCount`][Self::rasterSampleCount].
        ///
        /// # Safety
        ///
        /// This might not be bounds-checked.
        #[unsafe(method(setRasterSampleCount:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setRasterSampleCount(&self, raster_sample_count: NSUInteger);

        /// Whether the alpha value exported by the fragment shader for the first color attachment is converted to a sample mask, which is subsequently AND-ed with the fragments' sample mask
        ///
        /// The default value is NO.
        #[unsafe(method(isAlphaToCoverageEnabled))]
        #[unsafe(method_family = none)]
        pub fn isAlphaToCoverageEnabled(&self) -> bool;

        /// Setter for [`isAlphaToCoverageEnabled`][Self::isAlphaToCoverageEnabled].
        #[unsafe(method(setAlphaToCoverageEnabled:))]
        #[unsafe(method_family = none)]
        pub fn setAlphaToCoverageEnabled(&self, alpha_to_coverage_enabled: bool);

        /// Whether the alpha value exported by the fragment shader for all color attachments is modified to 1 (after evaluating alphaToCoverage).
        ///
        /// The default value is NO.
        #[unsafe(method(isAlphaToOneEnabled))]
        #[unsafe(method_family = none)]
        pub fn isAlphaToOneEnabled(&self) -> bool;

        /// Setter for [`isAlphaToOneEnabled`][Self::isAlphaToOneEnabled].
        #[unsafe(method(setAlphaToOneEnabled:))]
        #[unsafe(method_family = none)]
        pub fn setAlphaToOneEnabled(&self, alpha_to_one_enabled: bool);

        /// Whether rasterization is disabled, all primitives are dropped prior to rasterization.
        ///
        /// The default value is YES.
        #[unsafe(method(isRasterizationEnabled))]
        #[unsafe(method_family = none)]
        pub fn isRasterizationEnabled(&self) -> bool;

        /// Setter for [`isRasterizationEnabled`][Self::isRasterizationEnabled].
        #[unsafe(method(setRasterizationEnabled:))]
        #[unsafe(method_family = none)]
        pub fn setRasterizationEnabled(&self, rasterization_enabled: bool);

        /// The maximum value that can be passed to setVertexAmplificationCount when using this pipeline.
        ///
        /// The default value is 1. The value must be supported by the device, which can be checked with supportsVertexAmplificationCount.
        #[unsafe(method(maxVertexAmplificationCount))]
        #[unsafe(method_family = none)]
        pub fn maxVertexAmplificationCount(&self) -> NSUInteger;

        /// Setter for [`maxVertexAmplificationCount`][Self::maxVertexAmplificationCount].
        ///
        /// # Safety
        ///
        /// This might not be bounds-checked.
        #[unsafe(method(setMaxVertexAmplificationCount:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setMaxVertexAmplificationCount(
            &self,
            max_vertex_amplification_count: NSUInteger,
        );

        /// Describes the color attachments of the render pass in which this pipeline will be used.
        #[unsafe(method(colorAttachments))]
        #[unsafe(method_family = none)]
        pub fn colorAttachments(&self)
            -> Retained<MTLRenderPipelineColorAttachmentDescriptorArray>;

        #[cfg(feature = "MTLPixelFormat")]
        /// The pixel format of the depth attachment of the render pass in which this pipeline will be used.
        ///
        /// The default value is MTLPixelFormatInvalid; indicating no depth attachment will be used.
        #[unsafe(method(depthAttachmentPixelFormat))]
        #[unsafe(method_family = none)]
        pub fn depthAttachmentPixelFormat(&self) -> MTLPixelFormat;

        #[cfg(feature = "MTLPixelFormat")]
        /// Setter for [`depthAttachmentPixelFormat`][Self::depthAttachmentPixelFormat].
        #[unsafe(method(setDepthAttachmentPixelFormat:))]
        #[unsafe(method_family = none)]
        pub fn setDepthAttachmentPixelFormat(&self, depth_attachment_pixel_format: MTLPixelFormat);

        #[cfg(feature = "MTLPixelFormat")]
        /// The pixel format of the stencil attachment of the render pass in which this pipeline will be used.
        ///
        /// The default value is MTLPixelFormatInvalid; indicating no stencil attachment will be used.
        #[unsafe(method(stencilAttachmentPixelFormat))]
        #[unsafe(method_family = none)]
        pub fn stencilAttachmentPixelFormat(&self) -> MTLPixelFormat;

        #[cfg(feature = "MTLPixelFormat")]
        /// Setter for [`stencilAttachmentPixelFormat`][Self::stencilAttachmentPixelFormat].
        #[unsafe(method(setStencilAttachmentPixelFormat:))]
        #[unsafe(method_family = none)]
        pub fn setStencilAttachmentPixelFormat(
            &self,
            stencil_attachment_pixel_format: MTLPixelFormat,
        );

        /// Whether this pipeline will support being used by commands in an indirect command buffer.
        ///
        /// The default value is NO.
        #[unsafe(method(supportIndirectCommandBuffers))]
        #[unsafe(method_family = none)]
        pub fn supportIndirectCommandBuffers(&self) -> bool;

        /// Setter for [`supportIndirectCommandBuffers`][Self::supportIndirectCommandBuffers].
        #[unsafe(method(setSupportIndirectCommandBuffers:))]
        #[unsafe(method_family = none)]
        pub fn setSupportIndirectCommandBuffers(&self, support_indirect_command_buffers: bool);

        #[cfg(feature = "MTLBinaryArchive")]
        /// The set of MTLBinaryArchive to search for compiled code when creating the pipeline state.
        ///
        /// Accelerate pipeline state creation by providing archives of compiled code such that no compilation needs to happen on the fast path.
        ///
        /// See: MTLBinaryArchive
        #[unsafe(method(binaryArchives))]
        #[unsafe(method_family = none)]
        pub fn binaryArchives(
            &self,
        ) -> Option<Retained<NSArray<ProtocolObject<dyn MTLBinaryArchive>>>>;

        #[cfg(feature = "MTLBinaryArchive")]
        /// Setter for [`binaryArchives`][Self::binaryArchives].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setBinaryArchives:))]
        #[unsafe(method_family = none)]
        pub fn setBinaryArchives(
            &self,
            binary_archives: Option<&NSArray<ProtocolObject<dyn MTLBinaryArchive>>>,
        );

        #[cfg(feature = "MTLLinkedFunctions")]
        /// The set of functions to be linked with the pipeline state and accessed from the object function.
        ///
        /// See: MTLLinkedFunctions
        #[unsafe(method(objectLinkedFunctions))]
        #[unsafe(method_family = none)]
        pub fn objectLinkedFunctions(&self) -> Retained<MTLLinkedFunctions>;

        #[cfg(feature = "MTLLinkedFunctions")]
        /// Setter for [`objectLinkedFunctions`][Self::objectLinkedFunctions].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setObjectLinkedFunctions:))]
        #[unsafe(method_family = none)]
        pub fn setObjectLinkedFunctions(
            &self,
            object_linked_functions: Option<&MTLLinkedFunctions>,
        );

        #[cfg(feature = "MTLLinkedFunctions")]
        /// The set of functions to be linked with the pipeline state and accessed from the mesh function.
        ///
        /// See: MTLLinkedFunctions
        #[unsafe(method(meshLinkedFunctions))]
        #[unsafe(method_family = none)]
        pub fn meshLinkedFunctions(&self) -> Retained<MTLLinkedFunctions>;

        #[cfg(feature = "MTLLinkedFunctions")]
        /// Setter for [`meshLinkedFunctions`][Self::meshLinkedFunctions].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setMeshLinkedFunctions:))]
        #[unsafe(method_family = none)]
        pub fn setMeshLinkedFunctions(&self, mesh_linked_functions: Option<&MTLLinkedFunctions>);

        #[cfg(feature = "MTLLinkedFunctions")]
        /// The set of functions to be linked with the pipeline state and accessed from the fragment function.
        ///
        /// See: MTLLinkedFunctions
        #[unsafe(method(fragmentLinkedFunctions))]
        #[unsafe(method_family = none)]
        pub fn fragmentLinkedFunctions(&self) -> Retained<MTLLinkedFunctions>;

        #[cfg(feature = "MTLLinkedFunctions")]
        /// Setter for [`fragmentLinkedFunctions`][Self::fragmentLinkedFunctions].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setFragmentLinkedFunctions:))]
        #[unsafe(method_family = none)]
        pub fn setFragmentLinkedFunctions(
            &self,
            fragment_linked_functions: Option<&MTLLinkedFunctions>,
        );

        /// Restore all mesh pipeline descriptor properties to their default values.
        #[unsafe(method(reset))]
        #[unsafe(method_family = none)]
        pub fn reset(&self);

        #[cfg(feature = "MTLPipeline")]
        /// Toggle that determines whether Metal Shader Validation should be enabled or disabled for the pipeline.
        ///
        /// The value can be overridden using `MTL_SHADER_VALIDATION_ENABLE_PIPELINES` or `MTL_SHADER_VALIDATION_DISABLE_PIPELINES` Environment Variables.
        #[unsafe(method(shaderValidation))]
        #[unsafe(method_family = none)]
        pub fn shaderValidation(&self) -> MTLShaderValidation;

        #[cfg(feature = "MTLPipeline")]
        /// Setter for [`shaderValidation`][Self::shaderValidation].
        #[unsafe(method(setShaderValidation:))]
        #[unsafe(method_family = none)]
        pub fn setShaderValidation(&self, shader_validation: MTLShaderValidation);

        #[cfg(feature = "MTLTypes")]
        /// Sets the required object threads-per-threadgroup during mesh draws. The `threadsPerObjectThreadgroup` argument of any draw must match to this value if it is set.
        /// Optional, unless the pipeline is going to use CooperativeTensors in which case this must be set.
        /// Setting this to a size of 0 in every dimension disables this property
        #[unsafe(method(requiredThreadsPerObjectThreadgroup))]
        #[unsafe(method_family = none)]
        pub fn requiredThreadsPerObjectThreadgroup(&self) -> MTLSize;

        #[cfg(feature = "MTLTypes")]
        /// Setter for [`requiredThreadsPerObjectThreadgroup`][Self::requiredThreadsPerObjectThreadgroup].
        #[unsafe(method(setRequiredThreadsPerObjectThreadgroup:))]
        #[unsafe(method_family = none)]
        pub fn setRequiredThreadsPerObjectThreadgroup(
            &self,
            required_threads_per_object_threadgroup: MTLSize,
        );

        #[cfg(feature = "MTLTypes")]
        /// Sets the required mesh threads-per-threadgroup during mesh draws. The `threadsPerMeshThreadgroup` argument of any draw must match to this value if it is set.
        /// Optional, unless the pipeline is going to use CooperativeTensors in which case this must be set.
        /// Setting this to a size of 0 in every dimension disables this property
        #[unsafe(method(requiredThreadsPerMeshThreadgroup))]
        #[unsafe(method_family = none)]
        pub fn requiredThreadsPerMeshThreadgroup(&self) -> MTLSize;

        #[cfg(feature = "MTLTypes")]
        /// Setter for [`requiredThreadsPerMeshThreadgroup`][Self::requiredThreadsPerMeshThreadgroup].
        #[unsafe(method(setRequiredThreadsPerMeshThreadgroup:))]
        #[unsafe(method_family = none)]
        pub fn setRequiredThreadsPerMeshThreadgroup(
            &self,
            required_threads_per_mesh_threadgroup: MTLSize,
        );
    );
}

/// Methods declared on superclass `NSObject`.
impl MTLMeshRenderPipelineDescriptor {
    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 DefaultRetained for MTLMeshRenderPipelineDescriptor {
    #[inline]
    fn default_retained() -> Retained<Self> {
        Self::new()
    }
}
