* [FFmpeg-devel] [PATCH] swscale/x86/rgb2rgb: add AVX512ICL version of uyvytoyuv422
@ 2025-02-03 16:33 Shreesh Adiga
0 siblings, 0 replies; only message in thread
From: Shreesh Adiga @ 2025-02-03 16:33 UTC (permalink / raw)
To: ffmpeg-devel
The scalar loop is replaced with masked AVX512 instructions.
For extracting the Y from UYVY, vperm2b is used instead of
various AND and packuswb.
Instead of loading the vectors with interleaved lanes as done
in AVX2 version, normal load is used. At the end of packuswb,
for U and V, an extra permute operation is done to get the
required layout.
AMD 7950x Zen 4 benchmark data:
uyvytoyuv422_c: 29105.0 ( 1.00x)
uyvytoyuv422_sse2: 3888.0 ( 7.49x)
uyvytoyuv422_avx: 3374.2 ( 8.63x)
uyvytoyuv422_avx2: 2649.8 (10.98x)
uyvytoyuv422_avx512icl: 1615.0 (18.02x)
Signed-off-by: Shreesh Adiga <16567adigashreesh@gmail.com>
---
libswscale/x86/rgb2rgb.c | 6 ++
libswscale/x86/rgb_2_rgb.asm | 105 +++++++++++++++++++++++++++++++++++
2 files changed, 111 insertions(+)
diff --git a/libswscale/x86/rgb2rgb.c b/libswscale/x86/rgb2rgb.c
index 4cbed54b35..6601dad233 100644
--- a/libswscale/x86/rgb2rgb.c
+++ b/libswscale/x86/rgb2rgb.c
@@ -2383,6 +2383,9 @@ void ff_uyvytoyuv422_avx(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
void ff_uyvytoyuv422_avx2(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
const uint8_t *src, int width, int height,
int lumStride, int chromStride, int srcStride);
+void ff_uyvytoyuv422_avx512icl(uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
+ const uint8_t *src, int width, int height,
+ int lumStride, int chromStride, int srcStride);
#endif
#define DEINTERLEAVE_BYTES(cpuext) \
@@ -2477,6 +2480,9 @@ av_cold void rgb2rgb_init_x86(void)
}
if (EXTERNAL_AVX2_FAST(cpu_flags)) {
uyvytoyuv422 = ff_uyvytoyuv422_avx2;
+ }
+ if (EXTERNAL_AVX512ICL(cpu_flags)) {
+ uyvytoyuv422 = ff_uyvytoyuv422_avx512icl;
#endif
}
#endif
diff --git a/libswscale/x86/rgb_2_rgb.asm b/libswscale/x86/rgb_2_rgb.asm
index ca7a481255..6e4df17298 100644
--- a/libswscale/x86/rgb_2_rgb.asm
+++ b/libswscale/x86/rgb_2_rgb.asm
@@ -35,6 +35,20 @@ pb_shuffle2013: db 2, 0, 1, 3, 6, 4, 5, 7, 10, 8, 9, 11, 14, 12, 13, 15
pb_shuffle2130: db 2, 1, 3, 0, 6, 5, 7, 4, 10, 9, 11, 8, 14, 13, 15, 12
pb_shuffle1203: db 1, 2, 0, 3, 5, 6, 4, 7, 9, 10, 8, 11, 13, 14, 12, 15
+%if HAVE_AVX512ICL_EXTERNAL
+; shuffle vector to rearrange packuswb result to be linear
+shuf_packus: db 0, 1, 2, 3, 16, 17, 18, 19, 32, 33, 34, 35, 48, 49, 50, 51,\
+ 4, 5, 6, 7, 20, 21, 22, 23, 36, 37, 38, 39, 52, 53, 54, 55,\
+ 8, 9, 10, 11, 24, 25, 26, 27, 40, 41, 42, 43, 56, 57, 58, 59,\
+ 12, 13, 14, 15, 28, 29, 30, 31, 44, 45, 46, 47, 60, 61, 62, 63
+
+; shuffle vector to combine odd elements from two vectors to extract Y
+shuf_perm2b: db 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31,\
+ 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63,\
+ 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95,\
+ 97, 99, 101, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127
+%endif
+
SECTION .text
%macro RSHIFT_COPY 5
@@ -156,9 +170,20 @@ SHUFFLE_BYTES 1, 2, 0, 3
; int lumStride, int chromStride, int srcStride)
;-----------------------------------------------------------------------------------------------
%macro UYVY_TO_YUV422 0
+%if mmsize == 64
+; need two more registers to store shuffle vectors for AVX512ICL
+cglobal uyvytoyuv422, 9, 14, 10, ydst, udst, vdst, src, w, h, lum_stride, chrom_stride, src_stride, wtwo, whalf, tmp, x, back_w
+%else
cglobal uyvytoyuv422, 9, 14, 8, ydst, udst, vdst, src, w, h, lum_stride, chrom_stride, src_stride, wtwo, whalf, tmp, x, back_w
+%endif
pxor m0, m0
+%if mmsize == 64
+ vpternlogd m1, m1, m1, 0xff ; m1 = _mm512_set1_epi8(0xff)
+ movu m8, [shuf_packus]
+ movu m9, [shuf_perm2b]
+%else
pcmpeqw m1, m1
+%endif
psrlw m1, 8
movsxdifnidn wq, wd
@@ -188,6 +213,63 @@ cglobal uyvytoyuv422, 9, 14, 8, ydst, udst, vdst, src, w, h, lum_stride, chrom_s
and xq, mmsize * 2 - 1
je .loop_simd
+%if mmsize == 64
+ shr xq, 1
+ mov tmpq, -1
+ shlx tmpq, tmpq, xq
+ not tmpq
+ kmovq k7, tmpq ; write mask for U/V
+ kmovd k1, tmpd ; write mask for 1st half of Y
+ kmovw k3, tmpd ; read mask for 1st vector
+ shr tmpq, 16
+ kmovw k4, tmpd ; read mask for 2nd vector
+ shr tmpq, 16
+ kmovd k2, tmpd ; write mask for 2nd half of Y
+ kmovw k5, tmpd ; read mask for 3rd vector
+ shr tmpd, 16
+ kmovw k6, tmpd ; read mask for 4th vector
+
+ vmovdqu32 m2{k3}{z}, [srcq + wtwoq ]
+ vmovdqu32 m3{k4}{z}, [srcq + wtwoq + mmsize ]
+ vmovdqu32 m4{k5}{z}, [srcq + wtwoq + mmsize * 2]
+ vmovdqu32 m5{k6}{z}, [srcq + wtwoq + mmsize * 3]
+
+ ; extract y part 1
+ mova m6, m9
+ vpermi2b m6, m2, m3 ; UYVY UYVY -> YYYY using permute
+ vmovdqu16 [ydstq + wq]{k1}, m6
+
+ ; extract y part 2
+ mova m7, m9
+ vpermi2b m7, m4, m5 ; UYVY UYVY -> YYYY using permute
+ vmovdqu16 [ydstq + wq + mmsize]{k2}, m7
+
+ ; extract uv
+ pand m2, m1 ; UxVx...
+ pand m3, m1 ; UxVx...
+ pand m4, m1 ; UxVx...
+ pand m5, m1 ; UxVx...
+ packuswb m2, m3 ; UVUV...
+ packuswb m4, m5 ; UVUV...
+
+ ; U
+ pand m6, m2, m1 ; UxUx...
+ pand m7, m4, m1 ; UxUx...
+ packuswb m6, m7 ; UUUU
+ vpermb m6, m8, m6
+ vmovdqu8 [udstq + whalfq]{k7}, m6
+
+ ; V
+ psrlw m2, 8 ; VxVx...
+ psrlw m4, 8 ; VxVx...
+ packuswb m2, m4 ; VVVV
+ vpermb m2, m8, m2
+ vmovdqu8 [vdstq + whalfq]{k7}, m2
+
+ lea wq, [ wq + 2 * xq]
+ lea wtwoq, [wtwoq + 4 * xq]
+ add whalfq, xq
+%else
.loop_scalar:
mov tmpb, [srcq + wtwoq + 0]
mov [udstq + whalfq], tmpb
@@ -206,6 +288,7 @@ cglobal uyvytoyuv422, 9, 14, 8, ydst, udst, vdst, src, w, h, lum_stride, chrom_s
add whalfq, 1
sub xq, 2
jg .loop_scalar
+%endif
; check if simd loop is need
cmp wq, 0
@@ -228,6 +311,17 @@ cglobal uyvytoyuv422, 9, 14, 8, ydst, udst, vdst, src, w, h, lum_stride, chrom_s
movu m5, [srcq + wtwoq + mmsize * 3]
%endif
+%if mmsize == 64
+ ; extract y part 1
+ mova m6, m9
+ vpermi2b m6, m2, m3 ; UYVY UYVY -> YYYY using permute
+ movu [ydstq + wq], m6
+
+ ; extract y part 2
+ mova m7, m9
+ vpermi2b m7, m4, m5 ; UYVY UYVY -> YYYY using permute
+ movu [ydstq + wq + mmsize], m7
+%else
; extract y part 1
RSHIFT_COPY m6, m2, m4, 1, 0x20 ; UYVY UYVY -> YVYU YVY...
pand m6, m1; YxYx YxYx...
@@ -247,6 +341,7 @@ cglobal uyvytoyuv422, 9, 14, 8, ydst, udst, vdst, src, w, h, lum_stride, chrom_s
packuswb m6, m7 ; YYYY YYYY...
movu [ydstq + wq + mmsize], m6
+%endif
; extract uv
pand m2, m1 ; UxVx...
@@ -262,6 +357,9 @@ cglobal uyvytoyuv422, 9, 14, 8, ydst, udst, vdst, src, w, h, lum_stride, chrom_s
pand m7, m4, m1 ; UxUx...
packuswb m6, m7 ; UUUU
+%if mmsize == 64
+ vpermb m6, m8, m6
+%endif
movu [udstq + whalfq], m6
@@ -269,6 +367,9 @@ cglobal uyvytoyuv422, 9, 14, 8, ydst, udst, vdst, src, w, h, lum_stride, chrom_s
psrlw m2, 8 ; VxVx...
psrlw m4, 8 ; VxVx...
packuswb m2, m4 ; VVVV
+%if mmsize == 64
+ vpermb m2, m8, m2
+%endif
movu [vdstq + whalfq], m2
add whalfq, mmsize
@@ -303,4 +404,8 @@ UYVY_TO_YUV422
INIT_YMM avx2
UYVY_TO_YUV422
%endif
+%if HAVE_AVX512ICL_EXTERNAL
+INIT_ZMM avx512icl
+UYVY_TO_YUV422
+%endif
%endif
--
2.45.3
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2025-02-03 16:33 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-02-03 16:33 [FFmpeg-devel] [PATCH] swscale/x86/rgb2rgb: add AVX512ICL version of uyvytoyuv422 Shreesh Adiga
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git