Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. ;*****************************************************************************
  2. ;* x86-optimized functions for ssim filter
  3. ;*
  4. ;* Copyright (C) 2015 Ronald S. Bultje <rsbultje@gmail.com>
  5. ;*
  6. ;* This file is part of FFmpeg.
  7. ;*
  8. ;* FFmpeg is free software; you can redistribute it and/or
  9. ;* modify it under the terms of the GNU Lesser General Public
  10. ;* License as published by the Free Software Foundation; either
  11. ;* version 2.1 of the License, or (at your option) any later version.
  12. ;*
  13. ;* FFmpeg is distributed in the hope that it will be useful,
  14. ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16. ;* Lesser General Public License for more details.
  17. ;*
  18. ;* You should have received a copy of the GNU Lesser General Public
  19. ;* License along with FFmpeg; if not, write to the Free Software
  20. ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. ;******************************************************************************
  22.  
  23. %include "libavutil/x86/x86util.asm"
  24.  
  25. SECTION_RODATA
  26.  
  27. pw_1: times 8 dw 1
  28. ssim_c1: times 4 dd 416 ;(.01*.01*255*255*64 + .5)
  29. ssim_c2: times 4 dd 235963 ;(.03*.03*255*255*64*63 + .5)
  30.  
  31. SECTION .text
  32.  
  33. %macro SSIM_4X4_LINE 1
  34. %if ARCH_X86_64
  35. cglobal ssim_4x4_line, 6, 8, %1, buf, buf_stride, ref, ref_stride, sums, w, buf_stride3, ref_stride3
  36. %else
  37. cglobal ssim_4x4_line, 5, 7, %1, buf, buf_stride, ref, ref_stride, sums, buf_stride3, ref_stride3
  38. %define wd r5mp
  39. %endif
  40.     lea     ref_stride3q, [ref_strideq*3]
  41.     lea     buf_stride3q, [buf_strideq*3]
  42. %if notcpuflag(xop)
  43.     pxor              m7, m7
  44.     mova             m15, [pw_1]
  45. %endif
  46.  
  47. .loop:
  48. %if cpuflag(xop)
  49.     pmovzxbw          m0, [bufq+buf_strideq*0]
  50.     pmovzxbw          m1, [refq+ref_strideq*0]
  51.     pmaddwd           m4, m0, m0
  52.     pmaddwd           m6, m0, m1
  53.     pmovzxbw          m2, [bufq+buf_strideq*1]
  54.     vpmadcswd         m4, m1, m1, m4
  55.     pmovzxbw          m3, [refq+ref_strideq*1]
  56.     paddw             m0, m2
  57.     vpmadcswd         m4, m2, m2, m4
  58.     vpmadcswd         m6, m2, m3, m6
  59.     paddw             m1, m3
  60.     vpmadcswd         m4, m3, m3, m4
  61.  
  62.     pmovzxbw          m2, [bufq+buf_strideq*2]
  63.     pmovzxbw          m3, [refq+ref_strideq*2]
  64.     vpmadcswd         m4, m2, m2, m4
  65.     vpmadcswd         m6, m2, m3, m6
  66.     pmovzxbw          m5, [bufq+buf_stride3q]
  67.     pmovzxbw          m7, [refq+ref_stride3q]
  68.     vpmadcswd         m4, m3, m3, m4
  69.     vpmadcswd         m6, m5, m7, m6
  70.     paddw             m0, m2
  71.     paddw             m1, m3
  72.     vpmadcswd         m4, m5, m5, m4
  73.     paddw             m0, m5
  74.     paddw             m1, m7
  75.     vpmadcswd         m4, m7, m7, m4
  76. %else
  77.     movh              m0, [bufq+buf_strideq*0]  ; a1
  78.     movh              m1, [refq+ref_strideq*0]  ; b1
  79.     movh              m2, [bufq+buf_strideq*1]  ; a2
  80.     movh              m3, [refq+ref_strideq*1]  ; b2
  81.     punpcklbw         m0, m7                    ; s1 [word]
  82.     punpcklbw         m1, m7                    ; s2 [word]
  83.     punpcklbw         m2, m7                    ; s1 [word]
  84.     punpcklbw         m3, m7                    ; s2 [word]
  85.     pmaddwd           m4, m0, m0                ; a1 * a1
  86.     pmaddwd           m5, m1, m1                ; b1 * b1
  87.     pmaddwd           m8, m2, m2                ; a2 * a2
  88.     pmaddwd           m9, m3, m3                ; b2 * b2
  89.     paddd             m4, m5                    ; ss
  90.     paddd             m8, m9                    ; ss
  91.     pmaddwd           m6, m0, m1                ; a1 * b1 = ss12
  92.     pmaddwd           m5, m2, m3                ; a2 * b2 = ss12
  93.     paddw             m0, m2
  94.     paddw             m1, m3
  95.     paddd             m6, m5                    ; s12
  96.     paddd             m4, m8                    ; ss
  97.  
  98.     movh              m2, [bufq+buf_strideq*2]  ; a3
  99.     movh              m3, [refq+ref_strideq*2]  ; b3
  100.     movh              m5, [bufq+buf_stride3q]   ; a4
  101.     movh              m8, [refq+ref_stride3q]   ; b4
  102.     punpcklbw         m2, m7                    ; s1 [word]
  103.     punpcklbw         m3, m7                    ; s2 [word]
  104.     punpcklbw         m5, m7                    ; s1 [word]
  105.     punpcklbw         m8, m7                    ; s2 [word]
  106.     pmaddwd           m9, m2, m2                ; a3 * a3
  107.     pmaddwd          m10, m3, m3                ; b3 * b3
  108.     pmaddwd          m12, m5, m5                ; a4 * a4
  109.     pmaddwd          m13, m8, m8                ; b4 * b4
  110.     pmaddwd          m11, m2, m3                ; a3 * b3 = ss12
  111.     pmaddwd          m14, m5, m8                ; a4 * b4 = ss12
  112.     paddd             m9, m10
  113.     paddd            m12, m13
  114.     paddw             m0, m2
  115.     paddw             m1, m3
  116.     paddw             m0, m5
  117.     paddw             m1, m8
  118.     paddd             m6, m11
  119.     paddd             m4, m9
  120.     paddd             m6, m14
  121.     paddd             m4, m12
  122. %endif
  123.  
  124.     ; m0 = [word] s1 a,a,a,a,b,b,b,b
  125.     ; m1 = [word] s2 a,a,a,a,b,b,b,b
  126.     ; m4 = [dword] ss a,a,b,b
  127.     ; m6 = [dword] s12 a,a,b,b
  128.  
  129. %if cpuflag(xop)
  130.     vphaddwq          m0, m0                    ; [dword] s1  a, 0, b, 0
  131.     vphaddwq          m1, m1                    ; [dword] s2  a, 0, b, 0
  132.     vphadddq          m4, m4                    ; [dword] ss  a, 0, b, 0
  133.     vphadddq          m6, m6                    ; [dword] s12 a, 0, b, 0
  134.     punpckhdq     m2, m0, m1                    ; [dword] s1  b, s2 b, 0, 0
  135.     punpckldq         m0, m1                    ; [dword] s1  a, s2 a, 0, 0
  136.     punpckhdq     m3, m4, m6                    ; [dword] ss  b, s12 b, 0, 0
  137.     punpckldq         m4, m6                    ; [dword] ss  a, s12 a, 0, 0
  138.     punpcklqdq    m1, m2, m3                    ; [dword] b s1, s2, ss, s12
  139.     punpcklqdq        m0, m4                    ; [dword] a s1, s2, ss, s12
  140. %else
  141.     pmaddwd           m0, m15                   ; [dword] s1 a,a,b,b
  142.     pmaddwd           m1, m15                   ; [dword] s2 a,a,b,b
  143.     phaddd            m0, m4                    ; [dword] s1 a, b, ss a, b
  144.     phaddd            m1, m6                    ; [dword] s2 a, b, s12 a, b
  145.     punpckhdq     m2, m0, m1                    ; [dword] ss a, s12 a, ss b, s12 b
  146.     punpckldq         m0, m1                    ; [dword] s1 a, s2 a, s1 b, s2 b
  147.     punpckhqdq    m1, m0, m2                    ; [dword] b s1, s2, ss, s12
  148.     punpcklqdq        m0, m2                    ; [dword] a s1, s2, ss, s12
  149. %endif
  150.  
  151.     mova  [sumsq+     0], m0
  152.     mova  [sumsq+mmsize], m1
  153.  
  154.     add             bufq, mmsize/2
  155.     add             refq, mmsize/2
  156.     add            sumsq, mmsize*2
  157.     sub               wd, mmsize/8
  158.     jg .loop
  159.     RET
  160. %endmacro
  161.  
  162. %if ARCH_X86_64
  163. INIT_XMM ssse3
  164. SSIM_4X4_LINE 16
  165. %endif
  166. %if HAVE_XOP_EXTERNAL
  167. INIT_XMM xop
  168. SSIM_4X4_LINE 8
  169. %endif
  170.  
  171. INIT_XMM sse4
  172. cglobal ssim_end_line, 3, 3, 6, sum0, sum1, w
  173.     pxor              m0, m0
  174. .loop:
  175.     mova              m1, [sum0q+mmsize*0]
  176.     mova              m2, [sum0q+mmsize*1]
  177.     mova              m3, [sum0q+mmsize*2]
  178.     mova              m4, [sum0q+mmsize*3]
  179.     paddd             m1, [sum1q+mmsize*0]
  180.     paddd             m2, [sum1q+mmsize*1]
  181.     paddd             m3, [sum1q+mmsize*2]
  182.     paddd             m4, [sum1q+mmsize*3]
  183.     paddd             m1, m2
  184.     paddd             m2, m3
  185.     paddd             m3, m4
  186.     paddd             m4, [sum0q+mmsize*4]
  187.     paddd             m4, [sum1q+mmsize*4]
  188.     TRANSPOSE4x4D      1, 2, 3, 4, 5
  189.  
  190.     ; m1 = fs1, m2 = fs2, m3 = fss, m4 = fs12
  191.     pslld             m3, 6
  192.     pslld             m4, 6
  193.     pmulld            m5, m1, m2                ; fs1 * fs2
  194.     pmulld            m1, m1                    ; fs1 * fs1
  195.     pmulld            m2, m2                    ; fs2 * fs2
  196.     psubd             m3, m1
  197.     psubd             m4, m5                    ; covariance
  198.     psubd             m3, m2                    ; variance
  199.  
  200.     ; m1 = fs1 * fs1, m2 = fs2 * fs2, m3 = variance, m4 = covariance, m5 = fs1 * fs2
  201.     paddd             m4, m4                    ; 2 * covariance
  202.     paddd             m5, m5                    ; 2 * fs1 * fs2
  203.     paddd             m1, m2                    ; fs1 * fs1 + fs2 * fs2
  204.     paddd             m3, [ssim_c2]             ; variance + ssim_c2
  205.     paddd             m4, [ssim_c2]             ; 2 * covariance + ssim_c2
  206.     paddd             m5, [ssim_c1]             ; 2 * fs1 * fs2 + ssim_c1
  207.     paddd             m1, [ssim_c1]             ; fs1 * fs1 + fs2 * fs2 + ssim_c1
  208.  
  209.     ; convert to float
  210.     cvtdq2ps          m3, m3
  211.     cvtdq2ps          m4, m4
  212.     cvtdq2ps          m5, m5
  213.     cvtdq2ps          m1, m1
  214.     mulps             m4, m5
  215.     mulps             m3, m1
  216.     divps             m4, m3                    ; ssim_endl
  217.     addps             m0, m4                    ; ssim
  218.     add            sum0q, mmsize*4
  219.     add            sum1q, mmsize*4
  220.     sub               wd, 4
  221.     jg .loop
  222.  
  223.     ; subps the ones we added too much
  224.     test              wd, wd
  225.     jz .end
  226.     add               wd, 4
  227.     test              wd, 2
  228.     jz .skip2
  229.     psrldq            m4, 8
  230. .skip2:
  231.     test              wd, 1
  232.     jz .skip1
  233.     psrldq            m4, 4
  234. .skip1:
  235.     subps             m0, m4
  236.  
  237. .end:
  238.     movhlps           m4, m0
  239.     addps             m0, m4
  240.     movss             m4, m0
  241.     shufps            m0, m0, 1
  242.     addss             m0, m4
  243. %if ARCH_X86_32
  244.     movss            r0m, m0
  245.     fld             r0mp
  246. %endif
  247.     RET
  248.