/* Copyright (c) 2013 yvt This file is part of OpenSpades. OpenSpades is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenSpades is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenSpades. If not, see . */ #pragma once #include #if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) #define ENABLE_MMX 0 // FIXME: move this to the proper place #ifdef __SSE__ #define ENABLE_SSE 1 // FIXME: move this to the proper place #endif #ifdef __SSE2__ #define ENABLE_SSE2 1 // FIXME: move this to the proper place #endif #endif #ifndef ENABLE_SSE #define ENABLE_SSE 0 #endif #ifndef ENABLE_SSE2 #define ENABLE_SSE2 0 #endif #if ENABLE_SSE #include #endif #if ENABLE_SSE2 #include #endif #include #include #include // X11 macro #undef None namespace spades { namespace draw { enum class SWFeatureLevel { None, #if ENABLE_MMX MMX, #endif #if ENABLE_SSE SSE, #endif #if ENABLE_SSE2 SSE2, #endif }; static inline bool operator > (SWFeatureLevel a, SWFeatureLevel b) { return static_cast(a) > static_cast(b); } static inline bool operator >= (SWFeatureLevel a, SWFeatureLevel b) { return static_cast(a) >= static_cast(b); } SWFeatureLevel DetectFeatureLevel(); #if ENABLE_SSE // assume SSE availability (no checks!) static inline float fastDiv(float a, float b) { union { float tmp; __m128 mtmp; }; tmp = b; mtmp = _mm_rcp_ss(mtmp); return a * tmp; } static inline float fastRcp(float b) { union { float tmp; __m128 mtmp; }; tmp = b; mtmp = _mm_rcp_ss(mtmp); return tmp; } static inline float fastRSqrt(float v) { union { float tmp; __m128 mtmp; }; tmp = v; mtmp = _mm_rsqrt_ss(mtmp); return tmp; } #else static inline float fastDiv(float a, float b) { return a / b; } static inline float fastRcp(float b) { return 1.f / b; } static inline float fastRSqrt(float b) { return 1.f / sqrtf(b); } #endif static inline float fastSqrt(float s) { if(s == 0.f) return 0.f; return s * fastRSqrt(s); } } }