mirror of https://github.com/FFmpeg/FFmpeg.git
- MMXEXT, SSE2 and SSSE3 MC functions - MMX and SSE4 IDCT dc_add functions Patch by Jason Garrett-Glaser <darkshikari gmail com> and myself. Originally committed as revision 23815 to svn://svn.ffmpeg.org/ffmpeg/trunkoldabi
parent
21f45508ba
commit
0178d14fe5
5 changed files with 928 additions and 0 deletions
@ -0,0 +1,216 @@ |
||||
/*
|
||||
* VP8 DSP functions x86-optimized |
||||
* Copyright (c) 2010 Ronald S. Bultje <rsbultje@gmail.com> |
||||
* Copyright (c) 2010 Jason Garrett-Glaser <darkshikari@gmail.com> |
||||
* |
||||
* This file is part of FFmpeg. |
||||
* |
||||
* FFmpeg is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU Lesser General Public |
||||
* License as published by the Free Software Foundation; either |
||||
* version 2.1 of the License, or (at your option) any later version. |
||||
* |
||||
* FFmpeg is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
* Lesser General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Lesser General Public |
||||
* License along with FFmpeg; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
*/ |
||||
|
||||
#include "libavutil/x86_cpu.h" |
||||
#include "libavcodec/vp8dsp.h" |
||||
|
||||
/*
|
||||
* MC functions |
||||
*/ |
||||
extern void ff_put_vp8_epel4_h4_mmxext(uint8_t *dst, int dststride, |
||||
uint8_t *src, int srcstride, |
||||
int height, int mx, int my); |
||||
extern void ff_put_vp8_epel4_h6_mmxext(uint8_t *dst, int dststride, |
||||
uint8_t *src, int srcstride, |
||||
int height, int mx, int my); |
||||
extern void ff_put_vp8_epel4_v4_mmxext(uint8_t *dst, int dststride, |
||||
uint8_t *src, int srcstride, |
||||
int height, int mx, int my); |
||||
extern void ff_put_vp8_epel4_v6_mmxext(uint8_t *dst, int dststride, |
||||
uint8_t *src, int srcstride, |
||||
int height, int mx, int my); |
||||
|
||||
extern void ff_put_vp8_epel8_h4_sse2 (uint8_t *dst, int dststride, |
||||
uint8_t *src, int srcstride, |
||||
int height, int mx, int my); |
||||
extern void ff_put_vp8_epel8_h6_sse2 (uint8_t *dst, int dststride, |
||||
uint8_t *src, int srcstride, |
||||
int height, int mx, int my); |
||||
extern void ff_put_vp8_epel8_v4_sse2 (uint8_t *dst, int dststride, |
||||
uint8_t *src, int srcstride, |
||||
int height, int mx, int my); |
||||
extern void ff_put_vp8_epel8_v6_sse2 (uint8_t *dst, int dststride, |
||||
uint8_t *src, int srcstride, |
||||
int height, int mx, int my); |
||||
|
||||
extern void ff_put_vp8_epel8_h4_ssse3 (uint8_t *dst, int dststride, |
||||
uint8_t *src, int srcstride, |
||||
int height, int mx, int my); |
||||
extern void ff_put_vp8_epel8_h6_ssse3 (uint8_t *dst, int dststride, |
||||
uint8_t *src, int srcstride, |
||||
int height, int mx, int my); |
||||
extern void ff_put_vp8_epel8_v4_ssse3 (uint8_t *dst, int dststride, |
||||
uint8_t *src, int srcstride, |
||||
int height, int mx, int my); |
||||
extern void ff_put_vp8_epel8_v6_ssse3 (uint8_t *dst, int dststride, |
||||
uint8_t *src, int srcstride, |
||||
int height, int mx, int my); |
||||
|
||||
#define TAP_W16(OPT, TAPTYPE) \ |
||||
static void ff_put_vp8_epel16_ ## TAPTYPE ## _ ## OPT(uint8_t *dst, \
|
||||
int dststride, \
|
||||
uint8_t *src, \
|
||||
int srcstride, \
|
||||
int height, \
|
||||
int mx, int my) \
|
||||
{ \
|
||||
ff_put_vp8_epel8_ ## TAPTYPE ## _ ## OPT(dst, dststride, \
|
||||
src, srcstride, \
|
||||
height, mx, my); \
|
||||
ff_put_vp8_epel8_ ## TAPTYPE ## _ ## OPT(dst + 8, dststride, \
|
||||
src + 8, srcstride, \
|
||||
height, mx, my); \
|
||||
} |
||||
#define TAP_W8(OPT, TAPTYPE) \ |
||||
static void ff_put_vp8_epel8_ ## TAPTYPE ## _ ## OPT(uint8_t *dst, \
|
||||
int dststride, \
|
||||
uint8_t *src, \
|
||||
int srcstride, \
|
||||
int height, \
|
||||
int mx, int my) \
|
||||
{ \
|
||||
ff_put_vp8_epel4_ ## TAPTYPE ## _ ## OPT(dst, dststride, \
|
||||
src, srcstride, \
|
||||
height, mx, my); \
|
||||
ff_put_vp8_epel4_ ## TAPTYPE ## _ ## OPT(dst + 4, dststride, \
|
||||
src + 4, srcstride, \
|
||||
height, mx, my); \
|
||||
} |
||||
|
||||
TAP_W8 (mmxext, h4) |
||||
TAP_W8 (mmxext, h6) |
||||
TAP_W16(mmxext, h6) |
||||
TAP_W8 (mmxext, v4) |
||||
TAP_W8 (mmxext, v6) |
||||
TAP_W16(mmxext, v6) |
||||
|
||||
TAP_W16(sse2, h6) |
||||
TAP_W16(sse2, v6) |
||||
|
||||
TAP_W16(ssse3, h6) |
||||
TAP_W16(ssse3, v6) |
||||
|
||||
#define HVTAP(OPT, ALIGN, TAPNUMX, TAPNUMY, SIZE, MAXHEIGHT) \ |
||||
static void ff_put_vp8_epel ## SIZE ## _h ## TAPNUMX ## v ## TAPNUMY ## _ ## OPT \
|
||||
(uint8_t *dst, int dststride, \
|
||||
uint8_t *src, int srcstride, \
|
||||
int height, int mx, int my) \
|
||||
{ \
|
||||
DECLARE_ALIGNED(ALIGN, uint8_t, tmp)[SIZE * (MAXHEIGHT + TAPNUMY - 1)]; \
|
||||
uint8_t *tmpptr = tmp + SIZE * (TAPNUMY / 2 - 1); \
|
||||
src -= srcstride * (TAPNUMY / 2 - 1); \
|
||||
ff_put_vp8_epel ## SIZE ## _h ## TAPNUMX ## _ ## OPT(tmp, SIZE, \
|
||||
src, srcstride, \
|
||||
height + TAPNUMY - 1, \
|
||||
mx, my); \
|
||||
ff_put_vp8_epel ## SIZE ## _v ## TAPNUMY ## _ ## OPT(dst, dststride, \
|
||||
tmpptr, SIZE, \
|
||||
height, mx, my); \
|
||||
} |
||||
|
||||
#define HVTAPMMX(x, y) \ |
||||
HVTAP(mmxext, 8, x, y, 4, 8) \
|
||||
HVTAP(mmxext, 8, x, y, 8, 16) |
||||
|
||||
HVTAPMMX(4, 4) |
||||
HVTAPMMX(4, 6) |
||||
HVTAPMMX(6, 4) |
||||
HVTAPMMX(6, 6) |
||||
HVTAP(mmxext, 8, 6, 6, 16, 16) |
||||
|
||||
#define HVTAPSSE2(x, y, w) \ |
||||
HVTAP(sse2, 16, x, y, w, 16) \
|
||||
HVTAP(ssse3, 16, x, y, w, 16) |
||||
|
||||
HVTAPSSE2(4, 4, 8) |
||||
HVTAPSSE2(4, 6, 8) |
||||
HVTAPSSE2(6, 4, 8) |
||||
HVTAPSSE2(6, 6, 8) |
||||
HVTAPSSE2(6, 6, 16) |
||||
|
||||
extern void ff_vp8_idct_dc_add_mmx(uint8_t *dst, DCTELEM block[16], int stride); |
||||
extern void ff_vp8_idct_dc_add_sse4(uint8_t *dst, DCTELEM block[16], int stride); |
||||
|
||||
av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c) |
||||
{ |
||||
mm_flags = mm_support(); |
||||
|
||||
if (mm_flags & FF_MM_MMX) { |
||||
c->vp8_idct_dc_add = ff_vp8_idct_dc_add_mmx; |
||||
} |
||||
|
||||
/* note that 4-tap width=16 functions are missing because w=16
|
||||
* is only used for luma, and luma is always a copy or sixtap. */ |
||||
if (mm_flags & FF_MM_MMXEXT) { |
||||
c->put_vp8_epel_pixels_tab[0][0][2] = ff_put_vp8_epel16_h6_mmxext; |
||||
c->put_vp8_epel_pixels_tab[0][2][0] = ff_put_vp8_epel16_v6_mmxext; |
||||
c->put_vp8_epel_pixels_tab[0][2][2] = ff_put_vp8_epel16_h6v6_mmxext; |
||||
c->put_vp8_epel_pixels_tab[1][0][1] = ff_put_vp8_epel8_h4_mmxext; |
||||
c->put_vp8_epel_pixels_tab[1][0][2] = ff_put_vp8_epel8_h6_mmxext; |
||||
c->put_vp8_epel_pixels_tab[1][1][0] = ff_put_vp8_epel8_v4_mmxext; |
||||
c->put_vp8_epel_pixels_tab[1][1][1] = ff_put_vp8_epel8_h4v4_mmxext; |
||||
c->put_vp8_epel_pixels_tab[1][1][2] = ff_put_vp8_epel8_h6v4_mmxext; |
||||
c->put_vp8_epel_pixels_tab[1][2][0] = ff_put_vp8_epel8_v6_mmxext; |
||||
c->put_vp8_epel_pixels_tab[1][2][1] = ff_put_vp8_epel8_h4v6_mmxext; |
||||
c->put_vp8_epel_pixels_tab[1][2][2] = ff_put_vp8_epel8_h6v6_mmxext; |
||||
c->put_vp8_epel_pixels_tab[2][0][1] = ff_put_vp8_epel4_h4_mmxext; |
||||
c->put_vp8_epel_pixels_tab[2][0][2] = ff_put_vp8_epel4_h6_mmxext; |
||||
c->put_vp8_epel_pixels_tab[2][1][0] = ff_put_vp8_epel4_v4_mmxext; |
||||
c->put_vp8_epel_pixels_tab[2][1][1] = ff_put_vp8_epel4_h4v4_mmxext; |
||||
c->put_vp8_epel_pixels_tab[2][1][2] = ff_put_vp8_epel4_h6v4_mmxext; |
||||
c->put_vp8_epel_pixels_tab[2][2][0] = ff_put_vp8_epel4_v6_mmxext; |
||||
c->put_vp8_epel_pixels_tab[2][2][1] = ff_put_vp8_epel4_h4v6_mmxext; |
||||
c->put_vp8_epel_pixels_tab[2][2][2] = ff_put_vp8_epel4_h6v6_mmxext; |
||||
} |
||||
|
||||
if (mm_flags & FF_MM_SSE2) { |
||||
c->put_vp8_epel_pixels_tab[0][0][2] = ff_put_vp8_epel16_h6_sse2; |
||||
c->put_vp8_epel_pixels_tab[0][2][0] = ff_put_vp8_epel16_v6_sse2; |
||||
c->put_vp8_epel_pixels_tab[0][2][2] = ff_put_vp8_epel16_h6v6_sse2; |
||||
c->put_vp8_epel_pixels_tab[1][0][1] = ff_put_vp8_epel8_h4_sse2; |
||||
c->put_vp8_epel_pixels_tab[1][0][2] = ff_put_vp8_epel8_h6_sse2; |
||||
c->put_vp8_epel_pixels_tab[1][1][0] = ff_put_vp8_epel8_v4_sse2; |
||||
c->put_vp8_epel_pixels_tab[1][1][1] = ff_put_vp8_epel8_h4v4_sse2; |
||||
c->put_vp8_epel_pixels_tab[1][1][2] = ff_put_vp8_epel8_h6v4_sse2; |
||||
c->put_vp8_epel_pixels_tab[1][2][0] = ff_put_vp8_epel8_v6_sse2; |
||||
c->put_vp8_epel_pixels_tab[1][2][1] = ff_put_vp8_epel8_h4v6_sse2; |
||||
c->put_vp8_epel_pixels_tab[1][2][2] = ff_put_vp8_epel8_h6v6_sse2; |
||||
} |
||||
|
||||
if (mm_flags & FF_MM_SSSE3) { |
||||
c->put_vp8_epel_pixels_tab[0][0][2] = ff_put_vp8_epel16_h6_ssse3; |
||||
c->put_vp8_epel_pixels_tab[0][2][0] = ff_put_vp8_epel16_v6_ssse3; |
||||
c->put_vp8_epel_pixels_tab[0][2][2] = ff_put_vp8_epel16_h6v6_ssse3; |
||||
c->put_vp8_epel_pixels_tab[1][0][1] = ff_put_vp8_epel8_h4_ssse3; |
||||
c->put_vp8_epel_pixels_tab[1][0][2] = ff_put_vp8_epel8_h6_ssse3; |
||||
c->put_vp8_epel_pixels_tab[1][1][0] = ff_put_vp8_epel8_v4_ssse3; |
||||
c->put_vp8_epel_pixels_tab[1][1][1] = ff_put_vp8_epel8_h4v4_ssse3; |
||||
c->put_vp8_epel_pixels_tab[1][1][2] = ff_put_vp8_epel8_h6v4_ssse3; |
||||
c->put_vp8_epel_pixels_tab[1][2][0] = ff_put_vp8_epel8_v6_ssse3; |
||||
c->put_vp8_epel_pixels_tab[1][2][1] = ff_put_vp8_epel8_h4v6_ssse3; |
||||
c->put_vp8_epel_pixels_tab[1][2][2] = ff_put_vp8_epel8_h6v6_ssse3; |
||||
} |
||||
|
||||
if (mm_flags & FF_MM_SSE4) { |
||||
c->vp8_idct_dc_add = ff_vp8_idct_dc_add_sse4; |
||||
} |
||||
} |
@ -0,0 +1,706 @@ |
||||
;****************************************************************************** |
||||
;* VP8 MMXEXT optimizations |
||||
;* Copyright (c) 2010 Ronald S. Bultje <rsbultje@gmail.com> |
||||
;* Copyright (c) 2010 Jason Garrett-Glaser <darkshikari@gmail.com> |
||||
;* |
||||
;* This file is part of FFmpeg. |
||||
;* |
||||
;* FFmpeg is free software; you can redistribute it and/or |
||||
;* modify it under the terms of the GNU Lesser General Public |
||||
;* License as published by the Free Software Foundation; either |
||||
;* version 2.1 of the License, or (at your option) any later version. |
||||
;* |
||||
;* FFmpeg is distributed in the hope that it will be useful, |
||||
;* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
;* Lesser General Public License for more details. |
||||
;* |
||||
;* You should have received a copy of the GNU Lesser General Public |
||||
;* License along with FFmpeg; if not, write to the Free Software |
||||
;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
;****************************************************************************** |
||||
|
||||
%include "x86inc.asm" |
||||
|
||||
SECTION_RODATA |
||||
|
||||
fourtap_filter_hw_m: times 4 dw -6, 123 |
||||
times 4 dw 12, -1 |
||||
times 4 dw -9, 93 |
||||
times 4 dw 50, -6 |
||||
times 4 dw -6, 50 |
||||
times 4 dw 93, -9 |
||||
times 4 dw -1, 12 |
||||
times 4 dw 123, -6 |
||||
|
||||
sixtap_filter_hw_m: times 4 dw 2, -11 |
||||
times 4 dw 108, 36 |
||||
times 4 dw -8, 1 |
||||
times 4 dw 3, -16 |
||||
times 4 dw 77, 77 |
||||
times 4 dw -16, 3 |
||||
times 4 dw 1, -8 |
||||
times 4 dw 36, 108 |
||||
times 4 dw -11, 2 |
||||
|
||||
fourtap_filter_hb_m: times 8 db -6, -1 |
||||
times 8 db 123, 12 |
||||
times 8 db -9, -6 |
||||
times 8 db 93, 50 |
||||
times 8 db -6, -9 |
||||
times 8 db 50, 93 |
||||
times 8 db -1, -6 |
||||
times 8 db 12, 123 |
||||
|
||||
sixtap_filter_hb_m: times 8 db 2, 1 |
||||
times 8 db -11, 108 |
||||
times 8 db 36, -8 |
||||
times 8 db 3, 3 |
||||
times 8 db -16, 77 |
||||
times 8 db 77, -16 |
||||
times 8 db 1, 2 |
||||
times 8 db -8, 36 |
||||
times 8 db 108, -11 |
||||
|
||||
fourtap_filter_v_m: times 8 dw -6 |
||||
times 8 dw 123 |
||||
times 8 dw 12 |
||||
times 8 dw -1 |
||||
times 8 dw -9 |
||||
times 8 dw 93 |
||||
times 8 dw 50 |
||||
times 8 dw -6 |
||||
times 8 dw -6 |
||||
times 8 dw 50 |
||||
times 8 dw 93 |
||||
times 8 dw -9 |
||||
times 8 dw -1 |
||||
times 8 dw 12 |
||||
times 8 dw 123 |
||||
times 8 dw -6 |
||||
|
||||
sixtap_filter_v_m: times 8 dw 2 |
||||
times 8 dw -11 |
||||
times 8 dw 108 |
||||
times 8 dw 36 |
||||
times 8 dw -8 |
||||
times 8 dw 1 |
||||
times 8 dw 3 |
||||
times 8 dw -16 |
||||
times 8 dw 77 |
||||
times 8 dw 77 |
||||
times 8 dw -16 |
||||
times 8 dw 3 |
||||
times 8 dw 1 |
||||
times 8 dw -8 |
||||
times 8 dw 36 |
||||
times 8 dw 108 |
||||
times 8 dw -11 |
||||
times 8 dw 2 |
||||
|
||||
%ifdef PIC |
||||
%define fourtap_filter_hw r11 |
||||
%define sixtap_filter_hw r11 |
||||
%define fourtap_filter_hb r11 |
||||
%define sixtap_filter_hb r11 |
||||
%define fourtap_filter_v r11 |
||||
%define sixtap_filter_v r11 |
||||
%else |
||||
%define fourtap_filter_hw fourtap_filter_hw_m |
||||
%define sixtap_filter_hw sixtap_filter_hw_m |
||||
%define fourtap_filter_hb fourtap_filter_hb_m |
||||
%define sixtap_filter_hb sixtap_filter_hb_m |
||||
%define fourtap_filter_v fourtap_filter_v_m |
||||
%define sixtap_filter_v sixtap_filter_v_m |
||||
%endif |
||||
|
||||
filter_v4_shuf1: db 0, 3, 1, 4, 2, 5, 3, 6, 4, 7, 5, 8, 6, 9, 7, 10 |
||||
filter_v4_shuf2: db 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9 |
||||
|
||||
filter_v6_shuf1: db 0, 5, 1, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12 |
||||
filter_v6_shuf2: db 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9 |
||||
filter_v6_shuf3: db 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11 |
||||
|
||||
cextern pw_4 |
||||
cextern pw_64 |
||||
|
||||
SECTION .text |
||||
|
||||
;----------------------------------------------------------------------------- |
||||
; subpel MC functions: |
||||
; |
||||
; void put_vp8_epel<size>_h<htap>v<vtap>_<opt>(uint8_t *dst, int deststride, |
||||
; uint8_t *src, int srcstride, |
||||
; int height, int mx, int my); |
||||
;----------------------------------------------------------------------------- |
||||
|
||||
; 4x4 block, H-only 4-tap filter |
||||
cglobal put_vp8_epel4_h4_mmxext, 6, 6 |
||||
shl r5d, 4 |
||||
%ifdef PIC |
||||
lea r11, [fourtap_filter_hw_m] |
||||
%endif |
||||
movq mm4, [fourtap_filter_hw+r5-16] ; set up 4tap filter in words |
||||
movq mm5, [fourtap_filter_hw+r5] |
||||
movq mm7, [pw_64] |
||||
pxor mm6, mm6 |
||||
|
||||
.nextrow |
||||
movq mm1, [r2-1] ; (ABCDEFGH) load 8 horizontal pixels |
||||
|
||||
; first set of 2 pixels |
||||
movq mm2, mm1 ; byte ABCD.. |
||||
punpcklbw mm1, mm6 ; byte->word ABCD |
||||
pshufw mm0, mm2, 9 ; byte CDEF.. |
||||
punpcklbw mm0, mm6 ; byte->word CDEF |
||||
pshufw mm3, mm1, 0x94 ; word ABBC |
||||
pshufw mm1, mm0, 0x94 ; word CDDE |
||||
pmaddwd mm3, mm4 ; multiply 2px with F0/F1 |
||||
movq mm0, mm1 ; backup for second set of pixels |
||||
pmaddwd mm1, mm5 ; multiply 2px with F2/F3 |
||||
paddd mm3, mm1 ; finish 1st 2px |
||||
|
||||
; second set of 2 pixels, use backup of above |
||||
punpckhbw mm2, mm6 ; byte->word EFGH |
||||
pmaddwd mm0, mm4 ; multiply backed up 2px with F0/F1 |
||||
pshufw mm1, mm2, 0x94 ; word EFFG |
||||
pmaddwd mm1, mm5 ; multiply 2px with F2/F3 |
||||
paddd mm0, mm1 ; finish 2nd 2px |
||||
|
||||
; merge two sets of 2 pixels into one set of 4, round/clip/store |
||||
packssdw mm3, mm0 ; merge dword->word (4px) |
||||
paddsw mm3, mm7 ; rounding |
||||
psraw mm3, 7 |
||||
packuswb mm3, mm6 ; clip and word->bytes |
||||
movd [r0], mm3 ; store |
||||
|
||||
; go to next line |
||||
add r0, r1 |
||||
add r2, r3 |
||||
dec r4 ; next row |
||||
jg .nextrow |
||||
REP_RET |
||||
|
||||
; 4x4 block, H-only 6-tap filter |
||||
cglobal put_vp8_epel4_h6_mmxext, 6, 6 |
||||
lea r5d, [r5*3] |
||||
%ifdef PIC |
||||
lea r11, [sixtap_filter_hw_m] |
||||
%endif |
||||
movq mm4, [sixtap_filter_hw+r5*8-48] ; set up 4tap filter in words |
||||
movq mm5, [sixtap_filter_hw+r5*8-32] |
||||
movq mm6, [sixtap_filter_hw+r5*8-16] |
||||
movq mm7, [pw_64] |
||||
pxor mm3, mm3 |
||||
|
||||
.nextrow |
||||
movq mm1, [r2-2] ; (ABCDEFGH) load 8 horizontal pixels |
||||
|
||||
; first set of 2 pixels |
||||
movq mm2, mm1 ; byte ABCD.. |
||||
punpcklbw mm1, mm3 ; byte->word ABCD |
||||
pshufw mm0, mm2, 0x9 ; byte CDEF.. |
||||
punpckhbw mm2, mm3 ; byte->word EFGH |
||||
punpcklbw mm0, mm3 ; byte->word CDEF |
||||
pshufw mm1, mm1, 0x94 ; word ABBC |
||||
pshufw mm2, mm2, 0x94 ; word EFFG |
||||
pmaddwd mm1, mm4 ; multiply 2px with F0/F1 |
||||
pshufw mm3, mm0, 0x94 ; word CDDE |
||||
movq mm0, mm3 ; backup for second set of pixels |
||||
pmaddwd mm3, mm5 ; multiply 2px with F2/F3 |
||||
paddd mm1, mm3 ; add to 1st 2px cache |
||||
movq mm3, mm2 ; backup for second set of pixels |
||||
pmaddwd mm2, mm6 ; multiply 2px with F4/F5 |
||||
paddd mm1, mm2 ; finish 1st 2px |
||||
|
||||
; second set of 2 pixels, use backup of above |
||||
movd mm2, [r2+3] ; byte FGHI (prevent overreads) |
||||
pmaddwd mm0, mm4 ; multiply 1st backed up 2px with F0/F1 |
||||
pmaddwd mm3, mm5 ; multiply 2nd backed up 2px with F2/F3 |
||||
paddd mm0, mm3 ; add to 2nd 2px cache |
||||
pxor mm3, mm3 |
||||
punpcklbw mm2, mm3 ; byte->word FGHI |
||||
pshufw mm2, mm2, 0xE9 ; word GHHI |
||||
pmaddwd mm2, mm6 ; multiply 2px with F4/F5 |
||||
paddd mm0, mm2 ; finish 2nd 2px |
||||
|
||||
; merge two sets of 2 pixels into one set of 4, round/clip/store |
||||
packssdw mm1, mm0 ; merge dword->word (4px) |
||||
paddsw mm1, mm7 ; rounding |
||||
psraw mm1, 7 |
||||
packuswb mm1, mm3 ; clip and word->bytes |
||||
movd [r0], mm1 ; store |
||||
|
||||
; go to next line |
||||
add r0, r1 |
||||
add r2, r3 |
||||
dec r4 ; next row |
||||
jg .nextrow |
||||
REP_RET |
||||
|
||||
; 4x4 block, H-only 4-tap filter |
||||
INIT_XMM |
||||
cglobal put_vp8_epel8_h4_sse2, 6, 6, 8 |
||||
shl r5d, 4 |
||||
%ifdef PIC |
||||
lea r11, [fourtap_filter_hw_m] |
||||
%endif |
||||
mova m5, [fourtap_filter_hw+r5-16] ; set up 4tap filter in words |
||||
mova m6, [fourtap_filter_hw+r5] |
||||
pxor m7, m7 |
||||
|
||||
.nextrow |
||||
movh m0, [r2-1] |
||||
punpcklbw m0, m7 ; ABCDEFGH |
||||
mova m1, m0 |
||||
mova m2, m0 |
||||
mova m3, m0 |
||||
psrldq m1, 2 ; BCDEFGH |
||||
psrldq m2, 4 ; CDEFGH |
||||
psrldq m3, 6 ; DEFGH |
||||
punpcklwd m0, m1 ; ABBCCDDE |
||||
punpcklwd m2, m3 ; CDDEEFFG |
||||
pmaddwd m0, m5 |
||||
pmaddwd m2, m6 |
||||
paddd m0, m2 |
||||
|
||||
movh m1, [r2+3] |
||||
punpcklbw m1, m7 ; ABCDEFGH |
||||
mova m2, m1 |
||||
mova m3, m1 |
||||
mova m4, m1 |
||||
psrldq m2, 2 ; BCDEFGH |
||||
psrldq m3, 4 ; CDEFGH |
||||
psrldq m4, 6 ; DEFGH |
||||
punpcklwd m1, m2 ; ABBCCDDE |
||||
punpcklwd m3, m4 ; CDDEEFFG |
||||
pmaddwd m1, m5 |
||||
pmaddwd m3, m6 |
||||
paddd m1, m3 |
||||
|
||||
packssdw m0, m1 |
||||
paddsw m0, [pw_64] |
||||
psraw m0, 7 |
||||
packuswb m0, m7 |
||||
movh [r0], m0 ; store |
||||
|
||||
; go to next line |
||||
add r0, r1 |
||||
add r2, r3 |
||||
dec r4 ; next row |
||||
jg .nextrow |
||||
REP_RET |
||||
|
||||
cglobal put_vp8_epel8_h6_sse2, 6, 6, 8 |
||||
lea r5d, [r5*3] |
||||
%ifdef PIC |
||||
lea r11, [sixtap_filter_hw_m] |
||||
%endif |
||||
lea r5, [sixtap_filter_hw+r5*8] |
||||
pxor m7, m7 |
||||
|
||||
.nextrow |
||||
movu m0, [r2-2] |
||||
mova m6, m0 |
||||
mova m4, m0 |
||||
punpcklbw m0, m7 ; ABCDEFGHI |
||||
mova m1, m0 |
||||
mova m2, m0 |
||||
mova m3, m0 |
||||
psrldq m1, 2 ; BCDEFGH |
||||
psrldq m2, 4 ; CDEFGH |
||||
psrldq m3, 6 ; DEFGH |
||||
psrldq m4, 4 |
||||
punpcklbw m4, m7 ; EFGH |
||||
mova m5, m4 |
||||
psrldq m5, 2 ; FGH |
||||
punpcklwd m0, m1 ; ABBCCDDE |
||||
punpcklwd m2, m3 ; CDDEEFFG |
||||
punpcklwd m4, m5 ; EFFGGHHI |
||||
pmaddwd m0, [r5-48] |
||||
pmaddwd m2, [r5-32] |
||||
pmaddwd m4, [r5-16] |
||||
paddd m0, m2 |
||||
paddd m0, m4 |
||||
|
||||
psrldq m6, 4 |
||||
mova m4, m6 |
||||
punpcklbw m6, m7 ; ABCDEFGHI |
||||
mova m1, m6 |
||||
mova m2, m6 |
||||
mova m3, m6 |
||||
psrldq m1, 2 ; BCDEFGH |
||||
psrldq m2, 4 ; CDEFGH |
||||
psrldq m3, 6 ; DEFGH |
||||
psrldq m4, 4 |
||||
punpcklbw m4, m7 ; EFGH |
||||
mova m5, m4 |
||||
psrldq m5, 2 ; FGH |
||||
punpcklwd m6, m1 ; ABBCCDDE |
||||
punpcklwd m2, m3 ; CDDEEFFG |
||||
punpcklwd m4, m5 ; EFFGGHHI |
||||
pmaddwd m6, [r5-48] |
||||
pmaddwd m2, [r5-32] |
||||
pmaddwd m4, [r5-16] |
||||
paddd m6, m2 |
||||
paddd m6, m4 |
||||
|
||||
packssdw m0, m6 |
||||
paddsw m0, [pw_64] |
||||
psraw m0, 7 |
||||
packuswb m0, m7 |
||||
movh [r0], m0 ; store |
||||
|
||||
; go to next line |
||||
add r0, r1 |
||||
add r2, r3 |
||||
dec r4 ; next row |
||||
jg .nextrow |
||||
REP_RET |
||||
|
||||
cglobal put_vp8_epel8_h4_ssse3, 6, 6, 7 |
||||
shl r5d, 4 |
||||
mova m2, [pw_64] |
||||
mova m3, [filter_v4_shuf1] |
||||
mova m4, [filter_v4_shuf2] |
||||
%ifdef PIC |
||||
lea r11, [fourtap_filter_hb_m] |
||||
%endif |
||||
mova m5, [fourtap_filter_hb+r5-16] ; set up 4tap filter in bytes |
||||
mova m6, [fourtap_filter_hb+r5] |
||||
|
||||
.nextrow |
||||
movu m0, [r2-1] |
||||
mova m1, m0 |
||||
pshufb m0, m3 |
||||
pshufb m1, m4 |
||||
pmaddubsw m0, m5 |
||||
pmaddubsw m1, m6 |
||||
paddsw m0, m2 |
||||
paddsw m0, m1 |
||||
psraw m0, 7 |
||||
packuswb m0, m0 |
||||
movh [r0], m0 ; store |
||||
|
||||
; go to next line |
||||
add r0, r1 |
||||
add r2, r3 |
||||
dec r4 ; next row |
||||
jg .nextrow |
||||
REP_RET |
||||
|
||||
cglobal put_vp8_epel8_h6_ssse3, 6, 6, 8 |
||||
lea r5d, [r5*3] |
||||
mova m3, [filter_v6_shuf1] |
||||
mova m4, [filter_v6_shuf2] |
||||
%ifdef PIC |
||||
lea r11, [sixtap_filter_hb_m] |
||||
%endif |
||||
mova m5, [sixtap_filter_hb+r5*8-48] ; set up 6tap filter in bytes |
||||
mova m6, [sixtap_filter_hb+r5*8-32] |
||||
mova m7, [sixtap_filter_hb+r5*8-16] |
||||
|
||||
.nextrow |
||||
movu m0, [r2-2] |
||||
mova m1, m0 |
||||
mova m2, m0 |
||||
pshufb m0, m3 |
||||
pshufb m1, m4 |
||||
pshufb m2, [filter_v6_shuf3] |
||||
pmaddubsw m0, m5 |
||||
pmaddubsw m1, m6 |
||||
pmaddubsw m2, m7 |
||||
paddsw m0, m1 |
||||
paddsw m0, m2 |
||||
paddsw m0, [pw_64] |
||||
psraw m0, 7 |
||||
packuswb m0, m0 |
||||
movh [r0], m0 ; store |
||||
|
||||
; go to next line |
||||
add r0, r1 |
||||
add r2, r3 |
||||
dec r4 ; next row |
||||
jg .nextrow |
||||
REP_RET |
||||
|
||||
%macro FILTER_V 3 |
||||
; 4x4 block, V-only 4-tap filter |
||||
cglobal put_vp8_epel%2_v4_%1, 7, 7, %3 |
||||
shl r6d, 5 |
||||
%ifdef PIC |
||||
lea r11, [fourtap_filter_v_m] |
||||
%endif |
||||
lea r6, [fourtap_filter_v+r6-32] |
||||
mova m6, [pw_64] |
||||
pxor m7, m7 |
||||
mova m5, [r6+48] |
||||
|
||||
; read 3 lines |
||||
sub r2, r3 |
||||
movh m0, [r2] |
||||
movh m1, [r2+ r3] |
||||
movh m2, [r2+2*r3] |
||||
add r2, r3 |
||||
punpcklbw m0, m7 |
||||
punpcklbw m1, m7 |
||||
punpcklbw m2, m7 |
||||
|
||||
.nextrow |
||||
; first calculate negative taps (to prevent losing positive overflows) |
||||
movh m4, [r2+2*r3] ; read new row |
||||
punpcklbw m4, m7 |
||||
mova m3, m4 |
||||
pmullw m0, [r6+0] |
||||
pmullw m4, m5 |
||||
paddsw m4, m0 |
||||
|
||||
; then calculate positive taps |
||||
mova m0, m1 |
||||
pmullw m1, [r6+16] |
||||
paddsw m4, m1 |
||||
mova m1, m2 |
||||
pmullw m2, [r6+32] |
||||
paddsw m4, m2 |
||||
mova m2, m3 |
||||
|
||||
; round/clip/store |
||||
paddsw m4, m6 |
||||
psraw m4, 7 |
||||
packuswb m4, m7 |
||||
movh [r0], m4 |
||||
|
||||
; go to next line |
||||
add r0, r1 |
||||
add r2, r3 |
||||
dec r4 ; next row |
||||
jg .nextrow |
||||
REP_RET |
||||
|
||||
|
||||
; 4x4 block, V-only 6-tap filter |
||||
cglobal put_vp8_epel%2_v6_%1, 7, 7, %3 |
||||
shl r6d, 4 |
||||
lea r6, [r6*3] |
||||
%ifdef PIC |
||||
lea r11, [sixtap_filter_v_m] |
||||
%endif |
||||
lea r6, [sixtap_filter_v+r6-96] |
||||
pxor m7, m7 |
||||
|
||||
; read 5 lines |
||||
sub r2, r3 |
||||
sub r2, r3 |
||||
movh m0, [r2] |
||||
movh m1, [r2+r3] |
||||
movh m2, [r2+r3*2] |
||||
lea r2, [r2+r3*2] |
||||
add r2, r3 |
||||
movh m3, [r2] |
||||
movh m4, [r2+r3] |
||||
punpcklbw m0, m7 |
||||
punpcklbw m1, m7 |
||||
punpcklbw m2, m7 |
||||
punpcklbw m3, m7 |
||||
punpcklbw m4, m7 |
||||
|
||||
.nextrow |
||||
; first calculate negative taps (to prevent losing positive overflows) |
||||
mova m5, m1 |
||||
pmullw m5, [r6+16] |
||||
mova m6, m4 |
||||
pmullw m6, [r6+64] |
||||
paddsw m6, m5 |
||||
|
||||
; then calculate positive taps |
||||
movh m5, [r2+2*r3] ; read new row |
||||
punpcklbw m5, m7 |
||||
pmullw m0, [r6+0] |
||||
paddsw m6, m0 |
||||
mova m0, m1 |
||||
mova m1, m2 |
||||
pmullw m2, [r6+32] |
||||
paddsw m6, m2 |
||||
mova m2, m3 |
||||
pmullw m3, [r6+48] |
||||
paddsw m6, m3 |
||||
mova m3, m4 |
||||
mova m4, m5 |
||||
pmullw m5, [r6+80] |
||||
paddsw m6, m5 |
||||
|
||||
; round/clip/store |
||||
paddsw m6, [pw_64] |
||||
psraw m6, 7 |
||||
packuswb m6, m7 |
||||
movh [r0], m6 |
||||
|
||||
; go to next line |
||||
add r0, r1 |
||||
add r2, r3 |
||||
dec r4 ; next row |
||||
jg .nextrow |
||||
REP_RET |
||||
%endmacro |
||||
|
||||
INIT_MMX |
||||
FILTER_V mmxext, 4, 0 |
||||
INIT_XMM |
||||
FILTER_V sse2, 8, 8 |
||||
|
||||
cglobal put_vp8_epel8_v4_ssse3, 7, 7, 8 |
||||
shl r6d, 4 |
||||
%ifdef PIC |
||||
lea r11, [fourtap_filter_hb_m] |
||||
%endif |
||||
mova m5, [fourtap_filter_hb+r6-16] |
||||
mova m6, [fourtap_filter_hb+r6] |
||||
mova m7, [pw_64] |
||||
|
||||
; read 3 lines |
||||
sub r2, r3 |
||||
movh m0, [r2] |
||||
movh m1, [r2+ r3] |
||||
movh m2, [r2+2*r3] |
||||
add r2, r3 |
||||
|
||||
.nextrow |
||||
movh m3, [r2+2*r3] ; read new row |
||||
mova m4, m0 |
||||
mova m0, m1 |
||||
punpcklbw m4, m3 |
||||
punpcklbw m1, m2 |
||||
pmaddubsw m4, m5 |
||||
pmaddubsw m1, m6 |
||||
paddsw m4, m1 |
||||
mova m1, m2 |
||||
paddsw m4, m7 |
||||
mova m2, m3 |
||||
psraw m4, 7 |
||||
packuswb m4, m4 |
||||
movh [r0], m4 |
||||
|
||||
; go to next line |
||||
add r0, r1 |
||||
add r2, r3 |
||||
dec r4 ; next row |
||||
jg .nextrow |
||||
REP_RET |
||||
|
||||
cglobal put_vp8_epel8_v6_ssse3, 7, 7, 8 |
||||
lea r6d, [r6*3] |
||||
%ifdef PIC |
||||
lea r11, [sixtap_filter_hb_m] |
||||
%endif |
||||
lea r6, [sixtap_filter_hb+r6*8] |
||||
|
||||
; read 5 lines |
||||
sub r2, r3 |
||||
sub r2, r3 |
||||
movh m0, [r2] |
||||
movh m1, [r2+r3] |
||||
movh m2, [r2+r3*2] |
||||
lea r2, [r2+r3*2] |
||||
add r2, r3 |
||||
movh m3, [r2] |
||||
movh m4, [r2+r3] |
||||
|
||||
.nextrow |
||||
movh m5, [r2+2*r3] ; read new row |
||||
mova m6, m0 |
||||
punpcklbw m6, m5 |
||||
mova m0, m1 |
||||
punpcklbw m1, m2 |
||||
mova m7, m3 |
||||
punpcklbw m7, m4 |
||||
pmaddubsw m6, [r6-48] |
||||
pmaddubsw m1, [r6-32] |
||||
pmaddubsw m7, [r6-16] |
||||
paddsw m6, m1 |
||||
paddsw m6, m7 |
||||
mova m1, m2 |
||||
paddsw m6, [pw_64] |
||||
mova m2, m3 |
||||
psraw m6, 7 |
||||
mova m3, m4 |
||||
packuswb m6, m6 |
||||
mova m4, m5 |
||||
movh [r0], m6 |
||||
|
||||
; go to next line |
||||
add r0, r1 |
||||
add r2, r3 |
||||
dec r4 ; next row |
||||
jg .nextrow |
||||
REP_RET |
||||
|
||||
;----------------------------------------------------------------------------- |
||||
; IDCT functions: |
||||
; |
||||
; void vp8_idct_dc_add_<opt>(uint8_t *dst, DCTELEM block[16], int stride); |
||||
;----------------------------------------------------------------------------- |
||||
|
||||
cglobal vp8_idct_dc_add_mmx, 3, 3 |
||||
; load data |
||||
movd mm0, [r1] |
||||
|
||||
; calculate DC |
||||
paddw mm0, [pw_4] |
||||
pxor mm1, mm1 |
||||
psraw mm0, 3 |
||||
psubw mm1, mm0 |
||||
packuswb mm0, mm0 |
||||
packuswb mm1, mm1 |
||||
punpcklbw mm0, mm0 |
||||
punpcklbw mm1, mm1 |
||||
punpcklwd mm0, mm0 |
||||
punpcklwd mm1, mm1 |
||||
|
||||
; add DC |
||||
lea r1, [r0+r2*2] |
||||
movd mm2, [r0] |
||||
movd mm3, [r0+r2] |
||||
movd mm4, [r1] |
||||
movd mm5, [r1+r2] |
||||
paddusb mm2, mm0 |
||||
paddusb mm3, mm0 |
||||
paddusb mm4, mm0 |
||||
paddusb mm5, mm0 |
||||
psubusb mm2, mm1 |
||||
psubusb mm3, mm1 |
||||
psubusb mm4, mm1 |
||||
psubusb mm5, mm1 |
||||
movd [r0], mm2 |
||||
movd [r0+r2], mm3 |
||||
movd [r1], mm4 |
||||
movd [r1+r2], mm5 |
||||
RET |
||||
|
||||
cglobal vp8_idct_dc_add_sse4, 3, 3, 6 |
||||
; load data |
||||
movd xmm0, [r1] |
||||
lea r1, [r0+r2*2] |
||||
pxor xmm1, xmm1 |
||||
movq xmm2, [pw_4] |
||||
|
||||
; calculate DC |
||||
paddw xmm0, xmm2 |
||||
movd xmm2, [r0] |
||||
movd xmm3, [r0+r2] |
||||
movd xmm4, [r1] |
||||
movd xmm5, [r1+r2] |
||||
psraw xmm0, 3 |
||||
pshuflw xmm0, xmm0, 0 |
||||
punpcklqdq xmm0, xmm0 |
||||
punpckldq xmm2, xmm3 |
||||
punpckldq xmm4, xmm5 |
||||
punpcklbw xmm2, xmm1 |
||||
punpcklbw xmm4, xmm1 |
||||
paddw xmm2, xmm0 |
||||
paddw xmm4, xmm0 |
||||
packuswb xmm2, xmm4 |
||||
movd [r0], xmm2 |
||||
pextrd [r0+r2], xmm2, 1 |
||||
pextrd [r1], xmm2, 2 |
||||
pextrd [r1+r2], xmm2, 3 |
||||
RET |
Loading…
Reference in new issue