Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencommon_x86.c
Go to the documentation of this file.
00001 /* 00002 * Mesa 3-D graphics library 00003 * Version: 6.5.1 00004 * 00005 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 00006 * 00007 * Permission is hereby granted, free of charge, to any person obtaining a 00008 * copy of this software and associated documentation files (the "Software"), 00009 * to deal in the Software without restriction, including without limitation 00010 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 * and/or sell copies of the Software, and to permit persons to whom the 00012 * Software is furnished to do so, subject to the following conditions: 00013 * 00014 * The above copyright notice and this permission notice shall be included 00015 * in all copies or substantial portions of the Software. 00016 * 00017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00018 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00021 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00022 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00023 */ 00024 00037 /* XXX these includes should probably go into imports.h or glheader.h */ 00038 #if defined(USE_SSE_ASM) && defined(__linux__) 00039 #include <linux/version.h> 00040 #endif 00041 #if defined(USE_SSE_ASM) && defined(__FreeBSD__) 00042 #include <sys/types.h> 00043 #include <sys/sysctl.h> 00044 #endif 00045 #if defined(USE_SSE_ASM) && defined(__OpenBSD__) 00046 #include <sys/param.h> 00047 #include <sys/sysctl.h> 00048 #include <machine/cpu.h> 00049 #endif 00050 00051 #include "main/imports.h" 00052 #include "common_x86_asm.h" 00053 00054 00055 int _mesa_x86_cpu_features = 0; 00056 00057 /* No reason for this to be public. 00058 */ 00059 extern GLuint _ASMAPI _mesa_x86_has_cpuid(void); 00060 extern void _ASMAPI _mesa_x86_cpuid(GLuint op, GLuint *reg_eax, GLuint *reg_ebx, GLuint *reg_ecx, GLuint *reg_edx); 00061 extern GLuint _ASMAPI _mesa_x86_cpuid_eax(GLuint op); 00062 extern GLuint _ASMAPI _mesa_x86_cpuid_ebx(GLuint op); 00063 extern GLuint _ASMAPI _mesa_x86_cpuid_ecx(GLuint op); 00064 extern GLuint _ASMAPI _mesa_x86_cpuid_edx(GLuint op); 00065 00066 00067 #if defined(USE_SSE_ASM) 00068 /* 00069 * We must verify that the Streaming SIMD Extensions are truly supported 00070 * on this processor before we go ahead and hook out the optimized code. 00071 * 00072 * However, I have been told by Alan Cox that all 2.4 (and later) Linux 00073 * kernels provide full SSE support on all processors that expose SSE via 00074 * the CPUID mechanism. 00075 */ 00076 extern void _mesa_test_os_sse_support( void ); 00077 extern void _mesa_test_os_sse_exception_support( void ); 00078 00079 #if defined(WIN32) 00080 #ifndef STATUS_FLOAT_MULTIPLE_TRAPS 00081 # define STATUS_FLOAT_MULTIPLE_TRAPS (0xC00002B5L) 00082 #endif 00083 static LONG WINAPI ExceptionFilter(LPEXCEPTION_POINTERS exp) 00084 { 00085 PEXCEPTION_RECORD rec = exp->ExceptionRecord; 00086 PCONTEXT ctx = exp->ContextRecord; 00087 00088 if ( rec->ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION ) { 00089 _mesa_debug(NULL, "EXCEPTION_ILLEGAL_INSTRUCTION\n" ); 00090 _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM); 00091 } else if ( rec->ExceptionCode == STATUS_FLOAT_MULTIPLE_TRAPS ) { 00092 _mesa_debug(NULL, "STATUS_FLOAT_MULTIPLE_TRAPS\n"); 00093 /* Windows seems to clear the exception flag itself, we just have to increment Eip */ 00094 } else { 00095 _mesa_debug(NULL, "UNEXPECTED EXCEPTION (0x%08x), terminating!\n" ); 00096 return EXCEPTION_EXECUTE_HANDLER; 00097 } 00098 00099 if ( (ctx->ContextFlags & CONTEXT_CONTROL) != CONTEXT_CONTROL ) { 00100 _mesa_debug(NULL, "Context does not contain control registers, terminating!\n"); 00101 return EXCEPTION_EXECUTE_HANDLER; 00102 } 00103 ctx->Eip += 3; 00104 00105 return EXCEPTION_CONTINUE_EXECUTION; 00106 } 00107 #endif /* WIN32 */ 00108 00109 00110 static void check_os_sse_support( void ) 00111 { 00112 #if defined(__FreeBSD__) 00113 { 00114 int ret, enabled; 00115 unsigned int len; 00116 len = sizeof(enabled); 00117 ret = sysctlbyname("hw.instruction_sse", &enabled, &len, NULL, 0); 00118 if (ret || !enabled) 00119 _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM); 00120 } 00121 #elif defined (__NetBSD__) 00122 { 00123 int ret, enabled; 00124 size_t len = sizeof(enabled); 00125 ret = sysctlbyname("machdep.sse", &enabled, &len, (void *)NULL, 0); 00126 if (ret || !enabled) 00127 _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM); 00128 } 00129 #elif defined(__OpenBSD__) 00130 { 00131 int mib[2]; 00132 int ret, enabled; 00133 size_t len = sizeof(enabled); 00134 00135 mib[0] = CTL_MACHDEP; 00136 mib[1] = CPU_SSE; 00137 00138 ret = sysctl(mib, 2, &enabled, &len, NULL, 0); 00139 if (ret || !enabled) 00140 _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM); 00141 } 00142 #elif defined(WIN32) 00143 LPTOP_LEVEL_EXCEPTION_FILTER oldFilter; 00144 00145 /* Install our ExceptionFilter */ 00146 oldFilter = SetUnhandledExceptionFilter( ExceptionFilter ); 00147 00148 if ( cpu_has_xmm ) { 00149 _mesa_debug(NULL, "Testing OS support for SSE...\n"); 00150 00151 _mesa_test_os_sse_support(); 00152 00153 if ( cpu_has_xmm ) { 00154 _mesa_debug(NULL, "Yes.\n"); 00155 } else { 00156 _mesa_debug(NULL, "No!\n"); 00157 } 00158 } 00159 00160 if ( cpu_has_xmm ) { 00161 _mesa_debug(NULL, "Testing OS support for SSE unmasked exceptions...\n"); 00162 00163 //_mesa_test_os_sse_exception_support(); 00164 00165 if ( cpu_has_xmm ) { 00166 _mesa_debug(NULL, "Yes.\n"); 00167 } else { 00168 _mesa_debug(NULL, "No!\n"); 00169 } 00170 } 00171 00172 /* Restore previous exception filter */ 00173 SetUnhandledExceptionFilter( oldFilter ); 00174 00175 if ( cpu_has_xmm ) { 00176 _mesa_debug(NULL, "Tests of OS support for SSE passed.\n"); 00177 } else { 00178 _mesa_debug(NULL, "Tests of OS support for SSE failed!\n"); 00179 } 00180 #else 00181 /* Do nothing on other platforms for now. 00182 */ 00183 _mesa_debug(NULL, "Not testing OS support for SSE, leaving enabled.\n"); 00184 #endif /* __FreeBSD__ */ 00185 } 00186 00187 #endif /* USE_SSE_ASM */ 00188 00189 00190 void _mesa_init_all_x86_transform_asm( void ) 00191 { 00192 #ifdef USE_X86_ASM 00193 _mesa_x86_cpu_features = 0; 00194 00195 if (!_mesa_x86_has_cpuid()) { 00196 _mesa_debug(NULL, "CPUID not detected\n"); 00197 } 00198 else { 00199 GLuint cpu_features; 00200 GLuint cpu_ext_features; 00201 GLuint cpu_ext_info; 00202 char cpu_vendor[13]; 00203 GLuint result; 00204 00205 /* get vendor name */ 00206 _mesa_x86_cpuid(0, &result, (GLuint *)(cpu_vendor + 0), (GLuint *)(cpu_vendor + 8), (GLuint *)(cpu_vendor + 4)); 00207 cpu_vendor[12] = '\0'; 00208 00209 _mesa_debug(NULL, "CPU vendor: %s\n", cpu_vendor); 00210 00211 /* get cpu features */ 00212 cpu_features = _mesa_x86_cpuid_edx(1); 00213 00214 if (cpu_features & X86_CPU_FPU) 00215 _mesa_x86_cpu_features |= X86_FEATURE_FPU; 00216 if (cpu_features & X86_CPU_CMOV) 00217 _mesa_x86_cpu_features |= X86_FEATURE_CMOV; 00218 00219 #ifdef USE_MMX_ASM 00220 if (cpu_features & X86_CPU_MMX) 00221 _mesa_x86_cpu_features |= X86_FEATURE_MMX; 00222 #endif 00223 00224 #ifdef USE_SSE_ASM 00225 if (cpu_features & X86_CPU_XMM) 00226 _mesa_x86_cpu_features |= X86_FEATURE_XMM; 00227 if (cpu_features & X86_CPU_XMM2) 00228 _mesa_x86_cpu_features |= X86_FEATURE_XMM2; 00229 #endif 00230 00231 /* query extended cpu features */ 00232 if ((cpu_ext_info = _mesa_x86_cpuid_eax(0x80000000)) > 0x80000000) { 00233 if (cpu_ext_info >= 0x80000001) { 00234 00235 cpu_ext_features = _mesa_x86_cpuid_edx(0x80000001); 00236 00237 if (cpu_features & X86_CPU_MMX) { 00238 00239 #ifdef USE_3DNOW_ASM 00240 if (cpu_ext_features & X86_CPUEXT_3DNOW) 00241 _mesa_x86_cpu_features |= X86_FEATURE_3DNOW; 00242 if (cpu_ext_features & X86_CPUEXT_3DNOW_EXT) 00243 _mesa_x86_cpu_features |= X86_FEATURE_3DNOWEXT; 00244 #endif 00245 00246 #ifdef USE_MMX_ASM 00247 if (cpu_ext_features & X86_CPUEXT_MMX_EXT) 00248 _mesa_x86_cpu_features |= X86_FEATURE_MMXEXT; 00249 #endif 00250 } 00251 } 00252 00253 /* query cpu name */ 00254 if (cpu_ext_info >= 0x80000002) { 00255 GLuint ofs; 00256 char cpu_name[49]; 00257 for (ofs = 0; ofs < 3; ofs++) 00258 _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)); 00259 cpu_name[48] = '\0'; /* the name should be NULL terminated, but just to be sure */ 00260 00261 _mesa_debug(NULL, "CPU name: %s\n", cpu_name); 00262 } 00263 } 00264 00265 } 00266 00267 if ( _mesa_getenv( "MESA_NO_ASM" ) ) { 00268 _mesa_x86_cpu_features = 0; 00269 } 00270 00271 if ( _mesa_x86_cpu_features ) { 00272 _mesa_init_x86_transform_asm(); 00273 } 00274 00275 #ifdef USE_MMX_ASM 00276 if ( cpu_has_mmx ) { 00277 if ( _mesa_getenv( "MESA_NO_MMX" ) == 0 ) { 00278 _mesa_debug(NULL, "MMX cpu detected.\n"); 00279 } else { 00280 _mesa_x86_cpu_features &= ~(X86_FEATURE_MMX); 00281 } 00282 } 00283 #endif 00284 00285 #ifdef USE_3DNOW_ASM 00286 if ( cpu_has_3dnow ) { 00287 if ( _mesa_getenv( "MESA_NO_3DNOW" ) == 0 ) { 00288 _mesa_debug(NULL, "3DNow! cpu detected.\n"); 00289 _mesa_init_3dnow_transform_asm(); 00290 } else { 00291 _mesa_x86_cpu_features &= ~(X86_FEATURE_3DNOW); 00292 } 00293 } 00294 #endif 00295 00296 #ifdef USE_SSE_ASM 00297 if ( cpu_has_xmm ) { 00298 if ( _mesa_getenv( "MESA_NO_SSE" ) == 0 ) { 00299 _mesa_debug(NULL, "SSE cpu detected.\n"); 00300 if ( _mesa_getenv( "MESA_FORCE_SSE" ) == 0 ) { 00301 check_os_sse_support(); 00302 } 00303 if ( cpu_has_xmm ) { 00304 _mesa_init_sse_transform_asm(); 00305 } 00306 } else { 00307 _mesa_debug(NULL, "SSE cpu detected, but switched off by user.\n"); 00308 _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM); 00309 } 00310 } 00311 #endif 00312 #endif 00313 } 00314 Generated on Sat May 26 2012 04:19:39 for ReactOS by
1.7.6.1
|