Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

392 lines
10 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: mcdmath.h
  3. *
  4. * Various useful defines and macros to do efficient floating-point
  5. * processing for MCD drivers.
  6. *
  7. * Copyright (c) 1996 Microsoft Corporation
  8. \**************************************************************************/
  9. #ifndef _MCDMATH_H
  10. #define _MCDMATH_H
  11. #define CASTINT(a) (*((LONG *)&(a)))
  12. #define ZERO (MCDFLOAT)0.0
  13. #define __MCDZERO ZERO
  14. #define __MCDONE (MCDFLOAT)1.0
  15. #define __MCDHALF (MCDFLOAT)0.5
  16. #define __MCDFIXSCALE (MCDFLOAT)65536.0
  17. #define __MCD_MAX_WINDOW_SIZE_LOG2 14
  18. #define __MCD_VERTEX_FIX_POINT (__MCD_MAX_WINDOW_SIZE_LOG2+1)
  19. #define __MCD_VERTEX_X_FIX (1 << __MCD_VERTEX_FIX_POINT)
  20. #define __MCD_VERTEX_Y_FIX __MCD_VERTEX_X_FIX
  21. #define __MCD_FLOAT_MANTISSA_BITS 23
  22. #define __MCD_FLOAT_MANTISSA_SHIFT 0
  23. #define __MCD_FLOAT_EXPONENT_BIAS 127
  24. #define __MCD_FLOAT_EXPONENT_BITS 8
  25. #define __MCD_FLOAT_EXPONENT_SHIFT 23
  26. #define __MCD_FLOAT_SIGN_SHIFT 31
  27. // If the MSB of a FP number is known then float-to-int conversion
  28. // becomes a simple shift and mask
  29. // The value must be positive
  30. #define __MCD_FIXED_FLOAT_TO_INT(flt, shift) \
  31. ((*(LONG *)&(flt) >> (shift)) & \
  32. ((1 << (__MCD_FLOAT_MANTISSA_BITS-(shift)))-1) | \
  33. (1 << (__MCD_FLOAT_MANTISSA_BITS-(shift))))
  34. // Same as above except without the MSB, which can be useful
  35. // for getting unbiased numbers when the bias is only the MSB
  36. // The value must be positive
  37. #define __MCD_FIXED_FLOAT_TO_INT_NO_MSB(flt, shift) \
  38. ((*(LONG *)&(flt) >> (shift)) & \
  39. ((1 << (__MCD_FLOAT_MANTISSA_BITS-(shift)))-1))
  40. // Produces the fixed-point form
  41. // The value must be positive
  42. #define __MCD_FIXED_FLOAT_TO_FIXED(flt) \
  43. ((*(LONG *)&(flt)) & \
  44. ((1 << (__MCD_FLOAT_MANTISSA_BITS))-1) | \
  45. (1 << (__MCD_FLOAT_MANTISSA_BITS)))
  46. #define __MCD_FIXED_FLOAT_TO_FIXED_NO_MSB(flt) \
  47. ((*(LONG *)&(flt)) & \
  48. ((1 << (__MCD_FLOAT_MANTISSA_BITS))-1))
  49. // The fixed-point fraction as an integer
  50. // The value must be positive
  51. #define __MCD_FIXED_FLOAT_FRACTION(flt, shift) \
  52. (*(LONG *)&(flt) & ((1 << (shift))-1))
  53. // Converts the fixed-point form to an IEEE float, but still typed
  54. // as an int because a cast to float would cause the compiler to do
  55. // an int-float conversion
  56. // The value must be positive
  57. #define __MCD_FIXED_TO_FIXED_FLOAT(fxed, shift) \
  58. ((fxed) & ((1 << (__MCD_FLOAT_MANTISSA_BITS))-1) | \
  59. ((__MCD_FLOAT_EXPONENT_BIAS+(shift)) << __MCD_FLOAT_EXPONENT_SHIFT))
  60. #ifdef _X86_
  61. #define __MCD_FLOAT_GTZ(flt) (*(LONG *)&(flt) > 0)
  62. #define __MCD_FLOAT_LTZ(flt) (*(LONG *)&(flt) < 0)
  63. #define __MCD_FLOAT_EQZ(flt) (*(LONG *)&(flt) == 0)
  64. #define __MCD_FLOAT_LEZ(flt) (*(LONG *)&(flt) <= 0)
  65. #define __MCD_FLOAT_NEQZ(flt) (*(LONG *)&(flt) != 0)
  66. #define __MCD_FLOAT_EQUAL(f1, f2) (*(LONG *)&(f1) == *(LONG *)&(f2))
  67. #define __MCD_FLOAT_NEQUAL(f1, f2) (*(LONG *)&(f1) != *(LONG *)&(f2))
  68. #else
  69. #define __MCD_FLOAT_GTZ(flt) ((flt) > __MCDZERO)
  70. #define __MCD_FLOAT_LTZ(flt) ((flt) < __MCDZERO)
  71. #define __MCD_FLOAT_EQZ(flt) ((flt) == __MCDZERO)
  72. #define __MCD_FLOAT_LEZ(flt) ((flt) <= __MCDZERO)
  73. #define __MCD_FLOAT_NEQZ(flt) ((flt) != __MCDZERO)
  74. #define __MCD_FLOAT_EQUAL(f1, f2) ((f1) == (f2))
  75. #define __MCD_FLOAT_NEQUAL(f1, f2) ((f1) != (f2))
  76. #endif // _X86_
  77. // Macro to start an FP divide in the FPU, used to overlap a
  78. // divide with integer operations
  79. // Can't just use C because it stores the result immediately
  80. #ifdef _X86_
  81. #define __MCD_FLOAT_SIMPLE_BEGIN_DIVIDE(num, den, result) \
  82. __asm fld num \
  83. __asm fdiv den
  84. #define __MCD_FLOAT_SIMPLE_END_DIVIDE(result) \
  85. __asm fstp DWORD PTR result
  86. //USED
  87. __inline void __MCD_FLOAT_BEGIN_DIVIDE(MCDFLOAT num, MCDFLOAT den,
  88. MCDFLOAT *result)
  89. {
  90. __asm fld num
  91. __asm fdiv den
  92. }
  93. __inline void __MCD_FLOAT_END_DIVIDE(MCDFLOAT *result)
  94. {
  95. __asm mov eax, result
  96. __asm fstp DWORD PTR [eax]
  97. }
  98. #else
  99. #define __MCD_FLOAT_SIMPLE_BEGIN_DIVIDE(num, den, result) \
  100. ((result) = (num)/(den))
  101. #define __MCD_FLOAT_SIMPLE_END_DIVIDE(result)
  102. #define __MCD_FLOAT_BEGIN_DIVIDE(num, den, result) (*(result) = (num)/(den))
  103. #define __MCD_FLOAT_END_DIVIDE(result)
  104. #endif // _X86_
  105. #ifdef _X86_
  106. #pragma warning(disable:4035) // Function doesn't return a value
  107. // Convert float to int 15.16
  108. __inline LONG __fastcall FLT_TO_FIX(
  109. float a)
  110. {
  111. LARGE_INTEGER li;
  112. __asm {
  113. mov eax, a
  114. test eax, 07fffffffh
  115. jz RetZero
  116. add eax, 08000000h
  117. mov a, eax
  118. fld a
  119. fistp li
  120. mov eax, DWORD PTR li
  121. jmp Done
  122. RetZero:
  123. xor eax, eax
  124. Done:
  125. }
  126. }
  127. // Convert float to int 15.16, can cause overflow exceptions
  128. __inline LONG __fastcall UNSAFE_FLT_TO_FIX(
  129. float a)
  130. {
  131. LONG l;
  132. __asm {
  133. mov eax, a
  134. test eax, 07fffffffh
  135. jz RetZero
  136. add eax, 08000000h
  137. mov a, eax
  138. fld a
  139. fistp l
  140. mov eax, l
  141. jmp Done
  142. RetZero:
  143. xor eax, eax
  144. Done:
  145. }
  146. }
  147. // Convert float to int 0.31
  148. __inline LONG __fastcall FLT_FRACTION(
  149. float a)
  150. {
  151. LARGE_INTEGER li;
  152. __asm {
  153. mov eax, a
  154. test eax, 07fffffffh
  155. jz RetZero
  156. add eax, 0f800000h
  157. mov a, eax
  158. fld a
  159. fistp li
  160. mov eax, DWORD PTR li
  161. jmp Done
  162. RetZero:
  163. xor eax, eax
  164. Done:
  165. }
  166. }
  167. // Convert float to int 0.31, can cause overflow exceptions
  168. __inline LONG __fastcall UNSAFE_FLT_FRACTION(
  169. float a)
  170. {
  171. LONG l;
  172. __asm {
  173. mov eax, a
  174. test eax, 07fffffffh
  175. jz RetZero
  176. add eax, 0f800000h
  177. mov a, eax
  178. fld a
  179. fistp l
  180. mov eax, l
  181. jmp Done
  182. RetZero:
  183. xor eax, eax
  184. Done:
  185. }
  186. }
  187. #pragma warning(default:4035) // Function doesn't return a value
  188. // Convert float*scale to int
  189. __inline LONG __fastcall FLT_TO_FIX_SCALE(
  190. float a,
  191. float b)
  192. {
  193. LARGE_INTEGER li;
  194. __asm {
  195. fld a
  196. fmul b
  197. fistp li
  198. }
  199. return li.LowPart;
  200. }
  201. #define FLT_TO_UCHAR_SCALE(value_in, scale) \
  202. ((UCHAR)FLT_TO_FIX_SCALE(value_in, scale))
  203. __inline LONG __fastcall FTOL(
  204. float a)
  205. {
  206. LARGE_INTEGER li;
  207. _asm {
  208. fld a
  209. fistp li
  210. }
  211. return li.LowPart;
  212. }
  213. // Can cause overflow exceptions
  214. __inline LONG __fastcall UNSAFE_FTOL(
  215. float a)
  216. {
  217. LONG l;
  218. _asm {
  219. fld a
  220. fistp l
  221. }
  222. return l;
  223. }
  224. // Requires R-G-B to be FP stack 2-1-0
  225. // Requires gc in edx
  226. #define FLT_STACK_RGB_TO_GC_FIXED(rOffset, gOffset, bOffset) \
  227. __asm fld __glVal65536 \
  228. __asm fmul st(3), st(0) \
  229. __asm fmul st(2), st(0) \
  230. __asm fmulp st(1), st(0) \
  231. __asm fistp DWORD PTR [edx+bOffset] \
  232. __asm fistp DWORD PTR [edx+gOffset] \
  233. __asm fistp DWORD PTR [edx+rOffset]
  234. #define CHOP_ROUND_ON() \
  235. WORD cwSave; \
  236. WORD cwTemp; \
  237. \
  238. __asm { \
  239. _asm wait \
  240. _asm fstcw cwSave \
  241. _asm wait \
  242. _asm mov ax, cwSave \
  243. _asm or ah,0xc \
  244. _asm and ah,0xfc \
  245. _asm mov cwTemp,ax \
  246. _asm fldcw cwTemp \
  247. }
  248. #define CHOP_ROUND_OFF() \
  249. __asm { \
  250. _asm wait \
  251. _asm fldcw cwSave \
  252. }
  253. #else // _X86_
  254. #define FTOL(value) \
  255. ((GLint)(value))
  256. #define UNSAFE_FTOL(value) \
  257. FTOL(value)
  258. #define FLT_TO_FIX_SCALE(value_in, scale) \
  259. ((GLint)((MCDFLOAT)(value_in) * scale))
  260. #define FLT_TO_UCHAR_SCALE(value_in, scale) \
  261. ((UCHAR)((GLint)((MCDFLOAT)(value_in) * scale)))
  262. #define FLT_TO_FIX(value_in) \
  263. ((GLint)((MCDFLOAT)(value_in) * __MCDFIXSCALE))
  264. #define UNSAFE_FLT_TO_FIX(value_in) \
  265. FLT_TO_FIX(value_in)
  266. #define FLT_FRACTION(f) \
  267. FTOL((f) * __glVal2147483648)
  268. #define UNSAFE_FLT_FRACTION(f) \
  269. FLT_FRACTION(f)
  270. #define CHOP_ROUND_ON()
  271. #define CHOP_ROUND_OFF()
  272. #define ASSERT_CHOP_ROUND()
  273. #endif //_X86_
  274. #define __MCD_VERTEX_FRAC_BITS \
  275. (__MCD_FLOAT_MANTISSA_BITS-__MCD_VERTEX_FIX_POINT)
  276. //USED
  277. #define __MCD_VERTEX_FRAC_HALF \
  278. (1 << (__MCD_VERTEX_FRAC_BITS-1))
  279. #define __MCD_VERTEX_FRAC_ONE \
  280. (1 << __MCD_VERTEX_FRAC_BITS)
  281. // Converts a floating-point window coordinate to integer
  282. #define __MCD_VERTEX_FLOAT_TO_INT(windowCoord) \
  283. __MCD_FIXED_FLOAT_TO_INT(windowCoord, __MCD_VERTEX_FRAC_BITS)
  284. //USED
  285. // To fixed point
  286. #define __MCD_VERTEX_FLOAT_TO_FIXED(windowCoord) \
  287. __MCD_FIXED_FLOAT_TO_FIXED(windowCoord)
  288. // And back
  289. #define __MCD_VERTEX_FIXED_TO_FLOAT(fxWindowCoord) \
  290. __MCD_FIXED_TO_FIXED_FLOAT(fxWindowCoord, __MCD_VERTEX_FRAC_BITS)
  291. //USED
  292. // Fixed-point to integer
  293. #define __MCD_VERTEX_FIXED_TO_INT(fxWindowCoord) \
  294. ((fxWindowCoord) >> __MCD_VERTEX_FRAC_BITS)
  295. // Returns the fraction from a FP window coordinate as an N
  296. // bit integer, where N depends on the FP mantissa size and the
  297. // FIX size
  298. #define __MCD_VERTEX_FLOAT_FRACTION(windowCoord) \
  299. __MCD_FIXED_FLOAT_FRACTION(windowCoord, __MCD_VERTEX_FRAC_BITS)
  300. // Scale the fraction to 2^31 for step values
  301. #define __MCD_VERTEX_PROMOTE_FRACTION(frac) \
  302. ((frac) << (31-__MCD_VERTEX_FRAC_BITS))
  303. #define __MCD_VERTEX_PROMOTED_FRACTION(windowCoord) \
  304. __MCD_VERTEX_PROMOTE_FRACTION(__MCD_VERTEX_FLOAT_FRACTION(windowCoord))
  305. // Compare two window coordinates. Since window coordinates
  306. // are fixed-point numbers, they can be compared directly as
  307. // integers
  308. #define __MCD_VERTEX_COMPARE(a, op, b) \
  309. ((*(LONG *)&(a)) op (*(LONG *)&(b)))
  310. #define SNAPCOORD(value, intValue)\
  311. intValue = __MCD_VERTEX_FIXED_TO_INT(__MCD_VERTEX_FLOAT_TO_FIXED(value)+\
  312. __MCD_VERTEX_FRAC_HALF);
  313. // match the "ALMOST_HALF" value in SGI sample code (triflat.c)
  314. #define __MCD_ALMOST_HALF ((float) ((float)0x7fff/(float)0x10000))
  315. #endif // _MCDMATH_H