FrameCapture: Support EGLSync in MEC

This CL starts treating EGLSync as a tracked resource, such
that we can detect when they need to be created in Setup, or
regenerated in Reset.

Test: MEC of infinity_ops trace
Test: Replay new kentucky_route_zero trace without error
Bug: angleproject:8176
Change-Id: I130212f6edb78d9df29dd6e572843df25493ae09
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4566949
Reviewed-by: Roman Lavrov <romanl@google.com>
Commit-Queue: Cody Northrop <cnorthrop@google.com>
This commit is contained in:
Cody Northrop
2023-05-25 08:40:48 -06:00
committed by Angle LUCI CQ
parent 76b0e7f38b
commit d8339e78db
6 changed files with 133 additions and 8 deletions

View File

@@ -858,6 +858,14 @@ operator==(const T &lhs, const T &rhs)
{
return lhs.value == rhs.value;
}
template <typename T>
typename std::enable_if<IsResourceIDType<T>::value && !std::is_same<T, gl::ContextID>::value,
bool>::type
operator<(const T &lhs, const T &rhs)
{
return lhs.value < rhs.value;
}
} // namespace egl
#undef ANGLE_DEFINE_ID_TYPE

View File

@@ -117,6 +117,10 @@ class ShareGroup final : angle::NonCopyable
// Constant coded here as a reasonable limit.
constexpr EGLAttrib kProgramCacheSizeAbsoluteMax = 0x4000000;
using ImageMap = angle::HashMap<GLuint, Image *>;
using StreamSet = angle::HashSet<Stream *>;
using SyncMap = angle::HashMap<GLuint, Sync *>;
class Display final : public LabeledObject,
public angle::ObserverInterface,
public angle::NonCopyable
@@ -348,6 +352,8 @@ class Display final : public LabeledObject,
egl::Image *getImage(egl::ImageID imageID);
egl::Sync *getSync(egl::SyncID syncID);
const SyncMap &getSyncsForCapture() const { return mSyncMap; }
// Initialize thread-local variables used by the Display and its backing implementations. This
// includes:
//
@@ -389,13 +395,8 @@ class Display final : public LabeledObject,
ConfigSet mConfigSet;
typedef angle::HashMap<GLuint, Image *> ImageMap;
ImageMap mImageMap;
typedef angle::HashSet<Stream *> StreamSet;
StreamSet mStreamSet;
typedef angle::HashMap<GLuint, Sync *> SyncMap;
SyncMap mSyncMap;
void destroyImageImpl(Image *image, ImageMap *images);

View File

@@ -25,6 +25,7 @@ Sync::Sync(rx::EGLImplFactory *factory,
: mLabel(nullptr),
mId(id),
mType(type),
mAttributeMap(attribs),
mCondition(EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR),
mNativeFenceFD(
attribs.getAsInt(EGL_SYNC_NATIVE_FENCE_FD_ANDROID, EGL_NO_NATIVE_FENCE_FD_ANDROID))

View File

@@ -56,6 +56,7 @@ class Sync final : public angle::RefCountObject<Display, angle::Result>, public
Error dupNativeFenceFD(const Display *display, EGLint *result) const;
EGLenum getType() const { return mType; }
const AttributeMap &getAttributeMap() const { return mAttributeMap; }
EGLint getCondition() const { return mCondition; }
EGLint getNativeFenceFD() const { return mNativeFenceFD; }
@@ -66,6 +67,7 @@ class Sync final : public angle::RefCountObject<Display, angle::Result>, public
SyncID mId;
EGLenum mType;
AttributeMap mAttributeMap;
EGLint mCondition;
EGLint mNativeFenceFD;
};

View File

@@ -30,6 +30,7 @@
#include "libANGLE/Context.h"
#include "libANGLE/Context.inl.h"
#include "libANGLE/Display.h"
#include "libANGLE/EGLSync.h"
#include "libANGLE/Fence.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/GLES1Renderer.h"
@@ -1375,6 +1376,44 @@ void MaybeResetResources(gl::ContextID contextID,
}
break;
}
case ResourceIDType::egl_Sync:
{
TrackedResource &trackedEGLSyncs =
resourceTracker->getTrackedResource(contextID, ResourceIDType::egl_Sync);
ResourceSet &newEGLSyncs = trackedEGLSyncs.getNewResources();
ResourceSet &eglSyncsToDelete = trackedEGLSyncs.getResourcesToDelete();
ResourceSet &eglSyncsToRegen = trackedEGLSyncs.getResourcesToRegen();
ResourceCalls &eglSyncRegenCalls = trackedEGLSyncs.getResourceRegenCalls();
if (!newEGLSyncs.empty() || !eglSyncsToDelete.empty())
{
for (GLuint oldResource : eglSyncsToDelete)
{
out << " eglDestroySyncKHR(gEGLDisplay, gEGLSyncMap[" << oldResource
<< "]);\n";
}
for (GLuint newResource : newEGLSyncs)
{
out << " eglDestroySyncKHR(gEGLDisplay, gEGLSyncMap[" << newResource
<< "]);\n";
}
}
// If any of our starting EGLsyncs were deleted during the run, recreate them
for (GLuint id : eglSyncsToRegen)
{
// Emit their regen calls
for (CallCapture &call : eglSyncRegenCalls[id])
{
out << " ";
WriteCppReplayForCall(call, replayWriter, out, header, binaryData,
maxResourceIDBufferSize);
out << ";\n";
}
}
break;
}
default:
// TODO (http://anglebug.com/4599): Reset more resource types
break;
@@ -2248,8 +2287,9 @@ bool IsSharedObjectResource(ResourceIDType type)
case ResourceIDType::Image:
case ResourceIDType::Surface:
case ResourceIDType::egl_Sync:
// Return false for all EGL object types.
return false;
// EGL types are associated with a display and not bound to a context
// For the way this function is used, we can treat them as shared.
return true;
case ResourceIDType::EnumCount:
default:
@@ -3540,6 +3580,28 @@ void CaptureFenceSyncResetCalls(const gl::Context *context,
MaybeCaptureUpdateResourceIDs(context, resourceTracker, &fenceSyncRegenCalls[syncID]);
}
void CaptureEGLSyncResetCalls(const gl::Context *context,
const gl::State &replayState,
ResourceTracker *resourceTracker,
egl::SyncID eglSyncID,
EGLSync eglSyncObject,
const egl::Sync *eglSync)
{
// Track this as a starting resource that may need to be restored.
TrackedResource &trackedEGLSyncs =
resourceTracker->getTrackedResource(context->id(), ResourceIDType::egl_Sync);
// Track calls to regenerate a given buffer
ResourceCalls &eglSyncRegenCalls = trackedEGLSyncs.getResourceRegenCalls();
CallCapture createEGLSync =
CaptureCreateSyncKHR(nullptr, true, context->getDisplay(), eglSync->getType(),
eglSync->getAttributeMap(), eglSyncObject);
CaptureCustomCreateEGLSync("CreateEGLSyncKHR", createEGLSync,
eglSyncRegenCalls[eglSyncID.value]);
MaybeCaptureUpdateResourceIDs(context, resourceTracker, &eglSyncRegenCalls[eglSyncID.value]);
}
void CaptureBufferBindingResetCalls(const gl::State &replayState,
ResourceTracker *resourceTracker,
gl::BufferBinding binding,
@@ -4449,6 +4511,29 @@ void CaptureShareGroupMidExecutionSetup(
resourceTracker->getStartingFenceSyncs().insert(syncID);
}
// Capture EGL Sync Objects
const egl::SyncMap eglSyncMap = context->getDisplay()->getSyncsForCapture();
for (const auto &eglSyncIter : eglSyncMap)
{
egl::SyncID eglSyncID = {eglSyncIter.first};
const egl::Sync *eglSync = eglSyncIter.second;
EGLSync eglSyncObject = gl::unsafe_int_to_pointer_cast<EGLSync>(eglSyncID.value);
if (!eglSync)
{
continue;
}
CallCapture createEGLSync =
CaptureCreateSync(nullptr, true, context->getDisplay(), eglSync->getType(),
eglSync->getAttributeMap(), eglSyncObject);
CaptureCustomCreateEGLSync("CreateEGLSyncKHR", createEGLSync, *setupCalls);
CaptureEGLSyncResetCalls(context, replayState, resourceTracker, eglSyncID, eglSyncObject,
eglSync);
resourceTracker->getTrackedResource(context->id(), ResourceIDType::egl_Sync)
.getStartingResources()
.insert(eglSyncID.value);
}
GLint contextUnpackAlignment = context->getState().getUnpackState().alignment;
if (currentUnpackState.alignment != contextUnpackAlignment)
{
@@ -7563,6 +7648,33 @@ void FrameCaptureShared::maybeCapturePreCallUpdates(
egl::AttributeMap::CreateFromIntArray);
break;
}
case EntryPoint::EGLCreateSync:
case EntryPoint::EGLCreateSyncKHR:
{
egl::SyncID eglSyncID = call.params.getReturnValue().value.egl_SyncIDVal;
FrameCaptureShared *frameCaptureShared =
context->getShareGroup()->getFrameCaptureShared();
// If we're capturing, track which egl sync has been created
if (frameCaptureShared->isCaptureActive())
{
handleGennedResource(context, eglSyncID);
}
break;
}
case EntryPoint::EGLDestroySync:
case EntryPoint::EGLDestroySyncKHR:
{
egl::SyncID eglSyncID =
call.params.getParam("syncPacked", ParamType::Tegl_SyncID, 1).value.egl_SyncIDVal;
FrameCaptureShared *frameCaptureShared =
context->getShareGroup()->getFrameCaptureShared();
// If we're capturing, track which EGL sync has been deleted
if (frameCaptureShared->isCaptureActive())
{
handleDeletedResource(context, eglSyncID);
}
break;
}
case EntryPoint::GLDispatchCompute:
{
// When using shadow memory we need to update the real memory here
@@ -8509,7 +8621,7 @@ TrackedResource &ResourceTracker::getTrackedResource(gl::ContextID contextID, Re
{
if (IsSharedObjectResource(type))
{
// No need to index with context if not shared
// No need to index with context if shared
return mTrackedResourcesShared[static_cast<uint32_t>(type)];
}
else

View File

@@ -311,6 +311,7 @@ void FinishReplay()
delete[] gBufferMap;
delete[] gContextMap2;
delete[] gEGLImageMap2;
delete[] gEGLSyncMap;
delete[] gRenderbufferMap;
delete[] gTextureMap;
delete[] gFramebufferMap;