use tb_bind_ macro fro draw cube and tri, better type convention on binds.

This commit is contained in:
ed
2026-09-03 17:36:36 -04:00
parent 6b3fbab387
commit 1faf3539d8
3 changed files with 54 additions and 79 deletions
+6 -21
View File
@@ -356,24 +356,16 @@ internal Reg const regfile_alloc_order[] = {
R_T8, R_T9, R_T8, R_T9,
}; };
typedef Struct_(RegFile) { typedef Struct_(RegFile) { A2_U2 GPR; };
A2_U2 GPR;
A2_U2 GTE;
};
#define regfile(pin_mask) {.GPR={u4_lo(pin_mask), u4_hi(pin_mask)} } #define regfile(pin_mask) {.GPR={u4_lo(pin_mask), u4_hi(pin_mask)} }
FI_ void regfile_init(RegFile_R rf) { FI_ void regfile_init(RegFile_R rf) {
/* pack the 32-bit ABI mask into the two U2s */ /* pack the 32-bit ABI mask into the two U2s */
rf->GPR[0] = u4_lo(regfile_abi_mask); rf->GPR[0] = u4_lo(regfile_abi_mask);
rf->GPR[1] = u4_hi(regfile_abi_mask); rf->GPR[1] = u4_hi(regfile_abi_mask);
rf->GTE[0] = rf->GTE[1] = 0;
} }
FI_ RegFile regfile_make(void) { RegFile rf; regfile_init(& rf); return rf; } FI_ RegFile regfile_make(void) { RegFile rf; regfile_init(& rf); return rf; }
typedef Struct_(RegFile_RInfo) { typedef Struct_(RegFile_RInfo) { U2_R section; U2 mask; B2 occupied; };
U2_R section;
U2 mask;
B2 occupied;
};
FI_ RegFile_RInfo regfile_rinfo(A2_U2 file, Reg r_id) { FI_ RegFile_RInfo regfile_rinfo(A2_U2 file, Reg r_id) {
U2 s_id = r_id >> 4; U2 s_id = r_id >> 4;
U2_R section = & file[s_id]; U2_R section = & file[s_id];
@@ -383,15 +375,11 @@ FI_ RegFile_RInfo regfile_rinfo(A2_U2 file, Reg r_id) {
} }
FI_ Reg regfile__alloc_helper(A2_U2 file, Reg r_id) { FI_ Reg regfile__alloc_helper(A2_U2 file, Reg r_id) {
Reg result = 0; RegFile_RInfo info = regfile_rinfo(file, r_id); Reg result = 0; RegFile_RInfo info = regfile_rinfo(file, r_id);
if (info.occupied == false) { if (info.occupied == false) { info.section[0] |= info.mask; result = r_id; }
info.section[0] |= info.mask;
result = r_id;
}
return result; return result;
} }
I_ Reg regfile_alloc(RegFile_R rf) { I_ Reg regfile_alloc(RegFile_R rf) {
Reg allocated = 0; Reg allocated = 0; for index_iter(U4, r_id, R_V0, <, R_T9) {
for index_iter(U4, r_id, R_V0, <, R_T9) {
allocated = regfile__alloc_helper(rf->GPR, r_id); allocated = regfile__alloc_helper(rf->GPR, r_id);
Jmp_nZero_(allocated,resolved); Jmp_nZero_(allocated,resolved);
} }
@@ -405,8 +393,7 @@ FI_ Reg regfile_pin(RegFile_R rf, Reg r_id) {
return r_id; return r_id;
} }
FI_ void regfile_pin_mask(RegFile_R rf, U4 mask) { FI_ void regfile_pin_mask(RegFile_R rf, U4 mask) {
B4 occupied = u4_r(rf->GPR)[0] & mask; B4 occupied = u4_r(rf->GPR)[0] & mask; assert(occupied == false);
assert(occupied == false);
u4_r(rf->GPR)[0] |= mask; u4_r(rf->GPR)[0] |= mask;
} }
FI_ void regfile_free_mask(RegFile_R rf, U4 mask) { FI_ void regfile_free_mask(RegFile_R rf, U4 mask) {
@@ -414,8 +401,7 @@ FI_ void regfile_free_mask(RegFile_R rf, U4 mask) {
u4_r(rf->GPR)[0] &= ~mask; u4_r(rf->GPR)[0] &= ~mask;
} }
FI_ void regfile_free_reg(RegFile_R rf, Reg r_id) { FI_ void regfile_free_reg(RegFile_R rf, Reg r_id) {
/* never free the ABI set */ if (regfile_abi_mask & (1u << r_id)) return; // never free the ABI set
if (regfile_abi_mask & (1u << r_id)) return;
RegFile_RInfo info = regfile_rinfo(rf->GPR, r_id); RegFile_RInfo info = regfile_rinfo(rf->GPR, r_id);
info.section[0] &= ~info.mask; info.section[0] &= ~info.mask;
} }
@@ -449,7 +435,6 @@ FI_ void regfile_reset_to_mask(RegFile_R rf, U4 mask) {
add_si(r.t1.view_3, r.usual_modifiable, 10), add_si(r.t1.view_3, r.usual_modifiable, 10),
mac_yield(), mac_yield(),
}) })
#pragma endregion Mips Atom Procs #pragma endregion Mips Atom Procs
#pragma region Baked Mips Atoms #pragma region Baked Mips Atoms
+19 -19
View File
@@ -499,17 +499,17 @@ enum {
#define R_OtBase_Code R_T6_Code #define R_OtBase_Code R_T6_Code
}; };
typedef Struct_(Binds_CubeTri) { typedef Struct_(Binds_CubeTri) {
U4 PrimCursor; U1* prim_cursor;
V4_S2* FaceCursor; V4_S2* face_cursor;
V3_S2* VertBase; V3_S2* vert_base;
U4* OtBase; U4* ot_base;
}; };
internal MipsAtom_(rbind_cube_g4_face) atom_info(atom_bind(Binds_CubeTri), atom_phase(cube_g4)){ internal MipsAtom_(rbind_cube_g4_face) atom_info(atom_bind(Binds_CubeTri), atom_phase(cube_g4)){
/* Pop 4 arguments from the tape directly into the workspace registers */ /* Pop 4 arguments from the tape directly into the workspace registers */
load_word(R_PrimCursor, R_TapePtr, O_(Binds_CubeTri,PrimCursor)), load_word(R_PrimCursor, R_TapePtr, O_(Binds_CubeTri,prim_cursor)),
load_word(R_FaceCursor, R_TapePtr, O_(Binds_CubeTri,FaceCursor)), load_word(R_FaceCursor, R_TapePtr, O_(Binds_CubeTri,face_cursor)),
load_word(R_VertBase, R_TapePtr, O_(Binds_CubeTri,VertBase)), load_word(R_VertBase, R_TapePtr, O_(Binds_CubeTri,vert_base)),
load_word(R_OtBase, R_TapePtr, O_(Binds_CubeTri,OtBase)), load_word(R_OtBase, R_TapePtr, O_(Binds_CubeTri,ot_base)),
LdSlot_ add_ui_self( R_TapePtr, S_(Binds_CubeTri)), LdSlot_ add_ui_self( R_TapePtr, S_(Binds_CubeTri)),
mac_yield() mac_yield()
}; };
@@ -561,16 +561,16 @@ MipsAtom_(cube_g4_face) atom_info(atom_phase(cube_g4),
// end: branch(cull) // end: branch(cull)
atom_label(cube_g4_face_exit) atom_label(cube_g4_face_exit)
add_ui_self(R_PrimCursor, S_(Poly_G4)), /* 9 words = Poly_G4 */ add_ui_self(R_PrimCursor, S_(Poly_G4)), // 9 words = Poly_G4
add_ui_self(R_FaceCursor, S_(S2) * 4), /* 4 × S2 = 8 bytes */ add_ui_self(R_FaceCursor, S_(S2) * 4), // 4 × S2 = 8 bytes
jump_reg(R_AtomJmp), BdSlot_ nop // ac_yield: word 3-4 jump_reg(R_AtomJmp), BdSlot_ nop // ac_yield: word 3-4
}; };
typedef Struct_(Binds_FloorTri) { typedef Struct_(Binds_FloorTri) {
U4 PrimCursor; U1* prim_cursor;
V3_S2* FaceCursor; V3_S2* face_cursor;
V3_S2* VertBase; V3_S2* vert_base;
U4* OtBase; U4* ot_base;
}; };
internal internal
MipsAtom_(rbind_floor_f3_face) atom_info(atom_bind(Binds_FloorTri), atom_phase(floor_f3) MipsAtom_(rbind_floor_f3_face) atom_info(atom_bind(Binds_FloorTri), atom_phase(floor_f3)
@@ -578,10 +578,10 @@ MipsAtom_(rbind_floor_f3_face) atom_info(atom_bind(Binds_FloorTri), atom_phase(f
, atom_writes(R_PrimCursor, R_FaceCursor, R_VertBase, R_OtBase, R_TapePtr) , atom_writes(R_PrimCursor, R_FaceCursor, R_VertBase, R_OtBase, R_TapePtr)
){ ){
/* Pop 4 arguments from the tape directly into the workspace registers */ /* Pop 4 arguments from the tape directly into the workspace registers */
load_word(R_PrimCursor, R_TapePtr, O_(Binds_FloorTri,PrimCursor)), load_word(R_PrimCursor, R_TapePtr, O_(Binds_FloorTri,prim_cursor)),
load_word(R_FaceCursor, R_TapePtr, O_(Binds_FloorTri,FaceCursor)), load_word(R_FaceCursor, R_TapePtr, O_(Binds_FloorTri,face_cursor)),
load_word(R_VertBase, R_TapePtr, O_(Binds_FloorTri,VertBase)), load_word(R_VertBase, R_TapePtr, O_(Binds_FloorTri,vert_base)),
load_word(R_OtBase, R_TapePtr, O_(Binds_FloorTri,OtBase)), load_word(R_OtBase, R_TapePtr, O_(Binds_FloorTri,ot_base)),
LdSlot_ add_ui_self( R_TapePtr, S_(Binds_FloorTri)), LdSlot_ add_ui_self( R_TapePtr, S_(Binds_FloorTri)),
mac_yield() mac_yield()
}; };
@@ -623,7 +623,7 @@ atom_label(floor_f3_face_exit)
jump_reg(R_AtomJmp), BdSlot_ nop // ac_yield: word 3-4 jump_reg(R_AtomJmp), BdSlot_ nop // ac_yield: word 3-4
}; };
typedef Struct_(Binds_SyncPrimitiveArena) { U4 used; U4 cursor; }; typedef Struct_(Binds_SyncPrimitiveArena) { U4* used; U1* cursor; };
internal MipsAtom_(sync_primitive_arena) atom_info(atom_bind(Binds_SyncPrimitiveArena) internal MipsAtom_(sync_primitive_arena) atom_info(atom_bind(Binds_SyncPrimitiveArena)
, atom_reads(R_PrimCursor), atom_writes(R_AT) , atom_reads(R_PrimCursor), atom_writes(R_AT)
){ ){
+27 -37
View File
@@ -241,7 +241,6 @@ FI_ void camera_look_at(TapeBuilder_R tb, Camera* c, P3_S4* target, V3_S4* up_in
void update(PrimitiveArena* pa, U4* ordering_buf) void update(PrimitiveArena* pa, U4* ordering_buf)
{ {
TapeBuilder tb = tb_make(slice_ut_arr(smem.MemTape)); TapeBuilder tb = tb_make(slice_ut_arr(smem.MemTape));
/*Pad Input*/ { /*Pad Input*/ {
tb.used = 0; tb_scope_run(& tb) { tb.used = 0; tb_scope_run(& tb) {
// Grab latest state from bios. // Grab latest state from bios.
@@ -288,33 +287,28 @@ void update(PrimitiveArena* pa, U4* ordering_buf)
mt3s2s4_rotation (& smem.cube.rot, & smem.tform_world); mt3s2s4_rotation (& smem.cube.rot, & smem.tform_world);
mt3s2s4_translation(& smem.tform_world, & smem.cube.pos); mt3s2s4_translation(& smem.tform_world, & smem.cube.pos);
mt3s2s4_scale (& smem.tform_world, & smem.cube.scale); mt3s2s4_scale (& smem.tform_world, & smem.cube.scale);
// Combine world and look_at matrix. // Combine world and look_at matrix.
gte_comp_coord_m3s2(& smem.cam.look_at, & smem.tform_world, & smem.tform_view); gte_comp_coord_m3s2(& smem.cam.look_at, & smem.tform_world, & smem.tform_view);
gte_matrix_set_rotation (& smem.tform_view); gte_matrix_set_rotation (& smem.tform_view);
gte_matrix_set_translation(& smem.tform_view); gte_matrix_set_translation(& smem.tform_view);
U4 prim_base = u4_(pa->buf[smem.active_buf_id]); U1* prim_base = u1_r(pa->buf[smem.active_buf_id]);
U4 prim_cursor = prim_base + pa->used; U1* prim_cursor = prim_base + pa->used;
tb.used = 0; tb_scope_run(& tb) {
tb.used = 0; tb_scope(& tb) { tb_emit(& tb, rbind_cube_g4_face); tb_bind_(& tb, Binds_CubeTri,
tb_emit(& tb, rbind_cube_g4_face); .prim_cursor = prim_cursor,
tb_data(& tb, prim_cursor); .face_cursor = smem.cube.faces,
tb_data(& tb, u4_(smem.cube.faces)); .vert_base = smem.cube.verts,
tb_data(& tb, u4_(smem.cube.verts)); .ot_base = ordering_buf,
tb_data(& tb, u4_(ordering_buf)); );
for (U4 i = 0; i < Cube_num_faces; i++) { for (U4 i = 0; i < Cube_num_faces; i++) {
// Two triangles per quad face: (x,y,z) and (x,z,w) tb_emit(& tb, cube_g4_face); // Two triangles per quad face: (x,y,z) and (x,z,w)
tb_emit(& tb, cube_g4_face);
} }
tb_emit(& tb, sync_primitive_arena); tb_bind_(& tb, Binds_SyncPrimitiveArena,
tb_emit(& tb, sync_primitive_arena); .used = & pa->used,
tb_data(& tb, u4_(& pa->used)); .cursor = prim_base,
tb_data(& tb, prim_base); );
} }
tape_run(tb_slice(tb));// Fire off the tape (bigger-clobber variant).
// smem.cube.rot.y += 30; // smem.cube.rot.y += 30;
} }
// Draw floor // Draw floor
@@ -330,33 +324,29 @@ void update(PrimitiveArena* pa, U4* ordering_buf)
gte_matrix_set_rotation (& smem.tform_view); gte_matrix_set_rotation (& smem.tform_view);
gte_matrix_set_translation(& smem.tform_view); gte_matrix_set_translation(& smem.tform_view);
U4 prim_base = u4_(pa->buf[smem.active_buf_id]); U1_R prim_base = u1_r(pa->buf[smem.active_buf_id]);
U4 prim_cursor = prim_base + pa->used; U1_R prim_cursor = prim_base + pa->used;
// TODO(Ed): We should do a bounds check beforehand to confirm pa can hold all tris? // TODO(Ed): We should do a bounds check beforehand to confirm pa can hold all tris?
// The tape atoms in-flight should not need to care. // The tape atoms in-flight should not need to care.
// Prepare the tape. (Push protocol to tape) // Prepare the tape. (Push protocol to tape)
tb.used = 0; tb_scope(& tb) { tb.used = 0; tb_scope_run(& tb) {
// tb_emit(& tb, set_gte_mt3s2s4); tb_emit(& tb, rbind_floor_f3_face); tb_bind_(& tb, Binds_FloorTri,
// tb_data(& tb, u4_(& smem.tform_view)); .prim_cursor = prim_cursor,
.face_cursor = smem.floor.faces,
tb_emit(& tb, rbind_floor_f3_face); .vert_base = smem.floor.verts,
// TODO(Ed): Just use a single context struct ref? .ot_base = ordering_buf,
tb_data(& tb, prim_cursor); );
tb_data(& tb, u4_(smem.floor.faces));
tb_data(& tb, u4_(smem.floor.verts));
tb_data(& tb, u4_(ordering_buf));
for (U4 i = 0; i < Floor_num_faces; i++) { for (U4 i = 0; i < Floor_num_faces; i++) {
tb_emit(& tb, floor_f3_face); tb_emit(& tb, floor_f3_face);
} }
// After floor_f3_face iterations complete, the primitive arena's used counter needs updating. // After floor_f3_face iterations complete, the primitive arena's used counter needs updating.
tb_emit(& tb, sync_primitive_arena); tb_emit(& tb, sync_primitive_arena); tb_bind_(& tb, Binds_SyncPrimitiveArena,
tb_data(& tb, u4_(& pa->used)); .used = & pa->used,
tb_data(& tb, prim_base); .cursor = prim_base,
);
} }
tape_run(tb_slice(tb));// Fire off the tape (bigger-clobber variant).
// C-side state (pa->used) has already been updated by the tape! // C-side state (pa->used) has already been updated by the tape!
// smem.floor.rot.y += 5; // smem.floor.rot.y += 5;
} }