This commit is contained in:
Jakly 2024-11-12 12:56:34 +01:00 committed by GitHub
commit 1dae57b065
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 39 additions and 19 deletions

View File

@ -288,7 +288,7 @@ void GPU3D::Reset() noexcept
memset(VecTestResult, 0, 2*3); memset(VecTestResult, 0, 2*3);
memset(TempVertexBuffer, 0, sizeof(TempVertexBuffer)); memset(TempVertexBuffer, 0, sizeof(TempVertexBuffer));
VertexNum = 0; IncompletePoly = false;
VertexNumInPoly = 0; VertexNumInPoly = 0;
NumConsecutivePolygons = 0; NumConsecutivePolygons = 0;
LastStripPolygon = nullptr; LastStripPolygon = nullptr;
@ -366,7 +366,7 @@ void GPU3D::DoSavestate(Savestate* file) noexcept
file->VarArray(ExecParams, 32*4); file->VarArray(ExecParams, 32*4);
file->Var32(&ExecParamCount); file->Var32(&ExecParamCount);
file->Var32((u32*)&CycleCount); file->Var64((u64*)&CycleCount);
file->Var64(&Timestamp); file->Var64(&Timestamp);
file->Var32(&MatrixMode); file->Var32(&MatrixMode);
@ -390,7 +390,7 @@ void GPU3D::DoSavestate(Savestate* file) noexcept
file->VarArray(PosTestResult, 4*4); file->VarArray(PosTestResult, 4*4);
file->VarArray(VecTestResult, 2*3); file->VarArray(VecTestResult, 2*3);
file->Var32(&VertexNum); file->Bool32(&IncompletePoly);
file->Var32(&VertexNumInPoly); file->Var32(&VertexNumInPoly);
file->Var32(&NumConsecutivePolygons); file->Var32(&NumConsecutivePolygons);
@ -708,7 +708,7 @@ void GPU3D::UpdateClipMatrix() noexcept
void GPU3D::AddCycles(s32 num) noexcept void GPU3D::AddCycles(s64 num) noexcept
{ {
CycleCount += num; CycleCount += num;
@ -805,6 +805,14 @@ void GPU3D::StallPolygonPipeline(s32 delay, s32 nonstalldelay) noexcept
} }
} }
void GPU3D::HangGX(const char* cause) noexcept
{
Platform::Log(LogLevel::Warn, "GX CRASHED: %s\n", cause);
// this should hang the gx for roughly... 2181 years?
// I think that's close enough to forever for our usecase.
AddCycles(0x1FFFFFFFFFFFFFFF);
}
template<int comp, s32 plane, bool attribs> template<int comp, s32 plane, bool attribs>
@ -966,6 +974,7 @@ void GPU3D::SubmitPolygon() noexcept
PolygonPipeline = 8; PolygonPipeline = 8;
VertexSlotCounter = 1; VertexSlotCounter = 1;
VertexSlotsFree = 0b11110; VertexSlotsFree = 0b11110;
IncompletePoly = false;
// culling // culling
// TODO: work out how it works on the real thing // TODO: work out how it works on the real thing
@ -1385,7 +1394,6 @@ void GPU3D::SubmitVertex() noexcept
vertextrans->Clipped = false; vertextrans->Clipped = false;
VertexNum++;
VertexNumInPoly++; VertexNumInPoly++;
switch (PolygonMode) switch (PolygonMode)
@ -1395,8 +1403,8 @@ void GPU3D::SubmitVertex() noexcept
{ {
VertexNumInPoly = 0; VertexNumInPoly = 0;
SubmitPolygon(); SubmitPolygon();
NumConsecutivePolygons++;
} }
else IncompletePoly = true;
break; break;
case 1: // quad case 1: // quad
@ -1404,8 +1412,8 @@ void GPU3D::SubmitVertex() noexcept
{ {
VertexNumInPoly = 0; VertexNumInPoly = 0;
SubmitPolygon(); SubmitPolygon();
NumConsecutivePolygons++;
} }
else IncompletePoly = true;
break; break;
case 2: // triangle strip case 2: // triangle strip
@ -1425,11 +1433,11 @@ void GPU3D::SubmitVertex() noexcept
{ {
VertexNumInPoly = 2; VertexNumInPoly = 2;
SubmitPolygon(); SubmitPolygon();
NumConsecutivePolygons++;
TempVertexBuffer[0] = TempVertexBuffer[1]; TempVertexBuffer[0] = TempVertexBuffer[1];
TempVertexBuffer[1] = TempVertexBuffer[2]; TempVertexBuffer[1] = TempVertexBuffer[2];
} }
else IncompletePoly = true;
break; break;
case 3: // quad strip case 3: // quad strip
@ -1441,11 +1449,11 @@ void GPU3D::SubmitVertex() noexcept
VertexNumInPoly = 2; VertexNumInPoly = 2;
SubmitPolygon(); SubmitPolygon();
NumConsecutivePolygons++;
TempVertexBuffer[0] = TempVertexBuffer[3]; TempVertexBuffer[0] = TempVertexBuffer[3];
TempVertexBuffer[1] = TempVertexBuffer[2]; TempVertexBuffer[1] = TempVertexBuffer[2];
} }
else IncompletePoly = true;
break; break;
} }
@ -2058,11 +2066,13 @@ void GPU3D::ExecuteCommand() noexcept
break; break;
case 0x40: // begin polygons case 0x40: // begin polygons
if (IncompletePoly)
{
HangGX("Begin cmd sent with partial poly defined");
break;
}
StallPolygonPipeline(1, 0); StallPolygonPipeline(1, 0);
// TODO: check if there was a polygon being defined but incomplete
// such cases seem to freeze the GPU
PolygonMode = entry.Param & 0x3; PolygonMode = entry.Param & 0x3;
VertexNum = 0;
VertexNumInPoly = 0; VertexNumInPoly = 0;
NumConsecutivePolygons = 0; NumConsecutivePolygons = 0;
LastStripPolygon = NULL; LastStripPolygon = NULL;
@ -2078,6 +2088,11 @@ void GPU3D::ExecuteCommand() noexcept
break; break;
case 0x50: // flush case 0x50: // flush
if (IncompletePoly)
{
HangGX("Flush cmd sent with partial poly defined");
break;
}
VertexPipelineCmdDelayed4(); VertexPipelineCmdDelayed4();
FlushRequest = 1; FlushRequest = 1;
FlushAttributes = entry.Param & 0x3; FlushAttributes = entry.Param & 0x3;
@ -2341,6 +2356,11 @@ void GPU3D::ExecuteCommand() noexcept
break; break;
case 0x70: // box test case 0x70: // box test
if (IncompletePoly)
{
HangGX("BoxTest cmd sent with partial poly defined");
break;
}
NumTestCommands -= 3; NumTestCommands -= 3;
BoxTest(ExecParams); BoxTest(ExecParams);
break; break;
@ -2353,7 +2373,7 @@ void GPU3D::ExecuteCommand() noexcept
} }
} }
s32 GPU3D::CyclesToRunFor() const noexcept s64 GPU3D::CyclesToRunFor() const noexcept
{ {
if (CycleCount < 0) return 0; if (CycleCount < 0) return 0;
return CycleCount; return CycleCount;

View File

@ -98,7 +98,7 @@ public:
void ExecuteCommand() noexcept; void ExecuteCommand() noexcept;
s32 CyclesToRunFor() const noexcept; s64 CyclesToRunFor() const noexcept;
void Run() noexcept; void Run() noexcept;
void CheckFIFOIRQ() noexcept; void CheckFIFOIRQ() noexcept;
void CheckFIFODMA() noexcept; void CheckFIFODMA() noexcept;
@ -143,9 +143,10 @@ private:
void UpdateClipMatrix() noexcept; void UpdateClipMatrix() noexcept;
void ResetRenderingState() noexcept; void ResetRenderingState() noexcept;
void AddCycles(s32 num) noexcept; void AddCycles(s64 num) noexcept;
void NextVertexSlot() noexcept; void NextVertexSlot() noexcept;
void StallPolygonPipeline(s32 delay, s32 nonstalldelay) noexcept; void StallPolygonPipeline(s32 delay, s32 nonstalldelay) noexcept;
void HangGX(const char* cause) noexcept;
void SubmitPolygon() noexcept; void SubmitPolygon() noexcept;
void SubmitVertex() noexcept; void SubmitVertex() noexcept;
void CalculateLighting() noexcept; void CalculateLighting() noexcept;
@ -204,7 +205,7 @@ public:
u32 ExecParams[32] {}; u32 ExecParams[32] {};
u32 ExecParamCount = 0; u32 ExecParamCount = 0;
s32 CycleCount = 0; s64 CycleCount = 0;
s32 VertexPipeline = 0; s32 VertexPipeline = 0;
s32 NormalPipeline = 0; s32 NormalPipeline = 0;
s32 PolygonPipeline = 0; s32 PolygonPipeline = 0;
@ -306,7 +307,7 @@ public:
s16 VecTestResult[3] {}; s16 VecTestResult[3] {};
Vertex TempVertexBuffer[4] {}; Vertex TempVertexBuffer[4] {};
u32 VertexNum = 0; bool IncompletePoly = false;
u32 VertexNumInPoly = 0; u32 VertexNumInPoly = 0;
u32 NumConsecutivePolygons = 0; u32 NumConsecutivePolygons = 0;
Polygon* LastStripPolygon = nullptr; Polygon* LastStripPolygon = nullptr;

View File

@ -951,8 +951,7 @@ u32 NDS::RunFrame()
if (CPUStop & CPUStop_GXStall) if (CPUStop & CPUStop_GXStall)
{ {
// GXFIFO stall // GXFIFO stall
s32 cycles = GPU.GPU3D.CyclesToRunFor(); s64 cycles = GPU.GPU3D.CyclesToRunFor();
ARM9Timestamp = std::min(ARM9Target, ARM9Timestamp+(cycles<<ARM9ClockShift)); ARM9Timestamp = std::min(ARM9Target, ARM9Timestamp+(cycles<<ARM9ClockShift));
} }
else if (CPUStop & CPUStop_DMA9) else if (CPUStop & CPUStop_DMA9)