some more review. not working still.

This commit is contained in:
ed
2026-08-10 23:04:43 -04:00
parent 4afd1af0fd
commit 144c605ad8
14 changed files with 257 additions and 925 deletions
-347
View File
@@ -39,350 +39,3 @@ WORD_COUNT(mac_put_disp_env, 5)
, mac_gcmd_push(gp0_word_nop(), reg_transfer, reg_base, port)
WORD_COUNT(mac_put_draw_env, 16)
#define mac_resolve_look_at__input_and_sub(...) \
load_word(r_target_ptr, R_TapePtr, O_(Binds_ResolveLookAtSub,target)) \
, load_word(r_eye_ptr, R_TapePtr, O_(Binds_ResolveLookAtSub,eye)) \
, load_word(r_up_in_ptr, R_TapePtr, O_(Binds_ResolveLookAtSub,up_in)) \
, add_ui_self( R_TapePtr, S_(Binds_ResolveLookAtSub)) \
, load_word(r_scratch, R_TapePtr, O_(Binds_ResolveLookAtScratch,scratch_base)) \
, add_ui_self( R_TapePtr, S_(Binds_ResolveLookAtScratch)) /* Stage eye.x/y/z into the scratchpad (atom 6 reads these for the translation
* column). Reuse r_tmp0/r_tmp1/r_tmp2. Offsets via O_(ResolveLookAtScratch,*). */ \
, load_word(r_tmp0, r_eye_ptr, O_(P3_S4,x)) \
, load_word(r_tmp1, r_eye_ptr, O_(P3_S4,y)) \
, load_word(r_tmp2, r_eye_ptr, O_(P3_S4,z)) \
, nop /* load-delay */ \
, store_word(r_tmp0, r_scratch, O_(ResolveLookAtScratch,eye.x)) \
, store_word(r_tmp1, r_scratch, O_(ResolveLookAtScratch,eye.y)) \
, store_word(r_tmp2, r_scratch, O_(ResolveLookAtScratch,eye.z)) /* Stage up_in.x/y/z into the scratchpad (atom 2 reads these for the outer
* product with uz). Reuse r_tmp0/r_tmp1/r_tmp2. */ \
, load_word(r_tmp0, r_up_in_ptr, O_(V3_S4,x)) \
, load_word(r_tmp1, r_up_in_ptr, O_(V3_S4,y)) \
, load_word(r_tmp2, r_up_in_ptr, O_(V3_S4,z)) \
, nop /* load-delay */ \
, store_word(r_tmp0, r_scratch, O_(ResolveLookAtScratch,up_in.x)) \
, store_word(r_tmp1, r_scratch, O_(ResolveLookAtScratch,up_in.y)) \
, store_word(r_tmp2, r_scratch, O_(ResolveLookAtScratch,up_in.z)) /* Compute fwd = target - eye. */ \
, load_word(r_tmp0, r_target_ptr, O_(P3_S4,x)) \
, load_word(r_tmp1, r_target_ptr, O_(P3_S4,y)) \
, load_word(r_tmp2, r_target_ptr, O_(P3_S4,z)) \
, load_word(r_tmp3, r_eye_ptr, O_(P3_S4,x)) \
, load_word(R_AT, r_eye_ptr, O_(P3_S4,y)) \
, load_word(R_V0, r_eye_ptr, O_(P3_S4,z)) \
, nop /* load-delay */ \
, sub_u(r_tmp0, r_tmp0, r_tmp3) \
, sub_u(r_tmp1, r_tmp1, R_AT) \
, sub_u(r_tmp2, r_tmp2, R_V0) /* Store fwd.x/y/z (atom 1 reads these as the normalize src). */ \
, store_word(r_tmp0, r_scratch, O_(ResolveLookAtScratch,fwd.x)) \
, store_word(r_tmp1, r_scratch, O_(ResolveLookAtScratch,fwd.y)) \
, store_word(r_tmp2, r_scratch, O_(ResolveLookAtScratch,fwd.z)) \
, mac_yield()
WORD_COUNT(mac_resolve_look_at__input_and_sub, 34)
#define mac_resolve_look_at__cross_uz_up_in_to_right(...) \
add_si(r_g, r_scratch, O_(ResolveLookAtScratch,uz)) /* r_g = &uz */ \
, add_si(r_h, r_scratch, O_(ResolveLookAtScratch,up_in)) /* r_h = &up_in */ \
, add_si(r_f, r_scratch, O_(ResolveLookAtScratch,right)) /* r_f = &right (out) */ \
, nop /* Load a (uz).x/y/z into r_a/r_b/r_c. */ \
, load_word(r_a, r_g, O_(V3_S4,x)) \
, load_word(r_b, r_g, O_(V3_S4,y)) \
, load_word(r_c, r_g, O_(V3_S4,z)) \
, nop /* Load b (up_in).x/y/z into r_d + R_AT/R_V0 (hardcoded; reusing the
* body's last two loads is fine because the load-delay slot is the nop
* after the third load, and mtc2 below doesn't read these regs). */ \
, load_word(r_d, r_h, O_(V3_S4,x)) \
, load_word(R_AT, r_h, O_(V3_S4,y)) \
, load_word(R_V0, r_h, O_(V3_S4,z)) \
, nop /* mtc2 a → IR1/2/3, b → D1/2/3 (VXY0/VZ0/VXY1). */ \
, gte_mv_to_data_r(r_a, C2_IR1) \
, gte_mv_to_data_r(r_b, C2_IR2) \
, gte_mv_to_data_r(r_c, C2_IR3) \
, gte_mv_to_data_r(r_d, C2_VXY0) /* D1 = b.x */ \
, gte_mv_to_data_r(R_AT, C2_VZ0) /* D2 = b.y */ \
, gte_mv_to_data_r(R_V0, C2_VXY1) /* D3 = b.z */ \
, nop2 /* MTC2 retirement (CPU→COP2 2-slot delay) */ \
, gte_cmdw_outer_product /* OP fires; MAC1/2/3 = a × b */ /* mfc2 MAC1/2/3 → r_a/r_b/r_c (out.x/y/z). */ \
, gte_mv_from_data_r(r_a, C2_MAC1) \
, gte_mv_from_data_r(r_b, C2_MAC2) \
, gte_mv_from_data_r(r_c, C2_MAC3) \
, nop /* MFC2 retirement */ /* Store out.x/y/z to r_f (out ptr = scratch+32). */ \
, store_word(r_a, r_f, O_(V3_S4,x)) \
, store_word(r_b, r_f, O_(V3_S4,y)) \
, store_word(r_c, r_f, O_(V3_S4,z)) \
, mac_yield()
WORD_COUNT(mac_resolve_look_at__cross_uz_up_in_to_right, 29)
#define mac_resolve_look_at__cross_uz_ux_to_up(...) \
add_si(r_g, r_scratch, O_(ResolveLookAtScratch,uz)) /* r_g = &uz */ \
, add_si(r_h, r_scratch, O_(ResolveLookAtScratch,ux)) /* r_h = &ux */ \
, add_si(r_f, r_scratch, O_(ResolveLookAtScratch,up)) /* r_f = &up (out) */ \
, nop /* Load a (uz).x/y/z into r_a/r_b/r_c. */ \
, load_word(r_a, r_g, O_(V3_S4,x)) \
, load_word(r_b, r_g, O_(V3_S4,y)) \
, load_word(r_c, r_g, O_(V3_S4,z)) \
, nop /* Load b (ux).x/y/z into r_d + R_AT/R_V0. */ \
, load_word(r_d, r_h, O_(V3_S4,x)) \
, load_word(R_AT, r_h, O_(V3_S4,y)) \
, load_word(R_V0, r_h, O_(V3_S4,z)) \
, nop /* mtc2 a → IR1/2/3, b → D1/2/3 (VXY0/VZ0/VXY1). */ \
, gte_mv_to_data_r(r_a, C2_IR1) \
, gte_mv_to_data_r(r_b, C2_IR2) \
, gte_mv_to_data_r(r_c, C2_IR3) \
, gte_mv_to_data_r(r_d, C2_VXY0) \
, gte_mv_to_data_r(R_AT, C2_VZ0) \
, gte_mv_to_data_r(R_V0, C2_VXY1) \
, nop2 \
, gte_cmdw_outer_product \
, gte_mv_from_data_r(r_a, C2_MAC1) \
, gte_mv_from_data_r(r_b, C2_MAC2) \
, gte_mv_from_data_r(r_c, C2_MAC3) \
, nop \
, store_word(r_a, r_f, O_(V3_S4,x)) \
, store_word(r_b, r_f, O_(V3_S4,y)) \
, store_word(r_c, r_f, O_(V3_S4,z)) \
, mac_yield()
WORD_COUNT(mac_resolve_look_at__cross_uz_ux_to_up, 29)
#define mac_resolve_look_at__normalize_fwd_to_uz(...) \
add_si(r_a, r_scratch, O_(ResolveLookAtScratch,fwd)) /* r_a = &fwd */ \
, add_si(r_b, r_scratch, O_(ResolveLookAtScratch,uz)) /* r_b = &uz */ \
, nop /* Load src.x/y/z from r_a into r_e/r_f/r_i. */ \
, load_word(r_e, r_a, O_(V3_S4,x)) \
, load_word(r_f, r_a, O_(V3_S4,y)) \
, load_word(r_i, r_a, O_(V3_S4,z)) \
, nop /* load-delay */ /* Stage 1: mtc2 src → IR1/2/3, SQR fires. */ \
, gte_mv_to_data_r(r_e, C2_IR1) \
, gte_mv_to_data_r(r_f, C2_IR2) \
, gte_mv_to_data_r(r_i, C2_IR3) \
, nop \
, gte_cmdw_sqr /* Stage 2: mfc2 MAC1/2/3, sum, mtc2 LZCS. */ \
, gte_mv_from_data_r(r_d, C2_MAC1) \
, gte_mv_from_data_r(r_g, C2_MAC2) \
, gte_mv_from_data_r(r_recip_est, C2_MAC3) \
, nop \
, add_u(r_recip_est, r_recip_est, r_g) \
, add_u(r_recip_est, r_recip_est, r_d) \
, gte_mv_to_data_r(r_recip_est, C2_LZCS) \
, nop2 \
, gte_mv_from_data_r(r_h, C2_LZCR) \
, nop /* Stage 3: compute shift amount, align |v|² to bit 24. */ \
, and_i( r_h, r_h, -2) \
, li_s( r_shift, 31) \
, sub_s( r_shift, r_shift, r_h) \
, shift_aright(r_shift, r_shift, 1) \
, add_si( r_a, r_h, -24) /* r_a = LZCR - 24 (overlapping with r_recip_est; src ptr no longer needed) */ \
, branch_lt_zero(r_a, atom_offset(srav_path_fwd_to_uz, aligned_done_fwd_to_uz)) \
, nop \
, jump_rel(atom_offset(aligned_done_fwd_to_uz, srav_path_fwd_to_uz)) \
, shift_lleft_var(r_recip_est, r_recip_est, r_a) \
, atom_label(srav_path_fwd_to_uz) \
, li_s( r_a, 24) \
, sub_s( r_a, r_a, r_h) \
, shift_aright_var(r_recip_est, r_recip_est, r_a) \
, atom_label(aligned_done_fwd_to_uz) /* r_recip_est holds |v|² aligned to bit 24. */ \
, add_si( r_recip_est, r_recip_est, -64) \
, shift_lleft(r_recip_est, r_recip_est, 1) \
, load_upper_i(r_a, u4_hi(& gte_normalize_sqr_tbl)) \
, or_i_self(r_a, u4_lo(& gte_normalize_sqr_tbl)) \
, add_u(r_a, r_a, r_recip_est) \
, load_half(r_recip_est, r_a, 0) \
, nop /* Stage 4: GPF + srav finalize. */ \
, gte_mv_to_data_r(r_recip_est, C2_IR0) \
, gte_mv_to_data_r(r_e, C2_IR1) \
, gte_mv_to_data_r(r_f, C2_IR2) \
, gte_mv_to_data_r(r_i, C2_IR3) \
, nop2 \
, gte_cmdw_gpf \
, gte_mv_from_data_r(r_e, C2_MAC1) \
, gte_mv_from_data_r(r_f, C2_MAC2) \
, gte_mv_from_data_r(r_i, C2_MAC3) \
, shift_aright_var(r_e, r_e, r_shift) \
, shift_aright_var(r_f, r_f, r_shift) \
, shift_aright_var(r_i, r_i, r_shift) /* Store result.x/y/z to r_b (dst ptr = scratch+16). */ \
, store_word(r_e, r_b, O_(V3_S4,x)) \
, store_word(r_f, r_b, O_(V3_S4,y)) \
, store_word(r_i, r_b, O_(V3_S4,z)) \
, mac_yield()
WORD_COUNT(mac_resolve_look_at__normalize_fwd_to_uz, 59)
#define mac_resolve_look_at__normalize_right_to_ux(...) \
add_si(r_a, r_scratch, O_(ResolveLookAtScratch,right)) /* r_a = &right */ \
, add_si(r_b, r_scratch, O_(ResolveLookAtScratch,ux)) /* r_b = &ux */ \
, nop \
, load_word(r_e, r_a, O_(V3_S4,x)) \
, load_word(r_f, r_a, O_(V3_S4,y)) \
, load_word(r_i, r_a, O_(V3_S4,z)) \
, nop \
, gte_mv_to_data_r(r_e, C2_IR1) \
, gte_mv_to_data_r(r_f, C2_IR2) \
, gte_mv_to_data_r(r_i, C2_IR3) \
, nop \
, gte_cmdw_sqr \
, gte_mv_from_data_r(r_d, C2_MAC1) \
, gte_mv_from_data_r(r_g, C2_MAC2) \
, gte_mv_from_data_r(r_recip_est, C2_MAC3) \
, nop \
, add_u(r_recip_est, r_recip_est, r_g) \
, add_u(r_recip_est, r_recip_est, r_d) \
, gte_mv_to_data_r(r_recip_est, C2_LZCS) \
, nop2 \
, gte_mv_from_data_r(r_h, C2_LZCR) \
, nop \
, and_i( r_h, r_h, -2) \
, li_s( r_shift, 31) \
, sub_s( r_shift, r_shift, r_h) \
, shift_aright(r_shift, r_shift, 1) \
, add_si( r_a, r_h, -24) \
, branch_lt_zero(r_a, atom_offset(srav_path_right_to_ux, aligned_done_right_to_ux)) \
, nop \
, jump_rel(atom_offset(aligned_done_right_to_ux, srav_path_right_to_ux)) \
, shift_lleft_var(r_recip_est, r_recip_est, r_a) \
, atom_label(srav_path_right_to_ux) \
, li_s( r_a, 24) \
, sub_s( r_a, r_a, r_h) \
, shift_aright_var(r_recip_est, r_recip_est, r_a) \
, atom_label(aligned_done_right_to_ux) \
, add_si( r_recip_est, r_recip_est, -64) \
, shift_lleft(r_recip_est, r_recip_est, 1) \
, load_upper_i(r_a, u4_hi(& gte_normalize_sqr_tbl)) \
, or_i_self(r_a, u4_lo(& gte_normalize_sqr_tbl)) \
, add_u(r_a, r_a, r_recip_est) \
, load_half(r_recip_est, r_a, 0) \
, nop \
, gte_mv_to_data_r(r_recip_est, C2_IR0) \
, gte_mv_to_data_r(r_e, C2_IR1) \
, gte_mv_to_data_r(r_f, C2_IR2) \
, gte_mv_to_data_r(r_i, C2_IR3) \
, nop2 \
, gte_cmdw_gpf \
, gte_mv_from_data_r(r_e, C2_MAC1) \
, gte_mv_from_data_r(r_f, C2_MAC2) \
, gte_mv_from_data_r(r_i, C2_MAC3) \
, shift_aright_var(r_e, r_e, r_shift) \
, shift_aright_var(r_f, r_f, r_shift) \
, shift_aright_var(r_i, r_i, r_shift) \
, store_word(r_e, r_b, O_(V3_S4,x)) \
, store_word(r_f, r_b, O_(V3_S4,y)) \
, store_word(r_i, r_b, O_(V3_S4,z)) \
, mac_yield()
WORD_COUNT(mac_resolve_look_at__normalize_right_to_ux, 59)
#define mac_resolve_look_at__normalize_up_to_uy(...) \
add_si(r_a, r_scratch, O_(ResolveLookAtScratch,up)) /* r_a = &up */ \
, add_si(r_b, r_scratch, O_(ResolveLookAtScratch,uy)) /* r_b = &uy */ \
, nop \
, load_word(r_e, r_a, O_(V3_S4,x)) \
, load_word(r_f, r_a, O_(V3_S4,y)) \
, load_word(r_i, r_a, O_(V3_S4,z)) \
, nop \
, gte_mv_to_data_r(r_e, C2_IR1) \
, gte_mv_to_data_r(r_f, C2_IR2) \
, gte_mv_to_data_r(r_i, C2_IR3) \
, nop \
, gte_cmdw_sqr \
, gte_mv_from_data_r(r_d, C2_MAC1) \
, gte_mv_from_data_r(r_g, C2_MAC2) \
, gte_mv_from_data_r(r_recip_est, C2_MAC3) \
, nop \
, add_u(r_recip_est, r_recip_est, r_g) \
, add_u(r_recip_est, r_recip_est, r_d) \
, gte_mv_to_data_r(r_recip_est, C2_LZCS) \
, nop2 \
, gte_mv_from_data_r(r_h, C2_LZCR) \
, nop \
, and_i( r_h, r_h, -2) \
, li_s( r_shift, 31) \
, sub_s( r_shift, r_shift, r_h) \
, shift_aright(r_shift, r_shift, 1) \
, add_si( r_a, r_h, -24) \
, branch_lt_zero(r_a, atom_offset(srav_path_up_to_uy, aligned_done_up_to_uy)) \
, nop \
, jump_rel(atom_offset(aligned_done_up_to_uy, srav_path_up_to_uy)) \
, shift_lleft_var(r_recip_est, r_recip_est, r_a) \
, atom_label(srav_path_up_to_uy) \
, li_s( r_a, 24) \
, sub_s( r_a, r_a, r_h) \
, shift_aright_var(r_recip_est, r_recip_est, r_a) \
, atom_label(aligned_done_up_to_uy) \
, add_si( r_recip_est, r_recip_est, -64) \
, shift_lleft(r_recip_est, r_recip_est, 1) \
, load_upper_i(r_a, u4_hi(& gte_normalize_sqr_tbl)) \
, or_i_self(r_a, u4_lo(& gte_normalize_sqr_tbl)) \
, add_u(r_a, r_a, r_recip_est) \
, load_half(r_recip_est, r_a, 0) \
, nop \
, gte_mv_to_data_r(r_recip_est, C2_IR0) \
, gte_mv_to_data_r(r_e, C2_IR1) \
, gte_mv_to_data_r(r_f, C2_IR2) \
, gte_mv_to_data_r(r_i, C2_IR3) \
, nop2 \
, gte_cmdw_gpf \
, gte_mv_from_data_r(r_e, C2_MAC1) \
, gte_mv_from_data_r(r_f, C2_MAC2) \
, gte_mv_from_data_r(r_i, C2_MAC3) \
, shift_aright_var(r_e, r_e, r_shift) \
, shift_aright_var(r_f, r_f, r_shift) \
, shift_aright_var(r_i, r_i, r_shift) \
, store_word(r_e, r_b, O_(V3_S4,x)) \
, store_word(r_f, r_b, O_(V3_S4,y)) \
, store_word(r_i, r_b, O_(V3_S4,z)) \
, mac_yield()
WORD_COUNT(mac_resolve_look_at__normalize_up_to_uy, 59)
#define mac_resolve_look_at__populate_and_translate(...) \
load_word(r_look_at, R_TapePtr, O_(Binds_ResolveLookAtPopAndTrans,look_at)) \
, add_ui_self( R_TapePtr, S_(Binds_ResolveLookAtPopAndTrans)) /* Compute the 4 scratch pointers in their dedicated GPRs. */ \
, add_si(r_pux, r_scratch, O_(ResolveLookAtScratch,ux)) /* r_pux = &ux */ \
, add_si(r_puy, r_scratch, O_(ResolveLookAtScratch,uy)) /* r_puy = &uy */ \
, add_si(r_puz, r_scratch, O_(ResolveLookAtScratch,uz)) /* r_puz = &uz */ \
, add_si(r_peye, r_scratch, O_(ResolveLookAtScratch,eye)) /* r_peye = &eye */ \
, nop /* ── m[0] = (S2)ux ── */ \
, load_word(r_tmp0, r_pux, O_(V3_S4,x)) \
, load_word(r_tmp1, r_pux, O_(V3_S4,y)) \
, load_word(r_tmp2, r_pux, O_(V3_S4,z)) \
, nop \
, store_half(r_tmp0, r_look_at, O_(MT3_S2S4,m[0][0])) \
, store_half(r_tmp1, r_look_at, O_(MT3_S2S4,m[0][1])) \
, store_half(r_tmp2, r_look_at, O_(MT3_S2S4,m[0][2])) /* ── m[1] = (S2)uy ── */ \
, load_word(r_tmp0, r_puy, O_(V3_S4,x)) \
, load_word(r_tmp1, r_puy, O_(V3_S4,y)) \
, load_word(r_tmp2, r_puy, O_(V3_S4,z)) \
, nop \
, store_half(r_tmp0, r_look_at, O_(MT3_S2S4,m[1][0])) \
, store_half(r_tmp1, r_look_at, O_(MT3_S2S4,m[1][1])) \
, store_half(r_tmp2, r_look_at, O_(MT3_S2S4,m[1][2])) /* ── m[2] = (S2)uz ── */ \
, load_word(r_tmp0, r_puz, O_(V3_S4,x)) \
, load_word(r_tmp1, r_puz, O_(V3_S4,y)) \
, load_word(r_tmp2, r_puz, O_(V3_S4,z)) \
, nop \
, store_half(r_tmp0, r_look_at, O_(MT3_S2S4,m[2][0])) \
, store_half(r_tmp1, r_look_at, O_(MT3_S2S4,m[2][1])) \
, store_half(r_tmp2, r_look_at, O_(MT3_S2S4,m[2][2])) /* ── Translation column t[i] = R * (-eye) ─────────────────────────────
* pos = -eye: load eye.x/y/z from r_peye, negate via sub_u from R_0. */ \
, load_word(r_tmp0, r_peye, O_(P3_S4,x)) \
, load_word(r_tmp1, r_peye, O_(P3_S4,y)) \
, load_word(r_tmp2, r_peye, O_(P3_S4,z)) \
, nop \
, sub_u(r_tmp0, R_0, r_tmp0) /* pos.x = -eye.x */ \
, sub_u(r_tmp1, R_0, r_tmp1) \
, sub_u(r_tmp2, R_0, r_tmp2) /* mtc2 IR1/2/3 = pos (for MVMVA — input vector registers). */ \
, gte_mv_to_data_r(r_tmp0, C2_IR1) \
, gte_mv_to_data_r(r_tmp1, C2_IR2) \
, gte_mv_to_data_r(r_tmp2, C2_IR3) \
, nop2 /* MVMVA: MAC1/2/3 = R * IR with cv=0 (no TR vector), mx=0 (rotation matrix),
* sf=0 (no shift), v=0 (V0 = IR1/2/3, no far-plane clipping). The pre-set
* rotation matrix is the one set by the preceding set_gte_world atom.
* gte_cmdw_mvmva is parameterless and defaults to cv=0/mx=0/sf=0/v=0. */ \
, gte_cmdw_mvmva \
, nop /* GTE interlock */ /* mfc2 MAC1/2/3 → r_tmp0/r_tmp1/r_tmp2 (sign-extended into 32-bit GPRs).
* MAC1/2/3 hold R*v with no TR add and no perspective divide — exactly the
* 3 distinct world-space translation values we need for t[0..2]. */ \
, gte_mv_from_data_r(r_tmp0, C2_MAC1) \
, gte_mv_from_data_r(r_tmp1, C2_MAC2) \
, gte_mv_from_data_r(r_tmp2, C2_MAC3) \
, nop \
, store_word(r_tmp0, r_look_at, O_(MT3_S2S4,t[0])) \
, store_word(r_tmp1, r_look_at, O_(MT3_S2S4,t[1])) \
, store_word(r_tmp2, r_look_at, O_(MT3_S2S4,t[2])) \
, mac_yield()
WORD_COUNT(mac_resolve_look_at__populate_and_translate, 50)
-30
View File
@@ -8,36 +8,6 @@
#pragma region hello_camera
// --- atom: resolve_look_at__normalize_fwd_to_uz (62 words) ---
#define _atom_offset_srav_path_fwd_to_uz_aligned_done_fwd_to_uz 6
#define _atom_offset_aligned_done_fwd_to_uz_srav_path_fwd_to_uz 1
enum {
atom_offset_srav_path_fwd_to_uz_aligned_done_fwd_to_uz = _atom_offset_srav_path_fwd_to_uz_aligned_done_fwd_to_uz,
atom_offset_aligned_done_fwd_to_uz_srav_path_fwd_to_uz = _atom_offset_aligned_done_fwd_to_uz_srav_path_fwd_to_uz,
};
// --- atom: resolve_look_at__normalize_right_to_ux (62 words) ---
#define _atom_offset_srav_path_right_to_ux_aligned_done_right_to_ux 6
#define _atom_offset_aligned_done_right_to_ux_srav_path_right_to_ux 1
enum {
atom_offset_srav_path_right_to_ux_aligned_done_right_to_ux = _atom_offset_srav_path_right_to_ux_aligned_done_right_to_ux,
atom_offset_aligned_done_right_to_ux_srav_path_right_to_ux = _atom_offset_aligned_done_right_to_ux_srav_path_right_to_ux,
};
// --- atom: resolve_look_at__normalize_up_to_uy (62 words) ---
#define _atom_offset_srav_path_up_to_uy_aligned_done_up_to_uy 6
#define _atom_offset_aligned_done_up_to_uy_srav_path_up_to_uy 1
enum {
atom_offset_srav_path_up_to_uy_aligned_done_up_to_uy = _atom_offset_srav_path_up_to_uy_aligned_done_up_to_uy,
atom_offset_aligned_done_up_to_uy_srav_path_up_to_uy = _atom_offset_aligned_done_up_to_uy_srav_path_up_to_uy,
};
// --- atom: pad_input_cube_rotation (60 words) ---
#define _atom_offset_dpad_left_exit_dpad_left 6
+13 -257
View File
@@ -173,24 +173,22 @@ typedef Struct_(ResolveLookAtScratch) {
};
/* ─── resolve_look_at bundle chain atoms ────────────────────────────
* 7 unique atom procs in the resolve_look_at bundle (4 chain atoms + 3 normalize variants).
* All 7 are runtime-built MipsAtom_Proc_ atoms: each function declares a static MipsCode[] body,
* then calls atombuilder_unroll() to append it to the caller's MipsAtomBuilder arena.
* resolve_look_at_init() uses this pattern to pre-build the bundle into the static arena (smem.resolve_look_at_arena).
* 4 unique atom procs in the resolve_look_at bundle (4 chain atoms + 3 calls to generic normalize_v3s4_proc).
* All 4 chain atoms are runtime-built MipsAtom_Proc_ atoms: each function declares a static MipsCode[] body,
* then calls atombuilder_unroll() to append it to the caller's MipsAtomBuilder arena. resolve_look_at_init()
* uses this pattern to pre-build the bundle into the static arena (smem.resolve_look_at_arena).
*
* Atom roster:
* 0: resolve_look_at__input_and_sub (chain atom)
* 1: resolve_look_at__normalize_fwd_to_uz (normalize wrapper)
* 2: resolve_look_at__cross_uz_up_in_to_right (chain atom)
* 3: resolve_look_at__normalize_right_to_ux (normalize wrapper)
* 4: resolve_look_at__cross_uz_ux_to_up (chain atom)
* 5: resolve_look_at__normalize_up_to_uy (normalize wrapper)
* 6: resolve_look_at__populate_and_translate (chain atom)
* 0: resolve_look_at__input_and_sub (chain atom)
* 1: normalize_v3s4_proc (gte.atom.c) (generic normalize; called for fwd→uz)
* 2: resolve_look_at__cross_uz_up_in_to_right (chain atom)
* 3: normalize_v3s4_proc (gte.atom.c) (generic normalize; called for right→ux)
* 4: resolve_look_at__cross_uz_ux_to_up (chain atom)
* 5: normalize_v3s4_proc (gte.atom.c) (generic normalize; called for up→uy)
* 6: resolve_look_at__populate_and_translate (chain atom)
*
* The 3 normalize wrappers are CHAIN-SPECIFIC — they hardcode src/dst scratch offsets in the body
* (computed via r_scratch + O_(ResolveLookAtScratch, fld)).
* The generic normalize_v3s4_proc (in gte.atom.c) takes src/dst as GPR parameters and is NOT used by this bundle.
* (Layering rule: gte.atom.c contains only generic GTE primitives; bundle-specific code are within this file.)
* The generic normalize_v3s4_proc is a parameterized 4-stage GTE normalize (SQR → mfc2 → LZCS → GPF → srav);
* it accepts scratch base + offset args so any caller (with a scratch base + struct schema) can use it.
*/
typedef Struct_(Binds_ResolveLookAtSub) {
@@ -392,248 +390,6 @@ I_ void resolve_look_at__cross_uz_ux_to_up_proc(MipsAtomBuilder_R ab, U4 r_scrat
mac_yield()
})
/* Atoms 1, 3, 5 in the bundle: chain-specific normalize wrappers around the generic normalize_v3s4_proc (gte.atom.c).
* The generic proc takes src/dst as GPR parameters; these wrappers HARDCODE src/dst via r_scratch + O_(ResolveLookAtScratch, fld)
* so the C-side bundle helper doesn't need to push scratchpad addresses via tb_data between atoms.
*
* The 4-stage normalize body (SQR → mfc2 → LZCS → GPF → srav) is identical to the generic version (GPR-renamed); cycle counts match.
* The only difference is the (src, dst) scratch offsets and the per-proc atom_label suffixes
* (srav_path_fwd_to_uz, srav_path_right_to_ux, srav_path_up_to_uy) so the per-proc-instance offsets are emitted disjointly in gen/offsets.h.
*
* GPR pool (10 free regs: R_T0..R_T3, R_T5..R_T7, R_V0, R_V1, R_AT; R_T4 reserved for R_ResolveScratch):
* r_a : src ptr (overlaps with r_recip_est carrier after the 3 src-loads)
* r_b : dst ptr (saved throughout)
* r_e/r_f/r_i : src.x/y/z → result.x/y/z (preserved across stages 1-2 via r_d/r_g/r_recip_est scratch)
* r_d/r_g : MAC1/2 scratch (dead after stage 2)
* r_h : LZCR (saved across stages 3-4)
* r_recip_est : |v|² accumulator + sqrtbl[index] + 1/|v| (saved throughout)
* r_shift : final srav amount (saved across stages 3-4)
*
* The Lua metaprogram (Task 12.10) auto-emits:
* - `mac_resolve_look_at__normalize_<from>_to_<to>` alias in gen/macs.h
* - `atom_offset__srav_path_<from>_to_<to>__aligned_done_<from>_to_<to>` defs in gen/offsets.h
*/
/* Atom 1: normalize fwd (scratch+0) → uz (scratch+16). */
I_ void resolve_look_at__normalize_fwd_to_uz_proc(MipsAtomBuilder_R ab, U4 r_scratch
, U4 r_a, U4 r_b /* src/dst scratch pointers */
, U4 r_e, U4 r_f, U4 r_i /* src.x/y/z → result.x/y/z */
, U4 r_d, U4 r_g /* MAC1/2 scratch (dead after stage 2) */
, U4 r_h /* LZCR */
, U4 r_recip_est
, U4 r_shift
) MipsAtom_Proc_(resolve_look_at__normalize_fwd_to_uz, ab, {
/* Compute src/dst pointers from r_scratch. */
add_si(r_a, r_scratch, O_(ResolveLookAtScratch,fwd)), /* r_a = &fwd */
add_si(r_b, r_scratch, O_(ResolveLookAtScratch,uz)), /* r_b = &uz */
nop,
/* Load src.x/y/z from r_a into r_e/r_f/r_i. */
load_word(r_e, r_a, O_(V3_S4,x)),
load_word(r_f, r_a, O_(V3_S4,y)),
load_word(r_i, r_a, O_(V3_S4,z)),
nop, /* load-delay */
/* Stage 1: mtc2 src → IR1/2/3, SQR fires. */
gte_mv_to_data_r(r_e, C2_IR1),
gte_mv_to_data_r(r_f, C2_IR2),
gte_mv_to_data_r(r_i, C2_IR3),
nop, gte_cmdw_sqr,
/* Stage 2: mfc2 MAC1/2/3, sum, mtc2 LZCS. */
gte_mv_from_data_r(r_d, C2_MAC1),
gte_mv_from_data_r(r_g, C2_MAC2),
gte_mv_from_data_r(r_recip_est, C2_MAC3),
nop,
add_u(r_recip_est, r_recip_est, r_g),
add_u(r_recip_est, r_recip_est, r_d),
gte_mv_to_data_r(r_recip_est, C2_LZCS),
nop2,
gte_mv_from_data_r(r_h, C2_LZCR),
nop,
/* Stage 3: compute shift amount, align |v|² to bit 24. */
and_i( r_h, r_h, -2),
li_s( r_shift, 31),
sub_s( r_shift, r_shift, r_h),
shift_aright(r_shift, r_shift, 1),
add_si( r_a, r_h, -24), /* r_a = LZCR - 24 (overlapping with r_recip_est; src ptr no longer needed) */
branch_lt_zero(r_a, atom_offset(srav_path_fwd_to_uz, aligned_done_fwd_to_uz)), nop,
jump_rel(atom_offset(aligned_done_fwd_to_uz, srav_path_fwd_to_uz)),
shift_lleft_var(r_recip_est, r_recip_est, r_a),
atom_label(srav_path_fwd_to_uz)
li_s( r_a, 24),
sub_s( r_a, r_a, r_h),
shift_aright_var(r_recip_est, r_recip_est, r_a),
atom_label(aligned_done_fwd_to_uz)
/* r_recip_est holds |v|² aligned to bit 24. */
add_si( r_recip_est, r_recip_est, -64),
shift_lleft(r_recip_est, r_recip_est, 1),
load_upper_i(r_a, u4_hi(& gte_normalize_sqr_tbl)),
or_i_self(r_a, u4_lo(& gte_normalize_sqr_tbl)),
add_u(r_a, r_a, r_recip_est),
load_half(r_recip_est, r_a, 0),
nop,
/* Stage 4: GPF + srav finalize. */
gte_mv_to_data_r(r_recip_est, C2_IR0),
gte_mv_to_data_r(r_e, C2_IR1),
gte_mv_to_data_r(r_f, C2_IR2),
gte_mv_to_data_r(r_i, C2_IR3),
nop2,
gte_cmdw_gpf,
gte_mv_from_data_r(r_e, C2_MAC1),
gte_mv_from_data_r(r_f, C2_MAC2),
gte_mv_from_data_r(r_i, C2_MAC3),
shift_aright_var(r_e, r_e, r_shift),
shift_aright_var(r_f, r_f, r_shift),
shift_aright_var(r_i, r_i, r_shift),
/* Store result.x/y/z to r_b (dst ptr = scratch+16). */
store_word(r_e, r_b, O_(V3_S4,x)),
store_word(r_f, r_b, O_(V3_S4,y)),
store_word(r_i, r_b, O_(V3_S4,z)),
mac_yield()
})
/* Atom 3: normalize right (scratch+32) → ux (scratch+48). */
I_ void resolve_look_at__normalize_right_to_ux_proc(MipsAtomBuilder_R ab, U4 r_scratch
, U4 r_a, U4 r_b
, U4 r_e, U4 r_f, U4 r_i
, U4 r_d, U4 r_g
, U4 r_h
, U4 r_recip_est
, U4 r_shift
) MipsAtom_Proc_(resolve_look_at__normalize_right_to_ux, ab, {
add_si(r_a, r_scratch, O_(ResolveLookAtScratch,right)), /* r_a = &right */
add_si(r_b, r_scratch, O_(ResolveLookAtScratch,ux)), /* r_b = &ux */
nop,
load_word(r_e, r_a, O_(V3_S4,x)),
load_word(r_f, r_a, O_(V3_S4,y)),
load_word(r_i, r_a, O_(V3_S4,z)),
nop,
gte_mv_to_data_r(r_e, C2_IR1),
gte_mv_to_data_r(r_f, C2_IR2),
gte_mv_to_data_r(r_i, C2_IR3),
nop, gte_cmdw_sqr,
gte_mv_from_data_r(r_d, C2_MAC1),
gte_mv_from_data_r(r_g, C2_MAC2),
gte_mv_from_data_r(r_recip_est, C2_MAC3),
nop,
add_u(r_recip_est, r_recip_est, r_g),
add_u(r_recip_est, r_recip_est, r_d),
gte_mv_to_data_r(r_recip_est, C2_LZCS),
nop2,
gte_mv_from_data_r(r_h, C2_LZCR),
nop,
and_i( r_h, r_h, -2),
li_s( r_shift, 31),
sub_s( r_shift, r_shift, r_h),
shift_aright(r_shift, r_shift, 1),
add_si( r_a, r_h, -24),
branch_lt_zero(r_a, atom_offset(srav_path_right_to_ux, aligned_done_right_to_ux)), nop,
jump_rel(atom_offset(aligned_done_right_to_ux, srav_path_right_to_ux)),
shift_lleft_var(r_recip_est, r_recip_est, r_a),
atom_label(srav_path_right_to_ux)
li_s( r_a, 24),
sub_s( r_a, r_a, r_h),
shift_aright_var(r_recip_est, r_recip_est, r_a),
atom_label(aligned_done_right_to_ux)
add_si( r_recip_est, r_recip_est, -64),
shift_lleft(r_recip_est, r_recip_est, 1),
load_upper_i(r_a, u4_hi(& gte_normalize_sqr_tbl)),
or_i_self(r_a, u4_lo(& gte_normalize_sqr_tbl)),
add_u(r_a, r_a, r_recip_est),
load_half(r_recip_est, r_a, 0),
nop,
gte_mv_to_data_r(r_recip_est, C2_IR0),
gte_mv_to_data_r(r_e, C2_IR1),
gte_mv_to_data_r(r_f, C2_IR2),
gte_mv_to_data_r(r_i, C2_IR3),
nop2,
gte_cmdw_gpf,
gte_mv_from_data_r(r_e, C2_MAC1),
gte_mv_from_data_r(r_f, C2_MAC2),
gte_mv_from_data_r(r_i, C2_MAC3),
shift_aright_var(r_e, r_e, r_shift),
shift_aright_var(r_f, r_f, r_shift),
shift_aright_var(r_i, r_i, r_shift),
store_word(r_e, r_b, O_(V3_S4,x)),
store_word(r_f, r_b, O_(V3_S4,y)),
store_word(r_i, r_b, O_(V3_S4,z)),
mac_yield()
})
/* Atom 5: normalize up (scratch+64) → uy (scratch+80). */
I_ void resolve_look_at__normalize_up_to_uy_proc(MipsAtomBuilder_R ab
, U4 r_scratch
, U4 r_a, U4 r_b
, U4 r_e, U4 r_f, U4 r_i
, U4 r_d, U4 r_g
, U4 r_h
, U4 r_recip_est
, U4 r_shift
) MipsAtom_Proc_(resolve_look_at__normalize_up_to_uy, ab, {
add_si(r_a, r_scratch, O_(ResolveLookAtScratch,up)), /* r_a = &up */
add_si(r_b, r_scratch, O_(ResolveLookAtScratch,uy)), /* r_b = &uy */
nop,
load_word(r_e, r_a, O_(V3_S4,x)),
load_word(r_f, r_a, O_(V3_S4,y)),
load_word(r_i, r_a, O_(V3_S4,z)),
nop,
gte_mv_to_data_r(r_e, C2_IR1),
gte_mv_to_data_r(r_f, C2_IR2),
gte_mv_to_data_r(r_i, C2_IR3),
nop, gte_cmdw_sqr,
gte_mv_from_data_r(r_d, C2_MAC1),
gte_mv_from_data_r(r_g, C2_MAC2),
gte_mv_from_data_r(r_recip_est, C2_MAC3),
nop,
add_u(r_recip_est, r_recip_est, r_g),
add_u(r_recip_est, r_recip_est, r_d),
gte_mv_to_data_r(r_recip_est, C2_LZCS),
nop2,
gte_mv_from_data_r(r_h, C2_LZCR),
nop,
and_i( r_h, r_h, -2),
li_s( r_shift, 31),
sub_s( r_shift, r_shift, r_h),
shift_aright(r_shift, r_shift, 1),
add_si( r_a, r_h, -24),
branch_lt_zero(r_a, atom_offset(srav_path_up_to_uy, aligned_done_up_to_uy)), nop,
jump_rel(atom_offset(aligned_done_up_to_uy, srav_path_up_to_uy)),
shift_lleft_var(r_recip_est, r_recip_est, r_a),
atom_label(srav_path_up_to_uy)
li_s( r_a, 24),
sub_s( r_a, r_a, r_h),
shift_aright_var(r_recip_est, r_recip_est, r_a),
atom_label(aligned_done_up_to_uy)
add_si( r_recip_est, r_recip_est, -64),
shift_lleft(r_recip_est, r_recip_est, 1),
load_upper_i(r_a, u4_hi(& gte_normalize_sqr_tbl)),
or_i_self(r_a, u4_lo(& gte_normalize_sqr_tbl)),
add_u(r_a, r_a, r_recip_est),
load_half(r_recip_est, r_a, 0),
nop,
gte_mv_to_data_r(r_recip_est, C2_IR0),
gte_mv_to_data_r(r_e, C2_IR1),
gte_mv_to_data_r(r_f, C2_IR2),
gte_mv_to_data_r(r_i, C2_IR3),
nop2,
gte_cmdw_gpf,
gte_mv_from_data_r(r_e, C2_MAC1),
gte_mv_from_data_r(r_f, C2_MAC2),
gte_mv_from_data_r(r_i, C2_MAC3),
shift_aright_var(r_e, r_e, r_shift),
shift_aright_var(r_f, r_f, r_shift),
shift_aright_var(r_i, r_i, r_shift),
store_word(r_e, r_b, O_(V3_S4,x)),
store_word(r_f, r_b, O_(V3_S4,y)),
store_word(r_i, r_b, O_(V3_S4,z)),
mac_yield()
})
typedef Struct_(Binds_ResolveLookAtPopAndTrans) {
U4 look_at; /* U4 (MT3_S2S4* — destination matrix address) */
};
+65 -51
View File
@@ -133,20 +133,27 @@ resolve_look_at_c11(MT3_S2S4* look_at, P3_S4* eye, P3_S4* target, V3_S4* up_in)
}
/* Pre-build all 7 chain atoms of the resolve_look_at bundle into the static arena.
* Called ONCE from main() before the frame loop.
* After this returns, the smem.resolve_look_at_atom_addrs[] array contains valid MIPS atom pointers
* Called ONCE from main() before the frame loop.
* After this returns, the smem.resolve_look_at_atom_addrs[] array contains valid MIPS atom pointers
* for the frame-time bundle helper to emit via tb_emit(tb, captured_addr).
*
* 7 atoms are within hello_camera.atom.c:
* 4 unique procs in hello_camera.atom.c (chain atoms 0, 2, 4, 6); atoms 1, 3, 5
* share the GENERIC normalize_v3s4_proc from gte.atom.c (called 3x with different
* O_(ResolveLookAtScratch,...) offsets):
* 0: resolve_look_at__input_and_sub_proc
* 1: resolve_look_at__normalize_fwd_to_uz_proc
* 1: normalize_v3s4_proc (fwd → uz; offsets 0, 16)
* 2: resolve_look_at__cross_uz_up_in_to_right_proc
* 3: resolve_look_at__normalize_right_to_ux_proc
* 3: normalize_v3s4_proc (right → ux; offsets 32, 48)
* 4: resolve_look_at__cross_uz_ux_to_up_proc
* 5: resolve_look_at__normalize_up_to_uy_proc
* 5: normalize_v3s4_proc (up → uy; offsets 64, 80)
* 6: resolve_look_at__populate_and_translate_proc
*
* (gte.atom.c contains only normalize_v3s4_proc — bundle-specific scratch layout is no longer exposed to the GTE primitives file.)
* Task 12.16 promotion: the bundle-specific resolve_look_at__chain_normalize_proc
* has been promoted to the generic normalize_v3s4_proc (gte.atom.c), which now
* takes r_scratch + r_src_offset + r_dst_offset as U4 parameters. The 3 callers
* pass O_(ResolveLookAtScratch,...) macros as offset args. The metaprogram emits
* one set of `atom_offset__normalize_v3s4__srav_path__aligned_done` defs
* (namespaced by atom name) in duffle/gen/offsets.h, shared by all 3 callers.
*
* GPR pool per atom: 10 free GPRs (R_T0..R_T3 + R_T5..R_T7 + R_V0 + R_V1 + R_AT).
* R_T4 is reserved as the wave-context carrier (R_ResolveScratch).
@@ -168,65 +175,76 @@ internal void resolve_look_at_init(void) {
R_T2, /* r_up_in_ptr (popped from tape) */
R_T3, R_T5, R_T6, R_T7); /* r_tmp<0-3> */
/* Atom 1: resolve_look_at__normalize_fwd_to_uz — src=scratch+0, dst=scratch+16 (HARDCODED in body).
* GPR pool: r_scratch (R_T4 carrier) + 10 body GPRs = 11.
* r_a/r_b (R_T0/R_T1) : src/dst pointers (r_a overlaps r_recip_est after the loads)
* r_e/r_f/r_i (R_T2/R_T3/R_T5) : src.x/y/z → result.x/y/z
* r_d/r_g (R_T6/R_T7) : MAC1/2 scratch (dead after stage 2)
* r_h (R_V0) : LZCR
* r_recip_est (R_V1), r_shift (R_AT) : saved throughout */
/* Atom 1: normalize_v3s4_proc (generic, from gte.atom.c) — src=scratch+0=fwd, dst=scratch+16=uz.
* The proc takes r_src_offset + r_dst_offset as U4 PARAMETERS — we pass the O_(...) macros here (evaluating to numeric literals 0 and 16).
* The 4-stage body is identical across the 3 call sites (atoms 1, 3, 5); only the offset args differ.
* GPR pool: r_scratch (R_T4 carrier) + 9 body GPRs = 10.
* r_src_ptr (R_T0) : src ptr
* r_dst_ptr (R_T1) : dst ptr
* r_tmp (R_T2) : unused (reserved for symmetry)
* r_mac1_scratch (R_T3) : MAC1 scratch
* r_mac2_scratch (R_T5) : src.x → result.x (carries through stages 1-2)
* r_recip_est (R_T6) : src.y → result.y
* r_lzcr (R_T7) : |v|² accumulator + srav amount (single reg)
* r_shift (R_V0) : LZCR (saved across stages 3-4)
* r_branch_tmp (R_V1) : src.z → result.z (reused after stage 1)
*/
smem.resolve_look_at_atom_addrs[1] = (MipsAtom*)u4_v(ab->start + ab->used * sizeof(U4));
resolve_look_at__normalize_fwd_to_uz_proc(ab,
R_ResolveScratch, /* r_scratch (wave-context carrier; src/dst base) */
R_T0, R_T1, /* r_a, r_b (src/dst ptrs) */
R_T2, R_T3, R_T5, /* r_e, r_f, r_i (src components) */
R_T6, R_T7, /* r_d, r_g (MAC scratch) */
R_V0, /* r_h (LZCR) */
R_V1, /* r_recip_est */
R_AT); /* r_shift */
normalize_v3s4_proc(ab, R_ResolveScratch, /* r_scratch (wave-context carrier) */
O_(ResolveLookAtScratch, fwd), /* r_src_offset = 0 */
O_(ResolveLookAtScratch, uz), /* r_dst_offset = 16 */
R_T0, R_T1, R_T2, /* r_src_ptr, r_dst_ptr, r_tmp */
R_T3, /* r_mac1_scratch */
R_T5, /* r_mac2_scratch */
R_T6, /* r_recip_est */
R_T7, /* r_lzcr */
R_V0, /* r_shift */
R_V1); /* r_branch_tmp */
/* Atom 2: resolve_look_at__cross_uz_up_in_to_right — a=scratch+16, b=scratch+128,
* out=scratch+32 (HARDCODED in body). GPR pool: r_scratch + 7 body + R_AT + R_V0 = 10. */
smem.resolve_look_at_atom_addrs[2] = (MipsAtom*)u4_v(ab->start + ab->used * sizeof(U4));
resolve_look_at__cross_uz_up_in_to_right_proc(ab,
R_ResolveScratch, /* r_scratch (wave-context carrier; src/dst base) */
R_T0, R_T1, R_T2, /* r_a, r_b, r_c (a.x/y/z → out.x/y/z) */
R_T3, /* r_d (b.x) */
R_T5, /* r_f (out ptr = scratch+32) */
R_T6, /* r_g (a ptr = scratch+16) */
R_T7); /* r_h (b ptr = scratch+128) */
resolve_look_at__cross_uz_up_in_to_right_proc(ab, R_ResolveScratch, /* r_scratch (wave-context carrier; src/dst base) */
R_T0, R_T1, R_T2, /* r_a, r_b, r_c (a.x/y/z → out.x/y/z) */
R_T3, /* r_d (b.x) */
R_T5, /* r_f (out ptr = scratch+32) */
R_T6, /* r_g (a ptr = scratch+16) */
R_T7); /* r_h (b ptr = scratch+128) */
/* Atom 3: resolve_look_at__normalize_right_to_ux — src=scratch+32, dst=scratch+48 (HARDCODED). */
/* Atom 3: normalize_v3s4_proc (generic, from gte.atom.c) — src=scratch+32=right, dst=scratch+48=ux. */
smem.resolve_look_at_atom_addrs[3] = (MipsAtom*)u4_v(ab->start + ab->used * sizeof(U4));
resolve_look_at__normalize_right_to_ux_proc(ab,
R_ResolveScratch,
R_T0, R_T1,
R_T2, R_T3, R_T5,
R_T6, R_T7,
normalize_v3s4_proc(ab, R_ResolveScratch,
O_(ResolveLookAtScratch, right), /* r_src_offset = 32 */
O_(ResolveLookAtScratch, ux), /* r_dst_offset = 48 */
R_T0, R_T1, R_T2,
R_T3,
R_T5,
R_T6,
R_T7,
R_V0,
R_V1,
R_AT);
R_V1);
/* Atom 4: resolve_look_at__cross_uz_ux_to_up — a=scratch+16, b=scratch+48, out=scratch+64 (HARDCODED). */
smem.resolve_look_at_atom_addrs[4] = (MipsAtom*)u4_v(ab->start + ab->used * sizeof(U4));
resolve_look_at__cross_uz_ux_to_up_proc(ab,
R_ResolveScratch,
resolve_look_at__cross_uz_ux_to_up_proc(ab, R_ResolveScratch,
R_T0, R_T1, R_T2,
R_T3,
R_T5, /* r_f (out ptr = scratch+64) */
R_T6, /* r_g (a ptr = scratch+16) */
R_T7); /* r_h (b ptr = scratch+48) */
/* Atom 5: resolve_look_at__normalize_up_to_uy — src=scratch+64, dst=scratch+80 (HARDCODED). */
/* Atom 5: normalize_v3s4_proc (generic, from gte.atom.c) — src=scratch+64=up, dst=scratch+80=uy. */
smem.resolve_look_at_atom_addrs[5] = (MipsAtom*)u4_v(ab->start + ab->used * sizeof(U4));
resolve_look_at__normalize_up_to_uy_proc(ab,
R_ResolveScratch,
R_T0, R_T1,
R_T2, R_T3, R_T5,
R_T6, R_T7,
normalize_v3s4_proc(ab, R_ResolveScratch,
O_(ResolveLookAtScratch, up), /* r_src_offset = 64 */
O_(ResolveLookAtScratch, uy), /* r_dst_offset = 80 */
R_T0, R_T1, R_T2,
R_T3,
R_T5,
R_T6,
R_T7,
R_V0,
R_V1,
R_AT);
R_V1);
/* Atom 6: resolve_look_at__populate_and_translate — write look_at->m[][] from ux/uy/uz (computed from r_scratch+offset internally),
then compute translation column t[] = R * (-eye). GPR pool: r_look_at + r_scratch + 4 ptr regs + 3 tmp regs = 9. */
@@ -340,10 +358,6 @@ void update(PrimitiveArena* pa, U4* ordering_buf)
}
// Camera look at (Tape)
{
MT3_S2S4* look_at = & smem.cam.look_at;
P3_S4* eye = & smem.cam.pos;
V3_S4* up_in = & v3s4(0, -fp_one, 0);
tb.used = 0; tb_scope_run(& tb) {
resolve_look_at(& tb, & smem.cam.look_at, & smem.cam.pos, & smem.cube.pos, & v3s4(0, -fp_one, 0));
}