mirror of
https://code.videolan.org/videolan/dav1d
synced 2026-06-11 04:03:05 +00:00
mc: add HBD/SSSE3 mc.emu_edge optimizations
This commit is contained in:
@@ -3782,3 +3782,363 @@ cglobal blend_h_16bpc, 3, 7, 6, dst, ds, tmp, w, h, mask
|
||||
inc hq
|
||||
jl .w128
|
||||
RET
|
||||
|
||||
; emu_edge args:
|
||||
; const intptr_t bw, const intptr_t bh, const intptr_t iw, const intptr_t ih,
|
||||
; const intptr_t x, const intptr_t y, pixel *dst, const ptrdiff_t dst_stride,
|
||||
; const pixel *ref, const ptrdiff_t ref_stride
|
||||
;
|
||||
; bw, bh total filled size
|
||||
; iw, ih, copied block -> fill bottom, right
|
||||
; x, y, offset in bw/bh -> fill top, left
|
||||
cglobal emu_edge_16bpc, 10, 13, 1, bw, bh, iw, ih, x, \
|
||||
y, dst, dstride, src, sstride, \
|
||||
bottomext, rightext, blk
|
||||
; we assume that the buffer (stride) is larger than width, so we can
|
||||
; safely overwrite by a few bytes
|
||||
|
||||
%if ARCH_X86_64
|
||||
%define reg_zero r12q
|
||||
%define reg_tmp r10
|
||||
%define reg_src srcq
|
||||
%define reg_bottomext bottomextq
|
||||
%define reg_rightext rightextq
|
||||
%define reg_blkm r9m
|
||||
%else
|
||||
%define reg_zero r6
|
||||
%define reg_tmp r0
|
||||
%define reg_src r1
|
||||
%define reg_bottomext r0
|
||||
%define reg_rightext r1
|
||||
%define reg_blkm r2m
|
||||
%endif
|
||||
;
|
||||
; ref += iclip(y, 0, ih - 1) * PXSTRIDE(ref_stride)
|
||||
xor reg_zero, reg_zero
|
||||
lea reg_tmp, [ihq-1]
|
||||
cmp yq, ihq
|
||||
cmovs reg_tmp, yq
|
||||
test yq, yq
|
||||
cmovs reg_tmp, reg_zero
|
||||
%if ARCH_X86_64
|
||||
imul reg_tmp, sstrideq
|
||||
add srcq, reg_tmp
|
||||
%else
|
||||
imul reg_tmp, sstridem
|
||||
mov reg_src, srcm
|
||||
add reg_src, reg_tmp
|
||||
%endif
|
||||
;
|
||||
; ref += iclip(x, 0, iw - 1)
|
||||
lea reg_tmp, [iwq-1]
|
||||
cmp xq, iwq
|
||||
cmovs reg_tmp, xq
|
||||
test xq, xq
|
||||
cmovs reg_tmp, reg_zero
|
||||
lea reg_src, [reg_src+reg_tmp*2]
|
||||
%if ARCH_X86_32
|
||||
mov srcm, reg_src
|
||||
%endif
|
||||
;
|
||||
; bottom_ext = iclip(y + bh - ih, 0, bh - 1)
|
||||
%if ARCH_X86_32
|
||||
mov r1, r1m ; restore bh
|
||||
%endif
|
||||
lea reg_bottomext, [yq+bhq]
|
||||
sub reg_bottomext, ihq
|
||||
lea r3, [bhq-1]
|
||||
cmovs reg_bottomext, reg_zero
|
||||
;
|
||||
|
||||
DEFINE_ARGS bw, bh, iw, ih, x, \
|
||||
topext, dst, dstride, src, sstride, \
|
||||
bottomext, rightext, blk
|
||||
|
||||
; top_ext = iclip(-y, 0, bh - 1)
|
||||
neg topextq
|
||||
cmovs topextq, reg_zero
|
||||
cmp reg_bottomext, bhq
|
||||
cmovns reg_bottomext, r3
|
||||
cmp topextq, bhq
|
||||
cmovg topextq, r3
|
||||
%if ARCH_X86_32
|
||||
mov r4m, reg_bottomext
|
||||
;
|
||||
; right_ext = iclip(x + bw - iw, 0, bw - 1)
|
||||
mov r0, r0m ; restore bw
|
||||
%endif
|
||||
lea reg_rightext, [xq+bwq]
|
||||
sub reg_rightext, iwq
|
||||
lea r2, [bwq-1]
|
||||
cmovs reg_rightext, reg_zero
|
||||
|
||||
DEFINE_ARGS bw, bh, iw, ih, leftext, \
|
||||
topext, dst, dstride, src, sstride, \
|
||||
bottomext, rightext, blk
|
||||
|
||||
; left_ext = iclip(-x, 0, bw - 1)
|
||||
neg leftextq
|
||||
cmovs leftextq, reg_zero
|
||||
cmp reg_rightext, bwq
|
||||
cmovns reg_rightext, r2
|
||||
%if ARCH_X86_32
|
||||
mov r3m, r1
|
||||
%endif
|
||||
cmp leftextq, bwq
|
||||
cmovns leftextq, r2
|
||||
|
||||
%undef reg_zero
|
||||
%undef reg_tmp
|
||||
%undef reg_src
|
||||
%undef reg_bottomext
|
||||
%undef reg_rightext
|
||||
|
||||
DEFINE_ARGS bw, centerh, centerw, dummy, leftext, \
|
||||
topext, dst, dstride, src, sstride, \
|
||||
bottomext, rightext, blk
|
||||
|
||||
; center_h = bh - top_ext - bottom_ext
|
||||
%if ARCH_X86_64
|
||||
lea r3, [bottomextq+topextq]
|
||||
sub centerhq, r3
|
||||
%else
|
||||
mov r1, centerhm ; restore r1
|
||||
sub centerhq, topextq
|
||||
sub centerhq, r4m
|
||||
mov r1m, centerhq
|
||||
%endif
|
||||
;
|
||||
; blk += top_ext * PXSTRIDE(dst_stride)
|
||||
mov r2, topextq
|
||||
%if ARCH_X86_64
|
||||
imul r2, dstrideq
|
||||
%else
|
||||
mov r6, r6m ; restore dstq
|
||||
imul r2, dstridem
|
||||
%endif
|
||||
add dstq, r2
|
||||
mov reg_blkm, dstq ; save pointer for ext
|
||||
;
|
||||
; center_w = bw - left_ext - right_ext
|
||||
mov centerwq, bwq
|
||||
%if ARCH_X86_64
|
||||
lea r3, [rightextq+leftextq]
|
||||
sub centerwq, r3
|
||||
%else
|
||||
sub centerwq, r3m
|
||||
sub centerwq, leftextq
|
||||
%endif
|
||||
|
||||
; vloop Macro
|
||||
%macro v_loop 3 ; need_left_ext, need_right_ext, suffix
|
||||
%if ARCH_X86_64
|
||||
%define reg_tmp r12
|
||||
%else
|
||||
%define reg_tmp r0
|
||||
%endif
|
||||
.v_loop_%3:
|
||||
%if ARCH_X86_32
|
||||
mov r0, r0m
|
||||
mov r1, r1m
|
||||
%endif
|
||||
%if %1
|
||||
; left extension
|
||||
%if ARCH_X86_64
|
||||
movd m0, [srcq]
|
||||
%else
|
||||
mov r3, srcm
|
||||
movd m0, [r3]
|
||||
%endif
|
||||
pshuflw m0, m0, q0000
|
||||
punpcklqdq m0, m0
|
||||
xor r3, r3
|
||||
.left_loop_%3:
|
||||
mova [dstq+r3*2], m0
|
||||
add r3, mmsize/2
|
||||
cmp r3, leftextq
|
||||
jl .left_loop_%3
|
||||
; body
|
||||
lea reg_tmp, [dstq+leftextq*2]
|
||||
%endif
|
||||
xor r3, r3
|
||||
.body_loop_%3:
|
||||
%if ARCH_X86_64
|
||||
movu m0, [srcq+r3*2]
|
||||
%else
|
||||
mov r1, srcm
|
||||
movu m0, [r1+r3*2]
|
||||
%endif
|
||||
%if %1
|
||||
movu [reg_tmp+r3*2], m0
|
||||
%else
|
||||
movu [dstq+r3*2], m0
|
||||
%endif
|
||||
add r3, mmsize/2
|
||||
cmp r3, centerwq
|
||||
jl .body_loop_%3
|
||||
%if %2
|
||||
; right extension
|
||||
%if %1
|
||||
lea reg_tmp, [reg_tmp+centerwq*2]
|
||||
%else
|
||||
lea reg_tmp, [dstq+centerwq*2]
|
||||
%endif
|
||||
%if ARCH_X86_64
|
||||
movd m0, [srcq+centerwq*2-2]
|
||||
%else
|
||||
mov r3, srcm
|
||||
movd m0, [r3+centerwq*2-2]
|
||||
%endif
|
||||
pshuflw m0, m0, q0000
|
||||
punpcklqdq m0, m0
|
||||
xor r3, r3
|
||||
.right_loop_%3:
|
||||
movu [reg_tmp+r3*2], m0
|
||||
add r3, mmsize/2
|
||||
%if ARCH_X86_64
|
||||
cmp r3, rightextq
|
||||
%else
|
||||
cmp r3, r3m
|
||||
%endif
|
||||
jl .right_loop_%3
|
||||
%endif
|
||||
%if ARCH_X86_64
|
||||
add dstq, dstrideq
|
||||
add srcq, sstrideq
|
||||
dec centerhq
|
||||
jg .v_loop_%3
|
||||
%else
|
||||
add dstq, dstridem
|
||||
mov r0, sstridem
|
||||
add srcm, r0
|
||||
sub dword centerhm, 1
|
||||
jg .v_loop_%3
|
||||
mov r0, r0m ; restore r0
|
||||
%endif
|
||||
%endmacro ; vloop MACRO
|
||||
|
||||
test leftextq, leftextq
|
||||
jnz .need_left_ext
|
||||
%if ARCH_X86_64
|
||||
test rightextq, rightextq
|
||||
jnz .need_right_ext
|
||||
%else
|
||||
cmp leftextq, r3m ; leftextq == 0
|
||||
jne .need_right_ext
|
||||
%endif
|
||||
v_loop 0, 0, 0
|
||||
jmp .body_done
|
||||
|
||||
;left right extensions
|
||||
.need_left_ext:
|
||||
%if ARCH_X86_64
|
||||
test rightextq, rightextq
|
||||
%else
|
||||
mov r3, r3m
|
||||
test r3, r3
|
||||
%endif
|
||||
jnz .need_left_right_ext
|
||||
v_loop 1, 0, 1
|
||||
jmp .body_done
|
||||
|
||||
.need_left_right_ext:
|
||||
v_loop 1, 1, 2
|
||||
jmp .body_done
|
||||
|
||||
.need_right_ext:
|
||||
v_loop 0, 1, 3
|
||||
|
||||
.body_done:
|
||||
; r0 ; bw
|
||||
; r1 ;; x loop
|
||||
; r4 ;; y loop
|
||||
; r5 ; topextq
|
||||
; r6 ;dstq
|
||||
; r7 ;dstrideq
|
||||
; r8 ; srcq
|
||||
%if ARCH_X86_64
|
||||
%define reg_dstride dstrideq
|
||||
%else
|
||||
%define reg_dstride r2
|
||||
%endif
|
||||
;
|
||||
; bottom edge extension
|
||||
%if ARCH_X86_64
|
||||
test bottomextq, bottomextq
|
||||
jz .top
|
||||
%else
|
||||
xor r1, r1
|
||||
cmp r1, r4m
|
||||
je .top
|
||||
%endif
|
||||
;
|
||||
%if ARCH_X86_64
|
||||
mov srcq, dstq
|
||||
sub srcq, dstrideq
|
||||
xor r1, r1
|
||||
%else
|
||||
mov r3, dstq
|
||||
mov reg_dstride, dstridem
|
||||
sub r3, reg_dstride
|
||||
mov srcm, r3
|
||||
%endif
|
||||
;
|
||||
.bottom_x_loop:
|
||||
%if ARCH_X86_64
|
||||
mova m0, [srcq+r1*2]
|
||||
lea r3, [dstq+r1*2]
|
||||
mov r4, bottomextq
|
||||
%else
|
||||
mov r3, srcm
|
||||
mova m0, [r3+r1*2]
|
||||
lea r3, [dstq+r1*2]
|
||||
mov r4, r4m
|
||||
%endif
|
||||
;
|
||||
.bottom_y_loop:
|
||||
mova [r3], m0
|
||||
add r3, reg_dstride
|
||||
dec r4
|
||||
jg .bottom_y_loop
|
||||
add r1, mmsize/2
|
||||
cmp r1, bwq
|
||||
jl .bottom_x_loop
|
||||
|
||||
.top:
|
||||
; top edge extension
|
||||
test topextq, topextq
|
||||
jz .end
|
||||
%if ARCH_X86_64
|
||||
mov srcq, reg_blkm
|
||||
%else
|
||||
mov r3, reg_blkm
|
||||
mov reg_dstride, dstridem
|
||||
%endif
|
||||
mov dstq, dstm
|
||||
xor r1, r1
|
||||
;
|
||||
.top_x_loop:
|
||||
%if ARCH_X86_64
|
||||
mova m0, [srcq+r1*2]
|
||||
%else
|
||||
mov r3, reg_blkm
|
||||
mova m0, [r3+r1*2]
|
||||
%endif
|
||||
lea r3, [dstq+r1*2]
|
||||
mov r4, topextq
|
||||
;
|
||||
.top_y_loop:
|
||||
mova [r3], m0
|
||||
add r3, reg_dstride
|
||||
dec r4
|
||||
jg .top_y_loop
|
||||
add r1, mmsize/2
|
||||
cmp r1, bwq
|
||||
jl .top_x_loop
|
||||
|
||||
.end:
|
||||
RET
|
||||
|
||||
%undef reg_dstride
|
||||
%undef reg_blkm
|
||||
%undef reg_tmp
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
decl_##type##_fn(name##_16bpc_sse2); \
|
||||
decl_##type##_fn(name##_16bpc_ssse3); \
|
||||
decl_##type##_fn(name##_16bpc_avx2); \
|
||||
decl_##type##_fn(name##_avx512icl);
|
||||
decl_##type##_fn(name##_16bpc_avx512icl);
|
||||
#define init_mc_fn(type, name, suffix) \
|
||||
c->mc[type] = dav1d_put_##name##_16bpc_##suffix
|
||||
#define init_mct_fn(type, name, suffix) \
|
||||
@@ -217,6 +217,8 @@ COLD void bitfn(dav1d_mc_dsp_init_x86)(Dav1dMCDSPContext *const c) {
|
||||
c->blend = dav1d_blend_16bpc_ssse3;
|
||||
c->blend_v = dav1d_blend_v_16bpc_ssse3;
|
||||
c->blend_h = dav1d_blend_h_16bpc_ssse3;
|
||||
|
||||
c->emu_edge = dav1d_emu_edge_16bpc_ssse3;
|
||||
#endif
|
||||
|
||||
if(!(flags & DAV1D_X86_CPU_FLAG_SSE41))
|
||||
|
||||
Reference in New Issue
Block a user