diff options
| author | Radosław Kujawa <radoslaw.kujawa@c0ff33.net> | 2026-07-17 14:54:32 +0200 |
|---|---|---|
| committer | Radosław Kujawa <radoslaw.kujawa@c0ff33.net> | 2026-07-17 14:54:32 +0200 |
| commit | 2702c90d7a39fca2a3319c5e915fd290cb31fc70 (patch) | |
| tree | 283c4d851efef7e3a7cd03ba80c87e2bffcdbb2c /src/mesa/ppc | |
| parent | 836167945ec2c7ad5acdf0aa17ce35ec1b9428a6 (diff) | |
Initial import.
Diffstat (limited to 'src/mesa/ppc')
| -rw-r--r-- | src/mesa/ppc/ppc_xform.c | 46 | ||||
| -rw-r--r-- | src/mesa/ppc/ppc_xform.h | 6 | ||||
| -rw-r--r-- | src/mesa/ppc/rlvec.c | 185 | ||||
| -rw-r--r-- | src/mesa/ppc/rlvec.h | 62 | ||||
| -rw-r--r-- | src/mesa/ppc/rlvec_ppc.S | 257 |
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__ */ |
