aboutsummaryrefslogtreecommitdiff
path: root/src/mesa/ppc/rlvec.c
diff options
context:
space:
mode:
authorRadosław Kujawa <radoslaw.kujawa@c0ff33.net>2026-07-17 14:54:32 +0200
committerRadosław Kujawa <radoslaw.kujawa@c0ff33.net>2026-07-17 14:54:32 +0200
commit2702c90d7a39fca2a3319c5e915fd290cb31fc70 (patch)
tree283c4d851efef7e3a7cd03ba80c87e2bffcdbb2c /src/mesa/ppc/rlvec.c
parent836167945ec2c7ad5acdf0aa17ce35ec1b9428a6 (diff)
Initial import.
Diffstat (limited to 'src/mesa/ppc/rlvec.c')
-rw-r--r--src/mesa/ppc/rlvec.c185
1 files changed, 185 insertions, 0 deletions
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
+}