From 2702c90d7a39fca2a3319c5e915fd290cb31fc70 Mon Sep 17 00:00:00 2001 From: Radosław Kujawa Date: Fri, 17 Jul 2026 14:54:32 +0200 Subject: Initial import. --- src/mesa/ppc/rlvec.c | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 src/mesa/ppc/rlvec.c (limited to 'src/mesa/ppc/rlvec.c') 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 +#include +#include + +#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 +} -- cgit