Commit e4ceee97 by Cody Northrop Committed by Commit Bot

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/+/2321739Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarManh Nguyen <nguyenmh@google.com> Commit-Queue: Cody Northrop <cnorthrop@google.com>
parent 84eb7d87
......@@ -55,7 +55,8 @@ constexpr char kCaptureLabel[] = "ANGLE_CAPTURE_LABEL";
constexpr char kCompression[] = "ANGLE_CAPTURE_COMPRESSION";
constexpr char kSerializeStateEnabledVarName[] = "ANGLE_CAPTURE_SERIALIZE_STATE";
constexpr size_t kBinaryAlignment = 16;
constexpr size_t kBinaryAlignment = 16;
constexpr size_t kFunctionSizeLimit = 50000;
#if defined(ANGLE_PLATFORM_ANDROID)
......@@ -868,22 +869,65 @@ void WriteCppReplay(bool compression,
if (frameIndex == frameStart)
{
out << "void SetupContext" << Str(static_cast<int>(context->id())) << "Replay()\n";
out << "{\n";
std::stringstream setupCallStream;
std::stringstream setupCallStreamParts;
setupCallStream << "void SetupContext" << Str(static_cast<int>(context->id()))
<< "Replay()\n";
setupCallStream << "{\n";
WriteLoadBinaryDataCall(compression, setupCallStream, context->id(), captureLabel);
int callCount = 0;
int partCount = 0;
// Setup can get quite large. If over a certain size, break up the function to avoid
// overflowing the stack
if (setupCalls.size() > kFunctionSizeLimit)
{
setupCallStreamParts << "void SetupContext" << Str(static_cast<int>(context->id()))
<< "ReplayPart" << ++partCount << "()\n";
setupCallStreamParts << "{\n";
}
for (const CallCapture &call : setupCalls)
{
setupCallStream << " ";
WriteCppReplayForCall(call, &counters, setupCallStream, header, binaryData);
setupCallStream << ";\n";
setupCallStreamParts << " ";
WriteCppReplayForCall(call, &counters, setupCallStreamParts, header, binaryData);
setupCallStreamParts << ";\n";
if (partCount > 0 && ++callCount % kFunctionSizeLimit == 0)
{
setupCallStreamParts << "}\n";
setupCallStreamParts << "\n";
setupCallStreamParts << "void SetupContext" << Str(static_cast<int>(context->id()))
<< "ReplayPart" << ++partCount << "()\n";
setupCallStreamParts << "{\n";
}
}
out << setupCallStream.str();
if (partCount > 0)
{
setupCallStreamParts << "}\n";
setupCallStreamParts << "\n";
// Write out the parts
out << setupCallStreamParts.str();
// Write out the calls to the parts
for (int i = 1; i <= partCount; i++)
{
setupCallStream << " SetupContext" << Str(static_cast<int>(context->id()))
<< "ReplayPart" << i << "();\n";
}
}
else
{
// If we didn't chunk it up, write all the calls directly to SetupContext
setupCallStream << setupCallStreamParts.str();
}
out << setupCallStream.str();
out << "}\n";
out << "\n";
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment