//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// mtl_render_utils.h:
//    Defines the class interface for RenderUtils, which contains many utility functions and shaders
//    for converting, blitting, copying as well as generating data, and many more.
//

#ifndef LIBANGLE_RENDERER_METAL_MTL_RENDER_UTILS_H_
#define LIBANGLE_RENDERER_METAL_MTL_RENDER_UTILS_H_

#import <Metal/Metal.h>

#include "libANGLE/angletypes.h"
#include "libANGLE/renderer/metal/RenderTargetMtl.h"
#include "libANGLE/renderer/metal/mtl_command_buffer.h"
#include "libANGLE/renderer/metal/mtl_context_device.h"
#include "libANGLE/renderer/metal/mtl_state_cache.h"
#include "libANGLE/renderer/metal/shaders/constants.h"

namespace rx
{

class BufferMtl;
class ContextMtl;
class DisplayMtl;
class VisibilityBufferOffsetsMtl;

namespace mtl
{

struct ClearRectParams
{
    ClearRectParams() { clearWriteMaskArray.fill(MTLColorWriteMaskAll); }

    Optional<ClearColorValue> clearColor;
    Optional<float> clearDepth;
    Optional<uint32_t> clearStencil;

    WriteMaskArray clearWriteMaskArray;

    const mtl::Format *colorFormat = nullptr;
    gl::Extents dstTextureSize;

    // Only clear enabled buffers
    gl::DrawBufferMask enabledBuffers;
    gl::Rectangle clearArea;

    bool flipY = false;
};

struct NormalizedCoords
{
    NormalizedCoords();
    NormalizedCoords(float x, float y, float width, float height, const gl::Rectangle &rect);
    NormalizedCoords(const gl::Rectangle &rect, const gl::Extents &extents);
    float v[4];
};

struct BlitParams
{
    gl::Extents dstTextureSize;
    gl::Rectangle dstRect;
    gl::Rectangle dstScissorRect;
    // Destination texture needs to have viewport Y flipped?
    // The difference between this param and unpackFlipY is that unpackFlipY is from
    // glCopyImageCHROMIUM()/glBlitFramebuffer(), and dstFlipY controls whether the final viewport
    // needs to be flipped when drawing to destination texture. It is possible to combine the two
    // flags before passing to RenderUtils. However, to avoid duplicated works, just pass the two
    // flags to RenderUtils, they will be combined internally by RenderUtils logic.
    bool dstFlipY = false;
    bool dstFlipX = false;

    TextureRef src;
    MipmapNativeLevel srcLevel = kZeroNativeMipLevel;
    uint32_t srcLayer          = 0;

    // Source rectangle:
    // NOTE: if srcYFlipped=true, this rectangle will be converted internally to flipped rect before
    // blitting.
    NormalizedCoords srcNormalizedCoords;

    bool srcYFlipped = false;  // source texture has data flipped in Y direction
    bool unpackFlipX = false;  // flip texture data copying process in X direction
    bool unpackFlipY = false;  // flip texture data copying process in Y direction
};

struct ColorBlitParams : public BlitParams
{
    ColorBlitParams() {}

    gl::DrawBufferMask enabledBuffers;
    GLenum filter               = GL_NEAREST;
    bool unpackPremultiplyAlpha = false;
    bool unpackUnmultiplyAlpha  = false;
    bool dstLuminance           = false;
};

struct DepthStencilBlitParams : public BlitParams
{
    TextureRef srcStencil;
};

// Stencil blit via an intermediate buffer. NOTE: source depth texture parameter is ignored.
// See DepthStencilBlitUtils::blitStencilViaCopyBuffer()
struct StencilBlitViaBufferParams : public DepthStencilBlitParams
{
    StencilBlitViaBufferParams();
    StencilBlitViaBufferParams(const DepthStencilBlitParams &src);

    TextureRef dstStencil;
    MipmapNativeLevel dstStencilLevel = kZeroNativeMipLevel;
    uint32_t dstStencilLayer          = 0;
    bool dstPackedDepthStencilFormat  = false;
};

struct TriFanOrLineLoopFromArrayParams
{
    uint32_t firstVertex;
    uint32_t vertexCount;
    BufferRef dstBuffer;
    // Must be multiples of kIndexBufferOffsetAlignment
    uint32_t dstOffset;
};

struct IndexConversionParams
{

    gl::DrawElementsType srcType;
    uint32_t indexCount;
    const BufferRef &srcBuffer;
    uint32_t srcOffset;
    const BufferRef &dstBuffer;
    // Must be multiples of kIndexBufferOffsetAlignment
    uint32_t dstOffset;
    bool primitiveRestartEnabled = false;
};

struct IndexGenerationParams
{
    gl::DrawElementsType srcType;
    GLsizei indexCount;
    const void *indices;
    BufferRef dstBuffer;
    uint32_t dstOffset;
    bool primitiveRestartEnabled = false;
};

struct CopyPixelsCommonParams
{
    BufferRef buffer;
    uint32_t bufferStartOffset = 0;
    uint32_t bufferRowPitch    = 0;

    TextureRef texture;
};

struct CopyPixelsFromBufferParams : CopyPixelsCommonParams
{
    uint32_t bufferDepthPitch = 0;

    // z offset is:
    //  - slice index if texture is array.
    //  - depth if texture is 3d.
    gl::Box textureArea;
};

struct CopyPixelsToBufferParams : CopyPixelsCommonParams
{
    gl::Rectangle textureArea;
    MipmapNativeLevel textureLevel = kZeroNativeMipLevel;
    uint32_t textureSliceOrDeph    = 0;
    bool reverseTextureRowOrder;
};

struct VertexFormatConvertParams
{
    BufferRef srcBuffer;
    uint32_t srcBufferStartOffset = 0;
    uint32_t srcStride            = 0;
    uint32_t srcDefaultAlphaData  = 0;  // casted as uint

    BufferRef dstBuffer;
    uint32_t dstBufferStartOffset = 0;
    uint32_t dstStride            = 0;
    uint32_t dstComponents        = 0;

    uint32_t vertexCount = 0;
};

// Utils class for clear & blitting
class ClearUtils final : angle::NonCopyable
{
  public:
    ClearUtils() = delete;
    ClearUtils(const std::string &fragmentShaderName);
    ClearUtils(const ClearUtils &src);

    void onDestroy();

    // Clear current framebuffer
    angle::Result clearWithDraw(const gl::Context *context,
                                RenderCommandEncoder *cmdEncoder,
                                const ClearRectParams &params);

  private:
    void ensureRenderPipelineStateCacheInitialized(ContextMtl *ctx, uint32_t numColorAttachments);

    angle::Result setupClearWithDraw(const gl::Context *context,
                                     RenderCommandEncoder *cmdEncoder,
                                     const ClearRectParams &params);
    id<MTLDepthStencilState> getClearDepthStencilState(const gl::Context *context,
                                                       const ClearRectParams &params);
    id<MTLRenderPipelineState> getClearRenderPipelineState(const gl::Context *context,
                                                           RenderCommandEncoder *cmdEncoder,
                                                           const ClearRectParams &params);

    const std::string mFragmentShaderName;

    // Render pipeline cache for clear with draw:
    std::array<RenderPipelineCache, kMaxRenderTargets + 1> mClearRenderPipelineCache;
};

class ColorBlitUtils final : angle::NonCopyable
{
  public:
    ColorBlitUtils() = delete;
    ColorBlitUtils(const std::string &fragmentShaderName);
    ColorBlitUtils(const ColorBlitUtils &src);

    void onDestroy();

    // Blit texture data to current framebuffer
    angle::Result blitColorWithDraw(const gl::Context *context,
                                    RenderCommandEncoder *cmdEncoder,
                                    const ColorBlitParams &params);

  private:
    void ensureRenderPipelineStateCacheInitialized(ContextMtl *ctx,
                                                   uint32_t numColorAttachments,
                                                   int alphaPremultiplyType,
                                                   int sourceTextureType,
                                                   RenderPipelineCache *cacheOut);

    angle::Result setupColorBlitWithDraw(const gl::Context *context,
                                         RenderCommandEncoder *cmdEncoder,
                                         const ColorBlitParams &params);

    id<MTLRenderPipelineState> getColorBlitRenderPipelineState(const gl::Context *context,
                                                               RenderCommandEncoder *cmdEncoder,
                                                               const ColorBlitParams &params);

    const std::string mFragmentShaderName;

    // Blit with draw pipeline caches:
    // First array dimension: number of outputs.
    // Second array dimension: source texture type (2d, ms, array, 3d, etc)
    using ColorBlitRenderPipelineCacheArray =
        std::array<std::array<RenderPipelineCache, mtl_shader::kTextureTypeCount>,
                   kMaxRenderTargets>;
    ColorBlitRenderPipelineCacheArray mBlitRenderPipelineCache;
    ColorBlitRenderPipelineCacheArray mBlitPremultiplyAlphaRenderPipelineCache;
    ColorBlitRenderPipelineCacheArray mBlitUnmultiplyAlphaRenderPipelineCache;
};

class DepthStencilBlitUtils final : angle::NonCopyable
{
  public:
    void onDestroy();

    angle::Result blitDepthStencilWithDraw(const gl::Context *context,
                                           RenderCommandEncoder *cmdEncoder,
                                           const DepthStencilBlitParams &params);

    // Blit stencil data using intermediate buffer. This function is used on devices with no
    // support for direct stencil write in shader. Thus an intermediate buffer storing copied
    // stencil data is needed.
    // NOTE: this function shares the params struct with depth & stencil blit, but depth texture
    // parameter is not used. This function will break existing render pass.
    angle::Result blitStencilViaCopyBuffer(const gl::Context *context,
                                           const StencilBlitViaBufferParams &params);

  private:
    void ensureRenderPipelineStateCacheInitialized(ContextMtl *ctx,
                                                   int sourceDepthTextureType,
                                                   int sourceStencilTextureType,
                                                   RenderPipelineCache *cacheOut);

    angle::Result setupDepthStencilBlitWithDraw(const gl::Context *context,
                                                RenderCommandEncoder *cmdEncoder,
                                                const DepthStencilBlitParams &params);

    id<MTLRenderPipelineState> getDepthStencilBlitRenderPipelineState(
        const gl::Context *context,
        RenderCommandEncoder *cmdEncoder,
        const DepthStencilBlitParams &params);

    id<MTLComputePipelineState> getStencilToBufferComputePipelineState(
        ContextMtl *ctx,
        const StencilBlitViaBufferParams &params);

    std::array<RenderPipelineCache, mtl_shader::kTextureTypeCount> mDepthBlitRenderPipelineCache;
    std::array<RenderPipelineCache, mtl_shader::kTextureTypeCount> mStencilBlitRenderPipelineCache;
    std::array<std::array<RenderPipelineCache, mtl_shader::kTextureTypeCount>,
               mtl_shader::kTextureTypeCount>
        mDepthStencilBlitRenderPipelineCache;

    std::array<AutoObjCPtr<id<MTLComputePipelineState>>, mtl_shader::kTextureTypeCount>
        mStencilBlitToBufferComPipelineCache;

    // Intermediate buffer for storing copied stencil data. Used when device doesn't support
    // writing stencil in shader.
    BufferRef mStencilCopyBuffer;
};

// util class for generating index buffer
class IndexGeneratorUtils final : angle::NonCopyable
{
  public:
    void onDestroy();

    angle::Result convertIndexBufferGPU(ContextMtl *contextMtl,
                                        const IndexConversionParams &params);
    angle::Result generateTriFanBufferFromArrays(ContextMtl *contextMtl,
                                                 const TriFanOrLineLoopFromArrayParams &params);
    // Generate triangle fan index buffer for glDrawElements().
    angle::Result generateTriFanBufferFromElementsArray(ContextMtl *contextMtl,
                                                        const IndexGenerationParams &params,
                                                        uint32_t *indicesGenerated);

    angle::Result generateLineLoopBufferFromArrays(ContextMtl *contextMtl,
                                                   const TriFanOrLineLoopFromArrayParams &params);
    angle::Result generateLineLoopLastSegment(ContextMtl *contextMtl,
                                              uint32_t firstVertex,
                                              uint32_t lastVertex,
                                              const BufferRef &dstBuffer,
                                              uint32_t dstOffset);
    // Generate line loop index buffer for glDrawElements().
    // Destination buffer must have at least 2x the number of original indices if primitive restart
    // is enabled.
    angle::Result generateLineLoopBufferFromElementsArray(ContextMtl *contextMtl,
                                                          const IndexGenerationParams &params,
                                                          uint32_t *indicesGenerated);
    // Generate line loop's last segment index buffer for glDrawElements().
    // NOTE: this function assumes primitive restart is not enabled.
    angle::Result generateLineLoopLastSegmentFromElementsArray(ContextMtl *contextMtl,
                                                               const IndexGenerationParams &params);

    angle::Result generatePrimitiveRestartPointsBuffer(ContextMtl *contextMtl,
                                                       const IndexGenerationParams &params,
                                                       size_t *indicesGenerated);

    angle::Result generatePrimitiveRestartLinesBuffer(ContextMtl *contextMtl,
                                                      const IndexGenerationParams &params,
                                                      size_t *indicesGenerated);

    angle::Result generatePrimitiveRestartTrianglesBuffer(ContextMtl *contextMtl,
                                                          const IndexGenerationParams &params,
                                                          size_t *indicesGenerated);

  private:
    // Index generator compute pipelines:
    //  - First dimension: index type.
    //  - second dimension: source buffer's offset is aligned or not.
    using IndexConversionPipelineArray =
        std::array<std::array<AutoObjCPtr<id<MTLComputePipelineState>>, 2>,
                   angle::EnumSize<gl::DrawElementsType>()>;

    AutoObjCPtr<id<MTLComputePipelineState>> getIndexConversionPipeline(
        ContextMtl *contextMtl,
        gl::DrawElementsType srcType,
        uint32_t srcOffset);
    // Get compute pipeline to generate tri fan/line loop index for glDrawElements().
    AutoObjCPtr<id<MTLComputePipelineState>> getIndicesFromElemArrayGeneratorPipeline(
        ContextMtl *contextMtl,
        gl::DrawElementsType srcType,
        uint32_t srcOffset,
        NSString *shaderName,
        IndexConversionPipelineArray *pipelineCacheArray);
    // Defer loading of compute pipeline to generate tri fan index for glDrawArrays().
    void ensureTriFanFromArrayGeneratorInitialized(ContextMtl *contextMtl);
    // Defer loading of compute pipeline to generate line loop index for glDrawArrays().
    void ensureLineLoopFromArrayGeneratorInitialized(ContextMtl *contextMtl);

    angle::Result generateTriFanBufferFromElementsArrayGPU(
        ContextMtl *contextMtl,
        gl::DrawElementsType srcType,
        uint32_t indexCount,
        const BufferRef &srcBuffer,
        uint32_t srcOffset,
        const BufferRef &dstBuffer,
        // Must be multiples of kIndexBufferOffsetAlignment
        uint32_t dstOffset);
    angle::Result generateTriFanBufferFromElementsArrayCPU(ContextMtl *contextMtl,
                                                           const IndexGenerationParams &params,
                                                           uint32_t *indicesGenerated);

    angle::Result generateLineLoopBufferFromElementsArrayGPU(
        ContextMtl *contextMtl,
        gl::DrawElementsType srcType,
        uint32_t indexCount,
        const BufferRef &srcBuffer,
        uint32_t srcOffset,
        const BufferRef &dstBuffer,
        // Must be multiples of kIndexBufferOffsetAlignment
        uint32_t dstOffset);
    angle::Result generateLineLoopBufferFromElementsArrayCPU(ContextMtl *contextMtl,
                                                             const IndexGenerationParams &params,
                                                             uint32_t *indicesGenerated);
    angle::Result generateLineLoopLastSegmentFromElementsArrayCPU(
        ContextMtl *contextMtl,
        const IndexGenerationParams &params);

    angle::Result generatePrimitiveRestartBuffer(ContextMtl *contextMtl,
                                                 unsigned numVerticesPerPrimitive,
                                                 const IndexGenerationParams &params,
                                                 size_t *indicesGenerated);

    IndexConversionPipelineArray mIndexConversionPipelineCaches;

    IndexConversionPipelineArray mTriFanFromElemArrayGeneratorPipelineCaches;
    AutoObjCPtr<id<MTLComputePipelineState>> mTriFanFromArraysGeneratorPipeline;

    IndexConversionPipelineArray mLineLoopFromElemArrayGeneratorPipelineCaches;
    AutoObjCPtr<id<MTLComputePipelineState>> mLineLoopFromArraysGeneratorPipeline;
};

// Util class for handling visibility query result
class VisibilityResultUtils final : angle::NonCopyable
{
  public:
    void onDestroy();

    void combineVisibilityResult(ContextMtl *contextMtl,
                                 bool keepOldValue,
                                 const VisibilityBufferOffsetsMtl &renderPassResultBufOffsets,
                                 const BufferRef &renderPassResultBuf,
                                 const BufferRef &finalResultBuf);

  private:
    AutoObjCPtr<id<MTLComputePipelineState>> getVisibilityResultCombPipeline(ContextMtl *contextMtl,
                                                                             bool keepOldValue);
    // Visibility combination compute pipeline:
    // - 0: This compute pipeline only combine the new values and discard old value.
    // - 1: This compute pipeline keep the old value and combine with new values.
    std::array<AutoObjCPtr<id<MTLComputePipelineState>>, 2> mVisibilityResultCombPipelines;
};

// Util class for handling mipmap generation
class MipmapUtils final : angle::NonCopyable
{
  public:
    void onDestroy();

    // Compute based mipmap generation.
    angle::Result generateMipmapCS(ContextMtl *contextMtl,
                                   const TextureRef &srcTexture,
                                   bool sRGBMipmap,
                                   NativeTexLevelArray *mipmapOutputViews);

  private:
    void ensure3DMipGeneratorPipelineInitialized(ContextMtl *contextMtl);
    void ensure2DMipGeneratorPipelineInitialized(ContextMtl *contextMtl);
    void ensure2DArrayMipGeneratorPipelineInitialized(ContextMtl *contextMtl);
    void ensureCubeMipGeneratorPipelineInitialized(ContextMtl *contextMtl);

    // Mipmaps generating compute pipeline:
    AutoObjCPtr<id<MTLComputePipelineState>> m3DMipGeneratorPipeline;
    AutoObjCPtr<id<MTLComputePipelineState>> m2DMipGeneratorPipeline;
    AutoObjCPtr<id<MTLComputePipelineState>> m2DArrayMipGeneratorPipeline;
    AutoObjCPtr<id<MTLComputePipelineState>> mCubeMipGeneratorPipeline;
};

// Util class for handling pixels copy between buffers and textures
class CopyPixelsUtils final : angle::NonCopyable
{
  public:
    CopyPixelsUtils() = default;
    CopyPixelsUtils(const std::string &readShaderName, const std::string &writeShaderName);
    CopyPixelsUtils(const CopyPixelsUtils &src);

    void onDestroy();

    angle::Result unpackPixelsFromBufferToTexture(ContextMtl *contextMtl,
                                                  const angle::Format &srcAngleFormat,
                                                  const CopyPixelsFromBufferParams &params);
    angle::Result packPixelsFromTextureToBuffer(ContextMtl *contextMtl,
                                                const angle::Format &dstAngleFormat,
                                                const CopyPixelsToBufferParams &params);

  private:
    AutoObjCPtr<id<MTLComputePipelineState>> getPixelsCopyPipeline(ContextMtl *contextMtl,
                                                                   const angle::Format &angleFormat,
                                                                   const TextureRef &texture,
                                                                   bool bufferWrite);
    // Copy pixels between buffer and texture compute pipelines:
    // - First dimension: pixel format.
    // - Second dimension: texture type * (buffer read/write flag)
    using PixelsCopyPipelineArray = std::array<
        std::array<AutoObjCPtr<id<MTLComputePipelineState>>, mtl_shader::kTextureTypeCount * 2>,
        angle::kNumANGLEFormats>;
    PixelsCopyPipelineArray mPixelsCopyPipelineCaches;

    const std::string mReadShaderName;
    const std::string mWriteShaderName;
};

// Util class for handling vertex format conversion on GPU
class VertexFormatConversionUtils final : angle::NonCopyable
{
  public:
    void onDestroy();

    // Convert vertex format to float. Compute shader version.
    angle::Result convertVertexFormatToFloatCS(ContextMtl *contextMtl,
                                               const angle::Format &srcAngleFormat,
                                               const VertexFormatConvertParams &params);
    // Convert vertex format to float. Vertex shader version. This version should be used if
    // a render pass is active and we don't want to break it. Explicit memory barrier must be
    // supported.
    angle::Result convertVertexFormatToFloatVS(const gl::Context *context,
                                               RenderCommandEncoder *renderEncoder,
                                               const angle::Format &srcAngleFormat,
                                               const VertexFormatConvertParams &params);
    // Expand number of components per vertex's attribute (or just simply copy components between
    // buffers with different stride and offset)
    angle::Result expandVertexFormatComponentsCS(ContextMtl *contextMtl,
                                                 const angle::Format &srcAngleFormat,
                                                 const VertexFormatConvertParams &params);
    angle::Result expandVertexFormatComponentsVS(const gl::Context *context,
                                                 RenderCommandEncoder *renderEncoder,
                                                 const angle::Format &srcAngleFormat,
                                                 const VertexFormatConvertParams &params);

  private:
    void ensureComponentsExpandComputePipelineCreated(ContextMtl *contextMtl);
    AutoObjCPtr<id<MTLRenderPipelineState>> getComponentsExpandRenderPipeline(
        ContextMtl *contextMtl,
        RenderCommandEncoder *renderEncoder);

    AutoObjCPtr<id<MTLComputePipelineState>> getFloatConverstionComputePipeline(
        ContextMtl *contextMtl,
        const angle::Format &srcAngleFormat);

    AutoObjCPtr<id<MTLRenderPipelineState>> getFloatConverstionRenderPipeline(
        ContextMtl *contextMtl,
        RenderCommandEncoder *renderEncoder,
        const angle::Format &srcAngleFormat);

    template <typename EncoderType, typename PipelineType>
    angle::Result setupCommonConvertVertexFormatToFloat(ContextMtl *contextMtl,
                                                        EncoderType cmdEncoder,
                                                        const PipelineType &pipeline,
                                                        const angle::Format &srcAngleFormat,
                                                        const VertexFormatConvertParams &params);
    template <typename EncoderType, typename PipelineType>
    angle::Result setupCommonExpandVertexFormatComponents(ContextMtl *contextMtl,
                                                          EncoderType cmdEncoder,
                                                          const PipelineType &pipeline,
                                                          const angle::Format &srcAngleFormat,
                                                          const VertexFormatConvertParams &params);

    using ConvertToFloatCompPipelineArray =
        std::array<AutoObjCPtr<id<MTLComputePipelineState>>, angle::kNumANGLEFormats>;
    using ConvertToFloatRenderPipelineArray =
        std::array<RenderPipelineCache, angle::kNumANGLEFormats>;

    ConvertToFloatCompPipelineArray mConvertToFloatCompPipelineCaches;
    ConvertToFloatRenderPipelineArray mConvertToFloatRenderPipelineCaches;

    AutoObjCPtr<id<MTLComputePipelineState>> mComponentsExpandCompPipeline;
    RenderPipelineCache mComponentsExpandRenderPipelineCache;
};

// RenderUtils: container class of various util classes above
class RenderUtils : public Context, angle::NonCopyable
{
  public:
    RenderUtils(DisplayMtl *display);
    ~RenderUtils() override;

    angle::Result initialize();
    void onDestroy();

    // Clear current framebuffer
    angle::Result clearWithDraw(const gl::Context *context,
                                RenderCommandEncoder *cmdEncoder,
                                const ClearRectParams &params);
    // Blit texture data to current framebuffer
    angle::Result blitColorWithDraw(const gl::Context *context,
                                    RenderCommandEncoder *cmdEncoder,
                                    const angle::Format &srcAngleFormat,
                                    const ColorBlitParams &params);
    // Same as above but blit the whole texture to the whole of current framebuffer.
    // This function assumes the framebuffer and the source texture have same size.
    angle::Result blitColorWithDraw(const gl::Context *context,
                                    RenderCommandEncoder *cmdEncoder,
                                    const angle::Format &srcAngleFormat,
                                    const TextureRef &srcTexture);
    angle::Result copyTextureWithDraw(const gl::Context *context,
                                      RenderCommandEncoder *cmdEncoder,
                                      const angle::Format &srcAngleFormat,
                                      const angle::Format &dstAngleFormat,
                                      const ColorBlitParams &params);

    angle::Result blitDepthStencilWithDraw(const gl::Context *context,
                                           RenderCommandEncoder *cmdEncoder,
                                           const DepthStencilBlitParams &params);
    // See DepthStencilBlitUtils::blitStencilViaCopyBuffer()
    angle::Result blitStencilViaCopyBuffer(const gl::Context *context,
                                           const StencilBlitViaBufferParams &params);

    // See IndexGeneratorUtils
    angle::Result convertIndexBufferGPU(ContextMtl *contextMtl,
                                        const IndexConversionParams &params);
    angle::Result generateTriFanBufferFromArrays(ContextMtl *contextMtl,
                                                 const TriFanOrLineLoopFromArrayParams &params);
    angle::Result generateTriFanBufferFromElementsArray(ContextMtl *contextMtl,
                                                        const IndexGenerationParams &params,
                                                        uint32_t *indicesGenerated);

    angle::Result generateLineLoopBufferFromArrays(ContextMtl *contextMtl,
                                                   const TriFanOrLineLoopFromArrayParams &params);
    angle::Result generateLineLoopLastSegment(ContextMtl *contextMtl,
                                              uint32_t firstVertex,
                                              uint32_t lastVertex,
                                              const BufferRef &dstBuffer,
                                              uint32_t dstOffset);
    angle::Result generateLineLoopBufferFromElementsArray(ContextMtl *contextMtl,
                                                          const IndexGenerationParams &params,
                                                          uint32_t *indicesGenerated);
    angle::Result generateLineLoopLastSegmentFromElementsArray(ContextMtl *contextMtl,
                                                               const IndexGenerationParams &params);

    void combineVisibilityResult(ContextMtl *contextMtl,
                                 bool keepOldValue,
                                 const VisibilityBufferOffsetsMtl &renderPassResultBufOffsets,
                                 const BufferRef &renderPassResultBuf,
                                 const BufferRef &finalResultBuf);

    // Compute based mipmap generation. Only possible for 3D texture for now.
    angle::Result generateMipmapCS(ContextMtl *contextMtl,
                                   const TextureRef &srcTexture,
                                   bool sRGBMipmap,
                                   NativeTexLevelArray *mipmapOutputViews);

    angle::Result unpackPixelsFromBufferToTexture(ContextMtl *contextMtl,
                                                  const angle::Format &srcAngleFormat,
                                                  const CopyPixelsFromBufferParams &params);
    angle::Result packPixelsFromTextureToBuffer(ContextMtl *contextMtl,
                                                const angle::Format &dstAngleFormat,
                                                const CopyPixelsToBufferParams &params);

    // See VertexFormatConversionUtils::convertVertexFormatToFloatCS()
    angle::Result convertVertexFormatToFloatCS(ContextMtl *contextMtl,
                                               const angle::Format &srcAngleFormat,
                                               const VertexFormatConvertParams &params);
    // See VertexFormatConversionUtils::convertVertexFormatToFloatVS()
    angle::Result convertVertexFormatToFloatVS(const gl::Context *context,
                                               RenderCommandEncoder *renderEncoder,
                                               const angle::Format &srcAngleFormat,
                                               const VertexFormatConvertParams &params);
    // See VertexFormatConversionUtils::expandVertexFormatComponentsCS()
    angle::Result expandVertexFormatComponentsCS(ContextMtl *contextMtl,
                                                 const angle::Format &srcAngleFormat,
                                                 const VertexFormatConvertParams &params);
    // See VertexFormatConversionUtils::expandVertexFormatComponentsVS()
    angle::Result expandVertexFormatComponentsVS(const gl::Context *context,
                                                 RenderCommandEncoder *renderEncoder,
                                                 const angle::Format &srcAngleFormat,
                                                 const VertexFormatConvertParams &params);

    angle::Result generatePrimitiveRestartPointsBuffer(ContextMtl *contextMtl,
                                                       const IndexGenerationParams &params,
                                                       size_t *indicesGenerated);
    angle::Result generatePrimitiveRestartLinesBuffer(ContextMtl *contextMtl,
                                                      const IndexGenerationParams &params,
                                                      size_t *indicesGenerated);
    angle::Result generatePrimitiveRestartTrianglesBuffer(ContextMtl *contextMtl,
                                                          const IndexGenerationParams &params,
                                                          size_t *indicesGenerated);

  private:
    // override ErrorHandler
    void handleError(GLenum error,
                     const char *file,
                     const char *function,
                     unsigned int line) override;
    void handleError(NSError *error,
                     const char *file,
                     const char *function,
                     unsigned int line) override;

    std::array<ClearUtils, angle::EnumSize<PixelType>()> mClearUtils;

    std::array<ColorBlitUtils, angle::EnumSize<PixelType>()> mColorBlitUtils;
    ColorBlitUtils mCopyTextureFloatToUIntUtils;

    DepthStencilBlitUtils mDepthStencilBlitUtils;
    IndexGeneratorUtils mIndexUtils;
    VisibilityResultUtils mVisibilityResultUtils;
    MipmapUtils mMipmapUtils;
    std::array<CopyPixelsUtils, angle::EnumSize<PixelType>()> mCopyPixelsUtils;
    VertexFormatConversionUtils mVertexFormatUtils;
};

}  // namespace mtl
}  // namespace rx

#endif /* LIBANGLE_RENDERER_METAL_MTL_RENDER_UTILS_H_ */
