From: James Almer <jamrial@gmail.com>
To: ffmpeg-devel@ffmpeg.org
Subject: Re: [FFmpeg-devel] [PATCH] swscale/x86/rgb2rgb: add AVX512ICL version of uyvytoyuv422
Date: Tue, 18 Feb 2025 12:44:28 -0300
Message-ID: <46b49b38-b7b4-4c05-9454-85bee444c039@gmail.com> (raw)
In-Reply-To: <CA+-x59bp0MR3rZaVduv_WkRABW2f3K9DsEtgL65izFqNd-O57Q@mail.gmail.com>
[-- Attachment #1.1.1: Type: text/plain, Size: 9921 bytes --]
On 2/18/2025 11:58 AM, Shreesh Adiga wrote:
> On Mon, Feb 3, 2025 at 10:03 PM Shreesh Adiga
> <16567adigashreesh@gmail.com> wrote:
>>
>> 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
>>
>
> Hi maintainers,
>
> Would anyone be willing to review this and provide inputs on getting
> this accepted?
> As a new contributor interested in contributing ASM, I was hoping to
> work on https://trac.ffmpeg.org/wiki/SmallASMTasks mentioned AVX512ICL
> work.
Applied, sorry for the delay.
[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]
[-- Attachment #2: Type: text/plain, Size: 251 bytes --]
_______________________________________________
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".
prev parent reply other threads:[~2025-02-18 15:44 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-03 16:33 Shreesh Adiga
2025-02-18 14:58 ` Shreesh Adiga
2025-02-18 15:44 ` James Almer [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=46b49b38-b7b4-4c05-9454-85bee444c039@gmail.com \
--to=jamrial@gmail.com \
--cc=ffmpeg-devel@ffmpeg.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
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