commit 2b8d8989fb6f9c36baf166fc715182a1407ebadb Author: Ian Romanick Date: Sun Sep 28 20:31:46 2008 -0700 Use 3Dnow! x86-64 routines only on processors that support 3Dnow! Added an x86-64 CPUID function and use it to detect 3Dnow! If 3Dnow! is available, use _mesa_3dnow_transform_points4_3d_no_rot, _mesa_3dnow_transform_points4_perspective, _mesa_3dnow_transform_points4_2d_no_rot, and _mesa_3dnow_transform_points4_2d. This fixes long standing bug #8724. diff --git src/mesa/x86-64/x86-64.c src/mesa/x86-64/x86-64.c index 9ec43c8..96f8da8 100644 --- src/mesa/x86-64/x86-64.c +++ src/mesa/x86-64/x86-64.c @@ -41,7 +41,10 @@ #include "math/m_debug.h" #endif +extern void _mesa_x86_64_cpuid(unsigned int *regs); + DECLARE_XFORM_GROUP( x86_64, 4 ) +DECLARE_XFORM_GROUP( 3dnow, 4 ) #else /* just to silence warning below */ @@ -81,6 +84,7 @@ static void message( const char *msg ) void _mesa_init_all_x86_64_transform_asm(void) { #ifdef USE_X86_64_ASM + unsigned int regs[4]; if ( _mesa_getenv( "MESA_NO_ASM" ) ) { return; @@ -88,24 +92,32 @@ void _mesa_init_all_x86_64_transform_asm(void) message("Initializing x86-64 optimizations\n"); - ASSIGN_XFORM_GROUP( x86_64, 4 ); - /* _mesa_transform_tab[4][MATRIX_GENERAL] = _mesa_x86_64_transform_points4_general; _mesa_transform_tab[4][MATRIX_IDENTITY] = _mesa_x86_64_transform_points4_identity; _mesa_transform_tab[4][MATRIX_3D] = _mesa_x86_64_transform_points4_3d; - _mesa_transform_tab[4][MATRIX_3D_NO_ROT] = - _mesa_x86_64_transform_points4_3d_no_rot; - _mesa_transform_tab[4][MATRIX_PERSPECTIVE] = - _mesa_x86_64_transform_points4_perspective; - _mesa_transform_tab[4][MATRIX_2D_NO_ROT] = - _mesa_x86_64_transform_points4_2d_no_rot; - _mesa_transform_tab[4][MATRIX_2D] = - _mesa_x86_64_transform_points4_2d; - */ + + regs[0] = 0x80000001; + regs[1] = 0x00000000; + regs[2] = 0x00000000; + regs[3] = 0x00000000; + _mesa_x86_64_cpuid(regs); + if (regs[3] & (1U << 31)) { + message("3Dnow! detected\n"); + _mesa_transform_tab[4][MATRIX_3D_NO_ROT] = + _mesa_3dnow_transform_points4_3d_no_rot; + _mesa_transform_tab[4][MATRIX_PERSPECTIVE] = + _mesa_3dnow_transform_points4_perspective; + _mesa_transform_tab[4][MATRIX_2D_NO_ROT] = + _mesa_3dnow_transform_points4_2d_no_rot; + _mesa_transform_tab[4][MATRIX_2D] = + _mesa_3dnow_transform_points4_2d; + + } + #ifdef DEBUG_MATH _math_test_all_transform_functions("x86_64"); diff --git src/mesa/x86-64/xform4.S src/mesa/x86-64/xform4.S index 3f9c9d5..8059691 100644 --- src/mesa/x86-64/xform4.S +++ src/mesa/x86-64/xform4.S @@ -29,7 +29,22 @@ .text .align 16 +.globl _mesa_x86_64_cpuid +_mesa_x86_64_cpuid: + pushq %rbx + movl (%rdi), %eax + movl 8(%rdi), %ecx + + cpuid + + movl %ebx, 4(%rdi) + movl %eax, (%rdi) + movl %ecx, 8(%rdi) + movl %edx, 12(%rdi) + popq %rbx + ret +.align 16 .globl _mesa_x86_64_transform_points4_general _mesa_x86_64_transform_points4_general: /* @@ -204,8 +219,8 @@ p4_identity_done: .align 16 -.globl _mesa_x86_64_transform_points4_3d_no_rot -_mesa_x86_64_transform_points4_3d_no_rot: +.globl _mesa_3dnow_transform_points4_3d_no_rot +_mesa_3dnow_transform_points4_3d_no_rot: movl V4F_COUNT(%rdx), %ecx /* count */ movzx V4F_STRIDE(%rdx), %eax /* stride */ @@ -268,8 +283,8 @@ p4_3d_no_rot_done: .align 16 -.globl _mesa_x86_64_transform_points4_perspective -_mesa_x86_64_transform_points4_perspective: +.globl _mesa_3dnow_transform_points4_perspective +_mesa_3dnow_transform_points4_perspective: movl V4F_COUNT(%rdx), %ecx /* count */ movzx V4F_STRIDE(%rdx), %eax /* stride */ @@ -334,8 +349,8 @@ p4_perspective_done: ret .align 16 -.globl _mesa_x86_64_transform_points4_2d_no_rot -_mesa_x86_64_transform_points4_2d_no_rot: +.globl _mesa_3dnow_transform_points4_2d_no_rot +_mesa_3dnow_transform_points4_2d_no_rot: movl V4F_COUNT(%rdx), %ecx /* count */ movzx V4F_STRIDE(%rdx), %eax /* stride */ @@ -389,8 +404,8 @@ p4_2d_no_rot_done: .align 16 -.globl _mesa_x86_64_transform_points4_2d -_mesa_x86_64_transform_points4_2d: +.globl _mesa_3dnow_transform_points4_2d +_mesa_3dnow_transform_points4_2d: movl V4F_COUNT(%rdx), %ecx /* count */ movzx V4F_STRIDE(%rdx), %eax /* stride */