mirror of
https://github.com/godotengine/godot-angle-static.git
synced 2026-01-03 14:09:33 +03:00
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:
committed by
Angle LUCI CQ
parent
76b0e7f38b
commit
d8339e78db
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -311,6 +311,7 @@ void FinishReplay()
|
||||
delete[] gBufferMap;
|
||||
delete[] gContextMap2;
|
||||
delete[] gEGLImageMap2;
|
||||
delete[] gEGLSyncMap;
|
||||
delete[] gRenderbufferMap;
|
||||
delete[] gTextureMap;
|
||||
delete[] gFramebufferMap;
|
||||
|
||||
Reference in New Issue
Block a user