Coverage Report

Created: 2026-04-12 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/FreeRDP/libfreerdp/codec/sse/rfx_sse2.c
Line
Count
Source
1
/**
2
 * FreeRDP: A Remote Desktop Protocol Implementation
3
 * RemoteFX Codec Library - SSE2 Optimizations
4
 *
5
 * Copyright 2011 Stephen Erisman
6
 * Copyright 2011 Norbert Federa <norbert.federa@thincast.com>
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 *     http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20
21
#include <winpr/assert.h>
22
#include <winpr/cast.h>
23
#include <winpr/platform.h>
24
#include <freerdp/config.h>
25
26
#include "../rfx_types.h"
27
#include "rfx_sse2.h"
28
#include "../rfx_quantization.h"
29
30
#include "../../core/simd.h"
31
#include "../../primitives/sse/prim_avxsse.h"
32
33
#if defined(SSE_AVX_INTRINSICS_ENABLED)
34
#include <stdio.h>
35
#include <stdlib.h>
36
#include <string.h>
37
#include <winpr/sysinfo.h>
38
39
#include <xmmintrin.h>
40
#include <emmintrin.h>
41
42
#ifdef _MSC_VER
43
#define __attribute__(...)
44
#endif
45
46
0
#define CACHE_LINE_BYTES 64
47
48
#ifndef __clang__
49
#define ATTRIBUTES __gnu_inline__, __always_inline__, __artificial__
50
#else
51
#define ATTRIBUTES __gnu_inline__, __always_inline__
52
#endif
53
54
static inline void __attribute__((ATTRIBUTES)) mm_prefetch_buffer(char* WINPR_RESTRICT buffer,
55
                                                                  size_t num_bytes)
56
0
{
57
0
  __m128i* buf = (__m128i*)buffer;
58
59
0
  for (size_t i = 0; i < (num_bytes / sizeof(__m128i)); i += (CACHE_LINE_BYTES / sizeof(__m128i)))
60
0
  {
61
0
    _mm_prefetch((char*)(&buf[i]), _MM_HINT_NTA);
62
0
  }
63
0
}
64
65
/* rfx_decode_ycbcr_to_rgb_sse2 code now resides in the primitives library. */
66
/* rfx_encode_rgb_to_ycbcr_sse2 code now resides in the primitives library. */
67
68
static inline void __attribute__((ATTRIBUTES))
69
rfx_quantization_decode_block_sse2(INT16* WINPR_RESTRICT buffer, const size_t buffer_size,
70
                                   const UINT32 factor)
71
0
{
72
0
  __m128i* ptr = (__m128i*)buffer;
73
0
  const __m128i* buf_end = (__m128i*)(buffer + buffer_size);
74
75
0
  if (factor == 0)
76
0
    return;
77
78
0
  do
79
0
  {
80
0
    const __m128i la = LOAD_SI128(ptr);
81
0
    const __m128i a = _mm_slli_epi16(la, WINPR_ASSERTING_INT_CAST(int, factor));
82
83
0
    STORE_SI128(ptr, a);
84
0
    ptr++;
85
0
  } while (ptr < buf_end);
86
0
}
87
88
WINPR_ATTR_NODISCARD
89
static BOOL rfx_quantization_decode_sse2(INT16* WINPR_RESTRICT buffer,
90
                                         const UINT32* WINPR_RESTRICT quantVals,
91
                                         size_t nrQuantValues)
92
0
{
93
0
  WINPR_ASSERT(buffer);
94
0
  WINPR_ASSERT(quantVals);
95
0
  WINPR_ASSERT(nrQuantValues == NR_QUANT_VALUES);
96
97
0
  for (size_t x = 0; x < nrQuantValues; x++)
98
0
  {
99
0
    const UINT32 val = quantVals[x];
100
0
    if (val < 1)
101
0
      return FALSE;
102
0
  }
103
104
0
  mm_prefetch_buffer((char*)buffer, 4096 * sizeof(INT16));
105
0
  rfx_quantization_decode_block_sse2(&buffer[0], 1024, quantVals[8] - 1);    /* HL1 */
106
0
  rfx_quantization_decode_block_sse2(&buffer[1024], 1024, quantVals[7] - 1); /* LH1 */
107
0
  rfx_quantization_decode_block_sse2(&buffer[2048], 1024, quantVals[9] - 1); /* HH1 */
108
0
  rfx_quantization_decode_block_sse2(&buffer[3072], 256, quantVals[5] - 1);  /* HL2 */
109
0
  rfx_quantization_decode_block_sse2(&buffer[3328], 256, quantVals[4] - 1);  /* LH2 */
110
0
  rfx_quantization_decode_block_sse2(&buffer[3584], 256, quantVals[6] - 1);  /* HH2 */
111
0
  rfx_quantization_decode_block_sse2(&buffer[3840], 64, quantVals[2] - 1);   /* HL3 */
112
0
  rfx_quantization_decode_block_sse2(&buffer[3904], 64, quantVals[1] - 1);   /* LH3 */
113
0
  rfx_quantization_decode_block_sse2(&buffer[3968], 64, quantVals[3] - 1);   /* HH3 */
114
0
  rfx_quantization_decode_block_sse2(&buffer[4032], 64, quantVals[0] - 1);   /* LL3 */
115
0
  return TRUE;
116
0
}
117
118
static inline void __attribute__((ATTRIBUTES))
119
rfx_quantization_encode_block_sse2(INT16* WINPR_RESTRICT buffer, const unsigned buffer_size,
120
                                   const INT16 factor)
121
0
{
122
0
  __m128i* ptr = (__m128i*)buffer;
123
0
  const __m128i* buf_end = (const __m128i*)(buffer + buffer_size);
124
125
0
  if (factor == 0)
126
0
    return;
127
128
0
  const __m128i half = _mm_set1_epi16(WINPR_ASSERTING_INT_CAST(INT16, 1 << (factor - 1)));
129
130
0
  do
131
0
  {
132
0
    const __m128i la = LOAD_SI128(ptr);
133
0
    __m128i a = _mm_add_epi16(la, half);
134
0
    a = _mm_srai_epi16(a, factor);
135
0
    STORE_SI128(ptr, a);
136
0
    ptr++;
137
0
  } while (ptr < buf_end);
138
0
}
139
140
WINPR_ATTR_NODISCARD
141
static BOOL rfx_quantization_encode_sse2(INT16* WINPR_RESTRICT buffer,
142
                                         const UINT32* WINPR_RESTRICT quantization_values,
143
                                         size_t quantVals)
144
0
{
145
0
  WINPR_ASSERT(buffer);
146
0
  WINPR_ASSERT(quantization_values);
147
0
  WINPR_ASSERT(quantVals == NR_QUANT_VALUES);
148
149
0
  for (size_t x = 0; x < quantVals; x++)
150
0
  {
151
0
    const UINT32 val = quantization_values[x];
152
0
    if (val < 6)
153
0
      return FALSE;
154
0
    if (val > INT16_MAX)
155
0
      return FALSE;
156
0
  }
157
158
0
  mm_prefetch_buffer((char*)buffer, 4096 * sizeof(INT16));
159
0
  rfx_quantization_encode_block_sse2(
160
0
      buffer, 1024, WINPR_ASSERTING_INT_CAST(INT16, quantization_values[8] - 6)); /* HL1 */
161
0
  rfx_quantization_encode_block_sse2(
162
0
      buffer + 1024, 1024, WINPR_ASSERTING_INT_CAST(INT16, quantization_values[7] - 6)); /* LH1 */
163
0
  rfx_quantization_encode_block_sse2(
164
0
      buffer + 2048, 1024, WINPR_ASSERTING_INT_CAST(INT16, quantization_values[9] - 6)); /* HH1 */
165
0
  rfx_quantization_encode_block_sse2(
166
0
      buffer + 3072, 256, WINPR_ASSERTING_INT_CAST(INT16, quantization_values[5] - 6)); /* HL2 */
167
0
  rfx_quantization_encode_block_sse2(
168
0
      buffer + 3328, 256, WINPR_ASSERTING_INT_CAST(INT16, quantization_values[4] - 6)); /* LH2 */
169
0
  rfx_quantization_encode_block_sse2(
170
0
      buffer + 3584, 256, WINPR_ASSERTING_INT_CAST(INT16, quantization_values[6] - 6)); /* HH2 */
171
0
  rfx_quantization_encode_block_sse2(
172
0
      buffer + 3840, 64, WINPR_ASSERTING_INT_CAST(INT16, quantization_values[2] - 6)); /* HL3 */
173
0
  rfx_quantization_encode_block_sse2(
174
0
      buffer + 3904, 64, WINPR_ASSERTING_INT_CAST(INT16, quantization_values[1] - 6)); /* LH3 */
175
0
  rfx_quantization_encode_block_sse2(
176
0
      buffer + 3968, 64, WINPR_ASSERTING_INT_CAST(INT16, quantization_values[3] - 6)); /* HH3 */
177
0
  rfx_quantization_encode_block_sse2(
178
0
      buffer + 4032, 64, WINPR_ASSERTING_INT_CAST(INT16, quantization_values[0] - 6)); /* LL3 */
179
0
  rfx_quantization_encode_block_sse2(buffer, 4096, 5);
180
0
  return TRUE;
181
0
}
182
183
static inline void __attribute__((ATTRIBUTES))
184
rfx_dwt_2d_decode_block_horiz_sse2(INT16* WINPR_RESTRICT l, INT16* WINPR_RESTRICT h,
185
                                   INT16* WINPR_RESTRICT dst, size_t subband_width)
186
0
{
187
0
  INT16* l_ptr = l;
188
0
  INT16* h_ptr = h;
189
0
  INT16* dst_ptr = dst;
190
0
  int first = 0;
191
0
  int last = 0;
192
0
  __m128i dst1;
193
0
  __m128i dst2;
194
195
0
  for (size_t y = 0; y < subband_width; y++)
196
0
  {
197
    /* Even coefficients */
198
0
    for (size_t n = 0; n < subband_width; n += 8)
199
0
    {
200
      /* dst[2n] = l[n] - ((h[n-1] + h[n] + 1) >> 1); */
201
0
      __m128i l_n = LOAD_SI128(l_ptr);
202
0
      __m128i h_n = LOAD_SI128(h_ptr);
203
0
      __m128i h_n_m = LOAD_SI128(h_ptr - 1);
204
205
0
      if (n == 0)
206
0
      {
207
0
        first = _mm_extract_epi16(h_n_m, 1);
208
0
        h_n_m = _mm_insert_epi16(h_n_m, first, 0);
209
0
      }
210
211
0
      __m128i tmp_n = _mm_add_epi16(h_n, h_n_m);
212
0
      tmp_n = _mm_add_epi16(tmp_n, _mm_set1_epi16(1));
213
0
      tmp_n = _mm_srai_epi16(tmp_n, 1);
214
0
      const __m128i dst_n = _mm_sub_epi16(l_n, tmp_n);
215
0
      STORE_SI128(l_ptr, dst_n);
216
0
      l_ptr += 8;
217
0
      h_ptr += 8;
218
0
    }
219
220
0
    l_ptr -= subband_width;
221
0
    h_ptr -= subband_width;
222
223
    /* Odd coefficients */
224
0
    for (size_t n = 0; n < subband_width; n += 8)
225
0
    {
226
      /* dst[2n + 1] = (h[n] << 1) + ((dst[2n] + dst[2n + 2]) >> 1); */
227
0
      __m128i h_n = LOAD_SI128(h_ptr);
228
0
      h_n = _mm_slli_epi16(h_n, 1);
229
0
      __m128i dst_n = LOAD_SI128(l_ptr);
230
0
      __m128i dst_n_p = LOAD_SI128(l_ptr + 1);
231
232
0
      if (n == subband_width - 8)
233
0
      {
234
0
        last = _mm_extract_epi16(dst_n_p, 6);
235
0
        dst_n_p = _mm_insert_epi16(dst_n_p, last, 7);
236
0
      }
237
238
0
      __m128i tmp_n = _mm_add_epi16(dst_n_p, dst_n);
239
0
      tmp_n = _mm_srai_epi16(tmp_n, 1);
240
0
      tmp_n = _mm_add_epi16(tmp_n, h_n);
241
0
      dst1 = _mm_unpacklo_epi16(dst_n, tmp_n);
242
0
      dst2 = _mm_unpackhi_epi16(dst_n, tmp_n);
243
0
      STORE_SI128(dst_ptr, dst1);
244
0
      STORE_SI128(dst_ptr + 8, dst2);
245
0
      l_ptr += 8;
246
0
      h_ptr += 8;
247
0
      dst_ptr += 16;
248
0
    }
249
0
  }
250
0
}
251
252
static inline void __attribute__((ATTRIBUTES))
253
rfx_dwt_2d_decode_block_vert_sse2(INT16* WINPR_RESTRICT l, INT16* WINPR_RESTRICT h,
254
                                  INT16* WINPR_RESTRICT dst, size_t subband_width)
255
0
{
256
0
  INT16* l_ptr = l;
257
0
  INT16* h_ptr = h;
258
0
  INT16* dst_ptr = dst;
259
0
  const size_t total_width = subband_width + subband_width;
260
261
  /* Even coefficients */
262
0
  for (size_t n = 0; n < subband_width; n++)
263
0
  {
264
0
    for (size_t x = 0; x < total_width; x += 8)
265
0
    {
266
      /* dst[2n] = l[n] - ((h[n-1] + h[n] + 1) >> 1); */
267
0
      const __m128i l_n = LOAD_SI128(l_ptr);
268
0
      const __m128i h_n = LOAD_SI128(h_ptr);
269
0
      __m128i tmp_n = _mm_add_epi16(h_n, _mm_set1_epi16(1));
270
271
0
      if (n == 0)
272
0
        tmp_n = _mm_add_epi16(tmp_n, h_n);
273
0
      else
274
0
      {
275
0
        const __m128i h_n_m = LOAD_SI128(h_ptr - total_width);
276
0
        tmp_n = _mm_add_epi16(tmp_n, h_n_m);
277
0
      }
278
279
0
      tmp_n = _mm_srai_epi16(tmp_n, 1);
280
0
      const __m128i dst_n = _mm_sub_epi16(l_n, tmp_n);
281
0
      STORE_SI128(dst_ptr, dst_n);
282
0
      l_ptr += 8;
283
0
      h_ptr += 8;
284
0
      dst_ptr += 8;
285
0
    }
286
287
0
    dst_ptr += total_width;
288
0
  }
289
290
0
  h_ptr = h;
291
0
  dst_ptr = dst + total_width;
292
293
  /* Odd coefficients */
294
0
  for (size_t n = 0; n < subband_width; n++)
295
0
  {
296
0
    for (size_t x = 0; x < total_width; x += 8)
297
0
    {
298
      /* dst[2n + 1] = (h[n] << 1) + ((dst[2n] + dst[2n + 2]) >> 1); */
299
0
      __m128i h_n = LOAD_SI128(h_ptr);
300
0
      __m128i dst_n_m = LOAD_SI128(dst_ptr - total_width);
301
0
      h_n = _mm_slli_epi16(h_n, 1);
302
0
      __m128i tmp_n = dst_n_m;
303
304
0
      if (n == subband_width - 1)
305
0
        tmp_n = _mm_add_epi16(tmp_n, dst_n_m);
306
0
      else
307
0
      {
308
0
        const __m128i dst_n_p = LOAD_SI128(dst_ptr + total_width);
309
0
        tmp_n = _mm_add_epi16(tmp_n, dst_n_p);
310
0
      }
311
312
0
      tmp_n = _mm_srai_epi16(tmp_n, 1);
313
0
      const __m128i dst_n = _mm_add_epi16(tmp_n, h_n);
314
0
      STORE_SI128(dst_ptr, dst_n);
315
0
      h_ptr += 8;
316
0
      dst_ptr += 8;
317
0
    }
318
319
0
    dst_ptr += total_width;
320
0
  }
321
0
}
322
323
static inline void __attribute__((ATTRIBUTES))
324
rfx_dwt_2d_decode_block_sse2(INT16* WINPR_RESTRICT buffer, INT16* WINPR_RESTRICT idwt,
325
                             size_t subband_width)
326
0
{
327
0
  mm_prefetch_buffer((char*)idwt, 4ULL * subband_width * sizeof(INT16));
328
  /* Inverse DWT in horizontal direction, results in 2 sub-bands in L, H order in tmp buffer idwt.
329
   */
330
  /* The 4 sub-bands are stored in HL(0), LH(1), HH(2), LL(3) order. */
331
  /* The lower part L uses LL(3) and HL(0). */
332
  /* The higher part H uses LH(1) and HH(2). */
333
0
  INT16* ll = buffer + 3ULL * subband_width * subband_width;
334
0
  INT16* hl = buffer;
335
0
  INT16* l_dst = idwt;
336
0
  rfx_dwt_2d_decode_block_horiz_sse2(ll, hl, l_dst, subband_width);
337
0
  INT16* lh = buffer + 1ULL * subband_width * subband_width;
338
0
  INT16* hh = buffer + 2ULL * subband_width * subband_width;
339
0
  INT16* h_dst = idwt + 2ULL * subband_width * subband_width;
340
0
  rfx_dwt_2d_decode_block_horiz_sse2(lh, hh, h_dst, subband_width);
341
  /* Inverse DWT in vertical direction, results are stored in original buffer. */
342
0
  rfx_dwt_2d_decode_block_vert_sse2(l_dst, h_dst, buffer, subband_width);
343
0
}
344
345
static void rfx_dwt_2d_decode_sse2(INT16* WINPR_RESTRICT buffer, INT16* WINPR_RESTRICT dwt_buffer)
346
0
{
347
0
  WINPR_ASSERT(buffer);
348
0
  WINPR_ASSERT(dwt_buffer);
349
350
0
  mm_prefetch_buffer((char*)buffer, 4096 * sizeof(INT16));
351
0
  rfx_dwt_2d_decode_block_sse2(&buffer[3840], dwt_buffer, 8);
352
0
  rfx_dwt_2d_decode_block_sse2(&buffer[3072], dwt_buffer, 16);
353
0
  rfx_dwt_2d_decode_block_sse2(&buffer[0], dwt_buffer, 32);
354
0
}
355
356
static inline void __attribute__((ATTRIBUTES))
357
rfx_dwt_2d_encode_block_vert_sse2(INT16* WINPR_RESTRICT src, INT16* WINPR_RESTRICT l,
358
                                  INT16* WINPR_RESTRICT h, size_t subband_width)
359
0
{
360
0
  const size_t total_width = subband_width << 1;
361
362
0
  for (size_t n = 0; n < subband_width; n++)
363
0
  {
364
0
    for (size_t x = 0; x < total_width; x += 8)
365
0
    {
366
0
      __m128i src_2n = LOAD_SI128(src);
367
0
      __m128i src_2n_1 = LOAD_SI128(src + total_width);
368
0
      __m128i src_2n_2 = src_2n;
369
370
0
      if (n < subband_width - 1)
371
0
        src_2n_2 = LOAD_SI128(src + 2ULL * total_width);
372
373
      /* h[n] = (src[2n + 1] - ((src[2n] + src[2n + 2]) >> 1)) >> 1 */
374
0
      __m128i h_n = _mm_add_epi16(src_2n, src_2n_2);
375
0
      h_n = _mm_srai_epi16(h_n, 1);
376
0
      h_n = _mm_sub_epi16(src_2n_1, h_n);
377
0
      h_n = _mm_srai_epi16(h_n, 1);
378
0
      STORE_SI128(h, h_n);
379
380
0
      __m128i h_n_m = h_n;
381
0
      if (n != 0)
382
0
        h_n_m = LOAD_SI128(h - total_width);
383
384
      /* l[n] = src[2n] + ((h[n - 1] + h[n]) >> 1) */
385
0
      __m128i l_n = _mm_add_epi16(h_n_m, h_n);
386
0
      l_n = _mm_srai_epi16(l_n, 1);
387
0
      l_n = _mm_add_epi16(l_n, src_2n);
388
0
      STORE_SI128(l, l_n);
389
0
      src += 8;
390
0
      l += 8;
391
0
      h += 8;
392
0
    }
393
394
0
    src += total_width;
395
0
  }
396
0
}
397
398
static inline void __attribute__((ATTRIBUTES))
399
rfx_dwt_2d_encode_block_horiz_sse2(INT16* WINPR_RESTRICT src, INT16* WINPR_RESTRICT l,
400
                                   INT16* WINPR_RESTRICT h, size_t subband_width)
401
0
{
402
0
  for (size_t y = 0; y < subband_width; y++)
403
0
  {
404
0
    for (size_t n = 0; n < subband_width; n += 8)
405
0
    {
406
      /* The following 3 Set operations consumes more than half of the total DWT processing
407
       * time! */
408
0
      const INT16 src16 = (INT16)(((n + 8) == subband_width) ? src[14] : src[16]);
409
0
      __m128i src_2n =
410
0
          _mm_set_epi16(src[14], src[12], src[10], src[8], src[6], src[4], src[2], src[0]);
411
0
      __m128i src_2n_1 =
412
0
          _mm_set_epi16(src[15], src[13], src[11], src[9], src[7], src[5], src[3], src[1]);
413
0
      __m128i src_2n_2 =
414
0
          _mm_set_epi16(src16, src[14], src[12], src[10], src[8], src[6], src[4], src[2]);
415
      /* h[n] = (src[2n + 1] - ((src[2n] + src[2n + 2]) >> 1)) >> 1 */
416
0
      __m128i h_n = _mm_add_epi16(src_2n, src_2n_2);
417
0
      h_n = _mm_srai_epi16(h_n, 1);
418
0
      h_n = _mm_sub_epi16(src_2n_1, h_n);
419
0
      h_n = _mm_srai_epi16(h_n, 1);
420
0
      STORE_SI128(h, h_n);
421
0
      __m128i h_n_m = LOAD_SI128(h - 1);
422
423
0
      if (n == 0)
424
0
      {
425
0
        int first = _mm_extract_epi16(h_n_m, 1);
426
0
        h_n_m = _mm_insert_epi16(h_n_m, first, 0);
427
0
      }
428
429
      /* l[n] = src[2n] + ((h[n - 1] + h[n]) >> 1) */
430
0
      __m128i l_n = _mm_add_epi16(h_n_m, h_n);
431
0
      l_n = _mm_srai_epi16(l_n, 1);
432
0
      l_n = _mm_add_epi16(l_n, src_2n);
433
0
      STORE_SI128(l, l_n);
434
0
      src += 16;
435
0
      l += 8;
436
0
      h += 8;
437
0
    }
438
0
  }
439
0
}
440
441
static inline void __attribute__((ATTRIBUTES))
442
rfx_dwt_2d_encode_block_sse2(INT16* WINPR_RESTRICT buffer, INT16* WINPR_RESTRICT dwt,
443
                             size_t subband_width)
444
0
{
445
0
  mm_prefetch_buffer((char*)dwt, 4ULL * subband_width * sizeof(INT16));
446
  /* DWT in vertical direction, results in 2 sub-bands in L, H order in tmp buffer dwt. */
447
0
  INT16* l_src = dwt;
448
0
  INT16* h_src = dwt + 2ULL * subband_width * subband_width;
449
0
  rfx_dwt_2d_encode_block_vert_sse2(buffer, l_src, h_src, subband_width);
450
  /* DWT in horizontal direction, results in 4 sub-bands in HL(0), LH(1), HH(2), LL(3) order,
451
   * stored in original buffer. */
452
  /* The lower part L generates LL(3) and HL(0). */
453
  /* The higher part H generates LH(1) and HH(2). */
454
0
  INT16* ll = buffer + 3ULL * subband_width * subband_width;
455
0
  INT16* hl = buffer;
456
0
  INT16* lh = buffer + 1ULL * subband_width * subband_width;
457
0
  INT16* hh = buffer + 2ULL * subband_width * subband_width;
458
0
  rfx_dwt_2d_encode_block_horiz_sse2(l_src, ll, hl, subband_width);
459
0
  rfx_dwt_2d_encode_block_horiz_sse2(h_src, lh, hh, subband_width);
460
0
}
461
462
static void rfx_dwt_2d_encode_sse2(INT16* WINPR_RESTRICT buffer, INT16* WINPR_RESTRICT dwt_buffer)
463
0
{
464
0
  WINPR_ASSERT(buffer);
465
0
  WINPR_ASSERT(dwt_buffer);
466
467
0
  mm_prefetch_buffer((char*)buffer, 4096 * sizeof(INT16));
468
0
  rfx_dwt_2d_encode_block_sse2(buffer, dwt_buffer, 32);
469
0
  rfx_dwt_2d_encode_block_sse2(buffer + 3072, dwt_buffer, 16);
470
0
  rfx_dwt_2d_encode_block_sse2(buffer + 3840, dwt_buffer, 8);
471
0
}
472
#endif
473
474
void rfx_init_sse2_int(RFX_CONTEXT* WINPR_RESTRICT context)
475
11.7k
{
476
11.7k
#if defined(SSE_AVX_INTRINSICS_ENABLED)
477
11.7k
  WLog_VRB(PRIM_TAG, "SSE2/SSE3 optimizations");
478
11.7k
  PROFILER_RENAME(context->priv->prof_rfx_quantization_decode, "rfx_quantization_decode_sse2")
479
11.7k
  PROFILER_RENAME(context->priv->prof_rfx_quantization_encode, "rfx_quantization_encode_sse2")
480
11.7k
  PROFILER_RENAME(context->priv->prof_rfx_dwt_2d_decode, "rfx_dwt_2d_decode_sse2")
481
11.7k
  PROFILER_RENAME(context->priv->prof_rfx_dwt_2d_encode, "rfx_dwt_2d_encode_sse2")
482
11.7k
  context->quantization_decode = rfx_quantization_decode_sse2;
483
11.7k
  context->quantization_encode = rfx_quantization_encode_sse2;
484
11.7k
  context->dwt_2d_decode = rfx_dwt_2d_decode_sse2;
485
11.7k
  context->dwt_2d_encode = rfx_dwt_2d_encode_sse2;
486
#else
487
  WINPR_UNUSED(context);
488
  WLog_VRB(PRIM_TAG, "undefined WITH_SIMD or SSE2 intrinsics not available");
489
#endif
490
11.7k
}