Match a lot of GX

This commit is contained in:
dbalatoni13 2024-12-31 02:21:59 +01:00
parent b4279816e7
commit 3b90bdcb7f
25 changed files with 7195 additions and 174 deletions

View file

@ -901,7 +901,7 @@ typedef enum _GXAlphaReadMode {
GX_READ_FF = 1,
GX_READ_NONE = 2,
} _GXAlphaReadMode;
} GXAlphaReadMode;
#ifdef __cplusplus
}

View file

@ -1,7 +1,32 @@
#ifndef _DOLPHIN_GXPRIV
#define _DOLPHIN_GXPRIV
#include "dolphin/gx/GXVert.h"
#include "dolphin/gx.h"
#ifdef DEBUG
#define ASSERTLINE(line, cond) \
((cond) || (OSPanic(__FILE__, line, "Failed assertion " #cond), 0))
#define ASSERTMSGLINE(line, cond, msg) \
((cond) || (OSPanic(__FILE__, line, msg), 0))
// This is dumb but we dont have a Metrowerks way to do variadic macros in the macro to make this done in a not scrubby way.
#define ASSERTMSG1LINE(line, cond, msg, arg1) \
((cond) || (OSPanic(__FILE__, line, msg, arg1), 0))
#define ASSERTMSG2LINE(line, cond, msg, arg1, arg2) \
((cond) || (OSPanic(__FILE__, line, msg, arg1, arg2), 0))
#define ASSERTMSGLINEV(line, cond, ...) \
((cond) || (OSPanic(__FILE__, line, __VA_ARGS__), 0))
#else
#define ASSERTLINE(line, cond) (void)0
#define ASSERTMSGLINE(line, cond, msg) (void)0
#define ASSERTMSG1LINE(line, cond, msg, arg1) (void)0
#define ASSERTMSG2LINE(line, cond, msg, arg1, arg2) (void)0
#define ASSERTMSGLINEV(line, cond, ...) (void)0
#endif
typedef struct GXLightObjInt {
u32 padding[3];
@ -26,92 +51,137 @@ typedef struct GXLightObjInt {
#define GX_FIFO_ADDR 0xCC008000
#define GX_WRITE_U8(v) (GXWGFifo.u8 = v)
#define GX_WRITE_U16(us) (GXWGFifo.u16 = (u16)(us))
#define GX_WRITE_U32(v) (GXWGFifo.u32 = v)
#define GX_WRITE_F32(f) (GXWGFifo.f32 = (f32)(f))
typedef struct __GXData_struct {
u16 vNumNot;
u16 bpSentNot;
u16 vNum;
u16 vLim;
u32 cpEnable;
u32 cpStatus;
u32 cpClr;
u32 vcdLo;
u32 vcdHi;
u32 vatA[8];
u32 vatB[8];
u32 vatC[8];
u32 lpSize;
u32 matIdxA;
u32 matIdxB;
u32 indexBase[4];
u32 indexStride[4];
u32 ambColor[2];
u32 matColor[2];
u32 suTs0[8];
u32 suTs1[8];
u32 suScis0;
u32 suScis1;
u32 tref[8];
u32 iref;
u32 bpMask;
u32 IndTexScale0;
u32 IndTexScale1;
u32 tevc[16];
u32 teva[16];
u32 tevKsel[8];
u32 cmode0;
u32 cmode1;
u32 zmode;
u32 peCtrl;
u32 cpDispSrc;
u32 cpDispSize;
u32 cpDispStride;
u32 cpDisp;
u32 cpTexSrc;
u32 cpTexSize;
u32 cpTexStride;
u32 cpTex;
GXBool cpTexZ;
u32 genMode;
GXTexRegion TexRegions[8];
GXTexRegion TexRegionsCI[4];
u32 nextTexRgn;
u32 nextTexRgnCI;
GXTlutRegion TlutRegions[20];
GXTexRegion* (*texRegionCallback)(GXTexObj*, GXTexMapID);
GXTlutRegion* (*tlutRegionCallback)(u32);
GXAttrType nrmType;
GXBool hasNrms;
GXBool hasBiNrms;
u32 projType;
f32 projMtx[6];
f32 vpLeft;
f32 vpTop;
f32 vpWd;
f32 vpHt;
f32 vpNearz;
f32 vpFarz;
u8 fgRange;
f32 fgSideX;
u32 tImage0[8];
u32 tMode0[8];
u32 texmapId[16];
u32 tcsManEnab;
u32 tevTcEnab;
GXPerf0 perf0;
GXPerf1 perf1;
u32 perfSel;
GXBool inDispList;
GXBool dlSaveContext;
u8 dirtyVAT;
u32 dirtyState;
} GXData;
#if DEBUG
#define VERIF_XF_REG(addr, value) \
do { \
s32 regAddr = (addr); \
if (regAddr >= 0 && regAddr < 0x50) { \
__gxVerif->xfRegs[regAddr] = (value); \
__gxVerif->xfRegsDirty[regAddr] = 1; \
} \
} while (0)
#define VERIF_XF_REG_alt(addr, value) \
do { \
s32 xfAddr = (addr); \
if (xfAddr >= 0 && xfAddr < 0x50) { \
__gxVerif->xfRegs[xfAddr] = (value); \
__gxVerif->xfRegsDirty[xfAddr] = 1; \
} \
} while (0)
#define VERIF_RAS_REG(value) (__gxVerif->rasRegs[((value) & 0xFF000000) >> 24] = value)
#define VERIF_MTXLIGHT(addr, data) \
do { \
s32 xfAddr; \
if (addr < 0x400U) { \
__gxVerif->xfMtx[addr] = data; \
__gxVerif->xfMtxDirty[addr] = 1; \
} else if (addr < 0x500U) { \
xfAddr = addr - 0x400; \
__gxVerif->xfNrm[xfAddr] = data; \
__gxVerif->xfNrmDirty[xfAddr] = 1; \
} else if (addr < 0x600U) { \
xfAddr = addr - 0x500; \
__gxVerif->xfDMtx[xfAddr] = data; \
__gxVerif->xfDMtxDirty[xfAddr] = 1; \
} else if (addr < 0x680U) { \
xfAddr = addr - 0x600; \
__gxVerif->xfLight[xfAddr] = data; \
__gxVerif->xfLightDirty[xfAddr] = 1; \
} else { \
xfAddr = addr - 0x1000; \
if ((xfAddr >= 0) && (xfAddr < 0x50)) { \
__gxVerif->xfRegs[xfAddr] = data; \
__gxVerif->xfRegsDirty[xfAddr] = 1; \
} \
} \
} while (0)
#else
#define VERIF_XF_REG(addr, value) ((void)0)
#define VERIF_XF_REG_alt(addr, value) ((void)0)
#define VERIF_RAS_REG(value) ((void)0)
#endif
extern GXData* gx;
// #define gx __GXData
#define GX_WRITE_XF_REG(addr, value) \
do { \
GX_WRITE_U8(0x10); \
GX_WRITE_U32(0x1000 + (addr)); \
GX_WRITE_U32(value); \
VERIF_XF_REG(addr, value); \
} while (0)
void __GXInitGX();
#if DEBUG
#define GX_WRITE_XF_REG_2(addr, value) \
do { \
u32 xfData = (value); &xfData; \
GX_WRITE_U32(value); \
VERIF_XF_REG_alt(addr, xfData); \
} while (0)
#define GX_WRITE_XF_REG_F(addr, value) \
do { \
f32 xfData = (value); \
GX_WRITE_F32(value); \
VERIF_XF_REG_alt(addr, *(u32 *)&xfData); \
} while (0)
#else
#define GX_WRITE_XF_REG_2(addr, value) \
do { \
GX_WRITE_U32(value); \
} while (0)
#define GX_WRITE_XF_REG_F(addr, value) \
do { \
GX_WRITE_F32(value); \
} while (0)
#endif
#define GX_WRITE_RAS_REG(value) \
do { \
GX_WRITE_U8(0x61); \
GX_WRITE_U32(value); \
VERIF_RAS_REG(value); \
} while (0)
#define GX_WRITE_SOME_REG2(a, b, c, addr) \
do { \
long regAddr; \
GX_WRITE_U8(a); \
GX_WRITE_U8(b); \
GX_WRITE_U32(c); \
regAddr = addr; \
if (regAddr >= 0 && regAddr < 4) { \
gx->indexBase[regAddr] = c; \
} \
} while (0)
#define GX_WRITE_SOME_REG3(a, b, c, addr) \
do { \
long regAddr; \
GX_WRITE_U8(a); \
GX_WRITE_U8(b); \
GX_WRITE_U32(c); \
regAddr = addr; \
if (regAddr >= 0 && regAddr < 4) { \
gx->indexStride[regAddr] = c; \
} \
} while (0)
#define GX_WRITE_SOME_REG4(a, b, c, addr) \
do { \
long regAddr; \
GX_WRITE_U8(a); \
GX_WRITE_U8(b); \
GX_WRITE_U32(c); \
regAddr = addr; \
} while (0)
#define GET_REG_FIELD(reg, size, shift) ((int)((reg) >> (shift)) & ((1 << (size)) - 1))
#define SET_REG_FIELD(line, reg, size, shift, val) \
do { \
ASSERTMSGLINE(line, ((u32)(val) & ~((1 << (size)) - 1)) == 0, "GX Internal: Register field out of range"); \
(reg) = ((u32)(reg) & ~(((1 << (size)) - 1) << (shift))) | ((u32)(val) << (shift)); \
} while (0)
#define GX_REG_ASSERT(c) ASSERTMSG(c, "GX Internal: Register field out of range")
@ -358,4 +428,223 @@ void __GXInitGX();
#define GX_VAT_REG_B_UNK_SHIFT 31
#define GX_VAT_REG_B_UNK_MASK 0x80000000
#define GX_GET_MEM_REG(offset) (*(volatile u16*)((volatile u16*)(__memReg) + (offset)))
#define GX_GET_CP_REG(offset) (*(volatile u16*)((volatile u16*)(__cpReg) + (offset)))
#define GX_GET_PE_REG(offset) (*(volatile u16*)((volatile u16*)(__peReg) + (offset)))
#define GX_GET_PI_REG(offset) (*(volatile u32*)((volatile u32*)(__piReg) + (offset)))
#define GX_SET_MEM_REG(offset, val) (*(volatile u16*)((volatile u16*)(__memReg) + (offset)) = val)
#define GX_SET_CP_REG(offset, val) (*(volatile u16*)((volatile u16*)(__cpReg) + (offset)) = val)
#define GX_SET_PE_REG(offset, val) (*(volatile u16*)((volatile u16*)(__peReg) + (offset)) = val)
#define GX_SET_PI_REG(offset, val) (*(volatile u32*)((volatile u32*)(__piReg) + (offset)) = val)
#define CHECK_GXBEGIN(line, name) ASSERTMSGLINE(line, !__GXinBegin, "'" name "' is not allowed between GXBegin/GXEnd")
/* GXAttr.c */
void __GXSetVCD(void);
void __GXSetVAT(void);
/* GXBump.c */
void __GXUpdateBPMask(void);
void __GXFlushTextureState(void);
/* GXFifo.c */
// GXFifoObj private data
struct __GXFifoObj {
u8 *base;
u8 *top;
u32 size;
u32 hiWatermark;
u32 loWatermark;
void *rdPtr;
void *wrPtr;
s32 count;
u8 bind_cpu;
u8 bind_gp;
};
void __GXSaveCPUFifoAux(struct __GXFifoObj *realFifo);
void __GXFifoInit(void);
void __GXInsaneWatermark(void);
void __GXCleanGPFifo(void);
/* GXGeometry.c */
void __GXSetDirtyState(void);
void __GXSendFlushPrim(void);
void __GXSetGenMode(void);
/* GXInit.c */
void __GXInitGX();
void __GXInitRevisionBits(void);
typedef struct __GXData_struct {
u16 vNumNot;
u16 bpSentNot;
u16 vNum;
u16 vLim;
u32 cpEnable;
u32 cpStatus;
u32 cpClr;
u32 vcdLo;
u32 vcdHi;
u32 vatA[8];
u32 vatB[8];
u32 vatC[8];
u32 lpSize;
u32 matIdxA;
u32 matIdxB;
u32 indexBase[4];
u32 indexStride[4];
u32 ambColor[2];
u32 matColor[2];
u32 suTs0[8];
u32 suTs1[8];
u32 suScis0;
u32 suScis1;
u32 tref[8];
u32 iref;
u32 bpMask;
u32 IndTexScale0;
u32 IndTexScale1;
u32 tevc[16];
u32 teva[16];
u32 tevKsel[8];
u32 cmode0;
u32 cmode1;
u32 zmode;
u32 peCtrl;
u32 cpDispSrc;
u32 cpDispSize;
u32 cpDispStride;
u32 cpDisp;
u32 cpTexSrc;
u32 cpTexSize;
u32 cpTexStride;
u32 cpTex;
GXBool cpTexZ;
u32 genMode;
GXTexRegion TexRegions[8];
GXTexRegion TexRegionsCI[4];
u32 nextTexRgn;
u32 nextTexRgnCI;
GXTlutRegion TlutRegions[20];
GXTexRegion* (*texRegionCallback)(GXTexObj*, GXTexMapID);
GXTlutRegion* (*tlutRegionCallback)(u32);
GXAttrType nrmType;
GXBool hasNrms;
GXBool hasBiNrms;
u32 projType;
f32 projMtx[6];
f32 vpLeft;
f32 vpTop;
f32 vpWd;
f32 vpHt;
f32 vpNearz;
f32 vpFarz;
u8 fgRange;
f32 fgSideX;
u32 tImage0[8];
u32 tMode0[8];
u32 texmapId[16];
u32 tcsManEnab;
u32 tevTcEnab;
GXPerf0 perf0;
GXPerf1 perf1;
u32 perfSel;
GXBool inDispList;
GXBool dlSaveContext;
u8 dirtyVAT;
u32 dirtyState;
} GXData;
extern GXData* gx;
extern u16 *__memReg;
extern u16 *__peReg;
extern u16 *__cpReg;
extern u32 *__piReg;
// #define gx __GXData
/* GXMisc.c */
void __GXBypass(u32 reg);
u16 __GXReadPEReg(u32 reg);
void __GXPEInit(void);
void __GXAbort();
/* GXPerf.c */
void __GXSetBWDials(u16 cpDial, u16 tcDial, u16 peDial, u16 cpuRdDial, u16 cpuWrDial);
static inline u32 __GXReadCPCounterU32(u32 regAddrL, u32 regAddrH) {
u32 ctrH0;
u32 ctrH1;
u32 ctrL;
ctrH0 = GX_GET_CP_REG(regAddrH);
do {
ctrH1 = ctrH0;
ctrL = GX_GET_CP_REG(regAddrL);
ctrH0 = GX_GET_CP_REG(regAddrH);
} while (ctrH0 != ctrH1);
return (ctrH0 << 0x10) | ctrL;
}
static inline u32 __GXReadMEMCounterU32(u32 regAddrL, u32 regAddrH) {
u32 ctrH0;
u32 ctrH1;
u32 ctrL;
ctrH0 = GX_GET_MEM_REG(regAddrH);
do {
ctrH1 = ctrH0;
ctrL = GX_GET_MEM_REG(regAddrL);
ctrH0 = GX_GET_MEM_REG(regAddrH);
} while (ctrH0 != ctrH1);
return (ctrH0 << 0x10) | ctrL;
}
static inline u32 __GXReadPECounterU32(u32 regAddrL, u32 regAddrH) {
u32 ctrH0;
u32 ctrH1;
u32 ctrL;
ctrH0 = GX_GET_PE_REG(regAddrH);
do {
ctrH1 = ctrH0;
ctrL = GX_GET_PE_REG(regAddrL);
ctrH0 = GX_GET_PE_REG(regAddrH);
} while (ctrH0 != ctrH1);
return (ctrH0 << 0x10) | ctrL;
}
/* GXSave.c */
void __GXShadowDispList(void *list, u32 nbytes);
void __GXShadowIndexState(u32 idx_reg, u32 reg_data);
void __GXPrintShadowState(void);
/* GXStubs.c */
void __GXSetRange(float nearz, float fgSideX);
/* GXTexture.c */
void __GetImageTileCount(GXTexFmt fmt, u16 wd, u16 ht, u32 *rowTiles, u32 *colTiles, u32 *cmpTiles);
void __GXSetSUTexRegs(void);
void __GXGetSUTexSize(GXTexCoordID coord, u16 *width, u16 *height);
void __GXSetTmemConfig(u32 config);
/* GXTransform.c */
void __GXSetMatrixIndex(GXAttr matIdxAttr);
#endif // _DOLPHIN_GXPRIV

View file

@ -72,6 +72,26 @@ typedef struct _GXTlutRegion {
u32 dummy[4];
} GXTlutRegion;
typedef struct _GXFogAdjTable
{
u16 r[10];
} GXFogAdjTable;
typedef enum _GXTlutSize
{
GX_TLUT_16 = 1,
GX_TLUT_32 = 2,
GX_TLUT_64 = 4,
GX_TLUT_128 = 8,
GX_TLUT_256 = 16,
GX_TLUT_512 = 32,
GX_TLUT_1K = 64,
GX_TLUT_2K = 128,
GX_TLUT_4K = 256,
GX_TLUT_8K = 512,
GX_TLUT_16K = 1024,
} GXTlutSize;
typedef struct _GXVtxAttrFmtList {
// total size: 0x10
GXAttr attr; // offset 0x0, size 0x4

View file

@ -8,29 +8,35 @@
extern "C" {
#endif
typedef GXTexRegion* (*GXTexRegionCallback)(const GXTexObj* obj, GXTexMapID id);
typedef GXTexRegion *(*GXTexRegionCallback)(GXTexObj *t_obj, GXTexMapID id);
typedef GXTlutRegion *(*GXTlutRegionCallback)(u32 idx);
void GXInitTexObj(GXTexObj* obj, const void* data, u16 width, u16 height, u32 format,
GXTexWrapMode wrapS, GXTexWrapMode wrapT, GXBool mipmap);
void GXInitTexObjCI(GXTexObj* obj, const void* data, u16 width, u16 height, GXCITexFmt format,
GXTexWrapMode wrapS, GXTexWrapMode wrapT, GXBool mipmap, u32 tlut);
void GXInitTexObjData(GXTexObj* obj, const void* data);
void GXInitTexObjLOD(GXTexObj* obj, GXTexFilter min_filt, GXTexFilter mag_filt, f32 min_lod,
f32 max_lod, f32 lod_bias, GXBool bias_clamp, GXBool do_edge_lod,
GXAnisotropy max_aniso);
void GXLoadTexObj(GXTexObj* obj, GXTexMapID id);
u32 GXGetTexBufferSize(u16 width, u16 height, u32 format, GXBool mipmap, u8 max_lod);
void GXInvalidateTexAll();
void GXInitTexObjWrapMode(GXTexObj* obj, GXTexWrapMode s, GXTexWrapMode t);
void GXInitTlutObj(GXTlutObj* obj, void* data, GXTlutFmt format, u16 entries);
void GXLoadTlut(const GXTlutObj* obj, GXTlut idx);
void GXSetTexCoordScaleManually(GXTexCoordID coord, GXBool enable, u16 ss, u16 ts);
void GXInitTexCacheRegion(GXTexRegion* region, GXBool is_32b_mipmap, u32 tmem_even,
GXTexCacheSize size_even, u32 tmem_odd, GXTexCacheSize size_odd);
GXTexRegionCallback GXSetTexRegionCallback(GXTexRegionCallback callback);
void GXInvalidateTexRegion(const GXTexRegion* region);
void GXSetTexCoordScaleManually(GXTexCoordID coord, GXBool enable, u16 ss, u16 ts);
u32 GXGetTexBufferSize(u16 width, u16 height, u32 format, u8 mipmap, u8 max_lod);
void GXInitTexObj(GXTexObj *obj, void *image_ptr, u16 width, u16 height, GXTexFmt format, GXTexWrapMode wrap_s, GXTexWrapMode wrap_t, u8 mipmap);
void GXInitTexObjCI(GXTexObj *obj, void *image_ptr, u16 width, u16 height, GXCITexFmt format, GXTexWrapMode wrap_s, GXTexWrapMode wrap_t, u8 mipmap, u32 tlut_name);
void GXInitTexObjLOD(GXTexObj *obj, GXTexFilter min_filt, GXTexFilter mag_filt,
f32 min_lod, f32 max_lod, f32 lod_bias, GXBool bias_clamp,
GXBool do_edge_lod, GXAnisotropy max_aniso);
void GXInitTexObjData(GXTexObj *obj, void *image_ptr);
void GXInitTexObjWrapMode(GXTexObj *obj, GXTexWrapMode s, GXTexWrapMode t);
void GXInitTexObjTlut(GXTexObj *obj, u32 tlut_name);
void GXInitTexObjUserData(GXTexObj *obj, void *user_data);
void *GXGetTexObjUserData(const GXTexObj *obj);
void GXLoadTexObjPreLoaded(GXTexObj *obj, GXTexRegion *region, GXTexMapID id);
void GXLoadTexObj(GXTexObj *obj, GXTexMapID id);
void GXInitTlutObj(GXTlutObj *tlut_obj, void *lut, GXTlutFmt fmt, u16 n_entries);
void GXLoadTlut(GXTlutObj *tlut_obj, u32 tlut_name);
void GXInitTexCacheRegion(GXTexRegion *region, u8 is_32b_mipmap, u32 tmem_even, GXTexCacheSize size_even, u32 tmem_odd, GXTexCacheSize size_odd);
void GXInitTexPreLoadRegion(GXTexRegion *region, u32 tmem_even, u32 size_even, u32 tmem_odd, u32 size_odd);
void GXInitTlutRegion(GXTlutRegion *region, u32 tmem_addr, GXTlutSize tlut_size);
void GXInvalidateTexRegion(GXTexRegion *region);
void GXInvalidateTexAll(void);
GXTexRegionCallback GXSetTexRegionCallback(GXTexRegionCallback f);
GXTlutRegionCallback GXSetTlutRegionCallback(GXTlutRegionCallback f);
void GXPreLoadEntireTexture(GXTexObj *tex_obj, GXTexRegion *region);
void GXSetTexCoordScaleManually(GXTexCoordID coord, u8 enable, u16 ss, u16 ts);
void GXSetTexCoordCylWrap(GXTexCoordID coord, u8 s_enable, u8 t_enable);
void GXSetTexCoordBias(GXTexCoordID coord, u8 s_enable, u8 t_enable);
#ifdef __cplusplus
}
#endif