Commit ea3f501e by Jamie Madill Committed by Commit Bot

Feedback Loop Redesign 3/3: Remove feedback loop tracking.

We now we detect feedback loops by tracking the Framebuffers that the Texture is bound to. We still have the old tracking method that counts sampler and image bindings in the code as well. This CL removes the old front-end tracking for feedback loops. It's no longer used by any back-ends. This removal should reduce CPU overhead around Texture and Program binding changes. Reverts the image binding tracking to the simpler scheme that tracks if a Texture has ever been bound as an Image. This should practically have little or no perf effect and we can reinstate some simpler tracking in the future if required. Bug: angleproject:4500 Bug: angleproject:4959 Change-Id: Idc625d6e4c519919f97a4dc72dd9c35d262706fb Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2363210 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarTobin Ehlis <tobine@google.com> Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com>
parent ba1e049f
...@@ -1080,8 +1080,7 @@ void Context::bindTexture(TextureType target, TextureID handle) ...@@ -1080,8 +1080,7 @@ 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, getShareGroup());
getShareGroup());
mState.setReadFramebufferBinding(framebuffer); mState.setReadFramebufferBinding(framebuffer);
mReadFramebufferObserverBinding.bind(framebuffer); mReadFramebufferObserverBinding.bind(framebuffer);
} }
...@@ -1089,8 +1088,7 @@ void Context::bindReadFramebuffer(FramebufferID framebufferHandle) ...@@ -1089,8 +1088,7 @@ 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, getShareGroup());
getShareGroup());
mState.setDrawFramebufferBinding(framebuffer); mState.setDrawFramebufferBinding(framebuffer);
mDrawFramebufferObserverBinding.bind(framebuffer); mDrawFramebufferObserverBinding.bind(framebuffer);
mStateCache.onDrawFramebufferChange(this); mStateCache.onDrawFramebufferChange(this);
......
...@@ -265,10 +265,9 @@ angle::Result InitAttachment(const Context *context, FramebufferAttachment *atta ...@@ -265,10 +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, rx::Serial serial) FramebufferState::FramebufferState(rx::Serial serial)
: mId(Framebuffer::kDefaultDrawFramebufferHandle), : mId(Framebuffer::kDefaultDrawFramebufferHandle),
mFramebufferSerial(serial), mFramebufferSerial(serial),
mOwningContextID(owningContextID),
mLabel(), mLabel(),
mColorAttachments(1), mColorAttachments(1),
mDrawBufferStates(1, GL_BACK), mDrawBufferStates(1, GL_BACK),
...@@ -280,22 +279,15 @@ FramebufferState::FramebufferState(ContextID owningContextID, rx::Serial serial) ...@@ -280,22 +279,15 @@ FramebufferState::FramebufferState(ContextID owningContextID, rx::Serial serial)
mDefaultFixedSampleLocations(GL_FALSE), mDefaultFixedSampleLocations(GL_FALSE),
mDefaultLayers(0), mDefaultLayers(0),
mWebGLDepthStencilConsistent(true), mWebGLDepthStencilConsistent(true),
mDepthBufferFeedbackLoop(false),
mStencilBufferFeedbackLoop(false),
mHasRenderingFeedbackLoop(false),
mDefaultFramebufferReadAttachmentInitialized(false) mDefaultFramebufferReadAttachmentInitialized(false)
{ {
ASSERT(mDrawBufferStates.size() > 0); ASSERT(mDrawBufferStates.size() > 0);
mEnabledDrawBuffers.set(0); mEnabledDrawBuffers.set(0);
} }
FramebufferState::FramebufferState(const Caps &caps, FramebufferState::FramebufferState(const Caps &caps, FramebufferID id, rx::Serial serial)
FramebufferID id,
ContextID owningContextID,
rx::Serial serial)
: mId(id), : mId(id),
mFramebufferSerial(serial), mFramebufferSerial(serial),
mOwningContextID(owningContextID),
mLabel(), mLabel(),
mColorAttachments(caps.maxColorAttachments), mColorAttachments(caps.maxColorAttachments),
mDrawBufferStates(caps.maxDrawBuffers, GL_NONE), mDrawBufferStates(caps.maxDrawBuffers, GL_NONE),
...@@ -307,9 +299,6 @@ FramebufferState::FramebufferState(const Caps &caps, ...@@ -307,9 +299,6 @@ FramebufferState::FramebufferState(const Caps &caps,
mDefaultFixedSampleLocations(GL_FALSE), mDefaultFixedSampleLocations(GL_FALSE),
mDefaultLayers(0), mDefaultLayers(0),
mWebGLDepthStencilConsistent(true), mWebGLDepthStencilConsistent(true),
mDepthBufferFeedbackLoop(false),
mStencilBufferFeedbackLoop(false),
mHasRenderingFeedbackLoop(false),
mDefaultFramebufferReadAttachmentInitialized(false) mDefaultFramebufferReadAttachmentInitialized(false)
{ {
ASSERT(mId != Framebuffer::kDefaultDrawFramebufferHandle); ASSERT(mId != Framebuffer::kDefaultDrawFramebufferHandle);
...@@ -661,61 +650,13 @@ bool FramebufferState::isDefault() const ...@@ -661,61 +650,13 @@ bool FramebufferState::isDefault() const
return mId == Framebuffer::kDefaultDrawFramebufferHandle; return mId == Framebuffer::kDefaultDrawFramebufferHandle;
} }
bool FramebufferState::updateAttachmentFeedbackLoopAndReturnIfChanged(size_t dirtyBit)
{
bool previous;
bool loop;
switch (dirtyBit)
{
case Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT:
previous = mDepthBufferFeedbackLoop;
loop = mDepthAttachment.isBoundAsSamplerOrImage(mOwningContextID);
mDepthBufferFeedbackLoop = loop;
break;
case Framebuffer::DIRTY_BIT_STENCIL_ATTACHMENT:
previous = mStencilBufferFeedbackLoop;
loop = mStencilAttachment.isBoundAsSamplerOrImage(mOwningContextID);
mStencilBufferFeedbackLoop = loop;
break;
default:
{
ASSERT(dirtyBit <= Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX);
previous = mDrawBufferFeedbackLoops.test(dirtyBit);
loop = mColorAttachments[dirtyBit].isBoundAsSamplerOrImage(mOwningContextID);
mDrawBufferFeedbackLoops[dirtyBit] = loop;
break;
}
}
updateHasRenderingFeedbackLoop();
return previous != loop;
}
void FramebufferState::updateHasRenderingFeedbackLoop()
{
// We don't handle tricky cases where the default FBO is bound as a sampler.
// We also don't handle tricky cases with EGLImages and mipmap selection.
// TODO(http://anglebug.com/4500): Tricky rendering feedback loop cases.
if (isDefault())
{
return;
}
mHasRenderingFeedbackLoop =
mDrawBufferFeedbackLoops.any() || mDepthBufferFeedbackLoop || mStencilBufferFeedbackLoop;
}
const FramebufferID Framebuffer::kDefaultDrawFramebufferHandle = {0}; 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,
egl::ShareGroup *shareGroup) egl::ShareGroup *shareGroup)
: mState(caps, id, owningContextID, shareGroup->generateFramebufferSerial()), : mState(caps, id, shareGroup->generateFramebufferSerial()),
mImpl(factory->createFramebuffer(mState)), mImpl(factory->createFramebuffer(mState)),
mCachedStatus(), mCachedStatus(),
mDirtyDepthAttachmentBinding(this, DIRTY_BIT_DEPTH_ATTACHMENT), mDirtyDepthAttachmentBinding(this, DIRTY_BIT_DEPTH_ATTACHMENT),
...@@ -733,7 +674,7 @@ Framebuffer::Framebuffer(const Caps &caps, ...@@ -733,7 +674,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)
: mState(context->id(), context->getShareGroup()->generateFramebufferSerial()), : mState(context->getShareGroup()->generateFramebufferSerial()),
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),
...@@ -775,7 +716,7 @@ Framebuffer::Framebuffer(const Context *context, egl::Surface *surface, egl::Sur ...@@ -775,7 +716,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(), context->getShareGroup()->generateFramebufferSerial()), : mState(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),
...@@ -1876,7 +1817,6 @@ void Framebuffer::updateAttachment(const Context *context, ...@@ -1876,7 +1817,6 @@ void Framebuffer::updateAttachment(const Context *context,
mState.mResourceNeedsInit.set(dirtyBit, attachment->initState() == InitState::MayNeedInit); mState.mResourceNeedsInit.set(dirtyBit, attachment->initState() == InitState::MayNeedInit);
onDirtyBinding->bind(resource); onDirtyBinding->bind(resource);
mState.updateAttachmentFeedbackLoopAndReturnIfChanged(dirtyBit);
invalidateCompletenessCache(); invalidateCompletenessCache();
} }
...@@ -1911,16 +1851,7 @@ void Framebuffer::onSubjectStateChange(angle::SubjectIndex index, angle::Subject ...@@ -1911,16 +1851,7 @@ void Framebuffer::onSubjectStateChange(angle::SubjectIndex index, angle::Subject
return; return;
} }
// Triggered by changes to Texture feedback loops. ASSERT(message != angle::SubjectMessage::BindingChanged);
if (message == angle::SubjectMessage::BindingChanged)
{
if (mState.updateAttachmentFeedbackLoopAndReturnIfChanged(index))
{
mDirtyBits.set(index);
onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
}
return;
}
// This can be triggered by external changes to the default framebuffer. // This can be triggered by external changes to the default framebuffer.
if (message == angle::SubjectMessage::SurfaceChanged) if (message == angle::SubjectMessage::SurfaceChanged)
......
...@@ -53,11 +53,8 @@ class TextureCapsMap; ...@@ -53,11 +53,8 @@ class TextureCapsMap;
class FramebufferState final : angle::NonCopyable class FramebufferState final : angle::NonCopyable
{ {
public: public:
explicit FramebufferState(ContextID owningContextID, rx::Serial serial); explicit FramebufferState(rx::Serial serial);
FramebufferState(const Caps &caps, FramebufferState(const Caps &caps, FramebufferID id, rx::Serial serial);
FramebufferID id,
ContextID owningContextID,
rx::Serial serial);
~FramebufferState(); ~FramebufferState();
const std::string &getLabel() const; const std::string &getLabel() const;
...@@ -119,11 +116,6 @@ class FramebufferState final : angle::NonCopyable ...@@ -119,11 +116,6 @@ class FramebufferState final : angle::NonCopyable
bool isDefault() const; bool isDefault() const;
bool hasDepthStencilFeedbackLoop() const
{
return mDepthBufferFeedbackLoop || mStencilBufferFeedbackLoop;
}
const gl::Offset &getSurfaceTextureOffset() const { return mSurfaceTextureOffset; } const gl::Offset &getSurfaceTextureOffset() const { return mSurfaceTextureOffset; }
rx::Serial getFramebufferSerial() const { return mFramebufferSerial; } rx::Serial getFramebufferSerial() const { return mFramebufferSerial; }
...@@ -133,19 +125,12 @@ class FramebufferState final : angle::NonCopyable ...@@ -133,19 +125,12 @@ class FramebufferState final : angle::NonCopyable
const FramebufferAttachment *getWebGLDepthAttachment() const; const FramebufferAttachment *getWebGLDepthAttachment() const;
const FramebufferAttachment *getWebGLStencilAttachment() const; const FramebufferAttachment *getWebGLStencilAttachment() const;
// Returns true if there was a change in this attachments feedback-loop-ness.
bool updateAttachmentFeedbackLoopAndReturnIfChanged(size_t dirtyBit);
void updateHasRenderingFeedbackLoop();
friend class Framebuffer; friend class Framebuffer;
// The Framebuffer ID is unique to a Context. // The Framebuffer ID is unique to a Context.
// The Framebuffer Serial is unique to a Share Group. // The Framebuffer Serial is unique to a Share Group.
FramebufferID mId; FramebufferID mId;
rx::Serial mFramebufferSerial; rx::Serial mFramebufferSerial;
// TODO(jmadill): Remove the owning context ID. http://anglebug.com/4500
ContextID mOwningContextID;
std::string mLabel; std::string mLabel;
std::vector<FramebufferAttachment> mColorAttachments; std::vector<FramebufferAttachment> mColorAttachments;
...@@ -170,13 +155,6 @@ class FramebufferState final : angle::NonCopyable ...@@ -170,13 +155,6 @@ class FramebufferState final : angle::NonCopyable
FramebufferAttachment mWebGLStencilAttachment; FramebufferAttachment mWebGLStencilAttachment;
bool mWebGLDepthStencilConsistent; bool mWebGLDepthStencilConsistent;
// Tracks rendering feedback loops.
// TODO(jmadill): Remove. http://anglebug.com/4500
DrawBufferMask mDrawBufferFeedbackLoops;
bool mDepthBufferFeedbackLoop;
bool mStencilBufferFeedbackLoop;
bool mHasRenderingFeedbackLoop;
// Tracks if we need to initialize the resources for each attachment. // Tracks if we need to initialize the resources for each attachment.
angle::BitSet<IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS + 2> mResourceNeedsInit; angle::BitSet<IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS + 2> mResourceNeedsInit;
...@@ -195,7 +173,6 @@ class Framebuffer final : public angle::ObserverInterface, ...@@ -195,7 +173,6 @@ 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,
egl::ShareGroup *shareGroup); 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);
...@@ -410,9 +387,6 @@ class Framebuffer final : public angle::ObserverInterface, ...@@ -410,9 +387,6 @@ class Framebuffer final : public angle::ObserverInterface,
// Observer implementation // Observer implementation
void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
// TODO(jmadill): Remove. http://anglebug.com/4500
bool hasRenderingFeedbackLoop() const { return mState.mHasRenderingFeedbackLoop; }
bool formsRenderingFeedbackLoopWith(const Context *context) const; bool formsRenderingFeedbackLoopWith(const Context *context) const;
bool formsCopyingFeedbackLoopWith(TextureID copyTextureID, bool formsCopyingFeedbackLoopWith(TextureID copyTextureID,
GLint copyTextureLevel, GLint copyTextureLevel,
......
...@@ -283,18 +283,6 @@ void FramebufferAttachment::setInitState(InitState initState) const ...@@ -283,18 +283,6 @@ void FramebufferAttachment::setInitState(InitState initState) const
mResource->setInitState(mTarget.textureIndex(), initState); mResource->setInitState(mTarget.textureIndex(), initState);
} }
bool FramebufferAttachment::isBoundAsSamplerOrImage(ContextID contextID) const
{
if (mType != GL_TEXTURE)
{
return false;
}
const gl::TextureState &textureState = getTexture()->getTextureState();
return textureState.isBoundAsImageTexture(contextID) ||
textureState.isBoundAsSamplerTexture(contextID);
}
////// FramebufferAttachmentObject Implementation ////// ////// FramebufferAttachmentObject Implementation //////
FramebufferAttachmentObject::FramebufferAttachmentObject() {} FramebufferAttachmentObject::FramebufferAttachmentObject() {}
......
...@@ -94,8 +94,6 @@ class FramebufferAttachment final ...@@ -94,8 +94,6 @@ class FramebufferAttachment final
GLenum getComponentType() const; GLenum getComponentType() const;
GLenum getColorEncoding() const; GLenum getColorEncoding() const;
bool isBoundAsSamplerOrImage(ContextID contextID) const;
bool isTextureWithId(TextureID textureId) const bool isTextureWithId(TextureID textureId) const
{ {
return mType == GL_TEXTURE && id() == textureId.value; return mType == GL_TEXTURE && id() == textureId.value;
......
...@@ -351,12 +351,11 @@ Sync *SyncManager::getSync(GLuint handle) const ...@@ -351,12 +351,11 @@ 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,
egl::ShareGroup *shareGroup) 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, shareGroup); return new Framebuffer(caps, factory, handle, shareGroup);
} }
// static // static
......
...@@ -281,17 +281,14 @@ class FramebufferManager ...@@ -281,17 +281,14 @@ class FramebufferManager
Framebuffer *checkFramebufferAllocation(rx::GLImplFactory *factory, Framebuffer *checkFramebufferAllocation(rx::GLImplFactory *factory,
const Caps &caps, const Caps &caps,
FramebufferID handle, FramebufferID handle,
ContextID owningContextID,
egl::ShareGroup *shareGroup) egl::ShareGroup *shareGroup)
{ {
return checkObjectAllocation<const Caps &>(factory, handle, caps, owningContextID, return checkObjectAllocation<const Caps &>(factory, handle, caps, shareGroup);
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,
egl::ShareGroup *shareGroup); egl::ShareGroup *shareGroup);
static void DeleteObject(const Context *context, Framebuffer *framebuffer); static void DeleteObject(const Context *context, Framebuffer *framebuffer);
......
...@@ -245,11 +245,11 @@ ActiveTexturesCache::~ActiveTexturesCache() ...@@ -245,11 +245,11 @@ ActiveTexturesCache::~ActiveTexturesCache()
ASSERT(empty()); ASSERT(empty());
} }
void ActiveTexturesCache::clear(ContextID contextID) void ActiveTexturesCache::clear()
{ {
for (size_t textureIndex = 0; textureIndex < mTextures.size(); ++textureIndex) for (size_t textureIndex = 0; textureIndex < mTextures.size(); ++textureIndex)
{ {
reset(contextID, textureIndex); reset(textureIndex);
} }
} }
...@@ -266,27 +266,17 @@ bool ActiveTexturesCache::empty() const ...@@ -266,27 +266,17 @@ bool ActiveTexturesCache::empty() const
return true; return true;
} }
ANGLE_INLINE void ActiveTexturesCache::reset(ContextID contextID, size_t textureIndex) ANGLE_INLINE void ActiveTexturesCache::reset(size_t textureIndex)
{ {
if (mTextures[textureIndex]) if (mTextures[textureIndex])
{ {
mTextures[textureIndex]->onUnbindAsSamplerTexture(contextID);
mTextures[textureIndex] = nullptr; mTextures[textureIndex] = nullptr;
} }
} }
ANGLE_INLINE void ActiveTexturesCache::set(ContextID contextID, ANGLE_INLINE void ActiveTexturesCache::set(size_t textureIndex, Texture *texture)
size_t textureIndex,
Texture *texture)
{ {
// We don't call reset() here to avoid setting nullptr before rebind.
if (mTextures[textureIndex])
{
mTextures[textureIndex]->onUnbindAsSamplerTexture(contextID);
}
ASSERT(texture); ASSERT(texture);
texture->onBindAsSamplerTexture(contextID);
mTextures[textureIndex] = texture; mTextures[textureIndex] = texture;
} }
...@@ -514,7 +504,7 @@ void State::initialize(Context *context) ...@@ -514,7 +504,7 @@ void State::initialize(Context *context)
void State::reset(const Context *context) void State::reset(const Context *context)
{ {
mActiveTexturesCache.clear(mID); mActiveTexturesCache.clear();
for (auto &bindingVec : mSamplerTextures) for (auto &bindingVec : mSamplerTextures)
{ {
...@@ -589,7 +579,7 @@ ANGLE_INLINE void State::unsetActiveTextures(ActiveTextureMask textureMask) ...@@ -589,7 +579,7 @@ ANGLE_INLINE void State::unsetActiveTextures(ActiveTextureMask textureMask)
// Unset any relevant bound textures. // Unset any relevant bound textures.
for (size_t textureIndex : textureMask) for (size_t textureIndex : textureMask)
{ {
mActiveTexturesCache.reset(mID, textureIndex); mActiveTexturesCache.reset(textureIndex);
mCompleteTextureBindings[textureIndex].reset(); mCompleteTextureBindings[textureIndex].reset();
} }
} }
...@@ -601,11 +591,11 @@ ANGLE_INLINE void State::updateActiveTextureState(const Context *context, ...@@ -601,11 +591,11 @@ ANGLE_INLINE void State::updateActiveTextureState(const Context *context,
{ {
if (!texture || !texture->isSamplerComplete(context, sampler)) if (!texture || !texture->isSamplerComplete(context, sampler))
{ {
mActiveTexturesCache.reset(mID, textureIndex); mActiveTexturesCache.reset(textureIndex);
} }
else else
{ {
mActiveTexturesCache.set(mID, textureIndex, texture); mActiveTexturesCache.set(textureIndex, texture);
if (texture->hasAnyDirtyBit()) if (texture->hasAnyDirtyBit())
{ {
...@@ -644,7 +634,7 @@ ANGLE_INLINE void State::updateActiveTexture(const Context *context, ...@@ -644,7 +634,7 @@ ANGLE_INLINE void State::updateActiveTexture(const Context *context,
if (!texture) if (!texture)
{ {
mActiveTexturesCache.reset(mID, textureIndex); mActiveTexturesCache.reset(textureIndex);
mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS); mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
return; return;
} }
...@@ -3377,13 +3367,9 @@ void State::setImageUnit(const Context *context, ...@@ -3377,13 +3367,9 @@ void State::setImageUnit(const Context *context,
{ {
ImageUnit &imageUnit = mImageUnits[unit]; ImageUnit &imageUnit = mImageUnits[unit];
if (imageUnit.texture.get())
{
imageUnit.texture->onUnbindAsImageTexture(mID);
}
if (texture) if (texture)
{ {
texture->onBindAsImageTexture(mID); texture->onBindAsImageTexture();
} }
imageUnit.texture.set(context, texture); imageUnit.texture.set(context, texture);
imageUnit.level = level; imageUnit.level = level;
......
...@@ -78,9 +78,9 @@ class ActiveTexturesCache final : angle::NonCopyable ...@@ -78,9 +78,9 @@ class ActiveTexturesCache final : angle::NonCopyable
Texture *operator[](size_t textureIndex) const { return mTextures[textureIndex]; } Texture *operator[](size_t textureIndex) const { return mTextures[textureIndex]; }
void clear(ContextID contextID); void clear();
void set(ContextID contextID, size_t textureIndex, Texture *texture); void set(size_t textureIndex, Texture *texture);
void reset(ContextID contextID, size_t textureIndex); void reset(size_t textureIndex);
bool empty() const; bool empty() const;
private: private:
......
...@@ -99,6 +99,7 @@ TextureState::TextureState(TextureType type) ...@@ -99,6 +99,7 @@ TextureState::TextureState(TextureType type)
mBaseLevel(0), mBaseLevel(0),
mMaxLevel(kInitialMaxLevel), mMaxLevel(kInitialMaxLevel),
mDepthStencilTextureMode(GL_DEPTH_COMPONENT), mDepthStencilTextureMode(GL_DEPTH_COMPONENT),
mHasBeenBoundAsImage(false),
mImmutableFormat(false), mImmutableFormat(false),
mImmutableLevels(0), mImmutableLevels(0),
mUsage(GL_NONE), mUsage(GL_NONE),
...@@ -2024,15 +2025,12 @@ angle::Result Texture::getTexImage(const Context *context, ...@@ -2024,15 +2025,12 @@ angle::Result Texture::getTexImage(const Context *context,
pixels); pixels);
} }
void Texture::onBindAsImageTexture(ContextID contextID) void Texture::onBindAsImageTexture()
{ {
ContextBindingCount &bindingCount = mState.getBindingCount(contextID); if (!mState.mHasBeenBoundAsImage)
ASSERT(bindingCount.imageBindingCount < std::numeric_limits<uint32_t>::max());
mState.getBindingCount(contextID).imageBindingCount++;
if (bindingCount.imageBindingCount == 1)
{ {
mDirtyBits.set(DIRTY_BIT_BOUND_AS_IMAGE); mDirtyBits.set(DIRTY_BIT_BOUND_AS_IMAGE);
mState.mHasBeenBoundAsImage = true;
} }
} }
......
...@@ -94,13 +94,6 @@ struct SwizzleState final ...@@ -94,13 +94,6 @@ struct SwizzleState final
GLenum swizzleAlpha; GLenum swizzleAlpha;
}; };
struct ContextBindingCount
{
ContextID contextID;
uint32_t samplerBindingCount;
uint32_t imageBindingCount;
};
// State from Table 6.9 (state per texture object) in the OpenGL ES 3.0.2 spec. // State from Table 6.9 (state per texture object) in the OpenGL ES 3.0.2 spec.
class TextureState final : private angle::NonCopyable class TextureState final : private angle::NonCopyable
{ {
...@@ -147,15 +140,7 @@ class TextureState final : private angle::NonCopyable ...@@ -147,15 +140,7 @@ class TextureState final : private angle::NonCopyable
GLenum getDepthStencilTextureMode() const { return mDepthStencilTextureMode; } GLenum getDepthStencilTextureMode() const { return mDepthStencilTextureMode; }
bool isStencilMode() const { return mDepthStencilTextureMode == GL_STENCIL_INDEX; } bool isStencilMode() const { return mDepthStencilTextureMode == GL_STENCIL_INDEX; }
// TODO(jmadill): Remove. http://anglebug.com/4500 bool hasBeenBoundAsImage() const { return mHasBeenBoundAsImage; }
bool isBoundAsSamplerTexture(ContextID contextID) const
{
return getBindingCount(contextID).samplerBindingCount > 0;
}
bool isBoundAsImageTexture(ContextID contextID) const
{
return getBindingCount(contextID).imageBindingCount > 0;
}
gl::SrgbOverride getSRGBOverride() const { return mSrgbOverride; } gl::SrgbOverride getSRGBOverride() const { return mSrgbOverride; }
...@@ -173,8 +158,6 @@ class TextureState final : private angle::NonCopyable ...@@ -173,8 +158,6 @@ class TextureState final : private angle::NonCopyable
// Return the enabled mipmap level count. // Return the enabled mipmap level count.
GLuint getEnabledLevelCount() const; GLuint getEnabledLevelCount() const;
const std::vector<ContextBindingCount> &getBindingCounts() const { return mBindingCounts; }
bool getImmutableFormat() const { return mImmutableFormat; } bool getImmutableFormat() const { return mImmutableFormat; }
GLuint getImmutableLevels() const { return mImmutableLevels; } GLuint getImmutableLevels() const { return mImmutableLevels; }
...@@ -211,22 +194,6 @@ class TextureState final : private angle::NonCopyable ...@@ -211,22 +194,6 @@ class TextureState final : private angle::NonCopyable
void clearImageDesc(TextureTarget target, size_t level); void clearImageDesc(TextureTarget target, size_t level);
void clearImageDescs(); void clearImageDescs();
ContextBindingCount &getBindingCount(ContextID contextID)
{
for (ContextBindingCount &bindingCount : mBindingCounts)
{
if (bindingCount.contextID == contextID)
return bindingCount;
}
mBindingCounts.push_back({contextID, 0, 0});
return mBindingCounts.back();
}
const ContextBindingCount &getBindingCount(ContextID contextID) const
{
return const_cast<TextureState *>(this)->getBindingCount(contextID);
}
const TextureType mType; const TextureType mType;
SwizzleState mSwizzleState; SwizzleState mSwizzleState;
...@@ -240,7 +207,7 @@ class TextureState final : private angle::NonCopyable ...@@ -240,7 +207,7 @@ class TextureState final : private angle::NonCopyable
GLenum mDepthStencilTextureMode; GLenum mDepthStencilTextureMode;
std::vector<ContextBindingCount> mBindingCounts; bool mHasBeenBoundAsImage;
bool mImmutableFormat; bool mImmutableFormat;
GLuint mImmutableLevels; GLuint mImmutableLevels;
...@@ -474,37 +441,7 @@ class Texture final : public RefCountObject<TextureID>, ...@@ -474,37 +441,7 @@ class Texture final : public RefCountObject<TextureID>,
angle::Result generateMipmap(Context *context); angle::Result generateMipmap(Context *context);
void onBindAsImageTexture(ContextID contextID); void onBindAsImageTexture();
ANGLE_INLINE void onUnbindAsImageTexture(ContextID contextID)
{
ASSERT(mState.isBoundAsImageTexture(contextID));
mState.getBindingCount(contextID).imageBindingCount--;
}
ANGLE_INLINE void onBindAsSamplerTexture(ContextID contextID)
{
ContextBindingCount &bindingCount = mState.getBindingCount(contextID);
ASSERT(bindingCount.samplerBindingCount < std::numeric_limits<uint32_t>::max());
bindingCount.samplerBindingCount++;
if (bindingCount.samplerBindingCount == 1)
{
onStateChange(angle::SubjectMessage::BindingChanged);
}
}
ANGLE_INLINE void onUnbindAsSamplerTexture(ContextID contextID)
{
ContextBindingCount &bindingCount = mState.getBindingCount(contextID);
ASSERT(mState.isBoundAsSamplerTexture(contextID));
bindingCount.samplerBindingCount--;
if (bindingCount.samplerBindingCount == 0)
{
onStateChange(angle::SubjectMessage::BindingChanged);
}
}
egl::Surface *getBoundSurface() const; egl::Surface *getBoundSurface() const;
egl::Stream *getBoundStream() const; egl::Stream *getBoundStream() const;
......
...@@ -811,14 +811,6 @@ void SerializeImageDesc(gl::BinaryOutputStream *bos, const gl::ImageDesc &imageD ...@@ -811,14 +811,6 @@ void SerializeImageDesc(gl::BinaryOutputStream *bos, const gl::ImageDesc &imageD
bos->writeEnum(imageDesc.initState); bos->writeEnum(imageDesc.initState);
} }
void SerializeContextBindingCount(gl::BinaryOutputStream *bos,
const gl::ContextBindingCount &contextBindingCount)
{
bos->writeInt(contextBindingCount.contextID);
bos->writeInt(contextBindingCount.imageBindingCount);
bos->writeInt(contextBindingCount.samplerBindingCount);
}
void SerializeTextureState(gl::BinaryOutputStream *bos, const gl::TextureState &textureState) void SerializeTextureState(gl::BinaryOutputStream *bos, const gl::TextureState &textureState)
{ {
bos->writeEnum(textureState.getType()); bos->writeEnum(textureState.getType());
...@@ -828,12 +820,7 @@ void SerializeTextureState(gl::BinaryOutputStream *bos, const gl::TextureState & ...@@ -828,12 +820,7 @@ void SerializeTextureState(gl::BinaryOutputStream *bos, const gl::TextureState &
bos->writeInt(textureState.getBaseLevel()); bos->writeInt(textureState.getBaseLevel());
bos->writeInt(textureState.getMaxLevel()); bos->writeInt(textureState.getMaxLevel());
bos->writeInt(textureState.getDepthStencilTextureMode()); bos->writeInt(textureState.getDepthStencilTextureMode());
const std::vector<gl::ContextBindingCount> &contextBindingCounts = bos->writeInt(textureState.hasBeenBoundAsImage());
textureState.getBindingCounts();
for (const gl::ContextBindingCount &contextBindingCount : contextBindingCounts)
{
SerializeContextBindingCount(bos, contextBindingCount);
}
bos->writeInt(textureState.getImmutableFormat()); bos->writeInt(textureState.getImmutableFormat());
bos->writeInt(textureState.getImmutableLevels()); bos->writeInt(textureState.getImmutableLevels());
bos->writeInt(textureState.getUsage()); bos->writeInt(textureState.getUsage());
......
...@@ -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, rx::Serial())) {} MockFramebufferImpl() : rx::FramebufferImpl(gl::FramebufferState(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 *));
......
...@@ -1379,7 +1379,7 @@ ANGLE_INLINE angle::Result ContextVk::handleDirtyTexturesImpl( ...@@ -1379,7 +1379,7 @@ ANGLE_INLINE angle::Result ContextVk::handleDirtyTexturesImpl(
// Select the appropriate vk::ImageLayout depending on whether the texture is also bound as // Select the appropriate vk::ImageLayout depending on whether the texture is also bound as
// a GL image, and whether the program is a compute or graphics shader. // a GL image, and whether the program is a compute or graphics shader.
vk::ImageLayout textureLayout; vk::ImageLayout textureLayout;
if (textureVk->isBoundAsImageTexture(mState.getContextID())) if (textureVk->hasBeenBoundAsImage())
{ {
textureLayout = executable->isCompute() ? vk::ImageLayout::ComputeShaderWrite textureLayout = executable->isCompute() ? vk::ImageLayout::ComputeShaderWrite
: vk::ImageLayout::AllGraphicsShadersWrite; : vk::ImageLayout::AllGraphicsShadersWrite;
......
...@@ -81,13 +81,13 @@ bool SharedGarbage::destroyIfComplete(RendererVk *renderer, Serial completedSeri ...@@ -81,13 +81,13 @@ bool SharedGarbage::destroyIfComplete(RendererVk *renderer, Serial completedSeri
if (mLifetime.isCurrentlyInUse(completedSerial)) if (mLifetime.isCurrentlyInUse(completedSerial))
return false; return false;
mLifetime.release();
for (GarbageObject &object : mGarbage) for (GarbageObject &object : mGarbage)
{ {
object.destroy(renderer); object.destroy(renderer);
} }
mLifetime.release();
return true; return true;
} }
......
...@@ -2172,6 +2172,9 @@ angle::Result TextureVk::syncState(const gl::Context *context, ...@@ -2172,6 +2172,9 @@ angle::Result TextureVk::syncState(const gl::Context *context,
ANGLE_TRY(initImageViews(contextVk, mImage->getFormat(), baseLevelDesc.format.info->sized, ANGLE_TRY(initImageViews(contextVk, mImage->getFormat(), baseLevelDesc.format.info->sized,
mImage->getLevelCount(), layerCount)); mImage->getLevelCount(), layerCount));
// Let any Framebuffers know we need to refresh the RenderTarget cache.
onStateChange(angle::SubjectMessage::SubjectChanged);
} }
vk::SamplerDesc samplerDesc(mState.getSamplerState(), mState.isStencilMode(), vk::SamplerDesc samplerDesc(mState.getSamplerState(), mState.isStencilMode(),
......
...@@ -212,10 +212,7 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface ...@@ -212,10 +212,7 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface
GLenum type, GLenum type,
void *pixels) override; void *pixels) override;
ANGLE_INLINE bool isBoundAsImageTexture(gl::ContextID contextID) const ANGLE_INLINE bool hasBeenBoundAsImage() const { return mState.hasBeenBoundAsImage(); }
{
return mState.isBoundAsImageTexture(contextID);
}
private: private:
// Transform an image index from the frontend into one that can be used on the backing // Transform an image index from the frontend into one that can be used on the backing
......
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