Home | History | Annotate | Download | only in mips
      1 /*
      2  *  Copyright (c) 2015 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 
     11 #include "vpx_dsp/mips/macros_msa.h"
     12 
     13 static void avg_width4_msa(const uint8_t *src, int32_t src_stride, uint8_t *dst,
     14                            int32_t dst_stride, int32_t height) {
     15   int32_t cnt;
     16   uint32_t out0, out1, out2, out3;
     17   v16u8 src0, src1, src2, src3;
     18   v16u8 dst0, dst1, dst2, dst3;
     19 
     20   if (0 == (height % 4)) {
     21     for (cnt = (height / 4); cnt--;) {
     22       LD_UB4(src, src_stride, src0, src1, src2, src3);
     23       src += (4 * src_stride);
     24 
     25       LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3);
     26 
     27       AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, dst0, dst1,
     28                   dst2, dst3);
     29 
     30       out0 = __msa_copy_u_w((v4i32)dst0, 0);
     31       out1 = __msa_copy_u_w((v4i32)dst1, 0);
     32       out2 = __msa_copy_u_w((v4i32)dst2, 0);
     33       out3 = __msa_copy_u_w((v4i32)dst3, 0);
     34       SW4(out0, out1, out2, out3, dst, dst_stride);
     35       dst += (4 * dst_stride);
     36     }
     37   } else if (0 == (height % 2)) {
     38     for (cnt = (height / 2); cnt--;) {
     39       LD_UB2(src, src_stride, src0, src1);
     40       src += (2 * src_stride);
     41 
     42       LD_UB2(dst, dst_stride, dst0, dst1);
     43 
     44       AVER_UB2_UB(src0, dst0, src1, dst1, dst0, dst1);
     45 
     46       out0 = __msa_copy_u_w((v4i32)dst0, 0);
     47       out1 = __msa_copy_u_w((v4i32)dst1, 0);
     48       SW(out0, dst);
     49       dst += dst_stride;
     50       SW(out1, dst);
     51       dst += dst_stride;
     52     }
     53   }
     54 }
     55 
     56 static void avg_width8_msa(const uint8_t *src, int32_t src_stride, uint8_t *dst,
     57                            int32_t dst_stride, int32_t height) {
     58   int32_t cnt;
     59   uint64_t out0, out1, out2, out3;
     60   v16u8 src0, src1, src2, src3;
     61   v16u8 dst0, dst1, dst2, dst3;
     62 
     63   for (cnt = (height / 4); cnt--;) {
     64     LD_UB4(src, src_stride, src0, src1, src2, src3);
     65     src += (4 * src_stride);
     66     LD_UB4(dst, dst_stride, dst0, dst1, dst2, dst3);
     67 
     68     AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, dst0, dst1,
     69                 dst2, dst3);
     70 
     71     out0 = __msa_copy_u_d((v2i64)dst0, 0);
     72     out1 = __msa_copy_u_d((v2i64)dst1, 0);
     73     out2 = __msa_copy_u_d((v2i64)dst2, 0);
     74     out3 = __msa_copy_u_d((v2i64)dst3, 0);
     75     SD4(out0, out1, out2, out3, dst, dst_stride);
     76     dst += (4 * dst_stride);
     77   }
     78 }
     79 
     80 static void avg_width16_msa(const uint8_t *src, int32_t src_stride,
     81                             uint8_t *dst, int32_t dst_stride, int32_t height) {
     82   int32_t cnt;
     83   v16u8 src0, src1, src2, src3, src4, src5, src6, src7;
     84   v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7;
     85 
     86   for (cnt = (height / 8); cnt--;) {
     87     LD_UB8(src, src_stride, src0, src1, src2, src3, src4, src5, src6, src7);
     88     src += (8 * src_stride);
     89     LD_UB8(dst, dst_stride, dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7);
     90 
     91     AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, dst0, dst1,
     92                 dst2, dst3);
     93     AVER_UB4_UB(src4, dst4, src5, dst5, src6, dst6, src7, dst7, dst4, dst5,
     94                 dst6, dst7);
     95     ST_UB8(dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7, dst, dst_stride);
     96     dst += (8 * dst_stride);
     97   }
     98 }
     99 
    100 static void avg_width32_msa(const uint8_t *src, int32_t src_stride,
    101                             uint8_t *dst, int32_t dst_stride, int32_t height) {
    102   int32_t cnt;
    103   uint8_t *dst_dup = dst;
    104   v16u8 src0, src1, src2, src3, src4, src5, src6, src7;
    105   v16u8 src8, src9, src10, src11, src12, src13, src14, src15;
    106   v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7;
    107   v16u8 dst8, dst9, dst10, dst11, dst12, dst13, dst14, dst15;
    108 
    109   for (cnt = (height / 8); cnt--;) {
    110     LD_UB4(src, src_stride, src0, src2, src4, src6);
    111     LD_UB4(src + 16, src_stride, src1, src3, src5, src7);
    112     src += (4 * src_stride);
    113     LD_UB4(dst_dup, dst_stride, dst0, dst2, dst4, dst6);
    114     LD_UB4(dst_dup + 16, dst_stride, dst1, dst3, dst5, dst7);
    115     dst_dup += (4 * dst_stride);
    116     LD_UB4(src, src_stride, src8, src10, src12, src14);
    117     LD_UB4(src + 16, src_stride, src9, src11, src13, src15);
    118     src += (4 * src_stride);
    119     LD_UB4(dst_dup, dst_stride, dst8, dst10, dst12, dst14);
    120     LD_UB4(dst_dup + 16, dst_stride, dst9, dst11, dst13, dst15);
    121     dst_dup += (4 * dst_stride);
    122 
    123     AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, dst0, dst1,
    124                 dst2, dst3);
    125     AVER_UB4_UB(src4, dst4, src5, dst5, src6, dst6, src7, dst7, dst4, dst5,
    126                 dst6, dst7);
    127     AVER_UB4_UB(src8, dst8, src9, dst9, src10, dst10, src11, dst11, dst8, dst9,
    128                 dst10, dst11);
    129     AVER_UB4_UB(src12, dst12, src13, dst13, src14, dst14, src15, dst15, dst12,
    130                 dst13, dst14, dst15);
    131 
    132     ST_UB4(dst0, dst2, dst4, dst6, dst, dst_stride);
    133     ST_UB4(dst1, dst3, dst5, dst7, dst + 16, dst_stride);
    134     dst += (4 * dst_stride);
    135     ST_UB4(dst8, dst10, dst12, dst14, dst, dst_stride);
    136     ST_UB4(dst9, dst11, dst13, dst15, dst + 16, dst_stride);
    137     dst += (4 * dst_stride);
    138   }
    139 }
    140 
    141 static void avg_width64_msa(const uint8_t *src, int32_t src_stride,
    142                             uint8_t *dst, int32_t dst_stride, int32_t height) {
    143   int32_t cnt;
    144   uint8_t *dst_dup = dst;
    145   v16u8 src0, src1, src2, src3, src4, src5, src6, src7;
    146   v16u8 src8, src9, src10, src11, src12, src13, src14, src15;
    147   v16u8 dst0, dst1, dst2, dst3, dst4, dst5, dst6, dst7;
    148   v16u8 dst8, dst9, dst10, dst11, dst12, dst13, dst14, dst15;
    149 
    150   for (cnt = (height / 4); cnt--;) {
    151     LD_UB4(src, 16, src0, src1, src2, src3);
    152     src += src_stride;
    153     LD_UB4(src, 16, src4, src5, src6, src7);
    154     src += src_stride;
    155     LD_UB4(src, 16, src8, src9, src10, src11);
    156     src += src_stride;
    157     LD_UB4(src, 16, src12, src13, src14, src15);
    158     src += src_stride;
    159 
    160     LD_UB4(dst_dup, 16, dst0, dst1, dst2, dst3);
    161     dst_dup += dst_stride;
    162     LD_UB4(dst_dup, 16, dst4, dst5, dst6, dst7);
    163     dst_dup += dst_stride;
    164     LD_UB4(dst_dup, 16, dst8, dst9, dst10, dst11);
    165     dst_dup += dst_stride;
    166     LD_UB4(dst_dup, 16, dst12, dst13, dst14, dst15);
    167     dst_dup += dst_stride;
    168 
    169     AVER_UB4_UB(src0, dst0, src1, dst1, src2, dst2, src3, dst3, dst0, dst1,
    170                 dst2, dst3);
    171     AVER_UB4_UB(src4, dst4, src5, dst5, src6, dst6, src7, dst7, dst4, dst5,
    172                 dst6, dst7);
    173     AVER_UB4_UB(src8, dst8, src9, dst9, src10, dst10, src11, dst11, dst8, dst9,
    174                 dst10, dst11);
    175     AVER_UB4_UB(src12, dst12, src13, dst13, src14, dst14, src15, dst15, dst12,
    176                 dst13, dst14, dst15);
    177 
    178     ST_UB4(dst0, dst1, dst2, dst3, dst, 16);
    179     dst += dst_stride;
    180     ST_UB4(dst4, dst5, dst6, dst7, dst, 16);
    181     dst += dst_stride;
    182     ST_UB4(dst8, dst9, dst10, dst11, dst, 16);
    183     dst += dst_stride;
    184     ST_UB4(dst12, dst13, dst14, dst15, dst, 16);
    185     dst += dst_stride;
    186   }
    187 }
    188 
    189 void vpx_convolve_avg_msa(const uint8_t *src, ptrdiff_t src_stride,
    190                           uint8_t *dst, ptrdiff_t dst_stride,
    191                           const int16_t *filter_x, int32_t filter_x_stride,
    192                           const int16_t *filter_y, int32_t filter_y_stride,
    193                           int32_t w, int32_t h) {
    194   (void)filter_x;
    195   (void)filter_y;
    196   (void)filter_x_stride;
    197   (void)filter_y_stride;
    198 
    199   switch (w) {
    200     case 4: {
    201       avg_width4_msa(src, src_stride, dst, dst_stride, h);
    202       break;
    203     }
    204     case 8: {
    205       avg_width8_msa(src, src_stride, dst, dst_stride, h);
    206       break;
    207     }
    208     case 16: {
    209       avg_width16_msa(src, src_stride, dst, dst_stride, h);
    210       break;
    211     }
    212     case 32: {
    213       avg_width32_msa(src, src_stride, dst, dst_stride, h);
    214       break;
    215     }
    216     case 64: {
    217       avg_width64_msa(src, src_stride, dst, dst_stride, h);
    218       break;
    219     }
    220     default: {
    221       int32_t lp, cnt;
    222       for (cnt = h; cnt--;) {
    223         for (lp = 0; lp < w; ++lp) {
    224           dst[lp] = (((dst[lp] + src[lp]) + 1) >> 1);
    225         }
    226         src += src_stride;
    227         dst += dst_stride;
    228       }
    229       break;
    230     }
    231   }
    232 }
    233