Add pixman_fill_mmx() function
authorSøren Sandmann Pedersen <sandmann@redhat.com>
Tue, 12 Jun 2007 01:35:14 +0000 (21:35 -0400)
committerSøren Sandmann Pedersen <sandmann@redhat.com>
Tue, 12 Jun 2007 01:35:14 +0000 (21:35 -0400)
pixman/pixman-mmx.c
pixman/pixman-mmx.h
pixman/pixman-utils.c
pixman/pixman.h

index 3986cc8..84f440d 100644 (file)
@@ -1640,6 +1640,133 @@ fbCompositeSolidMask_nx8x8888mmx (pixman_op_t op,
     _mm_empty();
 }
 
+pixman_bool_t
+pixman_fill_mmx (uint32_t *bits,
+                int stride,
+                int bpp,
+                int x,
+                int y,
+                int width,
+                int height,
+                uint32_t xor)
+{
+    ullong     fill;
+    __m64      vfill;
+    uint32_t   byte_width;
+    uint8_t    *byte_line;
+#ifdef __GNUC__
+    __m64      v1, v2, v3, v4, v5, v6, v7;
+#endif
+    
+    if (bpp == 16 && (xor >> 16 != (xor & 0xffff)))
+       return FALSE;
+    
+    if (bpp != 16 && bpp != 32)
+       return FALSE;
+    
+    if (bpp == 16)
+    {
+       stride = stride * sizeof (uint32_t) / 2;
+       byte_line = (uint8_t *)(((uint16_t *)bits) + stride * y + x);
+       byte_width = 2 * width;
+       stride *= 2;
+    }
+    else
+    {
+       stride = stride * sizeof (uint32_t) / 4;
+       byte_line = (uint8_t *)(((uint32_t *)bits) + stride * y + x);
+       byte_width = 4 * width;
+       stride *= 4;
+    }
+    
+    fill = ((ullong)xor << 32) | xor;
+    vfill = (__m64)fill;
+    
+#ifdef __GNUC__
+    __asm__ (
+       "movq           %7,     %0\n"
+       "movq           %7,     %1\n"
+       "movq           %7,     %2\n"
+       "movq           %7,     %3\n"
+       "movq           %7,     %4\n"
+       "movq           %7,     %5\n"
+       "movq           %7,     %6\n"
+       : "=y" (v1), "=y" (v2), "=y" (v3),
+         "=y" (v4), "=y" (v5), "=y" (v6), "=y" (v7)
+       : "y" (vfill));
+#endif
+    
+    while (height--)
+    {
+       int w;
+       uint8_t *d = byte_line;
+       byte_line += stride;
+       w = byte_width;
+       
+       while (w >= 2 && ((unsigned long)d & 3))
+       {
+           *(uint16_t *)d = xor;
+           w -= 2;
+           d += 2;
+       }
+       
+       while (w >= 4 && ((unsigned long)d & 7))
+       {
+           *(uint32_t *)d = xor;
+           
+           w -= 4;
+           d += 4;
+       }
+
+       while (w >= 64)
+       {
+#ifdef __GNUC__
+           __asm__ (
+               "movq   %1,       (%0)\n"
+               "movq   %2,      8(%0)\n"
+               "movq   %3,     16(%0)\n"
+               "movq   %4,     24(%0)\n"
+               "movq   %5,     32(%0)\n"
+               "movq   %6,     40(%0)\n"
+               "movq   %7,     48(%0)\n"
+               "movq   %8,     56(%0)\n"
+               :
+               : "r" (d),
+                 "y" (vfill), "y" (v1), "y" (v2), "y" (v3),
+                 "y" (v4), "y" (v5), "y" (v6), "y" (v7)
+               : "memory");
+#else
+           *(__m64*) (d +  0) = vfill;
+           *(__m64*) (d +  8) = vfill;
+           *(__m64*) (d + 16) = vfill;
+           *(__m64*) (d + 24) = vfill;
+           *(__m64*) (d + 32) = vfill;
+           *(__m64*) (d + 40) = vfill;
+           *(__m64*) (d + 48) = vfill;
+           *(__m64*) (d + 56) = vfill;
+#endif    
+           w -= 64;
+           d += 64;
+       }
+       
+       while (w >= 4)
+       {
+           *(uint32_t *)d = xor;
+           
+           w -= 4;
+           d += 4;
+       }
+       if (w >= 2)
+       {
+           *(uint16_t *)d = xor;
+           w -= 2;
+           d += 2;
+       }
+    }
+    
+    _mm_empty();
+    return TRUE;
+}
 
 #if 0
 /* FIXME */
index 9ea2ad7..be8af88 100644 (file)
@@ -46,6 +46,26 @@ pixman_bool_t pixman_have_mmx(void);
 
 #ifdef USE_MMX
 
+pixman_bool_t 
+pixman_blt_mmx (uint32_t *src_bits,
+               uint32_t *dst_bits,
+               int src_stride,
+               int dst_stride,
+               int src_bpp,
+               int dst_bpp,
+               int src_x, int src_y,
+               int dst_x, int dst_y,
+               int width, int height);
+pixman_bool_t
+pixman_fill_mmx (uint32_t *bits,
+                int stride,
+                int bpp,
+                int x,
+                int y,
+                int width,
+                int height,
+                uint32_t xor);
+
 void fbComposeSetupMMX(void);
 
 void fbCompositeSolidMask_nx8888x0565Cmmx (pixman_op_t      op,
index ab6a1cd..4ac30aa 100644 (file)
@@ -24,6 +24,7 @@
 #include <config.h>
 #include "pixman.h"
 #include "pixman-private.h"
+#include "pixman-mmx.h"
 
 pixman_bool_t
 pixman_transform_point_3d (pixman_transform_t *transform,
@@ -78,3 +79,24 @@ pixman_blt (uint32_t *src_bits,
 #endif
        return FALSE;
 }
+
+pixman_bool_t
+pixman_fill (uint32_t *bits,
+                int stride,
+                int bpp,
+                int x,
+                int y,
+                int width,
+                int height,
+                uint32_t xor)
+{
+#ifdef USE_MMX
+    if (pixman_have_mmx())
+    {
+       return pixman_fill_mmx (bits, stride, bpp, x, y, width, height, xor);
+    }
+    else
+#endif
+       return FALSE;
+}
+           
index 0421723..277fc0f 100644 (file)
@@ -300,7 +300,14 @@ pixman_bool_t pixman_blt (uint32_t *src_bits,
                          int src_x, int src_y,
                          int dst_x, int dst_y,
                          int width, int height);
-
+pixman_bool_t pixman_fill (uint32_t *bits,
+                          int stride,
+                          int bpp,
+                          int x,
+                          int y,
+                          int width,
+                          int height,
+                          uint32_t xor);
 /*
  * Images
  */