gdk: add i386 SSE pixel compositing

This commit is contained in:
Daemonratte 2026-08-12 20:02:05 +02:00
commit 8a45eac09a
4 changed files with 90 additions and 0 deletions

View file

@ -215,6 +215,21 @@ AC_SUBST(GDK_PIXELOPS_X86_MMX_CFLAGS)
AM_CONDITIONAL(GDK_PIXELOPS_X86_MMX,
test -n "$GDK_PIXELOPS_X86_MMX_CFLAGS")
GDK_PIXELOPS_X86_SSE_CFLAGS=
case "$host_cpu:$gdk_pixelops_arch" in
i?86:x86)
GDK_PIXELOPS_X86_SSE_CFLAGS="-mmmx -mno-sse -mno-sse2 -mno-3dnow"
AC_DEFINE([HAVE_GDK_PIXELOPS_X86_SSE], [1],
[Define if the GDK 32-bit x86 SSE pixel operations backend is built])
;;
esac
AC_SUBST(GDK_PIXELOPS_X86_SSE_CFLAGS)
AM_CONDITIONAL(GDK_PIXELOPS_X86_SSE,
test -n "$GDK_PIXELOPS_X86_SSE_CFLAGS")
GDK_PIXELOPS_X86_3DNOW_CFLAGS=
case "$host_cpu:$gdk_pixelops_arch" in

View file

@ -138,6 +138,17 @@ libgdk_pixelops_x86_mmx_la_CFLAGS = \
$(GDK_PIXELOPS_X86_MMX_CFLAGS)
endif
if GDK_PIXELOPS_X86_SSE
noinst_LTLIBRARIES += libgdk-pixelops-x86-sse.la
gdk_pixelops_arch_libs += libgdk-pixelops-x86-sse.la
libgdk_pixelops_x86_sse_la_SOURCES = gdkpixelops-x86-mmx.c
libgdk_pixelops_x86_sse_la_CFLAGS = \
$(AM_CFLAGS) \
$(GDK_PIXELOPS_X86_SSE_CFLAGS) \
-DGDK_PIXELOPS_X86_SSE_IMPL
endif
if GDK_PIXELOPS_X86_3DNOW
noinst_LTLIBRARIES += libgdk-pixelops-x86-3dnow.la
gdk_pixelops_arch_libs += libgdk-pixelops-x86-3dnow.la

View file

@ -13,6 +13,10 @@
#define GDK_PIXELOPS_COMPOSITE_0888 _gdk_pixel_ops_composite_0888_3dnow
#define GDK_PIXELOPS_COMPOSITE_565 _gdk_pixel_ops_composite_565_3dnow
#define GDK_PIXELOPS_MMX_EMPTY() _m_femms ()
#elif defined(GDK_PIXELOPS_X86_SSE_IMPL)
#define GDK_PIXELOPS_COMPOSITE_0888 _gdk_pixel_ops_composite_0888_sse
#define GDK_PIXELOPS_COMPOSITE_565 _gdk_pixel_ops_composite_565_sse
#define GDK_PIXELOPS_MMX_EMPTY() _mm_empty ()
#else
#define GDK_PIXELOPS_COMPOSITE_0888 _gdk_pixel_ops_composite_0888_mmx
#define GDK_PIXELOPS_COMPOSITE_565 _gdk_pixel_ops_composite_565_mmx
@ -129,8 +133,13 @@ GDK_PIXELOPS_COMPOSITE_0888 (guchar *src_buf,
d = _mm_unpacklo_pi8 (d, zero);
a = _mm_srli_si64 (s, 48);
#ifdef GDK_PIXELOPS_X86_SSE_IMPL
__asm__ ("pshufw $0x00,%0,%0"
: "+y" (a));
#else
a = _mm_unpacklo_pi16 (a, a);
a = _mm_unpacklo_pi32 (a, a);
#endif
a = _mm_and_si64 (a, rgb_mask);
#ifdef GDK_PIXELOPS_X86_3DNOW_IMPL
@ -142,8 +151,18 @@ GDK_PIXELOPS_COMPOSITE_0888 (guchar *src_buf,
_mm_mullo_pi16 (d, ia));
t = _mm_add_pi16 (t, bias);
#ifdef GDK_PIXELOPS_X86_SSE_IMPL
{
__m64 scale = _mm_set1_pi16 (0x0101);
__asm__ ("pmulhuw %1,%0"
: "+y" (t)
: "y" (scale));
}
#else
t = _mm_add_pi16 (t, _mm_srli_pi16 (t, 8));
t = _mm_srli_pi16 (t, 8);
#endif
#endif
packed = _mm_packs_pu16 (t, t);
@ -209,8 +228,13 @@ blend_565_mmx (__m64 zero,
d = _mm_unpacklo_pi8 (d, zero);
a = _mm_srli_si64 (s, 48);
#ifdef GDK_PIXELOPS_X86_SSE_IMPL
__asm__ ("pshufw $0x00,%0,%0"
: "+y" (a));
#else
a = _mm_unpacklo_pi16 (a, a);
a = _mm_unpacklo_pi32 (a, a);
#endif
#ifdef GDK_PIXELOPS_X86_3DNOW_IMPL
t = blend_3dnow (s, d, a);
@ -221,8 +245,18 @@ blend_565_mmx (__m64 zero,
_mm_mullo_pi16 (d, ia));
t = _mm_add_pi16 (t, bias);
#ifdef GDK_PIXELOPS_X86_SSE_IMPL
{
__m64 scale = _mm_set1_pi16 (0x0101);
__asm__ ("pmulhuw %1,%0"
: "+y" (t)
: "y" (scale));
}
#else
t = _mm_add_pi16 (t, _mm_srli_pi16 (t, 8));
t = _mm_srli_pi16 (t, 8);
#endif
#endif
t = _mm_packs_pu16 (t, t);

View file

@ -36,6 +36,26 @@ _gdk_pixel_ops_composite_565_mmx (guchar *src_buf,
gint width,
gint height);
#ifdef HAVE_GDK_PIXELOPS_X86_SSE
G_GNUC_INTERNAL void
_gdk_pixel_ops_composite_0888_sse (guchar *src_buf,
gint src_rowstride,
guchar *dest_buf,
gint dest_rowstride,
GdkByteOrder dest_byte_order,
gint width,
gint height);
G_GNUC_INTERNAL void
_gdk_pixel_ops_composite_565_sse (guchar *src_buf,
gint src_rowstride,
guchar *dest_buf,
gint dest_rowstride,
GdkByteOrder dest_byte_order,
gint width,
gint height);
#endif
#ifdef HAVE_GDK_PIXELOPS_X86_3DNOW
G_GNUC_INTERNAL void
_gdk_pixel_ops_composite_0888_3dnow (guchar *src_buf,
@ -72,6 +92,16 @@ _gdk_pixel_ops_init (void)
_gdk_pixel_ops.composite_565 =
_gdk_pixel_ops_composite_565_mmx;
#ifdef HAVE_GDK_PIXELOPS_X86_SSE
if ((edx & bit_SSE) != 0)
{
_gdk_pixel_ops.composite_0888 =
_gdk_pixel_ops_composite_0888_sse;
_gdk_pixel_ops.composite_565 =
_gdk_pixel_ops_composite_565_sse;
}
#endif
#ifdef HAVE_GDK_PIXELOPS_X86_3DNOW
if (__get_cpuid (0x80000001U, &eax, &ebx, &ecx, &edx) &&
(edx & bit_3DNOW) != 0)