GSSoftVertex.h
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:13k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* 
  2.  * Copyright (C) 2003-2005 Gabest
  3.  * http://www.gabest.org
  4.  *
  5.  *  This Program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2, or (at your option)
  8.  *  any later version.
  9.  *   
  10.  *  This Program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13.  *  GNU General Public License for more details.
  14.  *   
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with GNU Make; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  18.  *  http://www.gnu.org/copyleft/gpl.html
  19.  *
  20.  */
  21. #pragma once
  22. //
  23. // GSSoftVertexFP
  24. //
  25. extern const __m128i _80000000, _4b000000, _3f800000;
  26. __declspec(align(16)) union GSSoftVertexFP
  27. {
  28. class __declspec(novtable) Scalar
  29. {
  30. float val;
  31. public:
  32. Scalar() {}
  33. explicit Scalar(float f) {val = f;}
  34. explicit Scalar(int i) {val = (float)i;}
  35. float Value() const {return val;}
  36. #if _M_IX86_FP >= 2 || defined(_M_AMD64)
  37. void sat() {_mm_store_ss(&val, _mm_min_ss(_mm_max_ss(_mm_set_ss(val), _mm_setzero_ps()), _mm_set_ss(255)));}
  38. void rcp() {_mm_store_ss(&val, _mm_rcp_ss(_mm_set_ss(val)));}
  39. #else
  40. void sat() {val = val < 0 ? 0 : val > 255 ? 255 : val;}
  41. void rcp() {val = 1.0f / val;}
  42. #endif
  43. void abs() {val = fabs(val);}
  44. Scalar floor_s() const {return Scalar(floor(val));}
  45. int floor_i() const {return (int)floor(val);}
  46. Scalar ceil_s() const {return Scalar(-floor(-val));}
  47. int ceil_i() const {return -(int)floor(-val);}
  48. void operator = (float f) {val = f;}
  49. void operator = (int i) {val = (float)i;}
  50. operator float() const {return val;}
  51. operator int() const {return (int)val;}
  52. void operator += (const Scalar& s) {val += s.val;}
  53. void operator -= (const Scalar& s) {val -= s.val;}
  54. void operator *= (const Scalar& s) {val *= s.val;}
  55. void operator /= (const Scalar& s) {val /= s.val;}
  56. friend Scalar operator + (const Scalar& s1, const Scalar& s2) {return Scalar(s1.val + s2.val);}
  57. friend Scalar operator - (const Scalar& s1, const Scalar& s2) {return Scalar(s1.val - s2.val);}
  58. friend Scalar operator * (const Scalar& s1, const Scalar& s2) {return Scalar(s1.val * s2.val);}
  59. friend Scalar operator / (const Scalar& s1, const Scalar& s2) {return Scalar(s1.val / s2.val);}
  60. friend Scalar operator + (const Scalar& s, int i) {return Scalar(s.val + i);}
  61. friend Scalar operator - (const Scalar& s, int i) {return Scalar(s.val - i);}
  62. friend Scalar operator * (const Scalar& s, int i) {return Scalar(s.val * i);}
  63. friend Scalar operator / (const Scalar& s, int i) {return Scalar(s.val / i);}
  64. friend Scalar operator << (const Scalar& s, int i) {return Scalar(s.val * (1<<i));}
  65. friend Scalar operator >> (const Scalar& s, int i) {return Scalar(s.val / (1<<i));}
  66. friend bool operator == (const Scalar& s1, const Scalar& s2) {return s1.val == s2.val;}
  67. friend bool operator <= (const Scalar& s1, const Scalar& s2) {return s1.val <= s2.val;}
  68. friend bool operator < (const Scalar& s1, const Scalar& s2) {return s1.val < s2.val;}
  69. };
  70. __declspec(align(16)) class __declspec(novtable) Vector
  71. {
  72. public:
  73. union
  74. {
  75. union {struct {Scalar x, y, z, q;}; struct {Scalar r, g, b, a;};};
  76. union {struct {Scalar v[4];}; struct {Scalar c[4];};};
  77. #if _M_IX86_FP >= 2 || defined(_M_AMD64)
  78. union {__m128 xyzq; __m128 rgba;};
  79. #endif
  80. };
  81. Vector() {}
  82. Vector(const Vector& v) {*this = v;}
  83. Vector(Scalar s) {*this = s;}
  84. Vector(Scalar s0, Scalar s1, Scalar s2, Scalar s3) {x = s0; y = s1; z = s2; q = s3;}
  85. explicit Vector(DWORD dw) {*this = dw;}
  86. #if _M_IX86_FP >= 2 || defined(_M_AMD64)
  87. Vector(__m128 f0123) {*this = f0123;}
  88. #endif
  89. #if _M_IX86_FP >= 2 || defined(_M_AMD64)
  90. void operator = (const Vector& v) {xyzq = v.xyzq;}
  91. void operator = (Scalar s) {xyzq = _mm_set1_ps(s);}
  92. void operator = (__m128 f0123) {xyzq = f0123;}
  93. operator __m128() const {return xyzq;}
  94. void operator = (DWORD dw) {__m128i zero = _mm_setzero_si128(); xyzq = _mm_cvtepi32_ps(_mm_unpacklo_epi16(_mm_unpacklo_epi8(_mm_cvtsi32_si128(dw), zero), zero));}
  95. operator DWORD() const {__m128i r0 = _mm_cvttps_epi32(xyzq); r0 = _mm_packs_epi32(r0, r0); r0 = _mm_packus_epi16(r0, r0); return (DWORD)_mm_cvtsi128_si32(r0);}
  96. operator UINT64() const {__m128i r0 = _mm_cvttps_epi32(xyzq); r0 = _mm_packs_epi32(r0, r0); return *(UINT64*)&r0;}
  97. void sat() {xyzq = _mm_min_ps(_mm_max_ps(xyzq, _mm_setzero_ps()), _mm_set1_ps(255));}
  98. void rcp() {xyzq = _mm_rcp_ps(xyzq);}
  99. Vector floor()
  100. {
  101. __m128 sign = _mm_and_ps(xyzq, *(__m128*)&_80000000);
  102. __m128 r0 = _mm_or_ps(sign, *(__m128*)&_4b000000);
  103. __m128 r1 = _mm_sub_ps(_mm_add_ps(xyzq, r0), r0);
  104. __m128 r2 = _mm_sub_ps(r1, xyzq);
  105. __m128 r3 = _mm_and_ps(_mm_cmpnle_ps(r2, sign), *(__m128*)&_3f800000);
  106. __m128 r4 = _mm_sub_ps(r1, r3);
  107. return r4;
  108. }
  109. void operator += (const Vector& v) {xyzq = _mm_add_ps(xyzq, v);}
  110. void operator -= (const Vector& v) {xyzq = _mm_sub_ps(xyzq, v);}
  111. void operator *= (const Vector& v) {xyzq = _mm_mul_ps(xyzq, v);}
  112. void operator /= (const Vector& v) {xyzq = _mm_div_ps(xyzq, v);}
  113. #else
  114. void operator = (const Vector& v) {x = v.x; y = v.y; z = v.z; q = v.q;}
  115. void operator = (Scalar s) {x = y = z = q = s;}
  116. void operator = (DWORD dw)
  117. {
  118. x = Scalar((int)((dw>>0)&0xff));
  119. y = Scalar((int)((dw>>8)&0xff));
  120. z = Scalar((int)((dw>>16)&0xff));
  121. q = Scalar((int)((dw>>24)&0xff));
  122. }
  123. operator DWORD() const
  124. {
  125. return (DWORD)(
  126. (((DWORD)(int)x&0xff)<<0) |
  127. (((DWORD)(int)y&0xff)<<8) |
  128. (((DWORD)(int)z&0xff)<<16) |
  129. (((DWORD)(int)q&0xff)<<24));
  130. }
  131. operator UINT64() const
  132. {
  133. return (DWORD)(
  134. (((UINT64)(int)x&0xffff)<<0) |
  135. (((UINT64)(int)y&0xffff)<<16) |
  136. (((UINT64)(int)z&0xffff)<<32) |
  137. (((UINT64)(int)q&0xffff)<<48));
  138. }
  139. void sat() {x.sat(); y.sat(); z.sat(); q.sat();}
  140. void rcp() {x.rcp(); y.rcp(); z.rcp(); q.rcp();}
  141. Vector floor() {return Vector(x.floor_s(), y.floor_s(), z.floor_s(), q.floor_s());}
  142. void operator += (const Vector& v) {*this = *this + v;}
  143. void operator -= (const Vector& v) {*this = *this - v;}
  144. void operator *= (const Vector& v) {*this = *this * v;}
  145. void operator /= (const Vector& v) {*this = *this / v;}
  146. #endif
  147. friend Vector operator + (const Vector& v1, const Vector& v2);
  148. friend Vector operator - (const Vector& v1, const Vector& v2);
  149. friend Vector operator * (const Vector& v1, const Vector& v2);
  150. friend Vector operator / (const Vector& v1, const Vector& v2);
  151. friend Vector operator + (const Vector& v, Scalar s);
  152. friend Vector operator - (const Vector& v, Scalar s);
  153. friend Vector operator * (const Vector& v, Scalar s);
  154. friend Vector operator / (const Vector& v, Scalar s);
  155. };
  156. struct {__declspec(align(16)) Vector c, p, t;};
  157. struct {__declspec(align(16)) Vector sv[3];};
  158. struct {__declspec(align(16)) Scalar s[12];};
  159. GSSoftVertexFP() {}
  160. GSSoftVertexFP(const GSSoftVertexFP& v) {*this = v;}
  161. void operator = (const GSSoftVertexFP& v) {c = v.c; p = v.p; t = v.t;}
  162. void operator += (const GSSoftVertexFP& v) {c += v.c; p += v.p; t += v.t;}
  163. operator CPoint() const {return CPoint((int)p.x, (int)p.y);}
  164. __forceinline DWORD GetZ() const 
  165. {
  166. ASSERT((float)p.z >= 0 && (float)p.q >= 0);
  167. #if _M_IX86_FP >= 2 || defined(_M_AMD64)
  168. __m128 z = _mm_shuffle_ps(p, p, _MM_SHUFFLE(2,2,2,2));
  169. __m128 q = _mm_shuffle_ps(p, p, _MM_SHUFFLE(3,3,3,3));
  170. // TODO: check if our floor is faster than doing ss->si->ss
  171. int zh = _mm_cvttss_si32(z);
  172. __m128 zhi = _mm_cvtsi32_ss(zhi, zh);
  173. __m128 zhf = _mm_mul_ss(_mm_sub_ss(z, zhi), _mm_set_ss(65536));
  174. int zl = _mm_cvtss_si32(_mm_add_ss(zhf, q));
  175. return ((DWORD)zh << 16) + (DWORD)zl;
  176. #else
  177. // return ((DWORD)(int)p.z << 16) + (DWORD)(int)((p.z - p.z.floor_s())*65536 + p.q);
  178. int z = (int)p.z;
  179. return ((DWORD)z << 16) + (DWORD)(((float)p.z - z)*65536 + (float)p.q);
  180. #endif
  181. }
  182. };
  183. #if _M_IX86_FP >= 2 || defined(_M_AMD64)
  184. __forceinline GSSoftVertexFP::Vector operator + (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(_mm_add_ps(v1, v2));}
  185. __forceinline GSSoftVertexFP::Vector operator - (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(_mm_sub_ps(v1, v2));}
  186. __forceinline GSSoftVertexFP::Vector operator * (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(_mm_mul_ps(v1, v2));}
  187. __forceinline GSSoftVertexFP::Vector operator / (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(_mm_div_ps(v1, v2));}
  188. __forceinline GSSoftVertexFP::Vector operator + (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(_mm_add_ps(v, _mm_set1_ps(s)));}
  189. __forceinline GSSoftVertexFP::Vector operator - (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(_mm_sub_ps(v, _mm_set1_ps(s)));}
  190. __forceinline GSSoftVertexFP::Vector operator * (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(_mm_mul_ps(v, _mm_set1_ps(s)));}
  191. __forceinline GSSoftVertexFP::Vector operator / (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(_mm_div_ps(v, _mm_set1_ps(s)));}
  192. __forceinline GSSoftVertexFP::Vector operator << (const GSSoftVertexFP::Vector& v, int i) {return GSSoftVertexFP::Vector(_mm_mul_ps(v, _mm_set1_ps((float)(1 << i))));}
  193. __forceinline GSSoftVertexFP::Vector operator >> (const GSSoftVertexFP::Vector& v, int i) {return GSSoftVertexFP::Vector(_mm_mul_ps(v, _mm_set1_ps(1.0f / (1 << i))));}
  194. #else
  195. __forceinline GSSoftVertexFP::Vector operator + (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.q + v2.q);}
  196. __forceinline GSSoftVertexFP::Vector operator - (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.q - v2.q);}
  197. __forceinline GSSoftVertexFP::Vector operator * (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z, v1.q * v2.q);}
  198. __forceinline GSSoftVertexFP::Vector operator / (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z, v1.q / v2.q);}
  199. __forceinline GSSoftVertexFP::Vector operator + (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(v.x + s, v.y + s, v.z + s, v.q + s);}
  200. __forceinline GSSoftVertexFP::Vector operator - (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(v.x - s, v.y - s, v.z - s, v.q - s);}
  201. __forceinline GSSoftVertexFP::Vector operator * (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(v.x * s, v.y * s, v.z * s, v.q * s);}
  202. __forceinline GSSoftVertexFP::Vector operator / (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(v.x / s, v.y / s, v.z / s, v.q / s);}
  203. __forceinline GSSoftVertexFP::Vector operator << (const GSSoftVertexFP::Vector& v, int i) {return GSSoftVertexFP::Vector(v.x << i, v.y << i, v.z << i, v.q << i);}
  204. __forceinline GSSoftVertexFP::Vector operator >> (const GSSoftVertexFP::Vector& v, int i) {return GSSoftVertexFP::Vector(v.x >> i, v.y >> i, v.z >> i, v.q >> i);}
  205. #endif
  206. //
  207. template <class Vertex>
  208. __forceinline Vertex operator + (const Vertex& v1, const Vertex& v2)
  209. {
  210. Vertex v0;
  211. v0.c = v1.c + v2.c;
  212. v0.p = v1.p + v2.p;
  213. v0.t = v1.t + v2.t;
  214. return v0;
  215. }
  216. template <class Vertex>
  217. __forceinline Vertex operator - (const Vertex& v1, const Vertex& v2)
  218. {
  219. Vertex v0;
  220. v0.c = v1.c - v2.c;
  221. v0.p = v1.p - v2.p;
  222. v0.t = v1.t - v2.t;
  223. return v0;
  224. }
  225. template <class Vertex>
  226. __forceinline Vertex operator * (const Vertex& v, typename Vertex::Scalar s)
  227. {
  228. Vertex v0;
  229. Vertex::Vector vs(s);
  230. v0.c = v.c * vs;
  231. v0.p = v.p * vs;
  232. v0.t = v.t * vs;
  233. return v0;
  234. }
  235. template <class Vertex>
  236. __forceinline Vertex operator / (const Vertex& v, typename Vertex::Scalar s)
  237. {
  238. Vertex v0;
  239. Vertex::Vector vs(s);
  240. v0.c = v.c / vs;
  241. v0.p = v.p / vs;
  242. v0.t = v.t / vs;
  243. return v0;
  244. }
  245. template <class Vertex>
  246. __forceinline void Exchange(Vertex* RESTRICT v1, Vertex* RESTRICT v2)
  247. {
  248. typename Vertex::Vector c = v1->c, p = v1->p, t = v1->t;
  249. v1->c = v2->c; v1->p = v2->p; v1->t = v2->t;
  250. v2->c = c; v2->p = p; v2->t = t;
  251. }