//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::ops::Range;

use core::ffi::c_float;
use core::ptr::NonNull;
use objc2::encode::{Encode, Encoding, RefEncode};
use objc2::runtime::ProtocolObject;
use objc2::{Message, extern_protocol, msg_send};
use objc2_foundation::{NSInteger, NSRange};

use crate::*;

/// Custom render pass options you specify at encoder creation time.
///
/// Use these options to implement parallel encoding of render passes across multiple CPU threads by providing these
/// values to the `options` parameter of ``MTL4CommandBuffer/renderCommandEncoderWithDescriptor:options:`` and
/// observing these requirements:
///
/// 1. Commit all command encoders together in an array you provide to ``MTL4CommandQueue/commit:count:`` or ``MTL4CommandQueue/commit:count:options:``
/// 2. The first command buffer in the array contains a render pass that you start with option ``MTL4RenderEncoderOptionSuspending``
/// 3. The last command buffer in the array contains the same render pass that you start with option ``MTL4RenderEncoderOptionResuming``
/// 4. All intermediate command buffers between the first and last in the array contain the same render pass that you
/// start with both ``MTL4RenderEncoderOptionResuming`` and ``MTL4RenderEncoderOptionSuspending`` options.
/// 5. The sequence of render passes, in submission order, doesn't intermix with compute, blit, acceleration structure
/// or machine learning encoding.
/// 6. A command buffer shouldn't contain a render pass that you start with option ``MTL4RenderEncoderOptionSuspending`` if
/// it already contains a render pass that you start with option ``MTL4RenderEncoderOptionResuming``.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtl4renderencoderoptions?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct MTL4RenderEncoderOptions(pub usize);
bitflags::bitflags! {
    impl MTL4RenderEncoderOptions: usize {
/// Declares that this render pass doesn't suspend nor resume.
        #[doc(alias = "MTL4RenderEncoderOptionNone")]
        const None = 0;
/// Configures the render pass as *suspending*.
///
/// Pass this option to ``MTL4CommandBuffer/renderCommandEncoderWithDescriptor:options:`` to specify that Metal can
/// stitch the work a render command encoder encodes with a subsequent "resuming" render command encoder.
        #[doc(alias = "MTL4RenderEncoderOptionSuspending")]
        const Suspending = 1<<0;
/// Configures the render pass to as *resuming*.
///
/// Pass this option to ``MTL4CommandBuffer/renderCommandEncoderWithDescriptor:options:`` to specify that Metal can
/// stitch the work a render command encoder encodes with a prior "suspending" render command encoder.
        #[doc(alias = "MTL4RenderEncoderOptionResuming")]
        const Resuming = 1<<1;
    }
}

unsafe impl Encode for MTL4RenderEncoderOptions {
    const ENCODING: Encoding = usize::ENCODING;
}

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

extern_protocol!(
    /// Encodes a render pass into a command buffer, including all its draw calls and configuration.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtl4rendercommandencoder?language=objc)
    pub unsafe trait MTL4RenderCommandEncoder: MTL4CommandEncoder {
        /// Sets the width of a tile for this render pass.
        #[unsafe(method(tileWidth))]
        #[unsafe(method_family = none)]
        fn tile_width(&self) -> usize;

        /// Sets the height of a tile for this render pass.
        #[unsafe(method(tileHeight))]
        #[unsafe(method_family = none)]
        fn tile_height(&self) -> usize;

        /// Sets the mapping from logical shader color output to physical render pass color attachments.
        ///
        /// Use this method to define how the physical color attachments you specify via ``MTL4RenderPassDescriptor/colorAttachments``
        /// map to the logical color output the fragment shader writes to.
        ///
        /// To use this feature, make sure to set ``MTL4RenderPassDescriptor/supportColorAttachmentMapping`` to
        /// <doc
        /// ://com.apple.documentation/documentation/swift/true>.
        ///
        /// - Parameter mapping: Mapping from logical shader outputs to physical outputs.
        #[unsafe(method(setColorAttachmentMap:))]
        #[unsafe(method_family = none)]
        fn set_color_attachment_map(
            &self,
            mapping: Option<&MTLLogicalToPhysicalColorAttachmentMap>,
        );

        /// Configures this encoder with a render pipeline state that applies to your subsequent draw commands.
        ///
        /// - Parameter pipelineState: a non-`nil` ``MTLRenderPipelineState`` instance.
        #[unsafe(method(setRenderPipelineState:))]
        #[unsafe(method_family = none)]
        fn set_render_pipeline_state(
            &self,
            pipeline_state: &ProtocolObject<dyn MTLRenderPipelineState>,
        );

        /// Sets the viewport which that transforms vertices from normalized device coordinates to window coordinates.
        ///
        /// Metal clips fragments that lie outside this viewport, and optionally clamps fragments outside of z-near/z-far range
        /// depending on the value you assign to ``setDepthClipMode:``.
        ///
        /// - Parameter viewport: ``MTLViewport`` to set.
        #[unsafe(method(setViewport:))]
        #[unsafe(method_family = none)]
        fn set_viewport(&self, viewport: MTLViewport);

        /// Sets an array of viewports to transform vertices from normalized device coordinates to window coordinates.
        ///
        /// Metal clips fragments that lie outside of the viewport, and optionally clamps fragments outside of z-near/z-far range,
        /// depending on the value you assign to ``setDepthClipMode:``.
        ///
        /// Metal selects the viewport to use from the `[[ viewport_array_index ]]` attribute you specify in the pipeline
        /// state's vertex shader function in the Metal Shading Language.
        ///
        /// - Parameters:
        /// - viewports: Array of ``MTLViewport`` instances.
        /// - count: Number of ``MTLViewport`` instances in the array.
        ///
        /// # Safety
        ///
        /// `viewports` must be a valid pointer.
        #[unsafe(method(setViewports:count:))]
        #[unsafe(method_family = none)]
        fn set_viewports_count(&self, viewports: NonNull<MTLViewport>, count: usize);

        /// Sets the vertex amplification count and its view mapping for each amplification ID.
        ///
        /// Each view mapping element describes how to route the corresponding amplification ID to a specific viewport and
        /// render target array index by using offsets from the base array index provided by the `[[ render_target_array_index ]]`
        /// and/or `[[ viewport_array_index ]]` output attributes in the vertex shader. This allows Metal to route each amplified
        /// vertex to a different `[[ render_target_array_index ]]` and `[[ viewport_array_index ]]`, even though you can't
        /// directly amplify these attributes.
        ///
        /// - Parameters:
        /// - count: The number of outputs to create. The maximum value is `2`.
        /// - viewMappings: Array of ``MTLVertexAmplificationViewMapping`` instances. Each instance provides
        /// per-output offsets to a specific render target and viewport.
        ///
        /// # Safety
        ///
        /// `view_mappings` must be a valid pointer or null.
        #[unsafe(method(setVertexAmplificationCount:viewMappings:))]
        #[unsafe(method_family = none)]
        fn set_vertex_amplification_count_view_mappings(
            &self,
            count: usize,
            view_mappings: *const MTLVertexAmplificationViewMapping,
        );

        /// Controls whether Metal culls front facing primitives, back facing primitives, or culls no primitives at all.
        ///
        /// - Parameter cullMode: ``MTLCullMode`` to set.
        #[unsafe(method(setCullMode:))]
        #[unsafe(method_family = none)]
        fn set_cull_mode(&self, cull_mode: MTLCullMode);

        /// Controls the behavior for fragments outside of the near or far planes.
        ///
        /// - Parameter depthClipMode: ``MTLDepthClipMode`` to set.
        #[unsafe(method(setDepthClipMode:))]
        #[unsafe(method_family = none)]
        fn set_depth_clip_mode(&self, depth_clip_mode: MTLDepthClipMode);

        /// Configures the adjustments a render pass applies to depth values from fragment shader functions
        /// by a scaling factor and bias.
        ///
        /// - Parameters:
        /// - depthBias: A constant bias the render pipeline applies to all fragments.
        /// - slopeScale: A bias coefficient that scales with the depth of the primitive relative to the camera.
        /// - clamp: A value that limits the bias value the render pipeline can apply to a fragment.
        /// Pass a positive or negative value to limit the largest magnitude of a positive
        /// or negative bias, respectively. Set this value to `0` to disable bias clamping.
        #[unsafe(method(setDepthBias:slopeScale:clamp:))]
        #[unsafe(method_family = none)]
        fn set_depth_bias_slope_scale_clamp(
            &self,
            depth_bias: c_float,
            slope_scale: c_float,
            clamp: c_float,
        );

        /// Configures the minimum and maximum bounds for depth bounds testing.
        ///
        /// The render command encoder disables depth bounds testing by default.
        /// The render command encoder also disables depth bounds testing when all of the following properties equal a specific value:
        /// - The `minBound` property is equal to `0.0f`.
        /// - The `maxBound` property is equal to `1.0f`.
        /// Both `minBound` and `maxBound` need to be within `[0.0f, 1.0f]`, and `minBound` needs to be less than or equal to `maxBound`.
        /// - Parameters:
        /// - minBound: A minimum bound for depth testing, which discards fragments with a stored depth that is less than `minBound`.
        /// - maxBound: A maximum bound for depth testing, which discards fragments with a stored depth that is greater than `maxBound`.
        #[unsafe(method(setDepthTestMinBound:maxBound:))]
        #[unsafe(method_family = none)]
        fn set_depth_test_min_bound_max_bound(&self, min_bound: c_float, max_bound: c_float);

        /// Sets a scissor rectangle to discard fragments outside a specific area.
        ///
        /// Metal performs a scissor test and discards all fragments outside of the scissor rect.
        ///
        /// - Parameter rect: ``MTLScissorRect`` rectangle to specify. This rectangle needs to lie completely
        /// within the current render attachment.
        #[unsafe(method(setScissorRect:))]
        #[unsafe(method_family = none)]
        fn set_scissor_rect(&self, rect: MTLScissorRect);

        /// Sets an array of scissor rectangles for a fragment scissor test.
        ///
        /// Metal uses the specific scissor rectangle corresponding to the index you specify via the `[[ viewport_array_index ]]`
        /// output attribute of the vertex shader function in the Metal Shading Language, discarding all fragments outside of
        /// the scissor rect.
        ///
        /// - Parameters:
        /// - scissorRects: Array of ``MTLScissorRect`` structures.
        /// - count: Number of ``MTLScissorRect`` structures in the array.
        ///
        /// # Safety
        ///
        /// `scissor_rects` must be a valid pointer.
        #[unsafe(method(setScissorRects:count:))]
        #[unsafe(method_family = none)]
        fn set_scissor_rects_count(
            &self,
            scissor_rects: NonNull<MTLScissorRect>,
            count: usize,
        );

        /// Configures how subsequent draw commands rasterize triangle and triangle strip primitives.
        ///
        /// - Parameter fillMode:``MTLTriangleFillMode`` the render pass applies to draw commands that
        /// rasterize triangles or triangle strips.
        #[unsafe(method(setTriangleFillMode:))]
        #[unsafe(method_family = none)]
        fn set_triangle_fill_mode(&self, fill_mode: MTLTriangleFillMode);

        /// Configures each pixel component value, including alpha, for the render pipeline’s constant blend color.
        ///
        /// - Parameters:
        /// - red: A value for the red component for the blend color constant.
        /// - green: A value for the green component for the blend color constant.
        /// - blue: A value for the blue component for the blend color constant.
        /// - alpha: A value for the alpha component for the blend color constant.
        #[unsafe(method(setBlendColorRed:green:blue:alpha:))]
        #[unsafe(method_family = none)]
        fn set_blend_color_red_green_blue_alpha(
            &self,
            red: c_float,
            green: c_float,
            blue: c_float,
            alpha: c_float,
        );

        /// Configures this encoder with a depth stencil state that applies to your subsequent draw commands.
        ///
        /// - Parameter depthStencilState: the ``MTLDepthStencilState`` instance to set.
        #[unsafe(method(setDepthStencilState:))]
        #[unsafe(method_family = none)]
        fn set_depth_stencil_state(
            &self,
            depth_stencil_state: Option<&ProtocolObject<dyn MTLDepthStencilState>>,
        );

        /// Configures this encoder with a reference value for stencil testing.
        ///
        /// The render pipeline applies this reference value to both front-facing and back-facing primitives.
        ///
        /// - Parameter referenceValue: A stencil test comparison value.
        #[unsafe(method(setStencilReferenceValue:))]
        #[unsafe(method_family = none)]
        fn set_stencil_reference_value(&self, reference_value: u32);

        /// Configures the encoder with different stencil test reference values for front-facing and back-facing primitives.
        ///
        /// The render pipeline applies `frontReferenceValue` to front-facing primitives and `backReferenceValue` to
        /// back-facing primitives.
        ///
        /// - Parameters:
        /// - frontReferenceValue: A stencil test comparison value the render pipeline applies
        /// to front-facing primitives.
        /// - backReferenceValue: A stencil test comparison value the render pipeline applies
        /// to back-facing primitives.
        #[unsafe(method(setStencilFrontReferenceValue:backReferenceValue:))]
        #[unsafe(method_family = none)]
        fn set_stencil_front_reference_value_back_reference_value(
            &self,
            front_reference_value: u32,
            back_reference_value: u32,
        );

        /// Configures a visibility test for Metal to run, and the destination for any results it generates.
        ///
        /// You use the `mode` parameter to enable or disable the visibility test, and determine if it produces a boolean
        /// response for passing fragments, or if it counts the number of fragments.
        ///
        /// - Parameters:
        /// - mode: A ``MTLVisibilityResultMode`` that configures which visibility test results
        /// the render pass saves to a buffer, or disables visibility testing.
        /// - offset: A location, in bytes, relative to the start of
        /// ``MTL4RenderPassDescriptor/visibilityResultBuffer`` The GPU stores
        /// the result of a visibility test at `offset`, which needs to be a multiple of `8`.
        #[unsafe(method(setVisibilityResultMode:offset:))]
        #[unsafe(method_family = none)]
        fn set_visibility_result_mode_offset(
            &self,
            mode: MTLVisibilityResultMode,
            offset: usize,
        );

        /// Configures the store action for a color attachment.
        ///
        /// - Parameters:
        /// - storeAction: A store action for the color attachment that
        /// can’t be ``MTLStoreAction/MTLStoreActionUnknown``.
        /// - colorAttachmentIndex: The index of a color attachment.
        #[unsafe(method(setColorStoreAction:atIndex:))]
        #[unsafe(method_family = none)]
        fn set_color_store_action_at_index(
            &self,
            store_action: MTLStoreAction,
            color_attachment_index: usize,
        );

        /// Configures the store action for the depth attachment.
        ///
        /// - Parameter storeAction: A store action for the depth attachment that
        /// can’t be ``MTLStoreAction/MTLStoreActionUnknown``.
        #[unsafe(method(setDepthStoreAction:))]
        #[unsafe(method_family = none)]
        fn set_depth_store_action(&self, store_action: MTLStoreAction);

        /// Configures the store action for the stencil attachment.
        ///
        /// - Parameter storeAction: A store action for the stencil attachment that
        /// can’t be ``MTLStoreAction/MTLStoreActionUnknown``.
        #[unsafe(method(setStencilStoreAction:))]
        #[unsafe(method_family = none)]
        fn set_stencil_store_action(&self, store_action: MTLStoreAction);

        /// Encodes a draw command that renders an instance of a geometric primitive.
        ///
        /// This command assigns each vertex a unique `vertex_id` value that increases from `vertexStart` through
        /// `(vertexStart + vertexCount - 1)`.
        ///
        /// Your vertex shader function can use this value to uniquely identify each vertex.
        ///
        /// - Parameters:
        /// - primitiveType: A ``MTLPrimitiveType`` representing how the command interprets vertex argument data.
        /// - vertexStart: The lowest value the command passes to your vertex shader function’s parameter with the
        /// `[[vertex_id]]` attribute.
        /// - vertexCount: An integer that represents the number of vertices of `primitiveType` the command draws.
        #[unsafe(method(drawPrimitives:vertexStart:vertexCount:))]
        #[unsafe(method_family = none)]
        fn draw_primitives_vertex_start_vertex_count(
            &self,
            primitive_type: MTLPrimitiveType,
            vertex_start: usize,
            vertex_count: usize,
        );

        /// Encodes a draw command that renders multiple instances of a geometric primitive.
        ///
        /// The command assigns each vertex a unique `vertex_id` value within its drawing instance
        /// that increases from `vertexStart` through `(vertexStart + vertexCount - 1)`.
        ///
        /// Additionally, the command assigns each drawing instance a unique `instance_id` value that increases
        /// from `0` through `(instanceCount - 1)`.
        ///
        /// Your vertex shader can use the `vertex_id` value to uniquely identify each vertex in each drawing instance, and the
        /// `instance_id` value to identify which instance that vertex belongs to.
        ///
        /// - Parameters:
        /// - primitiveType: A ``MTLPrimitiveType`` represents how the command interprets vertex argument data.
        /// - vertexStart: The lowest value the command passes to your vertex shader function’s parameter with
        /// the `vertex_id` attribute.
        /// - vertexCount: An integer that represents the number of vertices of `primitiveType` the command draws.
        /// - instanceCount: An integer that represents the number of times the command draws `primitiveType` primitives
        /// with `vertexCount` vertices.
        #[unsafe(method(drawPrimitives:vertexStart:vertexCount:instanceCount:))]
        #[unsafe(method_family = none)]
        fn draw_primitives_vertex_start_vertex_count_instance_count(
            &self,
            primitive_type: MTLPrimitiveType,
            vertex_start: usize,
            vertex_count: usize,
            instance_count: usize,
        );

        /// Encodes a draw command that renders multiple instances of a geometric primitive,
        /// starting with a custom instance identification number.
        ///
        /// The command assigns each vertex a unique `vertex_id` value within its drawing instance
        /// that increases from `vertexStart` through `(vertexStart + vertexCount - 1)`.
        ///
        /// Additionally, the command assigns each drawing instance a unique `instance_id` value that increases
        /// from `baseInstance` through `(baseInstance + instanceCount - 1)`.
        ///
        /// Your vertex shader can use the `vertex_id` value to uniquely identify each vertex in each drawing instance, and the
        /// `instance_id` value to identify which instance that vertex belongs to.
        ///
        /// - Parameters:
        /// - primitiveType: A ``MTLPrimitiveType``  representing how the command interprets vertex argument data.
        /// - vertexStart: The lowest value the command passes to your vertex shader function’s parameter with
        /// the `vertex_id` attribute.
        /// - vertexCount: An integer that represents the number of vertices of `primitiveType` the command draws.
        /// - instanceCount: An integer that represents the number of times the command draws `primitiveType`
        /// with `vertexCount` vertices.
        /// - baseInstance: The lowest value the command passes to your vertex shader function’s parameter with
        /// the `instance_id` attribute.
        #[unsafe(method(drawPrimitives:vertexStart:vertexCount:instanceCount:baseInstance:))]
        #[unsafe(method_family = none)]
        fn draw_primitives_vertex_start_vertex_count_instance_count_base_instance(
            &self,
            primitive_type: MTLPrimitiveType,
            vertex_start: usize,
            vertex_count: usize,
            instance_count: usize,
            base_instance: usize,
        );

        /// Encodes a draw command that renders an instance of a geometric primitive with indexed vertices.
        ///
        /// Use this method to perform indexed drawing, where an index buffer determines how Metal assembles primitives.
        ///
        /// Metal imposes some restrictions on the index buffer's address, which needs to be 2- or 4-byte aligned, and its length
        /// in bytes, which needs to be a multiple of 2 or 4, depending on whether the format of the index is
        /// ``MTLIndexType/MTLIndexTypeUInt16`` or ``MTLIndexType/MTLIndexTypeUInt32``.
        ///
        /// Use an instance of ``MTLResidencySet`` to mark residency of the index buffer the `indexBuffer` parameter references.
        ///
        /// - Parameters:
        /// - primitiveType: A ``MTLPrimitiveType`` representing how the command interprets vertex argument data.
        /// - indexCount: An integer that represents the number of vertices the command reads from `indexBuffer`.
        /// - indexType: A ``MTLIndexType`` instance that represents the index format.
        /// - indexBuffer: GPUAddress of a ``MTLBuffer`` instance that contains `indexCount` indices of `indexType` format.
        /// You are responsible for ensuring this address is aligned to 2 bytes if the `indexType` format is
        /// ``MTLIndexType/MTLIndexTypeUInt16``, and aligned to 4 bytes if the format is
        /// ``MTLIndexType/MTLIndexTypeUInt32``.
        /// - indexBufferLength: An integer that represents the length of `indexBuffer`, in bytes. You are responsible for
        /// ensuring this this size is a multiple of 2 if the `indexType` format is ``MTLIndexType/MTLIndexTypeUInt16``,
        /// and a multiple of 4 if the format is ``MTLIndexType/MTLIndexTypeUInt32``.
        /// If this draw call causes Metal to read indices at or beyond the `indexBufferLength`, Metal
        /// continues to execute them assigning a value of `0` to the `vertex_id` attribute.
        #[unsafe(method(drawIndexedPrimitives:indexCount:indexType:indexBuffer:indexBufferLength:))]
        #[unsafe(method_family = none)]
        fn draw_indexed_primitives_index_count_index_type_index_buffer_index_buffer_length(
            &self,
            primitive_type: MTLPrimitiveType,
            index_count: usize,
            index_type: MTLIndexType,
            index_buffer: MTLGPUAddress,
            index_buffer_length: usize,
        );

        /// Encodes a draw command that renders multiple instances of a geometric primitive with indexed vertices.
        ///
        /// Use this method to perform instanced indexed drawing, where an index buffer determines how Metal assembles primitives.
        ///
        /// The command assigns each drawing instance a unique `instance_id` value that increases
        /// from `0` through `(instanceCount - 1)`. Your shader can use this value to identify which
        /// instance the vertex belongs to.
        ///
        /// Metal imposes some restrictions on the index buffer's address, which needs to be 2- or 4-byte aligned, and its length
        /// in bytes, which needs to be a multiple of 2 or 4, depending on whether the format of the index is
        /// ``MTLIndexType/MTLIndexTypeUInt16`` or ``MTLIndexType/MTLIndexTypeUInt32``.
        ///
        /// Use an instance of ``MTLResidencySet`` to mark residency of the index buffer the `indexBuffer` parameter references.
        ///
        /// - Parameters:
        /// - primitiveType: A ``MTLPrimitiveType`` representing how the command interprets vertex argument data.
        /// - indexCount: An integer that represents the number of vertices the command reads from `indexBuffer`.
        /// - indexType: A ``MTLIndexType`` instance that represents the index format.
        /// - indexBuffer: GPUAddress of a ``MTLBuffer`` instance that contains `indexCount` indices of `indexType` format.
        /// You are responsible for ensuring this address is aligned to 2 bytes if the `indexType` format is
        /// ``MTLIndexType/MTLIndexTypeUInt16``, and aligned to 4 bytes if the format is
        /// ``MTLIndexType/MTLIndexTypeUInt32``.
        /// - indexBufferLength: An integer that represents the length of `indexBuffer`, in bytes. You are responsible for
        /// ensuring this this size is a multiple of 2 if the `indexType` format is ``MTLIndexType/MTLIndexTypeUInt16``,
        /// and a multiple of 4 if the format is ``MTLIndexType/MTLIndexTypeUInt32``.
        /// Metal disregards this value and assigns `0` to the `vertex_id` attribute for all primitives that
        /// require loading indices at a byte offset of `indexBufferLength` or greater.
        /// - instanceCount: An integer that represents the number of times the command draws `primitiveType` with `indexCount`
        /// vertices.
        #[unsafe(method(drawIndexedPrimitives:indexCount:indexType:indexBuffer:indexBufferLength:instanceCount:))]
        #[unsafe(method_family = none)]
        fn draw_indexed_primitives_index_count_index_type_index_buffer_index_buffer_length_instance_count(
            &self,
            primitive_type: MTLPrimitiveType,
            index_count: usize,
            index_type: MTLIndexType,
            index_buffer: MTLGPUAddress,
            index_buffer_length: usize,
            instance_count: usize,
        );

        /// Encodes a draw command that renders multiple instances of a geometric primitive with indexed vertices,
        /// starting with a custom vertex and instance.
        ///
        /// Use this method to perform instanced indexed drawing, where an index buffer determines how Metal assembles primitives
        /// whilst customizing the base vertex and base instance value Metal passes to the vertex shader function.
        ///
        /// The command assigns each drawing instance a unique `instance_id` value that increases
        /// from `baseInstance` through `(baseInstance + instanceCount - 1)`. Your shader can use this value
        /// to identify which instance the vertex belongs to.
        ///
        /// Metal imposes some restrictions on the index buffer's address, which needs to be 2- or 4-byte aligned, and its length
        /// in bytes, which needs to be a multiple of 2 or 4, depending on whether the format of the index is
        /// ``MTLIndexType/MTLIndexTypeUInt16`` or ``MTLIndexType/MTLIndexTypeUInt32``.
        ///
        /// Use an instance of ``MTLResidencySet`` to mark residency of the index buffer the `indexBuffer` parameter references.
        ///
        /// - Parameters:
        /// - primitiveType: A ``MTLPrimitiveType`` representing how the command interprets vertex argument data.
        /// - indexCount: An integer that represents the number of vertices the command reads from `indexBuffer`.
        /// - indexType: A ``MTLIndexType`` instance that represents the index format.
        /// - indexBuffer: GPUAddress of a ``MTLBuffer`` instance that contains `indexCount` indices of `indexType` format.
        /// You are responsible for ensuring this address is aligned to 2 bytes if the `indexType` format is
        /// ``MTLIndexType/MTLIndexTypeUInt16``, and aligned to 4 bytes if the format is
        /// ``MTLIndexType/MTLIndexTypeUInt32``.
        /// - indexBufferLength: An integer that represents the length of `indexBuffer`, in bytes. You are responsible for
        /// ensuring this this size is a multiple of 2 if the `indexType` format is ``MTLIndexType/MTLIndexTypeUInt16``,
        /// and a multiple of 4 if the format is ``MTLIndexType/MTLIndexTypeUInt32``.
        /// If this draw call causes Metal to read indices at or beyond the `indexBufferLength`, Metal
        /// continues to execute them assigning a value of `0` to the `vertex_id` attribute.
        /// - instanceCount: An integer that represents the number of times the command draws `primitiveType` with `indexCount`
        /// vertices.
        /// - baseVertex: The lowest value the command passes to your vertex shader functions’s parameter with the `vertex_id`
        /// attribute. Metal disregards this value and assigns `0` to the `vertex_id` attribute for all
        /// primitives that require loading indices at a byte offset of `indexBufferLength` or greater.
        /// - baseInstance: The lowest value the command passes to your vertex shader’s parameter with the `instance_id` attribute.
        #[unsafe(method(drawIndexedPrimitives:indexCount:indexType:indexBuffer:indexBufferLength:instanceCount:baseVertex:baseInstance:))]
        #[unsafe(method_family = none)]
        fn draw_indexed_primitives_index_count_index_type_index_buffer_index_buffer_length_instance_count_base_vertex_base_instance(
            &self,
            primitive_type: MTLPrimitiveType,
            index_count: usize,
            index_type: MTLIndexType,
            index_buffer: MTLGPUAddress,
            index_buffer_length: usize,
            instance_count: usize,
            base_vertex: NSInteger,
            base_instance: usize,
        );

        /// Encodes a draw command that renders multiple instances of a geometric primitive with indirect arguments.
        ///
        /// When you use this function, Metal reads the parameters to the draw command from an ``MTLBuffer`` instance,
        /// allowing you to implement a GPU-driven workflow where a compute pipeline state determines the draw arguments.
        ///
        /// You are responsible for ensuring that the address of the indirect buffer you provide to this method has 4-byte
        /// alignment.
        ///
        /// Because this is a non-indexed draw call, Metal interprets the contents of the indirect buffer to match the
        /// layout of struct ``MTLDrawPrimitivesIndirectArguments``.
        ///
        /// Use an instance of ``MTLResidencySet`` to mark residency of the indirect buffer that the `indirectBuffer` parameter
        /// references.
        ///
        /// - Parameters:
        /// - primitiveType: A ``MTLPrimitiveType`` representing how the command interprets vertex argument data.
        /// - indirectBuffer: GPUAddress of a ``MTLBuffer`` instance with data that matches the layout of the
        /// ``MTLDrawPrimitivesIndirectArguments`` structure. You are responsible for ensuring that the
        /// alignment of this address is 4 bytes.
        #[unsafe(method(drawPrimitives:indirectBuffer:))]
        #[unsafe(method_family = none)]
        fn draw_primitives_indirect_buffer(
            &self,
            primitive_type: MTLPrimitiveType,
            indirect_buffer: MTLGPUAddress,
        );

        /// Encodes a draw command that renders multiple instances of a geometric primitive with indexed vertices
        /// and indirect arguments.
        ///
        /// When you use this function, Metal reads the parameters to the draw command from an ``MTLBuffer`` instance,
        /// allowing you to implement a GPU-driven workflow where a compute pipeline state determines the draw arguments.
        ///
        /// Because this is an indexed draw call, Metal interprets the contents of the indirect buffer to match the
        /// layout of struct ``MTLDrawIndexedPrimitivesIndirectArguments``, which includes `indexStart` and `indexCount`
        /// members, denoting a range within the index buffer you provide in the `indexBuffer` parameter.
        ///
        /// The range of indices within the `indexBuffer` form the primitives Metal draws.
        ///
        /// Metal imposes some restrictions on the index buffer's address, which needs to be 2- or 4-byte aligned, and its length
        /// in bytes, which needs to be a multiple of 2 or 4, depending on whether the format of the index is
        /// ``MTLIndexType/MTLIndexTypeUInt16`` or ``MTLIndexType/MTLIndexTypeUInt32``.
        ///
        /// Similarly, you are responsible for ensuring the indirect buffer's address has 4-byte alignment.
        ///
        /// Use an instance of ``MTLResidencySet`` to mark residency of the indirect buffer that the `indirectBuffer` parameter
        /// references, and of the index buffer the `indexBuffer` parameter references.
        ///
        /// - Parameters:
        /// - primitiveType: A ``MTLPrimitiveType`` representing how the command interprets vertex argument data.
        /// - indexType: A ``MTLIndexType`` instance that represents the index format.
        /// - indexBuffer: GPUAddress of a ``MTLBuffer`` instance that contains `indexCount` indices of `indexType` format.
        /// You are responsible for ensuring this address is aligned to 2 bytes if the `indexType` format is
        /// ``MTLIndexType/MTLIndexTypeUInt16``, and aligned to 4 bytes if the format is
        /// ``MTLIndexType/MTLIndexTypeUInt32``.
        /// - indexBufferLength: An integer that represents the length of `indexBuffer`, in bytes. You are responsible for
        /// ensuring this this size is a multiple of 2 if the `indexType` format is ``MTLIndexType/MTLIndexTypeUInt16``,
        /// and a multiple of 4 if the format is ``MTLIndexType/MTLIndexTypeUInt32``.
        /// If this draw call causes Metal to read indices at or beyond the `indexBufferLength`, Metal
        /// continues to execute them assigning a value of `0` to the `vertex_id` attribute.
        /// - indirectBuffer: GPUAddress of an ``MTLBuffer`` instance with data that matches the layout of the
        /// ``MTLDrawIndexedPrimitivesIndirectArguments`` structure. This address requires 4-byte alignment.
        #[unsafe(method(drawIndexedPrimitives:indexType:indexBuffer:indexBufferLength:indirectBuffer:))]
        #[unsafe(method_family = none)]
        fn draw_indexed_primitives_index_type_index_buffer_index_buffer_length_indirect_buffer(
            &self,
            primitive_type: MTLPrimitiveType,
            index_type: MTLIndexType,
            index_buffer: MTLGPUAddress,
            index_buffer_length: usize,
            indirect_buffer: MTLGPUAddress,
        );

        /// Encodes a command that runs a range of commands from an indirect command buffer.
        ///
        /// - Parameters:
        /// - indirectCommandBuffer: A ``MTLIndirectCommandBuffer`` instance containing other commands that the current command runs.
        /// - executionRange: A span of integers that represent the command entries in the buffer that the current command runs.
        /// Encodes a command that runs an indirect range of commands from an indirect command buffer.
        ///
        /// Use this method to indicate to Metal the span of indices in the command buffer to execute indirectly via an
        /// ``MTLBuffer`` instance you provide in the `indirectRangeBuffer` parameter. This allows you to calculate the
        /// span of commands Metal executes in the GPU timeline, enabling GPU-driven workflows.
        ///
        /// Metal requires that the contents of this buffer match the layout of struct ``MTLIndirectCommandBufferExecutionRange``,
        /// which specifies a location and a length within the indirect command buffer. You are responsible for ensuring the
        /// address of this buffer has 4-byte alignment.
        ///
        /// Use an instance of ``MTLResidencySet`` to mark residency of the indirect buffer that the `indirectRangeBuffer`
        /// parameter references.
        ///
        /// - Parameters:
        /// - indirectCommandBuffer: A ``MTLIndirectCommandBuffer`` instance that contains other commands
        /// the current command runs.
        /// - indirectRangeBuffer: GPUAddress of a ``MTLBuffer`` instance with data that matches the layout of the
        /// ``MTLIndirectCommandBufferExecutionRange`` structure. This address requires 4-byte alignment.
        #[unsafe(method(executeCommandsInBuffer:indirectBuffer:))]
        #[unsafe(method_family = none)]
        fn execute_commands_in_buffer_indirect_buffer(
            &self,
            indirect_command_buffer: &ProtocolObject<dyn MTLIndirectCommandBuffer>,
            indirect_range_buffer: MTLGPUAddress,
        );

        /// Configures the size of a threadgroup memory buffer for a threadgroup argument in the object shader function.
        ///
        /// - Parameters:
        /// - length: The size of the threadgroup memory, in bytes.
        /// - index: An integer that corresponds to the index of the argument you annotate with attribute `[[threadgroup(index)]]`
        /// in the shader function.
        #[unsafe(method(setObjectThreadgroupMemoryLength:atIndex:))]
        #[unsafe(method_family = none)]
        fn set_object_threadgroup_memory_length_at_index(&self, length: usize, index: usize);

        /// Encodes a draw command that invokes a mesh shader and, optionally, an object shader with a grid of threadgroups.
        ///
        /// - Parameters:
        /// - threadgroupsPerGrid: A ``MTLSize`` instance that represents the number of threadgroups for each grid dimension.
        /// - threadsPerObjectThreadgroup: A ``MTLSize`` instance that represents the number of threads in an object
        /// shader threadgroup, if applicable.
        /// - threadsPerMeshThreadgroup: A ``MTLSize`` instance that represents the number of threads in a mesh shader
        /// threadgroup.
        #[unsafe(method(drawMeshThreadgroups:threadsPerObjectThreadgroup:threadsPerMeshThreadgroup:))]
        #[unsafe(method_family = none)]
        fn draw_mesh_threadgroups_threads_per_object_threadgroup_threads_per_mesh_threadgroup(
            &self,
            threadgroups_per_grid: MTLSize,
            threads_per_object_threadgroup: MTLSize,
            threads_per_mesh_threadgroup: MTLSize,
        );

        /// Encodes a draw command that invokes a mesh shader and, optionally, an object shader with a grid of threads.
        ///
        /// - Parameters:
        /// - threadsPerGrid: A ``MTLSize`` instance that represents the number of threads for each grid dimension.
        /// For mesh shaders, the command rounds the value down to the nearest multiple of
        /// `threadsPerMeshThreadgroup` for each dimension. For object shaders, the value doesn’t
        /// need to be a multiple of `threadsPerObjectThreadgroup`.
        /// - threadsPerObjectThreadgroup: A ``MTLSize`` instance that represents the number of threads in an object
        /// shader threadgroup, if applicable.
        /// - threadsPerMeshThreadgroup: A ``MTLSize`` instance that represents the number of threads in a mesh shader
        /// threadgroup.
        #[unsafe(method(drawMeshThreads:threadsPerObjectThreadgroup:threadsPerMeshThreadgroup:))]
        #[unsafe(method_family = none)]
        fn draw_mesh_threads_threads_per_object_threadgroup_threads_per_mesh_threadgroup(
            &self,
            threads_per_grid: MTLSize,
            threads_per_object_threadgroup: MTLSize,
            threads_per_mesh_threadgroup: MTLSize,
        );

        /// Encodes a draw command that invokes a mesh shader and, optionally, an object shader with indirect arguments.
        ///
        /// This method enables you to determine the number of threadgroups per grid indirectly, in the GPU timeline.
        /// Metal expects this buffer's contents to match the layout of structure ``MTLDispatchThreadgroupsIndirectArguments``.
        /// You are responsible for ensuring the address of this buffer has 4-byte alignment.
        ///
        /// Use an instance of ``MTLResidencySet`` to mark residency of the indirect buffer that the `indirectBuffer` parameter
        /// references.
        ///
        /// - Parameters:
        /// - indirectBuffer: GPUAddress of an ``MTLBuffer`` instance with data that matches the layout of the
        /// ``MTLDispatchThreadgroupsIndirectArguments`` structure. This address requires 4-byte alignment.
        /// - threadsPerObjectThreadgroup: A ``MTLSize`` instance that represents the number of threads in an object
        /// shader threadgroup, if applicable.
        /// - threadsPerMeshThreadgroup: A ``MTLSize`` instance that represents the number of threads in a mesh shader
        /// threadgroup.
        #[unsafe(method(drawMeshThreadgroupsWithIndirectBuffer:threadsPerObjectThreadgroup:threadsPerMeshThreadgroup:))]
        #[unsafe(method_family = none)]
        fn draw_mesh_threadgroups_with_indirect_buffer_threads_per_object_threadgroup_threads_per_mesh_threadgroup(
            &self,
            indirect_buffer: MTLGPUAddress,
            threads_per_object_threadgroup: MTLSize,
            threads_per_mesh_threadgroup: MTLSize,
        );

        /// Encodes a command that invokes a tile shader function from the encoder’s current tile render pipeline state.
        ///
        /// - Parameter threadsPerTile: A ``MTLSize`` instance that represents the number of threads the render pass uses per tile.
        /// Set the size’s ``MTLSize/width`` and ``MTLSize/height`` properties to values that are less
        /// than or equal to ``tileWidth`` and ``tileHeight``, respectively. Some GPU families
        /// only support square tile dispatches and require the same value for width and height.
        /// Set ``MTLSize/depth`` to `1`.
        #[unsafe(method(dispatchThreadsPerTile:))]
        #[unsafe(method_family = none)]
        fn dispatch_threads_per_tile(&self, threads_per_tile: MTLSize);

        /// Configures the size of a threadgroup memory buffer for a threadgroup argument in the fragment and tile shader functions.
        ///
        /// - Parameters:
        /// - length: The size of the threadgroup memory, in bytes.
        /// - offset: An integer that represents the location, in bytes, from the start of the threadgroup memory buffer
        /// at `index` where the threadgroup memory begins.
        /// - index: An integer that corresponds to the index of the argument you annotate with attribute `[[threadgroup(index)]]`
        /// in the shader function.
        #[unsafe(method(setThreadgroupMemoryLength:offset:atIndex:))]
        #[unsafe(method_family = none)]
        fn set_threadgroup_memory_length_offset_at_index(
            &self,
            length: usize,
            offset: usize,
            index: usize,
        );

        /// Associates an argument table with a set of render stages.
        ///
        /// Metal takes a snapshot of the resources in the argument table when you encode a draw, dispatch, or execute command.
        /// This snapshot becomes available to the `stages` you specify to this method.
        ///
        /// - Parameters:
        /// - argumentTable: ``MTL4ArgumentTable`` to set.
        /// - stages: A ``MTLRenderStages`` bitmask that specifies the shader stages with visibility over the table.
        #[unsafe(method(setArgumentTable:atStages:))]
        #[unsafe(method_family = none)]
        fn set_argument_table_at_stages(
            &self,
            argument_table: &ProtocolObject<dyn MTL4ArgumentTable>,
            stages: MTLRenderStages,
        );

        /// Configures the vertex winding order that determines which face of a geometric primitive is the front one.
        ///
        /// - Parameter frontFacingWinding: A ``MTLWinding`` value that determines which side of a primitive the render pipeline
        /// interprets as front facing.
        #[unsafe(method(setFrontFacingWinding:))]
        #[unsafe(method_family = none)]
        fn set_front_facing_winding(&self, front_facing_winding: MTLWinding);

        /// Writes a GPU timestamp into the given ``MTL4CounterHeap`` at `index` after `stage` completes.
        ///
        /// This command only guarantees all draws prior to this command are complete when Metal writes the timestamp into
        /// the counter heap you provide in the `counterHeap` parameter. The timestamp may also include subsequent operations.
        ///
        /// If you call this method before any draw calls, Metal writes a timestamp before the stage you specify in the
        /// `stage` parameter begins.
        ///
        /// - Parameters:
        /// - granularity: a ``MTL4TimestampGranularity`` hint.
        /// - stage: ``MTLRenderStages`` that need to complete before Metal writes the timestamp. This may also include later
        /// stages that are related, for example ``MTLRenderStages/MTLRenderStageMesh`` may include
        /// ``MTLRenderStages/MTLRenderStageVertex``.
        /// - counterHeap: ``MTL4CounterHeap`` into which Metal writes timestamps.
        /// - index: The index value into which Metal writes this timestamp.
        #[unsafe(method(writeTimestampWithGranularity:afterStage:intoHeap:atIndex:))]
        #[unsafe(method_family = none)]
        fn write_timestamp_with_granularity_after_stage_into_heap_at_index(
            &self,
            granularity: MTL4TimestampGranularity,
            stage: MTLRenderStages,
            counter_heap: &ProtocolObject<dyn MTL4CounterHeap>,
            index: usize,
        );
    }
);

pub trait MTL4RenderCommandEncoderExt: MTL4RenderCommandEncoder + Message {
    /// Encodes a command that runs a range of commands from an indirect command buffer.
    ///
    /// - Parameters:
    /// - indirectCommandBuffer: A ``MTLIndirectCommandBuffer`` instance containing other commands that the current command runs.
    /// - executionRange: A span of integers that represent the command entries in the buffer that the current command runs.
    fn execute_commands_in_buffer_with_range(
        &self,
        indirect_command_buffer: &ProtocolObject<dyn MTLIndirectCommandBuffer>,
        execution_range: Range<usize>,
    ) {
        let execution_range = NSRange {
            location: execution_range.start,
            length: execution_range.end.saturating_sub(execution_range.start),
        };
        unsafe {
            let _: () = msg_send![
                self,
                executeCommandsInBuffer: indirect_command_buffer,
                withRange: execution_range
            ];
        }
    }
}

impl<T: MTL4RenderCommandEncoder + Message> MTL4RenderCommandEncoderExt for T {}
