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.
This commit is contained in:
Ian Romanick 2008-09-28 20:31:46 -07:00
parent b5d59222cc
commit 2b8d8989fb
2 changed files with 46 additions and 19 deletions

View file

@ -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");

View file

@ -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 */