Mesa (master): Use 3Dnow! x86-64 routines only on processors that support 3Dnow!

Ian Romanick idr at kemper.freedesktop.org
Mon Sep 29 03:32:46 UTC 2008


Module: Mesa
Branch: master
Commit: 2b8d8989fb6f9c36baf166fc715182a1407ebadb
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=2b8d8989fb6f9c36baf166fc715182a1407ebadb

Author: Ian Romanick <ian.d.romanick at intel.com>
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.

---

 src/mesa/x86-64/x86-64.c |   34 +++++++++++++++++++++++-----------
 src/mesa/x86-64/xform4.S |   31 +++++++++++++++++++++++--------
 2 files changed, 46 insertions(+), 19 deletions(-)

diff --git a/src/mesa/x86-64/x86-64.c b/src/mesa/x86-64/x86-64.c
index 9ec43c8..96f8da8 100644
--- a/src/mesa/x86-64/x86-64.c
+++ b/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 a/src/mesa/x86-64/xform4.S b/src/mesa/x86-64/xform4.S
index 3f9c9d5..8059691 100644
--- a/src/mesa/x86-64/xform4.S
+++ b/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 */




More information about the mesa-commit mailing list