//! 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/mtlclearcolor?language=objc)
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct MTLClearColor {
    pub red: c_double,
    pub green: c_double,
    pub blue: c_double,
    pub alpha: c_double,
}

unsafe impl Encode for MTLClearColor {
    const ENCODING: Encoding = Encoding::Struct(
        "?",
        &[
            <c_double>::ENCODING,
            <c_double>::ENCODING,
            <c_double>::ENCODING,
            <c_double>::ENCODING,
        ],
    );
}

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

impl MTLClearColor {
    // TODO: pub fn MTLClearColorMake(red: c_double,green: c_double,blue: c_double,alpha: c_double,) -> MTLClearColor;
}

/// [Apple's documentation](https://developer.apple.com/documentation/metal/mtlloadaction?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTLLoadAction(pub NSUInteger);
impl MTLLoadAction {
    #[doc(alias = "MTLLoadActionDontCare")]
    pub const DontCare: Self = Self(0);
    #[doc(alias = "MTLLoadActionLoad")]
    pub const Load: Self = Self(1);
    #[doc(alias = "MTLLoadActionClear")]
    pub const Clear: Self = Self(2);
}

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

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

/// [Apple's documentation](https://developer.apple.com/documentation/metal/mtlstoreaction?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTLStoreAction(pub NSUInteger);
impl MTLStoreAction {
    #[doc(alias = "MTLStoreActionDontCare")]
    pub const DontCare: Self = Self(0);
    #[doc(alias = "MTLStoreActionStore")]
    pub const Store: Self = Self(1);
    #[doc(alias = "MTLStoreActionMultisampleResolve")]
    pub const MultisampleResolve: Self = Self(2);
    #[doc(alias = "MTLStoreActionStoreAndMultisampleResolve")]
    pub const StoreAndMultisampleResolve: Self = Self(3);
    #[doc(alias = "MTLStoreActionUnknown")]
    pub const Unknown: Self = Self(4);
    #[doc(alias = "MTLStoreActionCustomSampleDepthStore")]
    pub const CustomSampleDepthStore: Self = Self(5);
}

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

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

/// [Apple's documentation](https://developer.apple.com/documentation/metal/mtlstoreactionoptions?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTLStoreActionOptions(pub NSUInteger);
bitflags::bitflags! {
    impl MTLStoreActionOptions: NSUInteger {
        #[doc(alias = "MTLStoreActionOptionNone")]
        const None = 0;
        #[doc(alias = "MTLStoreActionOptionCustomSamplePositions")]
        const CustomSamplePositions = 1<<0;
    }
}

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

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

/// This enumeration controls if Metal accumulates visibility results between render encoders or resets them.
///
/// You can specify this property for ``MTLRenderCommandEncoders`` and for ``MTL4RenderCommandEncoders`` through
/// their descriptors' ``MTLRenderCommandEncoder/visibilityResultType`` and ``MTL4RenderCommandEncoder/visibilityResultType``
/// methods.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtlvisibilityresulttype?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTLVisibilityResultType(pub NSInteger);
impl MTLVisibilityResultType {
    /// Reset visibility result data when you create a render command encoder.
    #[doc(alias = "MTLVisibilityResultTypeReset")]
    pub const Reset: Self = Self(0);
    /// Accumulate visibility results data across multiple render passes.
    #[doc(alias = "MTLVisibilityResultTypeAccumulate")]
    pub const Accumulate: Self = Self(1);
}

unsafe impl Encode for MTLVisibilityResultType {
    const ENCODING: Encoding = NSInteger::ENCODING;
}

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

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

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

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

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

impl MTLRenderPassAttachmentDescriptor {
    extern_methods!(
        #[cfg(all(
            feature = "MTLAllocation",
            feature = "MTLResource",
            feature = "MTLTexture"
        ))]
        /// The MTLTexture object for this attachment.
        #[unsafe(method(texture))]
        #[unsafe(method_family = none)]
        pub fn texture(&self) -> Option<Retained<ProtocolObject<dyn MTLTexture>>>;

        #[cfg(all(
            feature = "MTLAllocation",
            feature = "MTLResource",
            feature = "MTLTexture"
        ))]
        /// Setter for [`texture`][Self::texture].
        #[unsafe(method(setTexture:))]
        #[unsafe(method_family = none)]
        pub fn setTexture(&self, texture: Option<&ProtocolObject<dyn MTLTexture>>);

        /// The mipmap level of the texture to be used for rendering.  Default is zero.
        #[unsafe(method(level))]
        #[unsafe(method_family = none)]
        pub fn level(&self) -> NSUInteger;

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

        /// The slice of the texture to be used for rendering.  Default is zero.
        #[unsafe(method(slice))]
        #[unsafe(method_family = none)]
        pub fn slice(&self) -> NSUInteger;

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

        /// The depth plane of the texture to be used for rendering.  Default is zero.
        #[unsafe(method(depthPlane))]
        #[unsafe(method_family = none)]
        pub fn depthPlane(&self) -> NSUInteger;

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

        #[cfg(all(
            feature = "MTLAllocation",
            feature = "MTLResource",
            feature = "MTLTexture"
        ))]
        /// The texture used for multisample resolve operations.  Only used (and required)
        /// if the store action is set to MTLStoreActionMultisampleResolve.
        #[unsafe(method(resolveTexture))]
        #[unsafe(method_family = none)]
        pub fn resolveTexture(&self) -> Option<Retained<ProtocolObject<dyn MTLTexture>>>;

        #[cfg(all(
            feature = "MTLAllocation",
            feature = "MTLResource",
            feature = "MTLTexture"
        ))]
        /// Setter for [`resolveTexture`][Self::resolveTexture].
        #[unsafe(method(setResolveTexture:))]
        #[unsafe(method_family = none)]
        pub fn setResolveTexture(&self, resolve_texture: Option<&ProtocolObject<dyn MTLTexture>>);

        /// The mipmap level of the resolve texture to be used for multisample resolve.  Defaults to zero.
        #[unsafe(method(resolveLevel))]
        #[unsafe(method_family = none)]
        pub fn resolveLevel(&self) -> NSUInteger;

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

        /// The texture slice of the resolve texture to be used for multisample resolve.  Defaults to zero.
        #[unsafe(method(resolveSlice))]
        #[unsafe(method_family = none)]
        pub fn resolveSlice(&self) -> NSUInteger;

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

        /// The texture depth plane of the resolve texture to be used for multisample resolve.  Defaults to zero.
        #[unsafe(method(resolveDepthPlane))]
        #[unsafe(method_family = none)]
        pub fn resolveDepthPlane(&self) -> NSUInteger;

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

        /// The action to be performed with this attachment at the beginning of a render pass.  Default is
        /// MTLLoadActionDontCare unless specified by a creation or init method.
        #[unsafe(method(loadAction))]
        #[unsafe(method_family = none)]
        pub fn loadAction(&self) -> MTLLoadAction;

        /// Setter for [`loadAction`][Self::loadAction].
        #[unsafe(method(setLoadAction:))]
        #[unsafe(method_family = none)]
        pub fn setLoadAction(&self, load_action: MTLLoadAction);

        /// The action to be performed with this attachment at the end of a render pass.  Default is
        /// MTLStoreActionDontCare unless specified by a creation or init method.
        #[unsafe(method(storeAction))]
        #[unsafe(method_family = none)]
        pub fn storeAction(&self) -> MTLStoreAction;

        /// Setter for [`storeAction`][Self::storeAction].
        #[unsafe(method(setStoreAction:))]
        #[unsafe(method_family = none)]
        pub fn setStoreAction(&self, store_action: MTLStoreAction);

        /// Optional configuration for the store action performed with this attachment at the end of a render pass.  Default is
        /// MTLStoreActionOptionNone.
        #[unsafe(method(storeActionOptions))]
        #[unsafe(method_family = none)]
        pub fn storeActionOptions(&self) -> MTLStoreActionOptions;

        /// Setter for [`storeActionOptions`][Self::storeActionOptions].
        #[unsafe(method(setStoreActionOptions:))]
        #[unsafe(method_family = none)]
        pub fn setStoreActionOptions(&self, store_action_options: MTLStoreActionOptions);
    );
}

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

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

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

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

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

impl MTLRenderPassColorAttachmentDescriptor {
    extern_methods!(
        /// The clear color to be used if the loadAction property is MTLLoadActionClear
        #[unsafe(method(clearColor))]
        #[unsafe(method_family = none)]
        pub fn clearColor(&self) -> MTLClearColor;

        /// Setter for [`clearColor`][Self::clearColor].
        #[unsafe(method(setClearColor:))]
        #[unsafe(method_family = none)]
        pub fn setClearColor(&self, clear_color: MTLClearColor);
    );
}

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

/// Controls the MSAA depth resolve operation. Supported on iOS GPU Family 3 and later.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtlmultisampledepthresolvefilter?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTLMultisampleDepthResolveFilter(pub NSUInteger);
impl MTLMultisampleDepthResolveFilter {
    #[doc(alias = "MTLMultisampleDepthResolveFilterSample0")]
    pub const Sample0: Self = Self(0);
    #[doc(alias = "MTLMultisampleDepthResolveFilterMin")]
    pub const Min: Self = Self(1);
    #[doc(alias = "MTLMultisampleDepthResolveFilterMax")]
    pub const Max: Self = Self(2);
}

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

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

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

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

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

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

impl MTLRenderPassDepthAttachmentDescriptor {
    extern_methods!(
        /// The clear depth value to be used if the loadAction property is MTLLoadActionClear
        #[unsafe(method(clearDepth))]
        #[unsafe(method_family = none)]
        pub fn clearDepth(&self) -> c_double;

        /// Setter for [`clearDepth`][Self::clearDepth].
        #[unsafe(method(setClearDepth:))]
        #[unsafe(method_family = none)]
        pub fn setClearDepth(&self, clear_depth: c_double);

        /// The filter to be used for depth multisample resolve.  Defaults to MTLMultisampleDepthResolveFilterSample0.
        #[unsafe(method(depthResolveFilter))]
        #[unsafe(method_family = none)]
        pub fn depthResolveFilter(&self) -> MTLMultisampleDepthResolveFilter;

        /// Setter for [`depthResolveFilter`][Self::depthResolveFilter].
        #[unsafe(method(setDepthResolveFilter:))]
        #[unsafe(method_family = none)]
        pub fn setDepthResolveFilter(&self, depth_resolve_filter: MTLMultisampleDepthResolveFilter);
    );
}

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

/// Controls the MSAA stencil resolve operation.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtlmultisamplestencilresolvefilter?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTLMultisampleStencilResolveFilter(pub NSUInteger);
impl MTLMultisampleStencilResolveFilter {
    /// The stencil sample corresponding to sample 0. This is the default behavior.
    #[doc(alias = "MTLMultisampleStencilResolveFilterSample0")]
    pub const Sample0: Self = Self(0);
    /// The stencil sample corresponding to whichever depth sample is selected by the depth resolve filter. If depth resolve is not enabled, the stencil sample is chosen based on what a depth resolve filter would have selected.
    #[doc(alias = "MTLMultisampleStencilResolveFilterDepthResolvedSample")]
    pub const DepthResolvedSample: Self = Self(1);
}

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

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

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

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

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

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

impl MTLRenderPassStencilAttachmentDescriptor {
    extern_methods!(
        /// The clear stencil value to be used if the loadAction property is MTLLoadActionClear
        #[unsafe(method(clearStencil))]
        #[unsafe(method_family = none)]
        pub fn clearStencil(&self) -> u32;

        /// Setter for [`clearStencil`][Self::clearStencil].
        #[unsafe(method(setClearStencil:))]
        #[unsafe(method_family = none)]
        pub fn setClearStencil(&self, clear_stencil: u32);

        /// The filter to be used for stencil multisample resolve. Defaults to MTLMultisampleStencilResolveFilterSample0.
        #[unsafe(method(stencilResolveFilter))]
        #[unsafe(method_family = none)]
        pub fn stencilResolveFilter(&self) -> MTLMultisampleStencilResolveFilter;

        /// Setter for [`stencilResolveFilter`][Self::stencilResolveFilter].
        #[unsafe(method(setStencilResolveFilter:))]
        #[unsafe(method_family = none)]
        pub fn setStencilResolveFilter(
            &self,
            stencil_resolve_filter: MTLMultisampleStencilResolveFilter,
        );
    );
}

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

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

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

impl MTLRenderPassColorAttachmentDescriptorArray {
    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<MTLRenderPassColorAttachmentDescriptor>;

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

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

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

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

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

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

impl MTLRenderPassSampleBufferAttachmentDescriptor {
    extern_methods!(
        #[cfg(feature = "MTLCounters")]
        /// The sample buffer to store samples for the render-pass defined samples.
        /// If sampleBuffer is non-nil, the sample indices will be used to store samples into
        /// the sample buffer.  If no sample buffer is provided, no samples will be taken.
        /// If any of the sample indices are specified as MTLCounterDontSample, no sample
        /// will be taken for that action.
        #[unsafe(method(sampleBuffer))]
        #[unsafe(method_family = none)]
        pub fn sampleBuffer(&self) -> Option<Retained<ProtocolObject<dyn MTLCounterSampleBuffer>>>;

        #[cfg(feature = "MTLCounters")]
        /// Setter for [`sampleBuffer`][Self::sampleBuffer].
        #[unsafe(method(setSampleBuffer:))]
        #[unsafe(method_family = none)]
        pub fn setSampleBuffer(
            &self,
            sample_buffer: Option<&ProtocolObject<dyn MTLCounterSampleBuffer>>,
        );

        /// The sample index to use to store the sample taken at the start of
        /// vertex processing.  Setting the value to MTLCounterDontSample will cause
        /// this sample to be omitted.
        ///
        /// On devices where MTLCounterSamplingPointAtStageBoundary is unsupported,
        /// this sample index is invalid and must be set to MTLCounterDontSample or creation of a render pass will fail.
        #[unsafe(method(startOfVertexSampleIndex))]
        #[unsafe(method_family = none)]
        pub fn startOfVertexSampleIndex(&self) -> NSUInteger;

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

        /// The sample index to use to store the sample taken at the end of
        /// vertex processing.  Setting the value to MTLCounterDontSample will cause
        /// this sample to be omitted.
        ///
        /// On devices where MTLCounterSamplingPointAtStageBoundary is unsupported,
        /// this sample index is invalid and must be set to MTLCounterDontSample or creation of a render pass will fail.
        #[unsafe(method(endOfVertexSampleIndex))]
        #[unsafe(method_family = none)]
        pub fn endOfVertexSampleIndex(&self) -> NSUInteger;

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

        /// The sample index to use to store the sample taken at the start of
        /// fragment processing.  Setting the value to MTLCounterDontSample will cause
        /// this sample to be omitted.
        ///
        /// On devices where MTLCounterSamplingPointAtStageBoundary is unsupported,
        /// this sample index is invalid and must be set to MTLCounterDontSample or creation of a render pass will fail.
        #[unsafe(method(startOfFragmentSampleIndex))]
        #[unsafe(method_family = none)]
        pub fn startOfFragmentSampleIndex(&self) -> NSUInteger;

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

        /// The sample index to use to store the sample taken at the end of
        /// fragment processing.  Setting the value to MTLCounterDontSample will cause
        /// this sample to be omitted.
        ///
        /// On devices where MTLCounterSamplingPointAtStageBoundary is unsupported,
        /// this sample index is invalid and must be set to MTLCounterDontSample or creation of a render pass will fail.
        #[unsafe(method(endOfFragmentSampleIndex))]
        #[unsafe(method_family = none)]
        pub fn endOfFragmentSampleIndex(&self) -> NSUInteger;

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

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

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

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

impl MTLRenderPassSampleBufferAttachmentDescriptorArray {
    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<MTLRenderPassSampleBufferAttachmentDescriptor>;

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

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

extern_class!(
    /// MTLRenderPassDescriptor represents a collection of attachments to be used to create a concrete render command encoder
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtlrenderpassdescriptor?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct MTLRenderPassDescriptor;
);

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

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

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

impl MTLRenderPassDescriptor {
    extern_methods!(
        /// Create an autoreleased default frame buffer descriptor
        #[unsafe(method(renderPassDescriptor))]
        #[unsafe(method_family = none)]
        pub fn renderPassDescriptor() -> Retained<MTLRenderPassDescriptor>;

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

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

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

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

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

        #[cfg(all(
            feature = "MTLAllocation",
            feature = "MTLBuffer",
            feature = "MTLResource"
        ))]
        /// Buffer into which samples passing the depth and stencil tests are counted.
        #[unsafe(method(visibilityResultBuffer))]
        #[unsafe(method_family = none)]
        pub fn visibilityResultBuffer(&self) -> Option<Retained<ProtocolObject<dyn MTLBuffer>>>;

        #[cfg(all(
            feature = "MTLAllocation",
            feature = "MTLBuffer",
            feature = "MTLResource"
        ))]
        /// Setter for [`visibilityResultBuffer`][Self::visibilityResultBuffer].
        #[unsafe(method(setVisibilityResultBuffer:))]
        #[unsafe(method_family = none)]
        pub fn setVisibilityResultBuffer(
            &self,
            visibility_result_buffer: Option<&ProtocolObject<dyn MTLBuffer>>,
        );

        /// The number of active layers
        #[unsafe(method(renderTargetArrayLength))]
        #[unsafe(method_family = none)]
        pub fn renderTargetArrayLength(&self) -> NSUInteger;

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

        /// The per sample size in bytes of the largest explicit imageblock layout in the renderPass.
        #[unsafe(method(imageblockSampleLength))]
        #[unsafe(method_family = none)]
        pub fn imageblockSampleLength(&self) -> NSUInteger;

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

        /// The per tile size in bytes of the persistent threadgroup memory allocation.
        #[unsafe(method(threadgroupMemoryLength))]
        #[unsafe(method_family = none)]
        pub fn threadgroupMemoryLength(&self) -> NSUInteger;

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

        /// The width in pixels of the tile.
        ///
        /// Defaults to 0. Zero means Metal chooses a width that fits within the local memory.
        #[unsafe(method(tileWidth))]
        #[unsafe(method_family = none)]
        pub fn tileWidth(&self) -> NSUInteger;

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

        /// The height in pixels of the tile.
        ///
        /// Defaults to 0. Zero means Metal chooses a height that fits within the local memory.
        #[unsafe(method(tileHeight))]
        #[unsafe(method_family = none)]
        pub fn tileHeight(&self) -> NSUInteger;

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

        /// The raster sample count for the render pass when no attachments are given.
        #[unsafe(method(defaultRasterSampleCount))]
        #[unsafe(method_family = none)]
        pub fn defaultRasterSampleCount(&self) -> NSUInteger;

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

        /// The width in pixels to constrain the render target to.
        ///
        /// Defaults to 0. If non-zero the value must be smaller than or equal to the minimum width of all attachments.
        #[unsafe(method(renderTargetWidth))]
        #[unsafe(method_family = none)]
        pub fn renderTargetWidth(&self) -> NSUInteger;

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

        /// The height in pixels to constrain the render target to.
        ///
        /// Defaults to 0. If non-zero the value must be smaller than or equal to the minimum height of all attachments.
        #[unsafe(method(renderTargetHeight))]
        #[unsafe(method_family = none)]
        pub fn renderTargetHeight(&self) -> NSUInteger;

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

        #[cfg(feature = "MTLTypes")]
        /// Configure the custom sample positions, to be used in MSAA rendering (i.e. when sample count > 1).
        ///
        /// Parameter `positions`: The source array for custom sample position data.
        ///
        /// Parameter `count`: Specifies the length of the positions array, and must be a valid sample count or 0 (to disable custom sample positions).
        ///
        /// # Safety
        ///
        /// - `positions` must be a valid pointer or null.
        /// - `count` might not be bounds-checked.
        #[unsafe(method(setSamplePositions:count:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setSamplePositions_count(
            &self,
            positions: *const MTLSamplePosition,
            count: NSUInteger,
        );

        #[cfg(feature = "MTLTypes")]
        /// Retrieve the previously configured custom sample positions. The positions input array will only be modified when count specifies a length sufficient for the number of previously configured positions.
        ///
        /// Parameter `positions`: The destination array for custom sample position data.
        ///
        /// Parameter `count`: Specifies the length of the positions array, which must be large enough to hold all configured sample positions.
        ///
        /// Returns: The number of previously configured custom sample positions.
        ///
        /// # Safety
        ///
        /// - `positions` must be a valid pointer or null.
        /// - `count` might not be bounds-checked.
        #[unsafe(method(getSamplePositions:count:))]
        #[unsafe(method_family = none)]
        pub unsafe fn getSamplePositions_count(
            &self,
            positions: *mut MTLSamplePosition,
            count: NSUInteger,
        ) -> NSUInteger;

        #[cfg(feature = "MTLRasterizationRate")]
        /// The variable rasterization rate map to use when rendering this pass, or nil to not use variable rasterization rate.
        ///
        /// The default value is nil. Enabling variable rasterization rate allows for decreasing the rasterization rate in unimportant regions of screen space.
        #[unsafe(method(rasterizationRateMap))]
        #[unsafe(method_family = none)]
        pub fn rasterizationRateMap(
            &self,
        ) -> Option<Retained<ProtocolObject<dyn MTLRasterizationRateMap>>>;

        #[cfg(feature = "MTLRasterizationRate")]
        /// Setter for [`rasterizationRateMap`][Self::rasterizationRateMap].
        #[unsafe(method(setRasterizationRateMap:))]
        #[unsafe(method_family = none)]
        pub fn setRasterizationRateMap(
            &self,
            rasterization_rate_map: Option<&ProtocolObject<dyn MTLRasterizationRateMap>>,
        );

        /// An array of sample buffers and associated sample indices.
        #[unsafe(method(sampleBufferAttachments))]
        #[unsafe(method_family = none)]
        pub fn sampleBufferAttachments(
            &self,
        ) -> Retained<MTLRenderPassSampleBufferAttachmentDescriptorArray>;

        /// Specifies if Metal accumulates visibility results between render encoders or resets them.
        #[unsafe(method(visibilityResultType))]
        #[unsafe(method_family = none)]
        pub fn visibilityResultType(&self) -> MTLVisibilityResultType;

        /// Setter for [`visibilityResultType`][Self::visibilityResultType].
        #[unsafe(method(setVisibilityResultType:))]
        #[unsafe(method_family = none)]
        pub fn setVisibilityResultType(&self, visibility_result_type: MTLVisibilityResultType);

        /// Specifies if the render pass should support color attachment mapping.
        #[unsafe(method(supportColorAttachmentMapping))]
        #[unsafe(method_family = none)]
        pub fn supportColorAttachmentMapping(&self) -> bool;

        /// Setter for [`supportColorAttachmentMapping`][Self::supportColorAttachmentMapping].
        #[unsafe(method(setSupportColorAttachmentMapping:))]
        #[unsafe(method_family = none)]
        pub fn setSupportColorAttachmentMapping(&self, support_color_attachment_mapping: bool);
    );
}

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

impl MTLClearColor {
    // TODO: pub fn MTLClearColorMake(red: c_double,green: c_double,blue: c_double,alpha: c_double,) -> MTLClearColor;
}
