| @@ -31,37 +31,72 @@ · 30 unmodified lines |
| 31 | // instructions. This optimization is much faster in speed unit test, but slowed | 31 | // instructions. This optimization is much faster in speed unit test, but slowed |
| 32 | // down the whole decoder by 5%. | 32 | // down the whole decoder by 5%. |
| 33 | | 33 | |
| 34 | static INLINE void store_u8_8x8(uint8_t *s, const ptrdiff_t p, | | |
| 35 | const uint8x8_t s0, const uint8x8_t s1, | | |
| 36 | const uint8x8_t s2, const uint8x8_t s3, | | |
| 37 | const uint8x8_t s4, const uint8x8_t s5, | | |
| 38 | const uint8x8_t s6, const uint8x8_t s7) { | | |
| 39 | vst1_u8(s, s0); | | |
| 40 | s += p; | | |
| 41 | vst1_u8(s, s1); | | |
| 42 | s += p; | | |
| 43 | vst1_u8(s, s2); | | |
| 44 | s += p; | | |
| 45 | vst1_u8(s, s3); | | |
| 46 | s += p; | | |
| 47 | vst1_u8(s, s4); | | |
| 48 | s += p; | | |
| 49 | vst1_u8(s, s5); | | |
| 50 | s += p; | | |
| 51 | vst1_u8(s, s6); | | |
| 52 | s += p; | | |
| 53 | vst1_u8(s, s7); | | |
| 54 | } | | |
| 55 | | | |
| 56 | #if defined(__aarch64__) && defined(__ARM_FEATURE_DOTPROD) && \ | 34 | #if defined(__aarch64__) && defined(__ARM_FEATURE_DOTPROD) && \ |
| 57 | (__ARM_FEATURE_DOTPROD == 1) | 35 | (__ARM_FEATURE_DOTPROD == 1) |
| 58 | | | |
| 59 | DECLARE_ALIGNED(16, static const uint8_t, dot_prod_permute_tbl[48]) = { | 36 | DECLARE_ALIGNED(16, static const uint8_t, dot_prod_permute_tbl[48]) = { |
| 60 | 0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6, | 37 | 0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5, 3, 4, 5, 6, |
| 61 | 4, 5, 6, 7, 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9, 10, | 38 | 4, 5, 6, 7, 5, 6, 7, 8, 6, 7, 8, 9, 7, 8, 9, 10, |
| 62 | 8, 9, 10, 11, 9, 10, 11, 12, 10, 11, 12, 13, 11, 12, 13, 14 | 39 | 8, 9, 10, 11, 9, 10, 11, 12, 10, 11, 12, 13, 11, 12, 13, 14 |
| 63 | }; | 40 | }; |
| 64 | | 41 | |
| | 42 | DECLARE_ALIGNED(16, static const uint8_t, dot_prod_tran_concat_tbl[32]) = { |
| | 43 | 0, 8, 16, 24, 1, 9, 17, 25, 2, 10, 18, 26, 3, 11, 19, 27, |
| | 44 | 4, 12, 20, 28, 5, 13, 21, 29, 6, 14, 22, 30, 7, 15, 23, 31 |
| | 45 | }; |
| | 46 | |
| | 47 | DECLARE_ALIGNED(16, static const uint8_t, dot_prod_merge_block_tbl[48]) = { |
| | 48 | /* Shift left and insert new last column in transposed 4x4 block. */ |
| | 49 | 1, 2, 3, 16, 5, 6, 7, 20, 9, 10, 11, 24, 13, 14, 15, 28, |
| | 50 | /* Shift left and insert two new columns in transposed 4x4 block. */ |
| | 51 | 2, 3, 16, 17, 6, 7, 20, 21, 10, 11, 24, 25, 14, 15, 28, 29, |
| | 52 | /* Shift left and insert three new columns in transposed 4x4 block. */ |
| | 53 | 3, 16, 17, 18, 7, 20, 21, 22, 11, 24, 25, 26, 15, 28, 29, 30 |
| | 54 | }; |
| | 55 | |
| | 56 | static INLINE void transpose_concat_4x4(int8x8_t *a0, int8x8_t *a1, |
| | 57 | int8x8_t *a2, int8x8_t *a3, |
| | 58 | int8x16_t *b, |
| | 59 | const uint8x16_t permute_tbl) { |
| | 60 | /* Transpose 8-bit elements and concatenate result rows as follows: |
| | 61 | * a0: 00, 01, 02, 03, XX, XX, XX, XX |
| | 62 | * a1: 10, 11, 12, 13, XX, XX, XX, XX |
| | 63 | * a2: 20, 21, 22, 23, XX, XX, XX, XX |
| | 64 | * a3: 30, 31, 32, 33, XX, XX, XX, XX |
| | 65 | * |
| | 66 | * b: 00, 10, 20, 30, 01, 11, 21, 31, 02, 12, 22, 32, 03, 13, 23, 33 |
| | 67 | * |
| | 68 | * The 'permute_tbl' is always 'dot_prod_tran_concat_tbl' above. Passing it |
| | 69 | * as an argument is preferable to loading it directly from memory as this |
| | 70 | * inline helper is called many times from the same parent function. |
| | 71 | */ |
| | 72 | |
| | 73 | int8x16x2_t samples = { { vcombine_s8(*a0, *a1), vcombine_s8(*a2, *a3) } }; |
| | 74 | *b = vqtbl2q_s8(samples, permute_tbl); |
| | 75 | } |
| | 76 | |
| | 77 | static INLINE void transpose_concat_8x4(int8x8_t *a0, int8x8_t *a1, |
| | 78 | int8x8_t *a2, int8x8_t *a3, |
| | 79 | int8x16_t *b0, int8x16_t *b1, |
| | 80 | const uint8x16x2_t permute_tbl) { |
| | 81 | /* Transpose 8-bit elements and concatenate result rows as follows: |
| | 82 | * a0: 00, 01, 02, 03, 04, 05, 06, 07 |
| | 83 | * a1: 10, 11, 12, 13, 14, 15, 16, 17 |
| | 84 | * a2: 20, 21, 22, 23, 24, 25, 26, 27 |
| | 85 | * a3: 30, 31, 32, 33, 34, 35, 36, 37 |
| | 86 | * |
| | 87 | * b0: 00, 10, 20, 30, 01, 11, 21, 31, 02, 12, 22, 32, 03, 13, 23, 33 |
| | 88 | * b1: 04, 14, 24, 34, 05, 15, 25, 35, 06, 16, 26, 36, 07, 17, 27, 37 |
| | 89 | * |
| | 90 | * The 'permute_tbl' is always 'dot_prod_tran_concat_tbl' above. Passing it |
| | 91 | * as an argument is preferable to loading it directly from memory as this |
| | 92 | * inline helper is called many times from the same parent function. |
| | 93 | */ |
| | 94 | |
| | 95 | int8x16x2_t samples = { { vcombine_s8(*a0, *a1), vcombine_s8(*a2, *a3) } }; |
| | 96 | *b0 = vqtbl2q_s8(samples, permute_tbl.val[0]); |
| | 97 | *b1 = vqtbl2q_s8(samples, permute_tbl.val[1]); |
| | 98 | } |
| | 99 | |
| 65 | void vpx_convolve8_horiz_neon(const uint8_t *src, ptrdiff_t src_stride, | 100 | void vpx_convolve8_horiz_neon(const uint8_t *src, ptrdiff_t src_stride, |
| 66 | uint8_t *dst, ptrdiff_t dst_stride, | 101 | uint8_t *dst, ptrdiff_t dst_stride, |
| 67 | const InterpKernel *filter, int x0_q4, | 102 | const InterpKernel *filter, int x0_q4, |
| @@ -268,8 +303,491 @@ void vpx_convolve8_avg_horiz_neon(const uint8_t *src, ptrdiff_t src_stride, · 200 unmodified lines |
| 268 | } | 303 | } |
| 269 | } | 304 | } |
| 270 | | 305 | |
| | 306 | void vpx_convolve8_vert_neon(const uint8_t *src, ptrdiff_t src_stride, |
| | 307 | uint8_t *dst, ptrdiff_t dst_stride, |
| | 308 | const InterpKernel *filter, int x0_q4, |
| | 309 | int x_step_q4, int y0_q4, int y_step_q4, int w, |
| | 310 | int h) { |
| | 311 | const int8x8_t filters = vmovn_s16(vld1q_s16(filter[y0_q4])); |
| | 312 | const int16x8_t correct_tmp = vmulq_n_s16(vld1q_s16(filter[y0_q4]), 128); |
| | 313 | const int32x4_t correction = vdupq_n_s32((int32_t)vaddvq_s16(correct_tmp)); |
| | 314 | const uint8x8_t range_limit = vdup_n_u8(128); |
| | 315 | const uint8x16x3_t merge_block_tbl = vld1q_u8_x3(dot_prod_merge_block_tbl); |
| | 316 | uint8x8_t t0, t1, t2, t3, t4, t5, t6; |
| | 317 | int8x8_t s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10; |
| | 318 | int8x16x2_t samples_LUT; |
| | 319 | |
| | 320 | assert(!((intptr_t)dst & 3)); |
| | 321 | assert(!(dst_stride & 3)); |
| | 322 | assert(y_step_q4 == 16); |
| | 323 | |
| | 324 | (void)x0_q4; |
| | 325 | (void)x_step_q4; |
| | 326 | (void)y_step_q4; |
| | 327 | |
| | 328 | src -= 3 * src_stride; |
| | 329 | |
| | 330 | if (w == 4) { |
| | 331 | const uint8x16_t tran_concat_tbl = vld1q_u8(dot_prod_tran_concat_tbl); |
| | 332 | int8x16_t s0123, s1234, s2345, s3456, s4567, s5678, s6789, s78910; |
| | 333 | int32x4_t d0, d1, d2, d3; |
| | 334 | uint8x8_t d01, d23; |
| | 335 | |
| | 336 | load_u8_8x4(src, src_stride, &t0, &t1, &t2, &t3); |
| | 337 | src += 4 * src_stride; |
| | 338 | t4 = vld1_u8(src); |
| | 339 | src += src_stride; |
| | 340 | t5 = vld1_u8(src); |
| | 341 | src += src_stride; |
| | 342 | t6 = vld1_u8(src); |
| | 343 | src += src_stride; |
| | 344 | |
| | 345 | /* Clamp sample range to [-128, 127] for 8-bit signed dot product. */ |
| | 346 | s0 = vreinterpret_s8_u8(vsub_u8(t0, range_limit)); |
| | 347 | s1 = vreinterpret_s8_u8(vsub_u8(t1, range_limit)); |
| | 348 | s2 = vreinterpret_s8_u8(vsub_u8(t2, range_limit)); |
| | 349 | s3 = vreinterpret_s8_u8(vsub_u8(t3, range_limit)); |
| | 350 | s4 = vreinterpret_s8_u8(vsub_u8(t4, range_limit)); |
| | 351 | s5 = vreinterpret_s8_u8(vsub_u8(t5, range_limit)); |
| | 352 | s6 = vreinterpret_s8_u8(vsub_u8(t6, range_limit)); |
| | 353 | s7 = vdup_n_s8(0); |
| | 354 | s8 = vdup_n_s8(0); |
| | 355 | s9 = vdup_n_s8(0); |
| | 356 | |
| | 357 | /* This operation combines a conventional transpose and the sample permute |
| | 358 | * (see horizontal case) required before computing the dot product. |
| | 359 | */ |
| | 360 | transpose_concat_4x4(&s0, &s1, &s2, &s3, &s0123, tran_concat_tbl); |
| | 361 | transpose_concat_4x4(&s1, &s2, &s3, &s4, &s1234, tran_concat_tbl); |
| | 362 | transpose_concat_4x4(&s2, &s3, &s4, &s5, &s2345, tran_concat_tbl); |
| | 363 | transpose_concat_4x4(&s3, &s4, &s5, &s6, &s3456, tran_concat_tbl); |
| | 364 | transpose_concat_4x4(&s4, &s5, &s6, &s7, &s4567, tran_concat_tbl); |
| | 365 | transpose_concat_4x4(&s5, &s6, &s7, &s8, &s5678, tran_concat_tbl); |
| | 366 | transpose_concat_4x4(&s6, &s7, &s8, &s9, &s6789, tran_concat_tbl); |
| | 367 | |
| | 368 | do { |
| | 369 | uint8x8_t t7, t8, t9, t10; |
| | 370 | |
| | 371 | load_u8_8x4(src, src_stride, &t7, &t8, &t9, &t10); |
| | 372 | |
| | 373 | s7 = vreinterpret_s8_u8(vsub_u8(t7, range_limit)); |
| | 374 | s8 = vreinterpret_s8_u8(vsub_u8(t8, range_limit)); |
| | 375 | s9 = vreinterpret_s8_u8(vsub_u8(t9, range_limit)); |
| | 376 | s10 = vreinterpret_s8_u8(vsub_u8(t10, range_limit)); |
| | 377 | |
| | 378 | transpose_concat_4x4(&s7, &s8, &s9, &s10, &s78910, tran_concat_tbl); |
| | 379 | |
| | 380 | /* Merge new data into block from previous iteration. */ |
| | 381 | samples_LUT.val[0] = s3456; |
| | 382 | samples_LUT.val[1] = s78910; |
| | 383 | s4567 = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[0]); |
| | 384 | s5678 = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[1]); |
| | 385 | s6789 = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[2]); |
| | 386 | |
| | 387 | d0 = convolve8_4_dot_partial(s0123, s4567, correction, filters); |
| | 388 | d1 = convolve8_4_dot_partial(s1234, s5678, correction, filters); |
| | 389 | d2 = convolve8_4_dot_partial(s2345, s6789, correction, filters); |
| | 390 | d3 = convolve8_4_dot_partial(s3456, s78910, correction, filters); |
| | 391 | |
| | 392 | d01 = vqrshrun_n_s16(vcombine_s16(vqmovn_s32(d0), vqmovn_s32(d1)), 7); |
| | 393 | d23 = vqrshrun_n_s16(vcombine_s16(vqmovn_s32(d2), vqmovn_s32(d3)), 7); |
| | 394 | |
| | 395 | vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(d01), 0); |
| | 396 | dst += dst_stride; |
| | 397 | vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(d01), 1); |
| | 398 | dst += dst_stride; |
| | 399 | vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(d23), 0); |
| | 400 | dst += dst_stride; |
| | 401 | vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(d23), 1); |
| | 402 | dst += dst_stride; |
| | 403 | |
| | 404 | /* Prepare block for next iteration - re-using as much as possible. */ |
| | 405 | /* Shuffle everything up four rows. */ |
| | 406 | s0123 = s4567; |
| | 407 | s1234 = s5678; |
| | 408 | s2345 = s6789; |
| | 409 | s3456 = s78910; |
| | 410 | |
| | 411 | src += 4 * src_stride; |
| | 412 | h -= 4; |
| | 413 | } while (h > 0); |
| | 414 | } else { |
| | 415 | const uint8x16x2_t tran_concat_tbl = vld1q_u8_x2(dot_prod_tran_concat_tbl); |
| | 416 | int8x16_t s0123_lo, s0123_hi, s1234_lo, s1234_hi, s2345_lo, s2345_hi, |
| | 417 | s3456_lo, s3456_hi, s4567_lo, s4567_hi, s5678_lo, s5678_hi, s6789_lo, |
| | 418 | s6789_hi, s78910_lo, s78910_hi; |
| | 419 | uint8x8_t d0, d1, d2, d3; |
| | 420 | const uint8_t *s; |
| | 421 | uint8_t *d; |
| | 422 | int height; |
| | 423 | |
| | 424 | do { |
| | 425 | height = h; |
| | 426 | s = src; |
| | 427 | d = dst; |
| | 428 | |
| | 429 | load_u8_8x4(s, src_stride, &t0, &t1, &t2, &t3); |
| | 430 | s += 4 * src_stride; |
| | 431 | t4 = vld1_u8(s); |
| | 432 | s += src_stride; |
| | 433 | t5 = vld1_u8(s); |
| | 434 | s += src_stride; |
| | 435 | t6 = vld1_u8(s); |
| | 436 | s += src_stride; |
| | 437 | |
| | 438 | /* Clamp sample range to [-128, 127] for 8-bit signed dot product. */ |
| | 439 | s0 = vreinterpret_s8_u8(vsub_u8(t0, range_limit)); |
| | 440 | s1 = vreinterpret_s8_u8(vsub_u8(t1, range_limit)); |
| | 441 | s2 = vreinterpret_s8_u8(vsub_u8(t2, range_limit)); |
| | 442 | s3 = vreinterpret_s8_u8(vsub_u8(t3, range_limit)); |
| | 443 | s4 = vreinterpret_s8_u8(vsub_u8(t4, range_limit)); |
| | 444 | s5 = vreinterpret_s8_u8(vsub_u8(t5, range_limit)); |
| | 445 | s6 = vreinterpret_s8_u8(vsub_u8(t6, range_limit)); |
| | 446 | s7 = vdup_n_s8(0); |
| | 447 | s8 = vdup_n_s8(0); |
| | 448 | s9 = vdup_n_s8(0); |
| | 449 | |
| | 450 | /* This operation combines a conventional transpose and the sample permute |
| | 451 | * (see horizontal case) required before computing the dot product. |
| | 452 | */ |
| | 453 | transpose_concat_8x4(&s0, &s1, &s2, &s3, &s0123_lo, &s0123_hi, |
| | 454 | tran_concat_tbl); |
| | 455 | transpose_concat_8x4(&s1, &s2, &s3, &s4, &s1234_lo, &s1234_hi, |
| | 456 | tran_concat_tbl); |
| | 457 | transpose_concat_8x4(&s2, &s3, &s4, &s5, &s2345_lo, &s2345_hi, |
| | 458 | tran_concat_tbl); |
| | 459 | transpose_concat_8x4(&s3, &s4, &s5, &s6, &s3456_lo, &s3456_hi, |
| | 460 | tran_concat_tbl); |
| | 461 | transpose_concat_8x4(&s4, &s5, &s6, &s7, &s4567_lo, &s4567_hi, |
| | 462 | tran_concat_tbl); |
| | 463 | transpose_concat_8x4(&s5, &s6, &s7, &s8, &s5678_lo, &s5678_hi, |
| | 464 | tran_concat_tbl); |
| | 465 | transpose_concat_8x4(&s6, &s7, &s8, &s9, &s6789_lo, &s6789_hi, |
| | 466 | tran_concat_tbl); |
| | 467 | |
| | 468 | do { |
| | 469 | uint8x8_t t7, t8, t9, t10; |
| | 470 | |
| | 471 | load_u8_8x4(s, src_stride, &t7, &t8, &t9, &t10); |
| | 472 | |
| | 473 | s7 = vreinterpret_s8_u8(vsub_u8(t7, range_limit)); |
| | 474 | s8 = vreinterpret_s8_u8(vsub_u8(t8, range_limit)); |
| | 475 | s9 = vreinterpret_s8_u8(vsub_u8(t9, range_limit)); |
| | 476 | s10 = vreinterpret_s8_u8(vsub_u8(t10, range_limit)); |
| | 477 | |
| | 478 | transpose_concat_8x4(&s7, &s8, &s9, &s10, &s78910_lo, &s78910_hi, |
| | 479 | tran_concat_tbl); |
| | 480 | |
| | 481 | /* Merge new data into block from previous iteration. */ |
| | 482 | samples_LUT.val[0] = s3456_lo; |
| | 483 | samples_LUT.val[1] = s78910_lo; |
| | 484 | s4567_lo = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[0]); |
| | 485 | s5678_lo = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[1]); |
| | 486 | s6789_lo = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[2]); |
| | 487 | |
| | 488 | samples_LUT.val[0] = s3456_hi; |
| | 489 | samples_LUT.val[1] = s78910_hi; |
| | 490 | s4567_hi = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[0]); |
| | 491 | s5678_hi = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[1]); |
| | 492 | s6789_hi = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[2]); |
| | 493 | |
| | 494 | d0 = convolve8_8_dot_partial(s0123_lo, s4567_lo, s0123_hi, s4567_hi, |
| | 495 | correction, filters); |
| | 496 | d1 = convolve8_8_dot_partial(s1234_lo, s5678_lo, s1234_hi, s5678_hi, |
| | 497 | correction, filters); |
| | 498 | d2 = convolve8_8_dot_partial(s2345_lo, s6789_lo, s2345_hi, s6789_hi, |
| | 499 | correction, filters); |
| | 500 | d3 = convolve8_8_dot_partial(s3456_lo, s78910_lo, s3456_hi, s78910_hi, |
| | 501 | correction, filters); |
| | 502 | vst1_u8(d + 0 * dst_stride, d0); |
| | 503 | vst1_u8(d + 1 * dst_stride, d1); |
| | 504 | vst1_u8(d + 2 * dst_stride, d2); |
| | 505 | vst1_u8(d + 3 * dst_stride, d3); |
| | 506 | |
| | 507 | /* Prepare block for next iteration - re-using as much as possible. */ |
| | 508 | /* Shuffle everything up four rows. */ |
| | 509 | s0123_lo = s4567_lo; |
| | 510 | s0123_hi = s4567_hi; |
| | 511 | s1234_lo = s5678_lo; |
| | 512 | s1234_hi = s5678_hi; |
| | 513 | s2345_lo = s6789_lo; |
| | 514 | s2345_hi = s6789_hi; |
| | 515 | s3456_lo = s78910_lo; |
| | 516 | s3456_hi = s78910_hi; |
| | 517 | |
| | 518 | s += 4 * src_stride; |
| | 519 | d += 4 * dst_stride; |
| | 520 | height -= 4; |
| | 521 | } while (height > 0); |
| | 522 | src += 8; |
| | 523 | dst += 8; |
| | 524 | w -= 8; |
| | 525 | } while (w > 0); |
| | 526 | } |
| | 527 | } |
| | 528 | |
| | 529 | void vpx_convolve8_avg_vert_neon(const uint8_t *src, ptrdiff_t src_stride, |
| | 530 | uint8_t *dst, ptrdiff_t dst_stride, |
| | 531 | const InterpKernel *filter, int x0_q4, |
| | 532 | int x_step_q4, int y0_q4, int y_step_q4, int w, |
| | 533 | int h) { |
| | 534 | const int8x8_t filters = vmovn_s16(vld1q_s16(filter[y0_q4])); |
| | 535 | const int16x8_t correct_tmp = vmulq_n_s16(vld1q_s16(filter[y0_q4]), 128); |
| | 536 | const int32x4_t correction = vdupq_n_s32((int32_t)vaddvq_s16(correct_tmp)); |
| | 537 | const uint8x8_t range_limit = vdup_n_u8(128); |
| | 538 | const uint8x16x3_t merge_block_tbl = vld1q_u8_x3(dot_prod_merge_block_tbl); |
| | 539 | uint8x8_t t0, t1, t2, t3, t4, t5, t6; |
| | 540 | int8x8_t s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10; |
| | 541 | int8x16x2_t samples_LUT; |
| | 542 | |
| | 543 | assert(!((intptr_t)dst & 3)); |
| | 544 | assert(!(dst_stride & 3)); |
| | 545 | assert(y_step_q4 == 16); |
| | 546 | |
| | 547 | (void)x0_q4; |
| | 548 | (void)x_step_q4; |
| | 549 | (void)y_step_q4; |
| | 550 | |
| | 551 | src -= 3 * src_stride; |
| | 552 | |
| | 553 | if (w == 4) { |
| | 554 | const uint8x16_t tran_concat_tbl = vld1q_u8(dot_prod_tran_concat_tbl); |
| | 555 | int8x16_t s0123, s1234, s2345, s3456, s4567, s5678, s6789, s78910; |
| | 556 | int32x4_t d0, d1, d2, d3; |
| | 557 | uint8x8_t d01, d23, dd01, dd23; |
| | 558 | |
| | 559 | load_u8_8x4(src, src_stride, &t0, &t1, &t2, &t3); |
| | 560 | src += 4 * src_stride; |
| | 561 | t4 = vld1_u8(src); |
| | 562 | src += src_stride; |
| | 563 | t5 = vld1_u8(src); |
| | 564 | src += src_stride; |
| | 565 | t6 = vld1_u8(src); |
| | 566 | src += src_stride; |
| | 567 | |
| | 568 | /* Clamp sample range to [-128, 127] for 8-bit signed dot product. */ |
| | 569 | s0 = vreinterpret_s8_u8(vsub_u8(t0, range_limit)); |
| | 570 | s1 = vreinterpret_s8_u8(vsub_u8(t1, range_limit)); |
| | 571 | s2 = vreinterpret_s8_u8(vsub_u8(t2, range_limit)); |
| | 572 | s3 = vreinterpret_s8_u8(vsub_u8(t3, range_limit)); |
| | 573 | s4 = vreinterpret_s8_u8(vsub_u8(t4, range_limit)); |
| | 574 | s5 = vreinterpret_s8_u8(vsub_u8(t5, range_limit)); |
| | 575 | s6 = vreinterpret_s8_u8(vsub_u8(t6, range_limit)); |
| | 576 | s7 = vdup_n_s8(0); |
| | 577 | s8 = vdup_n_s8(0); |
| | 578 | s9 = vdup_n_s8(0); |
| | 579 | |
| | 580 | /* This operation combines a conventional transpose and the sample permute |
| | 581 | * (see horizontal case) required before computing the dot product. |
| | 582 | */ |
| | 583 | transpose_concat_4x4(&s0, &s1, &s2, &s3, &s0123, tran_concat_tbl); |
| | 584 | transpose_concat_4x4(&s1, &s2, &s3, &s4, &s1234, tran_concat_tbl); |
| | 585 | transpose_concat_4x4(&s2, &s3, &s4, &s5, &s2345, tran_concat_tbl); |
| | 586 | transpose_concat_4x4(&s3, &s4, &s5, &s6, &s3456, tran_concat_tbl); |
| | 587 | transpose_concat_4x4(&s4, &s5, &s6, &s7, &s4567, tran_concat_tbl); |
| | 588 | transpose_concat_4x4(&s5, &s6, &s7, &s8, &s5678, tran_concat_tbl); |
| | 589 | transpose_concat_4x4(&s6, &s7, &s8, &s9, &s6789, tran_concat_tbl); |
| | 590 | |
| | 591 | do { |
| | 592 | uint8x8_t t7, t8, t9, t10; |
| | 593 | |
| | 594 | load_u8_8x4(src, src_stride, &t7, &t8, &t9, &t10); |
| | 595 | |
| | 596 | s7 = vreinterpret_s8_u8(vsub_u8(t7, range_limit)); |
| | 597 | s8 = vreinterpret_s8_u8(vsub_u8(t8, range_limit)); |
| | 598 | s9 = vreinterpret_s8_u8(vsub_u8(t9, range_limit)); |
| | 599 | s10 = vreinterpret_s8_u8(vsub_u8(t10, range_limit)); |
| | 600 | |
| | 601 | transpose_concat_4x4(&s7, &s8, &s9, &s10, &s78910, tran_concat_tbl); |
| | 602 | |
| | 603 | /* Merge new data into block from previous iteration. */ |
| | 604 | samples_LUT.val[0] = s3456; |
| | 605 | samples_LUT.val[1] = s78910; |
| | 606 | s4567 = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[0]); |
| | 607 | s5678 = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[1]); |
| | 608 | s6789 = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[2]); |
| | 609 | |
| | 610 | d0 = convolve8_4_dot_partial(s0123, s4567, correction, filters); |
| | 611 | d1 = convolve8_4_dot_partial(s1234, s5678, correction, filters); |
| | 612 | d2 = convolve8_4_dot_partial(s2345, s6789, correction, filters); |
| | 613 | d3 = convolve8_4_dot_partial(s3456, s78910, correction, filters); |
| | 614 | |
| | 615 | d01 = vqrshrun_n_s16(vcombine_s16(vqmovn_s32(d0), vqmovn_s32(d1)), 7); |
| | 616 | d23 = vqrshrun_n_s16(vcombine_s16(vqmovn_s32(d2), vqmovn_s32(d3)), 7); |
| | 617 | |
| | 618 | dd01 = load_u8(dst + 0 * dst_stride, dst_stride); |
| | 619 | dd23 = load_u8(dst + 2 * dst_stride, dst_stride); |
| | 620 | d01 = vrhadd_u8(d01, dd01); |
| | 621 | d23 = vrhadd_u8(d23, dd23); |
| | 622 | |
| | 623 | vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(d01), 0); |
| | 624 | dst += dst_stride; |
| | 625 | vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(d01), 1); |
| | 626 | dst += dst_stride; |
| | 627 | vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(d23), 0); |
| | 628 | dst += dst_stride; |
| | 629 | vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(d23), 1); |
| | 630 | dst += dst_stride; |
| | 631 | |
| | 632 | /* Prepare block for next iteration - re-using as much as possible. */ |
| | 633 | /* Shuffle everything up four rows. */ |
| | 634 | s0123 = s4567; |
| | 635 | s1234 = s5678; |
| | 636 | s2345 = s6789; |
| | 637 | s3456 = s78910; |
| | 638 | |
| | 639 | src += 4 * src_stride; |
| | 640 | h -= 4; |
| | 641 | } while (h > 0); |
| | 642 | } else { |
| | 643 | const uint8x16x2_t tran_concat_tbl = vld1q_u8_x2(dot_prod_tran_concat_tbl); |
| | 644 | int8x16_t s0123_lo, s0123_hi, s1234_lo, s1234_hi, s2345_lo, s2345_hi, |
| | 645 | s3456_lo, s3456_hi, s4567_lo, s4567_hi, s5678_lo, s5678_hi, s6789_lo, |
| | 646 | s6789_hi, s78910_lo, s78910_hi; |
| | 647 | uint8x8_t d0, d1, d2, d3, dd0, dd1, dd2, dd3; |
| | 648 | const uint8_t *s; |
| | 649 | uint8_t *d; |
| | 650 | int height; |
| | 651 | |
| | 652 | do { |
| | 653 | height = h; |
| | 654 | s = src; |
| | 655 | d = dst; |
| | 656 | |
| | 657 | load_u8_8x4(s, src_stride, &t0, &t1, &t2, &t3); |
| | 658 | s += 4 * src_stride; |
| | 659 | t4 = vld1_u8(s); |
| | 660 | s += src_stride; |
| | 661 | t5 = vld1_u8(s); |
| | 662 | s += src_stride; |
| | 663 | t6 = vld1_u8(s); |
| | 664 | s += src_stride; |
| | 665 | |
| | 666 | /* Clamp sample range to [-128, 127] for 8-bit signed dot product. */ |
| | 667 | s0 = vreinterpret_s8_u8(vsub_u8(t0, range_limit)); |
| | 668 | s1 = vreinterpret_s8_u8(vsub_u8(t1, range_limit)); |
| | 669 | s2 = vreinterpret_s8_u8(vsub_u8(t2, range_limit)); |
| | 670 | s3 = vreinterpret_s8_u8(vsub_u8(t3, range_limit)); |
| | 671 | s4 = vreinterpret_s8_u8(vsub_u8(t4, range_limit)); |
| | 672 | s5 = vreinterpret_s8_u8(vsub_u8(t5, range_limit)); |
| | 673 | s6 = vreinterpret_s8_u8(vsub_u8(t6, range_limit)); |
| | 674 | s7 = vdup_n_s8(0); |
| | 675 | s8 = vdup_n_s8(0); |
| | 676 | s9 = vdup_n_s8(0); |
| | 677 | |
| | 678 | /* This operation combines a conventional transpose and the sample permute |
| | 679 | * (see horizontal case) required before computing the dot product. |
| | 680 | */ |
| | 681 | transpose_concat_8x4(&s0, &s1, &s2, &s3, &s0123_lo, &s0123_hi, |
| | 682 | tran_concat_tbl); |
| | 683 | transpose_concat_8x4(&s1, &s2, &s3, &s4, &s1234_lo, &s1234_hi, |
| | 684 | tran_concat_tbl); |
| | 685 | transpose_concat_8x4(&s2, &s3, &s4, &s5, &s2345_lo, &s2345_hi, |
| | 686 | tran_concat_tbl); |
| | 687 | transpose_concat_8x4(&s3, &s4, &s5, &s6, &s3456_lo, &s3456_hi, |
| | 688 | tran_concat_tbl); |
| | 689 | transpose_concat_8x4(&s4, &s5, &s6, &s7, &s4567_lo, &s4567_hi, |
| | 690 | tran_concat_tbl); |
| | 691 | transpose_concat_8x4(&s5, &s6, &s7, &s8, &s5678_lo, &s5678_hi, |
| | 692 | tran_concat_tbl); |
| | 693 | transpose_concat_8x4(&s6, &s7, &s8, &s9, &s6789_lo, &s6789_hi, |
| | 694 | tran_concat_tbl); |
| | 695 | |
| | 696 | do { |
| | 697 | uint8x8_t t7, t8, t9, t10; |
| | 698 | |
| | 699 | load_u8_8x4(s, src_stride, &t7, &t8, &t9, &t10); |
| | 700 | |
| | 701 | s7 = vreinterpret_s8_u8(vsub_u8(t7, range_limit)); |
| | 702 | s8 = vreinterpret_s8_u8(vsub_u8(t8, range_limit)); |
| | 703 | s9 = vreinterpret_s8_u8(vsub_u8(t9, range_limit)); |
| | 704 | s10 = vreinterpret_s8_u8(vsub_u8(t10, range_limit)); |
| | 705 | |
| | 706 | transpose_concat_8x4(&s7, &s8, &s9, &s10, &s78910_lo, &s78910_hi, |
| | 707 | tran_concat_tbl); |
| | 708 | |
| | 709 | /* Merge new data into block from previous iteration. */ |
| | 710 | samples_LUT.val[0] = s3456_lo; |
| | 711 | samples_LUT.val[1] = s78910_lo; |
| | 712 | s4567_lo = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[0]); |
| | 713 | s5678_lo = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[1]); |
| | 714 | s6789_lo = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[2]); |
| | 715 | |
| | 716 | samples_LUT.val[0] = s3456_hi; |
| | 717 | samples_LUT.val[1] = s78910_hi; |
| | 718 | s4567_hi = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[0]); |
| | 719 | s5678_hi = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[1]); |
| | 720 | s6789_hi = vqtbl2q_s8(samples_LUT, merge_block_tbl.val[2]); |
| | 721 | |
| | 722 | d0 = convolve8_8_dot_partial(s0123_lo, s4567_lo, s0123_hi, s4567_hi, |
| | 723 | correction, filters); |
| | 724 | d1 = convolve8_8_dot_partial(s1234_lo, s5678_lo, s1234_hi, s5678_hi, |
| | 725 | correction, filters); |
| | 726 | d2 = convolve8_8_dot_partial(s2345_lo, s6789_lo, s2345_hi, s6789_hi, |
| | 727 | correction, filters); |
| | 728 | d3 = convolve8_8_dot_partial(s3456_lo, s78910_lo, s3456_hi, s78910_hi, |
| | 729 | correction, filters); |
| | 730 | |
| | 731 | dd0 = vld1_u8(d + 0 * dst_stride); |
| | 732 | dd1 = vld1_u8(d + 1 * dst_stride); |
| | 733 | dd2 = vld1_u8(d + 2 * dst_stride); |
| | 734 | dd3 = vld1_u8(d + 3 * dst_stride); |
| | 735 | d0 = vrhadd_u8(d0, dd0); |
| | 736 | d1 = vrhadd_u8(d1, dd1); |
| | 737 | d2 = vrhadd_u8(d2, dd2); |
| | 738 | d3 = vrhadd_u8(d3, dd3); |
| | 739 | |
| | 740 | vst1_u8(d + 0 * dst_stride, d0); |
| | 741 | vst1_u8(d + 1 * dst_stride, d1); |
| | 742 | vst1_u8(d + 2 * dst_stride, d2); |
| | 743 | vst1_u8(d + 3 * dst_stride, d3); |
| | 744 | |
| | 745 | /* Prepare block for next iteration - re-using as much as possible. */ |
| | 746 | /* Shuffle everything up four rows. */ |
| | 747 | s0123_lo = s4567_lo; |
| | 748 | s0123_hi = s4567_hi; |
| | 749 | s1234_lo = s5678_lo; |
| | 750 | s1234_hi = s5678_hi; |
| | 751 | s2345_lo = s6789_lo; |
| | 752 | s2345_hi = s6789_hi; |
| | 753 | s3456_lo = s78910_lo; |
| | 754 | s3456_hi = s78910_hi; |
| | 755 | |
| | 756 | s += 4 * src_stride; |
| | 757 | d += 4 * dst_stride; |
| | 758 | height -= 4; |
| | 759 | } while (height > 0); |
| | 760 | src += 8; |
| | 761 | dst += 8; |
| | 762 | w -= 8; |
| | 763 | } while (w > 0); |
| | 764 | } |
| | 765 | } |
| | 766 | |
| 271 | #else | 767 | #else |
| 272 | | 768 | |
| | 769 | static INLINE void store_u8_8x8(uint8_t *s, const ptrdiff_t p, |
| | 770 | const uint8x8_t s0, const uint8x8_t s1, |
| | 771 | const uint8x8_t s2, const uint8x8_t s3, |
| | 772 | const uint8x8_t s4, const uint8x8_t s5, |
| | 773 | const uint8x8_t s6, const uint8x8_t s7) { |
| | 774 | vst1_u8(s, s0); |
| | 775 | s += p; |
| | 776 | vst1_u8(s, s1); |
| | 777 | s += p; |
| | 778 | vst1_u8(s, s2); |
| | 779 | s += p; |
| | 780 | vst1_u8(s, s3); |
| | 781 | s += p; |
| | 782 | vst1_u8(s, s4); |
| | 783 | s += p; |
| | 784 | vst1_u8(s, s5); |
| | 785 | s += p; |
| | 786 | vst1_u8(s, s6); |
| | 787 | s += p; |
| | 788 | vst1_u8(s, s7); |
| | 789 | } |
| | 790 | |
| 273 | void vpx_convolve8_horiz_neon(const uint8_t *src, ptrdiff_t src_stride, | 791 | void vpx_convolve8_horiz_neon(const uint8_t *src, ptrdiff_t src_stride, |
| 274 | uint8_t *dst, ptrdiff_t dst_stride, | 792 | uint8_t *dst, ptrdiff_t dst_stride, |
| 275 | const InterpKernel *filter, int x0_q4, | 793 | const InterpKernel *filter, int x0_q4, |
| @@ -813,190 +1331,6 @@ void vpx_convolve8_avg_horiz_neon(const uint8_t *src, ptrdiff_t src_stride, · 537 unmodified lines |
| 813 | } | 1331 | } |
| 814 | } | 1332 | } |
| 815 | | 1333 | |
| 816 | #endif | | |
| 817 | | | |
| 818 | #if defined(__aarch64__) && defined(__ARM_FEATURE_DOTPROD) && \ | | |
| 819 | (__ARM_FEATURE_DOTPROD == 1) | | |
| 820 | | | |
| 821 | void vpx_convolve8_vert_neon(const uint8_t *src, ptrdiff_t src_stride, | | |
| 822 | uint8_t *dst, ptrdiff_t dst_stride, | | |
| 823 | const InterpKernel *filter, int x0_q4, | | |
| 824 | int x_step_q4, int y0_q4, int y_step_q4, int w, | | |
| 825 | int h) { | | |
| 826 | const int8x8_t filters = vmovn_s16(vld1q_s16(filter[y0_q4])); | | |
| 827 | const int16x8_t correct_tmp = vmulq_n_s16(vld1q_s16(filter[y0_q4]), 128); | | |
| 828 | const int32x4_t correction = vdupq_n_s32((int32_t)vaddvq_s16(correct_tmp)); | | |
| 829 | const uint8x16_t range_limit = vdupq_n_u8(128); | | |
| 830 | | | |
| 831 | assert(!((intptr_t)dst & 3)); | | |
| 832 | assert(!(dst_stride & 3)); | | |
| 833 | assert(y_step_q4 == 16); | | |
| 834 | | | |
| 835 | (void)x0_q4; | | |
| 836 | (void)x_step_q4; | | |
| 837 | (void)y_step_q4; | | |
| 838 | | | |
| 839 | src -= 3 * src_stride; | | |
| 840 | | | |
| 841 | if (w == 4) { | | |
| 842 | const uint8x16x2_t permute_tbl = vld1q_u8_x2(dot_prod_permute_tbl); | | |
| 843 | uint8x8_t t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, d01, d23; | | |
| 844 | uint8x16_t s0, s1, s2, s3; | | |
| 845 | int32x4_t d0, d1, d2, d3; | | |
| 846 | | | |
| 847 | load_u8_8x8(src, src_stride, &t0, &t1, &t2, &t3, &t4, &t5, &t6, &t7); | | |
| 848 | transpose_u8_4x8(&t0, &t1, &t2, &t3, t4, t5, t6, t7); | | |
| 849 | src += 8 * src_stride; | | |
| 850 | | | |
| 851 | do { | | |
| 852 | load_u8_8x4(src, src_stride, &t8, &t9, &t10, &t11); | | |
| 853 | transpose_u8_8x4(&t8, &t9, &t10, &t11); | | |
| 854 | s0 = vcombine_u8(t0, t8); | | |
| 855 | s1 = vcombine_u8(t1, t9); | | |
| 856 | s2 = vcombine_u8(t2, t10); | | |
| 857 | s3 = vcombine_u8(t3, t11); | | |
| 858 | | | |
| 859 | d0 = convolve8_4_dot(s0, filters, correction, range_limit, permute_tbl); | | |
| 860 | d1 = convolve8_4_dot(s1, filters, correction, range_limit, permute_tbl); | | |
| 861 | d2 = convolve8_4_dot(s2, filters, correction, range_limit, permute_tbl); | | |
| 862 | d3 = convolve8_4_dot(s3, filters, correction, range_limit, permute_tbl); | | |
| 863 | | | |
| 864 | d01 = vqrshrun_n_s16(vcombine_s16(vqmovn_s32(d0), vqmovn_s32(d1)), 7); | | |
| 865 | d23 = vqrshrun_n_s16(vcombine_s16(vqmovn_s32(d2), vqmovn_s32(d3)), 7); | | |
| 866 | transpose_u8_4x4(&d01, &d23); | | |
| 867 | | | |
| 868 | vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(d01), 0); | | |
| 869 | dst += dst_stride; | | |
| 870 | vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(d23), 0); | | |
| 871 | dst += dst_stride; | | |
| 872 | vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(d01), 1); | | |
| 873 | dst += dst_stride; | | |
| 874 | vst1_lane_u32((uint32_t *)dst, vreinterpret_u32_u8(d23), 1); | | |
| 875 | dst += dst_stride; | | |
| 876 | | | |
| 877 | t0 = vext_u8(t0, t8, 4); | | |
| 878 | t1 = vext_u8(t1, t9, 4); | | |
| 879 | t2 = vext_u8(t2, t10, 4); | | |
| 880 | t3 = vext_u8(t3, t11, 4); | | |
| 881 | src += 4 * src_stride; | | |
| 882 | h -= 4; | | |
| 883 | } while (h > 0); | | |
| 884 | } else if (h == 4) { | | |
| 885 | const uint8x16x2_t permute_tbl = vld1q_u8_x2(dot_prod_permute_tbl); | | |
| 886 | uint8x8_t t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, d04, d15, d26, d37; | | |
| 887 | uint8x16_t s0, s1, s2, s3, s4, s5, s6, s7; | | |
| 888 | int32x4_t d0, d1, d2, d3, d4, d5, d6, d7; | | |
| 889 | const uint8_t *s; | | |
| 890 | uint8_t *d; | | |
| 891 | | | |
| 892 | do { | | |
| 893 | s = src; | | |
| 894 | d = dst; | | |
| 895 | load_u8_8x8(s, src_stride, &t0, &t1, &t2, &t3, &t4, &t5, &t6, &t7); | | |
| 896 | s += 8 * src_stride; | | |
| 897 | t8 = vld1_u8(s); | | |
| 898 | s += src_stride; | | |
| 899 | t9 = vld1_u8(s); | | |
| 900 | s += src_stride; | | |
| 901 | t10 = vld1_u8(s); | | |
| 902 | s += src_stride; | | |
| 903 | | | |
| 904 | transpose_u8_8x16(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, | | |
| 905 | vdup_n_u8(0), vdup_n_u8(0), vdup_n_u8(0), vdup_n_u8(0), | | |
| 906 | vdup_n_u8(0), &s0, &s1, &s2, &s3, &s4, &s5, &s6, &s7); | | |
| 907 | | | |
| 908 | d0 = convolve8_4_dot(s0, filters, correction, range_limit, permute_tbl); | | |
| 909 | d1 = convolve8_4_dot(s1, filters, correction, range_limit, permute_tbl); | | |
| 910 | d2 = convolve8_4_dot(s2, filters, correction, range_limit, permute_tbl); | | |
| 911 | d3 = convolve8_4_dot(s3, filters, correction, range_limit, permute_tbl); | | |
| 912 | d4 = convolve8_4_dot(s4, filters, correction, range_limit, permute_tbl); | | |
| 913 | d5 = convolve8_4_dot(s5, filters, correction, range_limit, permute_tbl); | | |
| 914 | d6 = convolve8_4_dot(s6, filters, correction, range_limit, permute_tbl); | | |
| 915 | d7 = convolve8_4_dot(s7, filters, correction, range_limit, permute_tbl); | | |
| 916 | | | |
| 917 | d04 = vqrshrun_n_s16(vcombine_s16(vqmovn_s32(d0), vqmovn_s32(d4)), 7); | | |
| 918 | d15 = vqrshrun_n_s16(vcombine_s16(vqmovn_s32(d1), vqmovn_s32(d5)), 7); | | |
| 919 | d26 = vqrshrun_n_s16(vcombine_s16(vqmovn_s32(d2), vqmovn_s32(d6)), 7); | | |
| 920 | d37 = vqrshrun_n_s16(vcombine_s16(vqmovn_s32(d3), vqmovn_s32(d7)), 7); | | |
| 921 | | | |
| 922 | transpose_u8_8x4(&d04, &d15, &d26, &d37); | | |
| 923 | | | |
| 924 | vst1_u8(d, d04); | | |
| 925 | d += dst_stride; | | |
| 926 | vst1_u8(d, d15); | | |
| 927 | d += dst_stride; | | |
| 928 | vst1_u8(d, d26); | | |
| 929 | d += dst_stride; | | |
| 930 | vst1_u8(d, d37); | | |
| 931 | d += dst_stride; | | |
| 932 | | | |
| 933 | src += 8; | | |
| 934 | dst += 8; | | |
| 935 | w -= 8; | | |
| 936 | } while (w > 0); | | |
| 937 | } else { | | |
| 938 | const uint8x16x3_t permute_tbl = vld1q_u8_x3(dot_prod_permute_tbl); | | |
| 939 | uint8x8_t t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, | | |
| 940 | t15, d0, d1, d2, d3, d4, d5, d6, d7; | | |
| 941 | uint8x16_t s0, s1, s2, s3, s4, s5, s6, s7; | | |
| 942 | const uint8_t *s; | | |
| 943 | uint8_t *d; | | |
| 944 | int height; | | |
| 945 | | | |
| 946 | do { | | |
| 947 | height = h; | | |
| 948 | s = src; | | |
| 949 | d = dst; | | |
| 950 | load_u8_8x8(s, src_stride, &t0, &t1, &t2, &t3, &t4, &t5, &t6, &t7); | | |
| 951 | transpose_u8_8x8(&t0, &t1, &t2, &t3, &t4, &t5, &t6, &t7); | | |
| 952 | s += 8 * src_stride; | | |
| 953 | | | |
| 954 | do { | | |
| 955 | load_u8_8x8(s, src_stride, &t8, &t9, &t10, &t11, &t12, &t13, &t14, | | |
| 956 | &t15); | | |
| 957 | transpose_u8_8x8(&t8, &t9, &t10, &t11, &t12, &t13, &t14, &t15); | | |
| 958 | s0 = vcombine_u8(t0, t8); | | |
| 959 | s1 = vcombine_u8(t1, t9); | | |
| 960 | s2 = vcombine_u8(t2, t10); | | |
| 961 | s3 = vcombine_u8(t3, t11); | | |
| 962 | s4 = vcombine_u8(t4, t12); | | |
| 963 | s5 = vcombine_u8(t5, t13); | | |
| 964 | s6 = vcombine_u8(t6, t14); | | |
| 965 | s7 = vcombine_u8(t7, t15); | | |
| 966 | | | |
| 967 | d0 = convolve8_8_dot(s0, filters, correction, range_limit, permute_tbl); | | |
| 968 | d1 = convolve8_8_dot(s1, filters, correction, range_limit, permute_tbl); | | |
| 969 | d2 = convolve8_8_dot(s2, filters, correction, range_limit, permute_tbl); | | |
| 970 | d3 = convolve8_8_dot(s3, filters, correction, range_limit, permute_tbl); | | |
| 971 | d4 = convolve8_8_dot(s4, filters, correction, range_limit, permute_tbl); | | |
| 972 | d5 = convolve8_8_dot(s5, filters, correction, range_limit, permute_tbl); | | |
| 973 | d6 = convolve8_8_dot(s6, filters, correction, range_limit, permute_tbl); | | |
| 974 | d7 = convolve8_8_dot(s7, filters, correction, range_limit, permute_tbl); | | |
| 975 | | | |
| 976 | transpose_u8_8x8(&d0, &d1, &d2, &d3, &d4, &d5, &d6, &d7); | | |
| 977 | store_u8_8x8(d, dst_stride, d0, d1, d2, d3, d4, d5, d6, d7); | | |
| 978 | | | |
| 979 | t0 = t8; | | |
| 980 | t1 = t9; | | |
| 981 | t2 = t10; | | |
| 982 | t3 = t11; | | |
| 983 | t4 = t12; | | |
| 984 | t5 = t13; | | |
| 985 | t6 = t14; | | |
| 986 | t7 = t15; | | |
| 987 | s += 8 * src_stride; | | |
| 988 | d += 8 * dst_stride; | | |
| 989 | height -= 8; | | |
| 990 | } while (height > 0); | | |
| 991 | src += 8; | | |
| 992 | dst += 8; | | |
| 993 | w -= 8; | | |
| 994 | } while (w > 0); | | |
| 995 | } | | |
| 996 | } | | |
| 997 | | | |
| 998 | #else | | |
| 999 | | | |
| 1000 | void vpx_convolve8_vert_neon(const uint8_t *src, ptrdiff_t src_stride, | 1334 | void vpx_convolve8_vert_neon(const uint8_t *src, ptrdiff_t src_stride, |
| 1001 | uint8_t *dst, ptrdiff_t dst_stride, | 1335 | uint8_t *dst, ptrdiff_t dst_stride, |
| 1002 | const InterpKernel *filter, int x0_q4, | 1336 | const InterpKernel *filter, int x0_q4, |
| @@ -1169,8 +1503,6 @@ void vpx_convolve8_vert_neon(const uint8_t *src, ptrdiff_t src_stride, · 166 unmodified lines |
| 1169 | } | 1503 | } |
| 1170 | } | 1504 | } |
| 1171 | | 1505 | |
| 1172 | #endif | | |
| 1173 | | | |
| 1174 | void vpx_convolve8_avg_vert_neon(const uint8_t *src, ptrdiff_t src_stride, | 1506 | void vpx_convolve8_avg_vert_neon(const uint8_t *src, ptrdiff_t src_stride, |
| 1175 | uint8_t *dst, ptrdiff_t dst_stride, | 1507 | uint8_t *dst, ptrdiff_t dst_stride, |
| 1176 | const InterpKernel *filter, int x0_q4, | 1508 | const InterpKernel *filter, int x0_q4, |
| @@ -1361,3 +1693,5 @@ void vpx_convolve8_avg_vert_neon(const uint8_t *src, ptrdiff_t src_stride, · 184 unmodified lines |
| 1361 | } while (w != 0); | 1693 | } while (w != 0); |
| 1362 | } | 1694 | } |
| 1363 | } | 1695 | } |
| | 1696 | |
| | 1697 | #endif |