From 3fe2bb8933c15a7091838fd982dbad402fe6ad43 Mon Sep 17 00:00:00 2001 From: Jose Fonseca Date: Fri, 19 Apr 2002 20:12:30 +0000 Subject: [PATCH] Added min and max blend functions. Slight optimization of _mesa_mmx_blend_add. --- src/mesa/swrast/s_blend.c | 18 +++++++-- src/mesa/x86/mmx.h | 10 ++++- src/mesa/x86/mmx_blend.S | 79 ++++++++++++++++++++++++++++++++++----- 3 files changed, 93 insertions(+), 14 deletions(-) diff --git a/src/mesa/swrast/s_blend.c b/src/mesa/swrast/s_blend.c index 0d75e2a8cfd..73e7de5c31d 100644 --- a/src/mesa/swrast/s_blend.c +++ b/src/mesa/swrast/s_blend.c @@ -1,4 +1,4 @@ -/* $Id: s_blend.c,v 1.21 2002/04/19 10:53:08 jrfonseca Exp $ */ +/* $Id: s_blend.c,v 1.22 2002/04/19 20:12:31 jrfonseca Exp $ */ /* * Mesa 3-D graphics library @@ -678,10 +678,22 @@ void _swrast_choose_blend_func( GLcontext *ctx ) SWRAST_CONTEXT(ctx)->BlendFunc = blend_modulate; } else if (eq==GL_MIN_EXT) { - SWRAST_CONTEXT(ctx)->BlendFunc = blend_min; +#if defined(USE_MMX_ASM) + if ( cpu_has_mmx ) { + SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_min; + } + else +#endif + SWRAST_CONTEXT(ctx)->BlendFunc = blend_min; } else if (eq==GL_MAX_EXT) { - SWRAST_CONTEXT(ctx)->BlendFunc = blend_max; +#if defined(USE_MMX_ASM) + if ( cpu_has_mmx ) { + SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_max; + } + else +#endif + SWRAST_CONTEXT(ctx)->BlendFunc = blend_max; } else if (eq==GL_FUNC_ADD_EXT && srcRGB == GL_ZERO && dstRGB == GL_ONE) { SWRAST_CONTEXT(ctx)->BlendFunc = blend_noop; diff --git a/src/mesa/x86/mmx.h b/src/mesa/x86/mmx.h index da163880fb4..11f78635ae9 100644 --- a/src/mesa/x86/mmx.h +++ b/src/mesa/x86/mmx.h @@ -1,4 +1,4 @@ -/* $Id: mmx.h,v 1.8 2002/04/19 10:53:08 jrfonseca Exp $ */ +/* $Id: mmx.h,v 1.9 2002/04/19 20:12:30 jrfonseca Exp $ */ /* * Mesa 3-D graphics library @@ -36,6 +36,14 @@ extern void _ASMAPI _mesa_mmx_blend_add( GLcontext *ctx, GLuint n, const GLubyte mask[], GLubyte rgba[][4], const GLubyte dest[][4] ); +extern void _ASMAPI +_mesa_mmx_blend_min( GLcontext *ctx, GLuint n, const GLubyte mask[], + GLubyte rgba[][4], const GLubyte dest[][4] ); + +extern void _ASMAPI +_mesa_mmx_blend_max( GLcontext *ctx, GLuint n, const GLubyte mask[], + GLubyte rgba[][4], const GLubyte dest[][4] ); + extern void _ASMAPI _mesa_mmx_blend_modulate( GLcontext *ctx, GLuint n, const GLubyte mask[], GLubyte rgba[][4], const GLubyte dest[][4] ); diff --git a/src/mesa/x86/mmx_blend.S b/src/mesa/x86/mmx_blend.S index f3460465c99..259d71c2fa0 100644 --- a/src/mesa/x86/mmx_blend.S +++ b/src/mesa/x86/mmx_blend.S @@ -5,6 +5,9 @@ #include "matypes.h" +/* FIXME: The pairing rules must be checked as they aren't being fully obeyed. + */ + /* integer multiplication - alpha plus one * * makes the following approximation to the division (Sree) @@ -238,20 +241,23 @@ TWO(PUNPCKHDQ ( MA2, MA2 )) /* pa2 | pa2 | pa PACKUSWB ( MS2, MS1 ) /* sa2 | sb2 | sg2 | sr2 | sa1 | sb1 | sg1 | sr1 */ ;\ #define GMB_STORE(rgba, MSS ) \ -ONE(MOVD ( MSS, REGIND(rgba) )) ;\ -TWO(MOVQ ( MSS, REGIND(rgba) )) +ONE(MOVD ( MSS, REGIND(rgba) )) /* | | | | sa1 | sb1 | sg1 | sr1 */ ;\ +TWO(MOVQ ( MSS, REGIND(rgba) )) /* sa2 | sb2 | sg2 | sr2 | sa1 | sb1 | sg1 | sr1 */ SEG_DATA ALIGNDATA8 +const_0080: + D_LONG 0x00800080, 0x00800080 + const_80: - D_LONG 0x00800080, 0x00800080 + D_LONG 0x80808080, 0x80808080 SEG_TEXT -/* common transparency blending mode +/* Blend transparency function */ #define TAG(x) x##_transparency @@ -270,7 +276,9 @@ const_80: #include "mmx_blendtmp.h" -/* add bleding mode +/* Blend add function + * + * FIXME: Add some loop unrolling here... */ #define TAG(x) x##_add @@ -278,21 +286,72 @@ const_80: #define INIT #define MAIN( rgba, dest ) \ - GMB_LOAD( rgba, dest, MM1, MM2 ) ;\ - PADDUSB ( MM1, MM2 ) ;\ - GMB_STORE( rgba, MM2 ) +ONE(MOVD ( REGIND(rgba), MM1 )) /* | | | | qa1 | qb1 | qg1 | qr1 */ ;\ +ONE(MOVD ( REGIND(dest), MM2 )) /* | | | | pa1 | pb1 | pg1 | pr1 */ ;\ +ONE(PADDUSB ( MM2, MM1 )) ;\ +ONE(MOVD ( MM1, REGIND(rgba) )) /* | | | | sa1 | sb1 | sg1 | sr1 */ ;\ + ;\ +TWO(MOVQ ( REGIND(rgba), MM1 )) /* qa2 | qb2 | qg2 | qr2 | qa1 | qb1 | qg1 | qr1 */ ;\ +TWO(PADDUSB ( REGIND(dest), MM1 )) /* sa2 | sb2 | sg2 | sr2 | sa1 | sb1 | sg1 | sr1 */ ;\ +TWO(MOVQ ( MM1, REGIND(rgba) )) #include "mmx_blendtmp.h" -/* modulate blending mode +/* Blend min function + */ + +#define TAG(x) x##_min + +#define INIT \ + MOVQ ( CONTENT(const_80), MM7 ) /* 0x80| 0x80| 0x80| 0x80| 0x80| 0x80| 0x80| 0x80*/ + +#define MAIN( rgba, dest ) \ + GMB_LOAD( rgba, dest, MM1, MM2 ) ;\ + MOVQ ( MM1, MM3 ) ;\ + MOVQ ( MM2, MM4 ) ;\ + PXOR ( MM7, MM3 ) /* unsigned -> signed */ ;\ + PXOR ( MM7, MM4 ) /* unsigned -> signed */ ;\ + PCMPGTB ( MM3, MM4 ) /* q > p ? 0xff : 0x00 */ ;\ + PAND ( MM4, MM1 ) /* q > p ? p : 0 */ ;\ + PANDN ( MM2, MM4 ) /* q > p ? 0 : q */ ;\ + POR ( MM1, MM4 ) /* q > p ? p : q */ ;\ + GMB_STORE( rgba, MM4 ) + +#include "mmx_blendtmp.h" + + +/* Blend max function + */ + +#define TAG(x) x##_max + +#define INIT \ + MOVQ ( CONTENT(const_80), MM7 ) /* 0x80| 0x80| 0x80| 0x80| 0x80| 0x80| 0x80| 0x80*/ + +#define MAIN( rgba, dest ) \ + GMB_LOAD( rgba, dest, MM1, MM2 ) ;\ + MOVQ ( MM1, MM3 ) ;\ + MOVQ ( MM2, MM4 ) ;\ + PXOR ( MM7, MM3 ) /* unsigned -> signed */ ;\ + PXOR ( MM7, MM4 ) /* unsigned -> signed */ ;\ + PCMPGTB ( MM3, MM4 ) /* q > p ? 0xff : 0x00 */ ;\ + PAND ( MM4, MM2 ) /* q > p ? q : 0 */ ;\ + PANDN ( MM1, MM4 ) /* q > p ? 0 : p */ ;\ + POR ( MM2, MM4 ) /* q > p ? p : q */ ;\ + GMB_STORE( rgba, MM4 ) + +#include "mmx_blendtmp.h" + + +/* Blend modulate function */ #define TAG(x) x##_modulate #define INIT \ PXOR ( MM0, MM0 ) /* 0x0000 | 0x0000 | 0x0000 | 0x0000 */ ;\ - MOVQ ( CONTENT(const_80), MM7 ) /* 0xffff | 0xffff | 0xffff | 0xffff */ + MOVQ ( CONTENT(const_0080), MM7 ) /* 0x0080 | 0x0080 | 0x0080 | 0x0080 */ #define MAIN( rgba, dest ) \ GMB_LOAD( rgba, dest, MM1, MM2 ) ;\