зеркало из 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(); }
|
constexpr bool empty() const noexcept { return mPrivateData.empty(); }
|
||||||
|
|
||||||
// element access:
|
// element access:
|
||||||
reference operator[](E n) { return mPrivateData[static_cast<UnderlyingType>(n)]; }
|
reference operator[](E n)
|
||||||
const_reference operator[](E n) const { return mPrivateData[static_cast<UnderlyingType>(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)); }
|
const_reference at(E n) const { return mPrivateData.at(static_cast<UnderlyingType>(n)); }
|
||||||
reference at(E n) { 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)),
|
mWebGLContext(GetWebGLContext(attribs)),
|
||||||
mExtensionsEnabled(GetExtensionsEnabled(attribs, mWebGLContext)),
|
mExtensionsEnabled(GetExtensionsEnabled(attribs, mWebGLContext)),
|
||||||
mMemoryProgramCache(memoryProgramCache),
|
mMemoryProgramCache(memoryProgramCache),
|
||||||
mStateCache(this),
|
|
||||||
mVertexArrayObserverBinding(this, kVertexArraySubjectIndex),
|
mVertexArrayObserverBinding(this, kVertexArraySubjectIndex),
|
||||||
mDrawFramebufferObserverBinding(this, kDrawFramebufferSubjectIndex),
|
mDrawFramebufferObserverBinding(this, kDrawFramebufferSubjectIndex),
|
||||||
mReadFramebufferObserverBinding(this, kReadFramebufferSubjectIndex),
|
mReadFramebufferObserverBinding(this, kReadFramebufferSubjectIndex),
|
||||||
|
@ -3430,6 +3429,9 @@ void Context::updateCaps()
|
||||||
}
|
}
|
||||||
|
|
||||||
mThreadPool = angle::WorkerThreadPool::Create(mExtensions.parallelShaderCompile);
|
mThreadPool = angle::WorkerThreadPool::Create(mExtensions.parallelShaderCompile);
|
||||||
|
|
||||||
|
// Reinitialize state cache after extension changes.
|
||||||
|
mStateCache.initialize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Context::initWorkarounds()
|
void Context::initWorkarounds()
|
||||||
|
@ -7987,17 +7989,22 @@ GLenum ErrorSet::popError()
|
||||||
}
|
}
|
||||||
|
|
||||||
// StateCache implementation.
|
// StateCache implementation.
|
||||||
StateCache::StateCache(Context *context)
|
StateCache::StateCache()
|
||||||
: mCachedHasAnyEnabledClientAttrib(false),
|
: mCachedHasAnyEnabledClientAttrib(false),
|
||||||
mCachedNonInstancedVertexElementLimit(0),
|
mCachedNonInstancedVertexElementLimit(0),
|
||||||
mCachedInstancedVertexElementLimit(0),
|
mCachedInstancedVertexElementLimit(0),
|
||||||
mCachedBasicDrawStatesError(kInvalidPointer)
|
mCachedBasicDrawStatesError(kInvalidPointer)
|
||||||
{
|
{
|
||||||
updateValidDrawModes(context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StateCache::~StateCache() = default;
|
StateCache::~StateCache() = default;
|
||||||
|
|
||||||
|
void StateCache::initialize(Context *context)
|
||||||
|
{
|
||||||
|
updateValidDrawModes(context);
|
||||||
|
updateValidBindTextureTypes(context);
|
||||||
|
}
|
||||||
|
|
||||||
void StateCache::updateActiveAttribsMask(Context *context)
|
void StateCache::updateActiveAttribsMask(Context *context)
|
||||||
{
|
{
|
||||||
bool isGLES1 = context->isGLES1();
|
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
|
} // namespace gl
|
||||||
|
|
|
@ -92,9 +92,11 @@ class ErrorSet : angle::NonCopyable
|
||||||
class StateCache final : angle::NonCopyable
|
class StateCache final : angle::NonCopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StateCache(Context *context);
|
StateCache();
|
||||||
~StateCache();
|
~StateCache();
|
||||||
|
|
||||||
|
void initialize(Context *context);
|
||||||
|
|
||||||
// Places that can trigger updateActiveAttribsMask:
|
// Places that can trigger updateActiveAttribsMask:
|
||||||
// 1. onVertexArrayBindingChange.
|
// 1. onVertexArrayBindingChange.
|
||||||
// 2. onProgramExecutableChange.
|
// 2. onProgramExecutableChange.
|
||||||
|
@ -150,6 +152,12 @@ class StateCache final : angle::NonCopyable
|
||||||
return mCachedValidDrawModes[primitiveMode];
|
return mCachedValidDrawModes[primitiveMode];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cannot change except on Context/Extension init.
|
||||||
|
bool isValidBindTextureType(TextureType type) const
|
||||||
|
{
|
||||||
|
return mCachedValidBindTextureTypes[type];
|
||||||
|
}
|
||||||
|
|
||||||
// State change notifications.
|
// State change notifications.
|
||||||
void onVertexArrayBindingChange(Context *context);
|
void onVertexArrayBindingChange(Context *context);
|
||||||
void onProgramExecutableChange(Context *context);
|
void onProgramExecutableChange(Context *context);
|
||||||
|
@ -174,6 +182,7 @@ class StateCache final : angle::NonCopyable
|
||||||
void updateVertexElementLimits(Context *context);
|
void updateVertexElementLimits(Context *context);
|
||||||
void updateBasicDrawStatesError();
|
void updateBasicDrawStatesError();
|
||||||
void updateValidDrawModes(Context *context);
|
void updateValidDrawModes(Context *context);
|
||||||
|
void updateValidBindTextureTypes(Context *context);
|
||||||
|
|
||||||
intptr_t getBasicDrawStatesErrorImpl(Context *context) const;
|
intptr_t getBasicDrawStatesErrorImpl(Context *context) const;
|
||||||
|
|
||||||
|
@ -187,9 +196,11 @@ class StateCache final : angle::NonCopyable
|
||||||
GLint64 mCachedInstancedVertexElementLimit;
|
GLint64 mCachedInstancedVertexElementLimit;
|
||||||
mutable intptr_t mCachedBasicDrawStatesError;
|
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>
|
angle::PackedEnumMap<PrimitiveMode, bool, angle::EnumSize<PrimitiveMode>() + 1>
|
||||||
mCachedValidDrawModes;
|
mCachedValidDrawModes;
|
||||||
|
angle::PackedEnumMap<TextureType, bool, angle::EnumSize<TextureType>() + 1>
|
||||||
|
mCachedValidBindTextureTypes;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Context final : public egl::LabeledObject, angle::NonCopyable, public angle::ObserverInterface
|
class Context final : public egl::LabeledObject, angle::NonCopyable, public angle::ObserverInterface
|
||||||
|
|
|
@ -1110,6 +1110,44 @@ bool ValidDstBlendFunc(const Context *context, GLenum val)
|
||||||
return false;
|
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
|
} // anonymous namespace
|
||||||
|
|
||||||
bool ValidateES2TexImageParameters(Context *context,
|
bool ValidateES2TexImageParameters(Context *context,
|
||||||
|
@ -3044,55 +3082,10 @@ bool ValidateFlushMappedBufferRangeEXT(Context *context,
|
||||||
|
|
||||||
bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
|
bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
|
||||||
{
|
{
|
||||||
switch (target)
|
if (!context->getStateCache().isValidBindTextureType(target))
|
||||||
{
|
{
|
||||||
case TextureType::_2D:
|
RecordBindTextureTypeError(context, target);
|
||||||
case TextureType::CubeMap:
|
return false;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (texture == 0)
|
if (texture == 0)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче