Commit ad9f24e1 by Jamie Madill Committed by Commit Bot

Don't always sync all dirty object state on update.

This leads to a problem where we're synching objects out of order. For instance, when we call SetImage, we need to sync the pack state. But SetImage can affect the FBO state, so we need to sync the FBO only after we've finished with SetImage. Fix this by using a mask of dirty objects to sync instead of all of them, always. This also has the side effect of deferring some syncs that don't have to be processed immediately. BUG=angleproject:1260 Change-Id: I5678d8f967930d11b42a4309d209215be2bae963 Reviewed-on: https://chromium-review.googlesource.com/327259Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 662986f2
......@@ -217,6 +217,42 @@ Context::Context(const egl::Config *config,
}
mCompiler = new Compiler(mRenderer, getData());
// Initialize dirty bit masks
// TODO(jmadill): additional ES3 state
mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ALIGNMENT);
mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_ROW_LENGTH);
mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_IMAGES);
mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_ROWS);
mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_SKIP_PIXELS);
// No dirty objects.
// Readpixels uses the pack state and read FBO
mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ALIGNMENT);
mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_ROW_LENGTH);
mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_ROWS);
mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_SKIP_PIXELS);
mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
}
Context::~Context()
......@@ -2044,14 +2080,14 @@ void Context::syncRendererState()
mState.syncDirtyObjects();
}
void Context::syncRendererState(const State::DirtyBits &bitMask)
void Context::syncRendererState(const State::DirtyBits &bitMask,
const State::DirtyObjects &objectMask)
{
const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask);
mRenderer->syncState(mState, dirtyBits);
mState.clearDirtyBits(dirtyBits);
// TODO(jmadill): Filter objects by bitMask somehow?
mState.syncDirtyObjects();
mState.syncDirtyObjects(objectMask);
}
void Context::blitFramebuffer(GLint srcX0,
......@@ -2074,7 +2110,7 @@ void Context::blitFramebuffer(GLint srcX0,
Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
syncRendererState(mState.blitStateBitMask());
syncStateForBlit();
Error error = drawFramebuffer->blit(mState, srcArea, dstArea, mask, filter, readFramebuffer);
if (error.isError())
......@@ -2086,8 +2122,7 @@ void Context::blitFramebuffer(GLint srcX0,
void Context::clear(GLbitfield mask)
{
// Sync the clear state
syncRendererState(mState.clearStateBitMask());
syncStateForClear();
Error error = mState.getDrawFramebuffer()->clear(mData, mask);
if (error.isError())
......@@ -2098,8 +2133,7 @@ void Context::clear(GLbitfield mask)
void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
{
// Sync the clear state
syncRendererState(mState.clearStateBitMask());
syncStateForClear();
Error error = mState.getDrawFramebuffer()->clearBufferfv(mData, buffer, drawbuffer, values);
if (error.isError())
......@@ -2110,8 +2144,7 @@ void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *valu
void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
{
// Sync the clear state
syncRendererState(mState.clearStateBitMask());
syncStateForClear();
Error error = mState.getDrawFramebuffer()->clearBufferuiv(mData, buffer, drawbuffer, values);
if (error.isError())
......@@ -2122,8 +2155,7 @@ void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *valu
void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
{
// Sync the clear state
syncRendererState(mState.clearStateBitMask());
syncStateForClear();
Error error = mState.getDrawFramebuffer()->clearBufferiv(mData, buffer, drawbuffer, values);
if (error.isError())
......@@ -2144,8 +2176,7 @@ void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLin
return;
}
// Sync the clear state
syncRendererState(mState.clearStateBitMask());
syncStateForClear();
Error error = framebufferObject->clearBufferfi(mData, buffer, drawbuffer, depth, stencil);
if (error.isError())
......@@ -2162,8 +2193,7 @@ void Context::readPixels(GLint x,
GLenum type,
GLvoid *pixels)
{
// Sync pack state
syncRendererState(mState.packStateBitMask());
syncStateForReadPixels();
Framebuffer *framebufferObject = mState.getReadFramebuffer();
ASSERT(framebufferObject);
......@@ -2431,8 +2461,7 @@ void Context::texImage2D(GLenum target,
GLenum type,
const GLvoid *pixels)
{
// Sync the unpack state
syncRendererState(mState.unpackStateBitMask());
syncStateForTexImage();
Extents size(width, height, 1);
Texture *texture =
......@@ -2456,8 +2485,7 @@ void Context::texImage3D(GLenum target,
GLenum type,
const GLvoid *pixels)
{
// Sync the unpack state
syncRendererState(mState.unpackStateBitMask());
syncStateForTexImage();
Extents size(width, height, depth);
Texture *texture = getTargetTexture(target);
......@@ -2485,8 +2513,7 @@ void Context::texSubImage2D(GLenum target,
return;
}
// Sync the unpack state
syncRendererState(mState.unpackStateBitMask());
syncStateForTexImage();
Box area(xoffset, yoffset, 0, width, height, 1);
Texture *texture =
......@@ -2517,8 +2544,7 @@ void Context::texSubImage3D(GLenum target,
return;
}
// Sync the unpack state
syncRendererState(mState.unpackStateBitMask());
syncStateForTexImage();
Box area(xoffset, yoffset, zoffset, width, height, depth);
Texture *texture = getTargetTexture(target);
......@@ -2539,8 +2565,7 @@ void Context::compressedTexImage2D(GLenum target,
GLsizei imageSize,
const GLvoid *data)
{
// Sync the unpack state
syncRendererState(mState.unpackStateBitMask());
syncStateForTexImage();
Extents size(width, height, 1);
Texture *texture =
......@@ -2564,8 +2589,7 @@ void Context::compressedTexImage3D(GLenum target,
GLsizei imageSize,
const GLvoid *data)
{
// Sync the unpack state
syncRendererState(mState.unpackStateBitMask());
syncStateForTexImage();
Extents size(width, height, depth);
Texture *texture = getTargetTexture(target);
......@@ -2588,8 +2612,7 @@ void Context::compressedTexSubImage2D(GLenum target,
GLsizei imageSize,
const GLvoid *data)
{
// Sync the unpack state
syncRendererState(mState.unpackStateBitMask());
syncStateForTexImage();
Box area(xoffset, yoffset, 0, width, height, 1);
Texture *texture =
......@@ -2621,8 +2644,7 @@ void Context::compressedTexSubImage3D(GLenum target,
return;
}
// Sync the unpack state
syncRendererState(mState.unpackStateBitMask());
syncStateForTexImage();
Box area(xoffset, yoffset, zoffset, width, height, depth);
Texture *texture = getTargetTexture(target);
......@@ -2635,4 +2657,24 @@ void Context::compressedTexSubImage3D(GLenum target,
}
}
void Context::syncStateForReadPixels()
{
syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects);
}
void Context::syncStateForTexImage()
{
syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
}
void Context::syncStateForClear()
{
syncRendererState(mClearDirtyBits, mClearDirtyObjects);
}
void Context::syncStateForBlit()
{
syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
}
} // namespace gl
......@@ -390,10 +390,13 @@ class Context final : public ValidationContext
State &getState() { return mState; }
void syncRendererState();
void syncRendererState(const State::DirtyBits &bitMask);
private:
void syncRendererState();
void syncRendererState(const State::DirtyBits &bitMask, const State::DirtyObjects &objectMask);
void syncStateForReadPixels();
void syncStateForTexImage();
void syncStateForClear();
void syncStateForBlit();
void checkVertexArrayAllocation(GLuint vertexArray);
void checkTransformFeedbackAllocation(GLuint transformFeedback);
Framebuffer *checkFramebufferAllocation(GLuint framebufferHandle);
......@@ -467,6 +470,15 @@ class Context final : public ValidationContext
egl::Surface *mCurrentSurface;
ResourceManager *mResourceManager;
State::DirtyBits mTexImageDirtyBits;
State::DirtyObjects mTexImageDirtyObjects;
State::DirtyBits mReadPixelsDirtyBits;
State::DirtyObjects mReadPixelsDirtyObjects;
State::DirtyBits mClearDirtyBits;
State::DirtyObjects mClearDirtyObjects;
State::DirtyBits mBlitDirtyBits;
State::DirtyObjects mBlitDirtyObjects;
};
} // namespace gl
......
......@@ -44,35 +44,6 @@ State::State()
mActiveSampler(0),
mPrimitiveRestart(false)
{
// Initialize dirty bit masks
// TODO(jmadill): additional ES3 state
mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_ALIGNMENT);
mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_ROW_LENGTH);
mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_SKIP_IMAGES);
mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_SKIP_ROWS);
mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_SKIP_PIXELS);
mPackStateBitMask.set(DIRTY_BIT_PACK_ALIGNMENT);
mPackStateBitMask.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
mPackStateBitMask.set(DIRTY_BIT_PACK_ROW_LENGTH);
mPackStateBitMask.set(DIRTY_BIT_PACK_SKIP_ROWS);
mPackStateBitMask.set(DIRTY_BIT_PACK_SKIP_PIXELS);
mClearStateBitMask.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
mClearStateBitMask.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
mClearStateBitMask.set(DIRTY_BIT_SCISSOR);
mClearStateBitMask.set(DIRTY_BIT_VIEWPORT);
mClearStateBitMask.set(DIRTY_BIT_CLEAR_COLOR);
mClearStateBitMask.set(DIRTY_BIT_CLEAR_DEPTH);
mClearStateBitMask.set(DIRTY_BIT_CLEAR_STENCIL);
mClearStateBitMask.set(DIRTY_BIT_COLOR_MASK);
mClearStateBitMask.set(DIRTY_BIT_DEPTH_MASK);
mClearStateBitMask.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
mClearStateBitMask.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
mBlitStateBitMask.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
mBlitStateBitMask.set(DIRTY_BIT_SCISSOR);
}
State::~State()
......
......@@ -364,12 +364,6 @@ class State : angle::NonCopyable
void syncDirtyObject(GLenum target);
void setObjectDirty(GLenum target);
// Dirty bit masks
const DirtyBits &unpackStateBitMask() const { return mUnpackStateBitMask; }
const DirtyBits &packStateBitMask() const { return mPackStateBitMask; }
const DirtyBits &clearStateBitMask() const { return mClearStateBitMask; }
const DirtyBits &blitStateBitMask() const { return mBlitStateBitMask; }
private:
// Cached values from Context's caps
GLuint mMaxDrawBuffers;
......@@ -442,15 +436,10 @@ class State : angle::NonCopyable
Debug mDebug;
DirtyBits mDirtyBits;
DirtyBits mUnpackStateBitMask;
DirtyBits mPackStateBitMask;
DirtyBits mClearStateBitMask;
DirtyBits mBlitStateBitMask;
DirtyObjects mDirtyObjects;
};
}
} // namespace gl
#endif // LIBANGLE_STATE_H_
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