Commit d0b270e6 by Jamie Madill Committed by Commit Bot

Feedback Loop Redesign 1/3: Framebuffer Serials.

Currently we track feedback loops by counting the times a Texture is bound as a sampler or image in a particular context. This is a bit tricky because Texture bindings change frequently. Relative to the number of times we need to check for a feedback loop this causes excess overhead. Usually Framebuffers have a low number of Textures bound (in many cases just 1). And Textures aren't usually bound to many different FBOs. So instead of counting the number of times a Texture is bound as a sampler or image we will track the Framebuffers that the Texture is bound to. Because FBOs are unique to a Context, a Texture could be bound to two different FBOs with the same ID. In this CL we introduce a new Serial for the FBO which is unique to an EGL Share Group. This way we can ensure we don't make the wrong call when a Texture is referenced by a Framebuffer. It also replaces the old FB serial which was again only unique to a particular Context. Bug: angleproject:4500 Bug: angleproject:4959 Change-Id: I0a9989d861a4132bd3b7ed85f699a4448ff37a4e Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2358849Reviewed-by: 's avatarJonah Ryan-Davis <jonahr@google.com> Reviewed-by: 's avatarTobin Ehlis <tobine@google.com> Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 85919ef7
...@@ -1080,7 +1080,8 @@ void Context::bindTexture(TextureType target, TextureID handle) ...@@ -1080,7 +1080,8 @@ void Context::bindTexture(TextureType target, TextureID handle)
void Context::bindReadFramebuffer(FramebufferID framebufferHandle) void Context::bindReadFramebuffer(FramebufferID framebufferHandle)
{ {
Framebuffer *framebuffer = mState.mFramebufferManager->checkFramebufferAllocation( Framebuffer *framebuffer = mState.mFramebufferManager->checkFramebufferAllocation(
mImplementation.get(), mState.mCaps, framebufferHandle, mState.getContextID()); mImplementation.get(), mState.mCaps, framebufferHandle, mState.getContextID(),
getShareGroup());
mState.setReadFramebufferBinding(framebuffer); mState.setReadFramebufferBinding(framebuffer);
mReadFramebufferObserverBinding.bind(framebuffer); mReadFramebufferObserverBinding.bind(framebuffer);
} }
...@@ -1088,7 +1089,8 @@ void Context::bindReadFramebuffer(FramebufferID framebufferHandle) ...@@ -1088,7 +1089,8 @@ void Context::bindReadFramebuffer(FramebufferID framebufferHandle)
void Context::bindDrawFramebuffer(FramebufferID framebufferHandle) void Context::bindDrawFramebuffer(FramebufferID framebufferHandle)
{ {
Framebuffer *framebuffer = mState.mFramebufferManager->checkFramebufferAllocation( Framebuffer *framebuffer = mState.mFramebufferManager->checkFramebufferAllocation(
mImplementation.get(), mState.mCaps, framebufferHandle, mState.getContextID()); mImplementation.get(), mState.mCaps, framebufferHandle, mState.getContextID(),
getShareGroup());
mState.setDrawFramebufferBinding(framebuffer); mState.setDrawFramebufferBinding(framebuffer);
mDrawFramebufferObserverBinding.bind(framebuffer); mDrawFramebufferObserverBinding.bind(framebuffer);
mStateCache.onDrawFramebufferChange(this); mStateCache.onDrawFramebufferChange(this);
......
...@@ -632,6 +632,8 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl ...@@ -632,6 +632,8 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
void release() const { mRefCount--; } void release() const { mRefCount--; }
size_t getRefCount() const { return mRefCount; } size_t getRefCount() const { return mRefCount; }
egl::ShareGroup *getShareGroup() const { return mState.getShareGroup(); }
private: private:
void initialize(); void initialize();
......
...@@ -77,12 +77,15 @@ class ShareGroup final : angle::NonCopyable ...@@ -77,12 +77,15 @@ class ShareGroup final : angle::NonCopyable
rx::ShareGroupImpl *getImplementation() const { return mImplementation; } rx::ShareGroupImpl *getImplementation() const { return mImplementation; }
rx::Serial generateFramebufferSerial() { return mFramebufferSerialFactory.generate(); }
protected: protected:
~ShareGroup(); ~ShareGroup();
private: private:
size_t mRefCount; size_t mRefCount;
rx::ShareGroupImpl *mImplementation; rx::ShareGroupImpl *mImplementation;
rx::SerialFactory mFramebufferSerialFactory;
}; };
// Constant coded here as a sanity limit. // Constant coded here as a sanity limit.
......
...@@ -265,8 +265,9 @@ angle::Result InitAttachment(const Context *context, FramebufferAttachment *atta ...@@ -265,8 +265,9 @@ angle::Result InitAttachment(const Context *context, FramebufferAttachment *atta
} // anonymous namespace } // anonymous namespace
// This constructor is only used for default framebuffers. // This constructor is only used for default framebuffers.
FramebufferState::FramebufferState(ContextID owningContextID) FramebufferState::FramebufferState(ContextID owningContextID, rx::Serial serial)
: mId(Framebuffer::kDefaultDrawFramebufferHandle), : mId(Framebuffer::kDefaultDrawFramebufferHandle),
mFramebufferSerial(serial),
mOwningContextID(owningContextID), mOwningContextID(owningContextID),
mLabel(), mLabel(),
mColorAttachments(1), mColorAttachments(1),
...@@ -288,8 +289,12 @@ FramebufferState::FramebufferState(ContextID owningContextID) ...@@ -288,8 +289,12 @@ FramebufferState::FramebufferState(ContextID owningContextID)
mEnabledDrawBuffers.set(0); mEnabledDrawBuffers.set(0);
} }
FramebufferState::FramebufferState(const Caps &caps, FramebufferID id, ContextID owningContextID) FramebufferState::FramebufferState(const Caps &caps,
FramebufferID id,
ContextID owningContextID,
rx::Serial serial)
: mId(id), : mId(id),
mFramebufferSerial(serial),
mOwningContextID(owningContextID), mOwningContextID(owningContextID),
mLabel(), mLabel(),
mColorAttachments(caps.maxColorAttachments), mColorAttachments(caps.maxColorAttachments),
...@@ -708,9 +713,9 @@ const FramebufferID Framebuffer::kDefaultDrawFramebufferHandle = {0}; ...@@ -708,9 +713,9 @@ const FramebufferID Framebuffer::kDefaultDrawFramebufferHandle = {0};
Framebuffer::Framebuffer(const Caps &caps, Framebuffer::Framebuffer(const Caps &caps,
rx::GLImplFactory *factory, rx::GLImplFactory *factory,
FramebufferID id, FramebufferID id,
ContextID owningContextID) ContextID owningContextID,
: mSerial(factory->generateSerial()), egl::ShareGroup *shareGroup)
mState(caps, id, owningContextID), : mState(caps, id, owningContextID, shareGroup->generateFramebufferSerial()),
mImpl(factory->createFramebuffer(mState)), mImpl(factory->createFramebuffer(mState)),
mCachedStatus(), mCachedStatus(),
mDirtyDepthAttachmentBinding(this, DIRTY_BIT_DEPTH_ATTACHMENT), mDirtyDepthAttachmentBinding(this, DIRTY_BIT_DEPTH_ATTACHMENT),
...@@ -728,8 +733,7 @@ Framebuffer::Framebuffer(const Caps &caps, ...@@ -728,8 +733,7 @@ Framebuffer::Framebuffer(const Caps &caps,
} }
Framebuffer::Framebuffer(const Context *context, egl::Surface *surface, egl::Surface *readSurface) Framebuffer::Framebuffer(const Context *context, egl::Surface *surface, egl::Surface *readSurface)
: mSerial(context->getImplementation()->generateSerial()), : mState(context->id(), context->getShareGroup()->generateFramebufferSerial()),
mState(context->id()),
mImpl(surface->getImplementation()->createDefaultFramebuffer(context, mState)), mImpl(surface->getImplementation()->createDefaultFramebuffer(context, mState)),
mCachedStatus(GL_FRAMEBUFFER_COMPLETE), mCachedStatus(GL_FRAMEBUFFER_COMPLETE),
mDirtyDepthAttachmentBinding(this, DIRTY_BIT_DEPTH_ATTACHMENT), mDirtyDepthAttachmentBinding(this, DIRTY_BIT_DEPTH_ATTACHMENT),
...@@ -771,7 +775,7 @@ Framebuffer::Framebuffer(const Context *context, egl::Surface *surface, egl::Sur ...@@ -771,7 +775,7 @@ Framebuffer::Framebuffer(const Context *context, egl::Surface *surface, egl::Sur
Framebuffer::Framebuffer(const Context *context, Framebuffer::Framebuffer(const Context *context,
rx::GLImplFactory *factory, rx::GLImplFactory *factory,
egl::Surface *readSurface) egl::Surface *readSurface)
: mState(context->id()), : mState(context->id(), context->getShareGroup()->generateFramebufferSerial()),
mImpl(factory->createFramebuffer(mState)), mImpl(factory->createFramebuffer(mState)),
mCachedStatus(GL_FRAMEBUFFER_UNDEFINED_OES), mCachedStatus(GL_FRAMEBUFFER_UNDEFINED_OES),
mDirtyDepthAttachmentBinding(this, DIRTY_BIT_DEPTH_ATTACHMENT), mDirtyDepthAttachmentBinding(this, DIRTY_BIT_DEPTH_ATTACHMENT),
......
...@@ -53,8 +53,11 @@ class TextureCapsMap; ...@@ -53,8 +53,11 @@ class TextureCapsMap;
class FramebufferState final : angle::NonCopyable class FramebufferState final : angle::NonCopyable
{ {
public: public:
explicit FramebufferState(ContextID owningContextID); explicit FramebufferState(ContextID owningContextID, rx::Serial serial);
FramebufferState(const Caps &caps, FramebufferID id, ContextID owningContextID); FramebufferState(const Caps &caps,
FramebufferID id,
ContextID owningContextID,
rx::Serial serial);
~FramebufferState(); ~FramebufferState();
const std::string &getLabel() const; const std::string &getLabel() const;
...@@ -123,6 +126,8 @@ class FramebufferState final : angle::NonCopyable ...@@ -123,6 +126,8 @@ class FramebufferState final : angle::NonCopyable
const gl::Offset &getSurfaceTextureOffset() const { return mSurfaceTextureOffset; } const gl::Offset &getSurfaceTextureOffset() const { return mSurfaceTextureOffset; }
rx::Serial getFramebufferSerial() const { return mFramebufferSerial; }
private: private:
const FramebufferAttachment *getWebGLDepthStencilAttachment() const; const FramebufferAttachment *getWebGLDepthStencilAttachment() const;
const FramebufferAttachment *getWebGLDepthAttachment() const; const FramebufferAttachment *getWebGLDepthAttachment() const;
...@@ -134,7 +139,12 @@ class FramebufferState final : angle::NonCopyable ...@@ -134,7 +139,12 @@ class FramebufferState final : angle::NonCopyable
friend class Framebuffer; friend class Framebuffer;
// The Framebuffer ID is unique to a Context.
// The Framebuffer Serial is unique to a Share Group.
FramebufferID mId; FramebufferID mId;
rx::Serial mFramebufferSerial;
// TODO(jmadill): Remove the owning context ID. http://anglebug.com/4500
ContextID mOwningContextID; ContextID mOwningContextID;
std::string mLabel; std::string mLabel;
...@@ -184,7 +194,8 @@ class Framebuffer final : public angle::ObserverInterface, ...@@ -184,7 +194,8 @@ class Framebuffer final : public angle::ObserverInterface,
Framebuffer(const Caps &caps, Framebuffer(const Caps &caps,
rx::GLImplFactory *factory, rx::GLImplFactory *factory,
FramebufferID id, FramebufferID id,
ContextID owningContextID); ContextID owningContextID,
egl::ShareGroup *shareGroup);
// Constructor to build default framebuffers for a surface and context pair // Constructor to build default framebuffers for a surface and context pair
Framebuffer(const Context *context, egl::Surface *surface, egl::Surface *readSurface); Framebuffer(const Context *context, egl::Surface *surface, egl::Surface *readSurface);
// Constructor to build a fake default framebuffer when surfaceless // Constructor to build a fake default framebuffer when surfaceless
...@@ -415,8 +426,6 @@ class Framebuffer final : public angle::ObserverInterface, ...@@ -415,8 +426,6 @@ class Framebuffer final : public angle::ObserverInterface,
static const FramebufferID kDefaultDrawFramebufferHandle; static const FramebufferID kDefaultDrawFramebufferHandle;
rx::Serial serial() const { return mSerial; }
private: private:
bool detachResourceById(const Context *context, GLenum resourceType, GLuint resourceId); bool detachResourceById(const Context *context, GLenum resourceType, GLuint resourceId);
bool detachMatchingAttachment(const Context *context, bool detachMatchingAttachment(const Context *context,
...@@ -482,7 +491,6 @@ class Framebuffer final : public angle::ObserverInterface, ...@@ -482,7 +491,6 @@ class Framebuffer final : public angle::ObserverInterface,
mFloat32ColorAttachmentBits.set(index, format->type == GL_FLOAT); mFloat32ColorAttachmentBits.set(index, format->type == GL_FLOAT);
} }
rx::Serial mSerial;
FramebufferState mState; FramebufferState mState;
rx::FramebufferImpl *mImpl; rx::FramebufferImpl *mImpl;
......
...@@ -351,11 +351,12 @@ Sync *SyncManager::getSync(GLuint handle) const ...@@ -351,11 +351,12 @@ Sync *SyncManager::getSync(GLuint handle) const
Framebuffer *FramebufferManager::AllocateNewObject(rx::GLImplFactory *factory, Framebuffer *FramebufferManager::AllocateNewObject(rx::GLImplFactory *factory,
FramebufferID handle, FramebufferID handle,
const Caps &caps, const Caps &caps,
ContextID owningContextID) ContextID owningContextID,
egl::ShareGroup *shareGroup)
{ {
// Make sure the caller isn't using a reserved handle. // Make sure the caller isn't using a reserved handle.
ASSERT(handle != Framebuffer::kDefaultDrawFramebufferHandle); ASSERT(handle != Framebuffer::kDefaultDrawFramebufferHandle);
return new Framebuffer(caps, factory, handle, owningContextID); return new Framebuffer(caps, factory, handle, owningContextID, shareGroup);
} }
// static // static
......
...@@ -19,14 +19,18 @@ ...@@ -19,14 +19,18 @@
namespace rx namespace rx
{ {
class GLImplFactory; class GLImplFactory;
} } // namespace rx
namespace egl
{
class ShareGroup;
} // namespace egl
namespace gl namespace gl
{ {
class Buffer; class Buffer;
struct Caps; struct Caps;
class Context; class Context;
class Sync;
class Framebuffer; class Framebuffer;
struct Limitations; struct Limitations;
class MemoryObject; class MemoryObject;
...@@ -35,8 +39,9 @@ class Program; ...@@ -35,8 +39,9 @@ class Program;
class ProgramPipeline; class ProgramPipeline;
class Renderbuffer; class Renderbuffer;
class Sampler; class Sampler;
class Shader;
class Semaphore; class Semaphore;
class Shader;
class Sync;
class Texture; class Texture;
template <typename HandleAllocatorType> template <typename HandleAllocatorType>
...@@ -276,15 +281,18 @@ class FramebufferManager ...@@ -276,15 +281,18 @@ class FramebufferManager
Framebuffer *checkFramebufferAllocation(rx::GLImplFactory *factory, Framebuffer *checkFramebufferAllocation(rx::GLImplFactory *factory,
const Caps &caps, const Caps &caps,
FramebufferID handle, FramebufferID handle,
ContextID owningContextID) ContextID owningContextID,
egl::ShareGroup *shareGroup)
{ {
return checkObjectAllocation<const Caps &>(factory, handle, caps, owningContextID); return checkObjectAllocation<const Caps &>(factory, handle, caps, owningContextID,
shareGroup);
} }
static Framebuffer *AllocateNewObject(rx::GLImplFactory *factory, static Framebuffer *AllocateNewObject(rx::GLImplFactory *factory,
FramebufferID handle, FramebufferID handle,
const Caps &caps, const Caps &caps,
ContextID owningContextID); ContextID owningContextID,
egl::ShareGroup *shareGroup);
static void DeleteObject(const Context *context, Framebuffer *framebuffer); static void DeleteObject(const Context *context, Framebuffer *framebuffer);
protected: protected:
......
...@@ -20,7 +20,7 @@ namespace rx ...@@ -20,7 +20,7 @@ namespace rx
class MockFramebufferImpl : public rx::FramebufferImpl class MockFramebufferImpl : public rx::FramebufferImpl
{ {
public: public:
MockFramebufferImpl() : rx::FramebufferImpl(gl::FramebufferState(1)) {} MockFramebufferImpl() : rx::FramebufferImpl(gl::FramebufferState(1, rx::Serial())) {}
virtual ~MockFramebufferImpl() { destructor(); } virtual ~MockFramebufferImpl() { destructor(); }
MOCK_METHOD3(discard, angle::Result(const gl::Context *, size_t, const GLenum *)); MOCK_METHOD3(discard, angle::Result(const gl::Context *, size_t, const GLenum *));
......
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