/*
 * Copyright 2021 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/gpu/graphite/UniformManager.h"

#include "include/core/SkMatrix.h"
#include "include/private/SkHalf.h"
#include "include/private/base/SkAlign.h"
#include "include/private/base/SkTemplates.h"
#include "src/gpu/graphite/DrawTypes.h"
#include "src/gpu/graphite/PipelineData.h"
#include "src/gpu/graphite/Uniform.h"

// ensure that these types are the sizes the uniform data is expecting
static_assert(sizeof(int32_t) == 4);
static_assert(sizeof(float) == 4);
static_assert(sizeof(int16_t) == 2);
static_assert(sizeof(SkHalf) == 2);

namespace skgpu::graphite {

//////////////////////////////////////////////////////////////////////////////
template<typename BaseType>
static constexpr size_t tight_vec_size(int vecLength) {
    return sizeof(BaseType) * vecLength;
}

/**
 * From Section 7.6.2.2 "Standard Uniform Block Layout":
 *  1. If the member is a scalar consuming N basic machine units, the base alignment is N.
 *  2. If the member is a two- or four-component vector with components consuming N basic machine
 *     units, the base alignment is 2N or 4N, respectively.
 *  3. If the member is a three-component vector with components consuming N
 *     basic machine units, the base alignment is 4N.
 *  4. If the member is an array of scalars or vectors, the base alignment and array
 *     stride are set to match the base alignment of a single array element, according
 *     to rules (1), (2), and (3), and rounded up to the base alignment of a vec4. The
 *     array may have padding at the end; the base offset of the member following
 *     the array is rounded up to the next multiple of the base alignment.
 *  5. If the member is a column-major matrix with C columns and R rows, the
 *     matrix is stored identically to an array of C column vectors with R components each,
 *     according to rule (4).
 *  6. If the member is an array of S column-major matrices with C columns and
 *     R rows, the matrix is stored identically to a row of S × C column vectors
 *     with R components each, according to rule (4).
 *  7. If the member is a row-major matrix with C columns and R rows, the matrix
 *     is stored identically to an array of R row vectors with C components each,
 *     according to rule (4).
 *  8. If the member is an array of S row-major matrices with C columns and R
 *     rows, the matrix is stored identically to a row of S × R row vectors with C
 *    components each, according to rule (4).
 *  9. If the member is a structure, the base alignment of the structure is N, where
 *     N is the largest base alignment value of any of its members, and rounded
 *     up to the base alignment of a vec4. The individual members of this substructure are then
 *     assigned offsets by applying this set of rules recursively,
 *     where the base offset of the first member of the sub-structure is equal to the
 *     aligned offset of the structure. The structure may have padding at the end;
 *     the base offset of the member following the sub-structure is rounded up to
 *     the next multiple of the base alignment of the structure.
 * 10. If the member is an array of S structures, the S elements of the array are laid
 *     out in order, according to rule (9).
 */
template<typename BaseType, int RowsOrVecLength = 1, int Cols = 1>
struct Rules140 {
    /**
     * For an array of scalars or vectors this returns the stride between array elements. For
     * matrices or arrays of matrices this returns the stride between columns of the matrix. Note
     * that for single (non-array) scalars or vectors we don't require a stride.
     */
    static constexpr size_t Stride(int count) {
        SkASSERT(count >= 1 || count == graphite::Uniform::kNonArray);
        static_assert(RowsOrVecLength >= 1 && RowsOrVecLength <= 4);
        static_assert(Cols >= 1 && Cols <= 4);
        if (Cols != 1) {
            // This is a matrix or array of matrices. We return the stride between columns.
            SkASSERT(RowsOrVecLength > 1);
            return Rules140<BaseType, RowsOrVecLength>::Stride(Uniform::kNonArray);
        }

        // Get alignment of a single non-array vector of BaseType by Rule 1, 2, or 3.
        int n = RowsOrVecLength == 3 ? 4 : RowsOrVecLength;
        if (count == Uniform::kNonArray) {
            return n * sizeof(BaseType);
        }

        // Rule 4.

        // Alignment of vec4 by Rule 2.
        constexpr size_t kVec4Alignment = tight_vec_size<float>(4);
        size_t kElementAlignment = tight_vec_size<BaseType>(n);
        // Round kElementAlignment up to multiple of kVec4Alignment.
        size_t m = (kElementAlignment + kVec4Alignment - 1) / kVec4Alignment;
        return m * kVec4Alignment;
    }
};

/**
 * When using the std430 storage layout, shader storage blocks will be laid out in buffer storage
 * identically to uniform and shader storage blocks using the std140 layout, except that the base
 * alignment and stride of arrays of scalars and vectors in rule 4 and of structures in rule 9 are
 * not rounded up a multiple of the base alignment of a vec4.
 */
template<typename BaseType, int RowsOrVecLength = 1, int Cols = 1>
struct Rules430 {
    static constexpr size_t Stride(int count) {
        SkASSERT(count >= 1 || count == Uniform::kNonArray);
        static_assert(RowsOrVecLength >= 1 && RowsOrVecLength <= 4);
        static_assert(Cols >= 1 && Cols <= 4);

        if (Cols != 1) {
            // This is a matrix or array of matrices. We return the stride between columns.
            SkASSERT(RowsOrVecLength > 1);
            return Rules430<BaseType, RowsOrVecLength>::Stride(Uniform::kNonArray);
        }

        // Get alignment of a single non-array vector of BaseType by Rule 1, 2, or 3.
        int n = RowsOrVecLength == 3 ? 4 : RowsOrVecLength;
        if (count == Uniform::kNonArray) {
            return n * sizeof(BaseType);
        }

        // Rule 4 without the round up to a multiple of align-of vec4.
        return tight_vec_size<BaseType>(n);
    }
};

// The strides used here were derived from the rules we've imposed on ourselves in
// GrMtlPipelineStateDataManger. Everything is tight except 3-component which have the stride of
// their 4-component equivalents.
template<typename BaseType, int RowsOrVecLength = 1, int Cols = 1>
struct RulesMetal {
    static constexpr size_t Stride(int count) {
        SkASSERT(count >= 1 || count == Uniform::kNonArray);
        static_assert(RowsOrVecLength >= 1 && RowsOrVecLength <= 4);
        static_assert(Cols >= 1 && Cols <= 4);

        if (Cols != 1) {
            // This is a matrix or array of matrices. We return the stride between columns.
            SkASSERT(RowsOrVecLength > 1);
            return RulesMetal<BaseType, RowsOrVecLength>::Stride(Uniform::kNonArray);
        }

        // Get alignment of a single non-array vector of BaseType by Rule 1, 2, or 3.
        int n = RowsOrVecLength == 3 ? 4 : RowsOrVecLength;
        if (count == 0) {
            return n * sizeof(BaseType);
        }

        return tight_vec_size<BaseType>(n);
    }
};

template<template<typename BaseType, int RowsOrVecLength, int Cols> class Rules>
class Writer {
private:
    template <typename MemType, typename UniformType>
    static void CopyUniforms(void* dst, const void* src, int numUniforms) {
        if constexpr (std::is_same<MemType, UniformType>::value) {
            // Matching types--use memcpy.
            std::memcpy(dst, src, numUniforms * sizeof(MemType));
            return;
        }

        if constexpr (std::is_same<MemType, float>::value &&
                      std::is_same<UniformType, SkHalf>::value) {
            // Convert floats to half.
            const float* floatBits = static_cast<const float*>(src);
            SkHalf* halfBits = static_cast<SkHalf*>(dst);
            while (numUniforms-- > 0) {
                *halfBits++ = SkFloatToHalf(*floatBits++);
            }
            return;
        }

        if constexpr (std::is_same<MemType, int32_t>::value &&
                      std::is_same<UniformType, int16_t>::value) {
            // Convert ints to short.
            const int32_t* intBits = static_cast<const int32_t*>(src);
            int16_t* shortBits = static_cast<int16_t*>(dst);
            while (numUniforms-- > 0) {
                *shortBits++ = int16_t(*intBits++);
            }
            return;
        }

        SK_ABORT("implement conversion from MemType to UniformType");
    }

    template <typename MemType, typename UniformType, int RowsOrVecLength = 1, int Cols = 1>
    static uint32_t Write(void *dst, int n, const MemType src[]) {
        size_t stride = Rules<UniformType, RowsOrVecLength, Cols>::Stride(n);
        n = (n == Uniform::kNonArray) ? 1 : n;
        n *= Cols;

        // A null value for `dst` means that this method was called to calculate the size of the
        // write without actually copying data.
        if (dst) {
            if (stride == RowsOrVecLength * sizeof(UniformType)) {
                CopyUniforms<MemType, UniformType>(dst, src, n * RowsOrVecLength);
            } else {
                for (int i = 0; i < n; ++i) {
                    CopyUniforms<MemType, UniformType>(dst, src, RowsOrVecLength);
                    src += RowsOrVecLength;
                    dst = SkTAddOffset<void>(dst, stride);
                }
            }
        }

        return n * stride;
    }

    template <typename UniformType>
    static uint32_t WriteSkMatrices(void *dst, int n, const SkMatrix m[]) {
        // Stride() will give us the stride of each column, so mul by 3 to get matrix stride.
        size_t stride = 3 * Rules<UniformType, 3, 3>::Stride(1);
        n = std::max(n, 1);

        // A null value for `dst` means that this method was called to calculate the size of the
        // write without actually copying data.
        if (dst) {
            size_t offset = 0;
            for (int i = 0; i < n; ++i) {
                float mt[] = {
                        m[i].get(SkMatrix::kMScaleX),
                        m[i].get(SkMatrix::kMSkewY),
                        m[i].get(SkMatrix::kMPersp0),
                        m[i].get(SkMatrix::kMSkewX),
                        m[i].get(SkMatrix::kMScaleY),
                        m[i].get(SkMatrix::kMPersp1),
                        m[i].get(SkMatrix::kMTransX),
                        m[i].get(SkMatrix::kMTransY),
                        m[i].get(SkMatrix::kMPersp2),
                };
                Write<float, UniformType, 3, 3>(SkTAddOffset<void>(dst, offset), 1, mt);
                offset += stride;
            }
        }
        return n * stride;
    }

public:
    // If `dest` is a nullptr, then this method returns the size of the write without writing any
    // data.
    static uint32_t WriteUniform(SkSLType type,
                                 CType ctype,
                                 void *dest,
                                 int n,
                                 const void *src) {
        SkASSERT(n >= 1 || n == Uniform::kNonArray);
        switch (type) {
            case SkSLType::kShort:
                return Write<int32_t, int16_t>(dest, n, static_cast<const int32_t *>(src));

            case SkSLType::kShort2:
                return Write<int32_t, int16_t, 2>(dest, n, static_cast<const int32_t *>(src));

            case SkSLType::kShort3:
                return Write<int32_t, int16_t, 3>(dest, n, static_cast<const int32_t *>(src));

            case SkSLType::kShort4:
                return Write<int32_t, int16_t, 4>(dest, n, static_cast<const int32_t *>(src));

            case SkSLType::kInt:
                return Write<int32_t, int32_t>(dest, n, static_cast<const int32_t *>(src));

            case SkSLType::kInt2:
                return Write<int32_t, int32_t, 2>(dest, n, static_cast<const int32_t *>(src));

            case SkSLType::kInt3:
                return Write<int32_t, int32_t, 3>(dest, n, static_cast<const int32_t *>(src));

            case SkSLType::kInt4:
                return Write<int32_t, int32_t, 4>(dest, n, static_cast<const int32_t *>(src));

            case SkSLType::kHalf:
                return Write<float, SkHalf>(dest, n, static_cast<const float *>(src));

            case SkSLType::kFloat:
                return Write<float, float>(dest, n, static_cast<const float *>(src));

            case SkSLType::kHalf2:
                return Write<float, SkHalf, 2>(dest, n, static_cast<const float *>(src));

            case SkSLType::kFloat2:
                return Write<float, float, 2>(dest, n, static_cast<const float *>(src));

            case SkSLType::kHalf3:
                return Write<float, SkHalf, 3>(dest, n, static_cast<const float *>(src));

            case SkSLType::kFloat3:
                return Write<float, float, 3>(dest, n, static_cast<const float *>(src));

            case SkSLType::kHalf4:
                return Write<float, SkHalf, 4>(dest, n, static_cast<const float *>(src));

            case SkSLType::kFloat4:
                return Write<float, float, 4>(dest, n, static_cast<const float *>(src));

            case SkSLType::kHalf2x2:
                return Write<float, SkHalf, 2, 2>(dest, n, static_cast<const float *>(src));

            case SkSLType::kFloat2x2:
                return Write<float, float, 2, 2>(dest, n, static_cast<const float *>(src));

            case SkSLType::kHalf3x3:
                switch (ctype) {
                    case CType::kDefault:
                        return Write<float, SkHalf, 3, 3>(dest, n, static_cast<const float *>(src));
                    case CType::kSkMatrix:
                        return WriteSkMatrices<SkHalf>(dest, n, static_cast<const SkMatrix *>(src));
                }
                SkUNREACHABLE;

            case SkSLType::kFloat3x3:
                switch (ctype) {
                    case CType::kDefault:
                        return Write<float, float, 3, 3>(dest, n, static_cast<const float *>(src));
                    case CType::kSkMatrix:
                        return WriteSkMatrices<float>(dest, n, static_cast<const SkMatrix *>(src));
                }
                SkUNREACHABLE;

            case SkSLType::kHalf4x4:
                return Write<float, SkHalf, 4, 4>(dest, n, static_cast<const float *>(src));

            case SkSLType::kFloat4x4:
                return Write<float, float, 4, 4>(dest, n, static_cast<const float *>(src));

            default:
                SK_ABORT("Unexpected uniform type");
        }
    }
};

// To determine whether a current offset is aligned, we can just 'and' the lowest bits with the
// alignment mask. A value of 0 means aligned, any other value is how many bytes past alignment we
// are. This works since all alignments are powers of 2. The mask is always (alignment - 1).
static uint32_t sksltype_to_alignment_mask(SkSLType type) {
    switch (type) {
        case SkSLType::kInt:
        case SkSLType::kUInt:
        case SkSLType::kFloat:
            return 0x3;
        case SkSLType::kInt2:
        case SkSLType::kUInt2:
        case SkSLType::kFloat2:
            return 0x7;
        case SkSLType::kInt3:
        case SkSLType::kUInt3:
        case SkSLType::kFloat3:
        case SkSLType::kInt4:
        case SkSLType::kUInt4:
        case SkSLType::kFloat4:
            return 0xF;

        case SkSLType::kFloat2x2:
            return 0x7;
        case SkSLType::kFloat3x3:
            return 0xF;
        case SkSLType::kFloat4x4:
            return 0xF;

        case SkSLType::kShort:
        case SkSLType::kUShort:
        case SkSLType::kHalf:
            return 0x1;
        case SkSLType::kShort2:
        case SkSLType::kUShort2:
        case SkSLType::kHalf2:
            return 0x3;
        case SkSLType::kShort3:
        case SkSLType::kShort4:
        case SkSLType::kUShort3:
        case SkSLType::kUShort4:
        case SkSLType::kHalf3:
        case SkSLType::kHalf4:
            return 0x7;

        case SkSLType::kHalf2x2:
            return 0x3;
        case SkSLType::kHalf3x3:
            return 0x7;
        case SkSLType::kHalf4x4:
            return 0x7;

        // This query is only valid for certain types.
        case SkSLType::kVoid:
        case SkSLType::kBool:
        case SkSLType::kBool2:
        case SkSLType::kBool3:
        case SkSLType::kBool4:
        case SkSLType::kTexture2DSampler:
        case SkSLType::kTextureExternalSampler:
        case SkSLType::kTexture2DRectSampler:
        case SkSLType::kSampler:
        case SkSLType::kTexture2D:
        case SkSLType::kInput:
            break;
    }
    SK_ABORT("Unexpected type");
}

// Given the current offset into the ubo, calculate the offset for the uniform we're trying to add
// taking into consideration all alignment requirements. Returns the aligned start offset for the
// new uniform.
static uint32_t get_ubo_aligned_offset(Layout layout,
                                       uint32_t currentOffset,
                                       SkSLType type,
                                       bool isArray) {
    uint32_t alignmentMask;
    if (layout == Layout::kStd140 && isArray) {
        // std140 array element alignment always equals the base alignment of a vec4.
        alignmentMask = sksltype_to_alignment_mask(SkSLType::kFloat4);
    } else {
        alignmentMask = sksltype_to_alignment_mask(type);
    }
    return (currentOffset + alignmentMask) & ~alignmentMask;
}

SkSLType UniformOffsetCalculator::getUniformTypeForLayout(SkSLType type) {
    if (fLayout != Layout::kMetal) {
        // GL/Vk expect uniforms in 32-bit precision. Convert lower-precision types to 32-bit.
        switch (type) {
            case SkSLType::kShort:      return SkSLType::kInt;
            case SkSLType::kUShort:     return SkSLType::kUInt;
            case SkSLType::kHalf:       return SkSLType::kFloat;

            case SkSLType::kShort2:     return SkSLType::kInt2;
            case SkSLType::kUShort2:    return SkSLType::kUInt2;
            case SkSLType::kHalf2:      return SkSLType::kFloat2;

            case SkSLType::kShort3:     return SkSLType::kInt3;
            case SkSLType::kUShort3:    return SkSLType::kUInt3;
            case SkSLType::kHalf3:      return SkSLType::kFloat3;

            case SkSLType::kShort4:     return SkSLType::kInt4;
            case SkSLType::kUShort4:    return SkSLType::kUInt4;
            case SkSLType::kHalf4:      return SkSLType::kFloat4;

            case SkSLType::kHalf2x2:    return SkSLType::kFloat2x2;
            case SkSLType::kHalf3x3:    return SkSLType::kFloat3x3;
            case SkSLType::kHalf4x4:    return SkSLType::kFloat4x4;

            default:                    break;
        }
    }

    return type;
}

void UniformOffsetCalculator::setLayout(Layout layout) {
    fLayout = layout;
    switch (layout) {
        case Layout::kStd140:
            fWriteUniform = Writer<Rules140>::WriteUniform;
            break;
        case Layout::kStd430:
            fWriteUniform = Writer<Rules430>::WriteUniform;
            break;
        case Layout::kMetal:
            fWriteUniform = Writer<RulesMetal>::WriteUniform;
            break;
        case Layout::kInvalid:
            SK_ABORT("Invalid layout type");
            break;
    }
}

UniformOffsetCalculator::UniformOffsetCalculator(Layout layout, uint32_t startingOffset)
        : fLayout(layout), fOffset(startingOffset) {
    this->setLayout(fLayout);
}

size_t UniformOffsetCalculator::advanceOffset(SkSLType type, unsigned int count) {
    SkSLType revisedType = this->getUniformTypeForLayout(type);

    // Insert padding as needed to get the correct uniform alignment.
    uint32_t alignedOffset = get_ubo_aligned_offset(fLayout,
                                                    fOffset,
                                                    revisedType,
                                                    /*isArray=*/count != Uniform::kNonArray);
    SkASSERT(alignedOffset >= fOffset);

    // Append the uniform size to our offset, then return the uniform start position.
    uint32_t uniformSize = fWriteUniform(revisedType, CType::kDefault,
                                         /*dest=*/nullptr, count, /*src=*/nullptr);
    fOffset = alignedOffset + uniformSize;
    return alignedOffset;
}

UniformDataBlock UniformManager::finishUniformDataBlock() {
    size_t size = SkAlignTo(fStorage.size(), fReqAlignment);
    size_t paddingSize = size - fStorage.size();
    char* padding = fStorage.append(paddingSize);
    memset(padding, 0, paddingSize);
    return UniformDataBlock(SkSpan(fStorage.begin(), size));
}

void UniformManager::resetWithNewLayout(Layout layout) {
    if (layout != fLayout) {
        this->setLayout(layout);
    }
    this->reset();
}

void UniformManager::reset() {
    fOffset = 0;
    fReqAlignment = 0;
    fStorage.clear();
}

void UniformManager::checkReset() const {
    SkASSERT(fOffset == 0);
    SkASSERT(fStorage.empty());
}

void UniformManager::setExpectedUniforms(SkSpan<const Uniform> expectedUniforms) {
    SkDEBUGCODE(fExpectedUniforms = expectedUniforms;)
    SkDEBUGCODE(fExpectedUniformIndex = 0;)
}

void UniformManager::checkExpected(SkSLType type, unsigned int count) {
    SkASSERT(fExpectedUniforms.size());
    SkASSERT(fExpectedUniformIndex >= 0 && fExpectedUniformIndex < (int)fExpectedUniforms.size());

    SkASSERT(fExpectedUniforms[fExpectedUniformIndex].type() == type);
    SkASSERT((fExpectedUniforms[fExpectedUniformIndex].count() == 0 && count == 1) ||
             fExpectedUniforms[fExpectedUniformIndex].count() == count);
    SkDEBUGCODE(fExpectedUniformIndex++;)
}

void UniformManager::doneWithExpectedUniforms() {
    SkASSERT(fExpectedUniformIndex == static_cast<int>(fExpectedUniforms.size()));
    SkDEBUGCODE(fExpectedUniforms = {};)
}

void UniformManager::writeInternal(SkSLType type, unsigned int count, const void* src) {
    SkSLType revisedType = this->getUniformTypeForLayout(type);

    const uint32_t startOffset = fOffset;
    const uint32_t alignedStartOffset = this->advanceOffset(revisedType, count);
    SkASSERT(fOffset > alignedStartOffset);  // `fOffset` now equals the total bytes to be written
    const uint32_t bytesNeeded = fOffset - alignedStartOffset;

    // Insert padding if needed.
    if (alignedStartOffset > startOffset) {
        fStorage.append(alignedStartOffset - startOffset);
    }
    char* dst = fStorage.append(bytesNeeded);
    [[maybe_unused]] uint32_t bytesWritten =
            fWriteUniform(revisedType, CType::kDefault, dst, count, src);
    SkASSERT(bytesNeeded == bytesWritten);

    fReqAlignment = std::max(fReqAlignment, sksltype_to_alignment_mask(revisedType) + 1);
}

void UniformManager::write(SkSLType type, const void* src) {
    this->checkExpected(type, 1);
    this->writeInternal(type, Uniform::kNonArray, src);
}

void UniformManager::writeArray(SkSLType type, const void* src, unsigned int count) {
    // Don't write any elements if count is 0. Since Uniform::kNonArray == 0, passing count
    // directly would cause a one-element non-array write.
    if (count > 0) {
        this->checkExpected(type, count);
        this->writeInternal(type, count, src);
    }
}

void UniformManager::write(const Uniform& u, const uint8_t* src) {
    this->checkExpected(u.type(), (u.count() == Uniform::kNonArray) ? 1 : u.count());
    this->writeInternal(u.type(), u.count(), src);
}

void UniformManager::write(const SkM44& mat) {
    static constexpr SkSLType kType = SkSLType::kFloat4x4;
    this->write(kType, &mat);
}

void UniformManager::write(const SkPMColor4f& color) {
    static constexpr SkSLType kType = SkSLType::kFloat4;
    this->write(kType, &color);
}

void UniformManager::write(const SkRect& rect) {
    static constexpr SkSLType kType = SkSLType::kFloat4;
    this->write(kType, &rect);
}

void UniformManager::write(SkPoint point) {
    static constexpr SkSLType kType = SkSLType::kFloat2;
    this->write(kType, &point);
}

void UniformManager::write(float f) {
    static constexpr SkSLType kType = SkSLType::kFloat;
    this->write(kType, &f);
}

void UniformManager::write(int i) {
    static constexpr SkSLType kType = SkSLType::kInt;
    this->write(kType, &i);
}

void UniformManager::write(skvx::float2 v) {
    static constexpr SkSLType kType = SkSLType::kFloat2;
    this->write(kType, &v);
}

void UniformManager::write(skvx::float4 v) {
    static constexpr SkSLType kType = SkSLType::kFloat4;
    this->write(kType, &v);
}

void UniformManager::writeArray(SkSpan<const SkColor4f> arr) {
    static constexpr SkSLType kType = SkSLType::kFloat4;
    this->writeArray(kType, arr.data(), arr.size());
}

void UniformManager::writeArray(SkSpan<const SkPMColor4f> arr) {
    static constexpr SkSLType kType = SkSLType::kFloat4;
    this->writeArray(kType, arr.data(), arr.size());
}

void UniformManager::writeArray(SkSpan<const float> arr) {
    static constexpr SkSLType kType = SkSLType::kFloat;
    this->writeArray(kType, arr.data(), arr.size());
}

void UniformManager::writeHalf(const SkMatrix& mat) {
    static constexpr SkSLType kType = SkSLType::kHalf3x3;
    this->write(kType, &mat);
}

void UniformManager::writeHalfArray(SkSpan<const float> arr) {
    static constexpr SkSLType kType = SkSLType::kHalf;
    this->writeArray(kType, arr.data(), arr.size());
}

} // namespace skgpu::graphite
