Average vertically before horizontally; horizontal averaging is more worksome. Doing the vertical averaging first reduces the number of horizontal averages by half. Use pmaddubsw and pavgw to do the horizontal averaging for a slight performance improvement. Minor tweaks. Improve the SSSE3 dyadic downsample routines and drop the SSE4 routines. The non-temporal loads used in the SSE4 routines do nothing for cache- backed memory AFAIK. Adjust tests because averaging vertically first gives slightly different output. ~2.39x speedup for the widthx32 routine on Haswell when not memory-bound. ~2.20x speedup for the widthx16 routine on Haswell when not memory-bound. Note that the widthx16 routine can be unrolled for further speedup.
Showing the changes to codec/processing/src (3 of 7 files). Show all
Unified · Split
| @@ -102,8 +102,6 @@ void CDownsampling::InitDownsampleFuncs (SDownsampleFuncs& sDownsampleFunc, int · 101 unmodified lines | |||
| 102 | sDownsampleFunc.pfGeneralRatioLuma = GeneralBilinearFastDownsamplerWrap_ssse3; | 102 | sDownsampleFunc.pfGeneralRatioLuma = GeneralBilinearFastDownsamplerWrap_ssse3; |
| 103 | } | 103 | } |
| 104 | if (iCpuFlag & WELS_CPU_SSE41) { | 104 | if (iCpuFlag & WELS_CPU_SSE41) { |
| 105 | sDownsampleFunc.pfHalfAverageWidthx32 = DyadicBilinearDownsamplerWidthx32_sse4; | ||
| 106 | sDownsampleFunc.pfHalfAverageWidthx16 = DyadicBilinearDownsamplerWidthx16_sse4; | ||
| 107 | sDownsampleFunc.pfOneThirdDownsampler = DyadicBilinearOneThirdDownsampler_sse4; | 105 | sDownsampleFunc.pfOneThirdDownsampler = DyadicBilinearOneThirdDownsampler_sse4; |
| 108 | sDownsampleFunc.pfQuarterDownsampler = DyadicBilinearQuarterDownsampler_sse4; | 106 | sDownsampleFunc.pfQuarterDownsampler = DyadicBilinearQuarterDownsampler_sse4; |
| 109 | sDownsampleFunc.pfGeneralRatioChroma = GeneralBilinearAccurateDownsamplerWrap_sse41; | 107 | sDownsampleFunc.pfGeneralRatioChroma = GeneralBilinearAccurateDownsamplerWrap_sse41; |
| @@ -94,10 +94,6 @@ HalveDownsampleFunc DyadicBilinearDownsamplerWidthx32_sse; · 93 unmodified lines | |||
| 94 | HalveDownsampleFunc DyadicBilinearDownsamplerWidthx16_ssse3; | 94 | HalveDownsampleFunc DyadicBilinearDownsamplerWidthx16_ssse3; |
| 95 | // iSrcWidth= x32 pixels | 95 | // iSrcWidth= x32 pixels |
| 96 | HalveDownsampleFunc DyadicBilinearDownsamplerWidthx32_ssse3; | 96 | HalveDownsampleFunc DyadicBilinearDownsamplerWidthx32_ssse3; |
| 97 | // iSrcWidth= x16 pixels | ||
| 98 | HalveDownsampleFunc DyadicBilinearDownsamplerWidthx16_sse4; | ||
| 99 | // iSrcWidth= x32 pixels | ||
| 100 | HalveDownsampleFunc DyadicBilinearDownsamplerWidthx32_sse4; | ||
| 101 | 97 | ||
| 102 | GeneralDownsampleFunc GeneralBilinearFastDownsamplerWrap_sse2; | 98 | GeneralDownsampleFunc GeneralBilinearFastDownsamplerWrap_sse2; |
| 103 | GeneralDownsampleFunc GeneralBilinearAccurateDownsamplerWrap_sse2; | 99 | GeneralDownsampleFunc GeneralBilinearAccurateDownsamplerWrap_sse2; |
| @@ -40,6 +40,10 @@ · 39 unmodified lines | |||
| 40 | ;*************************************************************************/ | 40 | ;*************************************************************************/ |
| 41 | %include "asm_inc.asm" | 41 | %include "asm_inc.asm" |
| 42 | 42 | ||
| 43 | %ifdef __NASM_VER__ | ||
| 44 | %use smartalign | ||
| 45 | %endif | ||
| 46 | |||
| 43 | ;*********************************************************************** | 47 | ;*********************************************************************** |
| 44 | ; Macros and other preprocessor constants | 48 | ; Macros and other preprocessor constants |
| 45 | ;*********************************************************************** | 49 | ;*********************************************************************** |
| @@ -471,24 +475,12 @@ WELS_EXTERN DyadicBilinearDownsamplerWidthx8_sse · 425 unmodified lines | |||
| 471 | 475 | ||
| 472 | 476 | ||
| 473 | 477 | ||
| 474 | ; got about 50% improvement over DyadicBilinearDownsamplerWidthx32_sse | ||
| 475 | ;*********************************************************************** | 478 | ;*********************************************************************** |
| 476 | ; void DyadicBilinearDownsamplerWidthx32_ssse3( unsigned char* pDst, const int iDstStride, | 479 | ; void DyadicBilinearDownsamplerWidthx32_ssse3( unsigned char* pDst, const int iDstStride, |
| 477 | ; unsigned char* pSrc, const int iSrcStride, | 480 | ; unsigned char* pSrc, const int iSrcStride, |
| 478 | ; const int iSrcWidth, const int iSrcHeight ); | 481 | ; const int iSrcWidth, const int iSrcHeight ); |
| 479 | ;*********************************************************************** | 482 | ;*********************************************************************** |
| 480 | WELS_EXTERN DyadicBilinearDownsamplerWidthx32_ssse3 | 483 | WELS_EXTERN DyadicBilinearDownsamplerWidthx32_ssse3 |
| 481 | ;push ebx | ||
| 482 | ;push edx | ||
| 483 | ;push esi | ||
| 484 | ;push edi | ||
| 485 | ;push ebp | ||
| 486 | |||
| 487 | ;mov edi, [esp+24] ; pDst | ||
| 488 | ;mov edx, [esp+28] ; iDstStride | ||
| 489 | ;mov esi, [esp+32] ; pSrc | ||
| 490 | ;mov ecx, [esp+36] ; iSrcStride | ||
| 491 | ;mov ebp, [esp+44] ; iSrcHeight | ||
| 492 | %ifdef X86_32 | 484 | %ifdef X86_32 |
| 493 | push r6 | 485 | push r6 |
| 494 | %assign push_num 1 | 486 | %assign push_num 1 |
| @@ -496,7 +488,7 @@ WELS_EXTERN DyadicBilinearDownsamplerWidthx32_ssse3 · 1 unmodified line | |||
| 496 | %assign push_num 0 | 488 | %assign push_num 0 |
| 497 | %endif | 489 | %endif |
| 498 | LOAD_6_PARA | 490 | LOAD_6_PARA |
| 499 | PUSH_XMM 8 | 491 | PUSH_XMM 4 |
| 500 | SIGN_EXTENSION r1, r1d | 492 | SIGN_EXTENSION r1, r1d |
| 501 | SIGN_EXTENSION r3, r3d | 493 | SIGN_EXTENSION r3, r3d |
| 502 | SIGN_EXTENSION r4, r4d | 494 | SIGN_EXTENSION r4, r4d |
| @@ -508,96 +500,44 @@ WELS_EXTERN DyadicBilinearDownsamplerWidthx32_ssse3 · 5 unmodified lines | |||
| 508 | %endif | 500 | %endif |
| 509 | sar r5, $01 ; iSrcHeight >> 1 | 501 | sar r5, $01 ; iSrcHeight >> 1 |
| 510 | 502 | ||
| 511 | movdqa xmm7, [shufb_mask_low] ; mask low | 503 | WELS_DB1 xmm3 |
| 512 | movdqa xmm6, [shufb_mask_high] ; mask high | 504 | WELS_Zero xmm2 |
| 505 | sar r4, $01 ; iSrcWidth >> 1 | ||
| 506 | add r0, r4 ; pDst += iSrcWidth >> 1 | ||
| 513 | 507 | ||
| 514 | .yloops4: | 508 | .yloops4: |
| 515 | ;mov eax, [esp+40] ; iSrcWidth | ||
| 516 | ;sar eax, $01 ; iSrcWidth >> 1 | ||
| 517 | ;mov ebx, eax ; iDstWidth restored at ebx | ||
| 518 | ;sar eax, $04 ; (iSrcWidth >> 1) / 16 ; loop count = num_of_mb | ||
| 519 | ;neg ebx ; - (iSrcWidth >> 1) | ||
| 520 | %ifdef X86_32 | 509 | %ifdef X86_32 |
| 521 | mov r4, arg5 | 510 | mov r4, arg5 |
| 522 | %else | 511 | %else |
| 523 | mov r4, r12 | 512 | mov r4, r12 |
| 524 | %endif | 513 | %endif |
| 525 | sar r4, $01 ; iSrcWidth >> 1 | 514 | sar r4, $01 ; iSrcWidth >> 1 |
| 526 | mov r6, r4 ; iDstWidth restored at ebx | 515 | neg r4 ; -(iSrcWidth >> 1) |
| 527 | sar r4, $04 ; (iSrcWidth >> 1) / 16 ; loop count = num_of_mb | 516 | mov r6, r4 |
| 528 | neg r6 ; - (iSrcWidth >> 1) | 517 | align 16 |
| 529 | ; each loop = source bandwidth: 32 bytes | 518 | ; each loop = source bandwidth: 32 bytes |
| 530 | .xloops4: | 519 | .xloops4: |
| 531 | ; 1st part horizonal loop: x16 bytes | 520 | movdqa xmm0, [r2+r3] |
| 532 | ; mem hi<- ->lo | 521 | movdqa xmm1, [r2+r3+16] |
| 533 | ;1st Line Src: xmm0: h H g G f F e E d D c C b B a A | 522 | pavgb xmm0, [r2] ; avg vertical pixels 0-15 |
| 534 | ; xmm1: p P o O n N m M l L k K j J i I | 523 | pavgb xmm1, [r2+16] ; avg vertical pixels 16-31 |
| 535 | ;2nd Line Src: xmm2: h H g G f F e E d D c C b B a A | 524 | add r2, 32 ; pSrc += 32 |
| 536 | ; xmm3: p P o O n N m M l L k K j J i I | 525 | pmaddubsw xmm0, xmm3 ; pairwise horizontal sum neighboring pixels 0-15 |
| 537 | ;=> target: | 526 | pmaddubsw xmm1, xmm3 ; pairwise horizontal sum neighboring pixels 16-31 |
| 538 | ;: P O N M L K J I H G F E D C B A | 527 | pavgw xmm0, xmm2 ; (sum + 1) >> 1 |
| 539 | ;: p o n m l k j i h g f e d c b a | 528 | pavgw xmm1, xmm2 ; (sum + 1) >> 1 |
| 540 | ;: P .. A | 529 | packuswb xmm0, xmm1 ; pack words to bytes |
| 541 | ;: p .. a | 530 | movdqa [r0+r4], xmm0 ; store results |
| 542 | 531 | add r4, 16 | |
| 543 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 532 | jl .xloops4 |
| 544 | movdqa xmm0, [r2] ; 1st_src_line | ||
| 545 | movdqa xmm1, [r2+16] ; 1st_src_line + 16 | ||
| 546 | movdqa xmm2, [r2+r3] ; 2nd_src_line | ||
| 547 | movdqa xmm3, [r2+r3+16] ; 2nd_src_line + 16 | ||
| 548 | |||
| 549 | ; packing & avg | ||
| 550 | movdqa xmm4, xmm0 ; h H g G f F e E d D c C b B a A | ||
| 551 | pshufb xmm0, xmm7 ; 0 H 0 G 0 F 0 E 0 D 0 C 0 B 0 A | ||
| 552 | pshufb xmm4, xmm6 ; 0 h 0 g 0 f 0 e 0 d 0 c 0 b 0 a | ||
| 553 | ; another implementation for xmm4 high bits | ||
| 554 | ; psubb xmm4, xmm0 ; h 0 g 0 f 0 e 0 d 0 c 0 b 0 a 0 | ||
| 555 | ; psrlw xmm4, 8 ; 0 h 0 g 0 f 0 e 0 d 0 c 0 b 0 a | ||
| 556 | pavgb xmm0, xmm4 | ||
| 557 | |||
| 558 | movdqa xmm5, xmm1 | ||
| 559 | pshufb xmm1, xmm7 | ||
| 560 | pshufb xmm5, xmm6 | ||
| 561 | ; psubb xmm5, xmm1 | ||
| 562 | ; psrlw xmm5, 8 | ||
| 563 | pavgb xmm1, xmm5 | ||
| 564 | |||
| 565 | movdqa xmm4, xmm2 | ||
| 566 | pshufb xmm2, xmm7 | ||
| 567 | pshufb xmm4, xmm6 | ||
| 568 | ; psubb xmm4, xmm2 | ||
| 569 | ; psrlw xmm4, 8 | ||
| 570 | pavgb xmm2, xmm4 | ||
| 571 | |||
| 572 | movdqa xmm5, xmm3 | ||
| 573 | pshufb xmm3, xmm7 | ||
| 574 | pshufb xmm5, xmm6 | ||
| 575 | ; psubb xmm5, xmm3 | ||
| 576 | ; psrlw xmm5, 8 | ||
| 577 | pavgb xmm3, xmm5 | ||
| 578 | |||
| 579 | packuswb xmm0, xmm1 | ||
| 580 | packuswb xmm2, xmm3 | ||
| 581 | pavgb xmm0, xmm2 | ||
| 582 | |||
| 583 | ; write pDst | ||
| 584 | movdqa [r0], xmm0 | ||
| 585 | |||
| 586 | ; next SMB | ||
| 587 | lea r2, [r2+32] | ||
| 588 | lea r0, [r0+16] | ||
| 589 | |||
| 590 | dec r4 | ||
| 591 | jg near .xloops4 | ||
| 592 | 533 | ||
| 593 | ; next line | 534 | ; next line |
| 594 | lea r2, [r2+2*r3] ; next end of lines | 535 | lea r2, [r2+2*r3] ; next end of lines |
| 595 | lea r2, [r2+2*r6] ; reset to base 0 [- 2 * iDstWidth] | 536 | lea r2, [r2+2*r6] ; reset to base 0 [- 2 * iDstWidth] |
| 596 | lea r0, [r0+r1] | 537 | lea r0, [r0+r1] |
| 597 | lea r0, [r0+r6] ; reset to base 0 [- iDstWidth] | ||
| 598 | 538 | ||
| 599 | dec r5 | 539 | sub r5, 1 |
| 600 | jg near .yloops4 | 540 | jg .yloops4 |
| 601 | 541 | ||
| 602 | %ifndef X86_32 | 542 | %ifndef X86_32 |
| 603 | pop r12 | 543 | pop r12 |
| @@ -623,7 +563,7 @@ WELS_EXTERN DyadicBilinearDownsamplerWidthx16_ssse3 · 19 unmodified lines | |||
| 623 | %assign push_num 0 | 563 | %assign push_num 0 |
| 624 | %endif | 564 | %endif |
| 625 | LOAD_6_PARA | 565 | LOAD_6_PARA |
| 626 | PUSH_XMM 6 | 566 | PUSH_XMM 4 |
| 627 | SIGN_EXTENSION r1, r1d | 567 | SIGN_EXTENSION r1, r1d |
| 628 | SIGN_EXTENSION r3, r3d | 568 | SIGN_EXTENSION r3, r3d |
| 629 | SIGN_EXTENSION r4, r4d | 569 | SIGN_EXTENSION r4, r4d |
| @@ -634,8 +574,11 @@ WELS_EXTERN DyadicBilinearDownsamplerWidthx16_ssse3 · 4 unmodified lines | |||
| 634 | mov r12, r4 | 574 | mov r12, r4 |
| 635 | %endif | 575 | %endif |
| 636 | sar r5, $01 ; iSrcHeight >> 1 | 576 | sar r5, $01 ; iSrcHeight >> 1 |
| 637 | movdqa xmm5, [shufb_mask_low] ; mask low | 577 | WELS_DB1 xmm3 |
| 638 | movdqa xmm4, [shufb_mask_high] ; mask high | 578 | WELS_Zero xmm2 |
| 579 | add r2, r4 ; pSrc += iSrcWidth | ||
| 580 | sar r4, $01 ; iSrcWidth >> 1 | ||
| 581 | add r0, r4 ; pDst += iSrcWidth >> 1 | ||
| 639 | 582 | ||
| 640 | .yloops5: | 583 | .yloops5: |
| 641 | %ifdef X86_32 | 584 | %ifdef X86_32 |
| @@ -644,279 +587,26 @@ WELS_EXTERN DyadicBilinearDownsamplerWidthx16_ssse3 · 2 unmodified lines | |||
| 644 | mov r4, r12 | 587 | mov r4, r12 |
| 645 | %endif | 588 | %endif |
| 646 | sar r4, $01 ; iSrcWidth >> 1 | 589 | sar r4, $01 ; iSrcWidth >> 1 |
| 647 | mov r6, r4 ; iDstWidth restored at ebx | 590 | neg r4 ; -(iSrcWidth >> 1) |
| 648 | sar r4, $03 ; (iSrcWidth >> 1) / 8 ; loop count = num_of_mb | 591 | lea r6, [r2+r3] ; pSrc + iSrcStride |
| 649 | neg r6 ; - (iSrcWidth >> 1) | 592 | align 16 |
| 650 | ; each loop = source bandwidth: 16 bytes | 593 | ; each loop = source bandwidth: 16 bytes |
| 651 | .xloops5: | 594 | .xloops5: |
| 652 | ; horizonal loop: x16 bytes by source | 595 | movdqa xmm0, [r2+2*r4] |
| 653 | ; mem hi<- ->lo | 596 | pavgb xmm0, [r6+2*r4] ; avg vertical pixels |
| 654 | ;1st line pSrc: xmm0: h H g G f F e E d D c C b B a A | 597 | pmaddubsw xmm0, xmm3 ; pairwise horizontal sum neighboring pixels |
| 655 | ;2nd line pSrc: xmm1: p P o O n N m M l L k K j J i I | 598 | pavgw xmm0, xmm2 ; (sum + 1) >> 1 |
| 656 | ;=> target: | 599 | packuswb xmm0, xmm0 ; pack words to bytes |
| 657 | ;: H G F E D C B A, P O N M L K J I | 600 | movlps [r0+r4], xmm0 ; store results |
| 658 | ;: h g f e d c b a, p o n m l k j i | 601 | add r4, 8 |
| 659 | 602 | jl .xloops5 | |
| 660 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 661 | movdqa xmm0, [r2] ; 1st_src_line | ||
| 662 | movdqa xmm1, [r2+r3] ; 2nd_src_line | ||
| 663 | |||
| 664 | ; packing & avg | ||
| 665 | movdqa xmm2, xmm0 ; h H g G f F e E d D c C b B a A | ||
| 666 | pshufb xmm0, xmm5 ; 0 H 0 G 0 F 0 E 0 D 0 C 0 B 0 A | ||
| 667 | pshufb xmm2, xmm4 ; 0 h 0 g 0 f 0 e 0 d 0 c 0 b 0 a | ||
| 668 | ; another implementation for xmm2 high bits | ||
| 669 | ; psubb xmm2, xmm0 ; h 0 g 0 f 0 e 0 d 0 c 0 b 0 a 0 | ||
| 670 | ; psrlw xmm2, 8 ; 0 h 0 g 0 f 0 e 0 d 0 c 0 b 0 a | ||
| 671 | pavgb xmm0, xmm2 | ||
| 672 | |||
| 673 | movdqa xmm3, xmm1 | ||
| 674 | pshufb xmm1, xmm5 | ||
| 675 | pshufb xmm3, xmm4 | ||
| 676 | ; psubb xmm3, xmm1 | ||
| 677 | ; psrlw xmm3, 8 | ||
| 678 | pavgb xmm1, xmm3 | ||
| 679 | |||
| 680 | pavgb xmm0, xmm1 | ||
| 681 | packuswb xmm0, xmm1 | ||
| 682 | |||
| 683 | ; write pDst | ||
| 684 | movq [r0], xmm0 | ||
| 685 | |||
| 686 | ; next SMB | ||
| 687 | lea r2, [r2+16] | ||
| 688 | lea r0, [r0+8] | ||
| 689 | |||
| 690 | dec r4 | ||
| 691 | jg near .xloops5 | ||
| 692 | |||
| 693 | lea r2, [r2+2*r3] ; next end of lines | ||
| 694 | lea r2, [r2+2*r6] ; reset to base 0 [- 2 * iDstWidth] | ||
| 695 | lea r0, [r0+r1] | ||
| 696 | lea r0, [r0+r6] ; reset to base 0 [- iDstWidth] | ||
| 697 | |||
| 698 | dec r5 | ||
| 699 | jg near .yloops5 | ||
| 700 | |||
| 701 | %ifndef X86_32 | ||
| 702 | pop r12 | ||
| 703 | %endif | ||
| 704 | |||
| 705 | POP_XMM | ||
| 706 | LOAD_6_PARA_POP | ||
| 707 | %ifdef X86_32 | ||
| 708 | pop r6 | ||
| 709 | %endif | ||
| 710 | ret | ||
| 711 | |||
| 712 | ; got about 65% improvement over DyadicBilinearDownsamplerWidthx32_sse | ||
| 713 | ;*********************************************************************** | ||
| 714 | ; void DyadicBilinearDownsamplerWidthx32_sse4( unsigned char* pDst, const int iDstStride, | ||
| 715 | ; unsigned char* pSrc, const int iSrcStride, | ||
| 716 | ; const int iSrcWidth, const int iSrcHeight ); | ||
| 717 | ;*********************************************************************** | ||
| 718 | WELS_EXTERN DyadicBilinearDownsamplerWidthx32_sse4 | ||
| 719 | %ifdef X86_32 | ||
| 720 | push r6 | ||
| 721 | %assign push_num 1 | ||
| 722 | %else | ||
| 723 | %assign push_num 0 | ||
| 724 | %endif | ||
| 725 | LOAD_6_PARA | ||
| 726 | PUSH_XMM 8 | ||
| 727 | SIGN_EXTENSION r1, r1d | ||
| 728 | SIGN_EXTENSION r3, r3d | ||
| 729 | SIGN_EXTENSION r4, r4d | ||
| 730 | SIGN_EXTENSION r5, r5d | ||
| 731 | |||
| 732 | %ifndef X86_32 | ||
| 733 | push r12 | ||
| 734 | mov r12, r4 | ||
| 735 | %endif | ||
| 736 | sar r5, $01 ; iSrcHeight >> 1 | ||
| 737 | |||
| 738 | movdqa xmm7, [shufb_mask_low] ; mask low | ||
| 739 | movdqa xmm6, [shufb_mask_high] ; mask high | ||
| 740 | |||
| 741 | .yloops6: | ||
| 742 | %ifdef X86_32 | ||
| 743 | mov r4, arg5 | ||
| 744 | %else | ||
| 745 | mov r4, r12 | ||
| 746 | %endif | ||
| 747 | sar r4, $01 ; iSrcWidth >> 1 | ||
| 748 | mov r6, r4 ; iDstWidth restored at ebx | ||
| 749 | sar r4, $04 ; (iSrcWidth >> 1) / 16 ; loop count = num_of_mb | ||
| 750 | neg r6 ; - (iSrcWidth >> 1) | ||
| 751 | ; each loop = source bandwidth: 32 bytes | ||
| 752 | .xloops6: | ||
| 753 | ; 1st part horizonal loop: x16 bytes | ||
| 754 | ; mem hi<- ->lo | ||
| 755 | ;1st Line Src: xmm0: h H g G f F e E d D c C b B a A | ||
| 756 | ; xmm1: p P o O n N m M l L k K j J i I | ||
| 757 | ;2nd Line Src: xmm2: h H g G f F e E d D c C b B a A | ||
| 758 | ; xmm3: p P o O n N m M l L k K j J i I | ||
| 759 | ;=> target: | ||
| 760 | ;: P O N M L K J I H G F E D C B A | ||
| 761 | ;: p o n m l k j i h g f e d c b a | ||
| 762 | ;: P .. A | ||
| 763 | ;: p .. a | ||
| 764 | |||
| 765 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 766 | movntdqa xmm0, [r2] ; 1st_src_line | ||
| 767 | movntdqa xmm1, [r2+16] ; 1st_src_line + 16 | ||
| 768 | movntdqa xmm2, [r2+r3] ; 2nd_src_line | ||
| 769 | movntdqa xmm3, [r2+r3+16] ; 2nd_src_line + 16 | ||
| 770 | |||
| 771 | ; packing & avg | ||
| 772 | movdqa xmm4, xmm0 ; h H g G f F e E d D c C b B a A | ||
| 773 | pshufb xmm0, xmm7 ; 0 H 0 G 0 F 0 E 0 D 0 C 0 B 0 A | ||
| 774 | pshufb xmm4, xmm6 ; 0 h 0 g 0 f 0 e 0 d 0 c 0 b 0 a | ||
| 775 | ; psubb xmm4, xmm0 ; h 0 g 0 f 0 e 0 d 0 c 0 b 0 a 0 | ||
| 776 | ; psrlw xmm4, 8 ; 0 h 0 g 0 f 0 e 0 d 0 c 0 b 0 a | ||
| 777 | pavgb xmm0, xmm4 | ||
| 778 | |||
| 779 | movdqa xmm5, xmm1 | ||
| 780 | pshufb xmm1, xmm7 | ||
| 781 | pshufb xmm5, xmm6 | ||
| 782 | ; psubb xmm5, xmm1 | ||
| 783 | ; psrlw xmm5, 8 | ||
| 784 | pavgb xmm1, xmm5 | ||
| 785 | |||
| 786 | movdqa xmm4, xmm2 | ||
| 787 | pshufb xmm2, xmm7 | ||
| 788 | pshufb xmm4, xmm6 | ||
| 789 | ; psubb xmm4, xmm2 | ||
| 790 | ; psrlw xmm4, 8 | ||
| 791 | pavgb xmm2, xmm4 | ||
| 792 | |||
| 793 | movdqa xmm5, xmm3 | ||
| 794 | pshufb xmm3, xmm7 | ||
| 795 | pshufb xmm5, xmm6 | ||
| 796 | ; psubb xmm5, xmm3 | ||
| 797 | ; psrlw xmm5, 8 | ||
| 798 | pavgb xmm3, xmm5 | ||
| 799 | |||
| 800 | packuswb xmm0, xmm1 | ||
| 801 | packuswb xmm2, xmm3 | ||
| 802 | pavgb xmm0, xmm2 | ||
| 803 | |||
| 804 | ; write pDst | ||
| 805 | movdqa [r0], xmm0 | ||
| 806 | |||
| 807 | ; next SMB | ||
| 808 | lea r2, [r2+32] | ||
| 809 | lea r0, [r0+16] | ||
| 810 | |||
| 811 | dec r4 | ||
| 812 | jg near .xloops6 | ||
| 813 | |||
| 814 | lea r2, [r2+2*r3] ; next end of lines | ||
| 815 | lea r2, [r2+2*r6] ; reset to base 0 [- 2 * iDstWidth] | ||
| 816 | lea r0, [r0+r1] | ||
| 817 | lea r0, [r0+r6] ; reset to base 0 [- iDstWidth] | ||
| 818 | |||
| 819 | dec r5 | ||
| 820 | jg near .yloops6 | ||
| 821 | |||
| 822 | %ifndef X86_32 | ||
| 823 | pop r12 | ||
| 824 | %endif | ||
| 825 | |||
| 826 | POP_XMM | ||
| 827 | LOAD_6_PARA_POP | ||
| 828 | %ifdef X86_32 | ||
| 829 | pop r6 | ||
| 830 | %endif | ||
| 831 | ret | ||
| 832 | |||
| 833 | ;*********************************************************************** | ||
| 834 | ; void DyadicBilinearDownsamplerWidthx16_sse4( unsigned char* pDst, const int iDstStride, | ||
| 835 | ; unsigned char* pSrc, const int iSrcStride, | ||
| 836 | ; const int iSrcWidth, const int iSrcHeight ); | ||
| 837 | ;*********************************************************************** | ||
| 838 | WELS_EXTERN DyadicBilinearDownsamplerWidthx16_sse4 | ||
| 839 | %ifdef X86_32 | ||
| 840 | push r6 | ||
| 841 | %assign push_num 1 | ||
| 842 | %else | ||
| 843 | %assign push_num 0 | ||
| 844 | %endif | ||
| 845 | LOAD_6_PARA | ||
| 846 | PUSH_XMM 6 | ||
| 847 | SIGN_EXTENSION r1, r1d | ||
| 848 | SIGN_EXTENSION r3, r3d | ||
| 849 | SIGN_EXTENSION r4, r4d | ||
| 850 | SIGN_EXTENSION r5, r5d | ||
| 851 | |||
| 852 | %ifndef X86_32 | ||
| 853 | push r12 | ||
| 854 | mov r12, r4 | ||
| 855 | %endif | ||
| 856 | sar r5, $01 ; iSrcHeight >> 1 | ||
| 857 | movdqa xmm5, [shufb_mask_low] ; mask low | ||
| 858 | movdqa xmm4, [shufb_mask_high] ; mask high | ||
| 859 | |||
| 860 | .yloops7: | ||
| 861 | %ifdef X86_32 | ||
| 862 | mov r4, arg5 | ||
| 863 | %else | ||
| 864 | mov r4, r12 | ||
| 865 | %endif | ||
| 866 | sar r4, $01 ; iSrcWidth >> 1 | ||
| 867 | mov r6, r4 ; iDstWidth restored at ebx | ||
| 868 | sar r4, $03 ; (iSrcWidth >> 1) / 8 ; loop count = num_of_mb | ||
| 869 | neg r6 ; - (iSrcWidth >> 1) | ||
| 870 | ; each loop = source bandwidth: 16 bytes | ||
| 871 | .xloops7: | ||
| 872 | ; horizonal loop: x16 bytes by source | ||
| 873 | ; mem hi<- ->lo | ||
| 874 | ;1st line pSrc: xmm0: h H g G f F e E d D c C b B a A | ||
| 875 | ;2nd line pSrc: xmm1: p P o O n N m M l L k K j J i I | ||
| 876 | ;=> target: | ||
| 877 | ;: H G F E D C B A, P O N M L K J I | ||
| 878 | ;: h g f e d c b a, p o n m l k j i | ||
| 879 | |||
| 880 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 881 | movntdqa xmm0, [r2] ; 1st_src_line | ||
| 882 | movntdqa xmm1, [r2+r3] ; 2nd_src_line | ||
| 883 | |||
| 884 | ; packing & avg | ||
| 885 | movdqa xmm2, xmm0 ; h H g G f F e E d D c C b B a A | ||
| 886 | pshufb xmm0, xmm5 ; 0 H 0 G 0 F 0 E 0 D 0 C 0 B 0 A | ||
| 887 | pshufb xmm2, xmm4 ; 0 h 0 g 0 f 0 e 0 d 0 c 0 b 0 a | ||
| 888 | ; psubb xmm2, xmm0 ; h 0 g 0 f 0 e 0 d 0 c 0 b 0 a 0 | ||
| 889 | ; psrlw xmm2, 8 ; 0 h 0 g 0 f 0 e 0 d 0 c 0 b 0 a | ||
| 890 | pavgb xmm0, xmm2 | ||
| 891 | |||
| 892 | movdqa xmm3, xmm1 | ||
| 893 | pshufb xmm1, xmm5 | ||
| 894 | pshufb xmm3, xmm4 | ||
| 895 | ; psubb xmm3, xmm1 | ||
| 896 | ; psrlw xmm3, 8 | ||
| 897 | pavgb xmm1, xmm3 | ||
| 898 | |||
| 899 | pavgb xmm0, xmm1 | ||
| 900 | packuswb xmm0, xmm1 | ||
| 901 | |||
| 902 | ; write pDst | ||
| 903 | movq [r0], xmm0 | ||
| 904 | |||
| 905 | ; next SMB | ||
| 906 | lea r2, [r2+16] | ||
| 907 | lea r0, [r0+8] | ||
| 908 | |||
| 909 | dec r4 | ||
| 910 | jg near .xloops7 | ||
| 911 | 603 | ||
| 912 | ; next line | 604 | ; next line |
| 913 | lea r2, [r2+2*r3] ; next end of lines | 605 | lea r2, [r2+2*r3] ; next end of lines |
| 914 | lea r2, [r2+2*r6] ; reset to base 0 [- 2 * iDstWidth] | ||
| 915 | lea r0, [r0+r1] | 606 | lea r0, [r0+r1] |
| 916 | lea r0, [r0+r6] ; reset to base 0 [- iDstWidth] | ||
| 917 | 607 | ||
| 918 | dec r5 | 608 | sub r5, 1 |
| 919 | jg near .yloops7 | 609 | jg .yloops5 |
| 920 | 610 | ||
| 921 | %ifndef X86_32 | 611 | %ifndef X86_32 |
| 922 | pop r12 | 612 | pop r12 |