From 75259b820c8fa580736ce48729abc59d16fc5ca8 Mon Sep 17 00:00:00 2001 From: Aous Naman Date: Thu, 7 Nov 2024 08:24:48 +1100 Subject: [PATCH] I should have committed these incomplete files. --- src/core/transform/ojph_colour.cpp | 6 +- src/core/transform/ojph_colour_avx2.cpp | 200 +++++++++++++++++++----- 2 files changed, 166 insertions(+), 40 deletions(-) diff --git a/src/core/transform/ojph_colour.cpp b/src/core/transform/ojph_colour.cpp index 6289ae1..a4effbf 100644 --- a/src/core/transform/ojph_colour.cpp +++ b/src/core/transform/ojph_colour.cpp @@ -163,10 +163,10 @@ namespace ojph { #ifndef OJPH_DISABLE_AVX2 if (get_cpu_ext_level() >= X86_CPU_EXT_LEVEL_AVX2) { - // cnvrt_si32_to_si32_shftd = avx2_cnvrt_si32_to_si32_shftd; - // cnvrt_si32_to_si32_nlt_type3 = avx2_cnvrt_si32_to_si32_nlt_type3; + //rev_convert = avx2_rev_convert; + //rev_convert_nlt_type3 = avx2_rev_convert_nlt_type3; // rct_forward = avx2_rct_forward; - // rct_backward = avx2_rct_backward; + rct_backward = avx2_rct_backward; } #endif // !OJPH_DISABLE_AVX2 diff --git a/src/core/transform/ojph_colour_avx2.cpp b/src/core/transform/ojph_colour_avx2.cpp index 14e5a35..9e550d3 100644 --- a/src/core/transform/ojph_colour_avx2.cpp +++ b/src/core/transform/ojph_colour_avx2.cpp @@ -35,10 +35,12 @@ // Date: 11 October 2019 //***************************************************************************/ +#include #include #include "ojph_defs.h" #include "ojph_arch.h" +#include "ojph_mem.h" #include "ojph_colour.h" #include @@ -46,6 +48,20 @@ namespace ojph { namespace local { + ///////////////////////////////////////////////////////////////////////// + // https://github.com/seung-lab/dijkstra3d/blob/master/libdivide.h + static inline + __m256i avx2_mm256_srai_epi64(__m256i a, int amt, __m256i m) + { + // note than m must be obtained using + // __m256i m = _mm256_set1_epi64x(1ULL << (63 - amt)); + __m256i x = _mm256_srli_epi64(a, amt); + x = _mm256_xor_si256(x, m); + __m256i result = _mm256_sub_epi64(x, m); + return result; + } + + ////////////////////////////////////////////////////////////////////////// void avx2_cnvrt_si32_to_si32_shftd(const si32 *sp, si32 *dp, int shift, ui32 width) @@ -80,50 +96,160 @@ namespace ojph { } } + // + // _mm256_cvtepi32_epi64 + // + + // ////////////////////////////////////////////////////////////////////////// + // void avx2_rct_forward(const si32 *r, const si32 *g, const si32 *b, + // si32 *y, si32 *cb, si32 *cr, ui32 repeat) + // { + // for (int i = (repeat + 7) >> 3; i > 0; --i) + // { + // __m256i mr = _mm256_load_si256((__m256i*)r); + // __m256i mg = _mm256_load_si256((__m256i*)g); + // __m256i mb = _mm256_load_si256((__m256i*)b); + // __m256i t = _mm256_add_epi32(mr, mb); + // t = _mm256_add_epi32(t, _mm256_slli_epi32(mg, 1)); + // _mm256_store_si256((__m256i*)y, _mm256_srai_epi32(t, 2)); + // t = _mm256_sub_epi32(mb, mg); + // _mm256_store_si256((__m256i*)cb, t); + // t = _mm256_sub_epi32(mr, mg); + // _mm256_store_si256((__m256i*)cr, t); + + // r += 8; g += 8; b += 8; + // y += 8; cb += 8; cr += 8; + // } + // } + ////////////////////////////////////////////////////////////////////////// - void avx2_rct_forward(const si32 *r, const si32 *g, const si32 *b, - si32 *y, si32 *cb, si32 *cr, ui32 repeat) + void avx2_rct_backward(const line_buf *y, + const line_buf *cb, + const line_buf *cr, + line_buf *r, line_buf *g, line_buf *b, + ui32 repeat) { - for (int i = (repeat + 7) >> 3; i > 0; --i) + assert((y->flags & line_buf::LFT_REVERSIBLE) && + (cb->flags & line_buf::LFT_REVERSIBLE) && + (cr->flags & line_buf::LFT_REVERSIBLE) && + (r->flags & line_buf::LFT_REVERSIBLE) && + (g->flags & line_buf::LFT_REVERSIBLE) && + (b->flags & line_buf::LFT_REVERSIBLE)); + + if (y->flags & line_buf::LFT_32BIT) { - __m256i mr = _mm256_load_si256((__m256i*)r); - __m256i mg = _mm256_load_si256((__m256i*)g); - __m256i mb = _mm256_load_si256((__m256i*)b); - __m256i t = _mm256_add_epi32(mr, mb); - t = _mm256_add_epi32(t, _mm256_slli_epi32(mg, 1)); - _mm256_store_si256((__m256i*)y, _mm256_srai_epi32(t, 2)); - t = _mm256_sub_epi32(mb, mg); - _mm256_store_si256((__m256i*)cb, t); - t = _mm256_sub_epi32(mr, mg); - _mm256_store_si256((__m256i*)cr, t); - - r += 8; g += 8; b += 8; - y += 8; cb += 8; cr += 8; - } - } + assert((y->flags & line_buf::LFT_32BIT) && + (cb->flags & line_buf::LFT_32BIT) && + (cr->flags & line_buf::LFT_32BIT) && + (r->flags & line_buf::LFT_32BIT) && + (g->flags & line_buf::LFT_32BIT) && + (b->flags & line_buf::LFT_32BIT)); + const si32 *yp = y->i32, *cbp = cb->i32, *crp = cr->i32; + si32 *rp = r->i32, *gp = g->i32, *bp = b->i32; + for (int i = (repeat + 7) >> 3; i > 0; --i) + { + __m256i my = _mm256_load_si256((__m256i*)yp); + __m256i mcb = _mm256_load_si256((__m256i*)cbp); + __m256i mcr = _mm256_load_si256((__m256i*)crp); - ////////////////////////////////////////////////////////////////////////// - void avx2_rct_backward(const si32 *y, const si32 *cb, const si32 *cr, - si32 *r, si32 *g, si32 *b, ui32 repeat) - { - for (int i = (repeat + 7) >> 3; i > 0; --i) + __m256i t = _mm256_add_epi32(mcb, mcr); + t = _mm256_sub_epi32(my, _mm256_srai_epi32(t, 2)); + _mm256_store_si256((__m256i*)gp, t); + __m256i u = _mm256_add_epi32(mcb, t); + _mm256_store_si256((__m256i*)bp, u); + u = _mm256_add_epi32(mcr, t); + _mm256_store_si256((__m256i*)rp, u); + + yp += 8; cbp += 8; crp += 8; + rp += 8; gp += 8; bp += 8; + } + } + else { - __m256i my = _mm256_load_si256((__m256i*)y); - __m256i mcb = _mm256_load_si256((__m256i*)cb); - __m256i mcr = _mm256_load_si256((__m256i*)cr); - - __m256i t = _mm256_add_epi32(mcb, mcr); - t = _mm256_sub_epi32(my, _mm256_srai_epi32(t, 2)); - _mm256_store_si256((__m256i*)g, t); - __m256i u = _mm256_add_epi32(mcb, t); - _mm256_store_si256((__m256i*)b, u); - u = _mm256_add_epi32(mcr, t); - _mm256_store_si256((__m256i*)r, u); - - y += 8; cb += 8; cr += 8; - r += 8; g += 8; b += 8; + assert((y->flags & line_buf::LFT_64BIT) && + (cb->flags & line_buf::LFT_64BIT) && + (cr->flags & line_buf::LFT_64BIT) && + (r->flags & line_buf::LFT_32BIT) && + (g->flags & line_buf::LFT_32BIT) && + (b->flags & line_buf::LFT_32BIT)); + __m256i v2 = _mm256_set1_epi64x(1ULL << (63 - 2)); + __m256i low_bits = _mm256_set_epi64x(0, (si64)ULLONG_MAX, 0, (si64)ULLONG_MAX); + const si64 *yp = y->i64, *cbp = cb->i64, *crp = cr->i64; + si32 *rp = r->i32, *gp = g->i32, *bp = b->i32; + for (int i = (repeat + 7) >> 3; i > 0; --i) + { + __m256i my, mcb, mcr, tr, tg, tb; + my = _mm256_load_si256((__m256i*)yp); + mcb = _mm256_load_si256((__m256i*)cbp); + mcr = _mm256_load_si256((__m256i*)crp); + + tg = _mm256_add_epi64(mcb, mcr); + tg = _mm256_sub_epi64(my, avx2_mm256_srai_epi64(tg, 2, v2)); + tb = _mm256_add_epi64(mcb, tg); + tr = _mm256_add_epi64(mcr, tg); + + __m256i mr, mg, mb; + mr = _mm256_shuffle_epi32(tr, _MM_SHUFFLE(0, 0, 2, 0)); + mr = _mm256_and_si256(low_bits, mr); + mg = _mm256_shuffle_epi32(tg, _MM_SHUFFLE(0, 0, 2, 0)); + mg = _mm256_and_si256(low_bits, mg); + mb = _mm256_shuffle_epi32(tb, _MM_SHUFFLE(0, 0, 2, 0)); + mb = _mm256_and_si256(low_bits, mb); + + yp += 4; cbp += 4; crp += 4; + + my = _mm256_load_si256((__m256i*)yp); + mcb = _mm256_load_si256((__m256i*)cbp); + mcr = _mm256_load_si256((__m256i*)crp); + + tg = _mm256_add_epi64(mcb, mcr); + tg = _mm256_sub_epi64(my, avx2_mm256_srai_epi64(tg, 2, v2)); + tb = _mm256_add_epi64(mcb, tg); + tr = _mm256_add_epi64(mcr, tg); + + tr = _mm256_shuffle_epi32(tr, _MM_SHUFFLE(2, 0, 0, 0)); + tr = _mm256_andnot_si256(low_bits, tr); + mr = _mm256_or_si256(mr, tr); + tg = _mm256_shuffle_epi32(tg, _MM_SHUFFLE(2, 0, 0, 0)); + tg = _mm256_andnot_si256(low_bits, tg); + mg = _mm256_or_si256(mg, tg); + tb = _mm256_shuffle_epi32(tb, _MM_SHUFFLE(2, 0, 0, 0)); + tb = _mm256_andnot_si256(low_bits, tb); + mb = _mm256_or_si256(mb, tb); + + _mm256_store_si256((__m256i*)rp, mr); + _mm256_store_si256((__m256i*)gp, mg); + _mm256_store_si256((__m256i*)bp, mb); + + yp += 4; cbp += 4; crp += 4; + rp += 8; gp += 8; bp += 8; + } } } + + // ////////////////////////////////////////////////////////////////////////// + // void avx2_rct_backward(const si32 *y, const si32 *cb, const si32 *cr, + // si32 *r, si32 *g, si32 *b, ui32 repeat) + // { + // for (int i = (repeat + 7) >> 3; i > 0; --i) + // { + // __m256i my = _mm256_load_si256((__m256i*)y); + // __m256i mcb = _mm256_load_si256((__m256i*)cb); + // __m256i mcr = _mm256_load_si256((__m256i*)cr); + + // __m256i t = _mm256_add_epi32(mcb, mcr); + // t = _mm256_sub_epi32(my, _mm256_srai_epi32(t, 2)); + // _mm256_store_si256((__m256i*)g, t); + // __m256i u = _mm256_add_epi32(mcb, t); + // _mm256_store_si256((__m256i*)b, u); + // u = _mm256_add_epi32(mcr, t); + // _mm256_store_si256((__m256i*)r, u); + + // y += 8; cb += 8; cr += 8; + // r += 8; g += 8; b += 8; + // } + // } + } }