Files
ss/src/nw4r/g3d/platform/g3d_tmem.cpp
T
Elijah Thomas cec09ad023 g3d initial pullover (#115)
* g3d Headers

* initial g3d source files -- NOT YET FIXED

* change ResFile static_cast to explicit ctor
2025-02-09 12:40:41 -05:00

306 lines
12 KiB
C++

#include <nw4r/g3d.h>
// TODO: Naming
enum TMemCachePlan {
TMEM_CACHE_NONE,
TMEM_CACHE_PLAN_0,
TMEM_CACHE_PLAN_1,
TMEM_CACHE_PLAN_2,
TMEM_CACHE_MAX
};
enum TexRegionID {
TEX_REGION_DEFAULT,
TEX_REGION_DEFAULT_MIPMAP,
TEX_REGION_CI,
TEX_REGION_CI_MIPMAP,
TEX_REGION_RGBA8,
TEX_REGION_RGBA8_MIPMAP,
TEX_REGION_MAX
};
struct TexRegionAddr {
u32 addrDefaultEven[GX_MAX_TEXMAP]; // at 0x0
u32 addrDefaultMipMapEven[GX_MAX_TEXMAP]; // at 0x20
u32 addrDefaultMipMapOdd[GX_MAX_TEXMAP]; // at 0x40
u32 addrCiEven[GX_MAX_TEXMAP]; // at 0x60
u32 addrCiMipMapEven[GX_MAX_TEXMAP]; // at 0x80
u32 addrCiMipMapOdd[GX_MAX_TEXMAP]; // at 0xA0
u32 addrRgba8Even[GX_MAX_TEXMAP]; // at 0xC0
u32 addrRgba8Odd[GX_MAX_TEXMAP]; // at 0xE0
u32 addrRgba8MipMapEven[GX_MAX_TEXMAP]; // at 0x100
u32 addrRgba8MipMapOdd[GX_MAX_TEXMAP]; // at 0x120
};
struct TexRegionSize {
u32 sizeDefaultEven[GX_MAX_TEXMAP]; // at 0x0
u32 sizeDefaultMipMapEven[GX_MAX_TEXMAP]; // at 0x20
u32 sizeDefaultMipMapOdd[GX_MAX_TEXMAP]; // at 0x40
u32 sizeCiEven[GX_MAX_TEXMAP]; // at 0x60
u32 sizeCiMipMapEven[GX_MAX_TEXMAP]; // at 0x80
u32 sizeCiMipMapOdd[GX_MAX_TEXMAP]; // at 0xA0
u32 sizeRgba8Even[GX_MAX_TEXMAP]; // at 0xC0
u32 sizeRgba8Odd[GX_MAX_TEXMAP]; // at 0xE0
u32 sizeRgba8MipMapEven[GX_MAX_TEXMAP]; // at 0x100
u32 sizeRgba8MipMapOdd[GX_MAX_TEXMAP]; // at 0x120
};
static GXTexRegion saaTexRegion[TEX_REGION_MAX][GX_MAX_TEXMAP];
static GXTlutRegion saaTlutRegion[GX_BIGTLUT3 + 1];
static TMemCachePlan sTMemCachePlan = TMEM_CACHE_NONE;
static u32 sTlutRegionNum = 0;
static GXTexRegionCallback sfpDefaultTexRegionCallback = NULL;
static GXTlutRegionCallback sfpDefaultTlutRegionCallback = NULL;
// clang-format off
static const TexRegionAddr scaaaTexRegionAddr[TMEM_CACHE_MAX - 1] = {
// TMEM_CACHE_PLAN_0
{
{0x00000, 0x40000, 0x50000, 0x60000, 0x70000, 0x30000, 0x20000, 0x10000}, // addrDefaultEven
{0x00000, 0xB0000, 0x50000, 0x90000, 0x70000, 0xB0000, 0x20000, 0x90000}, // addrDefaultMipMapEven
{0x80000, 0x40000, 0xA0000, 0x60000, 0x80000, 0x30000, 0xA0000, 0x10000}, // addrDefaultMipMapOdd
{0x00000, 0x40000, 0x50000, 0x60000, 0x70000, 0x30000, 0x20000, 0x10000}, // addrCiEven
{0x00000, 0x40000, 0x50000, 0x60000, 0x70000, 0x30000, 0x20000, 0x10000}, // addrCiMipMapEven
{0x20000, 0x48000, 0x58000, 0x68000, 0x78000, 0x38000, 0x28000, 0x18000}, // addrCiMipMapOdd
{0x00000, 0xB0000, 0x50000, 0x90000, 0x70000, 0xB0000, 0x20000, 0x90000}, // addrRgba8Even
{0x80000, 0x40000, 0xA0000, 0x60000, 0x80000, 0x30000, 0xA0000, 0x10000}, // addrRgba8Odd
{0x00000, 0xB0000, 0x50000, 0x90000, 0x70000, 0xB0000, 0x20000, 0x90000}, // addrRgba8MipMapEven
{0x80000, 0x40000, 0xA0000, 0x60000, 0x80000, 0x30000, 0xA0000, 0x10000}, // addrRgba8MipMapOdd
},
// TMEM_CACHE_PLAN_1
{
{0x00000, 0x40000, 0x50000, 0x60000, 0x70000, 0x78000, 0x68000, 0x58000}, // addrDefaultEven
{0x00000, 0xC0000, 0x50000, 0xE0000, 0x70000, 0xD8000, 0x68000, 0xB8000}, // addrDefaultMipMapEven
{0x80000, 0x40000, 0xA0000, 0x60000, 0x80000, 0x30000, 0xA0000, 0x10000}, // addrDefaultMipMapOdd
{0x00000, 0x40000, 0x50000, 0x60000, 0x70000, 0x78000, 0x68000, 0x58000}, // addrCiEven
{0x00000, 0x40000, 0x50000, 0x60000, 0x70000, 0x70000, 0x60000, 0x50000}, // addrCiMipMapEven
{0x20000, 0x48000, 0x58000, 0x68000, 0x78000, 0x78000, 0x68000, 0x58000}, // addrCiMipMapOdd
{0x00000, 0xC0000, 0x50000, 0xE0000, 0x70000, 0xD8000, 0x68000, 0xB8000}, // addrRgba8Even
{0x80000, 0x40000, 0xD0000, 0x60000, 0xE8000, 0x78000, 0xC8000, 0x58000}, // addrRgba8Odd
{0x00000, 0xC0000, 0x50000, 0xE0000, 0x70000, 0xD0000, 0x60000, 0xB0000}, // addrRgba8MipMapEven
{0x80000, 0x40000, 0xD0000, 0x60000, 0xE0000, 0x70000, 0xC0000, 0x50000}, // addrRgba8MipMapOdd
},
// TMEM_CACHE_PLAN_2
{
{0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000}, // addrDefaultEven
{0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000}, // addrDefaultMipMapEven
{0x80000, 0xC0000, 0xC8000, 0xD0000, 0xD0000, 0xC8000, 0xC0000, 0xB0000}, // addrDefaultMipMapOdd
{0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000}, // addrCiEven
{0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000}, // addrCiMipMapEven
{0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000}, // addrCiMipMapOdd
{0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000}, // addrRgba8Even
{0x80000, 0xC0000, 0xC8000, 0xD0000, 0xD0000, 0xC8000, 0xC0000, 0xB0000}, // addrRgba8Odd
{0x00000, 0x40000, 0x40000, 0x40000, 0x40000, 0x40000, 0x40000, 0x00000}, // addrRgba8MipMapEven
{0x80000, 0xC0000, 0xD0000, 0xE0000, 0xE0000, 0xD0000, 0xC0000, 0xB0000}, // addrRgba8MipMapOdd
},
};
// clang-format on
// clang-format off
static const TexRegionSize scaaaTexRegionSize[TMEM_CACHE_MAX - 1] = {
// TMEM_CACHE_PLAN_0
{
{1, 0, 0, 0, 0, 0, 0, 0}, // sizeDefaultEven
{1, 0, 0, 0, 0, 0, 0, 0}, // sizeDefaultMipMapEven
{1, 0, 0, 0, 0, 0, 0, 0}, // sizeDefaultMipMapOdd
{1, 0, 0, 0, 0, 0, 0, 0}, // sizeCiEven
{1, 0, 0, 0, 0, 0, 0, 0}, // sizeCiMipMapEven
{1, 0, 0, 0, 0, 0, 0, 0}, // sizeCiMipMapOdd
{1, 0, 0, 0, 0, 0, 0, 0}, // sizeRgba8Even
{1, 0, 0, 0, 0, 0, 0, 0}, // sizeRgba8Odd
{1, 0, 0, 0, 0, 0, 0, 0}, // sizeRgba8MipMapEven
{1, 0, 0, 0, 0, 0, 0, 0}, // sizeRgba8MipMapOdd
},
// TMEM_CACHE_PLAN_1
{
{1, 0, 0, 0, 0, 0, 0, 0}, // sizeDefaultEven
{1, 0, 0, 0, 0, 0, 0, 0}, // sizeDefaultMipMapEven
{1, 0, 0, 0, 0, 0, 0, 0}, // sizeDefaultMipMapOdd
{1, 0, 0, 0, 0, 0, 0, 0}, // sizeCiEven
{1, 0, 0, 0, 0, 0, 0, 0}, // sizeCiMipMapEven
{1, 0, 0, 0, 0, 0, 0, 0}, // sizeCiMipMapOdd
{1, 0, 0, 0, 0, 0, 0, 0}, // sizeRgba8Even
{1, 0, 0, 0, 0, 0, 0, 0}, // sizeRgba8Odd
{1, 0, 0, 0, 0, 0, 0, 0}, // sizeRgba8MipMapEven
{1, 0, 0, 0, 0, 0, 0, 0}, // sizeRgba8MipMapOdd
},
// TMEM_CACHE_PLAN_2
{
{2, 2, 2, 2, 2, 2, 2, 2}, // sizeDefaultEven
{2, 2, 2, 2, 2, 2, 2, 2}, // sizeDefaultMipMapEven
{1, 1, 1, 1, 1, 1, 0, 0}, // sizeDefaultMipMapOdd
{2, 2, 2, 2, 2, 2, 2, 2}, // sizeCiEven
{2, 2, 2, 2, 2, 2, 2, 2}, // sizeCiMipMapEven
{1, 1, 1, 1, 1, 1, 0, 0}, // sizeCiMipMapOdd
{2, 2, 2, 2, 2, 2, 2, 2}, // sizeRgba8Even
{1, 1, 1, 1, 1, 1, 0, 0}, // sizeRgba8Odd
{1, 1, 1, 1, 1, 1, 1, 1}, // sizeRgba8MipMapEven
{1, 0, 0, 0, 0, 0, 0, 0}, // sizeRgba8MipMapOdd
},
};
// clang-format on
// Forward declarations
static GXTexRegion *TexRegionCallback(const GXTexObj *pObj, GXTexMapID map);
static GXTlutRegion *TlutRegionCallback(u32 id);
static void setTexRegion_(TMemCachePlan plan) __attribute__((never_inline));
namespace nw4r {
namespace g3d {
namespace tmem {
void SetTMemLayout(TMemLayout layout) {
if (sfpDefaultTexRegionCallback == NULL) {
// clang-format off
sfpDefaultTexRegionCallback = GXSetTexRegionCallback(TexRegionCallback);
GXSetTexRegionCallback(sfpDefaultTexRegionCallback);
sfpDefaultTlutRegionCallback = GXSetTlutRegionCallback(TlutRegionCallback);
GXSetTlutRegionCallback(sfpDefaultTlutRegionCallback);
// clang-format on
}
if (sfpDefaultTexRegionCallback == NULL) {
return;
}
sTMemCachePlan = static_cast<TMemCachePlan>(layout);
setTexRegion_(sTMemCachePlan);
switch (layout) {
case TMEM_LAYOUT_NONE:
case TMEM_LAYOUT_1: {
GXSetTlutRegionCallback(sfpDefaultTlutRegionCallback);
break;
}
case TMEM_LAYOUT_2: {
int i;
u32 num = 0;
u32 addr;
GXTlutRegion *pRegion = saaTlutRegion;
for (i = 0, addr = 0xF0000; i < GX_MAX_TEXMAP; i++, pRegion++, num++, addr += 0x2000) {
GXInitTlutRegion(pRegion, addr, 16);
}
sTlutRegionNum = num;
GXSetTlutRegionCallback(TlutRegionCallback);
break;
}
// TODO: Seems to imply no TMEM_LAYOUT_3 exists. Then why the [plan - 1]?
default: {
break;
}
}
}
} // namespace tmem
} // namespace g3d
} // namespace nw4r
static GXTexRegion *TexRegionCallback(const GXTexObj *pObj, GXTexMapID map) {
GXTexFmt fmt = GXGetTexObjFormat(pObj);
GXBool mipmap = GXGetTexObjMipMap(pObj);
switch (fmt) {
case GX_TF_RGBA8: {
return mipmap ? &saaTexRegion[TEX_REGION_RGBA8_MIPMAP][map] : &saaTexRegion[TEX_REGION_RGBA8][map];
}
case GX_TF_C4:
case GX_TF_C8:
case GX_TF_C14X2: {
return mipmap ? &saaTexRegion[TEX_REGION_CI_MIPMAP][map] : &saaTexRegion[TEX_REGION_CI][map];
}
default: {
return mipmap ? &saaTexRegion[TEX_REGION_DEFAULT_MIPMAP][map] : &saaTexRegion[TEX_REGION_DEFAULT][map];
}
}
}
static GXTlutRegion *TlutRegionCallback(u32 id) {
GXTlutRegion *pRegion = NULL;
if (id < sTlutRegionNum) {
pRegion = &saaTlutRegion[id];
}
return pRegion;
}
static void setTexRegion_(TMemCachePlan plan) {
if (plan == TMEM_CACHE_NONE) {
GXSetTexRegionCallback(sfpDefaultTexRegionCallback);
return;
}
for (int i = 0; i < GX_MAX_TEXMAP; i++) {
// clang-format off
GXInitTexCacheRegion(
&saaTexRegion[TEX_REGION_DEFAULT][i],
FALSE,
scaaaTexRegionAddr[plan - 1].addrDefaultEven[i],
scaaaTexRegionSize[plan - 1].sizeDefaultEven[i],
NULL,
3);
GXInitTexCacheRegion(
&saaTexRegion[TEX_REGION_DEFAULT_MIPMAP][i],
FALSE,
scaaaTexRegionAddr[plan - 1].addrDefaultMipMapEven[i],
scaaaTexRegionSize[plan - 1].sizeDefaultMipMapEven[i],
scaaaTexRegionAddr[plan - 1].addrDefaultMipMapOdd[i],
scaaaTexRegionSize[plan - 1].sizeDefaultMipMapOdd[i]);
GXInitTexCacheRegion(
&saaTexRegion[TEX_REGION_CI][i],
FALSE,
scaaaTexRegionAddr[plan - 1].addrCiEven[i],
scaaaTexRegionSize[plan - 1].sizeCiEven[i],
NULL,
3);
GXInitTexCacheRegion(
&saaTexRegion[TEX_REGION_CI_MIPMAP][i],
FALSE,
scaaaTexRegionAddr[plan - 1].addrCiMipMapEven[i],
scaaaTexRegionSize[plan - 1].sizeCiMipMapEven[i],
scaaaTexRegionAddr[plan - 1].addrCiMipMapOdd[i],
scaaaTexRegionSize[plan - 1].sizeCiMipMapOdd[i]);
GXInitTexCacheRegion(
&saaTexRegion[TEX_REGION_RGBA8][i],
FALSE,
scaaaTexRegionAddr[plan - 1].addrRgba8Even[i],
scaaaTexRegionSize[plan - 1].sizeRgba8Even[i],
scaaaTexRegionAddr[plan - 1].addrRgba8Odd[i],
scaaaTexRegionSize[plan - 1].sizeRgba8Odd[i]);
GXInitTexCacheRegion(
&saaTexRegion[TEX_REGION_RGBA8_MIPMAP][i],
FALSE,
scaaaTexRegionAddr[plan - 1].addrRgba8MipMapEven[i],
scaaaTexRegionSize[plan - 1].sizeRgba8MipMapEven[i],
scaaaTexRegionAddr[plan - 1].addrRgba8MipMapOdd[i],
scaaaTexRegionSize[plan - 1].sizeRgba8MipMapOdd[i]);
// clang-format on
}
GXSetTexRegionCallback(TexRegionCallback);
}