You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

914 lines
23KB

  1. ;*****************************************************************************
  2. ;* MMX/SSE2/AVX-optimized H.264 deblocking code
  3. ;*****************************************************************************
  4. ;* Copyright (C) 2005-2011 x264 project
  5. ;*
  6. ;* Authors: Loren Merritt <lorenm@u.washington.edu>
  7. ;* Jason Garrett-Glaser <darkshikari@gmail.com>
  8. ;* Oskar Arvidsson <oskar@irock.se>
  9. ;*
  10. ;* This file is part of FFmpeg.
  11. ;*
  12. ;* FFmpeg is free software; you can redistribute it and/or
  13. ;* modify it under the terms of the GNU Lesser General Public
  14. ;* License as published by the Free Software Foundation; either
  15. ;* version 2.1 of the License, or (at your option) any later version.
  16. ;*
  17. ;* FFmpeg is distributed in the hope that it will be useful,
  18. ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  20. ;* Lesser General Public License for more details.
  21. ;*
  22. ;* You should have received a copy of the GNU Lesser General Public
  23. ;* License along with FFmpeg; if not, write to the Free Software
  24. ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  25. ;******************************************************************************
  26. %include "x86inc.asm"
  27. %include "x86util.asm"
  28. SECTION .text
  29. cextern pb_0
  30. cextern pb_1
  31. cextern pb_3
  32. cextern pb_A1
  33. ; expands to [base],...,[base+7*stride]
  34. %define PASS8ROWS(base, base3, stride, stride3) \
  35. [base], [base+stride], [base+stride*2], [base3], \
  36. [base3+stride], [base3+stride*2], [base3+stride3], [base3+stride*4]
  37. %define PASS8ROWS(base, base3, stride, stride3, offset) \
  38. PASS8ROWS(base+offset, base3+offset, stride, stride3)
  39. ; in: 8 rows of 4 bytes in %4..%11
  40. ; out: 4 rows of 8 bytes in m0..m3
  41. %macro TRANSPOSE4x8_LOAD 11
  42. movh m0, %4
  43. movh m2, %5
  44. movh m1, %6
  45. movh m3, %7
  46. punpckl%1 m0, m2
  47. punpckl%1 m1, m3
  48. mova m2, m0
  49. punpckl%2 m0, m1
  50. punpckh%2 m2, m1
  51. movh m4, %8
  52. movh m6, %9
  53. movh m5, %10
  54. movh m7, %11
  55. punpckl%1 m4, m6
  56. punpckl%1 m5, m7
  57. mova m6, m4
  58. punpckl%2 m4, m5
  59. punpckh%2 m6, m5
  60. punpckh%3 m1, m0, m4
  61. punpckh%3 m3, m2, m6
  62. punpckl%3 m0, m4
  63. punpckl%3 m2, m6
  64. %endmacro
  65. ; in: 4 rows of 8 bytes in m0..m3
  66. ; out: 8 rows of 4 bytes in %1..%8
  67. %macro TRANSPOSE8x4B_STORE 8
  68. punpckhdq m4, m0, m0
  69. punpckhdq m5, m1, m1
  70. punpckhdq m6, m2, m2
  71. punpcklbw m0, m1
  72. punpcklbw m2, m3
  73. punpcklwd m1, m0, m2
  74. punpckhwd m0, m2
  75. movh %1, m1
  76. punpckhdq m1, m1
  77. movh %2, m1
  78. movh %3, m0
  79. punpckhdq m0, m0
  80. movh %4, m0
  81. punpckhdq m3, m3
  82. punpcklbw m4, m5
  83. punpcklbw m6, m3
  84. punpcklwd m5, m4, m6
  85. punpckhwd m4, m6
  86. movh %5, m5
  87. punpckhdq m5, m5
  88. movh %6, m5
  89. movh %7, m4
  90. punpckhdq m4, m4
  91. movh %8, m4
  92. %endmacro
  93. %macro TRANSPOSE4x8B_LOAD 8
  94. TRANSPOSE4x8_LOAD bw, wd, dq, %1, %2, %3, %4, %5, %6, %7, %8
  95. %endmacro
  96. %macro SBUTTERFLY3 4
  97. punpckh%1 %4, %2, %3
  98. punpckl%1 %2, %3
  99. %endmacro
  100. ; in: 8 rows of 8 (only the middle 6 pels are used) in %1..%8
  101. ; out: 6 rows of 8 in [%9+0*16] .. [%9+5*16]
  102. %macro TRANSPOSE6x8_MEM 9
  103. RESET_MM_PERMUTATION
  104. movq m0, %1
  105. movq m1, %2
  106. movq m2, %3
  107. movq m3, %4
  108. movq m4, %5
  109. movq m5, %6
  110. movq m6, %7
  111. SBUTTERFLY bw, 0, 1, 7
  112. SBUTTERFLY bw, 2, 3, 7
  113. SBUTTERFLY bw, 4, 5, 7
  114. movq [%9+0x10], m3
  115. SBUTTERFLY3 bw, m6, %8, m7
  116. SBUTTERFLY wd, 0, 2, 3
  117. SBUTTERFLY wd, 4, 6, 3
  118. punpckhdq m0, m4
  119. movq [%9+0x00], m0
  120. SBUTTERFLY3 wd, m1, [%9+0x10], m3
  121. SBUTTERFLY wd, 5, 7, 0
  122. SBUTTERFLY dq, 1, 5, 0
  123. SBUTTERFLY dq, 2, 6, 0
  124. punpckldq m3, m7
  125. movq [%9+0x10], m2
  126. movq [%9+0x20], m6
  127. movq [%9+0x30], m1
  128. movq [%9+0x40], m5
  129. movq [%9+0x50], m3
  130. RESET_MM_PERMUTATION
  131. %endmacro
  132. ; in: 8 rows of 8 in %1..%8
  133. ; out: 8 rows of 8 in %9..%16
  134. %macro TRANSPOSE8x8_MEM 16
  135. RESET_MM_PERMUTATION
  136. movq m0, %1
  137. movq m1, %2
  138. movq m2, %3
  139. movq m3, %4
  140. movq m4, %5
  141. movq m5, %6
  142. movq m6, %7
  143. SBUTTERFLY bw, 0, 1, 7
  144. SBUTTERFLY bw, 2, 3, 7
  145. SBUTTERFLY bw, 4, 5, 7
  146. SBUTTERFLY3 bw, m6, %8, m7
  147. movq %9, m5
  148. SBUTTERFLY wd, 0, 2, 5
  149. SBUTTERFLY wd, 4, 6, 5
  150. SBUTTERFLY wd, 1, 3, 5
  151. movq %11, m6
  152. movq m6, %9
  153. SBUTTERFLY wd, 6, 7, 5
  154. SBUTTERFLY dq, 0, 4, 5
  155. SBUTTERFLY dq, 1, 6, 5
  156. movq %9, m0
  157. movq %10, m4
  158. movq %13, m1
  159. movq %14, m6
  160. SBUTTERFLY3 dq, m2, %11, m0
  161. SBUTTERFLY dq, 3, 7, 4
  162. movq %11, m2
  163. movq %12, m0
  164. movq %15, m3
  165. movq %16, m7
  166. RESET_MM_PERMUTATION
  167. %endmacro
  168. ; out: %4 = |%1-%2|>%3
  169. ; clobbers: %5
  170. %macro DIFF_GT 5
  171. %if avx_enabled == 0
  172. mova %5, %2
  173. mova %4, %1
  174. psubusb %5, %1
  175. psubusb %4, %2
  176. %else
  177. psubusb %5, %2, %1
  178. psubusb %4, %1, %2
  179. %endif
  180. por %4, %5
  181. psubusb %4, %3
  182. %endmacro
  183. ; out: %4 = |%1-%2|>%3
  184. ; clobbers: %5
  185. %macro DIFF_GT2 5
  186. %ifdef ARCH_X86_64
  187. psubusb %5, %2, %1
  188. psubusb %4, %1, %2
  189. %else
  190. mova %5, %2
  191. mova %4, %1
  192. psubusb %5, %1
  193. psubusb %4, %2
  194. %endif
  195. psubusb %5, %3
  196. psubusb %4, %3
  197. pcmpeqb %4, %5
  198. %endmacro
  199. ; in: m0=p1 m1=p0 m2=q0 m3=q1 %1=alpha-1 %2=beta-1
  200. ; out: m5=beta-1, m7=mask, %3=alpha-1
  201. ; clobbers: m4,m6
  202. %macro LOAD_MASK 2-3
  203. movd m4, %1
  204. movd m5, %2
  205. SPLATW m4, m4
  206. SPLATW m5, m5
  207. packuswb m4, m4 ; 16x alpha-1
  208. packuswb m5, m5 ; 16x beta-1
  209. %if %0>2
  210. mova %3, m4
  211. %endif
  212. DIFF_GT m1, m2, m4, m7, m6 ; |p0-q0| > alpha-1
  213. DIFF_GT m0, m1, m5, m4, m6 ; |p1-p0| > beta-1
  214. por m7, m4
  215. DIFF_GT m3, m2, m5, m4, m6 ; |q1-q0| > beta-1
  216. por m7, m4
  217. pxor m6, m6
  218. pcmpeqb m7, m6
  219. %endmacro
  220. ; in: m0=p1 m1=p0 m2=q0 m3=q1 m7=(tc&mask)
  221. ; out: m1=p0' m2=q0'
  222. ; clobbers: m0,3-6
  223. %macro DEBLOCK_P0_Q0 0
  224. pxor m5, m1, m2 ; p0^q0
  225. pand m5, [pb_1] ; (p0^q0)&1
  226. pcmpeqb m4, m4
  227. pxor m3, m4
  228. pavgb m3, m0 ; (p1 - q1 + 256)>>1
  229. pavgb m3, [pb_3] ; (((p1 - q1 + 256)>>1)+4)>>1 = 64+2+(p1-q1)>>2
  230. pxor m4, m1
  231. pavgb m4, m2 ; (q0 - p0 + 256)>>1
  232. pavgb m3, m5
  233. paddusb m3, m4 ; d+128+33
  234. mova m6, [pb_A1]
  235. psubusb m6, m3
  236. psubusb m3, [pb_A1]
  237. pminub m6, m7
  238. pminub m3, m7
  239. psubusb m1, m6
  240. psubusb m2, m3
  241. paddusb m1, m3
  242. paddusb m2, m6
  243. %endmacro
  244. ; in: m1=p0 m2=q0
  245. ; %1=p1 %2=q2 %3=[q2] %4=[q1] %5=tc0 %6=tmp
  246. ; out: [q1] = clip( (q2+((p0+q0+1)>>1))>>1, q1-tc0, q1+tc0 )
  247. ; clobbers: q2, tmp, tc0
  248. %macro LUMA_Q1 6
  249. pavgb %6, m1, m2
  250. pavgb %2, %6 ; avg(p2,avg(p0,q0))
  251. pxor %6, %3
  252. pand %6, [pb_1] ; (p2^avg(p0,q0))&1
  253. psubusb %2, %6 ; (p2+((p0+q0+1)>>1))>>1
  254. psubusb %6, %1, %5
  255. paddusb %5, %1
  256. pmaxub %2, %6
  257. pminub %2, %5
  258. mova %4, %2
  259. %endmacro
  260. %ifdef ARCH_X86_64
  261. ;-----------------------------------------------------------------------------
  262. ; void deblock_v_luma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
  263. ;-----------------------------------------------------------------------------
  264. %macro DEBLOCK_LUMA 1
  265. cglobal deblock_v_luma_8_%1, 5,5,10
  266. movd m8, [r4] ; tc0
  267. lea r4, [r1*3]
  268. dec r2d ; alpha-1
  269. neg r4
  270. dec r3d ; beta-1
  271. add r4, r0 ; pix-3*stride
  272. mova m0, [r4+r1] ; p1
  273. mova m1, [r4+2*r1] ; p0
  274. mova m2, [r0] ; q0
  275. mova m3, [r0+r1] ; q1
  276. LOAD_MASK r2d, r3d
  277. punpcklbw m8, m8
  278. punpcklbw m8, m8 ; tc = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0]
  279. pcmpeqb m9, m9
  280. pcmpeqb m9, m8
  281. pandn m9, m7
  282. pand m8, m9
  283. movdqa m3, [r4] ; p2
  284. DIFF_GT2 m1, m3, m5, m6, m7 ; |p2-p0| > beta-1
  285. pand m6, m9
  286. psubb m7, m8, m6
  287. pand m6, m8
  288. LUMA_Q1 m0, m3, [r4], [r4+r1], m6, m4
  289. movdqa m4, [r0+2*r1] ; q2
  290. DIFF_GT2 m2, m4, m5, m6, m3 ; |q2-q0| > beta-1
  291. pand m6, m9
  292. pand m8, m6
  293. psubb m7, m6
  294. mova m3, [r0+r1]
  295. LUMA_Q1 m3, m4, [r0+2*r1], [r0+r1], m8, m6
  296. DEBLOCK_P0_Q0
  297. mova [r4+2*r1], m1
  298. mova [r0], m2
  299. RET
  300. ;-----------------------------------------------------------------------------
  301. ; void deblock_h_luma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
  302. ;-----------------------------------------------------------------------------
  303. INIT_MMX
  304. cglobal deblock_h_luma_8_%1, 5,7
  305. movsxd r10, r1d
  306. lea r11, [r10+r10*2]
  307. lea r6, [r0-4]
  308. lea r5, [r0-4+r11]
  309. %ifdef WIN64
  310. sub rsp, 0x98
  311. %define pix_tmp rsp+0x30
  312. %else
  313. sub rsp, 0x68
  314. %define pix_tmp rsp
  315. %endif
  316. ; transpose 6x16 -> tmp space
  317. TRANSPOSE6x8_MEM PASS8ROWS(r6, r5, r10, r11), pix_tmp
  318. lea r6, [r6+r10*8]
  319. lea r5, [r5+r10*8]
  320. TRANSPOSE6x8_MEM PASS8ROWS(r6, r5, r10, r11), pix_tmp+8
  321. ; vertical filter
  322. ; alpha, beta, tc0 are still in r2d, r3d, r4
  323. ; don't backup r6, r5, r10, r11 because deblock_v_luma_sse2 doesn't use them
  324. lea r0, [pix_tmp+0x30]
  325. mov r1d, 0x10
  326. %ifdef WIN64
  327. mov [rsp+0x20], r4
  328. %endif
  329. call deblock_v_luma_8_%1
  330. ; transpose 16x4 -> original space (only the middle 4 rows were changed by the filter)
  331. add r6, 2
  332. add r5, 2
  333. movq m0, [pix_tmp+0x18]
  334. movq m1, [pix_tmp+0x28]
  335. movq m2, [pix_tmp+0x38]
  336. movq m3, [pix_tmp+0x48]
  337. TRANSPOSE8x4B_STORE PASS8ROWS(r6, r5, r10, r11)
  338. shl r10, 3
  339. sub r6, r10
  340. sub r5, r10
  341. shr r10, 3
  342. movq m0, [pix_tmp+0x10]
  343. movq m1, [pix_tmp+0x20]
  344. movq m2, [pix_tmp+0x30]
  345. movq m3, [pix_tmp+0x40]
  346. TRANSPOSE8x4B_STORE PASS8ROWS(r6, r5, r10, r11)
  347. %ifdef WIN64
  348. add rsp, 0x98
  349. %else
  350. add rsp, 0x68
  351. %endif
  352. RET
  353. %endmacro
  354. INIT_XMM
  355. DEBLOCK_LUMA sse2
  356. %ifdef HAVE_AVX
  357. INIT_AVX
  358. DEBLOCK_LUMA avx
  359. %endif
  360. %else
  361. %macro DEBLOCK_LUMA 3
  362. ;-----------------------------------------------------------------------------
  363. ; void deblock_v8_luma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
  364. ;-----------------------------------------------------------------------------
  365. cglobal deblock_%2_luma_8_%1, 5,5
  366. lea r4, [r1*3]
  367. dec r2 ; alpha-1
  368. neg r4
  369. dec r3 ; beta-1
  370. add r4, r0 ; pix-3*stride
  371. %assign pad 2*%3+12-(stack_offset&15)
  372. SUB esp, pad
  373. mova m0, [r4+r1] ; p1
  374. mova m1, [r4+2*r1] ; p0
  375. mova m2, [r0] ; q0
  376. mova m3, [r0+r1] ; q1
  377. LOAD_MASK r2, r3
  378. mov r3, r4mp
  379. movd m4, [r3] ; tc0
  380. punpcklbw m4, m4
  381. punpcklbw m4, m4 ; tc = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0]
  382. mova [esp+%3], m4 ; tc
  383. pcmpeqb m3, m3
  384. pcmpgtb m4, m3
  385. pand m4, m7
  386. mova [esp], m4 ; mask
  387. mova m3, [r4] ; p2
  388. DIFF_GT2 m1, m3, m5, m6, m7 ; |p2-p0| > beta-1
  389. pand m6, m4
  390. pand m4, [esp+%3] ; tc
  391. psubb m7, m4, m6
  392. pand m6, m4
  393. LUMA_Q1 m0, m3, [r4], [r4+r1], m6, m4
  394. mova m4, [r0+2*r1] ; q2
  395. DIFF_GT2 m2, m4, m5, m6, m3 ; |q2-q0| > beta-1
  396. mova m5, [esp] ; mask
  397. pand m6, m5
  398. mova m5, [esp+%3] ; tc
  399. pand m5, m6
  400. psubb m7, m6
  401. mova m3, [r0+r1]
  402. LUMA_Q1 m3, m4, [r0+2*r1], [r0+r1], m5, m6
  403. DEBLOCK_P0_Q0
  404. mova [r4+2*r1], m1
  405. mova [r0], m2
  406. ADD esp, pad
  407. RET
  408. ;-----------------------------------------------------------------------------
  409. ; void deblock_h_luma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
  410. ;-----------------------------------------------------------------------------
  411. INIT_MMX
  412. cglobal deblock_h_luma_8_%1, 0,5
  413. mov r0, r0mp
  414. mov r3, r1m
  415. lea r4, [r3*3]
  416. sub r0, 4
  417. lea r1, [r0+r4]
  418. %assign pad 0x78-(stack_offset&15)
  419. SUB esp, pad
  420. %define pix_tmp esp+12
  421. ; transpose 6x16 -> tmp space
  422. TRANSPOSE6x8_MEM PASS8ROWS(r0, r1, r3, r4), pix_tmp
  423. lea r0, [r0+r3*8]
  424. lea r1, [r1+r3*8]
  425. TRANSPOSE6x8_MEM PASS8ROWS(r0, r1, r3, r4), pix_tmp+8
  426. ; vertical filter
  427. lea r0, [pix_tmp+0x30]
  428. PUSH dword r4m
  429. PUSH dword r3m
  430. PUSH dword r2m
  431. PUSH dword 16
  432. PUSH dword r0
  433. call deblock_%2_luma_8_%1
  434. %ifidn %2, v8
  435. add dword [esp ], 8 ; pix_tmp+0x38
  436. add dword [esp+16], 2 ; tc0+2
  437. call deblock_%2_luma_8_%1
  438. %endif
  439. ADD esp, 20
  440. ; transpose 16x4 -> original space (only the middle 4 rows were changed by the filter)
  441. mov r0, r0mp
  442. sub r0, 2
  443. lea r1, [r0+r4]
  444. movq m0, [pix_tmp+0x10]
  445. movq m1, [pix_tmp+0x20]
  446. movq m2, [pix_tmp+0x30]
  447. movq m3, [pix_tmp+0x40]
  448. TRANSPOSE8x4B_STORE PASS8ROWS(r0, r1, r3, r4)
  449. lea r0, [r0+r3*8]
  450. lea r1, [r1+r3*8]
  451. movq m0, [pix_tmp+0x18]
  452. movq m1, [pix_tmp+0x28]
  453. movq m2, [pix_tmp+0x38]
  454. movq m3, [pix_tmp+0x48]
  455. TRANSPOSE8x4B_STORE PASS8ROWS(r0, r1, r3, r4)
  456. ADD esp, pad
  457. RET
  458. %endmacro ; DEBLOCK_LUMA
  459. INIT_MMX
  460. DEBLOCK_LUMA mmxext, v8, 8
  461. INIT_XMM
  462. DEBLOCK_LUMA sse2, v, 16
  463. %ifdef HAVE_AVX
  464. INIT_AVX
  465. DEBLOCK_LUMA avx, v, 16
  466. %endif
  467. %endif ; ARCH
  468. %macro LUMA_INTRA_P012 4 ; p0..p3 in memory
  469. %ifdef ARCH_X86_64
  470. pavgb t0, p2, p1
  471. pavgb t1, p0, q0
  472. %else
  473. mova t0, p2
  474. mova t1, p0
  475. pavgb t0, p1
  476. pavgb t1, q0
  477. %endif
  478. pavgb t0, t1 ; ((p2+p1+1)/2 + (p0+q0+1)/2 + 1)/2
  479. mova t5, t1
  480. %ifdef ARCH_X86_64
  481. paddb t2, p2, p1
  482. paddb t3, p0, q0
  483. %else
  484. mova t2, p2
  485. mova t3, p0
  486. paddb t2, p1
  487. paddb t3, q0
  488. %endif
  489. paddb t2, t3
  490. mova t3, t2
  491. mova t4, t2
  492. psrlw t2, 1
  493. pavgb t2, mpb_0
  494. pxor t2, t0
  495. pand t2, mpb_1
  496. psubb t0, t2 ; p1' = (p2+p1+p0+q0+2)/4;
  497. %ifdef ARCH_X86_64
  498. pavgb t1, p2, q1
  499. psubb t2, p2, q1
  500. %else
  501. mova t1, p2
  502. mova t2, p2
  503. pavgb t1, q1
  504. psubb t2, q1
  505. %endif
  506. paddb t3, t3
  507. psubb t3, t2 ; p2+2*p1+2*p0+2*q0+q1
  508. pand t2, mpb_1
  509. psubb t1, t2
  510. pavgb t1, p1
  511. pavgb t1, t5 ; (((p2+q1)/2 + p1+1)/2 + (p0+q0+1)/2 + 1)/2
  512. psrlw t3, 2
  513. pavgb t3, mpb_0
  514. pxor t3, t1
  515. pand t3, mpb_1
  516. psubb t1, t3 ; p0'a = (p2+2*p1+2*p0+2*q0+q1+4)/8
  517. pxor t3, p0, q1
  518. pavgb t2, p0, q1
  519. pand t3, mpb_1
  520. psubb t2, t3
  521. pavgb t2, p1 ; p0'b = (2*p1+p0+q0+2)/4
  522. pxor t1, t2
  523. pxor t2, p0
  524. pand t1, mask1p
  525. pand t2, mask0
  526. pxor t1, t2
  527. pxor t1, p0
  528. mova %1, t1 ; store p0
  529. mova t1, %4 ; p3
  530. paddb t2, t1, p2
  531. pavgb t1, p2
  532. pavgb t1, t0 ; (p3+p2+1)/2 + (p2+p1+p0+q0+2)/4
  533. paddb t2, t2
  534. paddb t2, t4 ; 2*p3+3*p2+p1+p0+q0
  535. psrlw t2, 2
  536. pavgb t2, mpb_0
  537. pxor t2, t1
  538. pand t2, mpb_1
  539. psubb t1, t2 ; p2' = (2*p3+3*p2+p1+p0+q0+4)/8
  540. pxor t0, p1
  541. pxor t1, p2
  542. pand t0, mask1p
  543. pand t1, mask1p
  544. pxor t0, p1
  545. pxor t1, p2
  546. mova %2, t0 ; store p1
  547. mova %3, t1 ; store p2
  548. %endmacro
  549. %macro LUMA_INTRA_SWAP_PQ 0
  550. %define q1 m0
  551. %define q0 m1
  552. %define p0 m2
  553. %define p1 m3
  554. %define p2 q2
  555. %define mask1p mask1q
  556. %endmacro
  557. %macro DEBLOCK_LUMA_INTRA 2
  558. %define p1 m0
  559. %define p0 m1
  560. %define q0 m2
  561. %define q1 m3
  562. %define t0 m4
  563. %define t1 m5
  564. %define t2 m6
  565. %define t3 m7
  566. %ifdef ARCH_X86_64
  567. %define p2 m8
  568. %define q2 m9
  569. %define t4 m10
  570. %define t5 m11
  571. %define mask0 m12
  572. %define mask1p m13
  573. %define mask1q [rsp-24]
  574. %define mpb_0 m14
  575. %define mpb_1 m15
  576. %else
  577. %define spill(x) [esp+16*x+((stack_offset+4)&15)]
  578. %define p2 [r4+r1]
  579. %define q2 [r0+2*r1]
  580. %define t4 spill(0)
  581. %define t5 spill(1)
  582. %define mask0 spill(2)
  583. %define mask1p spill(3)
  584. %define mask1q spill(4)
  585. %define mpb_0 [pb_0]
  586. %define mpb_1 [pb_1]
  587. %endif
  588. ;-----------------------------------------------------------------------------
  589. ; void deblock_v_luma_intra( uint8_t *pix, int stride, int alpha, int beta )
  590. ;-----------------------------------------------------------------------------
  591. cglobal deblock_%2_luma_intra_8_%1, 4,6,16
  592. %ifndef ARCH_X86_64
  593. sub esp, 0x60
  594. %endif
  595. lea r4, [r1*4]
  596. lea r5, [r1*3] ; 3*stride
  597. dec r2d ; alpha-1
  598. jl .end
  599. neg r4
  600. dec r3d ; beta-1
  601. jl .end
  602. add r4, r0 ; pix-4*stride
  603. mova p1, [r4+2*r1]
  604. mova p0, [r4+r5]
  605. mova q0, [r0]
  606. mova q1, [r0+r1]
  607. %ifdef ARCH_X86_64
  608. pxor mpb_0, mpb_0
  609. mova mpb_1, [pb_1]
  610. LOAD_MASK r2d, r3d, t5 ; m5=beta-1, t5=alpha-1, m7=mask0
  611. SWAP 7, 12 ; m12=mask0
  612. pavgb t5, mpb_0
  613. pavgb t5, mpb_1 ; alpha/4+1
  614. movdqa p2, [r4+r1]
  615. movdqa q2, [r0+2*r1]
  616. DIFF_GT2 p0, q0, t5, t0, t3 ; t0 = |p0-q0| > alpha/4+1
  617. DIFF_GT2 p0, p2, m5, t2, t5 ; mask1 = |p2-p0| > beta-1
  618. DIFF_GT2 q0, q2, m5, t4, t5 ; t4 = |q2-q0| > beta-1
  619. pand t0, mask0
  620. pand t4, t0
  621. pand t2, t0
  622. mova mask1q, t4
  623. mova mask1p, t2
  624. %else
  625. LOAD_MASK r2d, r3d, t5 ; m5=beta-1, t5=alpha-1, m7=mask0
  626. mova m4, t5
  627. mova mask0, m7
  628. pavgb m4, [pb_0]
  629. pavgb m4, [pb_1] ; alpha/4+1
  630. DIFF_GT2 p0, q0, m4, m6, m7 ; m6 = |p0-q0| > alpha/4+1
  631. pand m6, mask0
  632. DIFF_GT2 p0, p2, m5, m4, m7 ; m4 = |p2-p0| > beta-1
  633. pand m4, m6
  634. mova mask1p, m4
  635. DIFF_GT2 q0, q2, m5, m4, m7 ; m4 = |q2-q0| > beta-1
  636. pand m4, m6
  637. mova mask1q, m4
  638. %endif
  639. LUMA_INTRA_P012 [r4+r5], [r4+2*r1], [r4+r1], [r4]
  640. LUMA_INTRA_SWAP_PQ
  641. LUMA_INTRA_P012 [r0], [r0+r1], [r0+2*r1], [r0+r5]
  642. .end:
  643. %ifndef ARCH_X86_64
  644. add esp, 0x60
  645. %endif
  646. RET
  647. INIT_MMX
  648. %ifdef ARCH_X86_64
  649. ;-----------------------------------------------------------------------------
  650. ; void deblock_h_luma_intra( uint8_t *pix, int stride, int alpha, int beta )
  651. ;-----------------------------------------------------------------------------
  652. cglobal deblock_h_luma_intra_8_%1, 4,7
  653. movsxd r10, r1d
  654. lea r11, [r10*3]
  655. lea r6, [r0-4]
  656. lea r5, [r0-4+r11]
  657. sub rsp, 0x88
  658. %define pix_tmp rsp
  659. ; transpose 8x16 -> tmp space
  660. TRANSPOSE8x8_MEM PASS8ROWS(r6, r5, r10, r11), PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30)
  661. lea r6, [r6+r10*8]
  662. lea r5, [r5+r10*8]
  663. TRANSPOSE8x8_MEM PASS8ROWS(r6, r5, r10, r11), PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30)
  664. lea r0, [pix_tmp+0x40]
  665. mov r1, 0x10
  666. call deblock_v_luma_intra_8_%1
  667. ; transpose 16x6 -> original space (but we can't write only 6 pixels, so really 16x8)
  668. lea r5, [r6+r11]
  669. TRANSPOSE8x8_MEM PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30), PASS8ROWS(r6, r5, r10, r11)
  670. shl r10, 3
  671. sub r6, r10
  672. sub r5, r10
  673. shr r10, 3
  674. TRANSPOSE8x8_MEM PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30), PASS8ROWS(r6, r5, r10, r11)
  675. add rsp, 0x88
  676. RET
  677. %else
  678. cglobal deblock_h_luma_intra_8_%1, 2,4
  679. lea r3, [r1*3]
  680. sub r0, 4
  681. lea r2, [r0+r3]
  682. %assign pad 0x8c-(stack_offset&15)
  683. SUB rsp, pad
  684. %define pix_tmp rsp
  685. ; transpose 8x16 -> tmp space
  686. TRANSPOSE8x8_MEM PASS8ROWS(r0, r2, r1, r3), PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30)
  687. lea r0, [r0+r1*8]
  688. lea r2, [r2+r1*8]
  689. TRANSPOSE8x8_MEM PASS8ROWS(r0, r2, r1, r3), PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30)
  690. lea r0, [pix_tmp+0x40]
  691. PUSH dword r3m
  692. PUSH dword r2m
  693. PUSH dword 16
  694. PUSH r0
  695. call deblock_%2_luma_intra_8_%1
  696. %ifidn %2, v8
  697. add dword [rsp], 8 ; pix_tmp+8
  698. call deblock_%2_luma_intra_8_%1
  699. %endif
  700. ADD esp, 16
  701. mov r1, r1m
  702. mov r0, r0mp
  703. lea r3, [r1*3]
  704. sub r0, 4
  705. lea r2, [r0+r3]
  706. ; transpose 16x6 -> original space (but we can't write only 6 pixels, so really 16x8)
  707. TRANSPOSE8x8_MEM PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30), PASS8ROWS(r0, r2, r1, r3)
  708. lea r0, [r0+r1*8]
  709. lea r2, [r2+r1*8]
  710. TRANSPOSE8x8_MEM PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30), PASS8ROWS(r0, r2, r1, r3)
  711. ADD rsp, pad
  712. RET
  713. %endif ; ARCH_X86_64
  714. %endmacro ; DEBLOCK_LUMA_INTRA
  715. INIT_XMM
  716. DEBLOCK_LUMA_INTRA sse2, v
  717. %ifdef HAVE_AVX
  718. INIT_AVX
  719. DEBLOCK_LUMA_INTRA avx , v
  720. %endif
  721. %ifndef ARCH_X86_64
  722. INIT_MMX
  723. DEBLOCK_LUMA_INTRA mmxext, v8
  724. %endif
  725. INIT_MMX
  726. %macro CHROMA_V_START 0
  727. dec r2d ; alpha-1
  728. dec r3d ; beta-1
  729. mov t5, r0
  730. sub t5, r1
  731. sub t5, r1
  732. %endmacro
  733. %macro CHROMA_H_START 0
  734. dec r2d
  735. dec r3d
  736. sub r0, 2
  737. lea t6, [r1*3]
  738. mov t5, r0
  739. add r0, t6
  740. %endmacro
  741. %define t5 r5
  742. %define t6 r6
  743. ;-----------------------------------------------------------------------------
  744. ; void ff_deblock_v_chroma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
  745. ;-----------------------------------------------------------------------------
  746. cglobal deblock_v_chroma_8_mmxext, 5,6
  747. CHROMA_V_START
  748. movq m0, [t5]
  749. movq m1, [t5+r1]
  750. movq m2, [r0]
  751. movq m3, [r0+r1]
  752. call ff_chroma_inter_body_mmxext
  753. movq [t5+r1], m1
  754. movq [r0], m2
  755. RET
  756. ;-----------------------------------------------------------------------------
  757. ; void ff_deblock_h_chroma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
  758. ;-----------------------------------------------------------------------------
  759. cglobal deblock_h_chroma_8_mmxext, 5,7
  760. %ifdef ARCH_X86_64
  761. %define buf0 [rsp-24]
  762. %define buf1 [rsp-16]
  763. %else
  764. %define buf0 r0m
  765. %define buf1 r2m
  766. %endif
  767. CHROMA_H_START
  768. TRANSPOSE4x8_LOAD bw, wd, dq, PASS8ROWS(t5, r0, r1, t6)
  769. movq buf0, m0
  770. movq buf1, m3
  771. call ff_chroma_inter_body_mmxext
  772. movq m0, buf0
  773. movq m3, buf1
  774. TRANSPOSE8x4B_STORE PASS8ROWS(t5, r0, r1, t6)
  775. RET
  776. ALIGN 16
  777. ff_chroma_inter_body_mmxext:
  778. LOAD_MASK r2d, r3d
  779. movd m6, [r4] ; tc0
  780. punpcklbw m6, m6
  781. pand m7, m6
  782. DEBLOCK_P0_Q0
  783. ret
  784. ; in: %1=p0 %2=p1 %3=q1
  785. ; out: p0 = (p0 + q1 + 2*p1 + 2) >> 2
  786. %macro CHROMA_INTRA_P0 3
  787. movq m4, %1
  788. pxor m4, %3
  789. pand m4, [pb_1] ; m4 = (p0^q1)&1
  790. pavgb %1, %3
  791. psubusb %1, m4
  792. pavgb %1, %2 ; dst = avg(p1, avg(p0,q1) - ((p0^q1)&1))
  793. %endmacro
  794. %define t5 r4
  795. %define t6 r5
  796. ;-----------------------------------------------------------------------------
  797. ; void ff_deblock_v_chroma_intra( uint8_t *pix, int stride, int alpha, int beta )
  798. ;-----------------------------------------------------------------------------
  799. cglobal deblock_v_chroma_intra_8_mmxext, 4,5
  800. CHROMA_V_START
  801. movq m0, [t5]
  802. movq m1, [t5+r1]
  803. movq m2, [r0]
  804. movq m3, [r0+r1]
  805. call ff_chroma_intra_body_mmxext
  806. movq [t5+r1], m1
  807. movq [r0], m2
  808. RET
  809. ;-----------------------------------------------------------------------------
  810. ; void ff_deblock_h_chroma_intra( uint8_t *pix, int stride, int alpha, int beta )
  811. ;-----------------------------------------------------------------------------
  812. cglobal deblock_h_chroma_intra_8_mmxext, 4,6
  813. CHROMA_H_START
  814. TRANSPOSE4x8_LOAD bw, wd, dq, PASS8ROWS(t5, r0, r1, t6)
  815. call ff_chroma_intra_body_mmxext
  816. TRANSPOSE8x4B_STORE PASS8ROWS(t5, r0, r1, t6)
  817. RET
  818. ALIGN 16
  819. ff_chroma_intra_body_mmxext:
  820. LOAD_MASK r2d, r3d
  821. movq m5, m1
  822. movq m6, m2
  823. CHROMA_INTRA_P0 m1, m0, m3
  824. CHROMA_INTRA_P0 m2, m3, m0
  825. psubb m1, m5
  826. psubb m2, m6
  827. pand m1, m7
  828. pand m2, m7
  829. paddb m1, m5
  830. paddb m2, m6
  831. ret