1 /****************************************************************************
2 * Copyright (C) 2014-2015 Intel Corporation. All Rights Reserved.
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:
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
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
23 * @file format_conversion.h
25 * @brief API implementation
27 ******************************************************************************/
28 #include "format_types.h"
29 #include "format_traits.h"
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
>
37 INLINE
void LoadSOA(const BYTE
*pSrc
, simdvector
&dst
)
39 // fast path for float32
40 if ((FormatTraits
<SrcFormat
>::GetType(0) == SWR_TYPE_FLOAT
) && (FormatTraits
<SrcFormat
>::GetBPC(0) == 32))
42 auto lambda
= [&](int comp
)
44 simdscalar vComp
= _simd_load_ps((const float*)(pSrc
+ comp
*sizeof(simdscalar
)));
46 dst
.v
[FormatTraits
<SrcFormat
>::swizzle(comp
)] = vComp
;
49 UnrollerL
<0, FormatTraits
<SrcFormat
>::numComps
, 1>::step(lambda
);
53 auto lambda
= [&](int comp
)
55 // load SIMD components
56 simdscalar vComp
= FormatTraits
<SrcFormat
>::loadSOA(comp
, pSrc
);
59 vComp
= FormatTraits
<SrcFormat
>::unpack(comp
, vComp
);
62 if (FormatTraits
<SrcFormat
>::isNormalized(comp
))
64 vComp
= _simd_cvtepi32_ps(_simd_castps_si(vComp
));
65 vComp
= _simd_mul_ps(vComp
, _simd_set1_ps(FormatTraits
<SrcFormat
>::toFloat(comp
)));
68 dst
.v
[FormatTraits
<SrcFormat
>::swizzle(comp
)] = vComp
;
70 pSrc
+= (FormatTraits
<SrcFormat
>::GetBPC(comp
) * KNOB_SIMD_WIDTH
) / 8;
73 UnrollerL
<0, FormatTraits
<SrcFormat
>::numComps
, 1>::step(lambda
);
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
>
82 INLINE simdscalar
Clamp(simdscalar vComp
, uint32_t Component
)
84 if (FormatTraits
<Format
>::isNormalized(Component
))
86 if (FormatTraits
<Format
>::GetType(Component
) == SWR_TYPE_UNORM
)
88 vComp
= _simd_max_ps(vComp
, _simd_setzero_ps());
91 if (FormatTraits
<Format
>::GetType(Component
) == SWR_TYPE_SNORM
)
93 vComp
= _simd_max_ps(vComp
, _simd_set1_ps(-1.0f
));
95 vComp
= _simd_min_ps(vComp
, _simd_set1_ps(1.0f
));
97 else if (FormatTraits
<Format
>::GetBPC(Component
) < 32)
99 if (FormatTraits
<Format
>::GetType(Component
) == SWR_TYPE_UINT
)
101 int iMax
= (1 << FormatTraits
<Format
>::GetBPC(Component
)) - 1;
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
);
108 else if (FormatTraits
<Format
>::GetType(Component
) == SWR_TYPE_SINT
)
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
);
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
>
128 INLINE simdscalar
Normalize(simdscalar vComp
, uint32_t Component
)
130 if (FormatTraits
<Format
>::isNormalized(Component
))
132 vComp
= _simd_mul_ps(vComp
, _simd_set1_ps(FormatTraits
<Format
>::fromFloat(Component
)));
133 vComp
= _simd_castsi_ps(_simd_cvtps_epi32(vComp
));
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
>
144 INLINE
void StoreSOA(const simdvector
&src
, BYTE
*pDst
)
146 // fast path for float32
147 if ((FormatTraits
<DstFormat
>::GetType(0) == SWR_TYPE_FLOAT
) && (FormatTraits
<DstFormat
>::GetBPC(0) == 32))
149 for (uint32_t comp
= 0; comp
< FormatTraits
<DstFormat
>::numComps
; ++comp
)
151 simdscalar vComp
= src
.v
[FormatTraits
<DstFormat
>::swizzle(comp
)];
154 if (FormatTraits
<DstFormat
>::isSRGB
)
156 if (comp
< 3) // Input format is always RGBA32_FLOAT.
158 vComp
= FormatTraits
<R32G32B32A32_FLOAT
>::convertSrgb(comp
, vComp
);
162 _simd_store_ps((float*)(pDst
+ comp
*sizeof(simdscalar
)), vComp
);
167 auto lambda
= [&](int comp
)
169 simdscalar vComp
= src
.v
[FormatTraits
<DstFormat
>::swizzle(comp
)];
172 if (FormatTraits
<DstFormat
>::isSRGB
)
174 if (comp
< 3) // Input format is always RGBA32_FLOAT.
176 vComp
= FormatTraits
<R32G32B32A32_FLOAT
>::convertSrgb(comp
, vComp
);
181 vComp
= Clamp
<DstFormat
>(vComp
, comp
);
184 vComp
= Normalize
<DstFormat
>(vComp
, comp
);
187 vComp
= FormatTraits
<DstFormat
>::pack(comp
, vComp
);
190 FormatTraits
<DstFormat
>::storeSOA(comp
, pDst
, vComp
);
192 pDst
+= (FormatTraits
<DstFormat
>::GetBPC(comp
) * KNOB_SIMD_WIDTH
) / 8;
195 UnrollerL
<0, FormatTraits
<DstFormat
>::numComps
, 1>::step(lambda
);