Added SPDontSkipTexLoadsAcross

This commit is contained in:
Sauraen
2024-05-31 22:34:13 -07:00
parent 0ac73f7208
commit c9720c06d3
2 changed files with 36 additions and 1 deletions

View File

@@ -67,7 +67,9 @@ breaking changes.**
texture loads in the material are skipped (the second time). This effectively
results in **auto-batched rendering** of repeated objects, as long as each
only uses one material. This system supports multitexture and all types of
loads.
loads. If this system incorrectly culls supposedly repeated texture loads
which actually differ due to segment manipulation, you can locally disable it
using the new `SPDontSkipTexLoadsAcross` command.
- New `SPTriangleStrip` and `SPTriangleFan` commands **pack up to 5 tris** into
one 64-bit GBI command (up from 2 tris in F3DEX2). In any given object, most
tris can be drawn with these commands, with only a few at the end drawn with

33
gbi.h
View File

@@ -263,6 +263,7 @@ longer a multiple of 8 (DMA word). This was not used in any command anyway. */
#define G_MWO_ATTR_OFFSET_Z 0x14
#define G_MWO_ALPHA_COMPARE_CULL 0x16
#define G_MWO_NORMALS_MODE 0x18
#define G_MWO_LAST_MAT_DL_ADDR 0x1A
/*
* RDP command argument defines
@@ -2854,6 +2855,38 @@ _DW({ \
#define gsSPNormalsMode(mode) \
gsMoveHalfwd(G_MW_FX, G_MWO_NORMALS_MODE, (mode) & 0xFF)
/*
* F3DEX3 has a basic auto-batched rendering system. At a high level, if a
* material display list being run is the same as the last material, the texture
* loads are automatically skipped the second time as they should already be in
* TMEM.
*
* This design generally works, but can break if you call a display list twice
* but in between change a segment mapping so that a referenced image inside is
* actually different the two times. In these cases, run the below command
* between the two calls (e.g. when you change the segment) and the microcode
* will not skip the second texture loads.
*
* Internally, a material is defined to start with any set image command, and
* end on any of the following: call, branch, return, vertex, all tri commands,
* modify vertex, branch Z/W, or cull. The physical address of the display list
* --not the address of the image--is stored when a material is started. If a
* material starts and its physical address is the same as the stored last start
* address, i.e. we're executing the same material display list as the last
* material, material cull mode is set. In this mode, load block, load tile, and
* load TLUT all are skipped. This mode is cleared when the material ends.
*
* This design has the benefit that it works correctly even with complex
* materials, e.g. with two CI4 textures (four loads), whereas it would be
* difficult to implement tracking all these loads separately. Furthermore, a
* design based on tracking the image addresses could break if you loaded
* different tile sections of the same image in consecutive materials.
*/
#define gSPDontSkipTexLoadsAcross(pkt) \
gMoveWd(pkt, G_MW_FX, G_MWO_LAST_MAT_DL_ADDR, 0xFFFFFFFF)
#define gsSPDontSkipTexLoadsAcross() \
gsMoveWd(G_MW_FX, G_MWO_LAST_MAT_DL_ADDR, 0xFFFFFFFF)
typedef union {
struct {
s16 intPart[3][4]; /* Fourth row containing translations is omitted. */