aboutsummaryrefslogtreecommitdiff
path: root/src/mesa/ppc
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/ppc')
-rw-r--r--src/mesa/ppc/ppc_xform.c46
-rw-r--r--src/mesa/ppc/ppc_xform.h6
-rw-r--r--src/mesa/ppc/rlvec.c185
-rw-r--r--src/mesa/ppc/rlvec.h62
-rw-r--r--src/mesa/ppc/rlvec_ppc.S257
5 files changed, 556 insertions, 0 deletions
diff --git a/src/mesa/ppc/ppc_xform.c b/src/mesa/ppc/ppc_xform.c
new file mode 100644
index 0000000..966798c
--- /dev/null
+++ b/src/mesa/ppc/ppc_xform.c
@@ -0,0 +1,46 @@
+#include "ppc_xform.h"
+
+#ifdef USE_PPC_ASM
+
+#include "glheader.h"
+#include "math/m_xform.h"
+
+#include "rlvec.h"
+
+static void _XFORMAPI
+ppc_transform_points3_general(GLvector4f *to_vec, const GLfloat m[16],
+ const GLvector4f *from_vec)
+{
+
+ rlvec.xform_points3((GLfloat *)to_vec->start, m,
+ (const GLfloat *)from_vec->start, from_vec->stride,
+ from_vec->count);
+ to_vec->size = 4;
+ to_vec->flags |= VEC_SIZE_4;
+ to_vec->count = from_vec->count;
+}
+
+void
+_mesa_init_all_ppc_transform_asm(void)
+{
+
+ rlvec_init();
+
+ /*
+ * points3 = the glVertex3f-class path.
+ */
+ _mesa_transform_tab[3][MATRIX_GENERAL] =
+ ppc_transform_points3_general;
+ _mesa_transform_tab[3][MATRIX_PERSPECTIVE] =
+ ppc_transform_points3_general;
+ _mesa_transform_tab[3][MATRIX_3D] =
+ ppc_transform_points3_general;
+ _mesa_transform_tab[3][MATRIX_3D_NO_ROT] =
+ ppc_transform_points3_general;
+ _mesa_transform_tab[3][MATRIX_2D] =
+ ppc_transform_points3_general;
+ _mesa_transform_tab[3][MATRIX_2D_NO_ROT] =
+ ppc_transform_points3_general;
+}
+
+#endif /* USE_PPC_ASM */
diff --git a/src/mesa/ppc/ppc_xform.h b/src/mesa/ppc/ppc_xform.h
new file mode 100644
index 0000000..6f64f7b
--- /dev/null
+++ b/src/mesa/ppc/ppc_xform.h
@@ -0,0 +1,6 @@
+#ifndef PPC_XFORM_H
+#define PPC_XFORM_H
+
+extern void _mesa_init_all_ppc_transform_asm(void);
+
+#endif
diff --git a/src/mesa/ppc/rlvec.c b/src/mesa/ppc/rlvec.c
new file mode 100644
index 0000000..929bafc
--- /dev/null
+++ b/src/mesa/ppc/rlvec.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2026 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Radoslaw Kujawa.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Canonical rlvec CPU vertex kernels for the verite driver. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "rlvec.h"
+
+static void
+xform_points3_c(float *to, const float m[16], const float *from,
+ int from_stride, int count)
+{
+ int i;
+
+ for (i = 0; i < count; i++) {
+ const float *o = (const float *)((const char *)from +
+ (size_t)i * from_stride);
+ float x = o[0], y = o[1], z = o[2];
+ float *d = to + i * 4;
+
+ d[0] = m[0] * x + m[4] * y + m[8] * z + m[12];
+ d[1] = m[1] * x + m[5] * y + m[9] * z + m[13];
+ d[2] = m[2] * x + m[6] * y + m[10] * z + m[14];
+ d[3] = m[3] * x + m[7] * y + m[11] * z + m[15];
+ }
+}
+
+static uint32_t
+outcode5_c(uint8_t *oc, uint32_t *and_out, const float *clip, int count)
+{
+ uint32_t or_acc = 0, and_acc = 0x1f;
+ int i;
+
+ for (i = 0; i < count; i++) {
+ const float *c = clip + i * 4;
+ float x = c[0], y = c[1], z = c[2], w = c[3];
+ uint32_t o = 0;
+
+ if (z + w < 0.0f)
+ o |= 0x01;
+ if (w + x < 0.0f)
+ o |= 0x02;
+ if (w - x < 0.0f)
+ o |= 0x04;
+ if (w + y < 0.0f)
+ o |= 0x08;
+ if (w - y < 0.0f)
+ o |= 0x10;
+ oc[i] = (uint8_t)o;
+ or_acc |= o;
+ and_acc &= o;
+ }
+ *and_out = and_acc;
+ return or_acc;
+}
+
+static void
+project_c(float *out9, const float *clip, const float *attr,
+ const float k[8], int count)
+{
+ int i;
+
+ for (i = 0; i < count; i++) {
+ const float *c = clip + i * 4;
+ const float *a = attr + i * 6;
+ float *s = out9 + i * 9;
+ float q = 1.0f / c[3];
+ float zz;
+
+ s[0] = a[0]; s[1] = a[1]; s[2] = a[2];
+ s[3] = k[0] + k[1] * (c[0] * q);
+ s[4] = k[2] - k[3] * (c[1] * q);
+ zz = k[4] + k[5] * (c[2] * q);
+ if (zz < 0.0f)
+ zz = 0.0f;
+ if (zz > 65000.0f)
+ zz = 65000.0f;
+ s[5] = zz;
+ s[6] = a[4] * k[6];
+ s[7] = a[5] * k[7];
+ s[8] = q;
+ }
+}
+
+static uint32_t *
+emit_tris_c(uint32_t *dst, const float *verts9, const uint8_t *idx,
+ int ntris, uint32_t hdr)
+{
+ int t, k;
+
+ for (t = 0; t < ntris; t++) {
+ *dst++ = hdr;
+ for (k = 0; k < 3; k++) {
+ memcpy(dst, verts9 +
+ (uint32_t)idx[t * 3 + k] * 9,
+ 9 * sizeof(float));
+ dst += 9;
+ }
+ }
+ return dst;
+}
+
+const struct rlvec_ops rlvec_c = {
+ xform_points3_c,
+ outcode5_c,
+ project_c,
+ emit_tris_c,
+};
+
+#ifdef RLVEC_PPC
+rlvec_xform_points3_fn rlvec_xform_points3_ppc;
+rlvec_outcode5_fn rlvec_outcode5_ppc;
+rlvec_emit_tris_fn rlvec_emit_tris_ppc;
+
+const struct rlvec_ops rlvec_ppc = {
+ rlvec_xform_points3_ppc,
+ outcode5_c,
+ project_c,
+ rlvec_emit_tris_ppc,
+};
+#endif
+
+struct rlvec_ops rlvec;
+
+void
+rlvec_init(void)
+{
+ static int done;
+ const char *noasm;
+
+ if (done)
+ return;
+ done = 1;
+ rlvec = rlvec_c;
+#ifdef RLVEC_PPC
+ rlvec = rlvec_ppc;
+ noasm = getenv("RLGL_NOASM");
+ if (noasm != NULL) {
+ if (strcmp(noasm, "1") == 0) {
+ rlvec = rlvec_c;
+ fprintf(stderr, "rlvec: all-C forced\n");
+ } else {
+ if (strstr(noasm, "xform") != NULL)
+ rlvec.xform_points3 = rlvec_c.xform_points3;
+ if (strstr(noasm, "outcode") != NULL)
+ rlvec.outcode5 = rlvec_c.outcode5;
+ if (strstr(noasm, "project") != NULL)
+ rlvec.project = rlvec_c.project;
+ if (strstr(noasm, "emit") != NULL)
+ rlvec.emit_tris = rlvec_c.emit_tris;
+ fprintf(stderr, "rlvec: C forced for: %s\n", noasm);
+ }
+ }
+#else
+ (void)noasm;
+#endif
+}
diff --git a/src/mesa/ppc/rlvec.h b/src/mesa/ppc/rlvec.h
new file mode 100644
index 0000000..bd0286a
--- /dev/null
+++ b/src/mesa/ppc/rlvec.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2026 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Radoslaw Kujawa.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RLVEC_H
+#define RLVEC_H
+
+#include <stdint.h>
+
+typedef void rlvec_xform_points3_fn(float *to, const float m[16],
+ const float *from, int from_stride, int count);
+
+typedef uint32_t rlvec_outcode5_fn(uint8_t *oc, uint32_t *and_out,
+ const float *clip, int count);
+
+typedef void rlvec_project_fn(float *out9, const float *clip,
+ const float *attr, const float k[8], int count);
+
+typedef uint32_t *rlvec_emit_tris_fn(uint32_t *dst, const float *verts9,
+ const uint8_t *idx, int ntris, uint32_t hdr);
+
+struct rlvec_ops {
+ rlvec_xform_points3_fn *xform_points3;
+ rlvec_outcode5_fn *outcode5;
+ rlvec_project_fn *project;
+ rlvec_emit_tris_fn *emit_tris;
+};
+
+extern struct rlvec_ops rlvec; /* active table */
+extern const struct rlvec_ops rlvec_c; /* portable reference */
+#ifdef RLVEC_PPC
+extern const struct rlvec_ops rlvec_ppc; /* rlvec_ppc.S */
+#endif
+
+void rlvec_init(void);
+
+#endif /* RLVEC_H */
diff --git a/src/mesa/ppc/rlvec_ppc.S b/src/mesa/ppc/rlvec_ppc.S
new file mode 100644
index 0000000..c2ee9c8
--- /dev/null
+++ b/src/mesa/ppc/rlvec_ppc.S
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2026 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Radoslaw Kujawa.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * rlvec_ppc.S - e300 (603e-class) kernels for rlvec.
+ */
+#ifdef __powerpc__
+
+ .machine ppc
+ .text
+
+/*
+ * void rlvec_xform_points3_ppc(float *to r3,
+ * const float m[16] r4,
+ * const float *from r5,
+ * int from_stride r6,
+ * int count r7)
+ *
+ * Matrix held in f14-f29 (m0..m15 in order), per vertex the four
+ * chains d0..d3 interleave: fmuls + 2*fmadds + fadds each, mirroring
+ * the C contraction (t = m[c]*x; t += m[4+c]*y; t += m[8+c]*z;
+ * t += m[12+c]) for best-effort bit parity.
+ */
+ .globl rlvec_xform_points3_ppc
+ .type rlvec_xform_points3_ppc,@function
+rlvec_xform_points3_ppc:
+ cmpwi %r7, 0
+ blelr
+ stwu %r1, -144(%r1)
+ stfd %f14, 16(%r1)
+ stfd %f15, 24(%r1)
+ stfd %f16, 32(%r1)
+ stfd %f17, 40(%r1)
+ stfd %f18, 48(%r1)
+ stfd %f19, 56(%r1)
+ stfd %f20, 64(%r1)
+ stfd %f21, 72(%r1)
+ stfd %f22, 80(%r1)
+ stfd %f23, 88(%r1)
+ stfd %f24, 96(%r1)
+ stfd %f25, 104(%r1)
+ stfd %f26, 112(%r1)
+ stfd %f27, 120(%r1)
+ stfd %f28, 128(%r1)
+ stfd %f29, 136(%r1)
+
+ lfs %f14, 0(%r4) /* m0 */
+ lfs %f15, 4(%r4)
+ lfs %f16, 8(%r4)
+ lfs %f17, 12(%r4)
+ lfs %f18, 16(%r4) /* m4 */
+ lfs %f19, 20(%r4)
+ lfs %f20, 24(%r4)
+ lfs %f21, 28(%r4)
+ lfs %f22, 32(%r4) /* m8 */
+ lfs %f23, 36(%r4)
+ lfs %f24, 40(%r4)
+ lfs %f25, 44(%r4)
+ lfs %f26, 48(%r4) /* m12 */
+ lfs %f27, 52(%r4)
+ lfs %f28, 56(%r4)
+ lfs %f29, 60(%r4)
+
+ mtctr %r7
+1: lfs %f0, 0(%r5) /* x */
+ lfs %f1, 4(%r5) /* y */
+ lfs %f2, 8(%r5) /* z */
+ add %r5, %r5, %r6
+ dcbt 0, %r5 /* next input row */
+
+ fmuls %f3, %f14, %f0
+ fmuls %f4, %f15, %f0
+ fmuls %f5, %f16, %f0
+ fmuls %f6, %f17, %f0
+ fmadds %f3, %f18, %f1, %f3
+ fmadds %f4, %f19, %f1, %f4
+ fmadds %f5, %f20, %f1, %f5
+ fmadds %f6, %f21, %f1, %f6
+ fmadds %f3, %f22, %f2, %f3
+ fmadds %f4, %f23, %f2, %f4
+ fmadds %f5, %f24, %f2, %f5
+ fmadds %f6, %f25, %f2, %f6
+ fadds %f3, %f3, %f26
+ fadds %f4, %f4, %f27
+ fadds %f5, %f5, %f28
+ fadds %f6, %f6, %f29
+
+ stfs %f3, 0(%r3)
+ stfs %f4, 4(%r3)
+ stfs %f5, 8(%r3)
+ stfs %f6, 12(%r3)
+ addi %r3, %r3, 16
+ bdnz 1b
+
+ lfd %f14, 16(%r1)
+ lfd %f15, 24(%r1)
+ lfd %f16, 32(%r1)
+ lfd %f17, 40(%r1)
+ lfd %f18, 48(%r1)
+ lfd %f19, 56(%r1)
+ lfd %f20, 64(%r1)
+ lfd %f21, 72(%r1)
+ lfd %f22, 80(%r1)
+ lfd %f23, 88(%r1)
+ lfd %f24, 96(%r1)
+ lfd %f25, 104(%r1)
+ lfd %f26, 112(%r1)
+ lfd %f27, 120(%r1)
+ lfd %f28, 128(%r1)
+ lfd %f29, 136(%r1)
+ addi %r1, %r1, 144
+ blr
+ .size rlvec_xform_points3_ppc,.-rlvec_xform_points3_ppc
+
+/*
+ * uint32_t rlvec_outcode5_ppc(uint8_t *oc r3,
+ * uint32_t *and_out r4,
+ * const float *clip r5,
+ * int count r6)
+ */
+ .globl rlvec_outcode5_ppc
+ .type rlvec_outcode5_ppc,@function
+rlvec_outcode5_ppc:
+ li %r10, 0 /* or accumulator */
+ li %r11, 0x1f /* and accumulator */
+ cmpwi %r6, 0
+ ble 2f
+ lis %r9, .Lfzero@ha
+ lfs %f0, .Lfzero@l(%r9)
+ mtctr %r6
+1: lfs %f1, 0(%r5) /* x */
+ lfs %f2, 4(%r5) /* y */
+ lfs %f3, 8(%r5) /* z */
+ lfs %f4, 12(%r5) /* w */
+ addi %r5, %r5, 16
+ fadds %f5, %f3, %f4 /* z+w -> bit 0 */
+ fadds %f6, %f4, %f1 /* w+x -> bit 1 */
+ fsubs %f7, %f4, %f1 /* w-x -> bit 2 */
+ fadds %f8, %f4, %f2 /* w+y -> bit 3 */
+ fsubs %f9, %f4, %f2 /* w-y -> bit 4 */
+ fcmpu %cr0, %f5, %f0
+ fcmpu %cr1, %f6, %f0
+ fcmpu %cr5, %f7, %f0
+ fcmpu %cr6, %f8, %f0
+ fcmpu %cr7, %f9, %f0
+ mfcr %r8
+ /*
+ * LT bits (LSB numbering): cr0=31 cr1=27 cr5=11 cr6=7 cr7=3;
+ * gather to outcode bits 0..4.
+ */
+ rlwinm %r9, %r8, 1, 31, 31
+ rlwinm %r12, %r8, 6, 30, 30
+ or %r9, %r9, %r12
+ rlwinm %r12, %r8, 23, 29, 29
+ or %r9, %r9, %r12
+ rlwinm %r12, %r8, 28, 28, 28
+ or %r9, %r9, %r12
+ rlwinm %r12, %r8, 1, 27, 27
+ or %r9, %r9, %r12
+ stb %r9, 0(%r3)
+ addi %r3, %r3, 1
+ or %r10, %r10, %r9
+ and %r11, %r11, %r9
+ bdnz 1b
+2: stw %r11, 0(%r4)
+ mr %r3, %r10
+ blr
+ .size rlvec_outcode5_ppc,.-rlvec_outcode5_ppc
+
+/*
+ * uint32_t *rlvec_emit_tris_ppc(uint32_t *dst r3,
+ * const float *verts9 r4,
+ * const uint8_t *idx r5,
+ * int ntris r6,
+ * uint32_t hdr r7)
+ */
+ .globl rlvec_emit_tris_ppc
+ .type rlvec_emit_tris_ppc,@function
+
+/* copy 9 words from (%r8) to (%r3) and advance %r3, GPRs only */
+.macro COPY9
+ lwz %r9, 0(%r8)
+ lwz %r10, 4(%r8)
+ lwz %r11, 8(%r8)
+ stw %r9, 0(%r3)
+ stw %r10, 4(%r3)
+ stw %r11, 8(%r3)
+ lwz %r9, 12(%r8)
+ lwz %r10, 16(%r8)
+ lwz %r11, 20(%r8)
+ stw %r9, 12(%r3)
+ stw %r10, 16(%r3)
+ stw %r11, 20(%r3)
+ lwz %r9, 24(%r8)
+ lwz %r10, 28(%r8)
+ lwz %r11, 32(%r8)
+ stw %r9, 24(%r3)
+ stw %r10, 28(%r3)
+ stw %r11, 32(%r3)
+ addi %r3, %r3, 36
+.endm
+
+rlvec_emit_tris_ppc:
+ cmpwi %r6, 0
+ blelr
+ mtctr %r6
+1: stw %r7, 0(%r3)
+ addi %r3, %r3, 4
+ lbz %r8, 0(%r5)
+ mulli %r8, %r8, 36
+ add %r8, %r4, %r8
+ COPY9
+ lbz %r8, 1(%r5)
+ mulli %r8, %r8, 36
+ add %r8, %r4, %r8
+ COPY9
+ lbz %r8, 2(%r5)
+ mulli %r8, %r8, 36
+ add %r8, %r4, %r8
+ COPY9
+ addi %r5, %r5, 3
+ bdnz 1b
+ blr
+ .size rlvec_emit_tris_ppc,.-rlvec_emit_tris_ppc
+
+ .section .rodata
+ .align 2
+.Lfzero:
+ .float 0.0
+
+#endif /* __powerpc__ */