Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit e4ceee9

Browse files
cnorthropCommit Bot
authored andcommitted
Capture/Replay: Break up SetupContext
While getting NBA2K20 MEC to work, discovered that SetupContext was so large, it was causing a stack overflow. To fix, simply break up the function into a series of helpers if the number of calls exceeds a set limit. Test: NBA2K20 MEC Bug: b/160014453 Bug: angleproject:4048 Change-Id: I332d5dea5fc4e14700b68150cbe31a4c88cdae89 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2321739 Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Manh Nguyen <nguyenmh@google.com> Commit-Queue: Cody Northrop <cnorthrop@google.com>
1 parent 84eb7d8 commit e4ceee9

File tree

1 file changed

+52
-8
lines changed

1 file changed

+52
-8
lines changed

src/libANGLE/FrameCapture.cpp

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ constexpr char kCaptureLabel[] = "ANGLE_CAPTURE_LABEL";
5555
constexpr char kCompression[] = "ANGLE_CAPTURE_COMPRESSION";
5656
constexpr char kSerializeStateEnabledVarName[] = "ANGLE_CAPTURE_SERIALIZE_STATE";
5757

58-
constexpr size_t kBinaryAlignment = 16;
58+
constexpr size_t kBinaryAlignment = 16;
59+
constexpr size_t kFunctionSizeLimit = 50000;
5960

6061
#if defined(ANGLE_PLATFORM_ANDROID)
6162

@@ -868,22 +869,65 @@ void WriteCppReplay(bool compression,
868869

869870
if (frameIndex == frameStart)
870871
{
871-
out << "void SetupContext" << Str(static_cast<int>(context->id())) << "Replay()\n";
872-
out << "{\n";
873-
874872
std::stringstream setupCallStream;
873+
std::stringstream setupCallStreamParts;
874+
875+
setupCallStream << "void SetupContext" << Str(static_cast<int>(context->id()))
876+
<< "Replay()\n";
877+
setupCallStream << "{\n";
875878

876879
WriteLoadBinaryDataCall(compression, setupCallStream, context->id(), captureLabel);
877880

881+
int callCount = 0;
882+
int partCount = 0;
883+
884+
// Setup can get quite large. If over a certain size, break up the function to avoid
885+
// overflowing the stack
886+
if (setupCalls.size() > kFunctionSizeLimit)
887+
{
888+
setupCallStreamParts << "void SetupContext" << Str(static_cast<int>(context->id()))
889+
<< "ReplayPart" << ++partCount << "()\n";
890+
setupCallStreamParts << "{\n";
891+
}
892+
878893
for (const CallCapture &call : setupCalls)
879894
{
880-
setupCallStream << " ";
881-
WriteCppReplayForCall(call, &counters, setupCallStream, header, binaryData);
882-
setupCallStream << ";\n";
895+
setupCallStreamParts << " ";
896+
WriteCppReplayForCall(call, &counters, setupCallStreamParts, header, binaryData);
897+
setupCallStreamParts << ";\n";
898+
899+
if (partCount > 0 && ++callCount % kFunctionSizeLimit == 0)
900+
{
901+
setupCallStreamParts << "}\n";
902+
setupCallStreamParts << "\n";
903+
setupCallStreamParts << "void SetupContext" << Str(static_cast<int>(context->id()))
904+
<< "ReplayPart" << ++partCount << "()\n";
905+
setupCallStreamParts << "{\n";
906+
}
883907
}
884908

885-
out << setupCallStream.str();
909+
if (partCount > 0)
910+
{
911+
setupCallStreamParts << "}\n";
912+
setupCallStreamParts << "\n";
913+
914+
// Write out the parts
915+
out << setupCallStreamParts.str();
916+
917+
// Write out the calls to the parts
918+
for (int i = 1; i <= partCount; i++)
919+
{
920+
setupCallStream << " SetupContext" << Str(static_cast<int>(context->id()))
921+
<< "ReplayPart" << i << "();\n";
922+
}
923+
}
924+
else
925+
{
926+
// If we didn't chunk it up, write all the calls directly to SetupContext
927+
setupCallStream << setupCallStreamParts.str();
928+
}
886929

930+
out << setupCallStream.str();
887931
out << "}\n";
888932
out << "\n";
889933
}

0 commit comments

Comments
 (0)