]> git.sesse.net Git - x264/blob - common/x86/deblock-a.asm
skip intra pred+dct+quant in cases where it's redundant (analyse vs encode)
[x264] / common / x86 / deblock-a.asm
1 ;*****************************************************************************
2 ;* deblock-a.asm: h264 encoder library
3 ;*****************************************************************************
4 ;* Copyright (C) 2005-2008 x264 project
5 ;*
6 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
7 ;*
8 ;* This program is free software; you can redistribute it and/or modify
9 ;* it under the terms of the GNU General Public License as published by
10 ;* the Free Software Foundation; either version 2 of the License, or
11 ;* (at your option) any later version.
12 ;*
13 ;* This program 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
16 ;* GNU General Public License for more details.
17 ;*
18 ;* You should have received a copy of the GNU General Public License
19 ;* along with this program; if not, write to the Free Software
20 ;* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
21 ;*****************************************************************************
22
23 %include "x86inc.asm"
24
25 SECTION_RODATA
26 pb_01: times 16 db 0x01
27 pb_03: times 16 db 0x03
28 pb_a1: times 16 db 0xa1
29
30 SECTION .text
31
32 %macro INIT_MMX 0
33     %undef movq
34     %define m0 mm0
35     %define m1 mm1
36     %define m2 mm2
37     %define m3 mm3
38     %define m4 mm4
39     %define m5 mm5
40     %define m6 mm6
41     %define m7 mm7
42     %undef  m8
43     %undef  m9
44 %endmacro
45
46 %macro INIT_XMM 0
47     %define movq movdqa
48     %define m0 xmm0
49     %define m1 xmm1
50     %define m2 xmm2
51     %define m3 xmm3
52     %define m4 xmm4
53     %define m5 xmm5
54     %define m6 xmm6
55     %define m7 xmm7
56     %define m8 xmm8
57     %define m9 xmm9
58 %endmacro
59
60 ; expands to [base],...,[base+7*stride]
61 %define PASS8ROWS(base, base3, stride, stride3) \
62     [base], [base+stride], [base+stride*2], [base3], \
63     [base3+stride], [base3+stride*2], [base3+stride3], [base3+stride*4]
64
65 ; in: 8 rows of 4 bytes in %1..%8
66 ; out: 4 rows of 8 bytes in m0..m3
67 %macro TRANSPOSE4x8_LOAD 8
68     movd       m0, %1
69     movd       m2, %2
70     movd       m1, %3
71     movd       m3, %4
72     punpcklbw  m0, m2
73     punpcklbw  m1, m3
74     movq       m2, m0
75     punpcklwd  m0, m1
76     punpckhwd  m2, m1
77
78     movd       m4, %5
79     movd       m6, %6
80     movd       m5, %7
81     movd       m7, %8
82     punpcklbw  m4, m6
83     punpcklbw  m5, m7
84     movq       m6, m4
85     punpcklwd  m4, m5
86     punpckhwd  m6, m5
87
88     movq       m1, m0
89     movq       m3, m2
90     punpckldq  m0, m4
91     punpckhdq  m1, m4
92     punpckldq  m2, m6
93     punpckhdq  m3, m6
94 %endmacro
95
96 ; in: 4 rows of 8 bytes in m0..m3
97 ; out: 8 rows of 4 bytes in %1..%8
98 %macro TRANSPOSE8x4_STORE 8
99     movq       m4, m0
100     movq       m5, m1
101     movq       m6, m2
102     punpckhdq  m4, m4
103     punpckhdq  m5, m5
104     punpckhdq  m6, m6
105
106     punpcklbw  m0, m1
107     punpcklbw  m2, m3
108     movq       m1, m0
109     punpcklwd  m0, m2
110     punpckhwd  m1, m2
111     movd       %1, m0
112     punpckhdq  m0, m0
113     movd       %2, m0
114     movd       %3, m1
115     punpckhdq  m1, m1
116     movd       %4, m1
117
118     punpckhdq  m3, m3
119     punpcklbw  m4, m5
120     punpcklbw  m6, m3
121     movq       m5, m4
122     punpcklwd  m4, m6
123     punpckhwd  m5, m6
124     movd       %5, m4
125     punpckhdq  m4, m4
126     movd       %6, m4
127     movd       %7, m5
128     punpckhdq  m5, m5
129     movd       %8, m5
130 %endmacro
131
132 %macro SBUTTERFLY 4
133     movq       %4, %2
134     punpckl%1  %2, %3
135     punpckh%1  %4, %3
136 %endmacro
137
138 ; in: 8 rows of 8 (only the middle 6 pels are used) in %1..%8
139 ; out: 6 rows of 8 in [%9+0*16] .. [%9+5*16]
140 %macro TRANSPOSE6x8_MEM 9
141     movq  m0, %1
142     movq  m1, %3
143     movq  m2, %5
144     movq  m3, %7
145     SBUTTERFLY bw, m0, %2, m4
146     SBUTTERFLY bw, m1, %4, m5
147     SBUTTERFLY bw, m2, %6, m6
148     movq  [%9+0x10], m5
149     SBUTTERFLY bw, m3, %8, m7
150     SBUTTERFLY wd, m0, m1, m5
151     SBUTTERFLY wd, m2, m3, m1
152     punpckhdq m0, m2
153     movq  [%9+0x00], m0
154     SBUTTERFLY wd, m4, [%9+0x10], m3
155     SBUTTERFLY wd, m6, m7, m2
156     SBUTTERFLY dq, m4, m6, m0
157     SBUTTERFLY dq, m5, m1, m7
158     punpckldq m3, m2
159     movq  [%9+0x10], m5
160     movq  [%9+0x20], m7
161     movq  [%9+0x30], m4
162     movq  [%9+0x40], m0
163     movq  [%9+0x50], m3
164 %endmacro
165
166 ; out: %4 = |%1-%2|>%3
167 ; clobbers: %5
168 %macro DIFF_GT 5
169     movq    %5, %2
170     movq    %4, %1
171     psubusb %5, %1
172     psubusb %4, %2
173     por     %4, %5
174     psubusb %4, %3
175 %endmacro
176
177 ; out: %4 = |%1-%2|>%3
178 ; clobbers: %5
179 %macro DIFF_GT2 5
180     movq    %5, %2
181     movq    %4, %1
182     psubusb %5, %1
183     psubusb %4, %2
184     psubusb %5, %3
185     psubusb %4, %3
186     pcmpeqb %4, %5
187 %endmacro
188
189 %macro SPLATW 1
190 %ifidn m0, xmm0
191     pshuflw  %1, %1, 0
192     punpcklqdq %1, %1
193 %else
194     pshufw   %1, %1, 0
195 %endif
196 %endmacro
197
198 ; in: m0=p1 m1=p0 m2=q0 m3=q1 %1=alpha-1 %2=beta-1
199 ; out: m5=beta-1, m7=mask
200 ; clobbers: m4,m6
201 %macro LOAD_MASK 2
202     movd     m4, %1
203     movd     m5, %2
204     SPLATW   m4
205     SPLATW   m5
206     packuswb m4, m4  ; 16x alpha-1
207     packuswb m5, m5  ; 16x beta-1
208     DIFF_GT  m1, m2, m4, m7, m6 ; |p0-q0| > alpha-1
209     DIFF_GT  m0, m1, m5, m4, m6 ; |p1-p0| > beta-1
210     por      m7, m4
211     DIFF_GT  m3, m2, m5, m4, m6 ; |q1-q0| > beta-1
212     por      m7, m4
213     pxor     m6, m6
214     pcmpeqb  m7, m6
215 %endmacro
216
217 ; in: m0=p1 m1=p0 m2=q0 m3=q1 m7=(tc&mask)
218 ; out: m1=p0' m2=q0'
219 ; clobbers: m0,3-6
220 %macro DEBLOCK_P0_Q0 0
221     movq    m5, m1
222     pxor    m5, m2           ; p0^q0
223     pand    m5, [pb_01 GLOBAL] ; (p0^q0)&1
224     pcmpeqb m4, m4
225     pxor    m3, m4
226     pavgb   m3, m0           ; (p1 - q1 + 256)>>1
227     pavgb   m3, [pb_03 GLOBAL] ; (((p1 - q1 + 256)>>1)+4)>>1 = 64+2+(p1-q1)>>2
228     pxor    m4, m1
229     pavgb   m4, m2           ; (q0 - p0 + 256)>>1
230     pavgb   m3, m5
231     paddusb m3, m4           ; d+128+33
232     movq    m6, [pb_a1 GLOBAL]
233     psubusb m6, m3
234     psubusb m3, [pb_a1 GLOBAL]
235     pminub  m6, m7
236     pminub  m3, m7
237     psubusb m1, m6
238     psubusb m2, m3
239     paddusb m1, m3
240     paddusb m2, m6
241 %endmacro
242
243 ; in: m1=p0 m2=q0
244 ;     %1=p1 %2=q2 %3=[q2] %4=[q1] %5=tc0 %6=tmp
245 ; out: [q1] = clip( (q2+((p0+q0+1)>>1))>>1, q1-tc0, q1+tc0 )
246 ; clobbers: q2, tmp, tc0
247 %macro LUMA_Q1 6
248     movq    %6, m1
249     pavgb   %6, m2
250     pavgb   %2, %6             ; avg(p2,avg(p0,q0))
251     pxor    %6, %3
252     pand    %6, [pb_01 GLOBAL] ; (p2^avg(p0,q0))&1
253     psubusb %2, %6             ; (p2+((p0+q0+1)>>1))>>1
254     movq    %6, %1
255     psubusb %6, %5
256     paddusb %5, %1
257     pmaxub  %2, %6
258     pminub  %2, %5
259     movq    %4, %2
260 %endmacro
261
262 ;-----------------------------------------------------------------------------
263 ; void x264_deblock_v_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
264 ;-----------------------------------------------------------------------------
265 %ifdef ARCH_X86_64
266 INIT_XMM
267 cglobal x264_deblock_v_luma_sse2
268     movd    m8, [r4] ; tc0
269     lea     r4, [r1*3]
270     dec     r2d        ; alpha-1
271     neg     r4
272     dec     r3d        ; beta-1
273     add     r4, r0     ; pix-3*stride
274
275     movdqa  m0, [r4+r1]   ; p1
276     movdqa  m1, [r4+2*r1] ; p0
277     movdqa  m2, [r0]      ; q0
278     movdqa  m3, [r0+r1]   ; q1
279     LOAD_MASK r2d, r3d
280
281     punpcklbw m8, m8
282     punpcklbw m8, m8 ; tc = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0]
283     pcmpeqb m9, m9
284     pcmpeqb m9, m8
285     pandn   m9, m7
286     pand    m8, m9
287
288     movdqa  m3, [r4] ; p2
289     DIFF_GT2 m1, m3, m5, m6, m7 ; |p2-p0| > beta-1
290     pand    m6, m9
291     movdqa  m7, m8
292     psubb   m7, m6
293     pand    m6, m8
294     LUMA_Q1 m0, m3, [r4], [r4+r1], m6, m4
295
296     movdqa  m4, [r0+2*r1] ; q2
297     DIFF_GT2 m2, m4, m5, m6, m3 ; |q2-q0| > beta-1
298     pand    m6, m9
299     pand    m8, m6
300     psubb   m7, m6
301     movdqa  m3, [r0+r1]
302     LUMA_Q1 m3, m4, [r0+2*r1], [r0+r1], m8, m6
303
304     DEBLOCK_P0_Q0
305     movdqa  [r4+2*r1], m1
306     movdqa  [r0], m2
307     ret
308
309 ;-----------------------------------------------------------------------------
310 ; void x264_deblock_h_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
311 ;-----------------------------------------------------------------------------
312 INIT_MMX
313 cglobal x264_deblock_h_luma_sse2
314     movsxd r10, esi
315     lea    r11, [r10+r10*2]
316     lea    rax, [r0-4]
317     lea    r9,  [r0-4+r11]
318     sub    rsp, 0x68
319     %define pix_tmp rsp
320
321     ; transpose 6x16 -> tmp space
322     TRANSPOSE6x8_MEM  PASS8ROWS(rax, r9, r10, r11), pix_tmp
323     lea    rax, [rax+r10*8]
324     lea    r9,  [r9 +r10*8]
325     TRANSPOSE6x8_MEM  PASS8ROWS(rax, r9, r10, r11), pix_tmp+8
326
327     ; vertical filter
328     ; alpha, beta, tc0 are still in r2d, r3d, r4
329     ; don't backup rax, r9, r10, r11 because x264_deblock_v_luma_sse2 doesn't use them
330     lea    r0, [pix_tmp+0x30]
331     mov    esi, 0x10
332     call   x264_deblock_v_luma_sse2
333
334     ; transpose 16x4 -> original space  (only the middle 4 rows were changed by the filter)
335     add    rax, 2
336     add    r9,  2
337     movq   m0, [pix_tmp+0x18]
338     movq   m1, [pix_tmp+0x28]
339     movq   m2, [pix_tmp+0x38]
340     movq   m3, [pix_tmp+0x48]
341     TRANSPOSE8x4_STORE  PASS8ROWS(rax, r9, r10, r11)
342
343     shl    r10, 3
344     sub    rax, r10
345     sub    r9,  r10
346     shr    r10, 3
347     movq   m0, [pix_tmp+0x10]
348     movq   m1, [pix_tmp+0x20]
349     movq   m2, [pix_tmp+0x30]
350     movq   m3, [pix_tmp+0x40]
351     TRANSPOSE8x4_STORE  PASS8ROWS(rax, r9, r10, r11)
352
353     add    rsp, 0x68
354     ret
355
356 %else
357
358 %macro DEBLOCK_LUMA 3
359 ;-----------------------------------------------------------------------------
360 ; void x264_deblock_v8_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
361 ;-----------------------------------------------------------------------------
362 cglobal x264_deblock_%2_luma_%1, 5,5,1
363     lea     r4, [r1*3]
364     dec     r2     ; alpha-1
365     neg     r4
366     dec     r3     ; beta-1
367     add     r4, r0 ; pix-3*stride
368
369     movq    m0, [r4+r1]   ; p1
370     movq    m1, [r4+2*r1] ; p0
371     movq    m2, [r0]      ; q0
372     movq    m3, [r0+r1]   ; q1
373     LOAD_MASK r2, r3
374
375     mov     r3, r4m
376 %if %3 == 16
377     mov     r2, esp
378     and     esp, -16
379     sub     esp, 32
380 %else
381     sub     esp, 16
382 %endif
383
384     movd    m4, [r3] ; tc0
385     punpcklbw m4, m4
386     punpcklbw m4, m4 ; tc = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0]
387     movq   [esp+%3], m4 ; tc
388     pcmpeqb m3, m3
389     pcmpgtb m4, m3
390     pand    m4, m7
391     movq   [esp], m4 ; mask
392
393     movq    m3, [r4] ; p2
394     DIFF_GT2 m1, m3, m5, m6, m7 ; |p2-p0| > beta-1
395     pand    m6, m4
396     pand    m4, [esp+%3] ; tc
397     movq    m7, m4
398     psubb   m7, m6
399     pand    m6, m4
400     LUMA_Q1 m0, m3, [r4], [r4+r1], m6, m4
401
402     movq    m4, [r0+2*r1] ; q2
403     DIFF_GT2 m2, m4, m5, m6, m3 ; |q2-q0| > beta-1
404     movq    m5, [esp] ; mask
405     pand    m6, m5
406     movq    m5, [esp+%3] ; tc
407     pand    m5, m6
408     psubb   m7, m6
409     movq    m3, [r0+r1]
410     LUMA_Q1 m3, m4, [r0+2*r1], [r0+r1], m5, m6
411
412     DEBLOCK_P0_Q0
413     movq    [r4+2*r1], m1
414     movq    [r0], m2
415
416 %if %3 == 16
417     mov     esp, r2
418 %else
419     add     esp, 16
420 %endif
421     RET
422
423 ;-----------------------------------------------------------------------------
424 ; void x264_deblock_h_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
425 ;-----------------------------------------------------------------------------
426 INIT_MMX
427 cglobal x264_deblock_h_luma_%1, 0,6
428     mov    r0, r0m
429     mov    r3, r1m
430     lea    r4, [r3*3]
431     sub    r0, 4
432     lea    r1, [r0+r4]
433     SUB    esp, 0x6c
434     lea    r5, [esp+12]
435     and    r5, -16
436 %define pix_tmp r5
437
438     ; transpose 6x16 -> tmp space
439     TRANSPOSE6x8_MEM  PASS8ROWS(r0, r1, r3, r4), pix_tmp
440     lea    r0, [r0+r3*8]
441     lea    r1, [r1+r3*8]
442     TRANSPOSE6x8_MEM  PASS8ROWS(r0, r1, r3, r4), pix_tmp+8
443
444     ; vertical filter
445     lea    r0, [pix_tmp+0x30]
446     PUSH   dword r4m
447     PUSH   dword r3m
448     PUSH   dword r2m
449     PUSH   dword 16
450     PUSH   dword r0
451     call   x264_deblock_%2_luma_%1
452 %ifidn %2, v8
453     add    dword [esp   ], 8 ; pix_tmp+0x38
454     add    dword [esp+16], 2 ; tc0+2
455     call   x264_deblock_%2_luma_%1
456 %endif
457     ADD    esp, 20
458
459     ; transpose 16x4 -> original space  (only the middle 4 rows were changed by the filter)
460     mov    r0, r0m
461     sub    r0, 2
462     lea    r1, [r0+r4]
463
464     movq   m0, [pix_tmp+0x10]
465     movq   m1, [pix_tmp+0x20]
466     movq   m2, [pix_tmp+0x30]
467     movq   m3, [pix_tmp+0x40]
468     TRANSPOSE8x4_STORE  PASS8ROWS(r0, r1, r3, r4)
469
470     lea    r0, [r0+r3*8]
471     lea    r1, [r1+r3*8]
472     movq   m0, [pix_tmp+0x18]
473     movq   m1, [pix_tmp+0x28]
474     movq   m2, [pix_tmp+0x38]
475     movq   m3, [pix_tmp+0x48]
476     TRANSPOSE8x4_STORE  PASS8ROWS(r0, r1, r3, r4)
477
478     ADD    esp, 0x6c
479     RET
480 %endmacro ; DEBLOCK_LUMA
481
482 INIT_MMX
483 DEBLOCK_LUMA mmxext, v8, 8
484 INIT_XMM
485 DEBLOCK_LUMA sse2, v, 16
486
487 %endif ; ARCH
488
489
490
491 INIT_MMX
492
493 %macro CHROMA_V_START 0
494     dec    r2d      ; alpha-1
495     dec    r3d      ; beta-1
496     mov    t5, r0
497     sub    t5, r1
498     sub    t5, r1
499 %endmacro
500
501 %macro CHROMA_H_START 0
502     dec    r2d
503     dec    r3d
504     sub    r0, 2
505     lea    t6, [r1*3]
506     mov    t5, r0
507     add    r0, t6
508 %endmacro
509
510 %define t5 r5
511 %define t6 r6
512
513 ;-----------------------------------------------------------------------------
514 ; void x264_deblock_v_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
515 ;-----------------------------------------------------------------------------
516 cglobal x264_deblock_v_chroma_mmxext, 5,6
517     CHROMA_V_START
518
519     movq  m0, [t5]
520     movq  m1, [t5+r1]
521     movq  m2, [r0]
522     movq  m3, [r0+r1]
523
524     LOAD_MASK  r2d, r3d
525     movd       m6, [r4] ; tc0
526     punpcklbw  m6, m6
527     pand       m7, m6
528     picgetgot r4
529     DEBLOCK_P0_Q0
530
531     movq  [t5+r1], m1
532     movq  [r0], m2
533     RET
534
535 ;-----------------------------------------------------------------------------
536 ; void x264_deblock_h_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
537 ;-----------------------------------------------------------------------------
538 cglobal x264_deblock_h_chroma_mmxext, 5,7
539 %ifdef ARCH_X86_64
540     %define buf0 [rsp-16]
541     %define buf1 [rsp-8]
542 %else
543     %define buf0 r0m
544     %define buf1 r2m
545 %endif
546     CHROMA_H_START
547
548     TRANSPOSE4x8_LOAD  PASS8ROWS(t5, r0, r1, t6)
549     movq  buf0, m0
550     movq  buf1, m3
551
552     LOAD_MASK  r2d, r3d
553     movd       m6, [r4] ; tc0
554     punpcklbw  m6, m6
555     pand       m7, m6
556     picgetgot r4
557     DEBLOCK_P0_Q0
558
559     movq  m0, buf0
560     movq  m3, buf1
561     TRANSPOSE8x4_STORE PASS8ROWS(t5, r0, r1, t6)
562     RET
563
564
565
566 ; in: %1=p0 %2=p1 %3=q1
567 ; out: p0 = (p0 + q1 + 2*p1 + 2) >> 2
568 %macro CHROMA_INTRA_P0 3
569     movq    m4, %1
570     pxor    m4, %3
571     pand    m4, [pb_01 GLOBAL] ; m4 = (p0^q1)&1
572     pavgb   %1, %3
573     psubusb %1, m4
574     pavgb   %1, %2             ; dst = avg(p1, avg(p0,q1) - ((p0^q1)&1))
575 %endmacro
576
577 %macro CHROMA_INTRA_BODY 0
578     LOAD_MASK r2d, r3d
579     movq   m5, m1
580     movq   m6, m2
581     CHROMA_INTRA_P0  m1, m0, m3
582     CHROMA_INTRA_P0  m2, m3, m0
583     psubb  m1, m5
584     psubb  m2, m6
585     pand   m1, m7
586     pand   m2, m7
587     paddb  m1, m5
588     paddb  m2, m6
589 %endmacro
590
591 %define t5 r4
592 %define t6 r5
593
594 ;-----------------------------------------------------------------------------
595 ; void x264_deblock_v_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta )
596 ;-----------------------------------------------------------------------------
597 cglobal x264_deblock_v_chroma_intra_mmxext, 4,5,1
598     CHROMA_V_START
599
600     movq  m0, [t5]
601     movq  m1, [t5+r1]
602     movq  m2, [r0]
603     movq  m3, [r0+r1]
604
605     CHROMA_INTRA_BODY
606
607     movq  [t5+r1], m1
608     movq  [r0], m2
609     RET
610
611 ;-----------------------------------------------------------------------------
612 ; void x264_deblock_h_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta )
613 ;-----------------------------------------------------------------------------
614 cglobal x264_deblock_h_chroma_intra_mmxext, 4,6,1
615     CHROMA_H_START
616     TRANSPOSE4x8_LOAD  PASS8ROWS(t5, r0, r1, t6)
617     CHROMA_INTRA_BODY
618     TRANSPOSE8x4_STORE PASS8ROWS(t5, r0, r1, t6)
619     RET
620