mirror of
https://github.com/Ed94/pikuma_ps1.git
synced 2026-08-06 15:48:49 +00:00
need to finally make a metaprogram for offset math...
This commit is contained in:
+16
-2
@@ -5,6 +5,7 @@
|
|||||||
# include "mips.h"
|
# include "mips.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#pragma region ASM DSL
|
||||||
/* ============================================================================
|
/* ============================================================================
|
||||||
* gte.h — Geometry Transformation Engine (COP2) for the PS1
|
* gte.h — Geometry Transformation Engine (COP2) for the PS1
|
||||||
* ============================================================================
|
* ============================================================================
|
||||||
@@ -332,7 +333,7 @@ enum { _C2_OPS_ = 0
|
|||||||
| enc_gte_cmd(cmd) \
|
| enc_gte_cmd(cmd) \
|
||||||
)
|
)
|
||||||
|
|
||||||
/* Pre-baked GTE command words for the common cases.
|
/* GTE command words for the common cases.
|
||||||
*
|
*
|
||||||
* These are pure compile-time integer constants — the C compiler
|
* These are pure compile-time integer constants — the C compiler
|
||||||
* constant-folds them into `.word` directives in .rodata. Use them
|
* constant-folds them into `.word` directives in .rodata. Use them
|
||||||
@@ -379,12 +380,17 @@ enum { _C2_OPS_ = 0
|
|||||||
#define gte_cmdw_op (gte_cmd_base | enc_gte_cmd(gte_cmd_op ))
|
#define gte_cmdw_op (gte_cmd_base | enc_gte_cmd(gte_cmd_op ))
|
||||||
#define gte_cmdw_mvmva (gte_cmd_base | enc_gte_cmd(gte_cmd_mvmva))
|
#define gte_cmdw_mvmva (gte_cmd_base | enc_gte_cmd(gte_cmd_mvmva))
|
||||||
|
|
||||||
|
#define gte_cmdw_rotate_translate_perspective_triple gte_cmdw_rtpt
|
||||||
|
|
||||||
/* PsyQ compatibility bits for AVSZ3 (Bits 20, 22, 24 must be set) */
|
/* PsyQ compatibility bits for AVSZ3 (Bits 20, 22, 24 must be set) */
|
||||||
#define gte_cmdw_psyq_avsz3_compat (0x15 << 20)
|
#define gte_cmdw_psyq_avsz3_compat (0x15 << 20)
|
||||||
#define gte_cmd_avsz3 0x2D
|
#define gte_cmd_avsz3 0x2D
|
||||||
|
|
||||||
#define gte_cmdw_avsz3 (gte_cmd_base | enc_gte_cmd(gte_cmd_avsz3) | gte_cmdw_psyq_avsz3_compat)
|
#define gte_cmdw_avsz3 (gte_cmd_base | enc_gte_cmd(gte_cmd_avsz3) | gte_cmdw_psyq_avsz3_compat)
|
||||||
|
|
||||||
|
// Takes the three screen-space Z values of the triangle → averages them → writes the result into the OTZ register.
|
||||||
|
#define gte_avg_sort_z3 gte_cmdw_avsz3
|
||||||
|
|
||||||
/* AVSZ4 — average Z of 4 vertices (for quads) */
|
/* AVSZ4 — average Z of 4 vertices (for quads) */
|
||||||
#define gte_cmd_avsz4 0x2E
|
#define gte_cmd_avsz4 0x2E
|
||||||
#define gte_cmdw_avsz4 (gte_cmd_base | enc_gte_cmd(gte_cmd_avsz4) | gte_cmdw_psyq_avsz3_compat)
|
#define gte_cmdw_avsz4 (gte_cmd_base | enc_gte_cmd(gte_cmd_avsz4) | gte_cmdw_psyq_avsz3_compat)
|
||||||
@@ -403,7 +409,7 @@ enum { _C2_OPS_ = 0
|
|||||||
* asm_gte_load_v0(svector_ptr);
|
* asm_gte_load_v0(svector_ptr);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Pre-baked lwc2 encoding helpers parameterized on the base GPR.
|
/* lwc2 encoding helpers parameterized on the base GPR.
|
||||||
*
|
*
|
||||||
* gte_lwc2_v0(base) → lwc2 $0, 0(base) ; C2_VXY0
|
* gte_lwc2_v0(base) → lwc2 $0, 0(base) ; C2_VXY0
|
||||||
* gte_lwc2_v0z(base) → lwc2 $1, 4(base) ; C2_VZ0
|
* gte_lwc2_v0z(base) → lwc2 $1, 4(base) ; C2_VZ0
|
||||||
@@ -656,3 +662,11 @@ enum {
|
|||||||
, r_use(r0) \
|
, r_use(r0) \
|
||||||
asm_clobber: clb_system, rlit(R_T4), rlit(R_T5), rlit(R_T6) \
|
asm_clobber: clb_system, rlit(R_T4), rlit(R_T5), rlit(R_T6) \
|
||||||
)
|
)
|
||||||
|
|
||||||
|
#pragma region ASM DSL
|
||||||
|
|
||||||
|
#pragma region Reserved
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#pragma endregion Reserved
|
||||||
|
|||||||
+28
-58
@@ -15,6 +15,7 @@
|
|||||||
* The C compiler is completely unaware of these bindings.
|
* The C compiler is completely unaware of these bindings.
|
||||||
* ---------------------------------------------------------------------------*/
|
* ---------------------------------------------------------------------------*/
|
||||||
enum {
|
enum {
|
||||||
|
R_AtomJmp = R_T9,
|
||||||
R_TapePtr = R_T8, /* The Instruction Stream Pointer */
|
R_TapePtr = R_T8, /* The Instruction Stream Pointer */
|
||||||
R_PrimCur = R_T7, /* VRAM output cursor (primitive buffer) */
|
R_PrimCur = R_T7, /* VRAM output cursor (primitive buffer) */
|
||||||
R_FaceCur = R_T4, /* Input data cursor (indices/faces) */
|
R_FaceCur = R_T4, /* Input data cursor (indices/faces) */
|
||||||
@@ -78,33 +79,30 @@ FI_ Slice_U4 tb_slice(TapeBuilder tb) { return (Sli
|
|||||||
* Loads the next pointer from the tape, advances the tape, and jumps.
|
* Loads the next pointer from the tape, advances the tape, and jumps.
|
||||||
* Cost: ~ 4 cycles */
|
* Cost: ~ 4 cycles */
|
||||||
#define mac_yield() \
|
#define mac_yield() \
|
||||||
load_word(R_T9, R_TapePtr, 0) \
|
load_word(R_AtomJmp, R_TapePtr, 0) \
|
||||||
, add_ui_1( R_TapePtr, 4) \
|
, add_ui_1( R_TapePtr, 4) \
|
||||||
, jump_reg( R_T9) \
|
, jump_reg( R_AtomJmp) \
|
||||||
, nop
|
, nop
|
||||||
|
|
||||||
/* Loads 3 16-bit indices from the face array */
|
/* Words: 3; Loads 3 S2 indices from the face array */
|
||||||
#define mac_load_tri_indices(rId_0, rId_1, rId_2) \
|
#define mac_load_tri_indices(rId_0, rId_1, rId_2) \
|
||||||
load_half_u(rId_0, R_FaceCur, 0) \
|
load_half_u(rId_0, R_FaceCur, 0) \
|
||||||
, load_half_u(rId_1, R_FaceCur, 2) \
|
, load_half_u(rId_1, R_FaceCur, 2) \
|
||||||
, load_half_u(rId_2, R_FaceCur, 4)
|
, load_half_u(rId_2, R_FaceCur, 4)
|
||||||
|
|
||||||
/* Translates indices to vertex addresses and pushes them to GTE */
|
/* Words: 18; Translates indices to vertex addresses and pushes them to GTE
|
||||||
|
R_AT = rId_[#] << 3;
|
||||||
|
R_AT += R_VertBase;
|
||||||
|
R_V0 = R_AT[0];
|
||||||
|
gte_mt(R_V0, V.xy[#]);
|
||||||
|
gte_mt(R_V1, V.z [#]);
|
||||||
|
*/
|
||||||
#define mac_load_tri_verts(rId_0, rId_1, rId_2) \
|
#define mac_load_tri_verts(rId_0, rId_1, rId_2) \
|
||||||
shift_ll(R_AT, rId_0, 3), add_u(R_AT, R_AT, R_VertBase), load_word(R_V0, R_AT, 0), load_word(R_V1, R_AT, 4), gte_mt(R_V0, C2_VXY0), gte_mt(R_V1, C2_VZ0) \
|
shift_ll(R_AT, rId_0, 3), add_u(R_AT, R_AT, R_VertBase), load_word(R_V0, R_AT, 0), load_word(R_V1, R_AT, 4), gte_mt(R_V0, C2_VXY0), gte_mt(R_V1, C2_VZ0) \
|
||||||
, shift_ll(R_AT, rId_1, 3), add_u(R_AT, R_AT, R_VertBase), load_word(R_V0, R_AT, 0), load_word(R_V1, R_AT, 4), gte_mt(R_V0, C2_VXY1), gte_mt(R_V1, C2_VZ1) \
|
, shift_ll(R_AT, rId_1, 3), add_u(R_AT, R_AT, R_VertBase), load_word(R_V0, R_AT, 0), load_word(R_V1, R_AT, 4), gte_mt(R_V0, C2_VXY1), gte_mt(R_V1, C2_VZ1) \
|
||||||
, shift_ll(R_AT, rId_2, 3), add_u(R_AT, R_AT, R_VertBase), load_word(R_V0, R_AT, 0), load_word(R_V1, R_AT, 4), gte_mt(R_V0, C2_VXY2), gte_mt(R_V1, C2_VZ2)
|
, shift_ll(R_AT, rId_2, 3), add_u(R_AT, R_AT, R_VertBase), load_word(R_V0, R_AT, 0), load_word(R_V1, R_AT, 4), gte_mt(R_V0, C2_VXY2), gte_mt(R_V1, C2_VZ2)
|
||||||
|
|
||||||
/* Formats the primitive memory layout (Tag + Color + Coordinates) */
|
/* Words: 11; Correctly inserts a primitive into the Ordering Table linked list */
|
||||||
#define mac_format_prim_f3(color_hi, color_lo) \
|
|
||||||
store_word(R_0, R_PrimCur, 0) \
|
|
||||||
, load_ui(R_AT, color_hi), or_i(R_AT, R_AT, color_lo) \
|
|
||||||
, store_word(R_AT, R_PrimCur, 4) \
|
|
||||||
, gte_sw(C2_SXY0, R_PrimCur, 8) \
|
|
||||||
, gte_sw(C2_SXY1, R_PrimCur, 12) \
|
|
||||||
, gte_sw(C2_SXY2, R_PrimCur, 16)
|
|
||||||
|
|
||||||
/* Correctly inserts a primitive into the Ordering Table linked list */
|
|
||||||
#define mac_insert_ot_tag(r_otz, prim_length) \
|
#define mac_insert_ot_tag(r_otz, prim_length) \
|
||||||
shift_ll( R_T1, r_otz, 2) \
|
shift_ll( R_T1, r_otz, 2) \
|
||||||
, add_u( R_T1, R_T1, R_OtBase) /* T1 = &OrderingTable[OTZ] */ \
|
, add_u( R_T1, R_T1, R_OtBase) /* T1 = &OrderingTable[OTZ] */ \
|
||||||
@@ -136,7 +134,7 @@ FI_ void atombuilder_unroll(MipsAtomBuilder_R ab, Slice_MipsCode_R code) {
|
|||||||
mem_copy(ab->start, u4_(code->ptr), code->len);
|
mem_copy(ab->start, u4_(code->ptr), code->len);
|
||||||
mem_bump(ab->start, ab->capacity, & ab->used, code->len);
|
mem_bump(ab->start, ab->capacity, & ab->used, code->len);
|
||||||
}
|
}
|
||||||
#define atombuilder_unroll_mac(ab, mac)
|
#define atombuilder_unroll_mac(ab, mac) atombuilder_unroll(ab, slice_arg_from_array(Slice_MipsCode, mac))
|
||||||
|
|
||||||
// When done authoring, utilize this to cap-off the atom
|
// When done authoring, utilize this to cap-off the atom
|
||||||
FI_ void atombuilder_end(MipsAtomBuilder_R ab) {
|
FI_ void atombuilder_end(MipsAtomBuilder_R ab) {
|
||||||
@@ -152,14 +150,19 @@ FI_ void atombuilder_end(MipsAtomBuilder_R ab) {
|
|||||||
#pragma region Baked Mips Atoms
|
#pragma region Baked Mips Atoms
|
||||||
// These atoms are resolved at compile time and are (usually) statically linked readonly data.
|
// These atoms are resolved at compile time and are (usually) statically linked readonly data.
|
||||||
|
|
||||||
|
typedef Struct_(Binds_SyncPrimCursor) {
|
||||||
|
U4 PrimtiveArena_Used;
|
||||||
|
U4 PrimtiveBase;
|
||||||
|
};
|
||||||
internal MipsAtom_(sync_prim_cursor) {
|
internal MipsAtom_(sync_prim_cursor) {
|
||||||
/* Pop the C-struct address and base address from the tape */
|
/* Pop the C-struct address and base address from the tape */
|
||||||
load_word(R_AT, R_TapePtr, 0), /* AT = &pa->used */
|
// Note(Ed): Argument shuffle....
|
||||||
load_word(R_T0, R_TapePtr, 4), /* T0 = prim_base */
|
load_word(R_AT, R_TapePtr, O_(Binds_SyncPrimCursor,PrimtiveArena_Used)),
|
||||||
add_ui_1( R_TapePtr, 8),
|
load_word(R_T0, R_TapePtr, O_(Binds_SyncPrimCursor,PrimtiveBase)),
|
||||||
|
add_ui_1( R_TapePtr, S_(Binds_SyncPrimCursor)),
|
||||||
/* Calculate byte offset and store directly back to RAM */
|
/* Calculate byte offset and store directly back to RAM */
|
||||||
sub_u(R_T0, R_PrimCur, R_T0),
|
sub_u(R_T0, R_PrimCur, R_T0), // R_T0 = PrimitiveArea_Used(R_AT) - R_PrimCur
|
||||||
store_word(R_T0, R_AT, 0),
|
store_word(R_T0, R_AT, 0), // PrimitiveBase(R_AT)[0] = R_T0
|
||||||
mac_yield()
|
mac_yield()
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -195,6 +198,8 @@ internal MipsAtom_(rbind_cube_tri) {
|
|||||||
load_word(R_VertBase, R_TapePtr, O_(Binds_CubeTri,VertBase)),
|
load_word(R_VertBase, R_TapePtr, O_(Binds_CubeTri,VertBase)),
|
||||||
load_word(R_OtBase, R_TapePtr, O_(Binds_CubeTri,OtBase)),
|
load_word(R_OtBase, R_TapePtr, O_(Binds_CubeTri,OtBase)),
|
||||||
add_ui_1( R_TapePtr, S_(Binds_CubeTri)),
|
add_ui_1( R_TapePtr, S_(Binds_CubeTri)),
|
||||||
|
// Note(Ed): This entire thing is argument shuffle?
|
||||||
|
// TODO(Ed): Eliminate
|
||||||
mac_yield()
|
mac_yield()
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -345,46 +350,11 @@ internal MipsAtom_(rbind_floor_tri) {
|
|||||||
load_word(R_VertBase, R_TapePtr, O_(Binds_FloorTri,VertBase)),
|
load_word(R_VertBase, R_TapePtr, O_(Binds_FloorTri,VertBase)),
|
||||||
load_word(R_OtBase, R_TapePtr, O_(Binds_FloorTri,OtBase)),
|
load_word(R_OtBase, R_TapePtr, O_(Binds_FloorTri,OtBase)),
|
||||||
add_ui_1( R_TapePtr, S_(Binds_FloorTri)),
|
add_ui_1( R_TapePtr, S_(Binds_FloorTri)),
|
||||||
|
// Note(Ed): This entire thing is argument shuffle?
|
||||||
|
// TODO(Ed): Eliminate
|
||||||
mac_yield()
|
mac_yield()
|
||||||
};
|
};
|
||||||
|
|
||||||
internal MipsAtom_(floor_tri) {
|
|
||||||
mac_load_tri_indices(R_T0, R_T1, R_T2),
|
|
||||||
mac_load_tri_verts( R_T0, R_T1, R_T2),
|
|
||||||
|
|
||||||
/* 3. Execute Math */
|
|
||||||
nop, nop, gte_cmdw_rtpt,
|
|
||||||
nop, nop, gte_cmdw_nclip,
|
|
||||||
nop, nop,
|
|
||||||
|
|
||||||
/* 4. Culling (Branch forward 29 instructions if Backface) */
|
|
||||||
gte_mf(R_T0, C2_MAC0),
|
|
||||||
nop,
|
|
||||||
branch_le_zero(R_T0, 29),
|
|
||||||
nop,
|
|
||||||
|
|
||||||
/* 5. Format Primitive */
|
|
||||||
mac_format_prim_f3(0x20FF, 0xFFFF), /* High: 0x20/B, Low: G/R */
|
|
||||||
|
|
||||||
/* 6. Calculate Depth */
|
|
||||||
nop, nop, gte_cmdw_avsz3,
|
|
||||||
nop, nop,
|
|
||||||
gte_mf(R_T1, C2_OTZ),
|
|
||||||
|
|
||||||
/* 7. Bounds Check OTZ < 2048 (Branch forward 13 instructions to skip insertion) */
|
|
||||||
add_ui( R_AT, R_0, 2048),
|
|
||||||
slt_u( R_AT, R_T1, R_AT),
|
|
||||||
branch_equal(R_AT, R_0, 13),
|
|
||||||
nop,
|
|
||||||
|
|
||||||
/* 8. Insert into Ordering Table Linked List */
|
|
||||||
mac_insert_ot_tag(R_T1, 0x0400), /* Length = 4 words */
|
|
||||||
|
|
||||||
add_ui(R_PrimCur, R_PrimCur, 20), /* Advance Prim Cursor (5 words) */
|
|
||||||
/* 9. Advance Input Cursor & Yield (Both branch targets land here) */
|
|
||||||
add_ui(R_FaceCur, R_FaceCur, 8), /* Advance Face Cursor (4 * S2 = 8 bytes) */
|
|
||||||
mac_yield()
|
|
||||||
};
|
|
||||||
|
|
||||||
/* DIAGNOSTIC 1: Pure tape loop test */
|
/* DIAGNOSTIC 1: Pure tape loop test */
|
||||||
internal MipsAtom_(diag_yield) { mac_yield() };
|
internal MipsAtom_(diag_yield) { mac_yield() };
|
||||||
|
|||||||
+18
-4
@@ -69,6 +69,7 @@ enum {
|
|||||||
/* Semantic Aliases for MIPS Registers (O32 ABI) */
|
/* Semantic Aliases for MIPS Registers (O32 ABI) */
|
||||||
|
|
||||||
, rdiscard = R_0 /* Hardwired to 0 */
|
, rdiscard = R_0 /* Hardwired to 0 */
|
||||||
|
, rasm_tmp = R_AT /* Assembler temporary (destroyed by some assembler pseudoinstructions!) */
|
||||||
, rret_0 = R_V0 /* Function return value */
|
, rret_0 = R_V0 /* Function return value */
|
||||||
, rret_1 = R_V1 /* Second return value (e.g., 64-bit) */
|
, rret_1 = R_V1 /* Second return value (e.g., 64-bit) */
|
||||||
, rarg_0 = R_A0 /* First function argument */
|
, rarg_0 = R_A0 /* First function argument */
|
||||||
@@ -112,21 +113,30 @@ enum {
|
|||||||
, op_xori = 0x0E /* XOR Immediate */
|
, op_xori = 0x0E /* XOR Immediate */
|
||||||
, op_lui = 0x0F /* Load Upper Immediate */
|
, op_lui = 0x0F /* Load Upper Immediate */
|
||||||
, op_cop0 = 0x10 /* Coprocessor 0 (System) */
|
, op_cop0 = 0x10 /* Coprocessor 0 (System) */
|
||||||
|
, op_cop1 = 0x11 /* Coprocessor 1 (Reserved, FP Unit, Omitted by Sony) */
|
||||||
, op_cop2 = 0x12 /* Coprocessor 2 (GTE) */
|
, op_cop2 = 0x12 /* Coprocessor 2 (GTE) */
|
||||||
, op_la = 0
|
, op_cop3 = 0x13 /* Coprocessor 3 (Reserved, Unused)*/
|
||||||
, op_li = 0
|
/* 14-1F: N/A */
|
||||||
, op_lb = 0x20 /* Load Byte */
|
, op_lb = 0x20 /* Load Byte */
|
||||||
, op_lh = 0x21 /* Load Halfword */
|
, op_lh = 0x21 /* Load Halfword */
|
||||||
|
, op_lwl = 0x22 /* Load Word (Left Bits) */
|
||||||
, op_lw = 0x23 /* Load Word */
|
, op_lw = 0x23 /* Load Word */
|
||||||
, op_lbu = 0x24 /* Load Byte Unsigned */
|
, op_lbu = 0x24 /* Load Byte Unsigned */
|
||||||
, op_lhu = 0x25 /* Load Halfword Unsigned */
|
, op_lhu = 0x25 /* Load Halfword Unsigned */
|
||||||
|
, op_lwr = 0x26 /* Load Word (Right Bits) */
|
||||||
|
/* 27: N/A */
|
||||||
, op_sb = 0x28 /* Store Byte */
|
, op_sb = 0x28 /* Store Byte */
|
||||||
, op_sh = 0x29 /* Store Halfword */
|
, op_sh = 0x29 /* Store Halfword */
|
||||||
|
, op_swl = 0x2A /* Store Word (Left Bits) */
|
||||||
, op_sw = 0x2B /* Store Word */
|
, op_sw = 0x2B /* Store Word */
|
||||||
|
/* 2C-2D: N/A */
|
||||||
|
, op_swr = 0x2E /* Store Word (Right Bits) */
|
||||||
|
/* 2F: N/A */
|
||||||
|
// , op_lwc0
|
||||||
|
|
||||||
|
|
||||||
, op_load_addr = op_la
|
// , op_load_addr = op_la
|
||||||
, op_load_imm = op_li
|
// , op_load_imm = op_li
|
||||||
, op_jump = op_j
|
, op_jump = op_j
|
||||||
, op_jump_nlink = op_jal
|
, op_jump_nlink = op_jal
|
||||||
|
|
||||||
@@ -246,6 +256,10 @@ enum { _BitOffsets = 0
|
|||||||
#define xor_i(rt, rs, imm) enc_i(op_xori, (rs), (rt), (imm))
|
#define xor_i(rt, rs, imm) enc_i(op_xori, (rs), (rt), (imm))
|
||||||
#define load_ui(rt, imm) enc_i(op_lui, R_0, (rt), (imm))
|
#define load_ui(rt, imm) enc_i(op_lui, R_0, (rt), (imm))
|
||||||
|
|
||||||
|
#define load_u1 load_byte_u
|
||||||
|
#define load_u2 load_half_u
|
||||||
|
#define load_u4 load_word
|
||||||
|
|
||||||
// Ergonomic add to the same register.
|
// Ergonomic add to the same register.
|
||||||
#define add_ui_1(rt_rs, imm) enc_i(op_addiu, (rt_rs), (rt_rs), (imm))
|
#define add_ui_1(rt_rs, imm) enc_i(op_addiu, (rt_rs), (rt_rs), (imm))
|
||||||
|
|
||||||
|
|||||||
+17
-16
@@ -14,11 +14,7 @@
|
|||||||
#include "duffle/gte.h"
|
#include "duffle/gte.h"
|
||||||
#include "duffle/lottes_tape.h"
|
#include "duffle/lottes_tape.h"
|
||||||
#include "hello_gte.h"
|
#include "hello_gte.h"
|
||||||
|
#include "hello_gte_tape.c"
|
||||||
enum {
|
|
||||||
PrimitiveBuff_Len = 4096,
|
|
||||||
OrderingTbl_Len = 2048
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef U4 OrderingTable_Buffer[OrderingTbl_Len];
|
typedef U4 OrderingTable_Buffer[OrderingTbl_Len];
|
||||||
typedef Array_(OrderingTable_Buffer, 2);
|
typedef Array_(OrderingTable_Buffer, 2);
|
||||||
@@ -104,6 +100,8 @@ typedef Struct_(SMemory) {
|
|||||||
|
|
||||||
Ent_Cube cube;
|
Ent_Cube cube;
|
||||||
Ent_Floor floor;
|
Ent_Floor floor;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
global SMemory static_mem;
|
global SMemory static_mem;
|
||||||
extern SMemory static_mem;
|
extern SMemory static_mem;
|
||||||
@@ -245,10 +243,10 @@ void update(PrimitiveArena* pa, U4* ordering_buf)
|
|||||||
LP_ U4 mem_temp_tape[512]; FArena tape_arena; farena_init(& tape_arena, slice_ut_arr(mem_temp_tape));
|
LP_ U4 mem_temp_tape[512]; FArena tape_arena; farena_init(& tape_arena, slice_ut_arr(mem_temp_tape));
|
||||||
TapeBuilder tb = tb_make(&tape_arena); tb_scope(& tb) {
|
TapeBuilder tb = tb_make(&tape_arena); tb_scope(& tb) {
|
||||||
tb_emit(& tb, code_rbind_cube_tri);
|
tb_emit(& tb, code_rbind_cube_tri);
|
||||||
tb_data(& tb, prim_cursor);
|
tb_data(& tb, prim_cursor);
|
||||||
tb_data(& tb, u4_(static_mem.cube.faces));
|
tb_data(& tb, u4_(static_mem.cube.faces));
|
||||||
tb_data(& tb, u4_(static_mem.cube.verts));
|
tb_data(& tb, u4_(static_mem.cube.verts));
|
||||||
tb_data(& tb, u4_(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)
|
// Two triangles per quad face: (x,y,z) and (x,z,w)
|
||||||
@@ -256,8 +254,8 @@ void update(PrimitiveArena* pa, U4* ordering_buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
tb_emit(& tb, code_sync_prim_cursor);
|
tb_emit(& tb, code_sync_prim_cursor);
|
||||||
tb_data(& tb, u4_(& pa->used));
|
tb_data(& tb, u4_(& pa->used));
|
||||||
tb_data(& tb, prim_base);
|
tb_data(& tb, prim_base);
|
||||||
}
|
}
|
||||||
tape_run(tb_slice(tb));
|
tape_run(tb_slice(tb));
|
||||||
|
|
||||||
@@ -334,21 +332,24 @@ void update(PrimitiveArena* pa, U4* ordering_buf)
|
|||||||
LP_ U4 mem_temp_tape[512]; FArena tape_arena; farena_init(& tape_arena, slice_ut_arr(mem_temp_tape));
|
LP_ U4 mem_temp_tape[512]; FArena tape_arena; farena_init(& tape_arena, slice_ut_arr(mem_temp_tape));
|
||||||
TapeBuilder tb = tb_make(&tape_arena); tb_scope(& tb) {
|
TapeBuilder tb = tb_make(&tape_arena); tb_scope(& tb) {
|
||||||
// Push "Protocol" to tape
|
// Push "Protocol" to tape
|
||||||
tb_emit_(& tb, rbind_floor_tri);
|
tb_emit(& tb, code_rbind_floor_tri);
|
||||||
|
// Note(Ed): This is technically argument shuffle and would be better if we did a single reference at most to a global batch context.
|
||||||
|
// Note(Ed): We can technically allocate a single ptr with the global offset to the working context instead of utilizing the tape for this stack of refs.
|
||||||
tb_data(& tb, prim_cursor);
|
tb_data(& tb, prim_cursor);
|
||||||
tb_data(& tb, u4_(static_mem.floor.faces));
|
tb_data(& tb, u4_(static_mem.floor.faces));
|
||||||
tb_data(& tb, u4_(static_mem.floor.verts));
|
tb_data(& tb, u4_(static_mem.floor.verts));
|
||||||
tb_data(& tb, u4_(ordering_buf));
|
tb_data(& tb, u4_(ordering_buf));
|
||||||
|
|
||||||
tb_emit(& tb, code_set_gte_world);
|
tb_emit(& tb, code_set_gte_world);
|
||||||
tb_data(& tb, u4_(& static_mem.tform_world));
|
tb_data(& tb, u4_(& static_mem.tform_world));
|
||||||
|
|
||||||
for (U4 i = 0; i < Floor_num_faces; i++) {
|
for (U4 i = 0; i < Floor_num_faces; i++) {
|
||||||
tb_emit(& tb, code_floor_tri);
|
tb_emit(& tb, code_floor_tri);
|
||||||
}
|
}
|
||||||
|
|
||||||
tb_emit(& tb, code_sync_prim_cursor);
|
tb_emit(& tb, code_sync_prim_cursor);
|
||||||
tb_data(& tb, u4_(& pa->used));
|
tb_data(& tb, u4_(& pa->used));
|
||||||
tb_data(& tb, prim_base);
|
tb_data(& tb, prim_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fire off the tape.
|
// Fire off the tape.
|
||||||
|
|||||||
@@ -5,6 +5,11 @@
|
|||||||
# include "duffle/gp.h"
|
# include "duffle/gp.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PrimitiveBuff_Len = 4096,
|
||||||
|
OrderingTbl_Len = 2048
|
||||||
|
};
|
||||||
|
|
||||||
typedef Struct_(DrawEnv_Packed) { U4 tag; U4 code[15]; };
|
typedef Struct_(DrawEnv_Packed) { U4 tag; U4 code[15]; };
|
||||||
typedef Struct_(DrawEnv) {
|
typedef Struct_(DrawEnv) {
|
||||||
Rect_S2 clip_area;
|
Rect_S2 clip_area;
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
#ifdef INTELLISENSE_DIRECTIVES
|
||||||
|
# include "duffle/lottes_tape.h"
|
||||||
|
# include "hello_gte.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#pragma region MACs
|
||||||
|
|
||||||
|
/* Words: 3; High: 0x20/B, Low: G/R */
|
||||||
|
#define mac_format_f3_color(color_hi, color_lo) \
|
||||||
|
load_ui(R_AT, color_hi), or_i(R_AT, R_AT, color_lo) \
|
||||||
|
, store_word(R_AT, R_PrimCur, O_(Poly_F3,color)) \
|
||||||
|
|
||||||
|
/* Words: 3 */
|
||||||
|
#define mac_gte_store_f3() \
|
||||||
|
gte_sw(C2_SXY0, R_PrimCur, O_(Poly_F3,p0)) \
|
||||||
|
, gte_sw(C2_SXY1, R_PrimCur, O_(Poly_F3,p1)) \
|
||||||
|
, gte_sw(C2_SXY2, R_PrimCur, O_(Poly_F3,p2))
|
||||||
|
|
||||||
|
#pragma endregion MACs
|
||||||
|
|
||||||
|
#pragma region Baked Atoms
|
||||||
|
|
||||||
|
internal MipsAtom_(floor_tri) {
|
||||||
|
// T0-T2 allocated
|
||||||
|
mac_load_tri_indices(R_T0, R_T1, R_T2),
|
||||||
|
mac_load_tri_verts( R_T0, R_T1, R_T2),
|
||||||
|
|
||||||
|
/* 3. Execute Math */
|
||||||
|
nop, nop, gte_cmdw_rotate_translate_perspective_triple,
|
||||||
|
nop, nop, gte_cmdw_nclip,
|
||||||
|
nop, nop,
|
||||||
|
|
||||||
|
/* 4. Culling (Branch forward 29 instructions if Backface) */
|
||||||
|
gte_mf(R_T0, C2_MAC0),
|
||||||
|
nop, branch_le_zero(R_T0, 29),
|
||||||
|
nop,
|
||||||
|
|
||||||
|
/* 5. Format Primitive */
|
||||||
|
mac_format_f3_color(0x20FF, 0xFFFF),
|
||||||
|
mac_gte_store_f3(),
|
||||||
|
|
||||||
|
/* 6. Calculate Depth */
|
||||||
|
nop, nop, gte_avg_sort_z3,
|
||||||
|
nop, nop, gte_mf(R_T1, C2_OTZ),
|
||||||
|
|
||||||
|
/* 7. Bounds Check OTZ < 2048 (Branch forward 13 instructions to skip insertion) */
|
||||||
|
add_ui( R_AT, R_0, OrderingTbl_Len),
|
||||||
|
slt_u( R_AT, R_T1, R_AT),
|
||||||
|
branch_equal(R_AT, R_0, 13),
|
||||||
|
nop,
|
||||||
|
|
||||||
|
/* 8. Insert into Ordering Table Linked List */
|
||||||
|
mac_insert_ot_tag(R_T1, 0x0400),
|
||||||
|
add_ui(R_PrimCur, R_PrimCur, S_(Poly_F3)), /* Advance Prim Cursor (5 words) */
|
||||||
|
|
||||||
|
/* 9. Advance Input Cursor & Yield (Both branch targets land here) */
|
||||||
|
add_ui(R_FaceCur, R_FaceCur, S_(S2) * 4), /* Advance Face Cursor (4 * S2 = 8 bytes) */
|
||||||
|
mac_yield()
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma endregion Baked Atoms
|
||||||
Reference in New Issue
Block a user