X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fx86%2Fcommon_x86.c;h=1c8640514ab64563f140cda9a83a1958e90c8ab9;hb=951bf44a56d3236550d4d910741c10d5e0d1311b;hp=5321547935878e4291666ae17df344900c6dd98d;hpb=3a40dee3eb5151a282ce831b67427f3aa625de28;p=mesa.git diff --git a/src/mesa/x86/common_x86.c b/src/mesa/x86/common_x86.c index 53215479358..1c8640514ab 100644 --- a/src/mesa/x86/common_x86.c +++ b/src/mesa/x86/common_x86.c @@ -1,6 +1,5 @@ /* * Mesa 3-D graphics library - * Version: 6.5.1 * * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * @@ -17,9 +16,10 @@ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ /** @@ -42,26 +42,38 @@ #include #include #endif -#if defined(USE_SSE_ASM) && defined(__OpenBSD__) +#if defined(USE_SSE_ASM) && (defined(__OpenBSD__) || defined(__NetBSD__)) #include #include #include #endif +#if defined(USE_X86_64_ASM) +#include +#if !defined(bit_SSE4_1) && defined(bit_SSE41) +/* XXX: clang defines bit_SSE41 instead of bit_SSE4_1 */ +#define bit_SSE4_1 bit_SSE41 +#elif !defined(bit_SSE4_1) && !defined(bit_SSE41) +#define bit_SSE4_1 0x00080000 +#endif +#endif #include "main/imports.h" #include "common_x86_asm.h" -int _mesa_x86_cpu_features = 0; +/** Bitmask of X86_FEATURE_x bits */ +int _mesa_x86_cpu_features = 0x0; + +static int detection_debug = GL_FALSE; /* No reason for this to be public. */ -extern GLuint _ASMAPI _mesa_x86_has_cpuid(void); -extern void _ASMAPI _mesa_x86_cpuid(GLuint op, GLuint *reg_eax, GLuint *reg_ebx, GLuint *reg_ecx, GLuint *reg_edx); -extern GLuint _ASMAPI _mesa_x86_cpuid_eax(GLuint op); -extern GLuint _ASMAPI _mesa_x86_cpuid_ebx(GLuint op); -extern GLuint _ASMAPI _mesa_x86_cpuid_ecx(GLuint op); -extern GLuint _ASMAPI _mesa_x86_cpuid_edx(GLuint op); +extern GLuint _mesa_x86_has_cpuid(void); +extern void _mesa_x86_cpuid(GLuint op, GLuint *reg_eax, GLuint *reg_ebx, GLuint *reg_ecx, GLuint *reg_edx); +extern GLuint _mesa_x86_cpuid_eax(GLuint op); +extern GLuint _mesa_x86_cpuid_ebx(GLuint op); +extern GLuint _mesa_x86_cpuid_ecx(GLuint op); +extern GLuint _mesa_x86_cpuid_edx(GLuint op); #if defined(USE_SSE_ASM) @@ -73,10 +85,13 @@ extern GLuint _ASMAPI _mesa_x86_cpuid_edx(GLuint op); * kernels provide full SSE support on all processors that expose SSE via * the CPUID mechanism. */ + +/* These are assembly functions: */ extern void _mesa_test_os_sse_support( void ); extern void _mesa_test_os_sse_exception_support( void ); -#if defined(WIN32) + +#if defined(_WIN32) #ifndef STATUS_FLOAT_MULTIPLE_TRAPS # define STATUS_FLOAT_MULTIPLE_TRAPS (0xC00002B5L) #endif @@ -104,10 +119,14 @@ static LONG WINAPI ExceptionFilter(LPEXCEPTION_POINTERS exp) return EXCEPTION_CONTINUE_EXECUTION; } -#endif /* WIN32 */ +#endif /* _WIN32 */ -static void check_os_sse_support( void ) +/** + * Check if SSE is supported. + * If not, turn off the X86_FEATURE_XMM flag in _mesa_x86_cpu_features. + */ +void _mesa_check_os_sse_support( void ) { #if defined(__FreeBSD__) { @@ -139,7 +158,7 @@ static void check_os_sse_support( void ) if (ret || !enabled) _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM); } -#elif defined(WIN32) +#elif defined(_WIN32) LPTOP_LEVEL_EXCEPTION_FILTER oldFilter; /* Install our ExceptionFilter */ @@ -180,23 +199,40 @@ static void check_os_sse_support( void ) #else /* Do nothing on other platforms for now. */ - _mesa_debug(NULL, "Not testing OS support for SSE, leaving enabled.\n"); + if (detection_debug) + _mesa_debug(NULL, "Not testing OS support for SSE, leaving enabled.\n"); #endif /* __FreeBSD__ */ } #endif /* USE_SSE_ASM */ -void _mesa_init_all_x86_transform_asm( void ) +/** + * Initialize the _mesa_x86_cpu_features bitfield. + * This is a no-op if called more than once. + */ +void +_mesa_get_x86_features(void) { + static int called = 0; + + if (called) + return; + + called = 1; + #ifdef USE_X86_ASM - _mesa_x86_cpu_features = 0; + _mesa_x86_cpu_features = 0x0; + + if (getenv( "MESA_NO_ASM")) { + return; + } if (!_mesa_x86_has_cpuid()) { _mesa_debug(NULL, "CPUID not detected\n"); } else { - GLuint cpu_features; + GLuint cpu_features, cpu_features_ecx; GLuint cpu_ext_features; GLuint cpu_ext_info; char cpu_vendor[13]; @@ -206,10 +242,12 @@ void _mesa_init_all_x86_transform_asm( void ) _mesa_x86_cpuid(0, &result, (GLuint *)(cpu_vendor + 0), (GLuint *)(cpu_vendor + 8), (GLuint *)(cpu_vendor + 4)); cpu_vendor[12] = '\0'; - _mesa_debug(NULL, "CPU vendor: %s\n", cpu_vendor); + if (detection_debug) + _mesa_debug(NULL, "CPU vendor: %s\n", cpu_vendor); /* get cpu features */ cpu_features = _mesa_x86_cpuid_edx(1); + cpu_features_ecx = _mesa_x86_cpuid_ecx(1); if (cpu_features & X86_CPU_FPU) _mesa_x86_cpu_features |= X86_FEATURE_FPU; @@ -226,6 +264,8 @@ void _mesa_init_all_x86_transform_asm( void ) _mesa_x86_cpu_features |= X86_FEATURE_XMM; if (cpu_features & X86_CPU_XMM2) _mesa_x86_cpu_features |= X86_FEATURE_XMM2; + if (cpu_features_ecx & X86_CPU_SSE4_1) + _mesa_x86_cpu_features |= X86_FEATURE_SSE4_1; #endif /* query extended cpu features */ @@ -258,24 +298,18 @@ void _mesa_init_all_x86_transform_asm( void ) _mesa_x86_cpuid(0x80000002+ofs, (GLuint *)(cpu_name + (16*ofs)+0), (GLuint *)(cpu_name + (16*ofs)+4), (GLuint *)(cpu_name + (16*ofs)+8), (GLuint *)(cpu_name + (16*ofs)+12)); cpu_name[48] = '\0'; /* the name should be NULL terminated, but just to be sure */ - _mesa_debug(NULL, "CPU name: %s\n", cpu_name); + if (detection_debug) + _mesa_debug(NULL, "CPU name: %s\n", cpu_name); } } } - - if ( _mesa_getenv( "MESA_NO_ASM" ) ) { - _mesa_x86_cpu_features = 0; - } - - if ( _mesa_x86_cpu_features ) { - _mesa_init_x86_transform_asm(); - } #ifdef USE_MMX_ASM if ( cpu_has_mmx ) { - if ( _mesa_getenv( "MESA_NO_MMX" ) == 0 ) { - _mesa_debug(NULL, "MMX cpu detected.\n"); + if ( getenv( "MESA_NO_MMX" ) == 0 ) { + if (detection_debug) + _mesa_debug(NULL, "MMX cpu detected.\n"); } else { _mesa_x86_cpu_features &= ~(X86_FEATURE_MMX); } @@ -284,9 +318,9 @@ void _mesa_init_all_x86_transform_asm( void ) #ifdef USE_3DNOW_ASM if ( cpu_has_3dnow ) { - if ( _mesa_getenv( "MESA_NO_3DNOW" ) == 0 ) { - _mesa_debug(NULL, "3DNow! cpu detected.\n"); - _mesa_init_3dnow_transform_asm(); + if ( getenv( "MESA_NO_3DNOW" ) == 0 ) { + if (detection_debug) + _mesa_debug(NULL, "3DNow! cpu detected.\n"); } else { _mesa_x86_cpu_features &= ~(X86_FEATURE_3DNOW); } @@ -295,13 +329,11 @@ void _mesa_init_all_x86_transform_asm( void ) #ifdef USE_SSE_ASM if ( cpu_has_xmm ) { - if ( _mesa_getenv( "MESA_NO_SSE" ) == 0 ) { - _mesa_debug(NULL, "SSE cpu detected.\n"); - if ( _mesa_getenv( "MESA_FORCE_SSE" ) == 0 ) { - check_os_sse_support(); - } - if ( cpu_has_xmm ) { - _mesa_init_sse_transform_asm(); + if ( getenv( "MESA_NO_SSE" ) == 0 ) { + if (detection_debug) + _mesa_debug(NULL, "SSE cpu detected.\n"); + if ( getenv( "MESA_FORCE_SSE" ) == 0 ) { + _mesa_check_os_sse_support(); } } else { _mesa_debug(NULL, "SSE cpu detected, but switched off by user.\n"); @@ -309,6 +341,21 @@ void _mesa_init_all_x86_transform_asm( void ) } } #endif -#endif -} +#elif defined(USE_X86_64_ASM) + { + unsigned int eax, ebx, ecx, edx; + + /* Always available on x86-64. */ + _mesa_x86_cpu_features |= X86_FEATURE_XMM | X86_FEATURE_XMM2; + + if (!__get_cpuid(1, &eax, &ebx, &ecx, &edx)) + return; + + if (ecx & bit_SSE4_1) + _mesa_x86_cpu_features |= X86_FEATURE_SSE4_1; + } +#endif /* USE_X86_64_ASM */ + + (void) detection_debug; +}