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>
2306 lines
68 KiB
Plaintext
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
|
|
//}}}
|
|
|