summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/video/rgbvmx.h
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/video/rgbvmx.h')
-rw-r--r--trunk/src/emu/video/rgbvmx.h440
1 files changed, 440 insertions, 0 deletions
diff --git a/trunk/src/emu/video/rgbvmx.h b/trunk/src/emu/video/rgbvmx.h
new file mode 100644
index 00000000000..adbe10aba60
--- /dev/null
+++ b/trunk/src/emu/video/rgbvmx.h
@@ -0,0 +1,440 @@
+/***************************************************************************
+
+ rgbvmx.h
+
+ VMX/Altivec optimised RGB utilities.
+
+ Copyright Nicola Salmoria and the MAME Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+***************************************************************************/
+
+#ifndef __RGBVMX__
+#define __RGBVMX__
+
+#if defined(__ALTIVEC__)
+#include <altivec.h>
+#endif
+
+
+/***************************************************************************
+ TYPE DEFINITIONS
+***************************************************************************/
+
+/* intermediate RGB values are stored in a vector */
+typedef vector signed short rgbint;
+
+/* intermediate RGB values are stored in a vector */
+typedef vector signed short rgbaint;
+
+
+
+/***************************************************************************
+ BASIC CONVERSIONS
+***************************************************************************/
+
+/*-------------------------------------------------
+ rgb_comp_to_rgbint - converts a trio of RGB
+ components to an rgbint type
+-------------------------------------------------*/
+
+INLINE void rgb_comp_to_rgbint(rgbint *rgb, INT16 r, INT16 g, INT16 b)
+{
+ rgbint result = { 0, r, g, b, 0, 0, 0, 0 };
+ *rgb = result;
+}
+
+
+/*-------------------------------------------------
+ rgba_comp_to_rgbint - converts a quad of RGB
+ components to an rgbint type
+-------------------------------------------------*/
+
+INLINE void rgba_comp_to_rgbaint(rgbaint *rgb, INT16 a, INT16 r, INT16 g, INT16 b)
+{
+ rgbaint result = { a, r, g, b, 0, 0, 0, 0 };
+ *rgb = result;
+}
+
+
+/*-------------------------------------------------
+ rgb_to_rgbint - converts a packed trio of RGB
+ components to an rgbint type
+-------------------------------------------------*/
+
+INLINE void rgb_to_rgbint(rgbint *rgb, rgb_t color)
+{
+ vector signed char temp = (vector signed char)vec_perm((vector signed int)vec_lde(0, &color), vec_splat_s32(0), vec_lvsl(0, &color));
+ *rgb = (rgbint)vec_mergeh((vector signed char)vec_splat_s32(0), temp);
+}
+
+
+/*-------------------------------------------------
+ rgba_to_rgbaint - converts a packed quad of RGB
+ components to an rgbint type
+-------------------------------------------------*/
+
+INLINE void rgba_to_rgbaint(rgbaint *rgb, rgb_t color)
+{
+ vector signed char temp = (vector signed char)vec_perm((vector signed int)vec_lde(0, &color), vec_splat_s32(0), vec_lvsl(0, &color));
+ *rgb = (rgbaint)vec_mergeh((vector signed char)vec_splat_s32(0), temp);
+}
+
+
+/*-------------------------------------------------
+ rgbint_to_rgb - converts an rgbint back to
+ a packed trio of RGB values
+-------------------------------------------------*/
+
+INLINE rgb_t rgbint_to_rgb(const rgbint *color)
+{
+ vector unsigned int temp = vec_splat((vector unsigned int)vec_packsu(*color, *color), 0);
+ rgb_t result;
+ vec_ste(temp, 0, &result);
+ return result;
+}
+
+
+/*-------------------------------------------------
+ rgbaint_to_rgba - converts an rgbint back to
+ a packed quad of RGB values
+-------------------------------------------------*/
+
+INLINE rgb_t rgbaint_to_rgba(const rgbaint *color)
+{
+ vector unsigned int temp = vec_splat((vector unsigned int)vec_packsu(*color, *color), 0);
+ rgb_t result;
+ vec_ste(temp, 0, &result);
+ return result;
+}
+
+
+/*-------------------------------------------------
+ rgbint_to_rgb_clamp - converts an rgbint back
+ to a packed trio of RGB values, clamping them
+ to bytes first
+-------------------------------------------------*/
+
+INLINE rgb_t rgbint_to_rgb_clamp(const rgbint *color)
+{
+ vector unsigned int temp = vec_splat((vector unsigned int)vec_packsu(*color, *color), 0);
+ rgb_t result;
+ vec_ste(temp, 0, &result);
+ return result;
+}
+
+
+/*-------------------------------------------------
+ rgbaint_to_rgba_clamp - converts an rgbint back
+ to a packed quad of RGB values, clamping them
+ to bytes first
+-------------------------------------------------*/
+
+INLINE rgb_t rgbaint_to_rgba_clamp(const rgbaint *color)
+{
+ vector unsigned int temp = vec_splat((vector unsigned int)vec_packsu(*color, *color), 0);
+ rgb_t result;
+ vec_ste(temp, 0, &result);
+ return result;
+}
+
+
+
+/***************************************************************************
+ CORE MATH
+***************************************************************************/
+
+/*-------------------------------------------------
+ rgbint_add - add two rgbint values
+-------------------------------------------------*/
+
+INLINE void rgbint_add(rgbint *color1, const rgbint *color2)
+{
+ *color1 = vec_add(*color1, *color2);
+}
+
+
+/*-------------------------------------------------
+ rgbaint_add - add two rgbaint values
+-------------------------------------------------*/
+
+INLINE void rgbaint_add(rgbaint *color1, const rgbaint *color2)
+{
+ *color1 = vec_add(*color1, *color2);
+}
+
+
+/*-------------------------------------------------
+ rgbint_sub - subtract two rgbint values
+-------------------------------------------------*/
+
+INLINE void rgbint_sub(rgbint *color1, const rgbint *color2)
+{
+ *color1 = vec_sub(*color1, *color2);
+}
+
+
+/*-------------------------------------------------
+ rgbaint_sub - subtract two rgbaint values
+-------------------------------------------------*/
+
+INLINE void rgbaint_sub(rgbaint *color1, const rgbaint *color2)
+{
+ *color1 = vec_sub(*color1, *color2);
+}
+
+
+/*-------------------------------------------------
+ rgbint_subr - reverse subtract two rgbint
+ values
+-------------------------------------------------*/
+
+INLINE void rgbint_subr(rgbint *color1, const rgbint *color2)
+{
+ *color1 = vec_sub(*color2, *color1);
+}
+
+
+/*-------------------------------------------------
+ rgbaint_subr - reverse subtract two rgbaint
+ values
+-------------------------------------------------*/
+
+INLINE void rgbaint_subr(rgbaint *color1, const rgbaint *color2)
+{
+ *color1 = vec_sub(*color2, *color1);
+}
+
+
+
+/***************************************************************************
+ TABLES
+***************************************************************************/
+
+extern const struct _rgbvmx_statics
+{
+ rgbaint maxbyte;
+ rgbaint scale_table[256];
+} rgbvmx_statics;
+
+
+
+/***************************************************************************
+ HIGHER LEVEL OPERATIONS
+***************************************************************************/
+
+/*-------------------------------------------------
+ rgbint_blend - blend two colors by the given
+ scale factor
+-------------------------------------------------*/
+
+INLINE void rgbint_blend(rgbint *color1, const rgbint *color2, UINT8 color1scale)
+{
+ vector signed int temp;
+ *color1 = vec_mergeh(*color1, *color2);
+ temp = vec_msum(*color1, rgbvmx_statics.scale_table[color1scale], vec_splat_s32(0));
+ temp = (vector signed int)vec_sr(temp, vec_splat_u32(8));
+ *color1 = vec_packs(temp, temp);
+}
+
+
+/*-------------------------------------------------
+ rgbaint_blend - blend two colors by the given
+ scale factor
+-------------------------------------------------*/
+
+INLINE void rgbaint_blend(rgbaint *color1, const rgbaint *color2, UINT8 color1scale)
+{
+ vector signed int temp;
+ *color1 = vec_mergeh(*color1, *color2);
+ temp = vec_msum(*color1, rgbvmx_statics.scale_table[color1scale], vec_splat_s32(0));
+ temp = (vector signed int)vec_sr(temp, vec_splat_u32(8));
+ *color1 = vec_packs(temp, temp);
+}
+
+
+/*-------------------------------------------------
+ rgbint_scale_and_clamp - scale the given
+ color by an 8.8 scale factor, immediate or
+ per channel, and clamp to byte values
+-------------------------------------------------*/
+
+INLINE void rgbint_scale_immediate_and_clamp(rgbint *color, INT16 colorscale)
+{
+ rgbint splatmap = vec_splat((rgbint)vec_lvsl(0, &colorscale), 0);
+ rgbint vecscale = vec_lde(0, &colorscale);
+ vector signed int temp;
+ vecscale = (rgbint)vec_perm(vecscale, vecscale, (vector unsigned char)splatmap);
+ *color = (rgbint)vec_mergeh(*color, (rgbint)vec_splat_s32(0));
+ temp = vec_msum(*color, vecscale, vec_splat_s32(0));
+ temp = (vector signed int)vec_sr(temp, vec_splat_u32(8));
+ *color = vec_min(vec_packs(temp, temp), rgbvmx_statics.maxbyte);
+}
+
+INLINE void rgbint_scale_channel_and_clamp(rgbint *color, const rgbint *colorscale)
+{
+ rgbint vecscale = (rgbint)vec_mergeh(*colorscale, (rgbint)vec_splat_s32(0));
+ vector signed int temp;
+ *color = (rgbint)vec_mergeh(*color, (rgbint)vec_splat_s32(0));
+ temp = vec_msum(*color, vecscale, vec_splat_s32(0));
+ temp = (vector signed int)vec_sr(temp, vec_splat_u32(8));
+ *color = vec_min(vec_packs(temp, temp), rgbvmx_statics.maxbyte);
+}
+
+
+/*-------------------------------------------------
+ rgbaint_scale_and_clamp - scale the given
+ color by an 8.8 scale factor, immediate or
+ per channel, and clamp to byte values
+-------------------------------------------------*/
+
+INLINE void rgbaint_scale_immediate_and_clamp(rgbaint *color, INT16 colorscale)
+{
+ rgbaint splatmap = vec_splat((rgbaint)vec_lvsl(0, &colorscale), 0);
+ rgbaint vecscale = vec_lde(0, &colorscale);
+ vector signed int temp;
+ vecscale = (rgbaint)vec_perm(vecscale, vecscale, (vector unsigned char)splatmap);
+ *color = (rgbaint)vec_mergeh(*color, (rgbaint)vec_splat_s32(0));
+ temp = vec_msum(*color, vecscale, vec_splat_s32(0));
+ temp = (vector signed int)vec_sr(temp, vec_splat_u32(8));
+ *color = vec_min(vec_packs(temp, temp), rgbvmx_statics.maxbyte);
+}
+
+INLINE void rgbaint_scale_channel_and_clamp(rgbaint *color, const rgbint *colorscale)
+{
+ rgbaint vecscale = (rgbaint)vec_mergeh(*color, (rgbaint)vec_splat_s32(0));
+ vector signed int temp;
+ *color = (rgbaint)vec_mergeh(*color, (rgbaint)vec_splat_s32(0));
+ temp = vec_msum(*color, vecscale, vec_splat_s32(0));
+ temp = (vector signed int)vec_sr(temp, vec_splat_u32(8));
+ *color = vec_min(vec_packs(temp, temp), rgbvmx_statics.maxbyte);
+}
+
+
+/*-------------------------------------------------
+ rgb_bilinear_filter - bilinear filter between
+ four pixel values
+-------------------------------------------------*/
+
+INLINE rgb_t rgb_bilinear_filter(rgb_t rgb00, rgb_t rgb01, rgb_t rgb10, rgb_t rgb11, UINT8 u, UINT8 v)
+{
+ rgb_t result;
+ rgbint color00 = (rgbint)vec_perm((vector signed int)vec_lde(0, &rgb00), vec_splat_s32(0), vec_lvsl(0, &rgb00));
+ rgbint color01 = (rgbint)vec_perm((vector signed int)vec_lde(0, &rgb01), vec_splat_s32(0), vec_lvsl(0, &rgb01));
+ rgbint color10 = (rgbint)vec_perm((vector signed int)vec_lde(0, &rgb10), vec_splat_s32(0), vec_lvsl(0, &rgb10));
+ rgbint color11 = (rgbint)vec_perm((vector signed int)vec_lde(0, &rgb11), vec_splat_s32(0), vec_lvsl(0, &rgb11));
+
+ /* interleave color01 and color00 at the byte level */
+ color01 = (rgbint)vec_mergeh((vector signed char)color01, (vector signed char)color00);
+ color11 = (rgbint)vec_mergeh((vector signed char)color11, (vector signed char)color10);
+ color01 = (rgbint)vec_mergeh((vector signed char)vec_splat_s32(0), (vector signed char)color01);
+ color11 = (rgbint)vec_mergeh((vector signed char)vec_splat_s32(0), (vector signed char)color11);
+ color01 = (rgbint)vec_msum(color01, rgbvmx_statics.scale_table[u], vec_splat_s32(0));
+ color11 = (rgbint)vec_msum(color11, rgbvmx_statics.scale_table[u], vec_splat_s32(0));
+ color01 = (rgbint)vec_sr((vector signed int)color01, vec_splat_u32(1));
+ color11 = (rgbint)vec_sl((vector signed int)color11, vec_splat_u32(15));
+ color01 = vec_max(color01, color11);
+ color01 = (rgbint)vec_msum(color01, rgbvmx_statics.scale_table[v], vec_splat_s32(0));
+ color01 = (rgbint)vec_sr((vector signed int)color01, vec_splat_u32(15));
+ color01 = vec_packs((vector signed int)color01, (vector signed int)color01);
+ color01 = (rgbint)vec_packsu(color01, color01);
+ vec_ste((vector unsigned int)color01, 0, &result);
+ return result;
+}
+
+
+/*-------------------------------------------------
+ rgba_bilinear_filter - bilinear filter between
+ four pixel values
+-------------------------------------------------*/
+
+INLINE rgb_t rgba_bilinear_filter(rgb_t rgb00, rgb_t rgb01, rgb_t rgb10, rgb_t rgb11, UINT8 u, UINT8 v)
+{
+ rgb_t result;
+ rgbaint color00 = (rgbaint)vec_perm((vector signed int)vec_lde(0, &rgb00), vec_splat_s32(0), vec_lvsl(0, &rgb00));
+ rgbaint color01 = (rgbaint)vec_perm((vector signed int)vec_lde(0, &rgb01), vec_splat_s32(0), vec_lvsl(0, &rgb01));
+ rgbaint color10 = (rgbaint)vec_perm((vector signed int)vec_lde(0, &rgb10), vec_splat_s32(0), vec_lvsl(0, &rgb10));
+ rgbaint color11 = (rgbaint)vec_perm((vector signed int)vec_lde(0, &rgb11), vec_splat_s32(0), vec_lvsl(0, &rgb11));
+
+ /* interleave color01 and color00 at the byte level */
+ color01 = (rgbaint)vec_mergeh((vector signed char)color01, (vector signed char)color00);
+ color11 = (rgbaint)vec_mergeh((vector signed char)color11, (vector signed char)color10);
+ color01 = (rgbaint)vec_mergeh((vector signed char)vec_splat_s32(0), (vector signed char)color01);
+ color11 = (rgbaint)vec_mergeh((vector signed char)vec_splat_s32(0), (vector signed char)color11);
+ color01 = (rgbaint)vec_msum(color01, rgbvmx_statics.scale_table[u], vec_splat_s32(0));
+ color11 = (rgbaint)vec_msum(color11, rgbvmx_statics.scale_table[u], vec_splat_s32(0));
+ color01 = (rgbaint)vec_sr((vector signed int)color01, vec_splat_u32(1));
+ color11 = (rgbaint)vec_sl((vector signed int)color11, vec_splat_u32(15));
+ color01 = vec_max(color01, color11);
+ color01 = (rgbaint)vec_msum(color01, rgbvmx_statics.scale_table[v], vec_splat_s32(0));
+ color01 = (rgbaint)vec_sr((vector signed int)color01, vec_splat_u32(15));
+ color01 = vec_packs((vector signed int)color01, (vector signed int)color01);
+ color01 = (rgbaint)vec_packsu(color01, color01);
+ vec_ste((vector unsigned int)color01, 0, &result);
+ return result;
+}
+
+
+/*-------------------------------------------------
+ rgbint_bilinear_filter - bilinear filter between
+ four pixel values
+-------------------------------------------------*/
+
+INLINE void rgbint_bilinear_filter(rgbint *color, rgb_t rgb00, rgb_t rgb01, rgb_t rgb10, rgb_t rgb11, UINT8 u, UINT8 v)
+{
+ rgbint color00 = (rgbint)vec_perm((vector signed int)vec_lde(0, &rgb00), vec_splat_s32(0), vec_lvsl(0, &rgb00));
+ rgbint color01 = (rgbint)vec_perm((vector signed int)vec_lde(0, &rgb01), vec_splat_s32(0), vec_lvsl(0, &rgb01));
+ rgbint color10 = (rgbint)vec_perm((vector signed int)vec_lde(0, &rgb10), vec_splat_s32(0), vec_lvsl(0, &rgb10));
+ rgbint color11 = (rgbint)vec_perm((vector signed int)vec_lde(0, &rgb11), vec_splat_s32(0), vec_lvsl(0, &rgb11));
+
+ /* interleave color01 and color00 at the byte level */
+ color01 = (rgbint)vec_mergeh((vector signed char)color01, (vector signed char)color00);
+ color11 = (rgbint)vec_mergeh((vector signed char)color11, (vector signed char)color10);
+ color01 = (rgbint)vec_mergeh((vector signed char)vec_splat_s32(0), (vector signed char)color01);
+ color11 = (rgbint)vec_mergeh((vector signed char)vec_splat_s32(0), (vector signed char)color11);
+ color01 = (rgbint)vec_msum(color01, rgbvmx_statics.scale_table[u], vec_splat_s32(0));
+ color11 = (rgbint)vec_msum(color11, rgbvmx_statics.scale_table[u], vec_splat_s32(0));
+ color01 = (rgbint)vec_sr((vector signed int)color01, vec_splat_u32(1));
+ color11 = (rgbint)vec_sl((vector signed int)color11, vec_splat_u32(15));
+ color01 = vec_max(color01, color11);
+ color01 = (rgbint)vec_msum(color01, rgbvmx_statics.scale_table[v], vec_splat_s32(0));
+ color01 = (rgbint)vec_sr((vector signed int)color01, vec_splat_u32(15));
+ *color = vec_packs((vector signed int)color01, (vector signed int)color01);
+}
+
+
+/*-------------------------------------------------
+ rgbaint_bilinear_filter - bilinear filter between
+ four pixel values
+-------------------------------------------------*/
+
+INLINE void rgbaint_bilinear_filter(rgbaint *color, rgb_t rgb00, rgb_t rgb01, rgb_t rgb10, rgb_t rgb11, UINT8 u, UINT8 v)
+{
+ rgbaint color00 = (rgbaint)vec_perm((vector signed int)vec_lde(0, &rgb00), vec_splat_s32(0), vec_lvsl(0, &rgb00));
+ rgbaint color01 = (rgbaint)vec_perm((vector signed int)vec_lde(0, &rgb01), vec_splat_s32(0), vec_lvsl(0, &rgb01));
+ rgbaint color10 = (rgbaint)vec_perm((vector signed int)vec_lde(0, &rgb10), vec_splat_s32(0), vec_lvsl(0, &rgb10));
+ rgbaint color11 = (rgbaint)vec_perm((vector signed int)vec_lde(0, &rgb11), vec_splat_s32(0), vec_lvsl(0, &rgb11));
+
+ /* interleave color01 and color00 at the byte level */
+ color01 = (rgbaint)vec_mergeh((vector signed char)color01, (vector signed char)color00);
+ color11 = (rgbaint)vec_mergeh((vector signed char)color11, (vector signed char)color10);
+ color01 = (rgbaint)vec_mergeh((vector signed char)vec_splat_s32(0), (vector signed char)color01);
+ color11 = (rgbaint)vec_mergeh((vector signed char)vec_splat_s32(0), (vector signed char)color11);
+ color01 = (rgbaint)vec_msum(color01, rgbvmx_statics.scale_table[u], vec_splat_s32(0));
+ color11 = (rgbaint)vec_msum(color11, rgbvmx_statics.scale_table[u], vec_splat_s32(0));
+ color01 = (rgbaint)vec_sr((vector signed int)color01, vec_splat_u32(1));
+ color11 = (rgbaint)vec_sl((vector signed int)color11, vec_splat_u32(15));
+ color01 = vec_max(color01, color11);
+ color01 = (rgbaint)vec_msum(color01, rgbvmx_statics.scale_table[v], vec_splat_s32(0));
+ color01 = (rgbaint)vec_sr((vector signed int)color01, vec_splat_u32(15));
+ *color = vec_packs((vector signed int)color01, (vector signed int)color01);
+}
+
+// altivec.h somehow redefines "bool" in a bad way on PowerPC Mac OS X. really.
+#ifdef SDLMAME_MACOSX
+#undef vector
+#undef pixel
+#undef bool
+#endif
+
+#endif /* __RGBVMX__ */