vpx_convolve8_neon.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*
  2. * Copyright (c) 2014 The WebM project authors. All Rights Reserved.
  3. *
  4. * Use of this source code is governed by a BSD-style license
  5. * that can be found in the LICENSE file in the root of the source
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #ifndef VPX_VPX_DSP_ARM_VPX_CONVOLVE8_NEON_H_
  11. #define VPX_VPX_DSP_ARM_VPX_CONVOLVE8_NEON_H_
  12. #include <arm_neon.h>
  13. #include "./vpx_config.h"
  14. #include "./vpx_dsp_rtcd.h"
  15. static INLINE void load_u8_8x4(const uint8_t *s, const ptrdiff_t p,
  16. uint8x8_t *const s0, uint8x8_t *const s1,
  17. uint8x8_t *const s2, uint8x8_t *const s3) {
  18. *s0 = vld1_u8(s);
  19. s += p;
  20. *s1 = vld1_u8(s);
  21. s += p;
  22. *s2 = vld1_u8(s);
  23. s += p;
  24. *s3 = vld1_u8(s);
  25. }
  26. static INLINE void load_u8_8x8(const uint8_t *s, const ptrdiff_t p,
  27. uint8x8_t *const s0, uint8x8_t *const s1,
  28. uint8x8_t *const s2, uint8x8_t *const s3,
  29. uint8x8_t *const s4, uint8x8_t *const s5,
  30. uint8x8_t *const s6, uint8x8_t *const s7) {
  31. *s0 = vld1_u8(s);
  32. s += p;
  33. *s1 = vld1_u8(s);
  34. s += p;
  35. *s2 = vld1_u8(s);
  36. s += p;
  37. *s3 = vld1_u8(s);
  38. s += p;
  39. *s4 = vld1_u8(s);
  40. s += p;
  41. *s5 = vld1_u8(s);
  42. s += p;
  43. *s6 = vld1_u8(s);
  44. s += p;
  45. *s7 = vld1_u8(s);
  46. }
  47. static INLINE void load_u8_16x8(const uint8_t *s, const ptrdiff_t p,
  48. uint8x16_t *const s0, uint8x16_t *const s1,
  49. uint8x16_t *const s2, uint8x16_t *const s3,
  50. uint8x16_t *const s4, uint8x16_t *const s5,
  51. uint8x16_t *const s6, uint8x16_t *const s7) {
  52. *s0 = vld1q_u8(s);
  53. s += p;
  54. *s1 = vld1q_u8(s);
  55. s += p;
  56. *s2 = vld1q_u8(s);
  57. s += p;
  58. *s3 = vld1q_u8(s);
  59. s += p;
  60. *s4 = vld1q_u8(s);
  61. s += p;
  62. *s5 = vld1q_u8(s);
  63. s += p;
  64. *s6 = vld1q_u8(s);
  65. s += p;
  66. *s7 = vld1q_u8(s);
  67. }
  68. static INLINE int16x4_t convolve8_4(const int16x4_t s0, const int16x4_t s1,
  69. const int16x4_t s2, const int16x4_t s3,
  70. const int16x4_t s4, const int16x4_t s5,
  71. const int16x4_t s6, const int16x4_t s7,
  72. const int16x8_t filters,
  73. const int16x4_t filter3,
  74. const int16x4_t filter4) {
  75. const int16x4_t filters_lo = vget_low_s16(filters);
  76. const int16x4_t filters_hi = vget_high_s16(filters);
  77. int16x4_t sum;
  78. sum = vmul_lane_s16(s0, filters_lo, 0);
  79. sum = vmla_lane_s16(sum, s1, filters_lo, 1);
  80. sum = vmla_lane_s16(sum, s2, filters_lo, 2);
  81. sum = vmla_lane_s16(sum, s5, filters_hi, 1);
  82. sum = vmla_lane_s16(sum, s6, filters_hi, 2);
  83. sum = vmla_lane_s16(sum, s7, filters_hi, 3);
  84. sum = vqadd_s16(sum, vmul_s16(s3, filter3));
  85. sum = vqadd_s16(sum, vmul_s16(s4, filter4));
  86. return sum;
  87. }
  88. static INLINE uint8x8_t convolve8_8(const int16x8_t s0, const int16x8_t s1,
  89. const int16x8_t s2, const int16x8_t s3,
  90. const int16x8_t s4, const int16x8_t s5,
  91. const int16x8_t s6, const int16x8_t s7,
  92. const int16x8_t filters,
  93. const int16x8_t filter3,
  94. const int16x8_t filter4) {
  95. const int16x4_t filters_lo = vget_low_s16(filters);
  96. const int16x4_t filters_hi = vget_high_s16(filters);
  97. int16x8_t sum;
  98. sum = vmulq_lane_s16(s0, filters_lo, 0);
  99. sum = vmlaq_lane_s16(sum, s1, filters_lo, 1);
  100. sum = vmlaq_lane_s16(sum, s2, filters_lo, 2);
  101. sum = vmlaq_lane_s16(sum, s5, filters_hi, 1);
  102. sum = vmlaq_lane_s16(sum, s6, filters_hi, 2);
  103. sum = vmlaq_lane_s16(sum, s7, filters_hi, 3);
  104. sum = vqaddq_s16(sum, vmulq_s16(s3, filter3));
  105. sum = vqaddq_s16(sum, vmulq_s16(s4, filter4));
  106. return vqrshrun_n_s16(sum, 7);
  107. }
  108. static INLINE uint8x8_t scale_filter_8(const uint8x8_t *const s,
  109. const int16x8_t filters) {
  110. const int16x8_t filter3 = vdupq_lane_s16(vget_low_s16(filters), 3);
  111. const int16x8_t filter4 = vdupq_lane_s16(vget_high_s16(filters), 0);
  112. int16x8_t ss[8];
  113. ss[0] = vreinterpretq_s16_u16(vmovl_u8(s[0]));
  114. ss[1] = vreinterpretq_s16_u16(vmovl_u8(s[1]));
  115. ss[2] = vreinterpretq_s16_u16(vmovl_u8(s[2]));
  116. ss[3] = vreinterpretq_s16_u16(vmovl_u8(s[3]));
  117. ss[4] = vreinterpretq_s16_u16(vmovl_u8(s[4]));
  118. ss[5] = vreinterpretq_s16_u16(vmovl_u8(s[5]));
  119. ss[6] = vreinterpretq_s16_u16(vmovl_u8(s[6]));
  120. ss[7] = vreinterpretq_s16_u16(vmovl_u8(s[7]));
  121. return convolve8_8(ss[0], ss[1], ss[2], ss[3], ss[4], ss[5], ss[6], ss[7],
  122. filters, filter3, filter4);
  123. }
  124. #endif // VPX_VPX_DSP_ARM_VPX_CONVOLVE8_NEON_H_