Commit 8ea11eb7 by Cody Northrop Committed by Commit Bot

Capture/Replay: Reset programs on loop

Apps that create new programs during the run need to have them deleted on loop. This CL handles that. It does not handle programs that have been deleted and need to be recreated, or that have been modified otherwise. An assert has been included to catch that for future needs. With this CL, entries like this will show up in ResetReplay: ... glDeleteProgram(gShaderProgramMap[120]); glDeleteProgram(gShaderProgramMap[121]); ... Test: Pokemon Go MEC Bug: b/188091629 Bug: angleproject:5968 Change-Id: I78c425e8fe95792fc626484641d067613dfae971 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2895326 Commit-Queue: Cody Northrop <cnorthrop@google.com> Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent a1a418e2
...@@ -926,6 +926,21 @@ void MaybeResetResources(std::stringstream &out, ...@@ -926,6 +926,21 @@ void MaybeResetResources(std::stringstream &out,
break; break;
} }
case ResourceIDType::ShaderProgram:
{
ProgramSet &newPrograms = resourceTracker->getNewPrograms();
// If we have any new programs created and not deleted during the run, delete them now
for (const auto &newProgram : newPrograms)
{
out << " glDeleteProgram(gShaderProgramMap[" << newProgram.value << "]);\n";
}
// TODO (http://anglebug.com/5968): Handle programs that need regen
// This would only happen if a starting program was deleted during the run
ASSERT(resourceTracker->getProgramsToRegen().empty());
break;
}
default: default:
// TODO (http://anglebug.com/4599): Reset more than just buffers // TODO (http://anglebug.com/4599): Reset more than just buffers
break; break;
...@@ -2932,6 +2947,7 @@ void CaptureMidExecutionSetup(const gl::Context *context, ...@@ -2932,6 +2947,7 @@ void CaptureMidExecutionSetup(const gl::Context *context,
} }
resourceTracker->onShaderProgramAccess(id); resourceTracker->onShaderProgramAccess(id);
resourceTracker->getStartingPrograms().insert(id);
} }
for (const auto &ppoIterator : *programPipelineManager) for (const auto &ppoIterator : *programPipelineManager)
...@@ -4347,6 +4363,35 @@ void FrameCapture::maybeCapturePreCallUpdates(const gl::Context *context, CallCa ...@@ -4347,6 +4363,35 @@ void FrameCapture::maybeCapturePreCallUpdates(const gl::Context *context, CallCa
context->getShareGroup()->getFrameCaptureShared(); context->getShareGroup()->getFrameCaptureShared();
frameCaptureShared->setShaderSource(shader->getHandle(), shader->getSourceString()); frameCaptureShared->setShaderSource(shader->getHandle(), shader->getSourceString());
frameCaptureShared->setProgramSources(programID, GetAttachedProgramSources(program)); frameCaptureShared->setProgramSources(programID, GetAttachedProgramSources(program));
if (isCaptureActive())
{
mResourceTracker.setCreatedProgram(programID);
}
break;
}
case EntryPoint::GLCreateProgram:
{
// If we're capturing, track which programs have been created
if (isCaptureActive())
{
gl::ShaderProgramID programID = {call.params.getReturnValue().value.GLuintVal};
mResourceTracker.setCreatedProgram(programID);
}
break;
}
case EntryPoint::GLDeleteProgram:
{
// If we're capturing, track which programs have been deleted
if (isCaptureActive())
{
const ParamCapture &param =
call.params.getParam("programPacked", ParamType::TShaderProgramID, 0);
mResourceTracker.setDeletedProgram(param.value.ShaderProgramIDVal);
}
break; break;
} }
...@@ -4909,6 +4954,40 @@ void ResourceTracker::setDeletedFenceSync(GLsync sync) ...@@ -4909,6 +4954,40 @@ void ResourceTracker::setDeletedFenceSync(GLsync sync)
mFenceSyncsToRegen.insert(sync); mFenceSyncsToRegen.insert(sync);
} }
void ResourceTracker::setCreatedProgram(gl::ShaderProgramID id)
{
if (mStartingPrograms.find(id) == mStartingPrograms.end())
{
// This is a program created after MEC was initialized, track it
mNewPrograms.insert(id);
return;
}
}
void ResourceTracker::setDeletedProgram(gl::ShaderProgramID id)
{
if (id.value == 0)
{
// Ignore program ID 0
return;
}
if (mNewPrograms.find(id) != mNewPrograms.end())
{
// This is a program created after MEC was initialized, just clear it, since there will be
// no actions required for it to return to starting state.
mNewPrograms.erase(id);
return;
}
// Ensure this program was in our starting set
// It's possible this could fire if the app deletes programs that were never generated
ASSERT(mStartingPrograms.empty() || (mStartingPrograms.find(id) != mStartingPrograms.end()));
// In this case, the app is deleting a program we started with, we need to regen on loop
mProgramsToRegen.insert(id);
}
void ResourceTracker::setGennedBuffer(gl::BufferID id) void ResourceTracker::setGennedBuffer(gl::BufferID id)
{ {
if (mStartingBuffers.find(id) == mStartingBuffers.end()) if (mStartingBuffers.find(id) == mStartingBuffers.end())
......
...@@ -216,6 +216,8 @@ using BufferMapStatusMap = std::map<gl::BufferID, bool>; ...@@ -216,6 +216,8 @@ using BufferMapStatusMap = std::map<gl::BufferID, bool>;
using FenceSyncSet = std::set<GLsync>; using FenceSyncSet = std::set<GLsync>;
using FenceSyncCalls = std::map<GLsync, std::vector<CallCapture>>; using FenceSyncCalls = std::map<GLsync, std::vector<CallCapture>>;
using ProgramSet = std::set<gl::ShaderProgramID>;
// Helper to track resource changes during the capture // Helper to track resource changes during the capture
class ResourceTracker final : angle::NonCopyable class ResourceTracker final : angle::NonCopyable
{ {
...@@ -266,6 +268,13 @@ class ResourceTracker final : angle::NonCopyable ...@@ -266,6 +268,13 @@ class ResourceTracker final : angle::NonCopyable
FenceSyncSet &getFenceSyncsToRegen() { return mFenceSyncsToRegen; } FenceSyncSet &getFenceSyncsToRegen() { return mFenceSyncsToRegen; }
void setDeletedFenceSync(GLsync sync); void setDeletedFenceSync(GLsync sync);
ProgramSet &getStartingPrograms() { return mStartingPrograms; }
ProgramSet &getNewPrograms() { return mNewPrograms; }
ProgramSet &getProgramsToRegen() { return mProgramsToRegen; }
void setCreatedProgram(gl::ShaderProgramID id);
void setDeletedProgram(gl::ShaderProgramID id);
private: private:
// Buffer regen calls will delete and gen a buffer // Buffer regen calls will delete and gen a buffer
BufferCalls mBufferRegenCalls; BufferCalls mBufferRegenCalls;
...@@ -296,6 +305,13 @@ class ResourceTracker final : angle::NonCopyable ...@@ -296,6 +305,13 @@ class ResourceTracker final : angle::NonCopyable
// Maximum accessed shader program ID. // Maximum accessed shader program ID.
uint32_t mMaxShaderPrograms = 0; uint32_t mMaxShaderPrograms = 0;
// Programs created during startup
ProgramSet mStartingPrograms;
// Programs created during the run that need to be deleted
ProgramSet mNewPrograms;
// Programs deleted during the run that need to be recreated
ProgramSet mProgramsToRegen;
// Fence sync objects created during MEC setup // Fence sync objects created during MEC setup
FenceSyncSet mStartingFenceSyncs; FenceSyncSet mStartingFenceSyncs;
// Fence sync regen calls will create a fence sync objects // Fence sync regen calls will create a fence sync objects
......
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