Added min and max blend functions.
authorJose Fonseca <j_r_fonseca@yahoo.co.uk>
Fri, 19 Apr 2002 20:12:30 +0000 (20:12 +0000)
committerJose Fonseca <j_r_fonseca@yahoo.co.uk>
Fri, 19 Apr 2002 20:12:30 +0000 (20:12 +0000)
Slight optimization of _mesa_mmx_blend_add.

src/mesa/swrast/s_blend.c
src/mesa/x86/mmx.h
src/mesa/x86/mmx_blend.S

index 0d75e2a8cfd326db3d226db104a9d7c51f76fd85..73e7de5c31d7d5673f7730fbf55ce415a07e9b3f 100644 (file)
@@ -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;
index da163880fb480a52eefd50bd2a2124d5c43be212..11f78635ae9f164516a21a6e7d4e5bd0c99ea686 100644 (file)
@@ -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] );
index f3460465c994ab70b408db1695de1ff44189d372..259d71c2fa0262b6f67f86d1db11e596dd047fc6 100644 (file)
@@ -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,29 +276,82 @@ const_80:
 #include "mmx_blendtmp.h"
 
 
-/* add bleding mode
+/* Blend add function
+ *
+ * FIXME: Add some loop unrolling here...
  */
 
 #define TAG(x) x##_add
 
 #define INIT
 
+#define MAIN( rgba, dest ) \
+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"
+
+
+/* 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 )                                                                   ;\
-    PADDUSB     ( MM1, MM2 )                                                                           ;\
-    GMB_STORE( rgba, 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"
 
 
-/* modulate blending mode
+/* 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 )                                                                   ;\