Compare commits

...

3 Commits

Author SHA1 Message Date
Jakly
94549c3082
Merge 793590da3a into 4528441c74 2024-11-09 23:54:01 +01:00
Jaklyy
793590da3a remove unused variable 2024-06-07 19:09:28 -04:00
Jaklyy
31cfe2ee8f implement gx hanging
implements hanging on:
begin poly with partial poly defined
box test with partial poly defined
swap buffers with partial poly defined

also remove some useless variables:
vertexnum wasn't used.
NumConsecPolys was only used by triangle strips
2024-04-30 17:46:23 -04:00
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(TempVertexBuffer, 0, sizeof(TempVertexBuffer));
VertexNum = 0;
IncompletePoly = false;
VertexNumInPoly = 0;
NumConsecutivePolygons = 0;
LastStripPolygon = nullptr;
@ -366,7 +366,7 @@ void GPU3D::DoSavestate(Savestate* file) noexcept
file->VarArray(ExecParams, 32*4);
file->Var32(&ExecParamCount);
file->Var32((u32*)&CycleCount);
file->Var64((u64*)&CycleCount);
file->Var64(&Timestamp);
file->Var32(&MatrixMode);
@ -390,7 +390,7 @@ void GPU3D::DoSavestate(Savestate* file) noexcept
file->VarArray(PosTestResult, 4*4);
file->VarArray(VecTestResult, 2*3);
file->Var32(&VertexNum);
file->Bool32(&IncompletePoly);
file->Var32(&VertexNumInPoly);
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;
@ -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>
@ -966,6 +974,7 @@ void GPU3D::SubmitPolygon() noexcept
PolygonPipeline = 8;
VertexSlotCounter = 1;
VertexSlotsFree = 0b11110;
IncompletePoly = false;
// culling
// TODO: work out how it works on the real thing
@ -1385,7 +1394,6 @@ void GPU3D::SubmitVertex() noexcept
vertextrans->Clipped = false;
VertexNum++;
VertexNumInPoly++;
switch (PolygonMode)
@ -1395,8 +1403,8 @@ void GPU3D::SubmitVertex() noexcept
{
VertexNumInPoly = 0;
SubmitPolygon();
NumConsecutivePolygons++;
}
else IncompletePoly = true;
break;
case 1: // quad
@ -1404,8 +1412,8 @@ void GPU3D::SubmitVertex() noexcept
{
VertexNumInPoly = 0;
SubmitPolygon();
NumConsecutivePolygons++;
}
else IncompletePoly = true;
break;
case 2: // triangle strip
@ -1425,11 +1433,11 @@ void GPU3D::SubmitVertex() noexcept
{
VertexNumInPoly = 2;
SubmitPolygon();
NumConsecutivePolygons++;
TempVertexBuffer[0] = TempVertexBuffer[1];
TempVertexBuffer[1] = TempVertexBuffer[2];
}
else IncompletePoly = true;
break;
case 3: // quad strip
@ -1441,11 +1449,11 @@ void GPU3D::SubmitVertex() noexcept
VertexNumInPoly = 2;
SubmitPolygon();
NumConsecutivePolygons++;
TempVertexBuffer[0] = TempVertexBuffer[3];
TempVertexBuffer[1] = TempVertexBuffer[2];
}
else IncompletePoly = true;
break;
}
@ -2058,11 +2066,13 @@ void GPU3D::ExecuteCommand() noexcept
break;
case 0x40: // begin polygons
if (IncompletePoly)
{
HangGX("Begin cmd sent with partial poly defined");
break;
}
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;
VertexNum = 0;
VertexNumInPoly = 0;
NumConsecutivePolygons = 0;
LastStripPolygon = NULL;
@ -2078,6 +2088,11 @@ void GPU3D::ExecuteCommand() noexcept
break;
case 0x50: // flush
if (IncompletePoly)
{
HangGX("Flush cmd sent with partial poly defined");
break;
}
VertexPipelineCmdDelayed4();
FlushRequest = 1;
FlushAttributes = entry.Param & 0x3;
@ -2341,6 +2356,11 @@ void GPU3D::ExecuteCommand() noexcept
break;
case 0x70: // box test
if (IncompletePoly)
{
HangGX("BoxTest cmd sent with partial poly defined");
break;
}
NumTestCommands -= 3;
BoxTest(ExecParams);
break;
@ -2353,7 +2373,7 @@ void GPU3D::ExecuteCommand() noexcept
}
}
s32 GPU3D::CyclesToRunFor() const noexcept
s64 GPU3D::CyclesToRunFor() const noexcept
{
if (CycleCount < 0) return 0;
return CycleCount;

View File

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

View File

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