Coverage Report

Created: 2026-07-25 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vvdec/source/Lib/CommonLib/x86/QuantX86.h
Line
Count
Source
1
/* -----------------------------------------------------------------------------
2
The copyright in this software is being made available under the Clear BSD
3
License, included below. No patent rights, trademark rights and/or
4
other Intellectual Property Rights other than the copyrights concerning
5
the Software are granted under this license.
6
7
The Clear BSD License
8
9
Copyright (c) 2018-2026, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. & The VVdeC Authors.
10
All rights reserved.
11
12
Redistribution and use in source and binary forms, with or without modification,
13
are permitted (subject to the limitations in the disclaimer below) provided that
14
the following conditions are met:
15
16
     * Redistributions of source code must retain the above copyright notice,
17
     this list of conditions and the following disclaimer.
18
19
     * Redistributions in binary form must reproduce the above copyright
20
     notice, this list of conditions and the following disclaimer in the
21
     documentation and/or other materials provided with the distribution.
22
23
     * Neither the name of the copyright holder nor the names of its
24
     contributors may be used to endorse or promote products derived from this
25
     software without specific prior written permission.
26
27
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
28
THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
29
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
31
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
32
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
33
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
34
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
35
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
36
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38
POSSIBILITY OF SUCH DAMAGE.
39
40
41
------------------------------------------------------------------------------------------- */
42
43
/** \file     QuantX86.h
44
    \brief    SIMD for Quant/Dequant
45
*/
46
47
#include "CommonLib/CommonDef.h"
48
#include "CommonDefX86.h"
49
#include "CommonLib/Quant.h"
50
51
namespace vvdec
52
{
53
54
#if ENABLE_SIMD_OPT_QUANT
55
#ifdef TARGET_SIMD_X86
56
57
template<X86_VEXT vext, class T, bool UseScalingList, bool RightShiftPositive>
58
static inline void DeQuantImplSIMD( const SizeType width,
59
                                    const int      maxX,
60
                                    const int      maxY,
61
                                    const int      scaleQP,
62
                                    const int*     piDequantCoef,   // unused if UseScalingList == false
63
                                    const T* const piQCoef,
64
                                    const size_t   piQCfStride,
65
                                    TCoeff* const  piCoef,
66
                                    const int      rightShift,
67
                                    const int      inputMaximum,
68
                                    const TCoeff   transformMaximum )
69
58.6k
{
70
58.6k
  static_assert( sizeof( piQCoef[0] ) == sizeof( int16_t ) || sizeof( piQCoef[0] ) == sizeof( int32_t ), "wrong coeff type" );
71
72
58.6k
  constexpr static bool QCoef_16bit = sizeof( piQCoef[0] ) == sizeof( int16_t );
73
74
58.6k
  const int    inputMinimum     = -( inputMaximum + 1 );
75
58.6k
  const TCoeff transformMinimum = -( transformMaximum + 1 );
76
77
58.6k
  const int iAdd  = RightShiftPositive ? 1 << ( rightShift - 1 ) : 0;
78
58.6k
  const int shift = RightShiftPositive ? rightShift : -rightShift;
79
80
58.6k
  const __m128i vInputMin     = _mm_set1_epi32( inputMinimum );
81
58.6k
  const __m128i vInputMax     = _mm_set1_epi32( inputMaximum );
82
58.6k
  const __m128i vTransformMin = _mm_set1_epi32( transformMinimum );
83
58.6k
  const __m128i vTransformMax = _mm_set1_epi32( transformMaximum );
84
85
58.6k
  const __m128i vAdd   = _mm_set1_epi32( iAdd );
86
58.6k
  const __m128i vShift = _mm_set_epi64x( 0, shift );
87
58.6k
        __m128i vScale = _mm_set1_epi32( scaleQP );
88
89
#if USE_AVX2
90
  const __m256i xvInputMin     = _mm256_set1_epi32( inputMinimum );
91
  const __m256i xvInputMax     = _mm256_set1_epi32( inputMaximum );
92
  const __m256i xvTransformMin = _mm256_set1_epi32( transformMinimum );
93
  const __m256i xvTransformMax = _mm256_set1_epi32( transformMaximum );
94
95
  const __m256i xvAdd   = _mm256_set1_epi32( iAdd );
96
        __m256i xvScale = _mm256_set1_epi32( scaleQP );
97
#endif   // USE_AVX2
98
99
58.6k
  const int endX       = maxX + 1;
100
58.6k
  const int maskCoeffs = endX & 3;   // number of coefficients in the last vector read
101
  // clang-format off
102
58.6k
  const __m128i vMask = maskCoeffs == 3 ? _mm_set_epi32( 0, -1, -1, -1 ) :
103
58.6k
                      ( maskCoeffs == 2 ? _mm_set_epi32( 0, 0, -1, -1 )
104
58.5k
                                        : _mm_set_epi32( 0, 0, 0, -1 ) );
105
  // clang-format on
106
107
418k
  for( int y = 0; y <= maxY; y++ )
108
359k
  {
109
359k
    int x = 0;
110
359k
    int n = y * width;
111
112
#if USE_AVX2
113
517k
    for( ; x + 7 < endX; x += 8, n += 8 )
114
158k
    {
115
158k
      if( UseScalingList )
116
0
      {
117
0
        xvScale = _mm256_set1_epi32( scaleQP );
118
0
        xvScale = _mm256_mullo_epi32( xvScale, _mm256_loadu_si256( (__m256i*) &piDequantCoef[n] ) );
119
0
      }
120
121
158k
      __m256i xvLevel = QCoef_16bit ? _mm256_cvtepi16_epi32( _mm_loadu_si128( (__m128i*) &piQCoef[x + y * piQCfStride] ) )   // 16 bit coeffs
122
31.8k
                                    : _mm256_loadu_si256( (__m256i*) &piQCoef[x + y * piQCfStride] );                        // 32 bit coeffs
123
124
      xvLevel = _mm256_max_epi32( xvLevel, xvInputMin );
125
      xvLevel = _mm256_min_epi32( xvLevel, xvInputMax );
126
127
      xvLevel = _mm256_mullo_epi32( xvLevel, xvScale );
128
158k
      if( RightShiftPositive )
129
63.0k
      {
130
63.0k
        xvLevel = _mm256_add_epi32( xvLevel, xvAdd );
131
63.0k
        xvLevel = _mm256_sra_epi32( xvLevel, vShift );
132
63.0k
      }
133
94.9k
      else
134
94.9k
      {
135
94.9k
        xvLevel = _mm256_sll_epi32( xvLevel, vShift );
136
94.9k
      }
137
138
      xvLevel = _mm256_max_epi32( xvLevel, xvTransformMin );
139
      xvLevel = _mm256_min_epi32( xvLevel, xvTransformMax );
140
141
158k
      _mm256_storeu_si256( (__m256i*) &piCoef[n], xvLevel );
142
158k
    }
143
#endif   // USE_AVX2
144
145
613k
    for( ; x + 3 < endX; x += 4, n += 4 )
146
253k
    {
147
253k
      if( UseScalingList )
148
0
      {
149
0
        vScale = _mm_set1_epi32( scaleQP );
150
0
        vScale = _mm_mullo_epi32( vScale, _mm_loadu_si128( (__m128i*) &piDequantCoef[n] ) );
151
0
      }
152
153
253k
      __m128i vLevel = QCoef_16bit ? _mm_cvtepi16_epi32( _mm_loadu_si64( &piQCoef[x + y * piQCfStride] ) )   // 16 bit coeffs
154
253k
                                   : _mm_loadu_si128( (__m128i*) &piQCoef[x + y * piQCfStride] );            // 32 bit coeffs
155
156
253k
      vLevel = _mm_max_epi32( vLevel, vInputMin );
157
253k
      vLevel = _mm_min_epi32( vLevel, vInputMax );
158
159
253k
      vLevel = _mm_mullo_epi32( vLevel, vScale );
160
253k
      if( RightShiftPositive )
161
26.4k
      {
162
26.4k
        vLevel = _mm_add_epi32( vLevel, vAdd );
163
26.4k
        vLevel = _mm_sra_epi32( vLevel, vShift );
164
26.4k
      }
165
227k
      else
166
227k
      {
167
227k
        vLevel = _mm_sll_epi32( vLevel, vShift );
168
227k
      }
169
170
253k
      vLevel = _mm_max_epi32( vLevel, vTransformMin );
171
253k
      vLevel = _mm_min_epi32( vLevel, vTransformMax );
172
173
253k
      _mm_storeu_si128( (__m128i*) &piCoef[n], vLevel );
174
253k
    }
175
176
#if 0   // dequant remaining coefficients using scalar code
177
    (void)vMask;
178
    for( ; x < endX; x++, n++ )
179
    {
180
      const TCoeff level = piQCoef[x + y * piQCfStride];
181
      if( !level )
182
      {
183
        continue;
184
      }
185
186
      const int        scale     = UseScalingList ? piDequantCoef[n] * scaleQP   //
187
                                                  : scaleQP;
188
      const TCoeff     clipQCoef = TCoeff( Clip3<Intermediate_Int>( inputMinimum, inputMaximum, level ) );
189
      Intermediate_Int iCoeffQ   = RightShiftPositive ? ( Intermediate_Int( clipQCoef ) * scale + iAdd ) >> rightShift   //
190
                                                      : ( Intermediate_Int( clipQCoef ) * scale ) * ( 1 << shift );
191
192
      piCoef[n] = TCoeff( Clip3<Intermediate_Int>( transformMinimum, transformMaximum, iCoeffQ ) );
193
    }
194
195
#else   // dequant remaining coefficients using SSE
196
197
359k
    if( x < endX )
198
1.87k
    {
199
1.87k
      CHECKD( endX - x >= 4 || endX - x != maskCoeffs, "wrong mask for remaining coeffs" << ( endX - x ) << " " << maskCoeffs );
200
201
1.87k
      if( UseScalingList )
202
0
      {
203
0
        vScale = _mm_set1_epi32( scaleQP );
204
0
        vScale = _mm_mullo_epi32( vScale, _mm_loadu_si128( (__m128i*) &piDequantCoef[n] ) );
205
0
        vScale = _mm_and_si128( vScale, vMask );
206
0
      }
207
208
1.87k
      __m128i vLevel = QCoef_16bit ? _mm_cvtepi16_epi32( _mm_loadu_si64( &piQCoef[x + y * piQCfStride] ) )   // 16 bit coeffs
209
1.87k
                                   : _mm_loadu_si128( (__m128i*) &piQCoef[x + y * piQCfStride] );            // 32 bit coeffs
210
211
1.87k
      vLevel = _mm_and_si128( vLevel, vMask );
212
213
1.87k
      vLevel = _mm_max_epi32( vLevel, vInputMin );
214
1.87k
      vLevel = _mm_min_epi32( vLevel, vInputMax );
215
216
1.87k
      vLevel = _mm_mullo_epi32( vLevel, vScale );
217
1.87k
      if( RightShiftPositive )
218
1.75k
      {
219
1.75k
        vLevel = _mm_add_epi32( vLevel, vAdd );
220
1.75k
        vLevel = _mm_sra_epi32( vLevel, vShift );
221
1.75k
      }
222
122
      else
223
122
      {
224
122
        vLevel = _mm_sll_epi32( vLevel, vShift );
225
122
      }
226
227
1.87k
      vLevel = _mm_max_epi32( vLevel, vTransformMin );
228
1.87k
      vLevel = _mm_min_epi32( vLevel, vTransformMax );
229
230
1.87k
      if( maskCoeffs <= 2 )
231
687
      {
232
687
        _mm_storeu_si64( (__m128i*) &piCoef[n], vLevel );
233
687
      }
234
1.19k
      else
235
1.19k
      {
236
1.19k
        _mm_storeu_si128( (__m128i*) &piCoef[n], vLevel );
237
1.19k
      }
238
1.87k
    }
239
359k
#endif
240
359k
  }
241
58.6k
}
Unexecuted instantiation: Quant_sse41.cpp:void vvdec::DeQuantImplSIMD<(vvdec::x86_simd::X86_VEXT)1, short, false, true>(unsigned int, int, int, int, int const*, short const*, unsigned long, int*, int, int, int)
Unexecuted instantiation: Quant_sse41.cpp:void vvdec::DeQuantImplSIMD<(vvdec::x86_simd::X86_VEXT)1, short, false, false>(unsigned int, int, int, int, int const*, short const*, unsigned long, int*, int, int, int)
Unexecuted instantiation: Quant_sse41.cpp:void vvdec::DeQuantImplSIMD<(vvdec::x86_simd::X86_VEXT)1, int, false, true>(unsigned int, int, int, int, int const*, int const*, unsigned long, int*, int, int, int)
Unexecuted instantiation: Quant_sse41.cpp:void vvdec::DeQuantImplSIMD<(vvdec::x86_simd::X86_VEXT)1, int, false, false>(unsigned int, int, int, int, int const*, int const*, unsigned long, int*, int, int, int)
Unexecuted instantiation: Quant_sse41.cpp:void vvdec::DeQuantImplSIMD<(vvdec::x86_simd::X86_VEXT)1, short, true, true>(unsigned int, int, int, int, int const*, short const*, unsigned long, int*, int, int, int)
Unexecuted instantiation: Quant_sse41.cpp:void vvdec::DeQuantImplSIMD<(vvdec::x86_simd::X86_VEXT)1, short, true, false>(unsigned int, int, int, int, int const*, short const*, unsigned long, int*, int, int, int)
Unexecuted instantiation: Quant_sse41.cpp:void vvdec::DeQuantImplSIMD<(vvdec::x86_simd::X86_VEXT)1, int, true, true>(unsigned int, int, int, int, int const*, int const*, unsigned long, int*, int, int, int)
Unexecuted instantiation: Quant_sse41.cpp:void vvdec::DeQuantImplSIMD<(vvdec::x86_simd::X86_VEXT)1, int, true, false>(unsigned int, int, int, int, int const*, int const*, unsigned long, int*, int, int, int)
Quant_avx2.cpp:void vvdec::DeQuantImplSIMD<(vvdec::x86_simd::X86_VEXT)4, short, false, true>(unsigned int, int, int, int, int const*, short const*, unsigned long, int*, int, int, int)
Line
Count
Source
69
5.84k
{
70
5.84k
  static_assert( sizeof( piQCoef[0] ) == sizeof( int16_t ) || sizeof( piQCoef[0] ) == sizeof( int32_t ), "wrong coeff type" );
71
72
5.84k
  constexpr static bool QCoef_16bit = sizeof( piQCoef[0] ) == sizeof( int16_t );
73
74
5.84k
  const int    inputMinimum     = -( inputMaximum + 1 );
75
5.84k
  const TCoeff transformMinimum = -( transformMaximum + 1 );
76
77
5.84k
  const int iAdd  = RightShiftPositive ? 1 << ( rightShift - 1 ) : 0;
78
5.84k
  const int shift = RightShiftPositive ? rightShift : -rightShift;
79
80
5.84k
  const __m128i vInputMin     = _mm_set1_epi32( inputMinimum );
81
5.84k
  const __m128i vInputMax     = _mm_set1_epi32( inputMaximum );
82
5.84k
  const __m128i vTransformMin = _mm_set1_epi32( transformMinimum );
83
5.84k
  const __m128i vTransformMax = _mm_set1_epi32( transformMaximum );
84
85
5.84k
  const __m128i vAdd   = _mm_set1_epi32( iAdd );
86
5.84k
  const __m128i vShift = _mm_set_epi64x( 0, shift );
87
5.84k
        __m128i vScale = _mm_set1_epi32( scaleQP );
88
89
5.84k
#if USE_AVX2
90
5.84k
  const __m256i xvInputMin     = _mm256_set1_epi32( inputMinimum );
91
5.84k
  const __m256i xvInputMax     = _mm256_set1_epi32( inputMaximum );
92
5.84k
  const __m256i xvTransformMin = _mm256_set1_epi32( transformMinimum );
93
5.84k
  const __m256i xvTransformMax = _mm256_set1_epi32( transformMaximum );
94
95
5.84k
  const __m256i xvAdd   = _mm256_set1_epi32( iAdd );
96
5.84k
        __m256i xvScale = _mm256_set1_epi32( scaleQP );
97
5.84k
#endif   // USE_AVX2
98
99
5.84k
  const int endX       = maxX + 1;
100
5.84k
  const int maskCoeffs = endX & 3;   // number of coefficients in the last vector read
101
  // clang-format off
102
5.84k
  const __m128i vMask = maskCoeffs == 3 ? _mm_set_epi32( 0, -1, -1, -1 ) :
103
5.84k
                      ( maskCoeffs == 2 ? _mm_set_epi32( 0, 0, -1, -1 )
104
5.70k
                                        : _mm_set_epi32( 0, 0, 0, -1 ) );
105
  // clang-format on
106
107
45.8k
  for( int y = 0; y <= maxY; y++ )
108
40.0k
  {
109
40.0k
    int x = 0;
110
40.0k
    int n = y * width;
111
112
40.0k
#if USE_AVX2
113
74.3k
    for( ; x + 7 < endX; x += 8, n += 8 )
114
34.2k
    {
115
34.2k
      if( UseScalingList )
116
0
      {
117
0
        xvScale = _mm256_set1_epi32( scaleQP );
118
0
        xvScale = _mm256_mullo_epi32( xvScale, _mm256_loadu_si256( (__m256i*) &piDequantCoef[n] ) );
119
0
      }
120
121
34.2k
      __m256i xvLevel = QCoef_16bit ? _mm256_cvtepi16_epi32( _mm_loadu_si128( (__m128i*) &piQCoef[x + y * piQCfStride] ) )   // 16 bit coeffs
122
34.2k
                                    : _mm256_loadu_si256( (__m256i*) &piQCoef[x + y * piQCfStride] );                        // 32 bit coeffs
123
124
34.2k
      xvLevel = _mm256_max_epi32( xvLevel, xvInputMin );
125
34.2k
      xvLevel = _mm256_min_epi32( xvLevel, xvInputMax );
126
127
34.2k
      xvLevel = _mm256_mullo_epi32( xvLevel, xvScale );
128
34.2k
      if( RightShiftPositive )
129
34.2k
      {
130
34.2k
        xvLevel = _mm256_add_epi32( xvLevel, xvAdd );
131
34.2k
        xvLevel = _mm256_sra_epi32( xvLevel, vShift );
132
34.2k
      }
133
0
      else
134
0
      {
135
0
        xvLevel = _mm256_sll_epi32( xvLevel, vShift );
136
0
      }
137
138
34.2k
      xvLevel = _mm256_max_epi32( xvLevel, xvTransformMin );
139
34.2k
      xvLevel = _mm256_min_epi32( xvLevel, xvTransformMax );
140
141
34.2k
      _mm256_storeu_si256( (__m256i*) &piCoef[n], xvLevel );
142
34.2k
    }
143
40.0k
#endif   // USE_AVX2
144
145
62.9k
    for( ; x + 3 < endX; x += 4, n += 4 )
146
22.9k
    {
147
22.9k
      if( UseScalingList )
148
0
      {
149
0
        vScale = _mm_set1_epi32( scaleQP );
150
0
        vScale = _mm_mullo_epi32( vScale, _mm_loadu_si128( (__m128i*) &piDequantCoef[n] ) );
151
0
      }
152
153
22.9k
      __m128i vLevel = QCoef_16bit ? _mm_cvtepi16_epi32( _mm_loadu_si64( &piQCoef[x + y * piQCfStride] ) )   // 16 bit coeffs
154
22.9k
                                   : _mm_loadu_si128( (__m128i*) &piQCoef[x + y * piQCfStride] );            // 32 bit coeffs
155
156
22.9k
      vLevel = _mm_max_epi32( vLevel, vInputMin );
157
22.9k
      vLevel = _mm_min_epi32( vLevel, vInputMax );
158
159
22.9k
      vLevel = _mm_mullo_epi32( vLevel, vScale );
160
22.9k
      if( RightShiftPositive )
161
22.9k
      {
162
22.9k
        vLevel = _mm_add_epi32( vLevel, vAdd );
163
22.9k
        vLevel = _mm_sra_epi32( vLevel, vShift );
164
22.9k
      }
165
0
      else
166
0
      {
167
0
        vLevel = _mm_sll_epi32( vLevel, vShift );
168
0
      }
169
170
22.9k
      vLevel = _mm_max_epi32( vLevel, vTransformMin );
171
22.9k
      vLevel = _mm_min_epi32( vLevel, vTransformMax );
172
173
22.9k
      _mm_storeu_si128( (__m128i*) &piCoef[n], vLevel );
174
22.9k
    }
175
176
#if 0   // dequant remaining coefficients using scalar code
177
    (void)vMask;
178
    for( ; x < endX; x++, n++ )
179
    {
180
      const TCoeff level = piQCoef[x + y * piQCfStride];
181
      if( !level )
182
      {
183
        continue;
184
      }
185
186
      const int        scale     = UseScalingList ? piDequantCoef[n] * scaleQP   //
187
                                                  : scaleQP;
188
      const TCoeff     clipQCoef = TCoeff( Clip3<Intermediate_Int>( inputMinimum, inputMaximum, level ) );
189
      Intermediate_Int iCoeffQ   = RightShiftPositive ? ( Intermediate_Int( clipQCoef ) * scale + iAdd ) >> rightShift   //
190
                                                      : ( Intermediate_Int( clipQCoef ) * scale ) * ( 1 << shift );
191
192
      piCoef[n] = TCoeff( Clip3<Intermediate_Int>( transformMinimum, transformMaximum, iCoeffQ ) );
193
    }
194
195
#else   // dequant remaining coefficients using SSE
196
197
40.0k
    if( x < endX )
198
1.75k
    {
199
1.75k
      CHECKD( endX - x >= 4 || endX - x != maskCoeffs, "wrong mask for remaining coeffs" << ( endX - x ) << " " << maskCoeffs );
200
201
1.75k
      if( UseScalingList )
202
0
      {
203
0
        vScale = _mm_set1_epi32( scaleQP );
204
0
        vScale = _mm_mullo_epi32( vScale, _mm_loadu_si128( (__m128i*) &piDequantCoef[n] ) );
205
0
        vScale = _mm_and_si128( vScale, vMask );
206
0
      }
207
208
1.75k
      __m128i vLevel = QCoef_16bit ? _mm_cvtepi16_epi32( _mm_loadu_si64( &piQCoef[x + y * piQCfStride] ) )   // 16 bit coeffs
209
1.75k
                                   : _mm_loadu_si128( (__m128i*) &piQCoef[x + y * piQCfStride] );            // 32 bit coeffs
210
211
1.75k
      vLevel = _mm_and_si128( vLevel, vMask );
212
213
1.75k
      vLevel = _mm_max_epi32( vLevel, vInputMin );
214
1.75k
      vLevel = _mm_min_epi32( vLevel, vInputMax );
215
216
1.75k
      vLevel = _mm_mullo_epi32( vLevel, vScale );
217
1.75k
      if( RightShiftPositive )
218
1.75k
      {
219
1.75k
        vLevel = _mm_add_epi32( vLevel, vAdd );
220
1.75k
        vLevel = _mm_sra_epi32( vLevel, vShift );
221
1.75k
      }
222
0
      else
223
0
      {
224
0
        vLevel = _mm_sll_epi32( vLevel, vShift );
225
0
      }
226
227
1.75k
      vLevel = _mm_max_epi32( vLevel, vTransformMin );
228
1.75k
      vLevel = _mm_min_epi32( vLevel, vTransformMax );
229
230
1.75k
      if( maskCoeffs <= 2 )
231
634
      {
232
634
        _mm_storeu_si64( (__m128i*) &piCoef[n], vLevel );
233
634
      }
234
1.12k
      else
235
1.12k
      {
236
1.12k
        _mm_storeu_si128( (__m128i*) &piCoef[n], vLevel );
237
1.12k
      }
238
1.75k
    }
239
40.0k
#endif
240
40.0k
  }
241
5.84k
}
Quant_avx2.cpp:void vvdec::DeQuantImplSIMD<(vvdec::x86_simd::X86_VEXT)4, short, false, false>(unsigned int, int, int, int, int const*, short const*, unsigned long, int*, int, int, int)
Line
Count
Source
69
50.5k
{
70
50.5k
  static_assert( sizeof( piQCoef[0] ) == sizeof( int16_t ) || sizeof( piQCoef[0] ) == sizeof( int32_t ), "wrong coeff type" );
71
72
50.5k
  constexpr static bool QCoef_16bit = sizeof( piQCoef[0] ) == sizeof( int16_t );
73
74
50.5k
  const int    inputMinimum     = -( inputMaximum + 1 );
75
50.5k
  const TCoeff transformMinimum = -( transformMaximum + 1 );
76
77
50.5k
  const int iAdd  = RightShiftPositive ? 1 << ( rightShift - 1 ) : 0;
78
50.5k
  const int shift = RightShiftPositive ? rightShift : -rightShift;
79
80
50.5k
  const __m128i vInputMin     = _mm_set1_epi32( inputMinimum );
81
50.5k
  const __m128i vInputMax     = _mm_set1_epi32( inputMaximum );
82
50.5k
  const __m128i vTransformMin = _mm_set1_epi32( transformMinimum );
83
50.5k
  const __m128i vTransformMax = _mm_set1_epi32( transformMaximum );
84
85
50.5k
  const __m128i vAdd   = _mm_set1_epi32( iAdd );
86
50.5k
  const __m128i vShift = _mm_set_epi64x( 0, shift );
87
50.5k
        __m128i vScale = _mm_set1_epi32( scaleQP );
88
89
50.5k
#if USE_AVX2
90
50.5k
  const __m256i xvInputMin     = _mm256_set1_epi32( inputMinimum );
91
50.5k
  const __m256i xvInputMax     = _mm256_set1_epi32( inputMaximum );
92
50.5k
  const __m256i xvTransformMin = _mm256_set1_epi32( transformMinimum );
93
50.5k
  const __m256i xvTransformMax = _mm256_set1_epi32( transformMaximum );
94
95
50.5k
  const __m256i xvAdd   = _mm256_set1_epi32( iAdd );
96
50.5k
        __m256i xvScale = _mm256_set1_epi32( scaleQP );
97
50.5k
#endif   // USE_AVX2
98
99
50.5k
  const int endX       = maxX + 1;
100
50.5k
  const int maskCoeffs = endX & 3;   // number of coefficients in the last vector read
101
  // clang-format off
102
50.5k
  const __m128i vMask = maskCoeffs == 3 ? _mm_set_epi32( 0, -1, -1, -1 ) :
103
50.5k
                      ( maskCoeffs == 2 ? _mm_set_epi32( 0, 0, -1, -1 )
104
50.5k
                                        : _mm_set_epi32( 0, 0, 0, -1 ) );
105
  // clang-format on
106
107
346k
  for( int y = 0; y <= maxY; y++ )
108
295k
  {
109
295k
    int x = 0;
110
295k
    int n = y * width;
111
112
295k
#if USE_AVX2
113
387k
    for( ; x + 7 < endX; x += 8, n += 8 )
114
91.9k
    {
115
91.9k
      if( UseScalingList )
116
0
      {
117
0
        xvScale = _mm256_set1_epi32( scaleQP );
118
0
        xvScale = _mm256_mullo_epi32( xvScale, _mm256_loadu_si256( (__m256i*) &piDequantCoef[n] ) );
119
0
      }
120
121
91.9k
      __m256i xvLevel = QCoef_16bit ? _mm256_cvtepi16_epi32( _mm_loadu_si128( (__m128i*) &piQCoef[x + y * piQCfStride] ) )   // 16 bit coeffs
122
91.9k
                                    : _mm256_loadu_si256( (__m256i*) &piQCoef[x + y * piQCfStride] );                        // 32 bit coeffs
123
124
91.9k
      xvLevel = _mm256_max_epi32( xvLevel, xvInputMin );
125
91.9k
      xvLevel = _mm256_min_epi32( xvLevel, xvInputMax );
126
127
91.9k
      xvLevel = _mm256_mullo_epi32( xvLevel, xvScale );
128
91.9k
      if( RightShiftPositive )
129
0
      {
130
0
        xvLevel = _mm256_add_epi32( xvLevel, xvAdd );
131
0
        xvLevel = _mm256_sra_epi32( xvLevel, vShift );
132
0
      }
133
91.9k
      else
134
91.9k
      {
135
91.9k
        xvLevel = _mm256_sll_epi32( xvLevel, vShift );
136
91.9k
      }
137
138
91.9k
      xvLevel = _mm256_max_epi32( xvLevel, xvTransformMin );
139
91.9k
      xvLevel = _mm256_min_epi32( xvLevel, xvTransformMax );
140
141
91.9k
      _mm256_storeu_si256( (__m256i*) &piCoef[n], xvLevel );
142
91.9k
    }
143
295k
#endif   // USE_AVX2
144
145
522k
    for( ; x + 3 < endX; x += 4, n += 4 )
146
227k
    {
147
227k
      if( UseScalingList )
148
0
      {
149
0
        vScale = _mm_set1_epi32( scaleQP );
150
0
        vScale = _mm_mullo_epi32( vScale, _mm_loadu_si128( (__m128i*) &piDequantCoef[n] ) );
151
0
      }
152
153
227k
      __m128i vLevel = QCoef_16bit ? _mm_cvtepi16_epi32( _mm_loadu_si64( &piQCoef[x + y * piQCfStride] ) )   // 16 bit coeffs
154
227k
                                   : _mm_loadu_si128( (__m128i*) &piQCoef[x + y * piQCfStride] );            // 32 bit coeffs
155
156
227k
      vLevel = _mm_max_epi32( vLevel, vInputMin );
157
227k
      vLevel = _mm_min_epi32( vLevel, vInputMax );
158
159
227k
      vLevel = _mm_mullo_epi32( vLevel, vScale );
160
227k
      if( RightShiftPositive )
161
0
      {
162
0
        vLevel = _mm_add_epi32( vLevel, vAdd );
163
0
        vLevel = _mm_sra_epi32( vLevel, vShift );
164
0
      }
165
227k
      else
166
227k
      {
167
227k
        vLevel = _mm_sll_epi32( vLevel, vShift );
168
227k
      }
169
170
227k
      vLevel = _mm_max_epi32( vLevel, vTransformMin );
171
227k
      vLevel = _mm_min_epi32( vLevel, vTransformMax );
172
173
227k
      _mm_storeu_si128( (__m128i*) &piCoef[n], vLevel );
174
227k
    }
175
176
#if 0   // dequant remaining coefficients using scalar code
177
    (void)vMask;
178
    for( ; x < endX; x++, n++ )
179
    {
180
      const TCoeff level = piQCoef[x + y * piQCfStride];
181
      if( !level )
182
      {
183
        continue;
184
      }
185
186
      const int        scale     = UseScalingList ? piDequantCoef[n] * scaleQP   //
187
                                                  : scaleQP;
188
      const TCoeff     clipQCoef = TCoeff( Clip3<Intermediate_Int>( inputMinimum, inputMaximum, level ) );
189
      Intermediate_Int iCoeffQ   = RightShiftPositive ? ( Intermediate_Int( clipQCoef ) * scale + iAdd ) >> rightShift   //
190
                                                      : ( Intermediate_Int( clipQCoef ) * scale ) * ( 1 << shift );
191
192
      piCoef[n] = TCoeff( Clip3<Intermediate_Int>( transformMinimum, transformMaximum, iCoeffQ ) );
193
    }
194
195
#else   // dequant remaining coefficients using SSE
196
197
295k
    if( x < endX )
198
122
    {
199
122
      CHECKD( endX - x >= 4 || endX - x != maskCoeffs, "wrong mask for remaining coeffs" << ( endX - x ) << " " << maskCoeffs );
200
201
122
      if( UseScalingList )
202
0
      {
203
0
        vScale = _mm_set1_epi32( scaleQP );
204
0
        vScale = _mm_mullo_epi32( vScale, _mm_loadu_si128( (__m128i*) &piDequantCoef[n] ) );
205
0
        vScale = _mm_and_si128( vScale, vMask );
206
0
      }
207
208
122
      __m128i vLevel = QCoef_16bit ? _mm_cvtepi16_epi32( _mm_loadu_si64( &piQCoef[x + y * piQCfStride] ) )   // 16 bit coeffs
209
122
                                   : _mm_loadu_si128( (__m128i*) &piQCoef[x + y * piQCfStride] );            // 32 bit coeffs
210
211
122
      vLevel = _mm_and_si128( vLevel, vMask );
212
213
122
      vLevel = _mm_max_epi32( vLevel, vInputMin );
214
122
      vLevel = _mm_min_epi32( vLevel, vInputMax );
215
216
122
      vLevel = _mm_mullo_epi32( vLevel, vScale );
217
122
      if( RightShiftPositive )
218
0
      {
219
0
        vLevel = _mm_add_epi32( vLevel, vAdd );
220
0
        vLevel = _mm_sra_epi32( vLevel, vShift );
221
0
      }
222
122
      else
223
122
      {
224
122
        vLevel = _mm_sll_epi32( vLevel, vShift );
225
122
      }
226
227
122
      vLevel = _mm_max_epi32( vLevel, vTransformMin );
228
122
      vLevel = _mm_min_epi32( vLevel, vTransformMax );
229
230
122
      if( maskCoeffs <= 2 )
231
53
      {
232
53
        _mm_storeu_si64( (__m128i*) &piCoef[n], vLevel );
233
53
      }
234
69
      else
235
69
      {
236
69
        _mm_storeu_si128( (__m128i*) &piCoef[n], vLevel );
237
69
      }
238
122
    }
239
295k
#endif
240
295k
  }
241
50.5k
}
Quant_avx2.cpp:void vvdec::DeQuantImplSIMD<(vvdec::x86_simd::X86_VEXT)4, int, false, true>(unsigned int, int, int, int, int const*, int const*, unsigned long, int*, int, int, int)
Line
Count
Source
69
2.07k
{
70
2.07k
  static_assert( sizeof( piQCoef[0] ) == sizeof( int16_t ) || sizeof( piQCoef[0] ) == sizeof( int32_t ), "wrong coeff type" );
71
72
2.07k
  constexpr static bool QCoef_16bit = sizeof( piQCoef[0] ) == sizeof( int16_t );
73
74
2.07k
  const int    inputMinimum     = -( inputMaximum + 1 );
75
2.07k
  const TCoeff transformMinimum = -( transformMaximum + 1 );
76
77
2.07k
  const int iAdd  = RightShiftPositive ? 1 << ( rightShift - 1 ) : 0;
78
2.07k
  const int shift = RightShiftPositive ? rightShift : -rightShift;
79
80
2.07k
  const __m128i vInputMin     = _mm_set1_epi32( inputMinimum );
81
2.07k
  const __m128i vInputMax     = _mm_set1_epi32( inputMaximum );
82
2.07k
  const __m128i vTransformMin = _mm_set1_epi32( transformMinimum );
83
2.07k
  const __m128i vTransformMax = _mm_set1_epi32( transformMaximum );
84
85
2.07k
  const __m128i vAdd   = _mm_set1_epi32( iAdd );
86
2.07k
  const __m128i vShift = _mm_set_epi64x( 0, shift );
87
2.07k
        __m128i vScale = _mm_set1_epi32( scaleQP );
88
89
2.07k
#if USE_AVX2
90
2.07k
  const __m256i xvInputMin     = _mm256_set1_epi32( inputMinimum );
91
2.07k
  const __m256i xvInputMax     = _mm256_set1_epi32( inputMaximum );
92
2.07k
  const __m256i xvTransformMin = _mm256_set1_epi32( transformMinimum );
93
2.07k
  const __m256i xvTransformMax = _mm256_set1_epi32( transformMaximum );
94
95
2.07k
  const __m256i xvAdd   = _mm256_set1_epi32( iAdd );
96
2.07k
        __m256i xvScale = _mm256_set1_epi32( scaleQP );
97
2.07k
#endif   // USE_AVX2
98
99
2.07k
  const int endX       = maxX + 1;
100
2.07k
  const int maskCoeffs = endX & 3;   // number of coefficients in the last vector read
101
  // clang-format off
102
2.07k
  const __m128i vMask = maskCoeffs == 3 ? _mm_set_epi32( 0, -1, -1, -1 ) :
103
2.07k
                      ( maskCoeffs == 2 ? _mm_set_epi32( 0, 0, -1, -1 )
104
2.07k
                                        : _mm_set_epi32( 0, 0, 0, -1 ) );
105
  // clang-format on
106
107
23.7k
  for( int y = 0; y <= maxY; y++ )
108
21.6k
  {
109
21.6k
    int x = 0;
110
21.6k
    int n = y * width;
111
112
21.6k
#if USE_AVX2
113
50.3k
    for( ; x + 7 < endX; x += 8, n += 8 )
114
28.7k
    {
115
28.7k
      if( UseScalingList )
116
0
      {
117
0
        xvScale = _mm256_set1_epi32( scaleQP );
118
0
        xvScale = _mm256_mullo_epi32( xvScale, _mm256_loadu_si256( (__m256i*) &piDequantCoef[n] ) );
119
0
      }
120
121
28.7k
      __m256i xvLevel = QCoef_16bit ? _mm256_cvtepi16_epi32( _mm_loadu_si128( (__m128i*) &piQCoef[x + y * piQCfStride] ) )   // 16 bit coeffs
122
28.7k
                                    : _mm256_loadu_si256( (__m256i*) &piQCoef[x + y * piQCfStride] );                        // 32 bit coeffs
123
124
28.7k
      xvLevel = _mm256_max_epi32( xvLevel, xvInputMin );
125
28.7k
      xvLevel = _mm256_min_epi32( xvLevel, xvInputMax );
126
127
28.7k
      xvLevel = _mm256_mullo_epi32( xvLevel, xvScale );
128
28.7k
      if( RightShiftPositive )
129
28.7k
      {
130
28.7k
        xvLevel = _mm256_add_epi32( xvLevel, xvAdd );
131
28.7k
        xvLevel = _mm256_sra_epi32( xvLevel, vShift );
132
28.7k
      }
133
0
      else
134
0
      {
135
0
        xvLevel = _mm256_sll_epi32( xvLevel, vShift );
136
0
      }
137
138
28.7k
      xvLevel = _mm256_max_epi32( xvLevel, xvTransformMin );
139
28.7k
      xvLevel = _mm256_min_epi32( xvLevel, xvTransformMax );
140
141
28.7k
      _mm256_storeu_si256( (__m256i*) &piCoef[n], xvLevel );
142
28.7k
    }
143
21.6k
#endif   // USE_AVX2
144
145
25.1k
    for( ; x + 3 < endX; x += 4, n += 4 )
146
3.50k
    {
147
3.50k
      if( UseScalingList )
148
0
      {
149
0
        vScale = _mm_set1_epi32( scaleQP );
150
0
        vScale = _mm_mullo_epi32( vScale, _mm_loadu_si128( (__m128i*) &piDequantCoef[n] ) );
151
0
      }
152
153
3.50k
      __m128i vLevel = QCoef_16bit ? _mm_cvtepi16_epi32( _mm_loadu_si64( &piQCoef[x + y * piQCfStride] ) )   // 16 bit coeffs
154
3.50k
                                   : _mm_loadu_si128( (__m128i*) &piQCoef[x + y * piQCfStride] );            // 32 bit coeffs
155
156
3.50k
      vLevel = _mm_max_epi32( vLevel, vInputMin );
157
3.50k
      vLevel = _mm_min_epi32( vLevel, vInputMax );
158
159
3.50k
      vLevel = _mm_mullo_epi32( vLevel, vScale );
160
3.50k
      if( RightShiftPositive )
161
3.50k
      {
162
3.50k
        vLevel = _mm_add_epi32( vLevel, vAdd );
163
3.50k
        vLevel = _mm_sra_epi32( vLevel, vShift );
164
3.50k
      }
165
0
      else
166
0
      {
167
0
        vLevel = _mm_sll_epi32( vLevel, vShift );
168
0
      }
169
170
3.50k
      vLevel = _mm_max_epi32( vLevel, vTransformMin );
171
3.50k
      vLevel = _mm_min_epi32( vLevel, vTransformMax );
172
173
3.50k
      _mm_storeu_si128( (__m128i*) &piCoef[n], vLevel );
174
3.50k
    }
175
176
#if 0   // dequant remaining coefficients using scalar code
177
    (void)vMask;
178
    for( ; x < endX; x++, n++ )
179
    {
180
      const TCoeff level = piQCoef[x + y * piQCfStride];
181
      if( !level )
182
      {
183
        continue;
184
      }
185
186
      const int        scale     = UseScalingList ? piDequantCoef[n] * scaleQP   //
187
                                                  : scaleQP;
188
      const TCoeff     clipQCoef = TCoeff( Clip3<Intermediate_Int>( inputMinimum, inputMaximum, level ) );
189
      Intermediate_Int iCoeffQ   = RightShiftPositive ? ( Intermediate_Int( clipQCoef ) * scale + iAdd ) >> rightShift   //
190
                                                      : ( Intermediate_Int( clipQCoef ) * scale ) * ( 1 << shift );
191
192
      piCoef[n] = TCoeff( Clip3<Intermediate_Int>( transformMinimum, transformMaximum, iCoeffQ ) );
193
    }
194
195
#else   // dequant remaining coefficients using SSE
196
197
21.6k
    if( x < endX )
198
0
    {
199
0
      CHECKD( endX - x >= 4 || endX - x != maskCoeffs, "wrong mask for remaining coeffs" << ( endX - x ) << " " << maskCoeffs );
200
201
0
      if( UseScalingList )
202
0
      {
203
0
        vScale = _mm_set1_epi32( scaleQP );
204
0
        vScale = _mm_mullo_epi32( vScale, _mm_loadu_si128( (__m128i*) &piDequantCoef[n] ) );
205
0
        vScale = _mm_and_si128( vScale, vMask );
206
0
      }
207
208
0
      __m128i vLevel = QCoef_16bit ? _mm_cvtepi16_epi32( _mm_loadu_si64( &piQCoef[x + y * piQCfStride] ) )   // 16 bit coeffs
209
0
                                   : _mm_loadu_si128( (__m128i*) &piQCoef[x + y * piQCfStride] );            // 32 bit coeffs
210
211
0
      vLevel = _mm_and_si128( vLevel, vMask );
212
213
0
      vLevel = _mm_max_epi32( vLevel, vInputMin );
214
0
      vLevel = _mm_min_epi32( vLevel, vInputMax );
215
216
0
      vLevel = _mm_mullo_epi32( vLevel, vScale );
217
0
      if( RightShiftPositive )
218
0
      {
219
0
        vLevel = _mm_add_epi32( vLevel, vAdd );
220
0
        vLevel = _mm_sra_epi32( vLevel, vShift );
221
0
      }
222
0
      else
223
0
      {
224
0
        vLevel = _mm_sll_epi32( vLevel, vShift );
225
0
      }
226
227
0
      vLevel = _mm_max_epi32( vLevel, vTransformMin );
228
0
      vLevel = _mm_min_epi32( vLevel, vTransformMax );
229
230
0
      if( maskCoeffs <= 2 )
231
0
      {
232
0
        _mm_storeu_si64( (__m128i*) &piCoef[n], vLevel );
233
0
      }
234
0
      else
235
0
      {
236
0
        _mm_storeu_si128( (__m128i*) &piCoef[n], vLevel );
237
0
      }
238
0
    }
239
21.6k
#endif
240
21.6k
  }
241
2.07k
}
Quant_avx2.cpp:void vvdec::DeQuantImplSIMD<(vvdec::x86_simd::X86_VEXT)4, int, false, false>(unsigned int, int, int, int, int const*, int const*, unsigned long, int*, int, int, int)
Line
Count
Source
69
200
{
70
200
  static_assert( sizeof( piQCoef[0] ) == sizeof( int16_t ) || sizeof( piQCoef[0] ) == sizeof( int32_t ), "wrong coeff type" );
71
72
200
  constexpr static bool QCoef_16bit = sizeof( piQCoef[0] ) == sizeof( int16_t );
73
74
200
  const int    inputMinimum     = -( inputMaximum + 1 );
75
200
  const TCoeff transformMinimum = -( transformMaximum + 1 );
76
77
200
  const int iAdd  = RightShiftPositive ? 1 << ( rightShift - 1 ) : 0;
78
200
  const int shift = RightShiftPositive ? rightShift : -rightShift;
79
80
200
  const __m128i vInputMin     = _mm_set1_epi32( inputMinimum );
81
200
  const __m128i vInputMax     = _mm_set1_epi32( inputMaximum );
82
200
  const __m128i vTransformMin = _mm_set1_epi32( transformMinimum );
83
200
  const __m128i vTransformMax = _mm_set1_epi32( transformMaximum );
84
85
200
  const __m128i vAdd   = _mm_set1_epi32( iAdd );
86
200
  const __m128i vShift = _mm_set_epi64x( 0, shift );
87
200
        __m128i vScale = _mm_set1_epi32( scaleQP );
88
89
200
#if USE_AVX2
90
200
  const __m256i xvInputMin     = _mm256_set1_epi32( inputMinimum );
91
200
  const __m256i xvInputMax     = _mm256_set1_epi32( inputMaximum );
92
200
  const __m256i xvTransformMin = _mm256_set1_epi32( transformMinimum );
93
200
  const __m256i xvTransformMax = _mm256_set1_epi32( transformMaximum );
94
95
200
  const __m256i xvAdd   = _mm256_set1_epi32( iAdd );
96
200
        __m256i xvScale = _mm256_set1_epi32( scaleQP );
97
200
#endif   // USE_AVX2
98
99
200
  const int endX       = maxX + 1;
100
200
  const int maskCoeffs = endX & 3;   // number of coefficients in the last vector read
101
  // clang-format off
102
200
  const __m128i vMask = maskCoeffs == 3 ? _mm_set_epi32( 0, -1, -1, -1 ) :
103
200
                      ( maskCoeffs == 2 ? _mm_set_epi32( 0, 0, -1, -1 )
104
200
                                        : _mm_set_epi32( 0, 0, 0, -1 ) );
105
  // clang-format on
106
107
2.34k
  for( int y = 0; y <= maxY; y++ )
108
2.14k
  {
109
2.14k
    int x = 0;
110
2.14k
    int n = y * width;
111
112
2.14k
#if USE_AVX2
113
5.22k
    for( ; x + 7 < endX; x += 8, n += 8 )
114
3.07k
    {
115
3.07k
      if( UseScalingList )
116
0
      {
117
0
        xvScale = _mm256_set1_epi32( scaleQP );
118
0
        xvScale = _mm256_mullo_epi32( xvScale, _mm256_loadu_si256( (__m256i*) &piDequantCoef[n] ) );
119
0
      }
120
121
3.07k
      __m256i xvLevel = QCoef_16bit ? _mm256_cvtepi16_epi32( _mm_loadu_si128( (__m128i*) &piQCoef[x + y * piQCfStride] ) )   // 16 bit coeffs
122
3.07k
                                    : _mm256_loadu_si256( (__m256i*) &piQCoef[x + y * piQCfStride] );                        // 32 bit coeffs
123
124
3.07k
      xvLevel = _mm256_max_epi32( xvLevel, xvInputMin );
125
3.07k
      xvLevel = _mm256_min_epi32( xvLevel, xvInputMax );
126
127
3.07k
      xvLevel = _mm256_mullo_epi32( xvLevel, xvScale );
128
3.07k
      if( RightShiftPositive )
129
0
      {
130
0
        xvLevel = _mm256_add_epi32( xvLevel, xvAdd );
131
0
        xvLevel = _mm256_sra_epi32( xvLevel, vShift );
132
0
      }
133
3.07k
      else
134
3.07k
      {
135
3.07k
        xvLevel = _mm256_sll_epi32( xvLevel, vShift );
136
3.07k
      }
137
138
3.07k
      xvLevel = _mm256_max_epi32( xvLevel, xvTransformMin );
139
3.07k
      xvLevel = _mm256_min_epi32( xvLevel, xvTransformMax );
140
141
3.07k
      _mm256_storeu_si256( (__m256i*) &piCoef[n], xvLevel );
142
3.07k
    }
143
2.14k
#endif   // USE_AVX2
144
145
2.45k
    for( ; x + 3 < endX; x += 4, n += 4 )
146
308
    {
147
308
      if( UseScalingList )
148
0
      {
149
0
        vScale = _mm_set1_epi32( scaleQP );
150
0
        vScale = _mm_mullo_epi32( vScale, _mm_loadu_si128( (__m128i*) &piDequantCoef[n] ) );
151
0
      }
152
153
308
      __m128i vLevel = QCoef_16bit ? _mm_cvtepi16_epi32( _mm_loadu_si64( &piQCoef[x + y * piQCfStride] ) )   // 16 bit coeffs
154
308
                                   : _mm_loadu_si128( (__m128i*) &piQCoef[x + y * piQCfStride] );            // 32 bit coeffs
155
156
308
      vLevel = _mm_max_epi32( vLevel, vInputMin );
157
308
      vLevel = _mm_min_epi32( vLevel, vInputMax );
158
159
308
      vLevel = _mm_mullo_epi32( vLevel, vScale );
160
308
      if( RightShiftPositive )
161
0
      {
162
0
        vLevel = _mm_add_epi32( vLevel, vAdd );
163
0
        vLevel = _mm_sra_epi32( vLevel, vShift );
164
0
      }
165
308
      else
166
308
      {
167
308
        vLevel = _mm_sll_epi32( vLevel, vShift );
168
308
      }
169
170
308
      vLevel = _mm_max_epi32( vLevel, vTransformMin );
171
308
      vLevel = _mm_min_epi32( vLevel, vTransformMax );
172
173
308
      _mm_storeu_si128( (__m128i*) &piCoef[n], vLevel );
174
308
    }
175
176
#if 0   // dequant remaining coefficients using scalar code
177
    (void)vMask;
178
    for( ; x < endX; x++, n++ )
179
    {
180
      const TCoeff level = piQCoef[x + y * piQCfStride];
181
      if( !level )
182
      {
183
        continue;
184
      }
185
186
      const int        scale     = UseScalingList ? piDequantCoef[n] * scaleQP   //
187
                                                  : scaleQP;
188
      const TCoeff     clipQCoef = TCoeff( Clip3<Intermediate_Int>( inputMinimum, inputMaximum, level ) );
189
      Intermediate_Int iCoeffQ   = RightShiftPositive ? ( Intermediate_Int( clipQCoef ) * scale + iAdd ) >> rightShift   //
190
                                                      : ( Intermediate_Int( clipQCoef ) * scale ) * ( 1 << shift );
191
192
      piCoef[n] = TCoeff( Clip3<Intermediate_Int>( transformMinimum, transformMaximum, iCoeffQ ) );
193
    }
194
195
#else   // dequant remaining coefficients using SSE
196
197
2.14k
    if( x < endX )
198
0
    {
199
0
      CHECKD( endX - x >= 4 || endX - x != maskCoeffs, "wrong mask for remaining coeffs" << ( endX - x ) << " " << maskCoeffs );
200
201
0
      if( UseScalingList )
202
0
      {
203
0
        vScale = _mm_set1_epi32( scaleQP );
204
0
        vScale = _mm_mullo_epi32( vScale, _mm_loadu_si128( (__m128i*) &piDequantCoef[n] ) );
205
0
        vScale = _mm_and_si128( vScale, vMask );
206
0
      }
207
208
0
      __m128i vLevel = QCoef_16bit ? _mm_cvtepi16_epi32( _mm_loadu_si64( &piQCoef[x + y * piQCfStride] ) )   // 16 bit coeffs
209
0
                                   : _mm_loadu_si128( (__m128i*) &piQCoef[x + y * piQCfStride] );            // 32 bit coeffs
210
211
0
      vLevel = _mm_and_si128( vLevel, vMask );
212
213
0
      vLevel = _mm_max_epi32( vLevel, vInputMin );
214
0
      vLevel = _mm_min_epi32( vLevel, vInputMax );
215
216
0
      vLevel = _mm_mullo_epi32( vLevel, vScale );
217
0
      if( RightShiftPositive )
218
0
      {
219
0
        vLevel = _mm_add_epi32( vLevel, vAdd );
220
0
        vLevel = _mm_sra_epi32( vLevel, vShift );
221
0
      }
222
0
      else
223
0
      {
224
0
        vLevel = _mm_sll_epi32( vLevel, vShift );
225
0
      }
226
227
0
      vLevel = _mm_max_epi32( vLevel, vTransformMin );
228
0
      vLevel = _mm_min_epi32( vLevel, vTransformMax );
229
230
0
      if( maskCoeffs <= 2 )
231
0
      {
232
0
        _mm_storeu_si64( (__m128i*) &piCoef[n], vLevel );
233
0
      }
234
0
      else
235
0
      {
236
0
        _mm_storeu_si128( (__m128i*) &piCoef[n], vLevel );
237
0
      }
238
0
    }
239
2.14k
#endif
240
2.14k
  }
241
200
}
Unexecuted instantiation: Quant_avx2.cpp:void vvdec::DeQuantImplSIMD<(vvdec::x86_simd::X86_VEXT)4, short, true, true>(unsigned int, int, int, int, int const*, short const*, unsigned long, int*, int, int, int)
Unexecuted instantiation: Quant_avx2.cpp:void vvdec::DeQuantImplSIMD<(vvdec::x86_simd::X86_VEXT)4, short, true, false>(unsigned int, int, int, int, int const*, short const*, unsigned long, int*, int, int, int)
Unexecuted instantiation: Quant_avx2.cpp:void vvdec::DeQuantImplSIMD<(vvdec::x86_simd::X86_VEXT)4, int, true, true>(unsigned int, int, int, int, int const*, int const*, unsigned long, int*, int, int, int)
Unexecuted instantiation: Quant_avx2.cpp:void vvdec::DeQuantImplSIMD<(vvdec::x86_simd::X86_VEXT)4, int, true, false>(unsigned int, int, int, int, int const*, int const*, unsigned long, int*, int, int, int)
242
243
template<X86_VEXT vext, class T>
244
static void DeQuantCoreSIMD( const SizeType width,
245
                             const int      maxX,
246
                             const int      maxY,
247
                             const int      scale,
248
                             const T* const piQCoef,
249
                             const size_t   piQCfStride,
250
                             TCoeff* const  piCoef,
251
                             const int      rightShift,
252
                             const int      inputMaximum,
253
                             const TCoeff   transformMaximum )
254
78.2k
{
255
78.2k
  if( maxX < 2 )
256
19.6k
  {
257
19.6k
    Quant::DeQuantCore<T>(width,
258
19.6k
                   maxX,
259
19.6k
                   maxY,
260
19.6k
                   scale,
261
19.6k
                   piQCoef,
262
19.6k
                   piQCfStride,
263
19.6k
                   piCoef,
264
19.6k
                   rightShift,
265
19.6k
                   inputMaximum,
266
19.6k
                   transformMaximum );
267
19.6k
  }
268
58.6k
  else if( rightShift > 0 )
269
7.92k
  {
270
7.92k
    DeQuantImplSIMD<vext, T, false, true>( width, maxX, maxY, scale, nullptr, piQCoef, piQCfStride, piCoef, rightShift, inputMaximum, transformMaximum );
271
7.92k
  }
272
50.6k
  else
273
50.6k
  {
274
50.6k
    DeQuantImplSIMD<vext, T, false, false>( width, maxX, maxY, scale, nullptr, piQCoef, piQCfStride, piCoef, rightShift, inputMaximum, transformMaximum );
275
50.6k
  }
276
78.2k
}
Unexecuted instantiation: Quant_sse41.cpp:void vvdec::DeQuantCoreSIMD<(vvdec::x86_simd::X86_VEXT)1, short>(unsigned int, int, int, int, short const*, unsigned long, int*, int, int, int)
Unexecuted instantiation: Quant_sse41.cpp:void vvdec::DeQuantCoreSIMD<(vvdec::x86_simd::X86_VEXT)1, int>(unsigned int, int, int, int, int const*, unsigned long, int*, int, int, int)
Quant_avx2.cpp:void vvdec::DeQuantCoreSIMD<(vvdec::x86_simd::X86_VEXT)4, short>(unsigned int, int, int, int, short const*, unsigned long, int*, int, int, int)
Line
Count
Source
254
76.0k
{
255
76.0k
  if( maxX < 2 )
256
19.6k
  {
257
19.6k
    Quant::DeQuantCore<T>(width,
258
19.6k
                   maxX,
259
19.6k
                   maxY,
260
19.6k
                   scale,
261
19.6k
                   piQCoef,
262
19.6k
                   piQCfStride,
263
19.6k
                   piCoef,
264
19.6k
                   rightShift,
265
19.6k
                   inputMaximum,
266
19.6k
                   transformMaximum );
267
19.6k
  }
268
56.3k
  else if( rightShift > 0 )
269
5.84k
  {
270
5.84k
    DeQuantImplSIMD<vext, T, false, true>( width, maxX, maxY, scale, nullptr, piQCoef, piQCfStride, piCoef, rightShift, inputMaximum, transformMaximum );
271
5.84k
  }
272
50.4k
  else
273
50.4k
  {
274
50.4k
    DeQuantImplSIMD<vext, T, false, false>( width, maxX, maxY, scale, nullptr, piQCoef, piQCfStride, piCoef, rightShift, inputMaximum, transformMaximum );
275
50.4k
  }
276
76.0k
}
Quant_avx2.cpp:void vvdec::DeQuantCoreSIMD<(vvdec::x86_simd::X86_VEXT)4, int>(unsigned int, int, int, int, int const*, unsigned long, int*, int, int, int)
Line
Count
Source
254
2.27k
{
255
2.27k
  if( maxX < 2 )
256
0
  {
257
0
    Quant::DeQuantCore<T>(width,
258
0
                   maxX,
259
0
                   maxY,
260
0
                   scale,
261
0
                   piQCoef,
262
0
                   piQCfStride,
263
0
                   piCoef,
264
0
                   rightShift,
265
0
                   inputMaximum,
266
0
                   transformMaximum );
267
0
  }
268
2.27k
  else if( rightShift > 0 )
269
2.07k
  {
270
2.07k
    DeQuantImplSIMD<vext, T, false, true>( width, maxX, maxY, scale, nullptr, piQCoef, piQCfStride, piCoef, rightShift, inputMaximum, transformMaximum );
271
2.07k
  }
272
200
  else
273
200
  {
274
200
    DeQuantImplSIMD<vext, T, false, false>( width, maxX, maxY, scale, nullptr, piQCoef, piQCfStride, piCoef, rightShift, inputMaximum, transformMaximum );
275
200
  }
276
2.27k
}
277
278
template<X86_VEXT vext, class T>
279
static void DeQuantScalingCoreSIMD( const SizeType width,
280
                                    const int      maxX,
281
                                    const int      maxY,
282
                                    const int      scaleQP,
283
                                    const int*     piDequantCoef,
284
                                    const T* const piQCoef,
285
                                    const size_t   piQCfStride,
286
                                    TCoeff* const  piCoef,
287
                                    const int      rightShift,
288
                                    const int      inputMaximum,
289
                                    const TCoeff   transformMaximum )
290
0
{
291
0
  if( maxX < 2 )
292
0
  {
293
0
    Quant::DeQuantScalingCore<T>(width,
294
0
                          maxX,
295
0
                          maxY,
296
0
                          scaleQP,
297
0
                          piDequantCoef,
298
0
                          piQCoef,
299
0
                          piQCfStride,
300
0
                          piCoef,
301
0
                          rightShift,
302
0
                          inputMaximum,
303
0
                          transformMaximum );
304
0
  }
305
0
  else if( rightShift > 0 )
306
0
  {
307
0
    DeQuantImplSIMD<vext, T, true, true>( width, maxX, maxY, scaleQP, piDequantCoef, piQCoef, piQCfStride, piCoef, rightShift, inputMaximum, transformMaximum );
308
0
  }
309
0
  else
310
0
  {
311
0
    DeQuantImplSIMD<vext, T, true, false>( width, maxX, maxY, scaleQP, piDequantCoef, piQCoef, piQCfStride, piCoef, rightShift, inputMaximum, transformMaximum );
312
0
  }
313
0
}
Unexecuted instantiation: Quant_sse41.cpp:void vvdec::DeQuantScalingCoreSIMD<(vvdec::x86_simd::X86_VEXT)1, short>(unsigned int, int, int, int, int const*, short const*, unsigned long, int*, int, int, int)
Unexecuted instantiation: Quant_sse41.cpp:void vvdec::DeQuantScalingCoreSIMD<(vvdec::x86_simd::X86_VEXT)1, int>(unsigned int, int, int, int, int const*, int const*, unsigned long, int*, int, int, int)
Unexecuted instantiation: Quant_avx2.cpp:void vvdec::DeQuantScalingCoreSIMD<(vvdec::x86_simd::X86_VEXT)4, short>(unsigned int, int, int, int, int const*, short const*, unsigned long, int*, int, int, int)
Unexecuted instantiation: Quant_avx2.cpp:void vvdec::DeQuantScalingCoreSIMD<(vvdec::x86_simd::X86_VEXT)4, int>(unsigned int, int, int, int, int const*, int const*, unsigned long, int*, int, int, int)
314
315
template<X86_VEXT vext>
316
void Quant::_initQuantX86()
317
59.8k
{
318
59.8k
  DeQuant           = DeQuantCoreSIMD<vext, TCoeffSig>;
319
59.8k
  DeQuantPCM        = DeQuantCoreSIMD<vext, TCoeff>;
320
59.8k
  DeQuantScaling    = DeQuantScalingCoreSIMD<vext, TCoeffSig>;
321
59.8k
  DeQuantScalingPCM = DeQuantScalingCoreSIMD<vext, TCoeff>;
322
59.8k
}
Unexecuted instantiation: void vvdec::Quant::_initQuantX86<(vvdec::x86_simd::X86_VEXT)1>()
void vvdec::Quant::_initQuantX86<(vvdec::x86_simd::X86_VEXT)4>()
Line
Count
Source
317
59.8k
{
318
59.8k
  DeQuant           = DeQuantCoreSIMD<vext, TCoeffSig>;
319
59.8k
  DeQuantPCM        = DeQuantCoreSIMD<vext, TCoeff>;
320
59.8k
  DeQuantScaling    = DeQuantScalingCoreSIMD<vext, TCoeffSig>;
321
59.8k
  DeQuantScalingPCM = DeQuantScalingCoreSIMD<vext, TCoeff>;
322
59.8k
}
323
template void Quant::_initQuantX86<SIMDX86>();
324
325
#endif  // TARGET_SIMD_X86
326
#endif  // ENABLE_SIMD_OPT_QUANT
327
328
}   // namespace vvdec