color.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. // Copyright 2009-2021 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. #if defined(EMBREE_SYCL_SUPPORT) && defined(__SYCL_DEVICE_ONLY__)
  5. # include "color_sycl.h"
  6. #else
  7. #include "constants.h"
  8. #include "col3.h"
  9. #include "col4.h"
  10. #include "../simd/sse.h"
  11. namespace embree
  12. {
  13. ////////////////////////////////////////////////////////////////////////////////
  14. /// SSE RGBA Color Class
  15. ////////////////////////////////////////////////////////////////////////////////
  16. struct Color4
  17. {
  18. union {
  19. __m128 m128;
  20. struct { float r,g,b,a; };
  21. };
  22. ////////////////////////////////////////////////////////////////////////////////
  23. /// Construction
  24. ////////////////////////////////////////////////////////////////////////////////
  25. __forceinline Color4 () {}
  26. __forceinline Color4 ( const __m128 a ) : m128(a) {}
  27. __forceinline explicit Color4 (const float v) : m128(_mm_set1_ps(v)) {}
  28. __forceinline Color4 (const float r, const float g, const float b, const float a) : m128(_mm_set_ps(a,b,g,r)) {}
  29. __forceinline explicit Color4 ( const Col3uc& other ) { m128 = _mm_mul_ps(_mm_set_ps(255.0f,other.b,other.g,other.r),_mm_set1_ps(one_over_255)); }
  30. __forceinline explicit Color4 ( const Col3f& other ) { m128 = _mm_set_ps(1.0f,other.b,other.g,other.r); }
  31. __forceinline explicit Color4 ( const Col4uc& other ) { m128 = _mm_mul_ps(_mm_set_ps(other.a,other.b,other.g,other.r),_mm_set1_ps(one_over_255)); }
  32. __forceinline explicit Color4 ( const Col4f& other ) { m128 = _mm_set_ps(other.a,other.b,other.g,other.r); }
  33. __forceinline Color4 ( const Color4& other ) : m128(other.m128) {}
  34. __forceinline Color4& operator=( const Color4& other ) { m128 = other.m128; return *this; }
  35. __forceinline operator const __m128&() const { return m128; }
  36. __forceinline operator __m128&() { return m128; }
  37. ////////////////////////////////////////////////////////////////////////////////
  38. /// Set
  39. ////////////////////////////////////////////////////////////////////////////////
  40. __forceinline void set(Col3f& d) const { d.r = r; d.g = g; d.b = b; }
  41. __forceinline void set(Col4f& d) const { d.r = r; d.g = g; d.b = b; d.a = a; }
  42. __forceinline void set(Col3uc& d) const
  43. {
  44. vfloat4 s = clamp(vfloat4(m128))*255.0f;
  45. d.r = (unsigned char)(s[0]);
  46. d.g = (unsigned char)(s[1]);
  47. d.b = (unsigned char)(s[2]);
  48. }
  49. __forceinline void set(Col4uc& d) const
  50. {
  51. vfloat4 s = clamp(vfloat4(m128))*255.0f;
  52. d.r = (unsigned char)(s[0]);
  53. d.g = (unsigned char)(s[1]);
  54. d.b = (unsigned char)(s[2]);
  55. d.a = (unsigned char)(s[3]);
  56. }
  57. __forceinline void set(float &f) const
  58. {
  59. f = 0.2126f*r+0.7125f*g+0.0722f*b; // sRGB luminance.
  60. }
  61. ////////////////////////////////////////////////////////////////////////////////
  62. /// Constants
  63. ////////////////////////////////////////////////////////////////////////////////
  64. __forceinline Color4( ZeroTy ) : m128(_mm_set1_ps(0.0f)) {}
  65. __forceinline Color4( OneTy ) : m128(_mm_set1_ps(1.0f)) {}
  66. __forceinline Color4( PosInfTy ) : m128(_mm_set1_ps(pos_inf)) {}
  67. __forceinline Color4( NegInfTy ) : m128(_mm_set1_ps(neg_inf)) {}
  68. };
  69. ////////////////////////////////////////////////////////////////////////////////
  70. /// SSE RGB Color Class
  71. ////////////////////////////////////////////////////////////////////////////////
  72. struct Color
  73. {
  74. union {
  75. __m128 m128;
  76. struct { float r,g,b; };
  77. };
  78. ////////////////////////////////////////////////////////////////////////////////
  79. /// Construction
  80. ////////////////////////////////////////////////////////////////////////////////
  81. __forceinline Color () {}
  82. __forceinline Color ( const __m128 a ) : m128(a) {}
  83. __forceinline explicit Color (const float v) : m128(_mm_set1_ps(v)) {}
  84. __forceinline Color (const float r, const float g, const float b) : m128(_mm_set_ps(0.0f,b,g,r)) {}
  85. __forceinline Color ( const Color& other ) : m128(other.m128) {}
  86. __forceinline Color& operator=( const Color& other ) { m128 = other.m128; return *this; }
  87. __forceinline Color ( const Color4& other ) : m128(other.m128) {}
  88. __forceinline Color& operator=( const Color4& other ) { m128 = other.m128; return *this; }
  89. __forceinline operator const __m128&() const { return m128; }
  90. __forceinline operator __m128&() { return m128; }
  91. ////////////////////////////////////////////////////////////////////////////////
  92. /// Set
  93. ////////////////////////////////////////////////////////////////////////////////
  94. __forceinline void set(Col3f& d) const { d.r = r; d.g = g; d.b = b; }
  95. __forceinline void set(Col4f& d) const { d.r = r; d.g = g; d.b = b; d.a = 1.0f; }
  96. __forceinline void set(Col3uc& d) const
  97. {
  98. vfloat4 s = clamp(vfloat4(m128))*255.0f;
  99. d.r = (unsigned char)(s[0]);
  100. d.g = (unsigned char)(s[1]);
  101. d.b = (unsigned char)(s[2]);
  102. }
  103. __forceinline void set(Col4uc& d) const
  104. {
  105. vfloat4 s = clamp(vfloat4(m128))*255.0f;
  106. d.r = (unsigned char)(s[0]);
  107. d.g = (unsigned char)(s[1]);
  108. d.b = (unsigned char)(s[2]);
  109. d.a = 255;
  110. }
  111. ////////////////////////////////////////////////////////////////////////////////
  112. /// Constants
  113. ////////////////////////////////////////////////////////////////////////////////
  114. __forceinline Color( ZeroTy ) : m128(_mm_set1_ps(0.0f)) {}
  115. __forceinline Color( OneTy ) : m128(_mm_set1_ps(1.0f)) {}
  116. __forceinline Color( PosInfTy ) : m128(_mm_set1_ps(pos_inf)) {}
  117. __forceinline Color( NegInfTy ) : m128(_mm_set1_ps(neg_inf)) {}
  118. };
  119. ////////////////////////////////////////////////////////////////////////////////
  120. /// Unary Operators
  121. ////////////////////////////////////////////////////////////////////////////////
  122. __forceinline const Color operator +( const Color& a ) { return a; }
  123. __forceinline const Color operator -( const Color& a ) {
  124. const __m128 mask = _mm_castsi128_ps(_mm_set1_epi32(0x80000000));
  125. return _mm_xor_ps(a.m128, mask);
  126. }
  127. __forceinline const Color abs ( const Color& a ) {
  128. const __m128 mask = _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff));
  129. return _mm_and_ps(a.m128, mask);
  130. }
  131. __forceinline const Color rcp ( const Color& a )
  132. {
  133. #if defined(__aarch64__)
  134. __m128 reciprocal = _mm_rcp_ps(a.m128);
  135. reciprocal = vmulq_f32(vrecpsq_f32(a.m128, reciprocal), reciprocal);
  136. reciprocal = vmulq_f32(vrecpsq_f32(a.m128, reciprocal), reciprocal);
  137. return (const Color)reciprocal;
  138. #else
  139. #if defined(__AVX512VL__)
  140. const Color r = _mm_rcp14_ps(a.m128);
  141. #else
  142. const Color r = _mm_rcp_ps(a.m128);
  143. #endif
  144. return _mm_add_ps(r,_mm_mul_ps(r, _mm_sub_ps(_mm_set1_ps(1.0f), _mm_mul_ps(a, r)))); // computes r + r * (1 - a * r)
  145. #endif //defined(__aarch64__)
  146. }
  147. __forceinline const Color rsqrt( const Color& a )
  148. {
  149. #if defined(__aarch64__)
  150. __m128 r = _mm_rsqrt_ps(a.m128);
  151. r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a.m128, r), r));
  152. r = vmulq_f32(r, vrsqrtsq_f32(vmulq_f32(a.m128, r), r));
  153. return r;
  154. #else
  155. #if defined(__AVX512VL__)
  156. __m128 r = _mm_rsqrt14_ps(a.m128);
  157. #else
  158. __m128 r = _mm_rsqrt_ps(a.m128);
  159. #endif
  160. return _mm_add_ps(_mm_mul_ps(_mm_set1_ps(1.5f),r), _mm_mul_ps(_mm_mul_ps(_mm_mul_ps(a, _mm_set1_ps(-0.5f)), r), _mm_mul_ps(r, r)));
  161. #endif //defined(__aarch64__)
  162. }
  163. __forceinline const Color sqrt ( const Color& a ) { return _mm_sqrt_ps(a.m128); }
  164. ////////////////////////////////////////////////////////////////////////////////
  165. /// Binary Operators
  166. ////////////////////////////////////////////////////////////////////////////////
  167. __forceinline const Color operator +( const Color& a, const Color& b ) { return _mm_add_ps(a.m128, b.m128); }
  168. __forceinline const Color operator -( const Color& a, const Color& b ) { return _mm_sub_ps(a.m128, b.m128); }
  169. __forceinline const Color operator *( const Color& a, const Color& b ) { return _mm_mul_ps(a.m128, b.m128); }
  170. __forceinline const Color operator *( const Color& a, const float b ) { return a * Color(b); }
  171. __forceinline const Color operator *( const float a, const Color& b ) { return Color(a) * b; }
  172. __forceinline const Color operator /( const Color& a, const Color& b ) { return a * rcp(b); }
  173. __forceinline const Color operator /( const Color& a, const float b ) { return a * rcp(b); }
  174. __forceinline const Color min( const Color& a, const Color& b ) { return _mm_min_ps(a.m128,b.m128); }
  175. __forceinline const Color max( const Color& a, const Color& b ) { return _mm_max_ps(a.m128,b.m128); }
  176. ////////////////////////////////////////////////////////////////////////////////
  177. /// Assignment Operators
  178. ////////////////////////////////////////////////////////////////////////////////
  179. __forceinline const Color operator+=(Color& a, const Color& b) { return a = a + b; }
  180. __forceinline const Color operator-=(Color& a, const Color& b) { return a = a - b; }
  181. __forceinline const Color operator*=(Color& a, const Color& b) { return a = a * b; }
  182. __forceinline const Color operator/=(Color& a, const Color& b) { return a = a / b; }
  183. __forceinline const Color operator*=(Color& a, const float b ) { return a = a * b; }
  184. __forceinline const Color operator/=(Color& a, const float b ) { return a = a / b; }
  185. ////////////////////////////////////////////////////////////////////////////////
  186. /// Reductions
  187. ////////////////////////////////////////////////////////////////////////////////
  188. __forceinline float reduce_add(const Color& v) { return v.r+v.g+v.b; }
  189. __forceinline float reduce_mul(const Color& v) { return v.r*v.g*v.b; }
  190. __forceinline float reduce_min(const Color& v) { return min(v.r,v.g,v.b); }
  191. __forceinline float reduce_max(const Color& v) { return max(v.r,v.g,v.b); }
  192. ////////////////////////////////////////////////////////////////////////////////
  193. /// Comparison Operators
  194. ////////////////////////////////////////////////////////////////////////////////
  195. __forceinline bool operator ==( const Color& a, const Color& b ) { return (_mm_movemask_ps(_mm_cmpeq_ps (a.m128, b.m128)) & 7) == 7; }
  196. __forceinline bool operator !=( const Color& a, const Color& b ) { return (_mm_movemask_ps(_mm_cmpneq_ps(a.m128, b.m128)) & 7) != 0; }
  197. __forceinline bool operator < ( const Color& a, const Color& b ) {
  198. if (a.r != b.r) return a.r < b.r;
  199. if (a.g != b.g) return a.g < b.g;
  200. if (a.b != b.b) return a.b < b.b;
  201. return false;
  202. }
  203. ////////////////////////////////////////////////////////////////////////////////
  204. /// Select
  205. ////////////////////////////////////////////////////////////////////////////////
  206. __forceinline const Color select( bool s, const Color& t, const Color& f ) {
  207. __m128 mask = s ? _mm_castsi128_ps(_mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128())) : _mm_setzero_ps();
  208. return blendv_ps(f, t, mask);
  209. }
  210. ////////////////////////////////////////////////////////////////////////////////
  211. /// Special Operators
  212. ////////////////////////////////////////////////////////////////////////////////
  213. /*! computes luminance of a color */
  214. __forceinline float luminance (const Color& a) { return madd(0.212671f,a.r,madd(0.715160f,a.g,0.072169f*a.b)); }
  215. /*! output operator */
  216. __forceinline embree_ostream operator<<(embree_ostream cout, const Color& a) {
  217. return cout << "(" << a.r << ", " << a.g << ", " << a.b << ")";
  218. }
  219. }
  220. #endif