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, ...@@ -170,6 +170,7 @@ void State::initialize(const Context *context,
} }
mCompleteTextureCache.resize(caps.maxCombinedTextureImageUnits, nullptr); mCompleteTextureCache.resize(caps.maxCombinedTextureImageUnits, nullptr);
mCompleteTextureBindings.reserve(caps.maxCombinedTextureImageUnits); mCompleteTextureBindings.reserve(caps.maxCombinedTextureImageUnits);
mCachedTexturesInitState = InitState::MayNeedInit;
for (uint32_t textureIndex = 0; textureIndex < caps.maxCombinedTextureImageUnits; for (uint32_t textureIndex = 0; textureIndex < caps.maxCombinedTextureImageUnits;
++textureIndex) ++textureIndex)
{ {
...@@ -2234,6 +2235,10 @@ void State::syncProgramTextures(const Context *context) ...@@ -2234,6 +2235,10 @@ void State::syncProgramTextures(const Context *context)
ActiveTextureMask newActiveTextures; 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()) for (const SamplerBinding &samplerBinding : mProgram->getSamplerBindings())
{ {
if (samplerBinding.unreferenced) if (samplerBinding.unreferenced)
...@@ -2271,6 +2276,11 @@ void State::syncProgramTextures(const Context *context) ...@@ -2271,6 +2276,11 @@ void State::syncProgramTextures(const Context *context)
{ {
sampler->syncState(context); sampler->syncState(context);
} }
if (texture->initState() == InitState::MayNeedInit)
{
mCachedTexturesInitState = InitState::MayNeedInit;
}
} }
} }
...@@ -2383,12 +2393,22 @@ void State::signal(size_t textureIndex, InitState initState) ...@@ -2383,12 +2393,22 @@ void State::signal(size_t textureIndex, InitState initState)
// Conservatively assume all textures are dirty. // Conservatively assume all textures are dirty.
// TODO(jmadill): More fine-grained update. // TODO(jmadill): More fine-grained update.
mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES); mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
if (initState == InitState::MayNeedInit)
{
mCachedTexturesInitState = InitState::MayNeedInit;
}
} }
Error State::clearUnclearedActiveTextures(const Context *context) Error State::clearUnclearedActiveTextures(const Context *context)
{ {
ASSERT(mRobustResourceInit); ASSERT(mRobustResourceInit);
if (mCachedTexturesInitState == InitState::Initialized)
{
return NoError();
}
for (auto textureIndex : mActiveTexturesMask) for (auto textureIndex : mActiveTexturesMask)
{ {
Texture *texture = mCompleteTextureCache[textureIndex]; Texture *texture = mCompleteTextureCache[textureIndex];
...@@ -2398,6 +2418,8 @@ Error State::clearUnclearedActiveTextures(const Context *context) ...@@ -2398,6 +2418,8 @@ Error State::clearUnclearedActiveTextures(const Context *context)
} }
} }
mCachedTexturesInitState = InitState::Initialized;
return NoError(); return NoError();
} }
......
...@@ -535,6 +535,7 @@ class State : public OnAttachmentDirtyReceiver, angle::NonCopyable ...@@ -535,6 +535,7 @@ class State : public OnAttachmentDirtyReceiver, angle::NonCopyable
// Also stores a notification channel to the texture itself to handle texture change events. // Also stores a notification channel to the texture itself to handle texture change events.
std::vector<Texture *> mCompleteTextureCache; std::vector<Texture *> mCompleteTextureCache;
std::vector<OnAttachmentDirtyBinding> mCompleteTextureBindings; std::vector<OnAttachmentDirtyBinding> mCompleteTextureBindings;
InitState mCachedTexturesInitState;
using ActiveTextureMask = angle::BitSet<IMPLEMENTATION_MAX_ACTIVE_TEXTURES>; using ActiveTextureMask = angle::BitSet<IMPLEMENTATION_MAX_ACTIVE_TEXTURES>;
ActiveTextureMask mActiveTexturesMask; ActiveTextureMask mActiveTexturesMask;
......
...@@ -122,7 +122,9 @@ TextureState::TextureState(GLenum target) ...@@ -122,7 +122,9 @@ TextureState::TextureState(GLenum target)
mImmutableFormat(false), mImmutableFormat(false),
mImmutableLevels(0), mImmutableLevels(0),
mUsage(GL_NONE), 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 ...@@ -469,6 +471,10 @@ void TextureState::setImageDesc(GLenum target, size_t level, const ImageDesc &de
size_t descIndex = GetImageDescIndex(target, level); size_t descIndex = GetImageDescIndex(target, level);
ASSERT(descIndex < mImageDescs.size()); ASSERT(descIndex < mImageDescs.size());
mImageDescs[descIndex] = desc; mImageDescs[descIndex] = desc;
if (desc.initState == InitState::MayNeedInit)
{
mInitState = InitState::MayNeedInit;
}
} }
const ImageDesc &TextureState::getImageDesc(const ImageIndex &imageIndex) const const ImageDesc &TextureState::getImageDesc(const ImageIndex &imageIndex) const
...@@ -1400,7 +1406,7 @@ void Texture::invalidateCompletenessCache() const ...@@ -1400,7 +1406,7 @@ void Texture::invalidateCompletenessCache() const
Error Texture::ensureInitialized(const Context *context) Error Texture::ensureInitialized(const Context *context)
{ {
if (!context->isRobustResourceInitEnabled()) if (!context->isRobustResourceInitEnabled() || mState.mInitState == InitState::Initialized)
{ {
return NoError(); return NoError();
} }
...@@ -1412,6 +1418,7 @@ Error Texture::ensureInitialized(const Context *context) ...@@ -1412,6 +1418,7 @@ Error Texture::ensureInitialized(const Context *context)
auto &imageDesc = mState.mImageDescs[descIndex]; auto &imageDesc = mState.mImageDescs[descIndex];
if (imageDesc.initState == InitState::MayNeedInit) if (imageDesc.initState == InitState::MayNeedInit)
{ {
ASSERT(mState.mInitState == InitState::MayNeedInit);
const auto &imageIndex = GetImageIndexFromDescIndex(mState.mTarget, descIndex); const auto &imageIndex = GetImageIndexFromDescIndex(mState.mTarget, descIndex);
ANGLE_TRY(initializeContents(context, imageIndex)); ANGLE_TRY(initializeContents(context, imageIndex));
imageDesc.initState = InitState::Initialized; imageDesc.initState = InitState::Initialized;
...@@ -1422,6 +1429,8 @@ Error Texture::ensureInitialized(const Context *context) ...@@ -1422,6 +1429,8 @@ Error Texture::ensureInitialized(const Context *context)
{ {
signalDirty(InitState::Initialized); signalDirty(InitState::Initialized);
} }
mState.mInitState = InitState::Initialized;
return NoError(); return NoError();
} }
...@@ -1430,6 +1439,11 @@ InitState Texture::initState(const ImageIndex &imageIndex) const ...@@ -1430,6 +1439,11 @@ InitState Texture::initState(const ImageIndex &imageIndex) const
return mState.getImageDesc(imageIndex).initState; return mState.getImageDesc(imageIndex).initState;
} }
InitState Texture::initState() const
{
return mState.mInitState;
}
void Texture::setInitState(const ImageIndex &imageIndex, InitState initState) void Texture::setInitState(const ImageIndex &imageIndex, InitState initState)
{ {
ImageDesc newDesc = mState.getImageDesc(imageIndex); ImageDesc newDesc = mState.getImageDesc(imageIndex);
...@@ -1442,7 +1456,7 @@ Error Texture::ensureSubImageInitialized(const Context *context, ...@@ -1442,7 +1456,7 @@ Error Texture::ensureSubImageInitialized(const Context *context,
size_t level, size_t level,
const gl::Box &area) const gl::Box &area)
{ {
if (!context->isRobustResourceInitEnabled()) if (!context->isRobustResourceInitEnabled() || mState.mInitState == InitState::Initialized)
{ {
return NoError(); return NoError();
} }
...@@ -1453,6 +1467,7 @@ Error Texture::ensureSubImageInitialized(const Context *context, ...@@ -1453,6 +1467,7 @@ Error Texture::ensureSubImageInitialized(const Context *context,
const auto &desc = mState.getImageDesc(imageIndex); const auto &desc = mState.getImageDesc(imageIndex);
if (desc.initState == InitState::MayNeedInit) if (desc.initState == InitState::MayNeedInit)
{ {
ASSERT(mState.mInitState == InitState::MayNeedInit);
bool coversWholeImage = area.x == 0 && area.y == 0 && area.z == 0 && bool coversWholeImage = area.x == 0 && area.y == 0 && area.z == 0 &&
area.width == desc.size.width && area.height == desc.size.height && area.width == desc.size.width && area.height == desc.size.height &&
area.depth == desc.size.depth; area.depth == desc.size.depth;
......
...@@ -161,7 +161,7 @@ struct TextureState final : private angle::NonCopyable ...@@ -161,7 +161,7 @@ struct TextureState final : private angle::NonCopyable
GLenum mUsage; GLenum mUsage;
std::vector<ImageDesc> mImageDescs; std::vector<ImageDesc> mImageDescs;
InitState mInitState;
}; };
bool operator==(const TextureState &a, const TextureState &b); bool operator==(const TextureState &a, const TextureState &b);
...@@ -366,6 +366,7 @@ class Texture final : public egl::ImageSibling, ...@@ -366,6 +366,7 @@ class Texture final : public egl::ImageSibling,
// Needed for robust resource init. // Needed for robust resource init.
Error ensureInitialized(const Context *context); Error ensureInitialized(const Context *context);
InitState initState(const ImageIndex &imageIndex) const override; InitState initState(const ImageIndex &imageIndex) const override;
InitState initState() const;
void setInitState(const ImageIndex &imageIndex, InitState initState) override; void setInitState(const ImageIndex &imageIndex, InitState initState) override;
enum DirtyBitType 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