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>
2182 lines
63 KiB
Scheme
2182 lines
63 KiB
Scheme
|
|
|
|
//{{{ 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 "\pazplrgb\pxpl5sup\pxplmacr.h"
|
|
#include "\pazplrgb\pxpl5sup\divpxmap.h"
|
|
#include "\pazplrgb\pxpl5sup\dmaengn.h"
|
|
#include "\pazplrgb\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
|
|
//}}}
|
|
|
|
//{{{ 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_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
|
|
|
|
fld_from(ftmp3,.C00037)
|
|
fld_from(ftmp1,.C362436)
|
|
dfld_from(max_screen_x,.Cmax_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:
|
|
|
|
and needs_texture, needs_texture, r0
|
|
bc .texscale_done
|
|
|
|
pfgt.ss fv1, fv2, f0
|
|
bc .z1_bigger
|
|
// so y1 < y2
|
|
pfgt.ss fv1, fv3, f0
|
|
bnc .z1_min
|
|
fmov.ss fv3, fminz
|
|
br .done_texscale
|
|
fmov.ss fv2, ftexscale
|
|
.z1_min:
|
|
// so y1<y2, and y1<y3, is y3>y2
|
|
pfgt.ss fv3, fv2, f0
|
|
bnc .z2_max
|
|
fmov.ss fv1, fminz
|
|
br .done_texscale
|
|
fmov.ss fv3, ftexscale
|
|
.z2_max:
|
|
fmov.ss fv1, fminz
|
|
br .done_texscale
|
|
fmov.ss fv2, ftexscale
|
|
|
|
.z1_bigger:
|
|
// so y2 < y1
|
|
pfgt.ss fv2, fv3, f0
|
|
bnc .z2_min
|
|
// so y2 < y1, and y3 < y2, so y3 min, y1 max
|
|
fmov.ss fv3, fminz
|
|
br .done_texscale
|
|
fmov.ss fv1, ftexscale
|
|
.z2_min:
|
|
// so y2<y1, and y2<y3, is y3>y1
|
|
pfgt.ss fv3, fv1, f0
|
|
bnc .z1_max
|
|
fmov.ss fv2, fminz
|
|
br .done_texscale
|
|
fmov.ss fv3, ftexscale
|
|
.z1_max:
|
|
fmov.ss fv2, fminz
|
|
fmov.ss fv1, ftexscale
|
|
|
|
|
|
|
|
// .texscale_check:
|
|
// pfgt.ss fv1, fv2, f0
|
|
// bc .z1_bigger
|
|
//
|
|
// pfgt.ss fv3, fv2, f0
|
|
// bc .z3_biggest
|
|
//
|
|
// // f2 is biggest, which is smallest
|
|
// pfgt.ss fv3, fv1, f0
|
|
// fmov.ss fv2, ftexscale
|
|
// bc .z1_smallest
|
|
// br .done_texscale
|
|
// fmov.ss fv3, fminz
|
|
// .z1_smallest::
|
|
// br .done_texscale
|
|
// fmov.ss fv1, fminz
|
|
//
|
|
// .z1_bigger:
|
|
// pfgt.ss fv3, fv1, f0
|
|
// bc .z3_biggest
|
|
//
|
|
// // f1 is biggest, which is smallest
|
|
// br .done_texscale
|
|
// fmov.ss fv1, ftexscale
|
|
//
|
|
// .z3_biggest:
|
|
// fmov.ss fv3, ftexscale
|
|
//
|
|
|
|
// now pipe up repeated expressions
|
|
.done_texscale:
|
|
.texscale_done:
|
|
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
|
|
|
|
//}}}
|
|
//{{{ _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_8 )
|
|
|
|
fld_from(eight, .eight_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 22, 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
|
|
//}}}
|
|
//{{{ _planarize_tx_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_tx_p
|
|
.align 8
|
|
|
|
_planarize_tx_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_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
|
|
//
|
|
|
|
//
|
|
// 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)
|
|
|
|
adds 0, r0, needs_texture
|
|
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_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)
|
|
adds 4, rcoeffptr, rcoeffptr
|
|
|
|
// 9 27
|
|
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 VERT_g_offs(rv2), 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 VERT_b_offs(rv2), 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)++
|
|
|
|
// 3 30
|
|
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, 15 )
|
|
|
|
// 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(15)
|
|
|
|
mov rcoeffsave, iparam1
|
|
|
|
call _safe_binitize_fn
|
|
addu 10, r0, iparam3
|
|
|
|
.bomb_tri_zb_f::
|
|
|
|
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)
|
|
|
|
adds 0, r0, needs_texture
|
|
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_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 35
|
|
pxpl5op_2(iparam2,Ix_SCAintoMEM_S1, dvpx_scalar, dvpx_scalarbits)
|
|
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_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, 18 )
|
|
|
|
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...
|
|
//
|
|
//
|
|
// all these functions need the texture rescale
|
|
//
|
|
//
|
|
// triangle, z-buffered, flat, textured
|
|
// 21 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)
|
|
|
|
adds 1, r0, needs_texture
|
|
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
|
|
|
|
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 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_r_offs, r0, iparam2
|
|
|
|
// do texture dynamic range frig
|
|
call _texture_rescale
|
|
adds 1, r0, extra_stuff
|
|
// 9 39
|
|
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 VERT_g_offs(rv2), 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 VERT_b_offs(rv2), 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)++
|
|
|
|
|
|
// 3 42
|
|
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)++
|
|
|
|
adds 21, 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
|
|
addu 10, r0, iparam3
|
|
|
|
|
|
.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(tri_zb_rgb_t_mesh)
|
|
tri_zb_rgb_t_mesh::
|
|
|
|
|
|
// 1 1
|
|
//
|
|
st.l iparam2, 4(rcoeffptr)
|
|
|
|
adds 1, r0, needs_texture
|
|
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
|
|
|
|
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 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
|
|
|
|
// do texture dynamic range frig
|
|
call _texture_rescale
|
|
adds 1, r0, extra_stuff
|
|
|
|
// 2 32
|
|
pxpl5op_2(iparam1,Ix_SCAintoMEM_S1, dvpx_scalar, dvpx_scalarbits )
|
|
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)++
|
|
|
|
adds 24, 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
|
|
addu 10, r0, iparam3
|
|
|
|
.bomb_tri_zb_rgb_t::
|
|
|
|
triangle_exit
|
|
//}}}
|
|
|
|
|
|
|
|
//
|
|
// 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)
|
|
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
|
|
//}}}
|
|
|
|
#if 0
|
|
//{{{ _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
|