Commit 81370214 by Tim Van Patten Committed by Commit Bot

Pass the Command when sync'ing dirty objects

A new enum is being created that contains command types, which are then passed to each dirty object when they are synced. This allows the syncState() methods to perform special handling for each command type. This change is in preparation for optimizing resolving multisample images with glBlit, since the render pass needs to be updated before it's ended. Bug: angleproject:4753 Change-Id: I77701f79418d35cff689e864c8a8b47b6fca0255 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2327335 Commit-Queue: Tim Van Patten <timvp@google.com> Reviewed-by: 's avatarCharlie Lao <cclao@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent 9892e6a2
......@@ -3622,7 +3622,7 @@ angle::Result Context::prepareForClearBuffer(GLenum buffer, GLint drawbuffer)
ANGLE_INLINE angle::Result Context::prepareForCopyImage()
{
ANGLE_TRY(syncDirtyObjects(mCopyImageDirtyObjects));
ANGLE_TRY(syncDirtyObjects(mCopyImageDirtyObjects, Command::CopyImage));
return syncDirtyBits(mCopyImageDirtyBits);
}
......@@ -3632,14 +3632,15 @@ ANGLE_INLINE angle::Result Context::prepareForDispatch()
// with a PPO, we need to convert it from a "draw"-type to "dispatch"-type.
convertPpoToComputeOrDraw(true);
ANGLE_TRY(syncDirtyObjects(mComputeDirtyObjects));
ANGLE_TRY(syncDirtyObjects(mComputeDirtyObjects, Command::Dispatch));
return syncDirtyBits(mComputeDirtyBits);
}
angle::Result Context::syncState(const State::DirtyBits &bitMask,
const State::DirtyObjects &objectMask)
const State::DirtyObjects &objectMask,
Command command)
{
ANGLE_TRY(syncDirtyObjects(objectMask));
ANGLE_TRY(syncDirtyObjects(objectMask, command));
ANGLE_TRY(syncDirtyBits(bitMask));
return angle::Result::Continue;
}
......@@ -4733,17 +4734,17 @@ void Context::flushMappedBufferRange(BufferBinding /*target*/,
angle::Result Context::syncStateForReadPixels()
{
return syncState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
return syncState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects, Command::ReadPixels);
}
angle::Result Context::syncStateForTexImage()
{
return syncState(mTexImageDirtyBits, mTexImageDirtyObjects);
return syncState(mTexImageDirtyBits, mTexImageDirtyObjects, Command::TexImage);
}
angle::Result Context::syncStateForBlit()
{
return syncState(mBlitDirtyBits, mBlitDirtyObjects);
return syncState(mBlitDirtyBits, mBlitDirtyObjects, Command::Blit);
}
void Context::activeShaderProgram(ProgramPipelineID pipeline, ShaderProgramID program)
......
......@@ -638,10 +638,12 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
angle::Result prepareForDraw(PrimitiveMode mode);
angle::Result prepareForClear(GLbitfield mask);
angle::Result prepareForClearBuffer(GLenum buffer, GLint drawbuffer);
angle::Result syncState(const State::DirtyBits &bitMask, const State::DirtyObjects &objectMask);
angle::Result syncState(const State::DirtyBits &bitMask,
const State::DirtyObjects &objectMask,
Command command);
angle::Result syncDirtyBits();
angle::Result syncDirtyBits(const State::DirtyBits &bitMask);
angle::Result syncDirtyObjects(const State::DirtyObjects &objectMask);
angle::Result syncDirtyObjects(const State::DirtyObjects &objectMask, Command command);
angle::Result syncStateForReadPixels();
angle::Result syncStateForTexImage();
angle::Result syncStateForBlit();
......
......@@ -100,9 +100,10 @@ ANGLE_INLINE angle::Result Context::syncDirtyBits(const State::DirtyBits &bitMas
return angle::Result::Continue;
}
ANGLE_INLINE angle::Result Context::syncDirtyObjects(const State::DirtyObjects &objectMask)
ANGLE_INLINE angle::Result Context::syncDirtyObjects(const State::DirtyObjects &objectMask,
Command command)
{
return mState.syncDirtyObjects(this, objectMask);
return mState.syncDirtyObjects(this, objectMask, command);
}
ANGLE_INLINE angle::Result Context::prepareForDraw(PrimitiveMode mode)
......@@ -112,7 +113,7 @@ ANGLE_INLINE angle::Result Context::prepareForDraw(PrimitiveMode mode)
ANGLE_TRY(mGLES1Renderer->prepareForDraw(mode, this, &mState));
}
ANGLE_TRY(syncDirtyObjects(mDrawDirtyObjects));
ANGLE_TRY(syncDirtyObjects(mDrawDirtyObjects, Command::Draw));
ASSERT(!isRobustResourceInitEnabled() ||
!mState.getDrawFramebuffer()->hasResourceThatNeedsInit());
return syncDirtyBits();
......
......@@ -1106,7 +1106,7 @@ GLenum Framebuffer::checkStatusImpl(const Context *context) const
{
// This binding is not totally correct. It is ok because the parameter isn't used in
// the GL back-end and the GL back-end is the only user of syncStateBeforeCheckStatus.
angle::Result err = syncState(context, GL_FRAMEBUFFER);
angle::Result err = syncState(context, GL_FRAMEBUFFER, Command::Other);
if (err != angle::Result::Continue)
{
return 0;
......@@ -1879,12 +1879,14 @@ void Framebuffer::resetAttachment(const Context *context, GLenum binding)
setAttachment(context, GL_NONE, binding, ImageIndex(), nullptr);
}
angle::Result Framebuffer::syncState(const Context *context, GLenum framebufferBinding) const
angle::Result Framebuffer::syncState(const Context *context,
GLenum framebufferBinding,
Command command) const
{
if (mDirtyBits.any())
{
mDirtyBitsGuard = mDirtyBits;
ANGLE_TRY(mImpl->syncState(context, framebufferBinding, mDirtyBits));
ANGLE_TRY(mImpl->syncState(context, framebufferBinding, mDirtyBits, command));
mDirtyBits.reset();
mDirtyBitsGuard.reset();
}
......
......@@ -21,6 +21,7 @@
#include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/Observer.h"
#include "libANGLE/RefCountObject.h"
#include "libANGLE/State.h"
namespace rx
{
......@@ -390,7 +391,9 @@ class Framebuffer final : public angle::ObserverInterface,
bool hasResourceThatNeedsInit() const { return mState.mResourceNeedsInit.any(); }
angle::Result syncState(const Context *context, GLenum framebufferBinding) const;
angle::Result syncState(const Context *context,
GLenum framebufferBinding,
Command command) const;
// Observer implementation
void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
......
......@@ -3054,7 +3054,7 @@ Texture *State::getTextureForActiveSampler(TextureType type, size_t index)
return mSamplerTextures[type][index].get();
}
angle::Result State::syncTexturesInit(const Context *context)
angle::Result State::syncTexturesInit(const Context *context, Command command)
{
ASSERT(mRobustResourceInit);
......@@ -3072,7 +3072,7 @@ angle::Result State::syncTexturesInit(const Context *context)
return angle::Result::Continue;
}
angle::Result State::syncImagesInit(const Context *context)
angle::Result State::syncImagesInit(const Context *context, Command command)
{
ASSERT(mRobustResourceInit);
ASSERT(mProgram);
......@@ -3087,33 +3087,33 @@ angle::Result State::syncImagesInit(const Context *context)
return angle::Result::Continue;
}
angle::Result State::syncReadAttachments(const Context *context)
angle::Result State::syncReadAttachments(const Context *context, Command command)
{
ASSERT(mReadFramebuffer);
ASSERT(mRobustResourceInit);
return mReadFramebuffer->ensureReadAttachmentsInitialized(context);
}
angle::Result State::syncDrawAttachments(const Context *context)
angle::Result State::syncDrawAttachments(const Context *context, Command command)
{
ASSERT(mDrawFramebuffer);
ASSERT(mRobustResourceInit);
return mDrawFramebuffer->ensureDrawAttachmentsInitialized(context);
}
angle::Result State::syncReadFramebuffer(const Context *context)
angle::Result State::syncReadFramebuffer(const Context *context, Command command)
{
ASSERT(mReadFramebuffer);
return mReadFramebuffer->syncState(context, GL_READ_FRAMEBUFFER);
return mReadFramebuffer->syncState(context, GL_READ_FRAMEBUFFER, command);
}
angle::Result State::syncDrawFramebuffer(const Context *context)
angle::Result State::syncDrawFramebuffer(const Context *context, Command command)
{
ASSERT(mDrawFramebuffer);
return mDrawFramebuffer->syncState(context, GL_DRAW_FRAMEBUFFER);
return mDrawFramebuffer->syncState(context, GL_DRAW_FRAMEBUFFER, command);
}
angle::Result State::syncTextures(const Context *context)
angle::Result State::syncTextures(const Context *context, Command command)
{
if (mDirtyTextures.none())
return angle::Result::Continue;
......@@ -3131,7 +3131,7 @@ angle::Result State::syncTextures(const Context *context)
return angle::Result::Continue;
}
angle::Result State::syncImages(const Context *context)
angle::Result State::syncImages(const Context *context, Command command)
{
if (mDirtyImages.none())
return angle::Result::Continue;
......@@ -3149,7 +3149,7 @@ angle::Result State::syncImages(const Context *context)
return angle::Result::Continue;
}
angle::Result State::syncSamplers(const Context *context)
angle::Result State::syncSamplers(const Context *context, Command command)
{
if (mDirtySamplers.none())
return angle::Result::Continue;
......@@ -3168,13 +3168,13 @@ angle::Result State::syncSamplers(const Context *context)
return angle::Result::Continue;
}
angle::Result State::syncVertexArray(const Context *context)
angle::Result State::syncVertexArray(const Context *context, Command command)
{
ASSERT(mVertexArray);
return mVertexArray->syncState(context);
}
angle::Result State::syncProgram(const Context *context)
angle::Result State::syncProgram(const Context *context, Command command)
{
// There may not be a program if the calling application only uses program pipelines.
if (mProgram)
......@@ -3184,7 +3184,7 @@ angle::Result State::syncProgram(const Context *context)
return angle::Result::Continue;
}
angle::Result State::syncProgramPipeline(const Context *context)
angle::Result State::syncProgramPipeline(const Context *context, Command command)
{
// There may not be a program pipeline if the calling application only uses programs.
if (mProgramPipeline.get())
......@@ -3224,7 +3224,7 @@ angle::Result State::syncDirtyObject(const Context *context, GLenum target)
break;
}
return syncDirtyObjects(context, localSet);
return syncDirtyObjects(context, localSet, Command::Other);
}
void State::setObjectDirty(GLenum target)
......
......@@ -70,6 +70,17 @@ using TextureBindingMap = angle::PackedEnumMap<TextureType, TextureBindingVec
using ActiveQueryMap = angle::PackedEnumMap<QueryType, BindingPointer<Query>>;
using BufferVector = std::vector<OffsetBindingPointer<Buffer>>;
enum class Command
{
Other,
Blit,
CopyImage,
Dispatch,
Draw,
ReadPixels,
TexImage
};
class ActiveTexturesCache final : angle::NonCopyable
{
public:
......@@ -674,7 +685,9 @@ class State : angle::NonCopyable
using DirtyObjects = angle::BitSet<DIRTY_OBJECT_MAX>;
void clearDirtyObjects() { mDirtyObjects.reset(); }
void setAllDirtyObjects() { mDirtyObjects.set(); }
angle::Result syncDirtyObjects(const Context *context, const DirtyObjects &bitset);
angle::Result syncDirtyObjects(const Context *context,
const DirtyObjects &bitset,
Command command);
angle::Result syncDirtyObject(const Context *context, GLenum target);
void setObjectDirty(GLenum target);
void setTextureDirty(size_t textureUnitIndex);
......@@ -853,20 +866,20 @@ class State : angle::NonCopyable
bool hasConstantAlpha(GLenum sourceRGB, GLenum destRGB) const;
// Functions to synchronize dirty states
angle::Result syncTexturesInit(const Context *context);
angle::Result syncImagesInit(const Context *context);
angle::Result syncReadAttachments(const Context *context);
angle::Result syncDrawAttachments(const Context *context);
angle::Result syncReadFramebuffer(const Context *context);
angle::Result syncDrawFramebuffer(const Context *context);
angle::Result syncVertexArray(const Context *context);
angle::Result syncTextures(const Context *context);
angle::Result syncImages(const Context *context);
angle::Result syncSamplers(const Context *context);
angle::Result syncProgram(const Context *context);
angle::Result syncProgramPipeline(const Context *context);
using DirtyObjectHandler = angle::Result (State::*)(const Context *context);
angle::Result syncTexturesInit(const Context *context, Command command);
angle::Result syncImagesInit(const Context *context, Command command);
angle::Result syncReadAttachments(const Context *context, Command command);
angle::Result syncDrawAttachments(const Context *context, Command command);
angle::Result syncReadFramebuffer(const Context *context, Command command);
angle::Result syncDrawFramebuffer(const Context *context, Command command);
angle::Result syncVertexArray(const Context *context, Command command);
angle::Result syncTextures(const Context *context, Command command);
angle::Result syncImages(const Context *context, Command command);
angle::Result syncSamplers(const Context *context, Command command);
angle::Result syncProgram(const Context *context, Command command);
angle::Result syncProgramPipeline(const Context *context, Command command);
using DirtyObjectHandler = angle::Result (State::*)(const Context *context, Command command);
static constexpr DirtyObjectHandler kDirtyObjectHandlers[DIRTY_OBJECT_MAX] = {
&State::syncTexturesInit, &State::syncImagesInit, &State::syncReadAttachments,
&State::syncDrawAttachments, &State::syncReadFramebuffer, &State::syncDrawFramebuffer,
......@@ -1069,13 +1082,14 @@ class State : angle::NonCopyable
};
ANGLE_INLINE angle::Result State::syncDirtyObjects(const Context *context,
const DirtyObjects &bitset)
const DirtyObjects &bitset,
Command command)
{
const DirtyObjects &dirtyObjects = mDirtyObjects & bitset;
for (size_t dirtyObject : dirtyObjects)
{
ANGLE_TRY((this->*kDirtyObjectHandlers[dirtyObject])(context));
ANGLE_TRY((this->*kDirtyObjectHandlers[dirtyObject])(context, command));
}
mDirtyObjects &= ~dirtyObjects;
......
......@@ -144,7 +144,7 @@ Result SerializeFramebufferAttachment(const gl::Context *context,
framebuffer->getState().getColorAttachments().size()))
{
framebuffer->setReadBuffer(framebufferAttachment.getBinding());
ANGLE_TRY(framebuffer->syncState(context, GL_FRAMEBUFFER));
ANGLE_TRY(framebuffer->syncState(context, GL_FRAMEBUFFER, gl::Command::Other));
}
MemoryBuffer *pixelsPtr = nullptr;
ANGLE_TRY(ReadPixelsFromAttachment(context, framebuffer, framebufferAttachment,
......
......@@ -13,6 +13,7 @@
#include "common/angleutils.h"
#include "libANGLE/Error.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/State.h"
namespace gl
{
......@@ -85,7 +86,8 @@ class FramebufferImpl : angle::NonCopyable
virtual angle::Result syncState(const gl::Context *context,
GLenum binding,
const gl::Framebuffer::DirtyBits &dirtyBits) = 0;
const gl::Framebuffer::DirtyBits &dirtyBits,
gl::Command command) = 0;
virtual angle::Result getSamplePosition(const gl::Context *context,
size_t index,
......
......@@ -54,8 +54,11 @@ class MockFramebufferImpl : public rx::FramebufferImpl
MOCK_CONST_METHOD1(checkStatus, bool(const gl::Context *));
MOCK_METHOD3(syncState,
angle::Result(const gl::Context *, GLenum, const gl::Framebuffer::DirtyBits &));
MOCK_METHOD4(syncState,
angle::Result(const gl::Context *,
GLenum,
const gl::Framebuffer::DirtyBits &,
gl::Command command));
MOCK_METHOD0(destructor, void());
};
......
......@@ -281,7 +281,8 @@ bool FramebufferD3D::checkStatus(const gl::Context *context) const
angle::Result FramebufferD3D::syncState(const gl::Context *context,
GLenum binding,
const gl::Framebuffer::DirtyBits &dirtyBits)
const gl::Framebuffer::DirtyBits &dirtyBits,
gl::Command command)
{
if (!mColorAttachmentsForRender.valid())
{
......
......@@ -96,7 +96,8 @@ class FramebufferD3D : public FramebufferImpl
angle::Result syncState(const gl::Context *context,
GLenum binding,
const gl::Framebuffer::DirtyBits &dirtyBits) override;
const gl::Framebuffer::DirtyBits &dirtyBits,
gl::Command command) override;
const gl::AttachmentList &getColorAttachmentsForRender(const gl::Context *context);
......
......@@ -392,10 +392,11 @@ const gl::InternalFormat &Framebuffer11::getImplementationColorReadFormat(
angle::Result Framebuffer11::syncState(const gl::Context *context,
GLenum binding,
const gl::Framebuffer::DirtyBits &dirtyBits)
const gl::Framebuffer::DirtyBits &dirtyBits,
gl::Command command)
{
ANGLE_TRY(mRenderTargetCache.update(context, mState, dirtyBits));
ANGLE_TRY(FramebufferD3D::syncState(context, binding, dirtyBits));
ANGLE_TRY(FramebufferD3D::syncState(context, binding, dirtyBits, command));
// Call this last to allow the state manager to take advantage of the cached render targets.
mRenderer->getStateManager()->invalidateRenderTarget();
......
......@@ -40,7 +40,8 @@ class Framebuffer11 : public FramebufferD3D
angle::Result syncState(const gl::Context *context,
GLenum binding,
const gl::Framebuffer::DirtyBits &dirtyBits) override;
const gl::Framebuffer::DirtyBits &dirtyBits,
gl::Command command) override;
const gl::AttachmentArray<RenderTarget11 *> &getCachedColorRenderTargets() const
{
......
......@@ -406,9 +406,10 @@ angle::Result Framebuffer9::getSamplePosition(const gl::Context *context,
angle::Result Framebuffer9::syncState(const gl::Context *context,
GLenum binding,
const gl::Framebuffer::DirtyBits &dirtyBits)
const gl::Framebuffer::DirtyBits &dirtyBits,
gl::Command command)
{
ANGLE_TRY(FramebufferD3D::syncState(context, binding, dirtyBits));
ANGLE_TRY(FramebufferD3D::syncState(context, binding, dirtyBits, command));
ANGLE_TRY(mRenderTargetCache.update(context, mState, dirtyBits));
return angle::Result::Continue;
}
......
......@@ -40,7 +40,8 @@ class Framebuffer9 : public FramebufferD3D
angle::Result syncState(const gl::Context *context,
GLenum binding,
const gl::Framebuffer::DirtyBits &dirtyBits) override;
const gl::Framebuffer::DirtyBits &dirtyBits,
gl::Command command) override;
const gl::AttachmentArray<RenderTarget9 *> &getCachedColorRenderTargets() const
{
......
......@@ -1198,7 +1198,8 @@ bool FramebufferGL::checkStatus(const gl::Context *context) const
angle::Result FramebufferGL::syncState(const gl::Context *context,
GLenum binding,
const gl::Framebuffer::DirtyBits &dirtyBits)
const gl::Framebuffer::DirtyBits &dirtyBits,
gl::Command command)
{
// Don't need to sync state for the default FBO.
if (mIsDefault)
......
......@@ -83,7 +83,8 @@ class FramebufferGL : public FramebufferImpl
angle::Result syncState(const gl::Context *context,
GLenum binding,
const gl::Framebuffer::DirtyBits &dirtyBits) override;
const gl::Framebuffer::DirtyBits &dirtyBits,
gl::Command command) override;
GLuint getFramebufferID() const;
bool isDefault() const;
......
......@@ -82,7 +82,8 @@ class FramebufferMtl : public FramebufferImpl
angle::Result syncState(const gl::Context *context,
GLenum binding,
const gl::Framebuffer::DirtyBits &dirtyBits) override;
const gl::Framebuffer::DirtyBits &dirtyBits,
gl::Command command) override;
angle::Result getSamplePosition(const gl::Context *context,
size_t index,
......
......@@ -228,7 +228,8 @@ bool FramebufferMtl::checkStatus(const gl::Context *context) const
angle::Result FramebufferMtl::syncState(const gl::Context *context,
GLenum binding,
const gl::Framebuffer::DirtyBits &dirtyBits)
const gl::Framebuffer::DirtyBits &dirtyBits,
gl::Command command)
{
ContextMtl *contextMtl = mtl::GetImpl(context);
ASSERT(dirtyBits.any());
......
......@@ -158,7 +158,8 @@ bool FramebufferNULL::checkStatus(const gl::Context *context) const
angle::Result FramebufferNULL::syncState(const gl::Context *context,
GLenum binding,
const gl::Framebuffer::DirtyBits &dirtyBits)
const gl::Framebuffer::DirtyBits &dirtyBits,
gl::Command command)
{
return angle::Result::Continue;
}
......
......@@ -69,7 +69,8 @@ class FramebufferNULL : public FramebufferImpl
angle::Result syncState(const gl::Context *context,
GLenum binding,
const gl::Framebuffer::DirtyBits &dirtyBits) override;
const gl::Framebuffer::DirtyBits &dirtyBits,
gl::Command command) override;
angle::Result getSamplePosition(const gl::Context *context,
size_t index,
......
......@@ -1538,7 +1538,8 @@ void FramebufferVk::updateDepthStencilAttachmentSerial(ContextVk *contextVk)
angle::Result FramebufferVk::syncState(const gl::Context *context,
GLenum binding,
const gl::Framebuffer::DirtyBits &dirtyBits)
const gl::Framebuffer::DirtyBits &dirtyBits,
gl::Command command)
{
ContextVk *contextVk = vk::GetImpl(context);
......
......@@ -89,7 +89,8 @@ class FramebufferVk : public FramebufferImpl
angle::Result syncState(const gl::Context *context,
GLenum binding,
const gl::Framebuffer::DirtyBits &dirtyBits) override;
const gl::Framebuffer::DirtyBits &dirtyBits,
gl::Command command) override;
angle::Result getSamplePosition(const gl::Context *context,
size_t index,
......
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