Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement gx hanging #2062

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 33 additions & 13 deletions src/GPU3D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,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;
Expand Down Expand Up @@ -363,7 +363,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);
Expand All @@ -387,7 +387,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);

Expand Down Expand Up @@ -705,7 +705,7 @@ void GPU3D::UpdateClipMatrix() noexcept



void GPU3D::AddCycles(s32 num) noexcept
void GPU3D::AddCycles(s64 num) noexcept
{
CycleCount += num;

Expand Down Expand Up @@ -802,6 +802,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>
Expand Down Expand Up @@ -963,6 +971,7 @@ void GPU3D::SubmitPolygon() noexcept
PolygonPipeline = 8;
VertexSlotCounter = 1;
VertexSlotsFree = 0b11110;
IncompletePoly = false;

// culling
// TODO: work out how it works on the real thing
Expand Down Expand Up @@ -1382,7 +1391,6 @@ void GPU3D::SubmitVertex() noexcept

vertextrans->Clipped = false;

VertexNum++;
VertexNumInPoly++;

switch (PolygonMode)
Expand All @@ -1392,17 +1400,17 @@ void GPU3D::SubmitVertex() noexcept
{
VertexNumInPoly = 0;
SubmitPolygon();
NumConsecutivePolygons++;
}
else IncompletePoly = true;
break;

case 1: // quad
if (VertexNumInPoly == 4)
{
VertexNumInPoly = 0;
SubmitPolygon();
NumConsecutivePolygons++;
}
else IncompletePoly = true;
break;

case 2: // triangle strip
Expand All @@ -1422,11 +1430,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
Expand All @@ -1438,11 +1446,11 @@ void GPU3D::SubmitVertex() noexcept

VertexNumInPoly = 2;
SubmitPolygon();
NumConsecutivePolygons++;

TempVertexBuffer[0] = TempVertexBuffer[3];
TempVertexBuffer[1] = TempVertexBuffer[2];
}
else IncompletePoly = true;
break;
}

Expand Down Expand Up @@ -2030,11 +2038,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;
Expand All @@ -2050,6 +2060,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;
Expand Down Expand Up @@ -2313,6 +2328,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;
Expand All @@ -2325,7 +2345,7 @@ void GPU3D::ExecuteCommand() noexcept
}
}

s32 GPU3D::CyclesToRunFor() const noexcept
s64 GPU3D::CyclesToRunFor() const noexcept
{
if (CycleCount < 0) return 0;
return CycleCount;
Expand Down
9 changes: 5 additions & 4 deletions src/GPU3D.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ class GPU3D

void ExecuteCommand() noexcept;

s32 CyclesToRunFor() const noexcept;
s64 CyclesToRunFor() const noexcept;
void Run() noexcept;
void CheckFIFOIRQ() noexcept;
void CheckFIFODMA() noexcept;
Expand Down Expand Up @@ -143,9 +143,10 @@ class GPU3D

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;
Expand Down Expand Up @@ -204,7 +205,7 @@ class GPU3D
u32 ExecParams[32] {};
u32 ExecParamCount = 0;

s32 CycleCount = 0;
s64 CycleCount = 0;
s32 VertexPipeline = 0;
s32 NormalPipeline = 0;
s32 PolygonPipeline = 0;
Expand Down Expand Up @@ -305,7 +306,7 @@ class GPU3D
s16 VecTestResult[3] {};

Vertex TempVertexBuffer[4] {};
u32 VertexNum = 0;
bool IncompletePoly = false;
u32 VertexNumInPoly = 0;
u32 NumConsecutivePolygons = 0;
Polygon* LastStripPolygon = nullptr;
Expand Down
3 changes: 1 addition & 2 deletions src/NDS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -943,8 +943,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)
Expand Down
Loading