//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // //=====================================================================================// #ifndef _MATH_PFNS_H_ #define _MATH_PFNS_H_ #if defined(_X360) #include #endif #if !defined(_X360) // These globals are initialized by mathlib and redirected based on available // fpu features extern float (*pfSqrt)(float x); extern float (*pfRSqrt)(float x); extern float (*pfRSqrtFast)(float x); extern void (*pfFastSinCos)(float x, float *s, float *c); extern float (*pfFastCos)(float x); // The following are not declared as macros because they are often used in // limiting situations, and sometimes the compiler simply refuses to inline them // for some reason #define FastSqrt(x) (*pfSqrt)(x) #define FastRSqrt(x) (*pfRSqrt)(x) #define FastRSqrtFast(x) (*pfRSqrtFast)(x) #define FastSinCos(x, s, c) (*pfFastSinCos)(x, s, c) #define FastCos(x) (*pfFastCos)(x) #if defined(__i386__) || defined(_M_IX86) // On x86, the inline FPU or SSE sqrt instruction is faster than // the overhead of setting up a function call and saving/restoring // the FPU or SSE register state and can be scheduled better, too. #undef FastSqrt #define FastSqrt(x) ::sqrtf(x) #endif #endif // !_X360 #if defined(_X360) FORCEINLINE float _VMX_Sqrt(float x) { return __fsqrts(x); } FORCEINLINE float _VMX_RSqrt(float x) { float rroot = __frsqrte(x); // Single iteration NewtonRaphson on reciprocal square root estimate return (0.5f * rroot) * (3.0f - (x * rroot) * rroot); } FORCEINLINE float _VMX_RSqrtFast(float x) { return __frsqrte(x); } FORCEINLINE void _VMX_SinCos(float a, float *pS, float *pC) { XMScalarSinCos(pS, pC, a); } FORCEINLINE float _VMX_Cos(float a) { return XMScalarCos(a); } // the 360 has fixed hw and calls directly #define FastSqrt(x) _VMX_Sqrt(x) #define FastRSqrt(x) _VMX_RSqrt(x) #define FastRSqrtFast(x) _VMX_RSqrtFast(x) #define FastSinCos(x, s, c) _VMX_SinCos(x, s, c) #define FastCos(x) _VMX_Cos(x) #endif // _X360 #endif // _MATH_PFNS_H_