Files
TeslaRel410/sda4/DPL3/VRENDER/PXPL5SUP/PXPL5TRI.SS-
T
CydandClaude Fable 5 db7745fcd0 sda4: commit the Glaze developer hard-drive dump
Un-ignored: the dev drive is the ground truth the restoration and
emulator work constantly reference (DPL3/LIBDPL + VRENDER i860 renderer
source, BT/RP live+dev game trees, VGL_LABS pod boot, scene/audio
content). Kept in-repo for the pod-owner community.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 19:41:15 -05:00

2306 lines
68 KiB
Plaintext

//{{{ about this code
//
//
// The triangle functions are C-callable, and simply chain together
// calls to other functions in this module, which do not themselves
// adhere to C calling conventions and register allocation
//
// These are the triangle functions - for each type of triangle
// rendereable by the system, a different function exists. The currently
// implemented set of triangles is
//
// _tri_zb_rgb
// _tri_zb_rgb_t
// _tri_zb_d_s
// _tri_zb_d_s_t
// _tri_zb_f
// _tri_zb_f_t
// _tri_zb_d
// _tri_zb_d_t
//
// which are enough to cover PAZ 1 shading model, white light PAZ 2
// shading model, optimized lightscape / Eindhoven radiosity, skyfly
// texturing, white light texturing
//}}}
#include "u:\projects\dbi0150\dbi0151\ucode\igc_opco.h"
#include "\pazpl5\pxpl5sup\pxplmacr.h"
#include "\pazpl5\pxpl5sup\divpxmap.h"
#include "\pazpl5\pxpl5sup\dmaengn.h"
#include "\pazpl5\pxpl5sup\register.h"
//{{{ triangle function entry and exit
#define triangle_entry(label) \
fst.d f2, -8(sp); \
fst.d f4, -16(sp); \
fst.d f6, -24(sp); \
st.l r4, -28(sp); \
st.l r5, -32(sp); \
st.l r6, -36(sp); \
st.l r7, -40(sp); \
st.l r8, -44(sp); \
st.l r9, -48(sp); \
st.l r10, -52(sp); \
st.l r11, -56(sp); \
st.l r12, -60(sp); \
st.l r13, -64(sp); \
st.l r14, -68(sp); \
st.l r15, -72(sp); \
st.l r1, -76(sp); \
st.l r3, -80(sp); \
mov coeffParam, rcoeffsave; \
adds -96, sp, sp; \
fmov.ss fparam1, fmaterial; \
adds -4, iparam1, rcoeffptr
#define triangle_exit \
adds 96, sp, sp; \
adds 4, rcoeffptr, iparam1; \
ld.l -80(sp), r3; \
ld.l -76(sp), r1; \
ld.l -72(sp), r15; \
ld.l -68(sp), r14; \
ld.l -64(sp), r13; \
ld.l -60(sp), r12; \
ld.l -56(sp), r11; \
ld.l -52(sp), r10; \
ld.l -48(sp), r9; \
ld.l -44(sp), r8; \
ld.l -40(sp), r7; \
ld.l -36(sp), r6; \
ld.l -32(sp), r5; \
ld.l -28(sp), r4; \
fld.d -24(sp), f6; \
fld.d -16(sp), f4; \
bri r1; \
fld.d -8(sp), f2; \
#define fix_rcoeffptr(long) \
adds ((((long*8)+31)&(0xffffffe0)) - 4), rcoeffsave, rcoeffptr
//}}}
//{{{ some pxpl5 comments and defines
//
// rendering is split into 2 phases; scan-conversion and shading. only
// scan-conversion uses the tree; shading operates SIMD on all pixels,
// regardless of their x,y locations.
//
// these functions deal only with scan-conversion. we therefore need
// access to only a very restricted subset of pxpl5 opcodes; those
// for edgizing, and those for planarizing, plus some enable-manipulation
// opcodes.
//
// to render a triangle, we perform 4 basic operations;
//
// a) initialize enable flag
// b) enable all interior pixels
// c) scan-convert screen-space variables into memory
// d) perform clean-up housekeeping
//
// only c) is ever performed more than once per primitive
//
// a) involves either
// clearing enable flag
// CLRENABS()
// or loading enable from memory
// MEMintoENAB(src)
// MEMBARintoENAB(src)
//
// b) involves executing the edgize expressions, which are either
// TREEgeZERO()
// or TREEltZERO()
// dependent on the direction of the edge
//
// c) involves just two instruction
// TREEintoMEM(dst,len)
// or in cases of potential over / underflow
// TREECLMPintoMEM(dst,len)
//
// d) involves storing some pixel type information, intrinsic colour,
// texture ID etc into memory; just one instruction
// SCAintoMEM(dst, dlen)
// and/ saving enable flag into memory;
// or ENABintoMEM(dst)
//
//
//}}}
//{{{ declare offsets in VERTEX structure
//
// Note new placement of next field - ensures double-alignment of
// position, normal and texcoords
//
// typedef struct s_vert {
// POINT position;
// POINT planeEqn;
// float normcol [3];
// struct s_vert *next;
// float texcoords [2];
// } VERTEX;
#define VERT_position_offs 0
#define VERT_plane_offs 16
#define VERT_normal_offs 32
#define VERT_tex_offs 48
#define VERT_size 56
#define VERT_x_offs ((VERT_position_offs) + 0)
#define VERT_y_offs ((VERT_position_offs) + 4)
#define VERT_z_offs ((VERT_position_offs) + 8)
#define VERT_w_offs ((VERT_position_offs) + 12)
#define VERT_r_offs (VERT_normal_offs)
#define VERT_g_offs ((VERT_normal_offs)+4)
#define VERT_b_offs ((VERT_normal_offs)+8)
#define VERT_diff_offs (VERT_r_offs)
#define VERT_spec_offs (VERT_g_offs)
#define VERT_tex_u_offs ((VERT_tex_offs)+0)
#define VERT_tex_v_offs ((VERT_tex_offs)+4)
//}}}
// /////////////////////////////////
// triangle support code
// preplane, planarize, binitize
//{{{ preplanarize_fn_p
//
//
//
.globl _preplanarize_fn_p
.align 8
//
// preplanarize_fn ( float *coeffs, unused, v1, v2, v3, v4 );
//
// preplanarize sets up all of the triangle code
//
// we need to cache all x,y into registers,
// precompute x23, x31, x12 and C, and determine
// minimax x, y for the triangle
//
// VICIOUS - returns TRIV_REJECT in r31
//
//
_preplanarize_fn_p::
//
// scattered amongst these minimax tests are the subtractions
// to precompute v2[Y] - v3[Y] etc for computing 1.0f/C
//
// p->x23=v2x - v3x;
// p->x31=v3x - v1x;
// p->x12=v1x - v2x;
//
#define max_screen_x fx4
#define max_screen_y fy4
fld.d VERT_position_offs(rv1), fx1
fld.d VERT_position_offs(rv2), fx2
fld.d VERT_position_offs(rv3), fx3
orh ha%.C00037, r0, r31 // pre-load 2.0000e+00
fld.l l%.C00037(r31), ftmp3
orh ha%.C362436, r0, r31 // pre-load minimum area
fld.l l%.C362436(r31), ftmp1
orh ha%.Cmax_x, r0, r31
fld.d l%.Cmax_x(r31), max_screen_x
//
// orh ha%_screenize_rec, r0, r31
// or l%_screenize_rec, r31, r31
// fld.d 0(r31), fminx
// fld.d 8(r31), fmaxx
// fld.l 16(r31), ftexscale
//
// do minimax in x,y and tex scale from z
//
//
pfgt.ss fx1, fx2, f0
bc .x1_bigger
// so x1 < x2
pfgt.ss fx1, fx3, f0
bnc .x1_min
fmov.ss fx3, fminx
br .minimax_y
fmov.ss fx2, fmaxx
.x1_min:
// so x1<x2, and x1<x3, is x3>x2
pfgt.ss fx3, fx2, f0
bnc .x2_max
fmov.ss fx1, fminx
br .minimax_y
fmov.ss fx3, fmaxx
.x2_max:
fmov.ss fx1, fminx
br .minimax_y
fmov.ss fx2, fmaxx
.x1_bigger:
// so x2 < x1
pfgt.ss fx2, fx3, f0
bnc .x2_min
// so x2 < x1, and x3 < x2, so x3 min, x1 max
fmov.ss fx3, fminx
br .minimax_y
fmov.ss fx1, fmaxx
.x2_min:
// so x2<x1, and x2<x3, is x3>x1
pfgt.ss fx3, fx1, f0
bnc .x1_max
fmov.ss fx2, fminx
br .minimax_y
fmov.ss fx3, fmaxx
.x1_max:
fmov.ss fx2, fminx
br .minimax_y
fmov.ss fx1, fmaxx
// do y checks, and pre-load z-coords into fv1 etc.
.minimax_y:
pfgt.ss fy1, fy2, f0
fld.l (8+VERT_position_offs)(rv1), fv1
bc .y1_bigger
// so y1 < y2
pfgt.ss fy1, fy3, f0
fld.l (8+VERT_position_offs)(rv2), fv2
bnc .y1_min
fld.l (8+VERT_position_offs)(rv3), fv3
fmov.ss fy3, fminy
br .texscale_check
fmov.ss fy2, fmaxy
.y1_min:
// so y1<y2, and y1<y3, is y3>y2
pfgt.ss fy3, fy2, f0
fld.l (8+VERT_position_offs)(rv3), fv3
bnc .y2_max
fmov.ss fy1, fminy
br .texscale_check
fmov.ss fy3, fmaxy
.y2_max:
fmov.ss fy1, fminy
br .texscale_check
fmov.ss fy2, fmaxy
.y1_bigger:
// so y2 < y1
pfgt.ss fy2, fy3, f0
fld.l (8+VERT_position_offs)(rv2), fv2
bnc .y2_min
// so y2 < y1, and y3 < y2, so y3 min, y1 max
fmov.ss fy3, fminy
fld.l (8+VERT_position_offs)(rv3), fv3
br .texscale_check
fmov.ss fy1, fmaxy
.y2_min:
// so y2<y1, and y2<y3, is y3>y1
pfgt.ss fy3, fy1, f0
fld.l (8+VERT_position_offs)(rv3), fv3
bnc .y1_max
fmov.ss fy2, fminy
br .texscale_check
fmov.ss fy3, fmaxy
.y1_max:
fmov.ss fy2, fminy
// br .texscale_check
fmov.ss fy1, fmaxy
.texscale_check:
pfgt.ss fv1, fv2, f0
bc .z1_bigger
pfgt.ss fv3, fv2, f0
bc .z3_biggest
br .done_texscale
fmov.ss fv2, ftexscale
.z1_bigger:
pfgt.ss fv3, fv1, f0
bc .z3_biggest
br .done_texscale
fmov.ss fv1, ftexscale
.z3_biggest:
fmov.ss fv3, ftexscale
// now pipe up repeated expressions
.done_texscale:
pfsub.ss fy1, fy2, f0
pfsub.ss fy3, fy1, f0
pfsub.ss fy2, fy3, f0
pfsub.ss f0, f0, fy12
pfsub.ss f0, f0, fy31
pfsub.ss f0, f0, fy23
// repeated expressions fx32, fx13, fx21, fC
//
// The definitive planarization algorithm
//
// invC=1.0f / (fx1 * (fy2 - fy3)) +
// (fx2 * (fy3 - fy1)) +
// (fx3 * (fy1 - fy2));
//
// eqn[0]= invC*(fy1 * (fv3 - fv2)) +
// (fy2 * (fv1 - fv3)) +
// (fy3 * (fv2 - fv1));
//
// eqn[1]= invC*(fv1 * (fx3 - fx2)) +
// (fv2 * (fx1 - fx3)) +
// (fv3 * (fx2 - fx1));
//
// eqn[2]= invC*(fx1*((fy2*fv3) - (fy3*fv2))) +
// (fx2*((fy3*fv1) - (fy1*fv3))) +
// (fx3*((fy1*fv2) - (fy2*fv1)));
//
// 11 ticks all told
pfmul.ss fx1, fy23, f0
pfmul.ss fx2, fy31, f0
pfmul.ss fx3, fy12, f0
// use T-reg as staging post...
rat1s2.ss fx1, fx3, f0
i2pt.ss f0, f0, f0
rat1s2.ss fx2, fx1, f0
pfsub.ss fx3, fx2, fx13
i2apt.ss f0, f0, f0
pfadd.ss f0, f0, fx21
pfadd.ss f0, f0, fx32
pfadd.ss f0, f0, fC
// ******************************************
// clamp minimax against screen max coordinates
// now get real minimax xy for binning
//
// firstly check triv rejection, max < 0 etc.
//
pfgt.ss ftmp1, fmaxx, f0
bc .triv_reject
pfgt.ss ftmp1, fmaxy, f0
bc .triv_reject
pfgt.ss fminx, max_screen_x, f0
bc .triv_reject
pfgt.ss fminy, max_screen_y, f0
bc .triv_reject
// now check binning
// get real minx
pfgt.ss fminx, f0, f0
bc .no_clamp_fminx
fmov.ss f0, fminx
.no_clamp_fminx::
// get real miny
pfgt.ss fminy, f0, f0
bc .no_clamp_fminy
fmov.ss f0, fminy
.no_clamp_fminy::
// get real maxx
pfgt.ss max_screen_x, fmaxx, f0
bc .no_clamp_fmaxx
fmov.ss max_screen_x, fmaxx
.no_clamp_fmaxx::
// get real maxy
pfgt.ss max_screen_y, fmaxy, f0
bc .no_clamp_fmaxy
fmov.ss max_screen_y, fmaxy
.no_clamp_fmaxy::
// if entire patch is on-screen, we can just come here
// ok, lets think about the minimum area test
// we have in registers x13 x21 x32
// and y31 y12 y23
//
//
// we need to check that (x21*y21) + (x32*y32) + (x13*y13) < min
// SO we compute (x21*y12 + x32*y23 + x13*y31) > min
//
// around 18 tick overhead, reduce to 12 ish by pfs
//
// fmul.ss fx21, fy12, ftmp1 // 3
// fmul.ss fx32, fy23, ftmp2 // 6
// fmul.ss fx13, fy31, ftmp3 // 9
// fadd.ss ftmp1, ftmp2, ftmp2 // 12
// fadd.ss ftmp3, ftmp2, ftmp2 // 15
// pfgt.ss ftmp2, ftmp1, f0 // 17
pfmul.ss fx21, fy12, f0 // 1
pfmul.ss fx32, fy23, f0 // 2
pfmul.ss fx13, fy31, f0 // 3
i2ap1.ss f0, f0, f0 // 4 last-stage mul into T
i2pt.ss f0, f0, f0 // 5 add last-stage mul and T
i2ap1.ss f0, f0, f0 // 6 last-stage mul into T again
pfadd.ss f0, f0, f0 // 7 adder stage3 now x21*y12
i2apt.ss f0, f0, f0 // 8 add adder 3 and T
pfadd.ss f0, f0, f0 // 9 adder stage2 now result
pfadd.ss f0, f0, f0 // 10 adder stage3 now result
pfadd.ss f0, f0, ftmp2 // 11
pfgt.ss ftmp2, ftmp1, f0 // 12
bnc .triv_reject
//
// straight out of the i860 prog ref man
//
// to iterate towards 1/V;
//
// G_new=G_old*(2.0f-(G_old*V))
//
// 20 ticks !? pretty poor
frcp.ss fC, ftmp1 // start 1.0 / fC - 2^-8
fmul.ss fC, ftmp1, ftmp2 // guess * divisor
// fld.l 16(r31), ftexscale
fsub.ss ftmp3, ftmp2, ftmp2 // 2 - (guess * divisor)
fld.l iparam2(rv1), fv1
fmul.ss ftmp1, ftmp2, ftmp1 // 2^-15
fld.l iparam2(rv2), fv2
fmul.ss fC, ftmp1, ftmp2 // guess * divisor
fsub.ss ftmp3, ftmp2, ftmp2 // 2 - (guess * divisor)
fld.l iparam2(rv3), fv3
fmul.ss ftmp1, ftmp2, fC // 2^-23 - run with it
// pre-compute opcode for edgize while multiply happens
pxpl5op_0_l(iparam1, Ix_TREEltZERO_L3)
pxpl5op_0_h(iparam1, Ix_TREEltZERO_L3)
bri r1
or 0x0, r0, r31
.triv_reject::
bri r1
or 0x1, r0, r31
//}}}
//{{{ _old_planarize_fn_p pipelined
//
// Hey Ho Lets Go!
//
// The definitive planarization algorithm
//
// invC=1.0f / (fx1 * (fy2 - fy3)) +
// (fx2 * (fy3 - fy1)) +
// (fx3 * (fy1 - fy2));
//
// eqn[0]= invC*(fy1 * (fv3 - fv2)) +
// (fy2 * (fv1 - fv3)) +
// (fy3 * (fv2 - fv1));
//
// a = fv3 - fv2
// b = fv1 - fv3
// c = fv2 - fv1
// d = fy1 * a
// e = fy2 * b
// f = fy3 * c
// g = d + e
// h = g + f
// eqn[0] = fC * h
//
// eqn[1]= invC*(fv1 * (fx3 - fx2)) +
// (fv2 * (fx1 - fx3)) +
// (fv3 * (fx2 - fx1));
//
// i = fv1 * fx32
// j = fv2 * fx13
// k = fv3 * fx21
// l = i + j
// m = k + l
// eqn[1] = fC * m
//
// eqn[2]= invC*(fx1*((fy2*fv3) - (fy3*fv2))) +
// (fx2*((fy3*fv1) - (fy1*fv3))) +
// (fx3*((fy1*fv2) - (fy2*fv1)));
//
// n = fy2 * fv3
// o = fy3 * fv2
// p = fy3 * fv1
// q = fy1 * fv3
// r = fy1 * fv2
// s = fy2 * fv1
// t = n - o
// u = p - q
// v = r - s
// w = fx1 * t
// x = fx2 * u
// y = fx3 * v
// z = w + x
// aa= y + z
// eqn[2] = invC * aa
//
#define ft1 ftmp1
#define ft2 ftmp2
#define ft3 ftmp3
.globl _old_planarize_fn_p
.globl _planarize_fn_p
.align 8
_old_planarize_fn_p::
_planarize_fn_p::
// m1 m2 m3 | T | a1 a2 a3 | KR | t1 t2 t3
pfmul.ss fy2, fv3, f0 // n ? ? | ? | ? ? ? | ? | ? ? ?
pfmul.ss fy3, fv2, f0 // o n ? | ? | ? ? ? | ? | ? ? ?
pfmul.ss fy3, fv1, f0 // p o n | ? | ? ? ? | ? | ? ? ?
mm12ttpm.ss fy1, fv3, f0 // q p o | n | ? ? ? | ? | ? ? ?
m12tsm.ss fy1, fv2, f0 // r q p | ? | t ? ? | ? | ? ? ?
mm12ttpm.ss fy2, fv1, f0 // s r q | p | ? t ? | ? | ? ? ?
m12tsm.ss fv1, fx32, f0 // i s r | ? | u ? t | ? | ? ? ?
pfsub.ss fv3, fv2, ft1 // i s r | ? | a u ? | ? | t ? ?
mm12ttpm.ss fv2, fx13, f0 // j i s | r | ? a u | ? | t ? ?
m12tsm.ss fv3, fx21, ft2 // k j i | ? | v ? a | ? | t u ?
pfmul.ss fx1, ft1, ft3 // w k j | ? | v ? a | ? | ? u i
pfmul.ss fx2, ft2, ft1 // x w k | ? | v ? a | ? | j ? i
pfadd.ss ft1, ft3, ft2 // x w k | ? | l v ? | ? | ? a ?
mm12mpm.ss fy1, ft2, ft3 // d x w | ? | ? l v | ? | ? ? k
d.pfsub.ss fv1, fv3, ft1 // d x w | ? | b ? l | ? | v ? k
nop
d.pfsub.ss fv2, fv1, ft2 // d x w | ? | c b ? | ? | v l k
fld.l iparam2(rv3), fv3
d.rat1p2.ss ft2, ft3, f0 // ? d x | w | m c b | ? | v ? ?
nop
d.m12tpm.ss fx3, ft1, ft2 // y ? d | ? | z m c | ? | ? b ?
nop
d.m12ttpa.ss fy2, ft2, ft1 // e y ? | d | ? z m | ? | c ? ?
fld.l iparam2(rv2), fv2
d.m12apm.ss fy3, ft1, ft2 // f e y | d | ? ? z | ? | ? m ?
nop
d.pfmul.ss fC, ft2, ft1 // e1 f e | d | ? ? z | ? | y ? ?
nop
d.r2pt.ss fC, f0, ft2 // ? e1 f | ? | g ? ? | ? | y z ?
fld.l iparam2(rv1), fv1
d.mrm1p2.ss ft1, ft2, ft3 // ? ? e1| ? | aa g ? | ? | ? ? f
nop
d.mm12mpm.ss f0, f0, ft2 // ? ? ? | ? | ? aa g | ? | ? e1 f
st.l iparam1, 4(rcoeffptr)
d.r2ap1.ss ft3, f0, f0 // ? ? ? | ? | h ? aa | ? | ? e1 ?
nop
d.ra1p2.ss f0, f0, f0 // e2 ? ? | ? | ? h ? | ? | ? e1 ?
nop
d.i2p1.ss f0, f0, f0 // ? e2 ? | ? | ? ? h | ? | ? e1 ?
fst.l ft2, 12(rcoeffptr)
d.rat1p2.ss f0, f0, f0
nop
d.mi2p1.ss f0, f0, ft1
nop
d.mi2p1.ss ft3, f0, f0
fst.l ft1, 16(rcoeffptr)++
mi2p1.ss f0, f0, ft3
bri r1
fnop
fst.l ft3, -8(rcoeffptr)
#undef ft1
#undef ft2
#undef ft3
//}}}
//{{{ locals defines for this fn
#define divpl5_xshift 6
#define divpl5_yshift 7
#define lbin r24
#define xbin r25
#define ycnt r26
#define xcnt r27
// leave xmin, max intact !
//
// these MUST be < r16 !!
//
#define usage r13
#define bin r14
#define bin_size 8
// head, tail
#define binchunk_size 2048
// DMA_opcodes[512]
// int usage
// *next
#define BIN_FULL 2032
// byte count of 254*2
#define usage_offs 2040
#define nextbin_offs 2044
#define head_offs 0
#define tail_offs 4
#define x_bins_shift 4
#define x_bins_bytes 128
// 16 bins in 1024
//}}}
//{{{ the incredibly expensive 'bin is full branch'
// dont panic -
// this branch is infrequent - happens every 256 triangles
// note that it can result in a call to malloc!
//
// if (bin->usage == BIN_FULL) {
// binchunk *nextbin=next_binchunk ();
//
// bin->DMA_opcodes[usage++]=(int) nextbin;
// bin->DMA_opcodes[usage++]=DMA_GOTO;
// bin=nextbin;
// xbin->tail=bin;
// usage=0;
// }
//
// damn, we enter C land here - push all registers onto stack
// note that floating-point registers are no longer needed
//
.align 8
bin_was_full::
st.l r16, -4(sp)
st.l r17, -8(sp)
st.l r18, -12(sp)
st.l r19, -16(sp)
st.l r20, -20(sp)
st.l r21, -24(sp)
st.l r22, -28(sp)
st.l r23, -32(sp)
st.l r24, -36(sp)
st.l r25, -40(sp)
st.l r26, -44(sp)
st.l r27, -48(sp)
st.l r28, -52(sp)
st.l r29, -56(sp)
st.l r30, -60(sp)
st.l r1, -64(sp)
st.l r4, -76(sp)
st.l r5, -80(sp)
st.l r6, -84(sp)
st.l r7, -88(sp)
st.l r8, -92(sp)
st.l r9, -96(sp)
st.l r10, -100(sp)
st.l r11, -104(sp)
st.l r12, -108(sp)
st.l r15, -120(sp)
call _next_binchunk
adds -128, sp, sp
// now iparam1 holds nextbin
// note that bin and usage are preserved after this call ( < r16)
adds usage, bin, r31 // construct pointer to coeff store
st.l iparam1, nextbin_offs(bin) // do linked list thing
mov iparam1, bin // return val from next_binchunk
st.l iparam1, 0(r31) // save it away
adds DMA_GOTO, r0, iparam1 // chain in new bin
st.l iparam1, 4(r31) // and save this opcode away
// lets restore registers
adds 128, sp, sp
ld.l -4(sp), r16
ld.l -8(sp), r17
ld.l -12(sp), r18
ld.l -16(sp), r19
ld.l -20(sp), r20
ld.l -24(sp), r21
ld.l -28(sp), r22
ld.l -32(sp), r23
ld.l -36(sp), r24
ld.l -40(sp), r25
ld.l -44(sp), r26
ld.l -48(sp), r27
ld.l -52(sp), r28
ld.l -56(sp), r29
ld.l -60(sp), r30
ld.l -64(sp), r1
ld.l -76(sp), r4
ld.l -80(sp), r5
ld.l -84(sp), r6
ld.l -88(sp), r7
ld.l -92(sp), r8
ld.l -96(sp), r9
ld.l -100(sp), r10
ld.l -104(sp), r11
ld.l -108(sp), r12
ld.l -120(sp), r15
// so now to patch up the new bin - simply fall thru
// into the bin not full branch
mov r0, usage
bri r1
st.l bin, tail_offs(xbin)
//}}}
//{{{ safe_binitize_fn pipelined intro
// void safe_binitize ( int macro_lo, int macro_hi,
// float fminx, float fminy,
// float fmaxx, float fmaxy,
// int screen_bins_x )
//
// binitize a triangle known to be on-screen, i.e minimax x y
// are within screen-space
//
.globl _safe_binitize_fn
.align 8
// binitize a primitive
_safe_binitize_fn::
//
// NB fxfr MUST have NOP as companion, or you are shafted
//
// minx=(int) fminx;
// miny=(int) fminy;
// maxx=(int) fmaxx;
// maxy=(int) fmaxy;
// minx >>= divpl5_xshift;
// miny >>= divpl5_yshift;
// maxx >>= divpl5_xshift;
// maxy >>= divpl5_yshift;
// {
// screenbin *lbin=&screenbins[(miny<<bins_shift)+minx];
// screenbin *xbin=lbin;
// ==> go mango
.align 8
d.pftrunc.sd fminx, f0
orh ha%_screenbins, r0, r31
d.pftrunc.sd fminy, f0
ld.l l%_screenbins(r31), r31
d.pftrunc.sd fmaxx, f0
ixfr iparam1, f24 // fv1
d.pftrunc.sd fmaxy, ftmp1
ixfr iparam2, f25 // fv2
d.fxfr ftmp1, itmp1
nop
d.pfadd.sd f0, f0, ftmp3
shr divpl5_xshift, itmp1, iminx
d.fxfr ftmp3, itmp2
nop
d.pfadd.sd f0, f0, ftmp1
shr divpl5_yshift, itmp2, iminy
d.fxfr ftmp1, itmp1
nop
pfadd.sd f0, f0, ftmp3
shr divpl5_xshift, itmp1, imaxx
fxfr ftmp3, itmp2
nop
shl x_bins_shift, iminy, lbin
adds iminx, lbin, lbin
shr divpl5_yshift, itmp2, imaxy
// each bin is head/tail pointer, so 8 bytes per bin entry
shl 3, lbin, lbin
adds r31, lbin, lbin
subs imaxy, iminy, ycnt
// while (ycnt)
_y_loop::
mov lbin, xbin
_y_loopdb::
subs imaxx, iminx, xcnt
// while (xcnt)
_x_loop::
ld.l tail_offs(xbin), bin
_x_loopdb::
ld.l usage_offs(bin), usage
xor BIN_FULL, usage, r0
bnc.t _bin_not_full
fst.d f24, usage(bin)
_bin_full::
st.l r1, -4(sp)
call bin_was_full
adds -8, sp, sp
adds 8, sp, sp
ld.l -4(sp), r1
fst.d f24, usage(bin)
_bin_not_full::
// bin->DMA_opcodes[usage++]=macro_lo;
// bin->DMA_opcodes[usage++]=macro_hi;
// bin->usage=usage;
// xbin++;
adds 8, usage, usage
adds bin_size, xbin, xbin
st.l usage, usage_offs(bin)
_bump_x::
// lbin+=screen_bins_x;
bte r0, xcnt, _bump_y
ld.l tail_offs(xbin), bin
br _x_loopdb
adds -1, xcnt, xcnt
_bump_y::
bte r0, ycnt, _exit_binitize
adds x_bins_bytes, lbin, lbin
adds -1, ycnt, ycnt
br _y_loopdb
mov lbin, xbin
_exit_binitize:
bri r1
nop
//}}}
// /////////////////////////////
// the currently implemented functions
// _tri_zb_rgb
// _tri_zb_rgb_t
// _tri_zb_d_s
// _tri_zb_d_s_t
// _tri_zb_f
// _tri_zb_f_t
// _tri_zb_d
// _tri_zb_d_t
//
// NOTE the texturing triangle functions now need to compute
// zscale based on smallest z in triangle, and multiply up
// z, u and v by this number
//
//
// triangle - no z-buffer, no colour, just edges
//
#if 0
//{{{ _tri_edge
.globl _tri_edge
.align 8
_tri_edge::
triangle_entry(tri_edge_mesh)
tri_edge_mesh::
// 1 1
//
st.l iparam2, 4(rcoeffptr)
call _preplanarize_fn_p
adds VERT_z_offs, r0, iparam2
// should we just exit ?
xor 0x0, r31, r0
bnc .bomb_tri_edge
// 12 13
pxpl5op_0(iparam1, Ix_TREEltZERO_L3)
call _edgize_tri_fn_p
adds 4, rcoeffptr, rcoeffptr
DMAop_1 (iparam2,DMA_SEND, 13 )
// DMA engine stuff, need to align next triangle to a 32-byte
// boundary, which may be a tad inefficient on memory
//
// coeffptr+=31
// coeffptr&=~31
// but coeffptr is pre-decremented, so add on 31+4, then fix up after
adds 35, rcoeffptr, rcoeffptr
andnot 31, rcoeffptr, rcoeffptr
adds -4, rcoeffptr, rcoeffptr
mov rcoeffsave, iparam1
br _safe_binitize_fn
addu 10, r0, iparam3
.bomb_tri_edge::
triangle_exit
//}}}
// contents of edgize
//{{{ edgize in-line
//
// lets try to code this without re-evaluating
// fx13 fx21 fx32
//
.align 8
d.pfsub.ss fy1, fy2, f0
pxpl5op_0_l(iparam1, Ix_TREEltZERO_L3)
d.pfsub.ss fy2, fy3, f0
pxpl5op_0_h(iparam1, Ix_TREEltZERO_L3)
d.pfsub.ss fy3, fy1, f0
adds 4, rcoeffptr, rcoeffptr
d.pfsub.ss fx2, fx1, ftmp2
st.l iparam1, 4(rcoeffptr)
d.pfsub.ss fx3, fx2, ftmp1
fst.l ftmp2, 8(rcoeffptr) // edge[0] eqn[0]
d.pfsub.ss fx1, fx3, ftmp2
fst.l ftmp1, 24(rcoeffptr) // edge[1] eqn [0]
d.m12tpm.ss fx1, fy2, ftmp1
fst.l ftmp2, 40(rcoeffptr) // edge[2] eqn [0]
d.m12tpm.ss fx2, fy3, ftmp2
nop
d.m12tpm.ss fx3, fy1, ftmp3
st.l iparam1, 20(rcoeffptr)
d.pfmul.ss fy1, fx2, ftmp4 // fy2*fx1
nop
d.pfmul.ss fy2, fx3, ftmp5 // fy3*fx2
fst.l ftmp1, 12(rcoeffptr) // edge[0] eqn[1]
d.pfmul.ss fy3, fx1, ftmp6 // fy1*fx3
fst.l ftmp2, 28(rcoeffptr) // edge[1] eqn[1]
d.i2s1.ss ftmp4, f0, f0 // push y2*x1 - x2*y1
fst.l ftmp3, 44(rcoeffptr) // edge[2] eqn[1]
d.i2s1.ss ftmp5, f0, f0
nop
d.i2s1.ss ftmp6, f0, f0
st.l iparam1, 36(rcoeffptr)
d.pfadd.ss f0, f0, ftmp1
fst.l ftmp1, 16(rcoeffptr) // edge[0] eqn[2]
pfadd.ss f0, f0, ftmp2
fst.l ftmp2, 32(rcoeffptr) // edge[1] eqn[2]
pfadd.ss f0, f0, ftmp3
fst.l ftmp3, 48(rcoeffptr)++ // edge[2] eqn[2]
//}}}
#endif
//
// triangle, z-buffered, flat
// 13 64-bit words
//
//{{{ _tri_zb_f
.globl _tri_zb_f
.align 8
_tri_zb_f::
triangle_entry(tri_zb_f_mesh)
tri_zb_f_mesh::
// 1 1
//
st.l iparam2, 4(rcoeffptr)
call _preplanarize_fn_p
adds VERT_z_offs, r0, iparam2
// should we just exit ?
xor 0x0, r31, r0
bnc .bomb_tri_zb_f
// 12 13
//{{{ edgize in-line, pre-loads ix_MEMltTREE_L3() into iparam1
// per edge
//
// eqn[0]=p1[Y] - p2[Y];
// eqn[1]=p2[X] - p1[X];
// eqn[2]=(p2[Y]*p1[X]) - (p2[X]*p1[Y]);
//
// NB we already have
// fx13 fx21 fx32 in registers
//
.align 8
d.pfsub.ss fy1, fy2, f0
adds 4, rcoeffptr, rcoeffptr
d.pfsub.ss fy2, fy3, f0
st.l iparam1, 4(rcoeffptr) // TREEltZERO
d.pfsub.ss fy3, fy1, f0
st.l iparam1, 20(rcoeffptr) // MORE TREEltZERO
d.m12tpm.ss fx1, fy2, ftmp1
fst.l ftmp1, 8(rcoeffptr) // edge[0] eqn[0]
d.m12tpm.ss fx2, fy3, ftmp2
fst.l ftmp2, 24(rcoeffptr) // edge[1] eqn [0]
d.m12tpm.ss fx3, fy1, ftmp1
fst.l ftmp1, 40(rcoeffptr) // edge[2] eqn [0]
d.pfmul.ss fy1, fx2, ftmp4 // fy2*fx1
fst.l fx21, 12(rcoeffptr) // edge[0] eqn [1]
d.pfmul.ss fy2, fx3, ftmp5 // fy3*fx2
fst.l fx32, 28(rcoeffptr) // edge[1] eqn[1]
d.pfmul.ss fy3, fx1, ftmp6 // fy1*fx3
fst.l fx13, 44(rcoeffptr) // edge[2] eqn[1]
d.i2s1.ss ftmp4, f0, f0 // push y2*x1 - x2*y1
st.l iparam1, 36(rcoeffptr)
d.i2s1.ss ftmp5, f0, f0
pxpl5op_2_l(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
d.i2s1.ss ftmp6, f0, f0
pxpl5op_2_h(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
d.pfadd.ss f0, f0, ftmp1
fst.l ftmp1, 16(rcoeffptr) // edge[0] eqn[2]
pfadd.ss f0, f0, ftmp2
fst.l ftmp2, 32(rcoeffptr) // edge[1] eqn[2]
pfadd.ss f0, f0, ftmp3
fst.l ftmp3, 48(rcoeffptr)++ // edge[2] eqn[2]
//}}}
// 5 18
call _planarize_fn_p
or VERT_diff_offs, r0, iparam2
// store 'do zbuffer, no arguments' into coeff store
pxpl5op_2(iparam1,Ix_TREEintoMEM_L0, dvpx_zbuf, dvpx_zbufbits)
st.l iparam1, 4(rcoeffptr)
adds 4, rcoeffptr, rcoeffptr
// 6 24
pxpl5op_2(iparam2,Ix_TREEclmpintoMEM_C1, dvpx_diffuse, dvpx_diffusebits)
st.l iparam2, 4(rcoeffptr)
pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_diffuse, dvpx_diffusebits)
st.l iparam1, 8(rcoeffptr)
fst.l fv2, 12(rcoeffptr)++
fld.l VERT_spec_offs(rv2), fv2
pxpl5op_2(iparam2,Ix_TREEclmpintoMEM_C1, dvpx_specular, dvpx_specularbits)
st.l iparam2, 4(rcoeffptr)
pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_specular, dvpx_specularbits)
st.l iparam1, 8(rcoeffptr)
fst.l fv2, 12(rcoeffptr)++
// 2 26
pxpl5op_2(iparam1,Ix_SCAintoMEM_S1, dvpx_scalar, dvpx_scalarbits)
st.l iparam1, 4(rcoeffptr)
fst.l fmaterial, 8(rcoeffptr)++
DMAop_1 (iparam2,DMA_SEND, 13 )
// DMA engine stuff, need to align next triangle to a 32-byte
// boundary, which may be a tad inefficient on memory
//
// coeffptr+=31
// coeffptr&=~31
// but coeffptr is pre-decremented, so add on 31+4, then fix up after
//
// but the simplest way is to add on 13*8 bytes, aligned to 32,
// so
//adds 35, rcoeffptr, rcoeffptr
//andnot 31, rcoeffptr, rcoeffptr
//adds -4, rcoeffptr, rcoeffptr
fix_rcoeffptr(13)
mov rcoeffsave, iparam1
call _safe_binitize_fn
addu 10, r0, iparam3
.bomb_tri_zb_f::
triangle_exit
//}}}
// triangle, diffuse lit, specular lit
// 15 64-bit words
//
//{{{ _tri_d_s
.globl _tri_d_s
.align 8
_tri_d_s::
triangle_entry(tri_d_s_mesh)
tri_d_s_mesh::
// 1 1
//
st.l iparam2, 4(rcoeffptr)
call _preplanarize_fn_p
adds VERT_z_offs, r0, iparam2
// should we just exit ?
xor 0x0, r31, r0
bnc .bomb_tri_d_s
// 12 13
//{{{ edgize in-line, pre-loads ix_MEMltTREE_L3() into iparam1
// per edge
//
// eqn[0]=p1[Y] - p2[Y];
// eqn[1]=p2[X] - p1[X];
// eqn[2]=(p2[Y]*p1[X]) - (p2[X]*p1[Y]);
//
// NB we already have
// fx13 fx21 fx32 in registers
//
.align 8
d.pfsub.ss fy1, fy2, f0
adds 4, rcoeffptr, rcoeffptr
d.pfsub.ss fy2, fy3, f0
st.l iparam1, 4(rcoeffptr) // TREEltZERO
d.pfsub.ss fy3, fy1, f0
st.l iparam1, 20(rcoeffptr) // MORE TREEltZERO
d.m12tpm.ss fx1, fy2, ftmp1
fst.l ftmp1, 8(rcoeffptr) // edge[0] eqn[0]
d.m12tpm.ss fx2, fy3, ftmp2
fst.l ftmp2, 24(rcoeffptr) // edge[1] eqn [0]
d.m12tpm.ss fx3, fy1, ftmp1
fst.l ftmp1, 40(rcoeffptr) // edge[2] eqn [0]
d.pfmul.ss fy1, fx2, ftmp4 // fy2*fx1
fst.l fx21, 12(rcoeffptr) // edge[0] eqn [1]
d.pfmul.ss fy2, fx3, ftmp5 // fy3*fx2
fst.l fx32, 28(rcoeffptr) // edge[1] eqn[1]
d.pfmul.ss fy3, fx1, ftmp6 // fy1*fx3
fst.l fx13, 44(rcoeffptr) // edge[2] eqn[1]
d.i2s1.ss ftmp4, f0, f0 // push y2*x1 - x2*y1
st.l iparam1, 36(rcoeffptr)
d.i2s1.ss ftmp5, f0, f0
pxpl5op_2_l(iparam1,Ix_TREEclmpintoMEM_L3, dvpx_diffuse, dvpx_diffusebits)
d.i2s1.ss ftmp6, f0, f0
pxpl5op_2_h(iparam1,Ix_TREEclmpintoMEM_L3, dvpx_diffuse, dvpx_diffusebits)
d.pfadd.ss f0, f0, ftmp1
fst.l ftmp1, 16(rcoeffptr) // edge[0] eqn[2]
pfadd.ss f0, f0, ftmp2
fst.l ftmp2, 32(rcoeffptr) // edge[1] eqn[2]
pfadd.ss f0, f0, ftmp3
fst.l ftmp3, 48(rcoeffptr)++ // edge[2] eqn[2]
//}}}
// 10 23
st.l iparam1, 4(rcoeffptr)
adds 4, rcoeffptr, rcoeffptr
pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_diffuse, dvpx_diffusebits)
call _planarize_fn_p
or VERT_spec_offs, r0, iparam2
//
// and these loads are not needed, but re-load specular, force
// cache-hits by referencing same vertex !
//
pxpl5op_2(iparam1,Ix_TREEclmpintoMEM_L3, dvpx_specular, dvpx_specularbits)
st.l iparam1, 4(rcoeffptr)
pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_specular, dvpx_specularbits)
call _planarize_fn_p
adds 4, rcoeffptr, rcoeffptr
// 3 26
pxpl5op_2(iparam1,Ix_SCAintoMEM_S1, dvpx_scalar, dvpx_scalarbits)
st.l iparam1, 4(rcoeffptr)
fst.l fmaterial, 8(rcoeffptr)
fst.l f0, 12(rcoeffptr)++
DMAop_1 (iparam2,DMA_SEND, 13 )
fix_rcoeffptr(13)
mov rcoeffsave, iparam1
call _safe_binitize_fn
addu 10, r0, iparam3
.bomb_tri_d_s::
triangle_exit
//}}}
// triangle, z-buffered, diffuse lit, specular lit
// 15 64-bit words
//
//{{{ _tri_zb_d_s
.globl _tri_zb_d_s
.align 8
_tri_zb_d_s::
triangle_entry(tri_zb_d_s_mesh)
tri_zb_d_s_mesh::
// 1 1
//
st.l iparam2, 4(rcoeffptr)
call _preplanarize_fn_p
adds VERT_z_offs, r0, iparam2
// should we just exit ?
xor 0x0, r31, r0
bnc .bomb_tri_zb_d_s
// 12 13
//{{{ edgize in-line, pre-loads ix_MEMltTREE_L3() into iparam1
// per edge
//
// eqn[0]=p1[Y] - p2[Y];
// eqn[1]=p2[X] - p1[X];
// eqn[2]=(p2[Y]*p1[X]) - (p2[X]*p1[Y]);
//
// NB we already have
// fx13 fx21 fx32 in registers
//
.align 8
d.pfsub.ss fy1, fy2, f0
adds 4, rcoeffptr, rcoeffptr
d.pfsub.ss fy2, fy3, f0
st.l iparam1, 4(rcoeffptr) // TREEltZERO
d.pfsub.ss fy3, fy1, f0
st.l iparam1, 20(rcoeffptr) // MORE TREEltZERO
d.m12tpm.ss fx1, fy2, ftmp1
fst.l ftmp1, 8(rcoeffptr) // edge[0] eqn[0]
d.m12tpm.ss fx2, fy3, ftmp2
fst.l ftmp2, 24(rcoeffptr) // edge[1] eqn [0]
d.m12tpm.ss fx3, fy1, ftmp1
fst.l ftmp1, 40(rcoeffptr) // edge[2] eqn [0]
d.pfmul.ss fy1, fx2, ftmp4 // fy2*fx1
fst.l fx21, 12(rcoeffptr) // edge[0] eqn [1]
d.pfmul.ss fy2, fx3, ftmp5 // fy3*fx2
fst.l fx32, 28(rcoeffptr) // edge[1] eqn[1]
d.pfmul.ss fy3, fx1, ftmp6 // fy1*fx3
fst.l fx13, 44(rcoeffptr) // edge[2] eqn[1]
d.i2s1.ss ftmp4, f0, f0 // push y2*x1 - x2*y1
st.l iparam1, 36(rcoeffptr)
d.i2s1.ss ftmp5, f0, f0
pxpl5op_2_l(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
d.i2s1.ss ftmp6, f0, f0
pxpl5op_2_h(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
d.pfadd.ss f0, f0, ftmp1
fst.l ftmp1, 16(rcoeffptr) // edge[0] eqn[2]
pfadd.ss f0, f0, ftmp2
fst.l ftmp2, 32(rcoeffptr) // edge[1] eqn[2]
pfadd.ss f0, f0, ftmp3
fst.l ftmp3, 48(rcoeffptr)++ // edge[2] eqn[2]
//}}}
// 5 18
// pxpl5op_2(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
call _planarize_fn_p
or VERT_diff_offs, r0, iparam2
// store 'do zbuffer, no arguments' into coeff store
pxpl5op_2(iparam1,Ix_TREEintoMEM_L0, dvpx_zbuf, dvpx_zbufbits)
st.l iparam1, 4(rcoeffptr)
//adds 4, rcoeffptr, rcoeffptr
// 10 28
pxpl5op_2(iparam2,Ix_TREEclmpintoMEM_L3, dvpx_diffuse, dvpx_diffusebits)
st.l iparam2, 8(rcoeffptr)
adds 8, rcoeffptr, rcoeffptr
pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_diffuse, dvpx_diffusebits)
call _planarize_fn_p
or VERT_spec_offs, r0, iparam2
//
// and these loads are not needed, but re-load specular, force
// cache-hits by referencing same vertex !
//
pxpl5op_2(iparam1,Ix_TREEclmpintoMEM_L3, dvpx_specular, dvpx_specularbits)
st.l iparam1, 4(rcoeffptr)
pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_specular, dvpx_specularbits)
call _planarize_fn_p
adds 4, rcoeffptr, rcoeffptr
// 2 30
pxpl5op_2(iparam1,Ix_SCAintoMEM_S1, dvpx_scalar, dvpx_scalarbits)
st.l iparam1, 4(rcoeffptr)
fst.l fmaterial, 8(rcoeffptr)++
DMAop_1 (iparam2,DMA_SEND, 15 )
fix_rcoeffptr(15)
mov rcoeffsave, iparam1
call _safe_binitize_fn
addu 10, r0, iparam3
.bomb_tri_zb_d_s::
triangle_exit
//}}}
// triangle, z-buffered, diffuse lit
// 15 64-bit words
//
//{{{ _tri_zb_d
.globl _tri_zb_d
.align 8
_tri_zb_d::
triangle_entry(tri_zb_d_mesh)
tri_zb_d_mesh::
// 1 1
//
st.l iparam2, 4(rcoeffptr)
call _preplanarize_fn_p
adds VERT_z_offs, r0, iparam2
// should we just exit ?
xor 0x0, r31, r0
bnc .bomb_tri_zb_d_s
// 12 13
//{{{ edgize in-line, pre-loads ix_MEMltTREE_L3() into iparam1
// per edge
//
// eqn[0]=p1[Y] - p2[Y];
// eqn[1]=p2[X] - p1[X];
// eqn[2]=(p2[Y]*p1[X]) - (p2[X]*p1[Y]);
//
// NB we already have
// fx13 fx21 fx32 in registers
//
.align 8
d.pfsub.ss fy1, fy2, f0
adds 4, rcoeffptr, rcoeffptr
d.pfsub.ss fy2, fy3, f0
st.l iparam1, 4(rcoeffptr) // TREEltZERO
d.pfsub.ss fy3, fy1, f0
st.l iparam1, 20(rcoeffptr) // MORE TREEltZERO
d.m12tpm.ss fx1, fy2, ftmp1
fst.l ftmp1, 8(rcoeffptr) // edge[0] eqn[0]
d.m12tpm.ss fx2, fy3, ftmp2
fst.l ftmp2, 24(rcoeffptr) // edge[1] eqn [0]
d.m12tpm.ss fx3, fy1, ftmp1
fst.l ftmp1, 40(rcoeffptr) // edge[2] eqn [0]
d.pfmul.ss fy1, fx2, ftmp4 // fy2*fx1
fst.l fx21, 12(rcoeffptr) // edge[0] eqn [1]
d.pfmul.ss fy2, fx3, ftmp5 // fy3*fx2
fst.l fx32, 28(rcoeffptr) // edge[1] eqn[1]
d.pfmul.ss fy3, fx1, ftmp6 // fy1*fx3
fst.l fx13, 44(rcoeffptr) // edge[2] eqn[1]
d.i2s1.ss ftmp4, f0, f0 // push y2*x1 - x2*y1
st.l iparam1, 36(rcoeffptr)
d.i2s1.ss ftmp5, f0, f0
pxpl5op_2_l(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
d.i2s1.ss ftmp6, f0, f0
pxpl5op_2_h(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
d.pfadd.ss f0, f0, ftmp1
fst.l ftmp1, 16(rcoeffptr) // edge[0] eqn[2]
pfadd.ss f0, f0, ftmp2
fst.l ftmp2, 32(rcoeffptr) // edge[1] eqn[2]
pfadd.ss f0, f0, ftmp3
fst.l ftmp3, 48(rcoeffptr)++ // edge[2] eqn[2]
//}}}
// 5 18
// pxpl5op_2(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
call _planarize_fn_p
or VERT_diff_offs, r0, iparam2
// store 'do zbuffer, no arguments' into coeff store
pxpl5op_2(iparam1,Ix_TREEintoMEM_L0, dvpx_zbuf, dvpx_zbufbits)
st.l iparam1, 4(rcoeffptr)
adds 4, rcoeffptr, rcoeffptr
// 5 23
pxpl5op_2(iparam2,Ix_TREEclmpintoMEM_L3, dvpx_diffuse, dvpx_diffusebits)
st.l iparam2, 4(rcoeffptr)
pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_diffuse, dvpx_diffusebits)
call _planarize_fn_p
adds 4, rcoeffptr, rcoeffptr
// 2 25
pxpl5op_2(iparam1,Ix_SCAintoMEM_S1, dvpx_scalar, dvpx_scalarbits)
st.l iparam1, 4(rcoeffptr)
fst.l fmaterial, 8(rcoeffptr)++
fst.l f0, 4(rcoeffptr)++
DMAop_1 (iparam2,DMA_SEND, 13 )
// DMA engine stuff, need to align next triangle to a 32-byte
// boundary, which may be a tad inefficient on memory
//
// coeffptr+=31
// coeffptr&=~31
// but coeffptr is pre-decremented, so add on 31+4, then fix up after
//adds 35, rcoeffptr, rcoeffptr
//andnot 31, rcoeffptr, rcoeffptr
//adds -4, rcoeffptr, rcoeffptr
fix_rcoeffptr(13)
mov rcoeffsave, iparam1
call _safe_binitize_fn
addu 10, r0, iparam3
.bomb_tri_zb_d::
triangle_exit
//}}}
// triangle, z-buffered, rgb
// 18 64-bit words
//
//{{{ _tri_zb_rgb
.globl _tri_zb_rgb
.align 8
_tri_zb_rgb::
triangle_entry(tri_zb_rgb_mesh)
tri_zb_rgb_mesh::
// 1 1
//
st.l iparam2, 4(rcoeffptr)
call _preplanarize_fn_p
adds VERT_z_offs, r0, iparam2
// should we just exit ?
xor 0x0, r31, r0
bnc .bomb_tri_zb_rgb
// 12 13
//{{{ edgize in-line, pre-loads ix_MEMltTREE_L3() into iparam1
// per edge
//
// eqn[0]=p1[Y] - p2[Y];
// eqn[1]=p2[X] - p1[X];
// eqn[2]=(p2[Y]*p1[X]) - (p2[X]*p1[Y]);
//
// NB we already have
// fx13 fx21 fx32 in registers
//
.align 8
d.pfsub.ss fy1, fy2, f0
adds 4, rcoeffptr, rcoeffptr
d.pfsub.ss fy2, fy3, f0
st.l iparam1, 4(rcoeffptr) // TREEltZERO
d.pfsub.ss fy3, fy1, f0
st.l iparam1, 20(rcoeffptr) // MORE TREEltZERO
d.m12tpm.ss fx1, fy2, ftmp1
fst.l ftmp1, 8(rcoeffptr) // edge[0] eqn[0]
d.m12tpm.ss fx2, fy3, ftmp2
fst.l ftmp2, 24(rcoeffptr) // edge[1] eqn [0]
d.m12tpm.ss fx3, fy1, ftmp1
fst.l ftmp1, 40(rcoeffptr) // edge[2] eqn [0]
d.pfmul.ss fy1, fx2, ftmp4 // fy2*fx1
fst.l fx21, 12(rcoeffptr) // edge[0] eqn [1]
d.pfmul.ss fy2, fx3, ftmp5 // fy3*fx2
fst.l fx32, 28(rcoeffptr) // edge[1] eqn[1]
d.pfmul.ss fy3, fx1, ftmp6 // fy1*fx3
fst.l fx13, 44(rcoeffptr) // edge[2] eqn[1]
d.i2s1.ss ftmp4, f0, f0 // push y2*x1 - x2*y1
st.l iparam1, 36(rcoeffptr)
d.i2s1.ss ftmp5, f0, f0
pxpl5op_2_l(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
d.i2s1.ss ftmp6, f0, f0
pxpl5op_2_h(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
d.pfadd.ss f0, f0, ftmp1
fst.l ftmp1, 16(rcoeffptr) // edge[0] eqn[2]
pfadd.ss f0, f0, ftmp2
fst.l ftmp2, 32(rcoeffptr) // edge[1] eqn[2]
pfadd.ss f0, f0, ftmp3
fst.l ftmp3, 48(rcoeffptr)++ // edge[2] eqn[2]
//}}}
// 5 18
// pxpl5op_2(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
call _planarize_fn_p
or VERT_diff_offs, r0, iparam2
// store 'do zbuffer, no arguments' into coeff store
pxpl5op_2(iparam1,Ix_TREEintoMEM_L0, dvpx_zbuf, dvpx_zbufbits)
st.l iparam1, 4(rcoeffptr)
// 2 35
pxpl5op_2(iparam2,Ix_SCAintoMEM_S1, dvpx_scalar, (dvpx_intrinsic-dvpx_scalar))
st.l iparam2, 8(rcoeffptr)
fst.l fmaterial, 12(rcoeffptr)++
// 15 33
pxpl5op_2(iparam2,Ix_TREEclmpintoMEM_L3, dvpx_r24, 8 )
st.l iparam2, 4(rcoeffptr)
adds 4, rcoeffptr, rcoeffptr
pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_r24, 8 )
call _planarize_fn_p
or VERT_spec_offs, r0, iparam2
pxpl5op_2(iparam2,Ix_TREEclmpintoMEM_L3, dvpx_g24, 8 )
st.l iparam2, 4(rcoeffptr)
adds 4, rcoeffptr, rcoeffptr
pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_g24, 8 )
call _planarize_fn_p
or VERT_b_offs, r0, iparam2
pxpl5op_2(iparam2,Ix_TREEclmpintoMEM_L3, dvpx_b24, 8 )
st.l iparam2, 4(rcoeffptr)
adds 4, rcoeffptr, rcoeffptr
pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_b24, 8 )
call _planarize_fn_p
or VERT_b_offs, r0, iparam2
fst.l f0, 4(rcoeffptr)++
DMAop_1 (iparam2,DMA_SEND, 18 )
// DMA engine stuff, need to align next triangle to a 32-byte
// boundary, which may be a tad inefficient on memory
//
// coeffptr+=31
// coeffptr&=~31
// but coeffptr is pre-decremented, so add on 31+4, then fix up after
//adds 35, rcoeffptr, rcoeffptr
//andnot 31, rcoeffptr, rcoeffptr
//adds -4, rcoeffptr, rcoeffptr
fix_rcoeffptr(18)
mov rcoeffsave, iparam1
call _safe_binitize_fn
addu 10, r0, iparam3
.bomb_tri_zb_rgb::
triangle_exit
//}}}
//
// Now the textured triangles
// NB if you need 1 bit of pushed storage during triangle processing,
// use texz LSB, it is dropped before perspective divide...
//
//
// triangle, z-buffered, flat, textured
// 19 64-bit words
//
//{{{ _tri_zb_f_t
.globl _tri_zb_f_t
.align 8
_tri_zb_f_t::
triangle_entry(tri_zb_f_t_mesh)
tri_zb_f_t_mesh::
// 1 1
//
st.l iparam2, 4(rcoeffptr)
call _preplanarize_fn_p
adds VERT_z_offs, r0, iparam2
// should we just exit ?
xor 0x0, r31, r0
bnc .bomb_tri_zb_f_t
// 12 13
//{{{ edgize in-line, pre-loads ix_MEMltTREE_L3() into iparam1
// per edge
//
// eqn[0]=p1[Y] - p2[Y];
// eqn[1]=p2[X] - p1[X];
// eqn[2]=(p2[Y]*p1[X]) - (p2[X]*p1[Y]);
//
// NB we already have
// fx13 fx21 fx32 in registers
//
.align 8
d.pfsub.ss fy1, fy2, f0
adds 4, rcoeffptr, rcoeffptr
d.pfsub.ss fy2, fy3, f0
st.l iparam1, 4(rcoeffptr) // TREEltZERO
d.pfsub.ss fy3, fy1, f0
st.l iparam1, 20(rcoeffptr) // MORE TREEltZERO
d.m12tpm.ss fx1, fy2, ftmp1
fst.l ftmp1, 8(rcoeffptr) // edge[0] eqn[0]
d.m12tpm.ss fx2, fy3, ftmp2
fst.l ftmp2, 24(rcoeffptr) // edge[1] eqn [0]
d.m12tpm.ss fx3, fy1, ftmp1
fst.l ftmp1, 40(rcoeffptr) // edge[2] eqn [0]
d.pfmul.ss fy1, fx2, ftmp4 // fy2*fx1
fst.l fx21, 12(rcoeffptr) // edge[0] eqn [1]
d.pfmul.ss fy2, fx3, ftmp5 // fy3*fx2
fst.l fx32, 28(rcoeffptr) // edge[1] eqn[1]
d.pfmul.ss fy3, fx1, ftmp6 // fy1*fx3
fst.l fx13, 44(rcoeffptr) // edge[2] eqn[1]
d.i2s1.ss ftmp4, f0, f0 // push y2*x1 - x2*y1
st.l iparam1, 36(rcoeffptr)
d.i2s1.ss ftmp5, f0, f0
pxpl5op_2_l(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
d.i2s1.ss ftmp6, f0, f0
pxpl5op_2_h(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
d.pfadd.ss f0, f0, ftmp1
fst.l ftmp1, 16(rcoeffptr) // edge[0] eqn[2]
pfadd.ss f0, f0, ftmp2
fst.l ftmp2, 32(rcoeffptr) // edge[1] eqn[2]
pfadd.ss f0, f0, ftmp3
fst.l ftmp3, 48(rcoeffptr)++ // edge[2] eqn[2]
//}}}
// 5 18
// TEXTURIZE TO FIND ZSCALE
orh ha%_.Cturn_z_to_tex, r0, r31
fld.l l%_.Cturn_z_to_tex(r31), ftmp2
frcp.ss ftexscale, ftmp1
fmul.ss ftmp1, ftmp2, ftmp1
// store 'do zbuffer, no arguments' into coeff store
pxpl5op_2(iparam1,Ix_TREEintoMEM_L0, dvpx_zbuf, dvpx_zbufbits)
fmul.ss fv1, ftmp1, ftmp7
st.l iparam1, 20(rcoeffptr)
fmul.ss fv2, ftmp1, ftmp8
fmul.ss fv3, ftmp1, ftmp9
pxpl5op_2(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
call _planarize_fn_p
or VERT_tex_u_offs, r0, iparam2
adds 4, rcoeffptr, rcoeffptr
fmov.ss ftmp7, fv1
fmov.ss ftmp8, fv2
fmov.ss ftmp9, fv3
// 4 22 tex z-coordinate
pxpl5op_2(iparam1,Ix_TREEintoMEM_L3, dvpx_texz, dvpx_texzbits)
call _planarize_fn_p
or VERT_tex_u_offs, r0, iparam2
// fix u-coordinate
pfmul.ss ftmp7, fv1, f0
pfmul.ss ftmp8, fv2, f0
pfmul.ss ftmp9, fv3, f0
pfmul.ss f0, f0, fv1
pfmul.ss f0, f0, fv2
pfmul.ss f0, f0, fv3
// 4 26 tex v-coordinate
pxpl5op_2(iparam1,Ix_TREEintoMEM_L3, dvpx_texu, dvpx_texubits)
call _planarize_fn_p
or VERT_tex_v_offs, r0, iparam2
// fix v-coordinate
pfmul.ss ftmp7, fv1, f0
pfmul.ss ftmp8, fv2, f0
pfmul.ss ftmp9, fv3, f0
pfmul.ss f0, f0, fv1
pfmul.ss f0, f0, fv2
pfmul.ss f0, f0, fv3
// 4 30 tex u-coordinate
pxpl5op_2(iparam1,Ix_TREEintoMEM_L3, dvpx_texv, dvpx_texvbits)
call _planarize_fn_p
or VERT_diff_offs, r0, iparam2
// 6 36
pxpl5op_2(iparam2,Ix_TREEclmpintoMEM_C1, dvpx_diffuse, dvpx_diffusebits)
st.l iparam2, 4(rcoeffptr)
pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_diffuse, dvpx_diffusebits)
st.l iparam1, 8(rcoeffptr)
fst.l fv2, 12(rcoeffptr)++
fld.l VERT_spec_offs(rv2), fv2
pxpl5op_2(iparam2,Ix_TREEclmpintoMEM_C1, dvpx_specular, dvpx_specularbits)
st.l iparam2, 4(rcoeffptr)
pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_specular, dvpx_specularbits)
st.l iparam1, 8(rcoeffptr)
fst.l fv2, 12(rcoeffptr)++
// 2 38
pxpl5op_2(iparam1,Ix_SCAintoMEM_S1, dvpx_scalar, dvpx_scalarbits)
st.l iparam1, 4(rcoeffptr)
fst.l fmaterial, 8(rcoeffptr)++
DMAop_1 (iparam2,DMA_SEND, 19 )
// DMA engine stuff, need to align next triangle to a 32-byte
// boundary, which may be a tad inefficient on memory
//
// coeffptr+=31
// coeffptr&=~31
// but coeffptr is pre-decremented, so add on 31+4, then fix up after
//adds 35, rcoeffptr, rcoeffptr
//andnot 31, rcoeffptr, rcoeffptr
//adds -4, rcoeffptr, rcoeffptr
fix_rcoeffptr(19)
mov rcoeffsave, iparam1
call _safe_binitize_fn
addu 10, r0, iparam3
.bomb_tri_zb_f_t::
triangle_exit
//}}}
//
// triangle, z-buffered, diffuse lit, textured
// 19 64-bit words
//
//{{{ _tri_zb_d_t
.globl _tri_zb_d_t
.align 8
_tri_zb_d_t::
triangle_entry(tri_zb_d_t_mesh)
tri_zb_d_t_mesh::
// 1 1
//
st.l iparam2, 4(rcoeffptr)
call _preplanarize_fn_p
adds VERT_z_offs, r0, iparam2
// should we just exit ?
xor 0x0, r31, r0
bnc .bomb_tri_zb_d_s_t
// 12 13
//{{{ edgize in-line, pre-loads ix_MEMltTREE_L3() into iparam1
// per edge
//
// eqn[0]=p1[Y] - p2[Y];
// eqn[1]=p2[X] - p1[X];
// eqn[2]=(p2[Y]*p1[X]) - (p2[X]*p1[Y]);
//
// NB we already have
// fx13 fx21 fx32 in registers
//
.align 8
d.pfsub.ss fy1, fy2, f0
adds 4, rcoeffptr, rcoeffptr
d.pfsub.ss fy2, fy3, f0
st.l iparam1, 4(rcoeffptr) // TREEltZERO
d.pfsub.ss fy3, fy1, f0
st.l iparam1, 20(rcoeffptr) // MORE TREEltZERO
d.m12tpm.ss fx1, fy2, ftmp1
fst.l ftmp1, 8(rcoeffptr) // edge[0] eqn[0]
d.m12tpm.ss fx2, fy3, ftmp2
fst.l ftmp2, 24(rcoeffptr) // edge[1] eqn [0]
d.m12tpm.ss fx3, fy1, ftmp1
fst.l ftmp1, 40(rcoeffptr) // edge[2] eqn [0]
d.pfmul.ss fy1, fx2, ftmp4 // fy2*fx1
fst.l fx21, 12(rcoeffptr) // edge[0] eqn [1]
d.pfmul.ss fy2, fx3, ftmp5 // fy3*fx2
fst.l fx32, 28(rcoeffptr) // edge[1] eqn[1]
d.pfmul.ss fy3, fx1, ftmp6 // fy1*fx3
fst.l fx13, 44(rcoeffptr) // edge[2] eqn[1]
d.i2s1.ss ftmp4, f0, f0 // push y2*x1 - x2*y1
st.l iparam1, 36(rcoeffptr)
d.i2s1.ss ftmp5, f0, f0
pxpl5op_2_l(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
d.i2s1.ss ftmp6, f0, f0
pxpl5op_2_h(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
d.pfadd.ss f0, f0, ftmp1
fst.l ftmp1, 16(rcoeffptr) // edge[0] eqn[2]
pfadd.ss f0, f0, ftmp2
fst.l ftmp2, 32(rcoeffptr) // edge[1] eqn[2]
pfadd.ss f0, f0, ftmp3
fst.l ftmp3, 48(rcoeffptr)++ // edge[2] eqn[2]
//}}}
// 5 18
// TEXTURIZE TO FIND ZSCALE
orh ha%_.Cturn_z_to_tex, r0, r31
fld.l l%_.Cturn_z_to_tex(r31), ftmp2
frcp.ss ftexscale, ftmp1
fmul.ss ftmp1, ftmp2, ftmp1
// store 'do zbuffer, no arguments' into coeff store
pxpl5op_2(iparam1,Ix_TREEintoMEM_L0, dvpx_zbuf, dvpx_zbufbits)
fmul.ss fv1, ftmp1, ftmp7
st.l iparam1, 20(rcoeffptr)
fmul.ss fv2, ftmp1, ftmp8
pxpl5op_2(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
fmul.ss fv3, ftmp1, ftmp9
//
call _planarize_fn_p
or VERT_tex_u_offs, r0, iparam2
fmov.ss ftmp7, fv1
adds 4, rcoeffptr, rcoeffptr
fmov.ss ftmp8, fv2
fmov.ss ftmp9, fv3
// 4 22 tex z-coordinate
pxpl5op_2(iparam1,Ix_TREEintoMEM_L3, dvpx_texz, dvpx_texzbits)
call _planarize_fn_p
or VERT_tex_u_offs, r0, iparam2
// fix u-coordinate
pfmul.ss ftmp7, fv1, f0
pfmul.ss ftmp8, fv2, f0
pfmul.ss ftmp9, fv3, f0
pfmul.ss f0, f0, fv1
pfmul.ss f0, f0, fv2
pfmul.ss f0, f0, fv3
// 4 26 tex v-coordinate
pxpl5op_2(iparam1,Ix_TREEintoMEM_L3, dvpx_texu, dvpx_texubits)
call _planarize_fn_p
or VERT_tex_v_offs, r0, iparam2
// fix v-coordinate
pfmul.ss ftmp7, fv1, f0
pfmul.ss ftmp8, fv2, f0
pfmul.ss ftmp9, fv3, f0
pfmul.ss f0, f0, fv1
pfmul.ss f0, f0, fv2
pfmul.ss f0, f0, fv3
// 4 30 tex u-coordinate
pxpl5op_2(iparam1,Ix_TREEintoMEM_L3, dvpx_texv, dvpx_texvbits)
call _planarize_fn_p
or VERT_diff_offs, r0, iparam2
// 2 32
pxpl5op_2(iparam1,Ix_SCAintoMEM_S1, dvpx_scalar, dvpx_scalarbits)
st.l iparam1, 4(rcoeffptr)
fst.l fmaterial, 8(rcoeffptr)++
// 5 37 diffuse
pxpl5op_2(iparam2,Ix_TREEclmpintoMEM_L3, dvpx_diffuse, dvpx_diffusebits)
st.l iparam2, 4(rcoeffptr)
pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_diffuse, dvpx_diffusebits)
call _planarize_fn_p
adds 4, rcoeffptr, rcoeffptr
fst.l f0, 4(rcoeffptr)++
DMAop_1 (iparam2,DMA_SEND, 19 )
// DMA engine stuff, need to align next triangle to a 32-byte
// boundary, which may be a tad inefficient on memory
//
// coeffptr+=31
// coeffptr&=~31
// but coeffptr is pre-decremented, so add on 31+4, then fix up after
//adds 35, rcoeffptr, rcoeffptr
//andnot 31, rcoeffptr, rcoeffptr
//adds -4, rcoeffptr, rcoeffptr
fix_rcoeffptr(19)
mov rcoeffsave, iparam1
call _safe_binitize_fn
addu 10, r0, iparam3
.bomb_tri_zb_d_t::
triangle_exit
//}}}
//
// triangle, z-buffered, diffuse lit, specular lit, textured
// 21 64-bit words
//
//{{{ _tri_zb_d_s_t
.globl _tri_zb_d_s_t
.align 8
_tri_zb_d_s_t::
triangle_entry(tri_zb_d_s_t_mesh)
tri_zb_d_s_t_mesh::
// 1 1
//
st.l iparam2, 4(rcoeffptr)
call _preplanarize_fn_p
adds VERT_z_offs, r0, iparam2
// should we just exit ?
xor 0x0, r31, r0
bnc .bomb_tri_zb_d_s_t
// 12 13
//{{{ edgize in-line, pre-loads ix_MEMltTREE_L3() into iparam1
// per edge
//
// eqn[0]=p1[Y] - p2[Y];
// eqn[1]=p2[X] - p1[X];
// eqn[2]=(p2[Y]*p1[X]) - (p2[X]*p1[Y]);
//
// NB we already have
// fx13 fx21 fx32 in registers
//
.align 8
d.pfsub.ss fy1, fy2, f0
adds 4, rcoeffptr, rcoeffptr
d.pfsub.ss fy2, fy3, f0
st.l iparam1, 4(rcoeffptr) // TREEltZERO
d.pfsub.ss fy3, fy1, f0
st.l iparam1, 20(rcoeffptr) // MORE TREEltZERO
d.m12tpm.ss fx1, fy2, ftmp1
fst.l ftmp1, 8(rcoeffptr) // edge[0] eqn[0]
d.m12tpm.ss fx2, fy3, ftmp2
fst.l ftmp2, 24(rcoeffptr) // edge[1] eqn [0]
d.m12tpm.ss fx3, fy1, ftmp1
fst.l ftmp1, 40(rcoeffptr) // edge[2] eqn [0]
d.pfmul.ss fy1, fx2, ftmp4 // fy2*fx1
fst.l fx21, 12(rcoeffptr) // edge[0] eqn [1]
d.pfmul.ss fy2, fx3, ftmp5 // fy3*fx2
fst.l fx32, 28(rcoeffptr) // edge[1] eqn[1]
d.pfmul.ss fy3, fx1, ftmp6 // fy1*fx3
fst.l fx13, 44(rcoeffptr) // edge[2] eqn[1]
d.i2s1.ss ftmp4, f0, f0 // push y2*x1 - x2*y1
st.l iparam1, 36(rcoeffptr)
d.i2s1.ss ftmp5, f0, f0
pxpl5op_2_l(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
d.i2s1.ss ftmp6, f0, f0
pxpl5op_2_h(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
d.pfadd.ss f0, f0, ftmp1
fst.l ftmp1, 16(rcoeffptr) // edge[0] eqn[2]
pfadd.ss f0, f0, ftmp2
fst.l ftmp2, 32(rcoeffptr) // edge[1] eqn[2]
pfadd.ss f0, f0, ftmp3
fst.l ftmp3, 48(rcoeffptr)++ // edge[2] eqn[2]
//}}}
// 5 18
// TEXTURIZE TO FIND ZSCALE
orh ha%_.Cturn_z_to_tex, r0, r31
fld.l l%_.Cturn_z_to_tex(r31), ftmp2
frcp.ss ftexscale, ftmp1
fmul.ss ftmp1, ftmp2, ftmp1
// store 'do zbuffer, no arguments' into coeff store
pxpl5op_2(iparam1,Ix_TREEintoMEM_L0, dvpx_zbuf, dvpx_zbufbits)
fmul.ss fv1, ftmp1, ftmp7
st.l iparam1, 20(rcoeffptr)
fmul.ss fv2, ftmp1, ftmp8
pxpl5op_2(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
fmul.ss fv3, ftmp1, ftmp9
call _planarize_fn_p
or VERT_tex_u_offs, r0, iparam2
fmov.ss ftmp7, fv1
adds 4, rcoeffptr, rcoeffptr
fmov.ss ftmp8, fv2
fmov.ss ftmp9, fv3
// 4 22 tex z-coordinate
pxpl5op_2(iparam1,Ix_TREEintoMEM_L3, dvpx_texz, dvpx_texzbits)
call _planarize_fn_p
or VERT_tex_u_offs, r0, iparam2
// fix u-coordinate
pfmul.ss ftmp7, fv1, f0
pfmul.ss ftmp8, fv2, f0
pfmul.ss ftmp9, fv3, f0
pfmul.ss f0, f0, fv1
pfmul.ss f0, f0, fv2
pfmul.ss f0, f0, fv3
// 4 26 tex v-coordinate
pxpl5op_2(iparam1,Ix_TREEintoMEM_L3, dvpx_texu, dvpx_texubits)
call _planarize_fn_p
or VERT_tex_v_offs, r0, iparam2
// fix v-coordinate
pfmul.ss ftmp7, fv1, f0
pfmul.ss ftmp8, fv2, f0
pfmul.ss ftmp9, fv3, f0
pfmul.ss f0, f0, fv1
pfmul.ss f0, f0, fv2
pfmul.ss f0, f0, fv3
// 4 30 tex u-coordinate
pxpl5op_2(iparam1,Ix_TREEintoMEM_L3, dvpx_texv, dvpx_texvbits)
call _planarize_fn_p
or VERT_diff_offs, r0, iparam2
// 2 32
pxpl5op_2(iparam1,Ix_SCAintoMEM_S1, dvpx_scalar, dvpx_scalarbits)
st.l iparam1, 4(rcoeffptr)
fst.l fmaterial, 8(rcoeffptr)++
// 5 37 diffuse
pxpl5op_2(iparam2,Ix_TREEclmpintoMEM_L3, dvpx_diffuse, dvpx_diffusebits)
st.l iparam2, 4(rcoeffptr)
adds 4, rcoeffptr, rcoeffptr
pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_diffuse, dvpx_diffusebits)
call _planarize_fn_p
or VERT_spec_offs, r0, iparam2
// 5 42 specular
pxpl5op_2(iparam2,Ix_TREEclmpintoMEM_L3, dvpx_specular, dvpx_specularbits)
st.l iparam2, 4(rcoeffptr)
adds 4, rcoeffptr, rcoeffptr
pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_specular, dvpx_specularbits)
call _planarize_fn_p
or VERT_spec_offs, r0, iparam2
DMAop_1 (iparam2,DMA_SEND, 21 )
// DMA engine stuff, need to align next triangle to a 32-byte
// boundary, which may be a tad inefficient on memory
//
// coeffptr+=31
// coeffptr&=~31
// but coeffptr is pre-decremented, so add on 31+4, then fix up after
//adds 35, rcoeffptr, rcoeffptr
//andnot 31, rcoeffptr, rcoeffptr
//adds -4, rcoeffptr, rcoeffptr
fix_rcoeffptr(21)
mov rcoeffsave, iparam1
call _safe_binitize_fn
addu 10, r0, iparam3
.bomb_tri_zb_d_s_t::
triangle_exit
//}}}
// triangle, z-buffered, rgb, textured
// 24 64-bit words
//
//{{{ _tri_zb_rgb_t
.globl _tri_zb_rgb_t
.align 8
_tri_zb_rgb_t::
triangle_entry(tri_zb_rgb_t_mesh)
tri_zb_rgb_t_mesh::
// 1 1
//
// misalign it !!!
//
st.l iparam2, 4(rcoeffptr)
call _preplanarize_fn_p
adds VERT_z_offs, r0, iparam2
// should we just exit ?
xor 0x0, r31, r0
bnc .bomb_tri_zb_rgb_t
// 12 13
//{{{ edgize in-line, pre-loads ix_MEMltTREE_L3() into iparam1
// per edge
//
// eqn[0]=p1[Y] - p2[Y];
// eqn[1]=p2[X] - p1[X];
// eqn[2]=(p2[Y]*p1[X]) - (p2[X]*p1[Y]);
//
// NB we already have
// fx13 fx21 fx32 in registers
//
.align 8
d.pfsub.ss fy1, fy2, f0
adds 4, rcoeffptr, rcoeffptr
d.pfsub.ss fy2, fy3, f0
st.l iparam1, 4(rcoeffptr) // TREEltZERO
d.pfsub.ss fy3, fy1, f0
st.l iparam1, 20(rcoeffptr) // MORE TREEltZERO
d.m12tpm.ss fx1, fy2, ftmp1
fst.l ftmp1, 8(rcoeffptr) // edge[0] eqn[0]
d.m12tpm.ss fx2, fy3, ftmp2
fst.l ftmp2, 24(rcoeffptr) // edge[1] eqn [0]
d.m12tpm.ss fx3, fy1, ftmp1
fst.l ftmp1, 40(rcoeffptr) // edge[2] eqn [0]
d.pfmul.ss fy1, fx2, ftmp4 // fy2*fx1
fst.l fx21, 12(rcoeffptr) // edge[0] eqn [1]
d.pfmul.ss fy2, fx3, ftmp5 // fy3*fx2
fst.l fx32, 28(rcoeffptr) // edge[1] eqn[1]
d.pfmul.ss fy3, fx1, ftmp6 // fy1*fx3
fst.l fx13, 44(rcoeffptr) // edge[2] eqn[1]
d.i2s1.ss ftmp4, f0, f0 // push y2*x1 - x2*y1
st.l iparam1, 36(rcoeffptr)
d.i2s1.ss ftmp5, f0, f0
pxpl5op_2_l(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
d.i2s1.ss ftmp6, f0, f0
pxpl5op_2_h(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
d.pfadd.ss f0, f0, ftmp1
fst.l ftmp1, 16(rcoeffptr) // edge[0] eqn[2]
pfadd.ss f0, f0, ftmp2
fst.l ftmp2, 32(rcoeffptr) // edge[1] eqn[2]
pfadd.ss f0, f0, ftmp3
fst.l ftmp3, 48(rcoeffptr)++ // edge[2] eqn[2]
//}}}
// 5 18
// TEXTURIZE TO FIND ZSCALE
orh ha%_.Cturn_z_to_tex, r0, r31
fld.l l%_.Cturn_z_to_tex(r31), ftmp2
frcp.ss ftexscale, ftmp1
fmul.ss ftmp1, ftmp2, ftmp1
// store 'do zbuffer, no arguments' into coeff store
pxpl5op_2(iparam1,Ix_TREEintoMEM_L0, dvpx_zbuf, dvpx_zbufbits)
fmul.ss fv1, ftmp1, ftmp7
st.l iparam1, 20(rcoeffptr)
fmul.ss fv2, ftmp1, ftmp8
pxpl5op_2(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
fmul.ss fv3, ftmp1, ftmp9
call _planarize_fn_p
or VERT_tex_u_offs, r0, iparam2
fmov.ss ftmp7, fv1
adds 4, rcoeffptr, rcoeffptr
fmov.ss ftmp8, fv2
pxpl5op_2(iparam1,Ix_TREEintoMEM_L3, dvpx_texz, dvpx_texzbits)
fmov.ss ftmp9, fv3
// 4 22 tex z-coordinate
call _planarize_fn_p
or VERT_tex_u_offs, r0, iparam2
// fix u-coordinate
pfmul.ss ftmp7, fv1, f0
pfmul.ss ftmp8, fv2, f0
pfmul.ss ftmp9, fv3, f0
pfmul.ss f0, f0, fv1
pfmul.ss f0, f0, fv2
pfmul.ss f0, f0, fv3
// 4 26 tex v-coordinate
pxpl5op_2(iparam1,Ix_TREEintoMEM_L3, dvpx_texu, dvpx_texubits)
call _planarize_fn_p
or VERT_tex_v_offs, r0, iparam2
// fix v-coordinate
pfmul.ss ftmp7, fv1, f0
pfmul.ss ftmp8, fv2, f0
pfmul.ss ftmp9, fv3, f0
pfmul.ss f0, f0, fv1
pfmul.ss f0, f0, fv2
pfmul.ss f0, f0, fv3
// 4 30 tex u-coordinate
pxpl5op_2(iparam1,Ix_TREEintoMEM_L3, dvpx_texv, dvpx_texvbits)
call _planarize_fn_p
or VERT_r_offs, r0, iparam2
// 2 32
pxpl5op_2(iparam1,Ix_SCAintoMEM_S1, dvpx_scalar, (dvpx_intrinsic-dvpx_scalar))
st.l iparam1, 4(rcoeffptr)
fst.l fmaterial, 8(rcoeffptr)++
// 15 47
pxpl5op_2(iparam2,Ix_TREEclmpintoMEM_L3, dvpx_r24, 8 )
st.l iparam2, 4(rcoeffptr)
adds 4, rcoeffptr, rcoeffptr
pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_r24, 8 )
call _planarize_fn_p
or VERT_g_offs, r0, iparam2
pxpl5op_2(iparam2,Ix_TREEclmpintoMEM_L3, dvpx_g24, 8 )
st.l iparam2, 4(rcoeffptr)
adds 4, rcoeffptr, rcoeffptr
pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_g24, 8 )
call _planarize_fn_p
or VERT_b_offs, r0, iparam2
pxpl5op_2(iparam2,Ix_TREEclmpintoMEM_L3, dvpx_b24, 8 )
st.l iparam2, 4(rcoeffptr)
adds 4, rcoeffptr, rcoeffptr
pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_b24, 8 )
call _planarize_fn_p
or VERT_b_offs, r0, iparam2
fst.l f0, 4(rcoeffptr)++
DMAop_1 (iparam2,DMA_SEND, 24 )
// DMA engine stuff, need to align next triangle to a 32-byte
// boundary, which may be a tad inefficient on memory
//
// coeffptr+=31
// coeffptr&=~31
// but coeffptr is pre-decremented, so add on 31+4, then fix up after
//adds 35, rcoeffptr, rcoeffptr
//andnot 31, rcoeffptr, rcoeffptr
//adds -4, rcoeffptr, rcoeffptr
fix_rcoeffptr(24)
mov rcoeffsave, iparam1
call _safe_binitize_fn
addu 10, r0, iparam3
.bomb_tri_zb_rgb_t::
triangle_exit
//}}}