//! 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::*;

/// Describes how a resource will be used by a shader through an argument buffer
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtlresourceusage?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTLResourceUsage(pub NSUInteger);
bitflags::bitflags! {
    impl MTLResourceUsage: NSUInteger {
        #[doc(alias = "MTLResourceUsageRead")]
        const Read = 1<<0;
        #[doc(alias = "MTLResourceUsageWrite")]
        const Write = 1<<1;
        #[doc(alias = "MTLResourceUsageSample")]
#[deprecated]
        const Sample = 1<<2;
    }
}

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

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

/// Describes the types of resources that the a barrier operates on
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtlbarrierscope?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTLBarrierScope(pub NSUInteger);
bitflags::bitflags! {
    impl MTLBarrierScope: NSUInteger {
        #[doc(alias = "MTLBarrierScopeBuffers")]
        const Buffers = 1<<0;
        #[doc(alias = "MTLBarrierScopeTextures")]
        const Textures = 1<<1;
        #[doc(alias = "MTLBarrierScopeRenderTargets")]
        const RenderTargets = 1<<2;
    }
}

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

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

/// Describes stages of GPU work.
///
/// All commands you encoder into command buffers relate to one or more shader stages,
/// for example, a compute dispatch command from a compute command encoder relates to
/// stage ``MTLStageDispatch``.
///
/// Use these stages to issue barriers between shader stages to ensure Metal correctly
/// synchronizes GPU commands.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtlstages?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTLStages(pub NSUInteger);
bitflags::bitflags! {
    impl MTLStages: NSUInteger {
/// Represents all vertex shader stage work in a render pass.
        #[doc(alias = "MTLStageVertex")]
        const Vertex = 1<<0;
/// Represents all fragment shader stage work in a render pass.
        #[doc(alias = "MTLStageFragment")]
        const Fragment = 1<<1;
/// Represents all tile shading stage work in a render pass.
        #[doc(alias = "MTLStageTile")]
        const Tile = 1<<2;
/// Represents all object shader stage work in a render pass.
        #[doc(alias = "MTLStageObject")]
        const Object = 1<<3;
/// Represents all mesh shader stage work work in a render pass.
        #[doc(alias = "MTLStageMesh")]
        const Mesh = 1<<4;
/// Represents all sparse and placement sparse resource mapping updates.
        #[doc(alias = "MTLStageResourceState")]
        const ResourceState = 1<<26;
/// Represents all compute dispatches in a compute pass.
        #[doc(alias = "MTLStageDispatch")]
        const Dispatch = 1<<27;
/// Represents all blit operations in a pass.
        #[doc(alias = "MTLStageBlit")]
        const Blit = 1<<28;
/// Represents all acceleration structure operations.
        #[doc(alias = "MTLStageAccelerationStructure")]
        const AccelerationStructure = 1<<29;
/// Represents all machine learning network dispatch operations.
        #[doc(alias = "MTLStageMachineLearning")]
        const MachineLearning = 1<<30;
/// Convenience mask representing all stages of GPU work.
        #[doc(alias = "MTLStageAll")]
        const All = NSIntegerMax as _;
    }
}

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

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

extern_protocol!(
    /// MTLCommandEncoder is the common interface for objects that write commands into MTLCommandBuffers.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtlcommandencoder?language=objc)
    pub unsafe trait MTLCommandEncoder: NSObjectProtocol {
        #[cfg(feature = "MTLDevice")]
        /// The device this resource was created against.
        #[unsafe(method(device))]
        #[unsafe(method_family = none)]
        fn device(&self) -> Retained<ProtocolObject<dyn MTLDevice>>;

        /// A string to help identify this object.
        #[unsafe(method(label))]
        #[unsafe(method_family = none)]
        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)]
        fn setLabel(&self, label: Option<&NSString>);

        /// Declare that all command generation from this encoder is complete, and detach from the MTLCommandBuffer.
        #[unsafe(method(endEncoding))]
        #[unsafe(method_family = none)]
        fn endEncoding(&self);

        /// Encodes a consumer barrier on work you commit to the same command queue.
        ///
        /// Encode a barrier that guarantees that any subsequent work you encode in the current command encoder that corresponds
        /// to the `beforeStages` stages doesn't proceed until Metal completes all work prior to the current command encoder
        /// corresponding to the `afterQueueStages` stages, completes.
        ///
        /// Metal can reorder the exact point where it applies the barrier, so use this method for synchronizing between different passes.
        ///
        /// If you need to synchronize work within a pass that you encode with an instance of a subclass of ``MTLCommandEncoder``,
        /// use memory barriers instead. For subclasses of ``MTL4CommandEncoder``, use encoder barriers.
        ///
        /// You can specify `afterQueueStages` and `beforeStages` that contain ``MTLStages`` unrelated to the current command
        /// encoder.
        ///
        /// - Parameters:
        /// - afterQueueStages: ``MTLStages`` mask that represents the stages of work to wait for.
        /// This argument applies to work corresponding to these stages you
        /// encode in prior command encoders, and not for the current encoder.
        /// - beforeStages:     ``MTLStages`` mask that represents the stages of work that wait.
        /// This argument applies to work you encode in the current command encoder.
        #[unsafe(method(barrierAfterQueueStages:beforeStages:))]
        #[unsafe(method_family = none)]
        fn barrierAfterQueueStages_beforeStages(
            &self,
            after_queue_stages: MTLStages,
            before_stages: MTLStages,
        );

        /// Inserts a debug string into the command buffer.  This does not change any API behavior, but can be useful when debugging.
        #[unsafe(method(insertDebugSignpost:))]
        #[unsafe(method_family = none)]
        fn insertDebugSignpost(&self, string: &NSString);

        /// Push a new named string onto a stack of string labels.
        #[unsafe(method(pushDebugGroup:))]
        #[unsafe(method_family = none)]
        fn pushDebugGroup(&self, string: &NSString);

        /// Pop the latest named string off of the stack.
        #[unsafe(method(popDebugGroup))]
        #[unsafe(method_family = none)]
        fn popDebugGroup(&self);
    }
);
