/*
 * Copyright (c) 2024, Alliance for Open Media. All rights reserved.
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
 */

#include <assert.h>
#include <arm_neon.h>
#include <stddef.h>
#include <stdint.h>

#include "config/aom_config.h"
#include "config/av1_rtcd.h"

#include "aom_dsp/aom_dsp_common.h"
#include "aom_dsp/aom_filter.h"
#include "aom_dsp/arm/mem_neon.h"
#include "aom_dsp/arm/transpose_neon.h"
#include "aom_ports/mem.h"
#include "av1/common/arm/convolve_scale_neon.h"
#include "av1/common/convolve.h"
#include "av1/common/enums.h"
#include "av1/common/filter.h"

// clang-format off
DECLARE_ALIGNED(16, static const uint8_t, kScale2DotProdPermuteTbl[32]) = {
  0, 1, 2, 3, 2, 3, 4, 5, 4, 5,  6,  7,  6,  7,  8,  9,
  4, 5, 6, 7, 6, 7, 8, 9, 8, 9, 10, 11, 10, 11, 12, 13
};
// clang-format on

static INLINE int16x4_t convolve8_4_h(const uint8x8_t s0, const uint8x8_t s1,
                                      const uint8x8_t s2, const uint8x8_t s3,
                                      const int8x8_t filter,
                                      const int32x4_t horiz_const) {
  const int8x16_t filters = vcombine_s8(filter, filter);

  uint8x16_t s01 = vcombine_u8(s0, s1);
  uint8x16_t s23 = vcombine_u8(s2, s3);

  int32x4_t sum01 = vusdotq_s32(horiz_const, s01, filters);
  int32x4_t sum23 = vusdotq_s32(horiz_const, s23, filters);

  int32x4_t sum = vpaddq_s32(sum01, sum23);

  // We halved the filter values so -1 from right shift.
  return vshrn_n_s32(sum, ROUND0_BITS - 1);
}

static INLINE int16x8_t convolve8_8_h(const uint8x8_t s0, const uint8x8_t s1,
                                      const uint8x8_t s2, const uint8x8_t s3,
                                      const uint8x8_t s4, const uint8x8_t s5,
                                      const uint8x8_t s6, const uint8x8_t s7,
                                      const int8x8_t filter,
                                      const int32x4_t horiz_const) {
  const int8x16_t filters = vcombine_s8(filter, filter);

  uint8x16_t s01 = vcombine_u8(s0, s1);
  uint8x16_t s23 = vcombine_u8(s2, s3);
  uint8x16_t s45 = vcombine_u8(s4, s5);
  uint8x16_t s67 = vcombine_u8(s6, s7);

  int32x4_t sum01 = vusdotq_s32(horiz_const, s01, filters);
  int32x4_t sum23 = vusdotq_s32(horiz_const, s23, filters);
  int32x4_t sum45 = vusdotq_s32(horiz_const, s45, filters);
  int32x4_t sum67 = vusdotq_s32(horiz_const, s67, filters);

  int32x4_t sum0123 = vpaddq_s32(sum01, sum23);
  int32x4_t sum4567 = vpaddq_s32(sum45, sum67);

  // We halved the filter values so -1 from right shift.
  return vcombine_s16(vshrn_n_s32(sum0123, ROUND0_BITS - 1),
                      vshrn_n_s32(sum4567, ROUND0_BITS - 1));
}

static INLINE void convolve_horiz_scale_neon_i8mm(const uint8_t *src,
                                                  int src_stride, int16_t *dst,
                                                  int dst_stride, int w, int h,
                                                  const int16_t *x_filter,
                                                  const int subpel_x_qn,
                                                  const int x_step_qn) {
  DECLARE_ALIGNED(16, int16_t, temp[8 * 8]);
  const int bd = 8;
  // A shim of 1 << (ROUND0_BITS - 1) enables us to use non-rounding
  // shifts - which are generally faster than rounding shifts on modern CPUs.
  // Divide the total by 4: we halved the filter values and will use a pairwise
  // add in the convolution kernel.
  const int32x4_t horiz_offset = vdupq_n_s32(
      ((1 << (bd + FILTER_BITS - 1)) + (1 << (ROUND0_BITS - 1))) >> 2);

  if (w == 4) {
    do {
      int x_qn = subpel_x_qn;

      // Process a 4x4 tile.
      for (int r = 0; r < 4; r++) {
        const uint8_t *const s = &src[x_qn >> SCALE_SUBPEL_BITS];

        const ptrdiff_t filter_offset =
            SUBPEL_TAPS * ((x_qn & SCALE_SUBPEL_MASK) >> SCALE_EXTRA_BITS);
        // Filter values are all even so halve them to fit in int8_t.
        const int8x8_t filter =
            vshrn_n_s16(vld1q_s16(x_filter + filter_offset), 1);

        uint8x8_t t0, t1, t2, t3;
        load_u8_8x4(s, src_stride, &t0, &t1, &t2, &t3);

        int16x4_t d0 = convolve8_4_h(t0, t1, t2, t3, filter, horiz_offset);

        vst1_s16(&temp[r * 4], d0);
        x_qn += x_step_qn;
      }

      // Transpose the 4x4 result tile and store.
      int16x4_t d0, d1, d2, d3;
      load_s16_4x4(temp, 4, &d0, &d1, &d2, &d3);

      transpose_elems_inplace_s16_4x4(&d0, &d1, &d2, &d3);

      store_s16_4x4(dst, dst_stride, d0, d1, d2, d3);

      dst += 4 * dst_stride;
      src += 4 * src_stride;
      h -= 4;
    } while (h > 0);
  } else {
    do {
      int x_qn = subpel_x_qn;
      int16_t *d = dst;
      int width = w;

      do {
        // Process an 8x8 tile.
        for (int r = 0; r < 8; r++) {
          const uint8_t *const s = &src[(x_qn >> SCALE_SUBPEL_BITS)];

          const ptrdiff_t filter_offset =
              SUBPEL_TAPS * ((x_qn & SCALE_SUBPEL_MASK) >> SCALE_EXTRA_BITS);
          // Filter values are all even so halve them to fit in int8_t.
          const int8x8_t filter =
              vshrn_n_s16(vld1q_s16(x_filter + filter_offset), 1);

          uint8x8_t t0, t1, t2, t3, t4, t5, t6, t7;
          load_u8_8x8(s, src_stride, &t0, &t1, &t2, &t3, &t4, &t5, &t6, &t7);

          int16x8_t d0 = convolve8_8_h(t0, t1, t2, t3, t4, t5, t6, t7, filter,
                                       horiz_offset);

          vst1q_s16(&temp[r * 8], d0);

          x_qn += x_step_qn;
        }

        // Transpose the 8x8 result tile and store.
        int16x8_t d0, d1, d2, d3, d4, d5, d6, d7;
        load_s16_8x8(temp, 8, &d0, &d1, &d2, &d3, &d4, &d5, &d6, &d7);

        transpose_elems_inplace_s16_8x8(&d0, &d1, &d2, &d3, &d4, &d5, &d6, &d7);

        store_s16_8x8(d, dst_stride, d0, d1, d2, d3, d4, d5, d6, d7);

        d += 8;
        width -= 8;
      } while (width != 0);

      dst += 8 * dst_stride;
      src += 8 * src_stride;
      h -= 8;
    } while (h > 0);
  }
}

static INLINE int16x4_t convolve8_4_h_scale_2(uint8x16_t samples,
                                              const int8x8_t filters,
                                              const int32x4_t horiz_const,
                                              const uint8x16x2_t permute_tbl) {
  // Permute samples ready for dot product.
  // { 0, 1, 2, 3, 2, 3, 4, 5, 4, 5,  6,  7,  6,  7,  8,  9 }
  // { 4, 5, 6, 7, 6, 7, 8, 9, 8, 9, 10, 11, 10, 11, 12, 13 }
  uint8x16_t perm_samples[2] = { vqtbl1q_u8(samples, permute_tbl.val[0]),
                                 vqtbl1q_u8(samples, permute_tbl.val[1]) };

  int32x4_t sum = vusdotq_lane_s32(horiz_const, perm_samples[0], filters, 0);
  sum = vusdotq_lane_s32(sum, perm_samples[1], filters, 1);

  // We halved the filter values so -1 from right shift.
  return vshrn_n_s32(sum, ROUND0_BITS - 1);
}

static INLINE int16x8_t convolve8_8_h_scale_2(uint8x16_t samples[2],
                                              const int8x8_t filters,
                                              const int32x4_t horiz_const,
                                              const uint8x16x2_t permute_tbl) {
  // Permute samples ready for dot product.
  // { 0, 1, 2, 3, 2, 3, 4, 5, 4, 5,  6,  7,  6,  7,  8,  9 }
  // { 4, 5, 6, 7, 6, 7, 8, 9, 8, 9, 10, 11, 10, 11, 12, 13 }
  uint8x16_t perm_samples[4] = { vqtbl1q_u8(samples[0], permute_tbl.val[0]),
                                 vqtbl1q_u8(samples[0], permute_tbl.val[1]),
                                 vqtbl1q_u8(samples[1], permute_tbl.val[0]),
                                 vqtbl1q_u8(samples[1], permute_tbl.val[1]) };

  // First 4 output values.
  int32x4_t sum0123 =
      vusdotq_lane_s32(horiz_const, perm_samples[0], filters, 0);
  sum0123 = vusdotq_lane_s32(sum0123, perm_samples[1], filters, 1);

  // Second 4 output values.
  int32x4_t sum4567 =
      vusdotq_lane_s32(horiz_const, perm_samples[2], filters, 0);
  sum4567 = vusdotq_lane_s32(sum4567, perm_samples[3], filters, 1);

  // We halved the filter values so -1 from right shift.
  return vcombine_s16(vshrn_n_s32(sum0123, ROUND0_BITS - 1),
                      vshrn_n_s32(sum4567, ROUND0_BITS - 1));
}

static INLINE void convolve_horiz_scale_2_neon_i8mm(
    const uint8_t *src, int src_stride, int16_t *dst, int dst_stride, int w,
    int h, const int16_t *x_filter) {
  const int bd = 8;
  // A shim of 1 << (ROUND0_BITS - 1) enables us to use non-rounding
  // shifts - which are generally faster than rounding shifts on modern CPUs.
  // The additional -1 is needed because we are halving the filter values.
  const int32x4_t horiz_offset =
      vdupq_n_s32((1 << (bd + FILTER_BITS - 2)) + (1 << (ROUND0_BITS - 2)));

  const uint8x16x2_t permute_tbl = vld1q_u8_x2(kScale2DotProdPermuteTbl);
  // Filter values are all even so halve them to fit in int8_t.
  const int8x8_t filter = vshrn_n_s16(vld1q_s16(x_filter), 1);

  if (w == 4) {
    do {
      const uint8_t *s = src;
      int16_t *d = dst;
      int width = w;

      do {
        uint8x16_t s0, s1, s2, s3;
        load_u8_16x4(s, src_stride, &s0, &s1, &s2, &s3);

        int16x4_t d0 =
            convolve8_4_h_scale_2(s0, filter, horiz_offset, permute_tbl);
        int16x4_t d1 =
            convolve8_4_h_scale_2(s1, filter, horiz_offset, permute_tbl);
        int16x4_t d2 =
            convolve8_4_h_scale_2(s2, filter, horiz_offset, permute_tbl);
        int16x4_t d3 =
            convolve8_4_h_scale_2(s3, filter, horiz_offset, permute_tbl);

        store_s16_4x4(d, dst_stride, d0, d1, d2, d3);

        s += 8;
        d += 4;
        width -= 4;
      } while (width != 0);

      dst += 4 * dst_stride;
      src += 4 * src_stride;
      h -= 4;
    } while (h > 0);
  } else {
    do {
      const uint8_t *s = src;
      int16_t *d = dst;
      int width = w;

      do {
        uint8x16_t s0[2], s1[2], s2[2], s3[2];
        load_u8_16x4(s, src_stride, &s0[0], &s1[0], &s2[0], &s3[0]);
        load_u8_16x4(s + 8, src_stride, &s0[1], &s1[1], &s2[1], &s3[1]);

        int16x8_t d0 =
            convolve8_8_h_scale_2(s0, filter, horiz_offset, permute_tbl);
        int16x8_t d1 =
            convolve8_8_h_scale_2(s1, filter, horiz_offset, permute_tbl);
        int16x8_t d2 =
            convolve8_8_h_scale_2(s2, filter, horiz_offset, permute_tbl);
        int16x8_t d3 =
            convolve8_8_h_scale_2(s3, filter, horiz_offset, permute_tbl);

        store_s16_8x4(d, dst_stride, d0, d1, d2, d3);

        s += 16;
        d += 8;
        width -= 8;
      } while (width != 0);

      dst += 4 * dst_stride;
      src += 4 * src_stride;
      h -= 4;
    } while (h > 0);
  }
}

void av1_convolve_2d_scale_neon_i8mm(const uint8_t *src, int src_stride,
                                     uint8_t *dst, int dst_stride, int w, int h,
                                     const InterpFilterParams *filter_params_x,
                                     const InterpFilterParams *filter_params_y,
                                     const int subpel_x_qn, const int x_step_qn,
                                     const int subpel_y_qn, const int y_step_qn,
                                     ConvolveParams *conv_params) {
  if (w < 4 || h < 4) {
    av1_convolve_2d_scale_c(src, src_stride, dst, dst_stride, w, h,
                            filter_params_x, filter_params_y, subpel_x_qn,
                            x_step_qn, subpel_y_qn, y_step_qn, conv_params);
    return;
  }

  // For the interpolation 8-tap filters are used.
  assert(filter_params_y->taps <= 8 && filter_params_x->taps <= 8);

  DECLARE_ALIGNED(32, int16_t,
                  im_block[(2 * MAX_SB_SIZE + MAX_FILTER_TAP) * MAX_SB_SIZE]);
  int im_h = (((h - 1) * y_step_qn + subpel_y_qn) >> SCALE_SUBPEL_BITS) +
             filter_params_y->taps;
  int im_stride = MAX_SB_SIZE;
  CONV_BUF_TYPE *dst16 = conv_params->dst;
  const int dst16_stride = conv_params->dst_stride;

  // Account for needing filter_taps / 2 - 1 lines prior and filter_taps / 2
  // lines post both horizontally and vertically.
  const ptrdiff_t horiz_offset = filter_params_x->taps / 2 - 1;
  const ptrdiff_t vert_offset = (filter_params_y->taps / 2 - 1) * src_stride;

  // Horizontal filter
  if (x_step_qn != 2 * (1 << SCALE_SUBPEL_BITS)) {
    convolve_horiz_scale_neon_i8mm(
        src - horiz_offset - vert_offset, src_stride, im_block, im_stride, w,
        im_h, filter_params_x->filter_ptr, subpel_x_qn, x_step_qn);
  } else {
    assert(subpel_x_qn < (1 << SCALE_SUBPEL_BITS));
    // The filter index is calculated using the
    // ((subpel_x_qn + x * x_step_qn) & SCALE_SUBPEL_MASK) >> SCALE_EXTRA_BITS
    // equation, where the values of x are from 0 to w. If x_step_qn is a
    // multiple of SCALE_SUBPEL_MASK we can leave it out of the equation.
    const ptrdiff_t filter_offset =
        SUBPEL_TAPS * ((subpel_x_qn & SCALE_SUBPEL_MASK) >> SCALE_EXTRA_BITS);
    const int16_t *x_filter = filter_params_x->filter_ptr + filter_offset;

    // The source index is calculated using the (subpel_x_qn + x * x_step_qn) >>
    // SCALE_SUBPEL_BITS, where the values of x are from 0 to w. If subpel_x_qn
    // < (1 << SCALE_SUBPEL_BITS) and x_step_qn % (1 << SCALE_SUBPEL_BITS) == 0,
    // the source index can be determined using the value x * (x_step_qn /
    // (1 << SCALE_SUBPEL_BITS)).
    convolve_horiz_scale_2_neon_i8mm(src - horiz_offset - vert_offset,
                                     src_stride, im_block, im_stride, w, im_h,
                                     x_filter);
  }

  // Vertical filter
  if (filter_params_y->interp_filter == MULTITAP_SHARP) {
    if (UNLIKELY(conv_params->is_compound)) {
      if (conv_params->do_average) {
        if (conv_params->use_dist_wtd_comp_avg) {
          compound_dist_wtd_convolve_vert_scale_8tap_neon(
              im_block, im_stride, dst, dst_stride, dst16, dst16_stride, w, h,
              filter_params_y->filter_ptr, conv_params, subpel_y_qn, y_step_qn);
        } else {
          compound_avg_convolve_vert_scale_8tap_neon(
              im_block, im_stride, dst, dst_stride, dst16, dst16_stride, w, h,
              filter_params_y->filter_ptr, subpel_y_qn, y_step_qn);
        }
      } else {
        compound_convolve_vert_scale_8tap_neon(
            im_block, im_stride, dst16, dst16_stride, w, h,
            filter_params_y->filter_ptr, subpel_y_qn, y_step_qn);
      }
    } else {
      convolve_vert_scale_8tap_neon(im_block, im_stride, dst, dst_stride, w, h,
                                    filter_params_y->filter_ptr, subpel_y_qn,
                                    y_step_qn);
    }
  } else {
    if (UNLIKELY(conv_params->is_compound)) {
      if (conv_params->do_average) {
        if (conv_params->use_dist_wtd_comp_avg) {
          compound_dist_wtd_convolve_vert_scale_6tap_neon(
              im_block + im_stride, im_stride, dst, dst_stride, dst16,
              dst16_stride, w, h, filter_params_y->filter_ptr, conv_params,
              subpel_y_qn, y_step_qn);
        } else {
          compound_avg_convolve_vert_scale_6tap_neon(
              im_block + im_stride, im_stride, dst, dst_stride, dst16,
              dst16_stride, w, h, filter_params_y->filter_ptr, subpel_y_qn,
              y_step_qn);
        }
      } else {
        compound_convolve_vert_scale_6tap_neon(
            im_block + im_stride, im_stride, dst16, dst16_stride, w, h,
            filter_params_y->filter_ptr, subpel_y_qn, y_step_qn);
      }
    } else {
      convolve_vert_scale_6tap_neon(
          im_block + im_stride, im_stride, dst, dst_stride, w, h,
          filter_params_y->filter_ptr, subpel_y_qn, y_step_qn);
    }
  }
}
