mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-25 23:29:55 -06:00
Refactor the GPU to be object-oriented (#1873)
* Refactor GPU3D to be an object - Who has two thumbs and is the sworn enemy of global state? This guy! * Refactor GPU itself to be an object - Wow, it's used in a lot of places - Also introduce a new `Melon` namespace for a few classes - I expect other classes will be moved into `Melon` over time * Change signature of Renderer3D::SetRenderSettings - Make it noexcept, and its argument const * Remove some stray whitespace
This commit is contained in:

committed by
GitHub

parent
88072a02c5
commit
4558be0d8e
276
src/GPU3D.h
276
src/GPU3D.h
@ -22,8 +22,13 @@
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
#include "GPU.h"
|
||||
#include "Savestate.h"
|
||||
#include "FIFO.h"
|
||||
|
||||
namespace Melon
|
||||
{
|
||||
struct RenderSettings;
|
||||
}
|
||||
|
||||
namespace GPU3D
|
||||
{
|
||||
@ -79,60 +84,246 @@ struct Polygon
|
||||
|
||||
};
|
||||
|
||||
extern u32 RenderDispCnt;
|
||||
extern u8 RenderAlphaRef;
|
||||
class Renderer3D;
|
||||
|
||||
extern u16 RenderToonTable[32];
|
||||
extern u16 RenderEdgeTable[8];
|
||||
class GPU3D
|
||||
{
|
||||
public:
|
||||
GPU3D() noexcept = default;
|
||||
~GPU3D() noexcept = default;
|
||||
void Reset() noexcept;
|
||||
|
||||
extern u32 RenderFogColor, RenderFogOffset, RenderFogShift;
|
||||
extern u8 RenderFogDensityTable[34];
|
||||
void DoSavestate(Savestate* file) noexcept;
|
||||
|
||||
extern u32 RenderClearAttr1, RenderClearAttr2;
|
||||
void SetEnabled(bool geometry, bool rendering) noexcept;
|
||||
|
||||
extern bool RenderFrameIdentical;
|
||||
void ExecuteCommand() noexcept;
|
||||
|
||||
extern u16 RenderXPos;
|
||||
s32 CyclesToRunFor() const noexcept;
|
||||
void Run() noexcept;
|
||||
void CheckFIFOIRQ() noexcept;
|
||||
void CheckFIFODMA() noexcept;
|
||||
|
||||
extern std::array<Polygon*,2048> RenderPolygonRAM;
|
||||
extern u32 RenderNumPolygons;
|
||||
void VCount144() noexcept;
|
||||
void VBlank() noexcept;
|
||||
void VCount215() noexcept;
|
||||
|
||||
extern bool AbortFrame;
|
||||
void RestartFrame() noexcept;
|
||||
|
||||
extern u64 Timestamp;
|
||||
void SetRenderXPos(u16 xpos) noexcept;
|
||||
[[nodiscard]] u16 GetRenderXPos() const noexcept { return RenderXPos; }
|
||||
u32* GetLine(int line) noexcept;
|
||||
|
||||
bool Init();
|
||||
void DeInit();
|
||||
void Reset();
|
||||
void WriteToGXFIFO(u32 val) noexcept;
|
||||
|
||||
void DoSavestate(Savestate* file);
|
||||
[[nodiscard]] bool IsRendererAccelerated() const noexcept;
|
||||
[[nodiscard]] Renderer3D* GetCurrentRenderer() noexcept { return CurrentRenderer.get(); }
|
||||
[[nodiscard]] const Renderer3D* GetCurrentRenderer() const noexcept { return CurrentRenderer.get(); }
|
||||
void SetCurrentRenderer(std::unique_ptr<Renderer3D>&& renderer) noexcept { CurrentRenderer = std::move(renderer); }
|
||||
|
||||
void SetEnabled(bool geometry, bool rendering);
|
||||
u8 Read8(u32 addr) noexcept;
|
||||
u16 Read16(u32 addr) noexcept;
|
||||
u32 Read32(u32 addr) noexcept;
|
||||
void Write8(u32 addr, u8 val) noexcept;
|
||||
void Write16(u32 addr, u16 val) noexcept;
|
||||
void Write32(u32 addr, u32 val) noexcept;
|
||||
private:
|
||||
typedef union
|
||||
{
|
||||
u64 _contents;
|
||||
struct
|
||||
{
|
||||
u32 Param;
|
||||
u8 Command;
|
||||
};
|
||||
|
||||
void ExecuteCommand();
|
||||
} CmdFIFOEntry;
|
||||
|
||||
s32 CyclesToRunFor();
|
||||
void Run();
|
||||
void CheckFIFOIRQ();
|
||||
void CheckFIFODMA();
|
||||
void UpdateClipMatrix() noexcept;
|
||||
void ResetRenderingState() noexcept;
|
||||
void AddCycles(s32 num) noexcept;
|
||||
void NextVertexSlot() noexcept;
|
||||
void StallPolygonPipeline(s32 delay, s32 nonstalldelay) noexcept;
|
||||
void SubmitPolygon() noexcept;
|
||||
void SubmitVertex() noexcept;
|
||||
void CalculateLighting() noexcept;
|
||||
void BoxTest(u32* params) noexcept;
|
||||
void PosTest() noexcept;
|
||||
void VecTest(u32 param) noexcept;
|
||||
void CmdFIFOWrite(CmdFIFOEntry& entry) noexcept;
|
||||
CmdFIFOEntry CmdFIFORead() noexcept;
|
||||
void FinishWork(s32 cycles) noexcept;
|
||||
void VertexPipelineSubmitCmd() noexcept
|
||||
{
|
||||
// vertex commands 0x24, 0x25, 0x26, 0x27, 0x28
|
||||
if (!(VertexSlotsFree & 0x1)) NextVertexSlot();
|
||||
else AddCycles(1);
|
||||
NormalPipeline = 0;
|
||||
}
|
||||
|
||||
void VCount144();
|
||||
void VBlank();
|
||||
void VCount215();
|
||||
void VertexPipelineCmdDelayed6() noexcept
|
||||
{
|
||||
// commands 0x20, 0x30, 0x31, 0x72 that can run 6 cycles after a vertex
|
||||
if (VertexPipeline > 2) AddCycles((VertexPipeline - 2) + 1);
|
||||
else AddCycles(NormalPipeline + 1);
|
||||
NormalPipeline = 0;
|
||||
}
|
||||
|
||||
void RestartFrame();
|
||||
void VertexPipelineCmdDelayed8() noexcept
|
||||
{
|
||||
// commands 0x29, 0x2A, 0x2B, 0x33, 0x34, 0x41, 0x60, 0x71 that can run 8 cycles after a vertex
|
||||
if (VertexPipeline > 0) AddCycles(VertexPipeline + 1);
|
||||
else AddCycles(NormalPipeline + 1);
|
||||
NormalPipeline = 0;
|
||||
}
|
||||
|
||||
void SetRenderXPos(u16 xpos);
|
||||
u32* GetLine(int line);
|
||||
void VertexPipelineCmdDelayed4() noexcept
|
||||
{
|
||||
// all other commands can run 4 cycles after a vertex
|
||||
// no need to do much here since that is the minimum
|
||||
AddCycles(NormalPipeline + 1);
|
||||
NormalPipeline = 0;
|
||||
}
|
||||
|
||||
void WriteToGXFIFO(u32 val);
|
||||
std::unique_ptr<Renderer3D> CurrentRenderer = nullptr;
|
||||
|
||||
u8 Read8(u32 addr);
|
||||
u16 Read16(u32 addr);
|
||||
u32 Read32(u32 addr);
|
||||
void Write8(u32 addr, u8 val);
|
||||
void Write16(u32 addr, u16 val);
|
||||
void Write32(u32 addr, u32 val);
|
||||
u16 RenderXPos = 0;
|
||||
|
||||
public:
|
||||
FIFO<CmdFIFOEntry, 256> CmdFIFO {};
|
||||
FIFO<CmdFIFOEntry, 4> CmdPIPE {};
|
||||
|
||||
FIFO<CmdFIFOEntry, 64> CmdStallQueue {};
|
||||
|
||||
u32 ZeroDotWLimit = 0;
|
||||
|
||||
u32 GXStat = 0;
|
||||
|
||||
u32 ExecParams[32] {};
|
||||
u32 ExecParamCount = 0;
|
||||
|
||||
s32 CycleCount = 0;
|
||||
s32 VertexPipeline = 0;
|
||||
s32 NormalPipeline = 0;
|
||||
s32 PolygonPipeline = 0;
|
||||
s32 VertexSlotCounter = 0;
|
||||
u32 VertexSlotsFree = 0;
|
||||
|
||||
u32 NumPushPopCommands = 0;
|
||||
u32 NumTestCommands = 0;
|
||||
|
||||
|
||||
u32 MatrixMode = 0;
|
||||
|
||||
s32 ProjMatrix[16] {};
|
||||
s32 PosMatrix[16] {};
|
||||
s32 VecMatrix[16] {};
|
||||
s32 TexMatrix[16] {};
|
||||
|
||||
s32 ClipMatrix[16] {};
|
||||
bool ClipMatrixDirty = false;
|
||||
|
||||
u32 Viewport[6] {};
|
||||
|
||||
s32 ProjMatrixStack[16] {};
|
||||
s32 PosMatrixStack[32][16] {};
|
||||
s32 VecMatrixStack[32][16] {};
|
||||
s32 TexMatrixStack[16] {};
|
||||
s32 ProjMatrixStackPointer = 0;
|
||||
s32 PosMatrixStackPointer = 0;
|
||||
s32 TexMatrixStackPointer = 0;
|
||||
|
||||
u32 NumCommands = 0;
|
||||
u32 CurCommand = 0;
|
||||
u32 ParamCount = 0;
|
||||
u32 TotalParams = 0;
|
||||
|
||||
bool GeometryEnabled = false;
|
||||
bool RenderingEnabled = false;
|
||||
|
||||
u32 DispCnt = 0;
|
||||
u8 AlphaRefVal = 0;
|
||||
u8 AlphaRef = 0;
|
||||
|
||||
u16 ToonTable[32] {};
|
||||
u16 EdgeTable[8] {};
|
||||
|
||||
u32 FogColor = 0;
|
||||
u32 FogOffset = 0;
|
||||
u8 FogDensityTable[32] {};
|
||||
|
||||
u32 ClearAttr1 = 0;
|
||||
u32 ClearAttr2 = 0;
|
||||
u32 RenderDispCnt = 0;
|
||||
u8 RenderAlphaRef = 0;
|
||||
|
||||
u16 RenderToonTable[32] {};
|
||||
u16 RenderEdgeTable[8] {};
|
||||
|
||||
u32 RenderFogColor = 0;
|
||||
u32 RenderFogOffset = 0;
|
||||
u32 RenderFogShift = 0;
|
||||
u8 RenderFogDensityTable[34] {};
|
||||
|
||||
u32 RenderClearAttr1 = 0;
|
||||
u32 RenderClearAttr2 = 0;
|
||||
|
||||
bool RenderFrameIdentical = false;
|
||||
|
||||
bool AbortFrame = false;
|
||||
|
||||
u64 Timestamp = 0;
|
||||
|
||||
|
||||
u32 PolygonMode = 0;
|
||||
s16 CurVertex[3] {};
|
||||
u8 VertexColor[3] {};
|
||||
s16 TexCoords[2] {};
|
||||
s16 RawTexCoords[2] {};
|
||||
s16 Normal[3] {};
|
||||
|
||||
s16 LightDirection[4][3] {};
|
||||
u8 LightColor[4][3] {};
|
||||
u8 MatDiffuse[3] {};
|
||||
u8 MatAmbient[3] {};
|
||||
u8 MatSpecular[3] {};
|
||||
u8 MatEmission[3] {};
|
||||
|
||||
bool UseShininessTable = false;
|
||||
u8 ShininessTable[128] {};
|
||||
|
||||
u32 PolygonAttr = 0;
|
||||
u32 CurPolygonAttr = 0;
|
||||
|
||||
u32 TexParam = 0;
|
||||
u32 TexPalette = 0;
|
||||
|
||||
s32 PosTestResult[4] {};
|
||||
s16 VecTestResult[3] {};
|
||||
|
||||
Vertex TempVertexBuffer[4] {};
|
||||
u32 VertexNum = 0;
|
||||
u32 VertexNumInPoly = 0;
|
||||
u32 NumConsecutivePolygons = 0;
|
||||
Polygon* LastStripPolygon = nullptr;
|
||||
u32 NumOpaquePolygons = 0;
|
||||
|
||||
Vertex VertexRAM[6144 * 2] {};
|
||||
Polygon PolygonRAM[2048 * 2] {};
|
||||
|
||||
Vertex* CurVertexRAM = nullptr;
|
||||
Polygon* CurPolygonRAM = nullptr;
|
||||
u32 NumVertices = 0;
|
||||
u32 NumPolygons = 0;
|
||||
u32 CurRAMBank = 0;
|
||||
|
||||
std::array<Polygon*,2048> RenderPolygonRAM {};
|
||||
u32 RenderNumPolygons = 0;
|
||||
|
||||
u32 FlushRequest = 0;
|
||||
u32 FlushAttributes = 0;
|
||||
u32 ScrolledLine[256];
|
||||
};
|
||||
|
||||
class Renderer3D
|
||||
{
|
||||
@ -149,7 +340,7 @@ public:
|
||||
// are more detailed "traits" that we can ask of the Renderer3D type
|
||||
const bool Accelerated;
|
||||
|
||||
virtual void SetRenderSettings(GPU::RenderSettings& settings) = 0;
|
||||
virtual void SetRenderSettings(const Melon::RenderSettings& settings) noexcept = 0;
|
||||
|
||||
virtual void VCount144() {};
|
||||
|
||||
@ -160,15 +351,6 @@ protected:
|
||||
Renderer3D(bool Accelerated);
|
||||
};
|
||||
|
||||
extern int Renderer;
|
||||
extern std::unique_ptr<Renderer3D> CurrentRenderer;
|
||||
|
||||
}
|
||||
|
||||
#include "GPU3D_Soft.h"
|
||||
|
||||
#ifdef OGLRENDERER_ENABLED
|
||||
#include "GPU3D_OpenGL.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user