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
+8 -23
View File
@@ -356,24 +356,16 @@ internal Reg const regfile_alloc_order[] = {
R_T8, R_T9,
};
typedef Struct_(RegFile) {
A2_U2 GPR;
A2_U2 GTE;
};
typedef Struct_(RegFile) { A2_U2 GPR; };
#define regfile(pin_mask) {.GPR={u4_lo(pin_mask), u4_hi(pin_mask)} }
FI_ void regfile_init(RegFile_R rf) {
/* pack the 32-bit ABI mask into the two U2s */
rf->GPR[0] = u4_lo(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; }
typedef Struct_(RegFile_RInfo) {
U2_R section;
U2 mask;
B2 occupied;
};
typedef Struct_(RegFile_RInfo) { U2_R section; U2 mask; B2 occupied; };
FI_ RegFile_RInfo regfile_rinfo(A2_U2 file, Reg r_id) {
U2 s_id = r_id >> 4;
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) {
Reg result = 0; RegFile_RInfo info = regfile_rinfo(file, r_id);
if (info.occupied == false) {
info.section[0] |= info.mask;
result = r_id;
}
if (info.occupied == false) { info.section[0] |= info.mask; result = r_id; }
return result;
}
I_ Reg regfile_alloc(RegFile_R rf) {
Reg allocated = 0;
for index_iter(U4, r_id, R_V0, <, R_T9) {
I_ Reg regfile_alloc(RegFile_R rf) {
Reg allocated = 0; for index_iter(U4, r_id, R_V0, <, R_T9) {
allocated = regfile__alloc_helper(rf->GPR, r_id);
Jmp_nZero_(allocated,resolved);
}
@@ -400,13 +388,12 @@ resolved: return allocated;
}
FI_ Reg regfile_pin(RegFile_R rf, Reg r_id) {
RegFile_RInfo info = regfile_rinfo(rf->GPR, r_id);
assert(info.occupied == false);
assert(info.occupied == false);
info.section[0] |= info.mask;
return r_id;
}
FI_ void regfile_pin_mask(RegFile_R rf, U4 mask) {
B4 occupied = u4_r(rf->GPR)[0] & mask;
assert(occupied == false);
B4 occupied = u4_r(rf->GPR)[0] & mask; assert(occupied == false);
u4_r(rf->GPR)[0] |= 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;
}
FI_ void regfile_free_reg(RegFile_R rf, Reg r_id) {
/* never free the ABI set */
if (regfile_abi_mask & (1u << r_id)) return;
if (regfile_abi_mask & (1u << r_id)) return; // never free the ABI set
RegFile_RInfo info = regfile_rinfo(rf->GPR, r_id);
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),
mac_yield(),
})
#pragma endregion Mips Atom Procs
#pragma region Baked Mips Atoms
+19 -19
View File
@@ -499,17 +499,17 @@ enum {
#define R_OtBase_Code R_T6_Code
};
typedef Struct_(Binds_CubeTri) {
U4 PrimCursor;
V4_S2* FaceCursor;
V3_S2* VertBase;
U4* OtBase;
U1* prim_cursor;
V4_S2* face_cursor;
V3_S2* vert_base;
U4* ot_base;
};
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 */
load_word(R_PrimCursor, R_TapePtr, O_(Binds_CubeTri,PrimCursor)),
load_word(R_FaceCursor, R_TapePtr, O_(Binds_CubeTri,FaceCursor)),
load_word(R_VertBase, R_TapePtr, O_(Binds_CubeTri,VertBase)),
load_word(R_OtBase, R_TapePtr, O_(Binds_CubeTri,OtBase)),
load_word(R_PrimCursor, R_TapePtr, O_(Binds_CubeTri,prim_cursor)),
load_word(R_FaceCursor, R_TapePtr, O_(Binds_CubeTri,face_cursor)),
load_word(R_VertBase, R_TapePtr, O_(Binds_CubeTri,vert_base)),
load_word(R_OtBase, R_TapePtr, O_(Binds_CubeTri,ot_base)),
LdSlot_ add_ui_self( R_TapePtr, S_(Binds_CubeTri)),
mac_yield()
};
@@ -561,16 +561,16 @@ MipsAtom_(cube_g4_face) atom_info(atom_phase(cube_g4),
// end: branch(cull)
atom_label(cube_g4_face_exit)
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_PrimCursor, S_(Poly_G4)), // 9 words = Poly_G4
add_ui_self(R_FaceCursor, S_(S2) * 4), // 4 × S2 = 8 bytes
jump_reg(R_AtomJmp), BdSlot_ nop // ac_yield: word 3-4
};
typedef Struct_(Binds_FloorTri) {
U4 PrimCursor;
V3_S2* FaceCursor;
V3_S2* VertBase;
U4* OtBase;
U1* prim_cursor;
V3_S2* face_cursor;
V3_S2* vert_base;
U4* ot_base;
};
internal
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)
){
/* Pop 4 arguments from the tape directly into the workspace registers */
load_word(R_PrimCursor, R_TapePtr, O_(Binds_FloorTri,PrimCursor)),
load_word(R_FaceCursor, R_TapePtr, O_(Binds_FloorTri,FaceCursor)),
load_word(R_VertBase, R_TapePtr, O_(Binds_FloorTri,VertBase)),
load_word(R_OtBase, R_TapePtr, O_(Binds_FloorTri,OtBase)),
load_word(R_PrimCursor, R_TapePtr, O_(Binds_FloorTri,prim_cursor)),
load_word(R_FaceCursor, R_TapePtr, O_(Binds_FloorTri,face_cursor)),
load_word(R_VertBase, R_TapePtr, O_(Binds_FloorTri,vert_base)),
load_word(R_OtBase, R_TapePtr, O_(Binds_FloorTri,ot_base)),
LdSlot_ add_ui_self( R_TapePtr, S_(Binds_FloorTri)),
mac_yield()
};
@@ -623,7 +623,7 @@ atom_label(floor_f3_face_exit)
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)
, 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)
{
TapeBuilder tb = tb_make(slice_ut_arr(smem.MemTape));
/*Pad Input*/ {
tb.used = 0; tb_scope_run(& tb) {
// 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_translation(& smem.tform_world, & smem.cube.pos);
mt3s2s4_scale (& smem.tform_world, & smem.cube.scale);
// Combine world and look_at matrix.
gte_comp_coord_m3s2(& smem.cam.look_at, & smem.tform_world, & smem.tform_view);
gte_matrix_set_rotation (& smem.tform_view);
gte_matrix_set_translation(& smem.tform_view);
U4 prim_base = u4_(pa->buf[smem.active_buf_id]);
U4 prim_cursor = prim_base + pa->used;
tb.used = 0; tb_scope(& tb) {
tb_emit(& tb, rbind_cube_g4_face);
tb_data(& tb, prim_cursor);
tb_data(& tb, u4_(smem.cube.faces));
tb_data(& tb, u4_(smem.cube.verts));
tb_data(& tb, u4_(ordering_buf));
U1* prim_base = u1_r(pa->buf[smem.active_buf_id]);
U1* prim_cursor = prim_base + pa->used;
tb.used = 0; tb_scope_run(& tb) {
tb_emit(& tb, rbind_cube_g4_face); tb_bind_(& tb, Binds_CubeTri,
.prim_cursor = prim_cursor,
.face_cursor = smem.cube.faces,
.vert_base = smem.cube.verts,
.ot_base = ordering_buf,
);
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);
tb_emit(& tb, cube_g4_face); // Two triangles per quad face: (x,y,z) and (x,z,w)
}
tb_emit(& tb, sync_primitive_arena);
tb_data(& tb, u4_(& pa->used));
tb_data(& tb, prim_base);
tb_emit(& tb, sync_primitive_arena); tb_bind_(& tb, Binds_SyncPrimitiveArena,
.used = & pa->used,
.cursor = prim_base,
);
}
tape_run(tb_slice(tb));// Fire off the tape (bigger-clobber variant).
// smem.cube.rot.y += 30;
}
// Draw floor
@@ -330,33 +324,29 @@ void update(PrimitiveArena* pa, U4* ordering_buf)
gte_matrix_set_rotation (& smem.tform_view);
gte_matrix_set_translation(& smem.tform_view);
U4 prim_base = u4_(pa->buf[smem.active_buf_id]);
U4 prim_cursor = prim_base + pa->used;
U1_R prim_base = u1_r(pa->buf[smem.active_buf_id]);
U1_R prim_cursor = prim_base + pa->used;
// 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.
// Prepare the tape. (Push protocol to tape)
tb.used = 0; tb_scope(& tb) {
// tb_emit(& tb, set_gte_mt3s2s4);
// tb_data(& tb, u4_(& smem.tform_view));
tb_emit(& tb, rbind_floor_f3_face);
// TODO(Ed): Just use a single context struct ref?
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));
tb.used = 0; tb_scope_run(& tb) {
tb_emit(& tb, rbind_floor_f3_face); tb_bind_(& tb, Binds_FloorTri,
.prim_cursor = prim_cursor,
.face_cursor = smem.floor.faces,
.vert_base = smem.floor.verts,
.ot_base = ordering_buf,
);
for (U4 i = 0; i < Floor_num_faces; i++) {
tb_emit(& tb, floor_f3_face);
}
// After floor_f3_face iterations complete, the primitive arena's used counter needs updating.
tb_emit(& tb, sync_primitive_arena);
tb_data(& tb, u4_(& pa->used));
tb_data(& tb, prim_base);
tb_emit(& tb, sync_primitive_arena); tb_bind_(& tb, Binds_SyncPrimitiveArena,
.used = & pa->used,
.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!
// smem.floor.rot.y += 5;
}