Files
TeslaRel410/sda4/DPL3/VRENDER/PXPL5SUP/PXPL5OK.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

2255 lines
66 KiB
Scheme

//
// aiming for -
//
// icoeff_p = vpx ( icoeff_ref, codeword, opcode0, conn, backwards, n_polys );
//
// problem - edgizing quads, pents and hexes
//
#define chunk_next_offset 65532
//{{{ 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 "\projects\dbi0150\dbi0151\ucode\igc_opco.h"
#include "\dpl3\vrender\pxpl5sup\pxplmacr.h"
#include "\dpl3\vrender\pxpl5sup\divpxmap.h"
#include "\dpl3\vrender\pxpl5sup\dmaengn.h"
#include "\dpl3\vrender\pxpl5sup\register.h"
//{{{ some load macros
#define ld_from(reg, addr) \
orh ha%addr, r0, r31; \
ld.l l%addr(r31), reg
#define fld_from(freg, addr) \
orh ha%addr, r0, r31; \
fld.l l%addr(r31), freg
#define dfld_from(freg, addr) \
orh ha%addr, r0, r31; \
fld.d l%addr(r31), freg
//}}}
//{{{ declare offsets in VERTEX structure
//
// Note new placement of next field - ensures double-alignment of
// position, normal and texcoords
//
// typedef struct s_rvert {
// 0 dpl_POINT position;
// 16 dpl_POINT normcol;
// 32 float32 texcoords [3];
// 44 struct s_rvert *next;
// 48 dpl_POINT xform_posn;
// 64 float32 rendered_color[3];
// int32 touched;
// 80 } dpl_REMOTE_VERTEX;
#define VERT_position_offs 48
#define VERT_normal_offs 64
#define VERT_tex_offs 32
#define VERT_size 80
#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_tex_u_offs ((VERT_tex_offs)+0)
#define VERT_tex_v_offs ((VERT_tex_offs)+4)
#define VERT_a_offs ((VERT_tex_offs)+8)
// typedef struct s_conn {
// struct s_conn *next; /* 0 */
// int32 n_verts; /* 4 */
// dpl_REMOTE_VERTEX* indices[6]; /* 8 */
// dpl_POINT planeEqn; /* 32 */
// float32 rendered_color[3]; /* 48 */
// int32 touched; /* 60 */
// } dpl_REMOTE_CONNECTION;
//
#define FACET_next_offs 0
#define FACET_nverts_offs 4
#define FACET_vert0_offs 8
#define FACET_r_offs 48
#define FACET_g_offs (48+4)
#define FACET_b_offs (48+8)
#define FACET_touched_offs (60)
//}}}
// /////////////////////////////////
// triangle support code
// preplane, planarize, binitize
//{{{ triangle_entry
#define triangle_entry(backwards_label) \
fst.d f2, -8(sp); \
fst.d f4, -16(sp); \
fst.d f6, -24(sp); \
st.l r1, -28(sp); \
st.l r3, -32(sp); \
st.l r4, -36(sp); \
st.l r5, -40(sp); \
st.l r6, -44(sp); \
st.l r7, -48(sp); \
st.l r8, -52(sp); \
st.l r9, -56(sp); \
st.l r10, -60(sp); \
st.l r11, -64(sp); \
st.l r12, -68(sp); \
st.l r13, -72(sp); \
st.l r14, -76(sp); \
st.l r15, -80(sp); \
adds -96, sp, sp; \
pxpl5op_0 (backwards, Ix_TREEltZERO_L3); \
bte 0x0, iparam4, backwards_label; \
pxpl5op_0 (backwards, Ix_TREEgeZERO_L3); \
backwards_label:: ;\
mov iparam1, rcoeff_pp; \
mov iparam2, opcode0; \
mov iparam3, rvertex; \
mov iparam5, n_polygons; \
fmov.ss fparam1, fmaterial; \
ld.l r0(rcoeff_pp), rcoeffsave; \
orh ha%_last_coeffchunk, r0, r31; \
ld.l l%_last_coeffchunk(r31), rcoeffmax; \
mov (chunk_next_offset-512), r31; \
adds r31, rcoeffmax, rcoeffmax
//}}}
//{{{ triangle_exit
#define triangle_exit \
st.l rcoeffsave, 0(rcoeff_pp); \
adds 96, sp, sp; \
adds 4, rcoeffptr, iparam1; \
ld.l -80(sp), r15; \
ld.l -76(sp), r14; \
ld.l -72(sp), r13; \
ld.l -68(sp), r12; \
ld.l -64(sp), r11; \
ld.l -60(sp), r10; \
ld.l -56(sp), r9; \
ld.l -52(sp), r8; \
ld.l -48(sp), r7; \
ld.l -44(sp), r6; \
ld.l -40(sp), r5; \
ld.l -36(sp), r4; \
ld.l -32(sp), r3; \
ld.l -28(sp), r1; \
fld.d -24(sp), f6; \
fld.d -16(sp), f4; \
bri r1; \
fld.d -8(sp), f2
//}}}
//{{{ fix_rcoeffptr
#define fix_rcoeffptr(long) \
adds ((((long*8)+31)&(0xffffffe0)) - 4), rcoeffsave, rcoeffptr
//}}}
//{{{ 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::
#define max_screen_x fx4
#define max_screen_y fy4
adds FACET_vert0_offs, r0, itmp2 // index into vert[2] of connection
fld_from(ftmp3,.C00037)
ld.l itmp2(rvertex), rvert // rvert is vertex[0]
fld_from(ftmp1,.C362436)
fld.d VERT_position_offs(rvert), fminx
fld.l VERT_z_offs(rvert), fminz
dfld_from(max_screen_x,.Cmax_x)
fmov.dd fminx, fmaxx
fmov.ss fminz, ftexscale
// rvert_p should be pointing at conn->verts[0]
// nv should be a temp, ditto minus1
adds -2, n_verts, r31 // set up for bla - will loop twice on triangle
adds -1, r0, itmp1 // auto-dec for bla
adds 4, itmp2, itmp2 // bump vertex for minimax tests
bla itmp1, r31, vertloop_db
vertloop::
ld.l itmp2(rvertex), rvert
vertloop_db::
fld.d VERT_position_offs(rvert), fx2
pfgt.ss fx2, fmaxx, f0
bnc xmax_ok
br xmin_ok
fmov.ss fx2, fmaxx
xmax_ok::
pfgt.ss fminx, fx2, f0
bnc xmin_ok
fmov.ss fx2, fminx
xmin_ok::
ycheck::
pfgt.ss fy2, fmaxy, f0
bnc ymax_ok
br ymin_ok
fmov.ss fy2, fmaxy
ymax_ok::
pfgt.ss fminy, fy2, f0
bnc ymin_ok
fmov.ss fy2, fminy
ymin_ok::
zcheck::
bte 0x0, needs_texture, zmin_ok
fld.l VERT_z_offs(rvert), fv2
pfgt.ss fv2, ftexscale, f0
bnc texscale_ok
br zmin_ok
fmov.ss fv2, ftexscale
texscale_ok::
pfgt.ss fminz, fv2, f0
bnc zmin_ok
fmov.ss fv2, fminz
zmin_ok::
bla itmp1, r31, vertloop
adds 4, itmp2, itmp2
// re-load x any y registers we have trashed
fld.d VERT_position_offs(rv1), fx1
fld.d VERT_position_offs(rv2), fx2
fld.d VERT_position_offs(rv3), fx3
// now pipe up repeated expressions
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
mov backwards, iparam1
bri r1
or 0x0, r0, r31
.triv_reject::
bri r1
or 0x1, r0, r31
//}}}
//{{{ _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 _planarize_fn_p
.align 8
_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
//}}}
//{{{ _texture_rescale
.globl _texture_rescale
.align 8
_texture_rescale::
#define eight ftmp3
#define max_by_eight ftmp2
//
// ENSURE YOU CALL THIS STRAIGHT AFTER PLANARIZING texu, v and z !!!
//
// note that at the nearest point on a triangle, the texz value is
// forced to 'turn_tex_to_z'. premultiply the far z by 8. then
//
// while (far_z < turn_tex_to_z) {
// enable_pixels_if_lt_turn_tex_to_z_by_8;
// far_z *= 8.0f;
// }
//
// i.e repeatedly execute MEMltTREE_C1 ( turn_z_to_tex / 8);
//
// rcoeffptr points at the next free word
//
// i just wrote
// tree a b c
// tree a b c
// tree a b c
// ==> tree_lt_mem c
// tree 8a 8b 8c
// tree 8a 8b 8c
// tree 8a 8b 8c
//
// so the first tree is at rcoeffptr-(12*4)
fld_from(max_by_eight, _.Cturn_z_to_tex_by_4 )
fld_from(eight, .four_point_0 )
// precompute this opcode in parallel with multiply
pxpl5op_1 ( iparam2,Ix_MEMintoENAB, dvpx_enblpush )
// adds 1, r0, extra_stuff // this 1 deals with push / pop opcodes
fmul.ss eight, fminz, fminz // minz*=8
adds 4, rcoeffptr, rcoeffptr
// so now rcoeffptr is next free opcode
// precompute the selective disable opcode
// N.B - STAY ENABLED if my texz < (tex_to_z / 8)
pxpl5op_2 ( iparam1, Ix_MEMltTREE_C1, dvpx_texz, dvpx_texzbits )
// the delayed branch op
fld.l -(12*4)(rcoeffptr), ftmp6
.loop_8x:
pfgt.ss fminz, ftexscale, f0
bc .done_8x
// do texu - note delayed branch opcode is missing
fld.l -(11*4)(rcoeffptr), ftmp7
fld.l -(10*4)(rcoeffptr), ftmp8
fld.l -(9*4)(rcoeffptr), ftmp9
pfmul.ss eight, ftmp7, f0
pfmul.ss eight, ftmp8, f0
pfmul.ss eight, ftmp9, f0
pfmul.ss f0, f0, ftmp7
pfmul.ss f0, f0, ftmp8
pfmul.ss f0, f0, ftmp9
// do the disable pixels thing
st.l iparam1, 0(rcoeffptr)
fst.l max_by_eight, 4(rcoeffptr)
fst.l ftmp6, 8(rcoeffptr)
fst.l ftmp7, 12(rcoeffptr)
fst.l ftmp8, 16(rcoeffptr)
fst.l ftmp9, 20(rcoeffptr)
// do texu
fld.l -(8*4)(rcoeffptr), ftmp6
fld.l -(7*4)(rcoeffptr), ftmp7
fld.l -(6*4)(rcoeffptr), ftmp8
fld.l -(5*4)(rcoeffptr), ftmp9
pfmul.ss eight, ftmp7, f0
pfmul.ss eight, ftmp8, f0
pfmul.ss eight, ftmp9, f0
pfmul.ss f0, f0, ftmp7
pfmul.ss f0, f0, ftmp8
pfmul.ss f0, f0, ftmp9
fst.l ftmp6, 24(rcoeffptr)
fst.l ftmp7, 28(rcoeffptr)
fst.l ftmp8, 32(rcoeffptr)
fst.l ftmp9, 36(rcoeffptr)
// do texv
fld.l -(4*4)(rcoeffptr), ftmp6
fld.l -(3*4)(rcoeffptr), ftmp7
fld.l -(2*4)(rcoeffptr), ftmp8
fld.l -(1*4)(rcoeffptr), ftmp9
pfmul.ss eight, ftmp7, f0
pfmul.ss eight, ftmp8, f0
pfmul.ss eight, ftmp9, f0
pfmul.ss f0, f0, ftmp7
pfmul.ss f0, f0, ftmp8
pfmul.ss f0, f0, ftmp9
fst.l ftmp6, 40(rcoeffptr)
fst.l ftmp7, 44(rcoeffptr)
fst.l ftmp8, 48(rcoeffptr)
fst.l ftmp9, 52(rcoeffptr)
fmul.ss eight, fminz, fminz
adds 7, extra_stuff, extra_stuff
adds 56, rcoeffptr, rcoeffptr
bte 15, extra_stuff, .done_8x
// clamp at a maximum of 3 rescans, roughly 1.5x time
br .loop_8x // do something in delayed branch!!
fld.l -(12*4)(rcoeffptr), ftmp6
.done_8x:
bri r1
st.l iparam2, 0(rcoeffptr)
#undef eight
#undef max_by_eight
//}}}
//{{{ locals defines for this fn
#define divpl5_xshift 6
#define divpl5_yshift 7
#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)
call _next_binchunk
adds -80, sp, sp
// lets restore registers
adds 80, sp, sp
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
// now iparam1 holds nextbin
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
// restore iparam1
ld.l -4(sp), r16
// 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
.align 8
_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
// rcoeffptr holds last place we wrote
// rcoeffsave is base of data
// so, (rcoeffptr+7 - rcoeffbase) >> 3 gives n_words
ixfr rcoeffsave, f24 // fv1
adds 7, rcoeffptr, r31
subs r31, rcoeffsave, rcoeffsave
shr 0x3, rcoeffsave, r31
orh (DMA_SEND_VAL>>16)&0xffff, r31, iparam2
adds 35, rcoeffptr, rcoeffptr
d.pftrunc.sd fminx, f0
andnot 31, rcoeffptr, rcoeffsave
d.pftrunc.sd fminy, f0
orh ha%_screenbins, r0, r31
d.pftrunc.sd fmaxx, f0
ld.l l%_screenbins(r31), r31
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
//}}}
//{{{ chunk_fn
.align 8
chunk_fn::
subs rcoeffmax, rcoeffsave, r0
bnc .dont_grab_chunk
// do we need to malloc, or shall we just chain the list
// find last_coeffchunk from rcoeffmax
// well - rcoeffmax=lastcoeffchunk+65532-512, so
// add 512 to rcoeffmax, and we have the next pointer
// hmm trace regs here ?
ld.l 512(rcoeffmax), rcoeffsave
// rcoeffsave=lcc->next
btne 0x0, rcoeffsave, .dont_malloc
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)
mov 65536, r16
call _newBytes
adds -80, sp, sp
// lets restore registers
adds 80, sp, sp
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
mov r16, rcoeffsave
// rcoeffsave=malloc(64k)
st.l r16, 512(rcoeffmax)
// lcc->next = rcoeffsave
mov chunk_next_offset, r31
fst.l f0, r31(rcoeffsave)
// rcoeffsave->next = NULL
.dont_malloc::
// last_coeffchunk=next,
// rcoeffptr=next,
// rcoeffmax=next+65020,
orh ha%_last_coeffchunk, r0, r31
st.l rcoeffsave, l%_last_coeffchunk(r31)
mov (chunk_next_offset-512), r31
adds r31, rcoeffsave, rcoeffmax
.dont_grab_chunk::
bri r1
nop
//}}}
//{{{ opacity_intro(label1, label2)
#define opacity_intro(label1,label2) \
label1::;\
ld.l FACET_touched_offs(rvertex), r31;\
ld.l FACET_nverts_offs(rvertex), n_verts; \
bte 0x0, r31, label2; \
call chunk_fn; \
ld.l (FACET_vert0_offs+0)(rvertex), rv1; \
adds 12, rcoeffsave, rcoeffptr; \
ld.l (FACET_vert0_offs+4)(rvertex), rv2; \
or Ix_SETENABS(), r0, iparam2; \
ld.l (FACET_vert0_offs+8)(rvertex), rv3; \
st.l iparam2, 0(rcoeffsave); \
pxpl5op_2(iparam2,Ix_MEMgeSCA_S1, dvpx_opacity, dvpx_opacitybits); \
st.l iparam2, 4(rcoeffsave); \
or P_MEMgeSCA(dvpx_opacity, dvpx_opacitybits), r0, iparam2; \
st.l iparam2, 8(rcoeffsave); \
st.l opcode0, 12(rcoeffsave)
//}}}
//{{{ ignore_opacity_intro(label1,label2)
#define ignore_opacity_intro(label1,label2) \
label1::;\
ld.l FACET_touched_offs(rvertex), r31;\
ld.l FACET_nverts_offs(rvertex), n_verts; \
bte 0x0, r31, label2; \
call chunk_fn; \
ld.l (FACET_vert0_offs+0)(rvertex), rv1; \
adds 0, rcoeffsave, rcoeffptr; \
ld.l (FACET_vert0_offs+4)(rvertex), rv2; \
or Ix_SETENABS(), r0, iparam2; \
ld.l (FACET_vert0_offs+8)(rvertex), rv3; \
st.l iparam2, 0(rcoeffptr)
//}}}
//{{{ next_poly(label)
#define next_poly(label1,label2) \
label2::;\
adds -1, n_polygons, n_polygons; \
xor 0x0000, n_polygons, r0; \
bnc.t label1; \
ld.l 0(rvertex), rvertex
//}}}
// /////////////////////////////
// the currently implemented functions
// _tri_zb_rgb
// _tri_zb_rgb_t
// _tri_zb_f
// _tri_zb_f_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
//
// use register backwards to hold edge opcode, so intro needs to go,
// if backwards, opcode=tree_ge_zero, else opcode=tree_lt_zero
//
//
// triangle, z-buffered, flat
// 16 64-bit words
//
//{{{ _tri_zb_f
.globl _tri_zb_f
.align 8
_tri_zb_f::
triangle_entry(back_000)
adds 0, r0, needs_texture
// 4 4
//
// new opacity code
//
opacity_intro(label000, label001)
call _preplanarize_fn_p
adds VERT_z_offs, r0, iparam2
// should we just exit ?
xor 0x0, r31, r0
bnc label001
// 12 16
//{{{ 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
nop // adds 16, 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 21
call _planarize_fn_p
or VERT_z_offs, r0, iparam2
fld.l FACET_r_offs(rvertex), fv2
// 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
// 9 30
pxpl5op_2(iparam2,Ix_TREEclmpintoMEM_C1, dvpx_r24, 8 )
st.l iparam2, 4(rcoeffptr)
pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_r24, 8 )
st.l iparam1, 8(rcoeffptr)
fst.l fv2, 12(rcoeffptr)++
fld.l FACET_g_offs(rvertex), fv2
pxpl5op_2(iparam2,Ix_TREEclmpintoMEM_C1, dvpx_g24, 8 )
st.l iparam2, 4(rcoeffptr)
pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_g24, 8 )
st.l iparam1, 8(rcoeffptr)
fst.l fv2, 12(rcoeffptr)++
fld.l FACET_b_offs(rvertex), fv2
pxpl5op_2(iparam2,Ix_TREEclmpintoMEM_C1, dvpx_b24, 8 )
st.l iparam2, 4(rcoeffptr)
pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_b24, 8 )
st.l iparam1, 8(rcoeffptr)
fst.l fv2, 12(rcoeffptr)++
// 2 32
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, 16 )
//
// fix_rcoeffptr(16)
//
// mov rcoeffsave, iparam1
call _safe_binitize_fn
fst.l f0, 4(rcoeffptr)++ // addu 10, r0, iparam3
next_poly(label000,label001)
.bomb_tri_zb_f::
triangle_exit
//}}}
// triangle, z-buffered, rgb
// 19 64-bit words
//
//{{{ _tri_zb_rgb
.globl _tri_zb_rgb
.align 8
_tri_zb_rgb::
triangle_entry(back_001)
adds 0, r0, needs_texture
// 4 4
//
// new opacity code
//
opacity_intro(label002,label003)
call _preplanarize_fn_p
adds VERT_z_offs, r0, iparam2
// should we just exit ?
xor 0x0, r31, r0
bnc label003
// 12 16
//{{{ 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
nop // adds 16, 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 21
// pxpl5op_2(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
call _planarize_fn_p
or VERT_r_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 23
pxpl5op_2(iparam2,Ix_SCAintoMEM_S1, dvpx_scalar, dvpx_scalarbits)
st.l iparam2, 8(rcoeffptr)
fst.l fmaterial, 12(rcoeffptr)++
// 15 38
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
// DMAop_1 (iparam2,DMA_SEND, 19 )
//
// fix_rcoeffptr(19)
//
// mov rcoeffsave, iparam1
call _safe_binitize_fn
fst.l f0, 4(rcoeffptr)++ // addu 10, r0, iparam3
next_poly(label002,label003)
.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...
//
//
// all these functions need the texture rescale
//
//
// triangle, z-buffered, flat, textured
// 22 64-bit words
//
//{{{ _tri_zb_f_t
.globl _tri_zb_f_t
.align 8
_tri_zb_f_t::
triangle_entry(back_002)
adds 1, r0, needs_texture
// 4 4
//
// new opacity code
//
opacity_intro(label004,label005)
call _preplanarize_fn_p
adds VERT_z_offs, r0, iparam2
// should we just exit ?
xor 0x0, r31, r0
bnc label005
// 12 16
//{{{ 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
nop // adds 16, 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 21
// TEXTURIZE TO FIND ZSCALE
fld_from ( ftmp2, _.Cturn_z_to_tex )
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
fmul.ss fminz, ftmp1, fminz
pxpl5op_2(iparam1,Ix_MEMltTREE_L3,dvpx_zbuf,dvpx_zbufbits)
call _planarize_fn_p
or VERT_tex_u_offs, r0, iparam2
fmov.ss ftmp7, fv1
fmov.ss ftmp8, fv2
fmov.ss ftmp9, fv3
// push enable flag for texture support
pxpl5op_1 ( iparam1,Ix_ENABintoMEM, dvpx_enblpush );
st.l iparam1, 8(rcoeffptr)
adds 8, rcoeffptr, rcoeffptr
// 4 25 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
fld_from ( ftmp2, _Cdelta_u )
pfadd.ss ftmp2, fv1, f0
pfadd.ss ftmp2, fv2, f0
pfadd.ss ftmp2, fv3, f0
pfadd.ss f0, f0, fv1
m12apm.ss ftmp7, fv1, fv2
m12apm.ss ftmp8, fv2, fv3
pfmul.ss ftmp9, fv3, f0
pfmul.ss f0, f0, fv1
pfmul.ss f0, f0, fv2
pfmul.ss f0, f0, fv3
// 4 29 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
fld_from ( ftmp2, _Cdelta_v )
pfadd.ss ftmp2, fv1, f0
pfadd.ss ftmp2, fv2, f0
pfadd.ss ftmp2, fv3, f0
pfadd.ss f0, f0, fv1
m12apm.ss ftmp7, fv1, fv2
m12apm.ss ftmp8, fv2, fv3
pfmul.ss ftmp9, fv3, f0
pfmul.ss f0, f0, fv1
pfmul.ss f0, f0, fv2
pfmul.ss f0, f0, fv3
// 4 33 tex u-coordinate
pxpl5op_2(iparam1,Ix_TREEintoMEM_L3, dvpx_texv, dvpx_texvbits)
call _planarize_fn_p
or VERT_z_offs, r0, iparam2
// do texture dynamic range frig
call _texture_rescale
adds 1, r0, extra_stuff
// 9 42
fld.l FACET_r_offs(rvertex), fv2
pxpl5op_2(iparam2,Ix_TREEclmpintoMEM_C1, dvpx_r24, 8 )
st.l iparam2, 4(rcoeffptr)
pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_r24, 8 )
st.l iparam1, 8(rcoeffptr)
fst.l fv2, 12(rcoeffptr)++
fld.l FACET_g_offs(rvertex), fv2
pxpl5op_2(iparam2,Ix_TREEclmpintoMEM_C1, dvpx_g24, 8)
st.l iparam2, 4(rcoeffptr)
pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_g24, 8 )
st.l iparam1, 8(rcoeffptr)
fst.l fv2, 12(rcoeffptr)++
fld.l FACET_b_offs(rvertex), fv2
pxpl5op_2(iparam2,Ix_TREEclmpintoMEM_C1, dvpx_b24, 8)
st.l iparam2, 4(rcoeffptr)
pxpl5op_2(iparam1,P_TREEclmpintoMEM, dvpx_b24, 8 )
st.l iparam1, 8(rcoeffptr)
fst.l fv2, 12(rcoeffptr)++
// 2 44
pxpl5op_2(iparam1,Ix_SCAintoMEM_S1, dvpx_scalar, dvpx_scalarbits)
st.l iparam1, 4(rcoeffptr)
fst.l fmaterial, 8(rcoeffptr)++
// adds 22, extra_stuff, iparam2
// orh (DMA_SEND_VAL>>16)&0xffff, iparam2, iparam2
// adds 35, rcoeffptr, rcoeffptr
// andnot 31, rcoeffptr, rcoeffptr
// adds -4, rcoeffptr, rcoeffptr
// mov rcoeffsave, iparam1
call _safe_binitize_fn
fst.l f0, 4(rcoeffptr)++ // addu 10, r0, iparam3
next_poly(label004,label005)
.bomb_tri_zb_f_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(back_003)
adds 1, r0, needs_texture
// 4 4
//
// new opacity code
//
opacity_intro(label006,label007)
call _preplanarize_fn_p
adds VERT_z_offs, r0, iparam2
// should we just exit ?
xor 0x0, r31, r0
bnc label007
// 12 16
//{{{ 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
nop // adds 16, 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 21
// TEXTURIZE TO FIND ZSCALE
fld_from ( ftmp2, _.Cturn_z_to_tex )
frcp.ss ftexscale, ftmp1
fmul.ss ftmp1, ftmp2, ftmp1
pfmul.ss fv1, ftmp1, f0
pfmul.ss fv2, ftmp1, f0
pfmul.ss fv3, ftmp1, f0
pfmul.ss f0, f0, ftmp7
pfmul.ss f0, f0, ftmp8
pfmul.ss f0, f0, ftmp9
call _planarize_fn_p
or VERT_tex_u_offs, r0, iparam2
// push enable flag for texture support
pxpl5op_1 ( iparam1,Ix_ENABintoMEM, dvpx_enblpush );
st.l iparam1, 4(rcoeffptr)
pxpl5op_2(iparam1,Ix_TREEintoMEM_L0, dvpx_zbuf, dvpx_zbufbits)
st.l iparam1, 8(rcoeffptr)
fmov.ss ftmp7, fv1
adds 8, rcoeffptr, rcoeffptr // cater for tree_l0 and enable push
fmov.ss ftmp8, fv2
pxpl5op_2(iparam1,Ix_TREEintoMEM_L3, dvpx_texz, dvpx_texzbits)
fmov.ss ftmp9, fv3
// 4 25 tex z-coordinate
call _planarize_fn_p
or VERT_tex_u_offs, r0, iparam2
// fix u-coordinate
// fix v-coordinate
fld_from ( ftmp2, _Cdelta_u )
pfadd.ss ftmp2, fv1, f0
pfadd.ss ftmp2, fv2, f0
pfadd.ss ftmp2, fv3, f0
pfadd.ss f0, f0, fv1
m12apm.ss ftmp7, fv1, fv2
m12apm.ss ftmp8, fv2, fv3
pfmul.ss ftmp9, fv3, f0
pfmul.ss f0, f0, fv1
pfmul.ss f0, f0, fv2
pfmul.ss f0, f0, fv3
// 4 29 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
// fix v-coordinate
fld_from ( ftmp2, _Cdelta_v )
pfadd.ss ftmp2, fv1, f0
pfadd.ss ftmp2, fv2, f0
pfadd.ss ftmp2, fv3, f0
pfadd.ss f0, f0, fv1
m12apm.ss ftmp7, fv1, fv2
m12apm.ss ftmp8, fv2, fv3
pfmul.ss ftmp9, fv3, f0
pfmul.ss f0, f0, fv1
pfmul.ss f0, f0, fv2
pfmul.ss f0, f0, fv3
// 4 33 tex u-coordinate
pxpl5op_2(iparam1,Ix_TREEintoMEM_L3, dvpx_texv, dvpx_texvbits)
call _planarize_fn_p
or VERT_r_offs, r0, iparam2
// do texture dynamic range frig
call _texture_rescale
adds 1, r0, extra_stuff
// 2 35
pxpl5op_2(iparam1,Ix_SCAintoMEM_S1, dvpx_scalar, dvpx_scalarbits )
st.l iparam1, 4(rcoeffptr)
fst.l fmaterial, 8(rcoeffptr)++
// 15 50
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
// adds 25, extra_stuff, iparam2
// orh (DMA_SEND_VAL>>16)&0xffff, iparam2, iparam2
// adds 35, rcoeffptr, rcoeffptr
// andnot 31, rcoeffptr, rcoeffptr
// adds -4, rcoeffptr, rcoeffptr
// mov rcoeffsave, iparam1
call _safe_binitize_fn
fst.l f0, 4(rcoeffptr)++ // addu 10, r0, iparam3
next_poly(label006,label007)
.bomb_tri_zb_rgb_t::
triangle_exit
//}}}
// triangle, z-buffered, rgb, textured, opacity-per-vertex
// 24 64-bit words
//
//{{{ _tri_zb_rgb_o_t
.globl _tri_zb_rgb_o_t
.align 8
_tri_zb_rgb_o_t::
triangle_entry(back_004)
adds 1, r0, needs_texture
// 1 1
//
// new opacity code
//
// destination for per-triangle loop - what registers are still in shape?
ignore_opacity_intro(label008,label009)
call _preplanarize_fn_p
adds VERT_a_offs, r0, iparam2
// should we just exit ?
xor 0x0, r31, r0
bnc label009
// 12 13
//{{{ edgize in-line, pre-loads ix_MEMgeTREE_L3() into iparam1 for opacity compare
// 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
nop // 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_MEMgeTREE_L3, dvpx_opacity, dvpx_opacitybits )
d.i2s1.ss ftmp6, f0, f0
pxpl5op_2_h(iparam1,Ix_MEMgeTREE_L3, dvpx_opacity, dvpx_opacitybits )
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]
//}}}
// 4 17
call _planarize_fn_p
or VERT_z_offs, r0, iparam2
pxpl5op_2(iparam1,Ix_MEMltTREE_L3, dvpx_zbuf,dvpx_zbufbits)
// 5 22
// TEXTURIZE TO FIND ZSCALE
fld_from ( ftmp2, _.Cturn_z_to_tex )
frcp.ss ftexscale, ftmp1
fmul.ss ftmp1, ftmp2, ftmp1
pfmul.ss fv1, ftmp1, f0
pfmul.ss fv2, ftmp1, f0
pfmul.ss fv3, ftmp1, f0
pfmul.ss f0, f0, ftmp7
pfmul.ss f0, f0, ftmp8
pfmul.ss f0, f0, ftmp9
call _planarize_fn_p
or VERT_tex_u_offs, r0, iparam2
// push enable flag for texture support
pxpl5op_1 ( iparam1,Ix_ENABintoMEM, dvpx_enblpush );
st.l iparam1, 4(rcoeffptr)
pxpl5op_2(iparam1,Ix_TREEintoMEM_L0, dvpx_zbuf, dvpx_zbufbits)
st.l iparam1, 8(rcoeffptr)
fmov.ss ftmp7, fv1
adds 8, rcoeffptr, rcoeffptr // cater for tree_l0 and enable push
fmov.ss ftmp8, fv2
pxpl5op_2(iparam1,Ix_TREEintoMEM_L3, dvpx_texz, dvpx_texzbits)
fmov.ss ftmp9, fv3
// 4 26 tex z-coordinate
call _planarize_fn_p
or VERT_tex_u_offs, r0, iparam2
// fix u-coordinate
// fix v-coordinate
fld_from ( ftmp2, _Cdelta_u )
pfadd.ss ftmp2, fv1, f0
pfadd.ss ftmp2, fv2, f0
pfadd.ss ftmp2, fv3, f0
pfadd.ss f0, f0, fv1
m12apm.ss ftmp7, fv1, fv2
m12apm.ss ftmp8, fv2, fv3
pfmul.ss ftmp9, fv3, f0
pfmul.ss f0, f0, fv1
pfmul.ss f0, f0, fv2
pfmul.ss f0, f0, fv3
// 4 30 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
// fix v-coordinate
fld_from ( ftmp2, _Cdelta_v )
pfadd.ss ftmp2, fv1, f0
pfadd.ss ftmp2, fv2, f0
pfadd.ss ftmp2, fv3, f0
pfadd.ss f0, f0, fv1
m12apm.ss ftmp7, fv1, fv2
m12apm.ss ftmp8, fv2, fv3
pfmul.ss ftmp9, fv3, f0
pfmul.ss f0, f0, fv1
pfmul.ss f0, f0, fv2
pfmul.ss f0, f0, fv3
// 4 34 tex u-coordinate
pxpl5op_2(iparam1,Ix_TREEintoMEM_L3, dvpx_texv, dvpx_texvbits)
call _planarize_fn_p
or VERT_r_offs, r0, iparam2
// do texture dynamic range frig
call _texture_rescale
adds 1, r0, extra_stuff
// 2 36
pxpl5op_2(iparam1,Ix_SCAintoMEM_S1, dvpx_scalar, dvpx_scalarbits )
st.l iparam1, 4(rcoeffptr)
fst.l fmaterial, 8(rcoeffptr)++
// 15 51
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)++
// adds 26, extra_stuff, iparam2
// orh (DMA_SEND_VAL>>16)&0xffff, iparam2, iparam2
// adds 35, rcoeffptr, rcoeffptr
// andnot 31, rcoeffptr, rcoeffptr
// adds -4, rcoeffptr, rcoeffptr
// mov rcoeffsave, iparam1
call _safe_binitize_fn
fst.l f0, 4(rcoeffptr)++ // addu 10, r0, iparam3
next_poly(label008,label009)
.bomb_tri_zb_rgb_o_t::
triangle_exit
//}}}
#if 0
//{{{ spheres
//
// s p h e r e s
//
//{{{ presphereize
//
// VICIOUS - returns TRIV_REJECT in r31
//
.align 8
_prespherize::
fld.d (0+VERT_position_offs)(rv1), fxc // load x and y
fld.d (8+VERT_position_offs)(rv1), fzc // load z and radius
fld_from ( ftmp1, .C362436 )
dfld_from ( max_screen_x, .Cmax_x )
pfadd.ss fxc, frad, f0
pfadd.ss fyc, frad, f0
pfsub.ss fxc, frad, f0
pfsub.ss fyc, frad, fmaxx // cool pipelining here - dig the pfgt!
// ******************************************
// clamp minimax against screen max coordinates
// now get real minimax xy for binning
//
// firstly check triv rejection, max < 0 etc.
//
pfgt.ss ftmp1, fmaxx, fmaxy
bc .sph_triv_reject
pfgt.ss ftmp1, fmaxy, fminx
bc .sph_triv_reject
pfgt.ss fminx, max_screen_x, fminy
bc .sph_triv_reject
pfgt.ss fminy, max_screen_y, f0
bc .sph_triv_reject
pfgt.ss fminy, fmaxy, f0
bc .sph_triv_reject
pfgt.ss fminx, fmaxx, f0
bc .sph_triv_reject
// now check binning
// get real minx
pfgt.ss fminx, f0, f0
bc .no_clamp_sfminx
fmov.ss f0, fminx
.no_clamp_sfminx::
// get real miny
pfgt.ss fminy, f0, f0
bc .no_clamp_sfminy
fmov.ss f0, fminy
.no_clamp_sfminy::
// get real maxx
pfgt.ss max_screen_x, fmaxx, f0
bc .no_clamp_sfmaxx
fmov.ss max_screen_x, fmaxx
.no_clamp_sfmaxx::
// get real maxy
pfgt.ss max_screen_y, fmaxy, f0
bc .no_clamp_sfmaxy
fmov.ss max_screen_y, fmaxy
.no_clamp_sfmaxy::
fmul.ss fxc, fxc, ftmp1
fld_from(ftwo,.C00037)
fld.d (16+VERT_position_offs)(rv2), flx
fmul.ss fyc, fyc, ftmp2
fld.l (24+VERT_position_offs)(rv2), flz
fmul.ss frad, frad, fr2
fld_from ( fminus1, .fminus_one )
fadd.ss ftmp1, ftmp2, fx2y2
// do 1.0f / r2
frcp.ss fr2, ftmp1 // error 2^-7
fmul.ss fr2, ftmp1, ftmp2 // guess * divisor
fld.l (28+VERT_position_offs)(rv1), frz
fsub.ss ftwo, ftmp2, ftmp2 // 2 - (guess * divisor)
pxpl5op_1 ( iparam1, Ix_FBITS, 22 )
fmul.ss ftmp1, ftmp2, fr12 // accurate to 2^-15
pxpl5op_1 ( iparam2, P_FBITS, 22 )
bri r1
or 0x0, r0, r31
.sph_triv_reject::
bri r1
or 0x1, r0, r31
//}}}
// sphere, z-buffered, rgb lit
// 17 64-bit words
//
//{{{ _sph_zb_rgb
.globl _sphere_zb_rgb
.align 8
_sphere_zb_rgb::
triangle_entry(sphere_zb_rgb_mesh, back_005)
sphere_zb_rgb_mesh::
// 1 1
//
call _prespherize
st.l iparam2, 4(rcoeffptr)
// should we just exit ?
xor 0x0, r31, r0
bnc .bomb_sphere_zb_rgb
// r2-=x2y2;
//
// fA=x*two;
// fB=y*two;
// fC=r2;
// fD=-1.0f;
// 10 11 fbits, p_fbits, noop, TREE a b c d e f
fsub.ss fr2, fx2y2, fr2 // r^2 now r^2-(x^2+y^2)
st.l iparam1, 8(rcoeffptr) // store I_FBITS
pxpl5op_0 ( iparam1, Ix_TREEgeZERO_Q6 )
fadd.ss fxc, fxc, fxtwo
st.l iparam2, 12(rcoeffptr) // and P_FBITS
fst.l f0, 16(rcoeffptr) // quick NOOP
fadd.ss fyc, fyc, fytwo
st.l iparam1, 20(rcoeffptr) // opcode
fst.l fminus1, 24(rcoeffptr) // done D
fst.l f0, 28(rcoeffptr) // done E
fmul.ss frz, fr12, fK // precompute K
fst.l fminus1, 32(rcoeffptr) // done F
fst.l fxtwo, 36(rcoeffptr) // done A
fmul.ss fxtwo, fK, ftmp1 // do A = twox*K
fst.l fytwo, 40(rcoeffptr) // done B
fst.l fr2, 44(rcoeffptr)++ // done C
// K =rz*r12;
// fA*=K;
// fB*=K;
// fC=(z+rz)-(x2y2*K);
// fD=-K;
//
// opcode = 4 A=20, B=24, C=28, D=8, E=12, F=16
//
// 9 20 zbuf compare / replace
//
fmul.ss fytwo, fK, ftmp2 // do B = twoy*K
pxpl5op_2 ( iparam1, Ix_MEMltTREE_Q6, dvpx_zbuf, dvpx_zbufbits )
st.l iparam1, 4(rcoeffptr) // save MEMltTREE
fsub.ss f0, fK, ftmp3 // do D = -K
fst.l ftmp1, 20(rcoeffptr) // save A
fst.l ftmp2, 24(rcoeffptr) // save B
fmul.ss fx2y2, fK, ftmp1 // do x2y2*K
fst.l ftmp3, 8(rcoeffptr) // save D
fst.l f0, 12(rcoeffptr) // save E 0.0f
fadd.ss fzc, frz, ftmp2 // do z+rz
fst.l ftmp3, 16(rcoeffptr) // save F
fsub.ss ftmp2, ftmp1, ftmp1 // do C = (z+rz) - (x2y2*K)
fst.l ftmp1, 28(rcoeffptr) // save C
pxpl5op_2 ( iparam1, Ix_TREEclmpintoMEM_Q0, dvpx_zbuf, dvpx_zbufbits )
st.l iparam1, 32(rcoeffptr) // save TREEclmp
pxpl5op_2 ( iparam2,P_TREEclmpintoMEM, dvpx_zbuf, dvpx_zbufbits )
st.l iparam2, 36(rcoeffptr) // save P_TREEclmp
// 3 23 SCAintoMEM, material, CLEAR ( r, g, b )
// r_invlz=r/lz;
frcp.ss flz, ftmp1 // start 1.0 / fC - 2^-8
fmul.ss flz, ftmp1, ftmp2 // guess * divisor
pxpl5op_2(iparam2, Ix_CLEAR, dvpx_r24, 24 )
st.l iparam2, 40(rcoeffptr) // store IGC_CLEAR
fsub.ss ftwo, ftmp2, ftmp2 // 2 - (guess * divisor)
pxpl5op_2(iparam1, Ix_SCAintoMEM_S1, dvpx_scalar, dvpx_scalarbits)
st.l iparam1, 44(rcoeffptr) // store SCAintoMEM
fmul.ss ftmp1, ftmp2, frinvlz // accurate to 2^-15
fst.l fmaterial, 48(rcoeffptr)++ // store SCALAR
// 8 31
pxpl5op_2(iparam1,Ix_TREEclmpintoMEM_Q6, dvpx_r24, 8 )
fmul.ss frinvlz, frad, frinvlz
st.l iparam1, 4(rcoeffptr) // store TREEclmp
pxpl5op_2(iparam2,P_TREEclmpintoMEM, dvpx_r24, 8 )
st.l iparam2, 8(rcoeffptr) // store P_TREEclmp
// K=-255.99f*lz*r12;
// lx*=r_invlz;
// ly*=r_invlz;
//
// fA= K*((x*two) - lx);
// fB= K*((y*two) - ly);
// fC= K*(r2 + (lx*x + ly*y));
// fD=-K;
fmul.ss flz, fr12, ftmp1
fld_from ( ftmp2, .fminus_256 )
fmul.ss flx, frinvlz, flx
pxpl5op_1 ( iparam1,Ix_FBITS, 15 )
st.l iparam1, 36(rcoeffptr)
fmul.ss ftmp2, ftmp1, fK // got K
pxpl5op_1 ( iparam1,P_FBITS, 15 )
st.l iparam1, 40(rcoeffptr)
fsub.ss f0, fK, ftmp3 // tmp3 = -K
fmul.ss fly, frinvlz, fly
fst.l ftmp3, 12(rcoeffptr) // save D
fst.l f0, 16(rcoeffptr) // save E
fsub.ss fxtwo, flx, ftmp1
fst.l ftmp3, 20(rcoeffptr) // save F
fsub.ss fytwo, fly, ftmp2
fmul.ss fK, ftmp1, ftmp1 // A
fmul.ss fK, ftmp2, ftmp2 // B
fst.l ftmp1, 24(rcoeffptr) // save A
fst.l ftmp2, 28(rcoeffptr) // save B
fmul.ss flx, fxc, ftmp1
DMAop_1 (iparam2, DMA_SEND, 17 )
fmul.ss fly, fyc, ftmp2
mov rcoeffsave, iparam1
fadd.ss ftmp1, ftmp2, ftmp2 // lx.x + ly.y
fadd.ss fr2, ftmp2, ftmp1 // r2 + lx.x + ly.y
fmul.ss fK, ftmp1, ftmp2 // tmp2 = C
fst.l ftmp2, 32(rcoeffptr) // save C
// 3 34
fst.l f0, 44(rcoeffptr)++
fix_rcoeffptr(17)
call _safe_binitize_fn
addu 10, r0, iparam3
.bomb_sphere_zb_rgb::
triangle_exit
//}}}
//{{{ _circ_z_rgb
//
// z-buffered disk, full colour
//
.globl _circ_zb_rgb
.align 8
_circ_zb_rgb::
triangle_entry(circ_zb_rgb_mesh)
circ_zb_rgb_mesh::
// 1 1
//
call _prespherize
st.l iparam2, 4(rcoeffptr)
// should we just exit ?
xor 0x0, r31, r0
bnc .bomb_circ_zb_rgb
// r2-=x2y2;
//
// fA=x*two;
// fB=y*two;
// fC=r2;
// fD=-1.0f;
// 10 11 fbits, p_fbits, noop, TREE a b c d e f
fsub.ss fr2, fx2y2, fr2 // r^2 now r^2-(x^2+y^2)
st.l iparam1, 8(rcoeffptr) // store I_FBITS
pxpl5op_0 ( iparam1, Ix_TREEgeZERO_Q6 )
fadd.ss fxc, fxc, fxtwo
st.l iparam2, 12(rcoeffptr) // and P_FBITS
fst.l f0, 16(rcoeffptr) // quick NOOP
fadd.ss fyc, fyc, fytwo
st.l iparam1, 20(rcoeffptr) // opcode
fst.l fminus1, 24(rcoeffptr) // done D
fst.l f0, 28(rcoeffptr) // done E
fst.l fminus1, 32(rcoeffptr) // done F
fst.l fxtwo, 36(rcoeffptr) // done A
fst.l fytwo, 40(rcoeffptr) // done B
fst.l fr2, 44(rcoeffptr)++ // done C
// 5 16 MEMltTREE, C, TREEintoMEM, SCAintoMEM, S
pxpl5op_2 ( iparam1, Ix_MEMltTREE_C1, dvpx_zbuf, dvpx_zbufbits )
st.l iparam1, 4(rcoeffptr)
fst.l zc, 8(rcoeffptr)++
pxpl5op_2 ( iparam1, Ix_TREEintoMEM_C0, dvpx_zbuf, dvpx_zbufbits )
st.l iparam1, 4(rcoeffptr)
pxpl5op_2(iparam2,Ix_SCAintoMEM_S1, dvpx_scalar, (dvpx_intrinsic-dvpx_scalar))
st.l iparam2, 8(rcoeffptr)
fst.l fmaterial, 12(rcoeffptr)++
// now put r g b into memory
// 5 16 MEMltTREE, C, TREEintoMEM, SCAintoMEM, S
pxpl5op_2(iparam2,Ix_TREEintoMEM_L3, dvpx_r24, 24 )
st.l iparam2, 4(rcoeffptr)
fst.l f0, 8(rcoeffptr)
pxpl5op_1 ( iparam1,Ix_FBITS, 15 )
pxpl5op_1 ( iparam2,P_FBITS, 15 )
st.l iparam1, 40(rcoeffptr)
st.l iparam2, 40(rcoeffptr)
fst.l f0, 44(rcoeffptr)++
DMAop_1 (iparam2, DMA_SEND, 17 )
fix_rcoeffptr(17)
call _safe_binitize_fn
addu 10, r0, iparam3
.bomb_circ_zb_rgb::
triangle_exit
//}}}
//}}}
#endif