зеркало из https://github.com/AvaloniaUI/angle.git
Optimize ValidateBindTexture type check.
This switch can be cached in a very fast packed map. The map contents only change if different extensions are exposed. This reduces the number of instructions we hit in ValidateBindTexture. Bug: angleproject:2763 Change-Id: I6ba8a4124d85e4c193d0dee3e03e50713d51b1f4 Reviewed-on: https://chromium-review.googlesource.com/c/1262739 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Yuly Novikov <ynovikov@google.com>
This commit is contained in:
Родитель
31116738ad
Коммит
ac66f9822f
|
@ -110,8 +110,18 @@ class PackedEnumMap
|
|||
constexpr bool empty() const noexcept { return mPrivateData.empty(); }
|
||||
|
||||
// element access:
|
||||
reference operator[](E n) { return mPrivateData[static_cast<UnderlyingType>(n)]; }
|
||||
const_reference operator[](E n) const { return mPrivateData[static_cast<UnderlyingType>(n)]; }
|
||||
reference operator[](E n)
|
||||
{
|
||||
ASSERT(static_cast<size_t>(n) < mPrivateData.size());
|
||||
return mPrivateData[static_cast<UnderlyingType>(n)];
|
||||
}
|
||||
|
||||
const_reference operator[](E n) const
|
||||
{
|
||||
ASSERT(static_cast<size_t>(n) < mPrivateData.size());
|
||||
return mPrivateData[static_cast<UnderlyingType>(n)];
|
||||
}
|
||||
|
||||
const_reference at(E n) const { return mPrivateData.at(static_cast<UnderlyingType>(n)); }
|
||||
reference at(E n) { return mPrivateData.at(static_cast<UnderlyingType>(n)); }
|
||||
|
||||
|
|
|
@ -361,7 +361,6 @@ Context::Context(rx::EGLImplFactory *implFactory,
|
|||
mWebGLContext(GetWebGLContext(attribs)),
|
||||
mExtensionsEnabled(GetExtensionsEnabled(attribs, mWebGLContext)),
|
||||
mMemoryProgramCache(memoryProgramCache),
|
||||
mStateCache(this),
|
||||
mVertexArrayObserverBinding(this, kVertexArraySubjectIndex),
|
||||
mDrawFramebufferObserverBinding(this, kDrawFramebufferSubjectIndex),
|
||||
mReadFramebufferObserverBinding(this, kReadFramebufferSubjectIndex),
|
||||
|
@ -3430,6 +3429,9 @@ void Context::updateCaps()
|
|||
}
|
||||
|
||||
mThreadPool = angle::WorkerThreadPool::Create(mExtensions.parallelShaderCompile);
|
||||
|
||||
// Reinitialize state cache after extension changes.
|
||||
mStateCache.initialize(this);
|
||||
}
|
||||
|
||||
void Context::initWorkarounds()
|
||||
|
@ -7987,17 +7989,22 @@ GLenum ErrorSet::popError()
|
|||
}
|
||||
|
||||
// StateCache implementation.
|
||||
StateCache::StateCache(Context *context)
|
||||
StateCache::StateCache()
|
||||
: mCachedHasAnyEnabledClientAttrib(false),
|
||||
mCachedNonInstancedVertexElementLimit(0),
|
||||
mCachedInstancedVertexElementLimit(0),
|
||||
mCachedBasicDrawStatesError(kInvalidPointer)
|
||||
{
|
||||
updateValidDrawModes(context);
|
||||
}
|
||||
|
||||
StateCache::~StateCache() = default;
|
||||
|
||||
void StateCache::initialize(Context *context)
|
||||
{
|
||||
updateValidDrawModes(context);
|
||||
updateValidBindTextureTypes(context);
|
||||
}
|
||||
|
||||
void StateCache::updateActiveAttribsMask(Context *context)
|
||||
{
|
||||
bool isGLES1 = context->isGLES1();
|
||||
|
@ -8209,4 +8216,24 @@ void StateCache::updateValidDrawModes(Context *context)
|
|||
}};
|
||||
}
|
||||
}
|
||||
|
||||
void StateCache::updateValidBindTextureTypes(Context *context)
|
||||
{
|
||||
const Extensions &exts = context->getExtensions();
|
||||
bool isGLES3 = context->getClientMajorVersion() >= 3;
|
||||
bool isGLES31 = context->getClientVersion() >= Version(3, 1);
|
||||
|
||||
mCachedValidBindTextureTypes = {{
|
||||
true, /* _2D */
|
||||
isGLES3, /* _2DArray */
|
||||
isGLES31, /* _2DMultisample */
|
||||
exts.textureStorageMultisample2DArray, /* _2DMultisampleArray */
|
||||
isGLES3, /* _3D */
|
||||
exts.eglImageExternal || exts.eglStreamConsumerExternal, /* External */
|
||||
exts.textureRectangle, /* Rectangle */
|
||||
true, /* CubeMap */
|
||||
false, /* InvalidEnum */
|
||||
|
||||
}};
|
||||
}
|
||||
} // namespace gl
|
||||
|
|
|
@ -92,9 +92,11 @@ class ErrorSet : angle::NonCopyable
|
|||
class StateCache final : angle::NonCopyable
|
||||
{
|
||||
public:
|
||||
StateCache(Context *context);
|
||||
StateCache();
|
||||
~StateCache();
|
||||
|
||||
void initialize(Context *context);
|
||||
|
||||
// Places that can trigger updateActiveAttribsMask:
|
||||
// 1. onVertexArrayBindingChange.
|
||||
// 2. onProgramExecutableChange.
|
||||
|
@ -150,6 +152,12 @@ class StateCache final : angle::NonCopyable
|
|||
return mCachedValidDrawModes[primitiveMode];
|
||||
}
|
||||
|
||||
// Cannot change except on Context/Extension init.
|
||||
bool isValidBindTextureType(TextureType type) const
|
||||
{
|
||||
return mCachedValidBindTextureTypes[type];
|
||||
}
|
||||
|
||||
// State change notifications.
|
||||
void onVertexArrayBindingChange(Context *context);
|
||||
void onProgramExecutableChange(Context *context);
|
||||
|
@ -174,6 +182,7 @@ class StateCache final : angle::NonCopyable
|
|||
void updateVertexElementLimits(Context *context);
|
||||
void updateBasicDrawStatesError();
|
||||
void updateValidDrawModes(Context *context);
|
||||
void updateValidBindTextureTypes(Context *context);
|
||||
|
||||
intptr_t getBasicDrawStatesErrorImpl(Context *context) const;
|
||||
|
||||
|
@ -187,9 +196,11 @@ class StateCache final : angle::NonCopyable
|
|||
GLint64 mCachedInstancedVertexElementLimit;
|
||||
mutable intptr_t mCachedBasicDrawStatesError;
|
||||
|
||||
// Reserve an extra slot at the end of the map for invalid enum.
|
||||
// Reserve an extra slot at the end of these maps for invalid enum.
|
||||
angle::PackedEnumMap<PrimitiveMode, bool, angle::EnumSize<PrimitiveMode>() + 1>
|
||||
mCachedValidDrawModes;
|
||||
angle::PackedEnumMap<TextureType, bool, angle::EnumSize<TextureType>() + 1>
|
||||
mCachedValidBindTextureTypes;
|
||||
};
|
||||
|
||||
class Context final : public egl::LabeledObject, angle::NonCopyable, public angle::ObserverInterface
|
||||
|
|
|
@ -1110,6 +1110,44 @@ bool ValidDstBlendFunc(const Context *context, GLenum val)
|
|||
return false;
|
||||
}
|
||||
|
||||
void RecordBindTextureTypeError(Context *context, TextureType target)
|
||||
{
|
||||
ASSERT(!context->getStateCache().isValidBindTextureType(target));
|
||||
|
||||
switch (target)
|
||||
{
|
||||
case TextureType::Rectangle:
|
||||
ASSERT(!context->getExtensions().textureRectangle);
|
||||
context->handleError(InvalidEnum()
|
||||
<< "Context does not support GL_ANGLE_texture_rectangle");
|
||||
break;
|
||||
|
||||
case TextureType::_3D:
|
||||
case TextureType::_2DArray:
|
||||
ASSERT(context->getClientMajorVersion() < 3);
|
||||
ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
|
||||
break;
|
||||
|
||||
case TextureType::_2DMultisample:
|
||||
ASSERT(context->getClientVersion() < Version(3, 1));
|
||||
ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
|
||||
break;
|
||||
|
||||
case TextureType::_2DMultisampleArray:
|
||||
ASSERT(!context->getExtensions().textureStorageMultisample2DArray);
|
||||
ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleArrayExtensionRequired);
|
||||
break;
|
||||
|
||||
case TextureType::External:
|
||||
ASSERT(!context->getExtensions().eglImageExternal &&
|
||||
!context->getExtensions().eglStreamConsumerExternal);
|
||||
context->handleError(InvalidEnum() << "External texture extension not enabled");
|
||||
break;
|
||||
|
||||
default:
|
||||
ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
|
||||
}
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
bool ValidateES2TexImageParameters(Context *context,
|
||||
|
@ -3044,55 +3082,10 @@ bool ValidateFlushMappedBufferRangeEXT(Context *context,
|
|||
|
||||
bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
|
||||
{
|
||||
switch (target)
|
||||
if (!context->getStateCache().isValidBindTextureType(target))
|
||||
{
|
||||
case TextureType::_2D:
|
||||
case TextureType::CubeMap:
|
||||
break;
|
||||
|
||||
case TextureType::Rectangle:
|
||||
if (!context->getExtensions().textureRectangle)
|
||||
{
|
||||
context->handleError(InvalidEnum()
|
||||
<< "Context does not support GL_ANGLE_texture_rectangle");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case TextureType::_3D:
|
||||
case TextureType::_2DArray:
|
||||
if (context->getClientMajorVersion() < 3)
|
||||
{
|
||||
ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case TextureType::_2DMultisample:
|
||||
if (context->getClientVersion() < Version(3, 1))
|
||||
{
|
||||
ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case TextureType::_2DMultisampleArray:
|
||||
if (!context->getExtensions().textureStorageMultisample2DArray)
|
||||
{
|
||||
ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleArrayExtensionRequired);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case TextureType::External:
|
||||
if (!context->getExtensions().eglImageExternal &&
|
||||
!context->getExtensions().eglStreamConsumerExternal)
|
||||
{
|
||||
context->handleError(InvalidEnum() << "External texture extension not enabled");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
|
||||
return false;
|
||||
RecordBindTextureTypeError(context, target);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (texture == 0)
|
||||
|
|
Загрузка…
Ссылка в новой задаче