• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2 * Copyright (C) 2014-2015 Intel Corporation.   All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * @file format_conversion.h
24 *
25 * @brief API implementation
26 *
27 ******************************************************************************/
28 #include "format_types.h"
29 #include "format_traits.h"
30 
31 //////////////////////////////////////////////////////////////////////////
32 /// @brief Load SIMD packed pixels in SOA format and converts to
33 ///        SOA RGBA32_FLOAT format.
34 /// @param pSrc - source data in SOA form
35 /// @param dst - output data in SOA form
36 template<SWR_FORMAT SrcFormat>
LoadSOA(const uint8_t * pSrc,simdvector & dst)37 INLINE void LoadSOA(const uint8_t *pSrc, simdvector &dst)
38 {
39     // fast path for float32
40     if ((FormatTraits<SrcFormat>::GetType(0) == SWR_TYPE_FLOAT) && (FormatTraits<SrcFormat>::GetBPC(0) == 32))
41     {
42         auto lambda = [&](int comp)
43         {
44             simdscalar vComp = _simd_load_ps((const float*)(pSrc + comp*sizeof(simdscalar)));
45 
46             dst.v[FormatTraits<SrcFormat>::swizzle(comp)] = vComp;
47         };
48 
49         UnrollerL<0, FormatTraits<SrcFormat>::numComps, 1>::step(lambda);
50         return;
51     }
52 
53     auto lambda = [&](int comp)
54     {
55         // load SIMD components
56         simdscalar vComp = FormatTraits<SrcFormat>::loadSOA(comp, pSrc);
57 
58         // unpack
59         vComp = FormatTraits<SrcFormat>::unpack(comp, vComp);
60 
61         // convert
62         if (FormatTraits<SrcFormat>::isNormalized(comp))
63         {
64             vComp = _simd_cvtepi32_ps(_simd_castps_si(vComp));
65             vComp = _simd_mul_ps(vComp, _simd_set1_ps(FormatTraits<SrcFormat>::toFloat(comp)));
66         }
67 
68         dst.v[FormatTraits<SrcFormat>::swizzle(comp)] = vComp;
69 
70         pSrc += (FormatTraits<SrcFormat>::GetBPC(comp) * KNOB_SIMD_WIDTH) / 8;
71     };
72 
73     UnrollerL<0, FormatTraits<SrcFormat>::numComps, 1>::step(lambda);
74 }
75 
76 //////////////////////////////////////////////////////////////////////////
77 /// @brief Clamps the given component based on the requirements on the
78 ///        Format template arg
79 /// @param vComp - SIMD vector of floats
80 /// @param Component - component
81 template<SWR_FORMAT Format>
Clamp(simdscalar vComp,uint32_t Component)82 INLINE simdscalar Clamp(simdscalar vComp, uint32_t Component)
83 {
84     if (FormatTraits<Format>::isNormalized(Component))
85     {
86         if (FormatTraits<Format>::GetType(Component) == SWR_TYPE_UNORM)
87         {
88             vComp = _simd_max_ps(vComp, _simd_setzero_ps());
89         }
90 
91         if (FormatTraits<Format>::GetType(Component) == SWR_TYPE_SNORM)
92         {
93             vComp = _simd_max_ps(vComp, _simd_set1_ps(-1.0f));
94         }
95         vComp = _simd_min_ps(vComp, _simd_set1_ps(1.0f));
96     }
97     else if (FormatTraits<Format>::GetBPC(Component) < 32)
98     {
99         if (FormatTraits<Format>::GetType(Component) == SWR_TYPE_UINT)
100         {
101             int iMax = (1 << FormatTraits<Format>::GetBPC(Component)) - 1;
102             int iMin = 0;
103             simdscalari vCompi = _simd_castps_si(vComp);
104             vCompi = _simd_max_epu32(vCompi, _simd_set1_epi32(iMin));
105             vCompi = _simd_min_epu32(vCompi, _simd_set1_epi32(iMax));
106             vComp = _simd_castsi_ps(vCompi);
107         }
108         else if (FormatTraits<Format>::GetType(Component) == SWR_TYPE_SINT)
109         {
110             int iMax = (1 << (FormatTraits<Format>::GetBPC(Component) - 1)) - 1;
111             int iMin = -1 - iMax;
112             simdscalari vCompi = _simd_castps_si(vComp);
113             vCompi = _simd_max_epi32(vCompi, _simd_set1_epi32(iMin));
114             vCompi = _simd_min_epi32(vCompi, _simd_set1_epi32(iMax));
115             vComp = _simd_castsi_ps(vCompi);
116         }
117     }
118 
119     return vComp;
120 }
121 
122 //////////////////////////////////////////////////////////////////////////
123 /// @brief Normalize the given component based on the requirements on the
124 ///        Format template arg
125 /// @param vComp - SIMD vector of floats
126 /// @param Component - component
127 template<SWR_FORMAT Format>
Normalize(simdscalar vComp,uint32_t Component)128 INLINE simdscalar Normalize(simdscalar vComp, uint32_t Component)
129 {
130     if (FormatTraits<Format>::isNormalized(Component))
131     {
132         vComp = _simd_mul_ps(vComp, _simd_set1_ps(FormatTraits<Format>::fromFloat(Component)));
133         vComp = _simd_castsi_ps(_simd_cvtps_epi32(vComp));
134     }
135     return vComp;
136 }
137 
138 //////////////////////////////////////////////////////////////////////////
139 /// @brief Convert and store simdvector of pixels in SOA
140 ///        RGBA32_FLOAT to SOA format
141 /// @param src - source data in SOA form
142 /// @param dst - output data in SOA form
143 template<SWR_FORMAT DstFormat>
StoreSOA(const simdvector & src,uint8_t * pDst)144 INLINE void StoreSOA(const simdvector &src, uint8_t *pDst)
145 {
146     // fast path for float32
147     if ((FormatTraits<DstFormat>::GetType(0) == SWR_TYPE_FLOAT) && (FormatTraits<DstFormat>::GetBPC(0) == 32))
148     {
149         for (uint32_t comp = 0; comp < FormatTraits<DstFormat>::numComps; ++comp)
150         {
151             simdscalar vComp = src.v[FormatTraits<DstFormat>::swizzle(comp)];
152 
153             // Gamma-correct
154             if (FormatTraits<DstFormat>::isSRGB)
155             {
156                 if (comp < 3)  // Input format is always RGBA32_FLOAT.
157                 {
158                     vComp = FormatTraits<R32G32B32A32_FLOAT>::convertSrgb(comp, vComp);
159                 }
160             }
161 
162             _simd_store_ps((float*)(pDst + comp*sizeof(simdscalar)), vComp);
163         }
164         return;
165     }
166 
167     auto lambda = [&](int comp)
168     {
169         simdscalar vComp = src.v[FormatTraits<DstFormat>::swizzle(comp)];
170 
171         // Gamma-correct
172         if (FormatTraits<DstFormat>::isSRGB)
173         {
174             if (comp < 3)  // Input format is always RGBA32_FLOAT.
175             {
176                 vComp = FormatTraits<R32G32B32A32_FLOAT>::convertSrgb(comp, vComp);
177             }
178         }
179 
180         // clamp
181         vComp = Clamp<DstFormat>(vComp, comp);
182 
183         // normalize
184         vComp = Normalize<DstFormat>(vComp, comp);
185 
186         // pack
187         vComp = FormatTraits<DstFormat>::pack(comp, vComp);
188 
189         // store
190         FormatTraits<DstFormat>::storeSOA(comp, pDst, vComp);
191 
192         pDst += (FormatTraits<DstFormat>::GetBPC(comp) * KNOB_SIMD_WIDTH) / 8;
193     };
194 
195     UnrollerL<0, FormatTraits<DstFormat>::numComps, 1>::step(lambda);
196 }
197 
198 #if ENABLE_AVX512_SIMD16
199 //////////////////////////////////////////////////////////////////////////
200 /// @brief Load SIMD packed pixels in SOA format and converts to
201 ///        SOA RGBA32_FLOAT format.
202 /// @param pSrc - source data in SOA form
203 /// @param dst - output data in SOA form
204 template<SWR_FORMAT SrcFormat>
LoadSOA(const uint8_t * pSrc,simd16vector & dst)205 INLINE void LoadSOA(const uint8_t *pSrc, simd16vector &dst)
206 {
207     // fast path for float32
208     if ((FormatTraits<SrcFormat>::GetType(0) == SWR_TYPE_FLOAT) && (FormatTraits<SrcFormat>::GetBPC(0) == 32))
209     {
210         auto lambda = [&](int comp)
211         {
212             simd16scalar vComp = _simd16_load_ps(reinterpret_cast<const float *>(pSrc + comp * sizeof(simd16scalar)));
213 
214             dst.v[FormatTraits<SrcFormat>::swizzle(comp)] = vComp;
215         };
216 
217         UnrollerL<0, FormatTraits<SrcFormat>::numComps, 1>::step(lambda);
218         return;
219     }
220 
221     auto lambda = [&](int comp)
222     {
223         // load SIMD components
224         simd16scalar vComp = FormatTraits<SrcFormat>::loadSOA_16(comp, pSrc);
225 
226         // unpack
227         vComp = FormatTraits<SrcFormat>::unpack(comp, vComp);
228 
229         // convert
230         if (FormatTraits<SrcFormat>::isNormalized(comp))
231         {
232             vComp = _simd16_cvtepi32_ps(_simd16_castps_si(vComp));
233             vComp = _simd16_mul_ps(vComp, _simd16_set1_ps(FormatTraits<SrcFormat>::toFloat(comp)));
234         }
235 
236         dst.v[FormatTraits<SrcFormat>::swizzle(comp)] = vComp;
237 
238         pSrc += (FormatTraits<SrcFormat>::GetBPC(comp) * KNOB_SIMD16_WIDTH) / 8;
239     };
240 
241     UnrollerL<0, FormatTraits<SrcFormat>::numComps, 1>::step(lambda);
242 }
243 
244 //////////////////////////////////////////////////////////////////////////
245 /// @brief Clamps the given component based on the requirements on the
246 ///        Format template arg
247 /// @param vComp - SIMD vector of floats
248 /// @param Component - component
249 template<SWR_FORMAT Format>
Clamp(simd16scalar vComp,uint32_t Component)250 INLINE simd16scalar Clamp(simd16scalar vComp, uint32_t Component)
251 {
252     if (FormatTraits<Format>::isNormalized(Component))
253     {
254         if (FormatTraits<Format>::GetType(Component) == SWR_TYPE_UNORM)
255         {
256             vComp = _simd16_max_ps(vComp, _simd16_setzero_ps());
257         }
258 
259         if (FormatTraits<Format>::GetType(Component) == SWR_TYPE_SNORM)
260         {
261             vComp = _simd16_max_ps(vComp, _simd16_set1_ps(-1.0f));
262         }
263         vComp = _simd16_min_ps(vComp, _simd16_set1_ps(1.0f));
264     }
265     else if (FormatTraits<Format>::GetBPC(Component) < 32)
266     {
267         if (FormatTraits<Format>::GetType(Component) == SWR_TYPE_UINT)
268         {
269             int iMax = (1 << FormatTraits<Format>::GetBPC(Component)) - 1;
270             int iMin = 0;
271             simd16scalari vCompi = _simd16_castps_si(vComp);
272             vCompi = _simd16_max_epu32(vCompi, _simd16_set1_epi32(iMin));
273             vCompi = _simd16_min_epu32(vCompi, _simd16_set1_epi32(iMax));
274             vComp = _simd16_castsi_ps(vCompi);
275         }
276         else if (FormatTraits<Format>::GetType(Component) == SWR_TYPE_SINT)
277         {
278             int iMax = (1 << (FormatTraits<Format>::GetBPC(Component) - 1)) - 1;
279             int iMin = -1 - iMax;
280             simd16scalari vCompi = _simd16_castps_si(vComp);
281             vCompi = _simd16_max_epi32(vCompi, _simd16_set1_epi32(iMin));
282             vCompi = _simd16_min_epi32(vCompi, _simd16_set1_epi32(iMax));
283             vComp = _simd16_castsi_ps(vCompi);
284         }
285     }
286 
287     return vComp;
288 }
289 
290 //////////////////////////////////////////////////////////////////////////
291 /// @brief Normalize the given component based on the requirements on the
292 ///        Format template arg
293 /// @param vComp - SIMD vector of floats
294 /// @param Component - component
295 template<SWR_FORMAT Format>
Normalize(simd16scalar vComp,uint32_t Component)296 INLINE simd16scalar Normalize(simd16scalar vComp, uint32_t Component)
297 {
298     if (FormatTraits<Format>::isNormalized(Component))
299     {
300         vComp = _simd16_mul_ps(vComp, _simd16_set1_ps(FormatTraits<Format>::fromFloat(Component)));
301         vComp = _simd16_castsi_ps(_simd16_cvtps_epi32(vComp));
302     }
303     return vComp;
304 }
305 
306 //////////////////////////////////////////////////////////////////////////
307 /// @brief Convert and store simdvector of pixels in SOA
308 ///        RGBA32_FLOAT to SOA format
309 /// @param src - source data in SOA form
310 /// @param dst - output data in SOA form
311 template<SWR_FORMAT DstFormat>
StoreSOA(const simd16vector & src,uint8_t * pDst)312 INLINE void StoreSOA(const simd16vector &src, uint8_t *pDst)
313 {
314     // fast path for float32
315     if ((FormatTraits<DstFormat>::GetType(0) == SWR_TYPE_FLOAT) && (FormatTraits<DstFormat>::GetBPC(0) == 32))
316     {
317         for (uint32_t comp = 0; comp < FormatTraits<DstFormat>::numComps; ++comp)
318         {
319             simd16scalar vComp = src.v[FormatTraits<DstFormat>::swizzle(comp)];
320 
321             // Gamma-correct
322             if (FormatTraits<DstFormat>::isSRGB)
323             {
324                 if (comp < 3)  // Input format is always RGBA32_FLOAT.
325                 {
326                     vComp = FormatTraits<R32G32B32A32_FLOAT>::convertSrgb(comp, vComp);
327                 }
328             }
329 
330             _simd16_store_ps(reinterpret_cast<float *>(pDst + comp * sizeof(simd16scalar)), vComp);
331         }
332         return;
333     }
334 
335     auto lambda = [&](int comp)
336     {
337         simd16scalar vComp = src.v[FormatTraits<DstFormat>::swizzle(comp)];
338 
339         // Gamma-correct
340         if (FormatTraits<DstFormat>::isSRGB)
341         {
342             if (comp < 3)  // Input format is always RGBA32_FLOAT.
343             {
344                 vComp = FormatTraits<R32G32B32A32_FLOAT>::convertSrgb(comp, vComp);
345             }
346         }
347 
348         // clamp
349         vComp = Clamp<DstFormat>(vComp, comp);
350 
351         // normalize
352         vComp = Normalize<DstFormat>(vComp, comp);
353 
354         // pack
355         vComp = FormatTraits<DstFormat>::pack(comp, vComp);
356 
357         // store
358         FormatTraits<DstFormat>::storeSOA(comp, pDst, vComp);
359 
360         pDst += (FormatTraits<DstFormat>::GetBPC(comp) * KNOB_SIMD16_WIDTH) / 8;
361     };
362 
363     UnrollerL<0, FormatTraits<DstFormat>::numComps, 1>::step(lambda);
364 }
365 
366 #endif
367