Commit e51ba63b by Geoff Lang Committed by Commit Bot

Optimize Texture initialization tracking with extra caching.

In both Texture and State, track when all images/textures are initailized so that State::clearUnclearedActiveTextures can early-exit. Improves performance on the WebGL Aquarium by 26% (23->29 FPS) with 30000 fish. BUG=angleproject:2188 Change-Id: Ie2860a81d7be19ee87262325d8cf27bde43f80b8 Reviewed-on: https://chromium-review.googlesource.com/782339 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 465835d6
......@@ -170,6 +170,7 @@ void State::initialize(const Context *context,
}
mCompleteTextureCache.resize(caps.maxCombinedTextureImageUnits, nullptr);
mCompleteTextureBindings.reserve(caps.maxCombinedTextureImageUnits);
mCachedTexturesInitState = InitState::MayNeedInit;
for (uint32_t textureIndex = 0; textureIndex < caps.maxCombinedTextureImageUnits;
++textureIndex)
{
......@@ -2234,6 +2235,10 @@ void State::syncProgramTextures(const Context *context)
ActiveTextureMask newActiveTextures;
// Initialize to the 'Initialized' state and set to 'MayNeedInit' if any texture is not
// initialized.
mCachedTexturesInitState = InitState::Initialized;
for (const SamplerBinding &samplerBinding : mProgram->getSamplerBindings())
{
if (samplerBinding.unreferenced)
......@@ -2271,6 +2276,11 @@ void State::syncProgramTextures(const Context *context)
{
sampler->syncState(context);
}
if (texture->initState() == InitState::MayNeedInit)
{
mCachedTexturesInitState = InitState::MayNeedInit;
}
}
}
......@@ -2383,12 +2393,22 @@ void State::signal(size_t textureIndex, InitState initState)
// Conservatively assume all textures are dirty.
// TODO(jmadill): More fine-grained update.
mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
if (initState == InitState::MayNeedInit)
{
mCachedTexturesInitState = InitState::MayNeedInit;
}
}
Error State::clearUnclearedActiveTextures(const Context *context)
{
ASSERT(mRobustResourceInit);
if (mCachedTexturesInitState == InitState::Initialized)
{
return NoError();
}
for (auto textureIndex : mActiveTexturesMask)
{
Texture *texture = mCompleteTextureCache[textureIndex];
......@@ -2398,6 +2418,8 @@ Error State::clearUnclearedActiveTextures(const Context *context)
}
}
mCachedTexturesInitState = InitState::Initialized;
return NoError();
}
......
......@@ -535,6 +535,7 @@ class State : public OnAttachmentDirtyReceiver, angle::NonCopyable
// Also stores a notification channel to the texture itself to handle texture change events.
std::vector<Texture *> mCompleteTextureCache;
std::vector<OnAttachmentDirtyBinding> mCompleteTextureBindings;
InitState mCachedTexturesInitState;
using ActiveTextureMask = angle::BitSet<IMPLEMENTATION_MAX_ACTIVE_TEXTURES>;
ActiveTextureMask mActiveTexturesMask;
......
......@@ -122,7 +122,9 @@ TextureState::TextureState(GLenum target)
mImmutableFormat(false),
mImmutableLevels(0),
mUsage(GL_NONE),
mImageDescs((IMPLEMENTATION_MAX_TEXTURE_LEVELS + 1) * (target == GL_TEXTURE_CUBE_MAP ? 6 : 1))
mImageDescs((IMPLEMENTATION_MAX_TEXTURE_LEVELS + 1) *
(target == GL_TEXTURE_CUBE_MAP ? 6 : 1)),
mInitState(InitState::MayNeedInit)
{
}
......@@ -469,6 +471,10 @@ void TextureState::setImageDesc(GLenum target, size_t level, const ImageDesc &de
size_t descIndex = GetImageDescIndex(target, level);
ASSERT(descIndex < mImageDescs.size());
mImageDescs[descIndex] = desc;
if (desc.initState == InitState::MayNeedInit)
{
mInitState = InitState::MayNeedInit;
}
}
const ImageDesc &TextureState::getImageDesc(const ImageIndex &imageIndex) const
......@@ -1400,7 +1406,7 @@ void Texture::invalidateCompletenessCache() const
Error Texture::ensureInitialized(const Context *context)
{
if (!context->isRobustResourceInitEnabled())
if (!context->isRobustResourceInitEnabled() || mState.mInitState == InitState::Initialized)
{
return NoError();
}
......@@ -1412,6 +1418,7 @@ Error Texture::ensureInitialized(const Context *context)
auto &imageDesc = mState.mImageDescs[descIndex];
if (imageDesc.initState == InitState::MayNeedInit)
{
ASSERT(mState.mInitState == InitState::MayNeedInit);
const auto &imageIndex = GetImageIndexFromDescIndex(mState.mTarget, descIndex);
ANGLE_TRY(initializeContents(context, imageIndex));
imageDesc.initState = InitState::Initialized;
......@@ -1422,6 +1429,8 @@ Error Texture::ensureInitialized(const Context *context)
{
signalDirty(InitState::Initialized);
}
mState.mInitState = InitState::Initialized;
return NoError();
}
......@@ -1430,6 +1439,11 @@ InitState Texture::initState(const ImageIndex &imageIndex) const
return mState.getImageDesc(imageIndex).initState;
}
InitState Texture::initState() const
{
return mState.mInitState;
}
void Texture::setInitState(const ImageIndex &imageIndex, InitState initState)
{
ImageDesc newDesc = mState.getImageDesc(imageIndex);
......@@ -1442,7 +1456,7 @@ Error Texture::ensureSubImageInitialized(const Context *context,
size_t level,
const gl::Box &area)
{
if (!context->isRobustResourceInitEnabled())
if (!context->isRobustResourceInitEnabled() || mState.mInitState == InitState::Initialized)
{
return NoError();
}
......@@ -1453,6 +1467,7 @@ Error Texture::ensureSubImageInitialized(const Context *context,
const auto &desc = mState.getImageDesc(imageIndex);
if (desc.initState == InitState::MayNeedInit)
{
ASSERT(mState.mInitState == InitState::MayNeedInit);
bool coversWholeImage = area.x == 0 && area.y == 0 && area.z == 0 &&
area.width == desc.size.width && area.height == desc.size.height &&
area.depth == desc.size.depth;
......
......@@ -161,7 +161,7 @@ struct TextureState final : private angle::NonCopyable
GLenum mUsage;
std::vector<ImageDesc> mImageDescs;
InitState mInitState;
};
bool operator==(const TextureState &a, const TextureState &b);
......@@ -366,6 +366,7 @@ class Texture final : public egl::ImageSibling,
// Needed for robust resource init.
Error ensureInitialized(const Context *context);
InitState initState(const ImageIndex &imageIndex) const override;
InitState initState() const;
void setInitState(const ImageIndex &imageIndex, InitState initState) override;
enum DirtyBitType
......
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