DolphinCGraphics inches closer

Former-commit-id: 64a23c22cc
This commit is contained in:
Luke Street 2022-12-02 00:19:15 -05:00
parent 2e5ef5051a
commit 4e0dfde249
4 changed files with 299 additions and 24 deletions

View File

@ -1626,7 +1626,6 @@ FullRender__9CGraphicsFv:
/* 8030A4C0 00307420 7C 03 00 2E */ lwzx r0, r3, r0
/* 8030A4C4 00307424 7C 09 03 A6 */ mtctr r0
/* 8030A4C8 00307428 4E 80 04 20 */ bctr
.global lbl_8030A4CC
lbl_8030A4CC:
/* 8030A4CC 0030742C 80 CD A7 FC */ lwz r6, mNumPrimitives__9CGraphics@sda21(r13)
/* 8030A4D0 00307430 38 E0 00 00 */ li r7, 0
@ -1713,7 +1712,6 @@ lbl_8030A5F0:
/* 8030A608 00307568 D0 23 80 00 */ stfs f1, 0xCC008000@l(r3)
/* 8030A60C 0030756C 42 00 FF E4 */ bdnz lbl_8030A5F0
/* 8030A610 00307570 48 00 08 AC */ b lbl_8030AEBC
.global lbl_8030A614
lbl_8030A614:
/* 8030A614 00307574 80 0D A7 FC */ lwz r0, mNumPrimitives__9CGraphics@sda21(r13)
/* 8030A618 00307578 3C 80 CC 01 */ lis r4, 0xcc01
@ -1798,7 +1796,6 @@ lbl_8030A714:
/* 8030A748 003076A8 D0 44 80 00 */ stfs f2, 0xCC008000@l(r4)
/* 8030A74C 003076AC 42 00 FF C8 */ bdnz lbl_8030A714
/* 8030A750 003076B0 48 00 07 6C */ b lbl_8030AEBC
.global lbl_8030A754
lbl_8030A754:
/* 8030A754 003076B4 80 ED A7 FC */ lwz r7, mNumPrimitives__9CGraphics@sda21(r13)
/* 8030A758 003076B8 39 00 00 00 */ li r8, 0
@ -1909,7 +1906,6 @@ lbl_8030A8CC:
/* 8030A8F0 00307850 90 03 80 00 */ stw r0, 0xCC008000@l(r3)
/* 8030A8F4 00307854 42 00 FF D8 */ bdnz lbl_8030A8CC
/* 8030A8F8 00307858 48 00 05 C4 */ b lbl_8030AEBC
.global lbl_8030A8FC
lbl_8030A8FC:
/* 8030A8FC 0030785C 80 0D A7 FC */ lwz r0, mNumPrimitives__9CGraphics@sda21(r13)
/* 8030A900 00307860 3C 80 CC 01 */ lis r4, 0xcc01
@ -1984,7 +1980,6 @@ lbl_8030A9DC:
/* 8030AA08 00307968 D0 24 80 00 */ stfs f1, 0xCC008000@l(r4)
/* 8030AA0C 0030796C 42 00 FF D0 */ bdnz lbl_8030A9DC
/* 8030AA10 00307970 48 00 04 AC */ b lbl_8030AEBC
.global lbl_8030AA14
lbl_8030AA14:
/* 8030AA14 00307974 80 0D A7 FC */ lwz r0, mNumPrimitives__9CGraphics@sda21(r13)
/* 8030AA18 00307978 3C 80 CC 01 */ lis r4, 0xcc01
@ -2060,7 +2055,6 @@ lbl_8030AADC:
/* 8030AB24 00307A84 D0 24 80 00 */ stfs f1, 0xCC008000@l(r4)
/* 8030AB28 00307A88 42 00 FF B4 */ bdnz lbl_8030AADC
/* 8030AB2C 00307A8C 48 00 03 90 */ b lbl_8030AEBC
.global lbl_8030AB30
lbl_8030AB30:
/* 8030AB30 00307A90 80 0D A7 FC */ lwz r0, mNumPrimitives__9CGraphics@sda21(r13)
/* 8030AB34 00307A94 3C 80 CC 01 */ lis r4, 0xcc01
@ -2130,7 +2124,6 @@ lbl_8030ABE8:
/* 8030AC28 00307B88 90 04 80 00 */ stw r0, 0xCC008000@l(r4)
/* 8030AC2C 00307B8C 42 00 FF BC */ bdnz lbl_8030ABE8
/* 8030AC30 00307B90 48 00 02 8C */ b lbl_8030AEBC
.global lbl_8030AC34
lbl_8030AC34:
/* 8030AC34 00307B94 80 0D A7 FC */ lwz r0, mNumPrimitives__9CGraphics@sda21(r13)
/* 8030AC38 00307B98 3C 80 CC 01 */ lis r4, 0xcc01
@ -2218,7 +2211,6 @@ lbl_8030AD3C:
/* 8030AD74 00307CD4 D0 24 80 00 */ stfs f1, 0xCC008000@l(r4)
/* 8030AD78 00307CD8 42 00 FF C4 */ bdnz lbl_8030AD3C
/* 8030AD7C 00307CDC 48 00 01 40 */ b lbl_8030AEBC
.global lbl_8030AD80
lbl_8030AD80:
/* 8030AD80 00307CE0 80 0D A7 FC */ lwz r0, mNumPrimitives__9CGraphics@sda21(r13)
/* 8030AD84 00307CE4 3C 80 CC 01 */ lis r4, 0xcc01

View File

@ -149,6 +149,15 @@ enum ERglLight {
kLightMax,
};
enum ERglTexOffset {
kTO_Zero = GX_TO_ZERO,
kTO_Sixteenth = GX_TO_SIXTEENTH,
kTO_Eighth = GX_TO_EIGHTH,
kTO_Fourth = GX_TO_FOURTH,
kTO_Half = GX_TO_HALF,
kTO_One = GX_TO_ONE,
};
struct CViewport {
int mLeft;
int mTop;
@ -222,6 +231,7 @@ public:
static void SetLightState(uchar lights);
static void SetViewMatrix();
static void SetScissor(int left, int bottom, int width, int height);
static void SetLineWidth(float w, ERglTexOffset offs);
static void ClearBackAndDepthBuffers();
static void SetIdentityViewPointMatrix();
@ -247,13 +257,14 @@ public:
static void SetTevOp(ERglTevStage stage, const CTevCombiners::CTevPass& pass);
static void StreamBegin(ERglPrimitive primitive);
static void StreamColor(uint color);
static void StreamColor(float, float, float, float);
static void StreamColor(float r, float g, float b, float a);
static void StreamColor(const CColor& color);
static void StreamTexcoord(float u, float v);
static void StreamVertex(float, float, float);
static void StreamTexcoord(const CVector2f& uv);
static void StreamVertex(float x, float y, float z);
static void StreamVertex(const CVector3f& vtx);
static void StreamVertex(const float*);
static void StreamNormal(const float*);
static void StreamVertex(const float* vtx);
static void StreamNormal(const float* nrm);
static void StreamEnd();
static void Render2D(const CTexture& tex, int x, int y, int w, int h, const CColor& col);
static void DrawPrimitive(ERglPrimitive primitive, const float* pos, const CVector3f& normal, const CColor& col, int numVerts);
@ -301,12 +312,17 @@ public:
static CTevCombiners::CTevPass kEnvModulateColorByAlpha;
private:
static void UpdateVertexDataStream();
static void ResetVertexDataStream(bool initial);
static void FlushStream();
static void FullRender();
static CRenderState sRenderState;
static VecPtr vtxBuffer;
static VecPtr nrmBuffer;
static Vec2Ptr txtBuffer0;
static Vec2Ptr txtBuffer1;
static GXColor* clrBuffer;
static uint* clrBuffer;
static bool mJustReset;
static ERglCullMode mCullMode;
static int mNumLightsActive;
@ -315,7 +331,7 @@ private:
static VecPtr mpNrmBuffer;
static Vec2Ptr mpTxtBuffer0;
static Vec2Ptr mpTxtBuffer1;
static GXColor* mpClrBuffer;
static uint* mpClrBuffer;
static int mNumPrimitives;
static int mFrameCounter;
static float mFramesPerSecond;

View File

@ -18,6 +18,7 @@ void ICInvalidateRange(void* addr, u32 nBytes);
#define LC_BASE_PREFIX 0xE000
#define LC_BASE (LC_BASE_PREFIX << 16)
#define LCGetBase() ((void*)LC_BASE)
void LCEnable();
void LCDisable(void);

View File

@ -10,6 +10,8 @@
#include "dolphin/vi.h"
#include <string.h>
bool CGraphicsSys::mGraphicsInitialized;
static CStopwatch sFPSTimer;
static uchar sSpareFrameBuffer[640 * 448];
@ -162,7 +164,7 @@ VecPtr CGraphics::vtxBuffer;
VecPtr CGraphics::nrmBuffer;
Vec2Ptr CGraphics::txtBuffer0;
Vec2Ptr CGraphics::txtBuffer1;
GXColor* CGraphics::clrBuffer;
uint* CGraphics::clrBuffer;
bool CGraphics::mJustReset;
ERglCullMode CGraphics::mCullMode;
int CGraphics::mNumLightsActive;
@ -171,7 +173,7 @@ VecPtr CGraphics::mpVtxBuffer;
VecPtr CGraphics::mpNrmBuffer;
Vec2Ptr CGraphics::mpTxtBuffer0;
Vec2Ptr CGraphics::mpTxtBuffer1;
GXColor* CGraphics::mpClrBuffer;
uint* CGraphics::mpClrBuffer;
struct CGXLightParams {
int x0_;
@ -187,11 +189,10 @@ CGXLightParams mLightParams[8];
struct {
Vec vtx;
Vec nrm;
float uvU, uvV;
int unk0;
int unk1;
GXColor color;
short textureUsed;
Vec2 uv0;
Vec2 uv1;
uint color;
ushort textureUsed;
uchar streamFlags;
} vtxDescr;
@ -354,7 +355,7 @@ void CGraphics::ConfigureFrameBuffer(const COsContext& osContext) {
GXSetDispCopyDst(mRenderModeObj.fbWidth, mRenderModeObj.efbHeight);
GXSetDispCopyYScale(static_cast< float >(mRenderModeObj.xfbHeight) /
static_cast< float >(mRenderModeObj.efbHeight));
GXSetCopyFilter(mRenderModeObj.aa, mRenderModeObj.sample_pattern, GX_TRUE,
GXSetCopyFilter(mRenderModeObj.aa, mRenderModeObj.sample_pattern, GX_ENABLE,
mRenderModeObj.vfilter);
if (mRenderModeObj.aa) {
GXSetPixelFmt(GX_PF_RGB565_Z16, GX_ZC_LINEAR);
@ -487,7 +488,7 @@ void CGraphics::SetLightState(uchar lights) {
if (lights != 0) {
diffFn = GX_DF_CLAMP;
}
CGX::SetChanCtrl(CGX::Channel0, lights != 0 ? GX_TRUE : GX_FALSE, GX_SRC_REG,
CGX::SetChanCtrl(CGX::Channel0, lights != 0 ? GX_ENABLE : GX_DISABLE, GX_SRC_REG,
(vtxDescr.streamFlags & 2) != 0 ? GX_SRC_VTX : GX_SRC_REG,
static_cast< GXLightID >(lights), diffFn, attnFn);
mLightActive = lights;
@ -754,7 +755,7 @@ void CGraphics::EndScene() {
GXSetCopyFilter(mRenderModeObj.aa, mRenderModeObj.sample_pattern, true, vfilter);
GXCopyDisp(frameBuf, mIsBeginSceneClearFb ? GX_TRUE : GX_FALSE);
GXSetCopyFilter(mRenderModeObj.aa, mRenderModeObj.sample_pattern,
mUseVideoFilter ? GX_TRUE : GX_FALSE, mRenderModeObj.vfilter);
mUseVideoFilter ? GX_ENABLE : GX_DISABLE, mRenderModeObj.vfilter);
GXSetBreakPtCallback(SwapBuffers);
VISetPreRetraceCallback(VideoPreCallback);
VISetPostRetraceCallback(VideoPostCallback);
@ -864,3 +865,268 @@ void CGraphics::DrawPrimitive(ERglPrimitive primitive, const float* pos, const C
}
StreamEnd();
}
#define STREAM_PRIM_BUFFER_SIZE 240
#define VTX_BUFFER_ADDR LC_BASE
#if NONMATCHING
// Bug fix: these should be 3 times larger to avoid overflow
// Likely the result of bad pointer arithmetic
#define NRM_BUFFER_ADDR (VTX_BUFFER_ADDR + ((STREAM_PRIM_BUFFER_SIZE + 1) * sizeof(Vec)))
#define TXT0_BUFFER_ADDR (NRM_BUFFER_ADDR + ((STREAM_PRIM_BUFFER_SIZE + 1) * sizeof(Vec)))
#else
#define NRM_BUFFER_ADDR (VTX_BUFFER_ADDR + ((STREAM_PRIM_BUFFER_SIZE + 1) * sizeof(float)))
#define TXT0_BUFFER_ADDR (NRM_BUFFER_ADDR + ((STREAM_PRIM_BUFFER_SIZE + 1) * sizeof(float)))
#endif
#define TXT1_BUFFER_ADDR (TXT0_BUFFER_ADDR + ((STREAM_PRIM_BUFFER_SIZE + 1) * sizeof(Vec2)))
#define CLR_BUFFER_ADDR (TXT1_BUFFER_ADDR + ((STREAM_PRIM_BUFFER_SIZE + 1) * sizeof(Vec2)))
static const uchar kHasNormals = 1;
static const uchar kHasColor = 2;
static const uchar kHasTexture = 4;
void CGraphics::StreamBegin(ERglPrimitive primitive) {
vtxBuffer = reinterpret_cast< VecPtr >(VTX_BUFFER_ADDR);
nrmBuffer = reinterpret_cast< VecPtr >(NRM_BUFFER_ADDR);
txtBuffer0 = reinterpret_cast< Vec2Ptr >(TXT0_BUFFER_ADDR);
txtBuffer1 = reinterpret_cast< Vec2Ptr >(TXT1_BUFFER_ADDR);
clrBuffer = reinterpret_cast< uint* >(CLR_BUFFER_ADDR);
ResetVertexDataStream(true);
mCurrentPrimitive = primitive;
vtxDescr.streamFlags = kHasColor;
}
void CGraphics::StreamVertex(float x, float y, float z) {
vtxDescr.vtx.x = x;
vtxDescr.vtx.y = y;
vtxDescr.vtx.z = z;
UpdateVertexDataStream();
}
void CGraphics::StreamVertex(const float* vtx) {
vtxDescr.vtx.x = vtx[0];
vtxDescr.vtx.y = vtx[1];
vtxDescr.vtx.z = vtx[2];
UpdateVertexDataStream();
}
void CGraphics::StreamVertex(const CVector3f& vtx) {
vtxDescr.vtx.x = vtx.GetX();
vtxDescr.vtx.y = vtx.GetY();
vtxDescr.vtx.z = vtx.GetZ();
UpdateVertexDataStream();
}
void CGraphics::StreamNormal(const float* nrm) {
vtxDescr.nrm.x = nrm[0];
vtxDescr.nrm.y = nrm[1];
vtxDescr.nrm.z = nrm[2];
vtxDescr.streamFlags |= kHasNormals;
}
void CGraphics::StreamColor(uint color) {
vtxDescr.color = color;
vtxDescr.streamFlags |= kHasColor;
}
void CGraphics::StreamColor(const CColor& color) {
vtxDescr.color = color.GetColor_u32();
vtxDescr.streamFlags |= kHasColor;
}
void CGraphics::StreamColor(float r, float g, float b, float a) {
// clang-format off
vtxDescr.color = (static_cast< uchar >(r * 255.f) << 24) |
(static_cast< uchar >(g * 255.f) << 16) |
(static_cast< uchar >(b * 255.f) << 8) |
static_cast< uchar >(a * 255.f);
// clang-format on
vtxDescr.streamFlags |= kHasColor;
}
void CGraphics::StreamTexcoord(const CVector2f& uv) {
vtxDescr.uv0.x = uv.GetX();
vtxDescr.uv0.y = uv.GetY();
vtxDescr.streamFlags |= kHasTexture;
vtxDescr.textureUsed |= 1;
}
void CGraphics::StreamTexcoord(float u, float v) {
vtxDescr.uv0.x = u;
vtxDescr.uv0.y = v;
vtxDescr.streamFlags |= kHasTexture;
vtxDescr.textureUsed |= 1;
}
void CGraphics::StreamEnd() {
if (mNumPrimitives != 0) {
FlushStream();
}
vtxBuffer = nullptr;
vtxDescr.streamFlags = 0;
vtxDescr.textureUsed = 0;
nrmBuffer = nullptr;
txtBuffer0 = nullptr;
txtBuffer1 = nullptr;
clrBuffer = nullptr;
}
void CGraphics::SetLineWidth(float w, ERglTexOffset offs) {
CGX::SetLineWidth(static_cast< uchar >(w * 6.f), static_cast< GXTexOffset >(offs));
}
void CGraphics::UpdateVertexDataStream() {
++mNumPrimitives;
mpVtxBuffer->x = vtxDescr.vtx.x;
mpVtxBuffer->y = vtxDescr.vtx.y;
mpVtxBuffer->z = vtxDescr.vtx.z;
++mpVtxBuffer;
if ((vtxDescr.streamFlags & kHasNormals) != 0) {
mpNrmBuffer->x = vtxDescr.nrm.x;
mpNrmBuffer->y = vtxDescr.nrm.y;
mpNrmBuffer->z = vtxDescr.nrm.z;
++mpNrmBuffer;
}
if ((vtxDescr.streamFlags & kHasTexture) != 0) {
mpTxtBuffer0->x = vtxDescr.uv0.x;
mpTxtBuffer0->y = vtxDescr.uv0.y;
++mpTxtBuffer0;
mpTxtBuffer1->x = vtxDescr.uv1.x;
mpTxtBuffer1->y = vtxDescr.uv1.y;
++mpTxtBuffer1;
}
if ((vtxDescr.streamFlags & kHasColor) != 0) {
*mpClrBuffer = vtxDescr.color;
++mpClrBuffer;
}
mJustReset = 0;
if (mNumPrimitives == STREAM_PRIM_BUFFER_SIZE) {
FlushStream();
ResetVertexDataStream(false);
}
}
void CGraphics::ResetVertexDataStream(bool initial) {
mpVtxBuffer = vtxBuffer;
mpNrmBuffer = nrmBuffer;
mpTxtBuffer0 = txtBuffer0;
mpTxtBuffer1 = txtBuffer1;
mpClrBuffer = clrBuffer;
mNumPrimitives = 0;
if (initial) {
return;
}
switch (mCurrentPrimitive) {
case kP_TriangleFan:
mpVtxBuffer = vtxBuffer + 1;
memcpy(mpVtxBuffer, &vtxDescr.vtx, sizeof(Vec));
++mpVtxBuffer;
if ((vtxDescr.streamFlags & kHasNormals) != 0) {
++mpNrmBuffer;
memcpy(mpNrmBuffer, &vtxDescr.nrm, sizeof(Vec));
++mpNrmBuffer;
}
if ((vtxDescr.streamFlags & kHasTexture) != 0) {
++mpTxtBuffer0;
memcpy(mpTxtBuffer0, &vtxDescr.uv0, sizeof(Vec2));
++mpTxtBuffer0;
++mpTxtBuffer1;
memcpy(mpTxtBuffer1, &vtxDescr.uv1, sizeof(Vec2));
++mpTxtBuffer1;
}
if ((vtxDescr.streamFlags & kHasColor) != 0) {
++mpClrBuffer;
*mpClrBuffer = vtxDescr.color;
++mpClrBuffer;
}
mNumPrimitives += 2;
break;
default:
break;
}
mJustReset = 1;
}
void CGraphics::FlushStream() {
GXVtxDescList vtxDesc[10];
GXVtxDescList* curDesc = vtxDesc;
const GXVtxDescList vtxDescPos = {GX_VA_POS, GX_DIRECT};
*curDesc++ = vtxDescPos;
if ((vtxDescr.streamFlags & kHasNormals) != 0) {
const GXVtxDescList vtxDescNrm = {GX_VA_CLR0, GX_DIRECT};
*curDesc++ = vtxDescNrm;
}
if ((vtxDescr.streamFlags & kHasColor) != 0) {
const GXVtxDescList vtxDescClr0 = {GX_VA_CLR0, GX_DIRECT};
*curDesc++ = vtxDescClr0;
}
if ((vtxDescr.streamFlags & kHasTexture) != 0) {
const GXVtxDescList vtxDescTex0 = {GX_VA_TEX0, GX_DIRECT};
*curDesc++ = vtxDescTex0;
}
const GXVtxDescList vtxDescNull = {GX_VA_NULL, GX_NONE};
*curDesc = vtxDescNull;
CGX::SetVtxDescv(vtxDesc);
SetTevStates(vtxDescr.streamFlags);
FullRender();
}
void CGraphics::SetTevStates(uchar flags) {
switch (flags) {
case 0:
case kHasNormals:
case kHasColor:
case kHasNormals | kHasColor:
CGX::SetNumChans(1);
CGX::SetNumTexGens(0);
CGX::SetNumTevStages(1);
CGX::SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
CGX::SetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
break;
case kHasTexture:
case kHasNormals | kHasTexture:
case kHasColor | kHasTexture:
case kHasNormals | kHasColor | kHasTexture:
CGX::SetNumChans(1);
if ((vtxDescr.textureUsed & 3) != 0) {
CGX::SetNumTexGens(2);
} else {
CGX::SetNumTexGens(1);
}
CGX::SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
CGX::SetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP1, GX_COLOR0A0);
break;
}
CGX::SetNumIndStages(0);
CGX::SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, false, GX_PTIDENTITY);
CGX::SetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX1, GX_IDENTITY, false, GX_PTIDENTITY);
uint light = mLightActive;
GXAttnFn attnFn = GX_AF_NONE;
if (light != 0) {
attnFn = GX_AF_SPOT;
}
GXDiffuseFn diffFn = GX_DF_NONE;
if (light != 0) {
diffFn = GX_DF_CLAMP;
}
CGX::SetChanCtrl(CGX::Channel0, light ? GX_ENABLE : GX_DISABLE, GX_SRC_REG,
(flags & kHasColor) ? GX_SRC_VTX : GX_SRC_REG, static_cast< GXLightID >(light),
diffFn, attnFn);
}